failing test

This commit is contained in:
Víctor Oliva 2023-09-18 18:04:40 +02:00
parent 9696f9fb6d
commit 599f8d2ab2
2 changed files with 55 additions and 32 deletions

View File

@ -1,7 +1,7 @@
import { substate } from "./substate"
import { Subject } from "rxjs"
import { describe, expect, it } from "vitest"
import { createRoot } from "./create-root"
import { describe, it, expect } from "vitest"
import { Subject, of } from "rxjs"
import { substate } from "./substate"
import { subtree } from "./subtree"
describe("subtree", () => {
@ -22,4 +22,20 @@ describe("subtree", () => {
subnode$.next("b")
expect(otherRoot.getValue()).toEqual({ value: "b" })
})
it("the subtree can be referenced simultaneously", () => {
const mainRoot = createRoot()
const subnode$ = new Subject<string>()
const subnode = substate(mainRoot, () => subnode$)
const otherRootCopy = substate(subnode, (_, getObs$) => getObs$(otherRoot))
const otherRoot = createRoot().withTypes<{ value: string }>()
subtree(subnode, (ctx) => otherRoot.run(null, { value: ctx(subnode) }))
mainRoot.run()
subnode$.next("a")
expect(otherRootCopy.getValue()).toEqual({ value: "a" })
})
})

View File

@ -1,5 +1,10 @@
import { Observable } from "rxjs"
import { createStateNode, getInternals, trackParentChanges } from "./internal"
import {
NestedMap,
createStateNode,
getInternals,
trackParentChanges,
} from "./internal"
import {
GetObservableFn,
GetValueFn,
@ -17,36 +22,38 @@ export function subtree<K extends KeysBaseType>(
) => () => void,
): void {
const internalParent = getInternals(parent)
const stateNode = createStateNode(
internalParent.keysOrder,
[internalParent],
(getContext, getObservable, key) =>
new Observable(() =>
createInstance(
(node) => getContext(getInternals(node)),
(other, keys?: any) =>
getObservable(isSignal(other) ? other : getInternals(other), keys),
key,
),
const teardowns = new NestedMap<K[keyof K], () => void>()
const nestedMapKey = (key: K) => internalParent.keysOrder.map((k) => key[k])
const teardown = (key: K) => teardowns.get(nestedMapKey(key))?.()
const restart = (key: K) => {
teardown(key)
teardowns.set(
nestedMapKey(key),
createInstance(
(node) => internalParent.getContext(getInternals(node), key),
(other, keys?) => {
const mergedKey = {
...key,
...(keys ?? {}),
} as any
return isSignal(other)
? other.getSignal$(mergedKey)
: other.getState$(mergedKey)
},
key,
),
)
)
}
trackParentChanges(parent, {
onAdded(key) {
stateNode.addInstance(key)
},
onActive(key) {
stateNode.activateInstance(key)
},
onReset(key) {
stateNode.resetInstance(key)
stateNode.activateInstance(key)
},
onAfterChange(key) {
stateNode.activateInstance(key)
},
onRemoved(key) {
stateNode.removeInstance(key)
},
onAdded: () => {},
onActive: () => {},
// It starts when it has a value
// TODO Maybe there should be a way of "activating" roots without actually running!
// will have to review the API then
onAfterChange: restart,
onReset: restart,
onRemoved: teardown,
})
}