2022-12-01 14:28:52 +01:00
|
|
|
import type {IdentityPrismProvider} from './Atom'
|
2022-12-01 18:56:34 +01:00
|
|
|
import Atom, {val} from './Atom'
|
2021-08-07 23:24:37 +02:00
|
|
|
import type {Pointer} from './pointer'
|
2021-06-18 13:05:06 +02:00
|
|
|
import pointer from './pointer'
|
|
|
|
import type {$FixMe, $IntentionalAny} from './types'
|
2022-12-01 15:09:53 +01:00
|
|
|
import prism from './prism/prism'
|
2021-06-18 13:05:06 +02:00
|
|
|
|
2022-01-19 13:06:13 +01:00
|
|
|
/**
|
2022-12-01 14:59:03 +01:00
|
|
|
* Allows creating pointer-prisms where the pointer can be switched out.
|
2022-01-19 13:06:13 +01:00
|
|
|
*
|
|
|
|
* @remarks
|
|
|
|
* This allows reacting not just to value changes at a certain pointer, but changes
|
|
|
|
* to the proxied pointer too.
|
|
|
|
*/
|
2021-06-18 13:05:06 +02:00
|
|
|
export default class PointerProxy<O extends {}>
|
2022-12-01 14:28:52 +01:00
|
|
|
implements IdentityPrismProvider
|
2021-06-18 13:05:06 +02:00
|
|
|
{
|
2022-01-19 13:06:13 +01:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
2022-12-01 14:28:52 +01:00
|
|
|
readonly $$isIdentityPrismProvider = true
|
2022-12-01 18:56:34 +01:00
|
|
|
private readonly _currentPointerBox: Atom<Pointer<O>>
|
2022-01-19 13:06:13 +01:00
|
|
|
/**
|
|
|
|
* Convenience pointer pointing to the root of this PointerProxy.
|
|
|
|
*
|
|
|
|
* @remarks
|
2022-12-01 14:26:17 +01:00
|
|
|
* Allows convenient use of {@link pointerToPrism} and {@link val}.
|
2022-01-19 13:06:13 +01:00
|
|
|
*/
|
2021-06-18 13:05:06 +02:00
|
|
|
readonly pointer: Pointer<O>
|
|
|
|
|
|
|
|
constructor(currentPointer: Pointer<O>) {
|
2022-12-01 18:56:34 +01:00
|
|
|
this._currentPointerBox = new Atom(currentPointer)
|
2021-06-18 13:05:06 +02:00
|
|
|
this.pointer = pointer({root: this as $FixMe, path: []})
|
|
|
|
}
|
|
|
|
|
2022-01-19 13:06:13 +01:00
|
|
|
/**
|
|
|
|
* Sets the underlying pointer.
|
2022-02-23 22:53:39 +01:00
|
|
|
* @param p - The pointer to be proxied.
|
2022-01-19 13:06:13 +01:00
|
|
|
*/
|
2021-06-18 13:05:06 +02:00
|
|
|
setPointer(p: Pointer<O>) {
|
|
|
|
this._currentPointerBox.set(p)
|
|
|
|
}
|
|
|
|
|
2022-01-19 13:06:13 +01:00
|
|
|
/**
|
2022-12-01 14:41:46 +01:00
|
|
|
* Returns a prism of the value at the provided sub-path of the proxied pointer.
|
2022-01-19 13:06:13 +01:00
|
|
|
*
|
2022-12-01 14:41:46 +01:00
|
|
|
* @param path - The path to create the prism at.
|
2022-01-19 13:06:13 +01:00
|
|
|
*/
|
2022-12-01 14:28:52 +01:00
|
|
|
getIdentityPrism(path: Array<string | number>) {
|
2022-11-26 15:00:14 +01:00
|
|
|
return prism(() => {
|
2022-12-01 14:41:46 +01:00
|
|
|
const currentPointer = this._currentPointerBox.prism.getValue()
|
2021-06-18 13:05:06 +02:00
|
|
|
const subPointer = path.reduce(
|
|
|
|
(pointerSoFar, pathItem) => (pointerSoFar as $IntentionalAny)[pathItem],
|
2022-11-26 15:00:14 +01:00
|
|
|
currentPointer,
|
2021-06-18 13:05:06 +02:00
|
|
|
)
|
2022-11-26 15:00:14 +01:00
|
|
|
return val(subPointer)
|
2021-06-18 13:05:06 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|