perf(quark): sync shared wrapper methods from standalone
Vendored sync of quark 15159e5: State and Computed wrappers share this-based set/update/subscribe methods through a node handle, cutting three closures per slot. Verified no opencode consumer detaches quark wrapper methods.
This commit is contained in:
parent
819522830b
commit
e374393e3c
1 changed files with 34 additions and 15 deletions
|
|
@ -19,19 +19,14 @@ export namespace State {
|
|||
subs: undefined,
|
||||
subsTail: undefined,
|
||||
}
|
||||
const read = (() => readState(node)) as Writable<A>
|
||||
read.set = (value) => writeState(node, value)
|
||||
read.update = (f) => {
|
||||
// Read untracked: calling update inside a tracked evaluation must not
|
||||
// make the caller depend on (and re-trigger from) this state.
|
||||
const previous = swapActiveSub(undefined)
|
||||
try {
|
||||
writeState(node, f(readState(node)))
|
||||
} finally {
|
||||
activeSub = previous
|
||||
}
|
||||
}
|
||||
read.subscribe = (listener) => subscribeNode(node, read, listener)
|
||||
// Methods are shared this-based functions rather than per-instance
|
||||
// closures: one callable and one node per state, and every call site
|
||||
// stays monomorphic on the shared method identity.
|
||||
const read = (() => readState(node)) as Writable<A> & Handle<StateNode<A>>
|
||||
read.node = node
|
||||
read.set = stateSet
|
||||
read.update = stateUpdate
|
||||
read.subscribe = sharedSubscribe
|
||||
return read
|
||||
}
|
||||
}
|
||||
|
|
@ -47,12 +42,36 @@ export namespace Computed {
|
|||
subs: undefined,
|
||||
subsTail: undefined,
|
||||
}
|
||||
const read = (() => readComputed(node)) as Readable<A>
|
||||
read.subscribe = (listener) => subscribeNode(node, read, listener)
|
||||
const read = (() => readComputed(node)) as Readable<A> & Handle<ComputedNode<A>>
|
||||
read.node = node
|
||||
read.subscribe = sharedSubscribe
|
||||
return read
|
||||
}
|
||||
}
|
||||
|
||||
interface Handle<Node> {
|
||||
node: Node
|
||||
}
|
||||
|
||||
function stateSet<A>(this: Handle<StateNode<A>>, value: A): void {
|
||||
writeState(this.node, value)
|
||||
}
|
||||
|
||||
function stateUpdate<A>(this: Handle<StateNode<A>>, f: (value: A) => A): void {
|
||||
// Read untracked: calling update inside a tracked evaluation must not
|
||||
// make the caller depend on (and re-trigger from) this state.
|
||||
const previous = swapActiveSub(undefined)
|
||||
try {
|
||||
writeState(this.node, f(readState(this.node)))
|
||||
} finally {
|
||||
activeSub = previous
|
||||
}
|
||||
}
|
||||
|
||||
function sharedSubscribe<A>(this: (() => A) & Handle<ReactiveNode>, listener: (value: A) => void): () => void {
|
||||
return subscribeNode(this.node, this, listener)
|
||||
}
|
||||
|
||||
export namespace Transaction {
|
||||
export function run<A>(f: () => A): A {
|
||||
batchDepth++
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue