chore(quark): sync vendored quark with diff gating and codegen

This commit is contained in:
Kit Langton 2026-07-17 22:15:46 -04:00
commit 77dcae0968
4 changed files with 617 additions and 334 deletions

View file

@ -61,9 +61,12 @@ export namespace Keyed {
if (publish(slot, value)) changed = true if (publish(slot, value)) changed = true
return slot return slot
}) })
byKey.forEach((_slot, key) => { // After reconciliation byKey is a superset of retained; equal sizes
if (!retained.has(key)) byKey.delete(key) // mean no stale keys and the sweep can be skipped.
}) if (byKey.size !== retained.size)
byKey.forEach((_slot, key) => {
if (!retained.has(key)) byKey.delete(key)
})
if (!same(previous, reconciled)) { if (!same(previous, reconciled)) {
slots.set(reconciled) slots.set(reconciled)
if (options.metrics) options.metrics.structuralPublications++ if (options.metrics) options.metrics.structuralPublications++
@ -73,14 +76,13 @@ export namespace Keyed {
}) })
}, },
update(value) { update(value) {
const key = options.key(value) const slot = byKey.get(options.key(value))
const slot = byKey.get(key) if (!slot) return false
if (!slot) throw new Error(`Keyed value does not exist: ${String(key)}`)
return publish(slot, value) return publish(slot, value)
}, },
modify(key, f) { modify(key, f) {
const slot = byKey.get(key) const slot = byKey.get(key)
if (!slot) throw new Error(`Keyed value does not exist: ${String(key)}`) if (!slot) return false
const value = f(slot()) const value = f(slot())
if (byKey.get(options.key(value)) !== slot) throw new Error("Keyed modify must preserve the value key") if (byKey.get(options.key(value)) !== slot) throw new Error("Keyed modify must preserve the value key")
return publish(slot, value) return publish(slot, value)
@ -91,32 +93,33 @@ export namespace Keyed {
const current = slots() const current = slots()
const index = positionIndex(current, position) const index = positionIndex(current, position)
const slot = State.make(value) const slot = State.make(value)
Transaction.run(() => { // byKey is not reactive and slots.set is a single publication, so no
byKey.set(key, slot) // transaction is required here; callers batch when they need to.
slots.set(current.toSpliced(index, 0, slot)) byKey.set(key, slot)
if (options.metrics) options.metrics.structuralPublications++ slots.set(current.toSpliced(index, 0, slot))
}) if (options.metrics) options.metrics.structuralPublications++
return slot return slot
}, },
remove(key) { remove(key) {
const slot = byKey.get(key) const slot = byKey.get(key)
if (!slot) return false if (!slot) return false
Transaction.run(() => { byKey.delete(key)
byKey.delete(key) slots.set(slots().filter((candidate) => candidate !== slot))
slots.set(slots().filter((candidate) => candidate !== slot)) if (options.metrics) options.metrics.structuralPublications++
if (options.metrics) options.metrics.structuralPublications++
})
return true return true
}, },
move(key, position) { move(key, position) {
const slot = byKey.get(key) const slot = byKey.get(key)
if (!slot) throw new Error(`Keyed value does not exist: ${String(key)}`) if (!slot) return false
const current = slots() const current = slots()
const from = current.indexOf(slot) const from = current.indexOf(slot)
const target = positionIndex(current, position) const target = positionIndex(current, position)
const to = from < target ? target - 1 : target const to = from < target ? target - 1 : target
if (from === to) return false if (from === to) return false
slots.set(current.toSpliced(from, 1).toSpliced(to, 0, slot)) const next = current.slice()
next.splice(from, 1)
next.splice(to, 0, slot)
slots.set(next)
if (options.metrics) options.metrics.structuralPublications++ if (options.metrics) options.metrics.structuralPublications++
return true return true
}, },
@ -129,7 +132,8 @@ export namespace Keyed {
} }
function publish(slot: Writable<A>, value: A) { function publish(slot: Writable<A>, value: A) {
if (equivalent(slot(), value)) { const current = slot()
if (current === value || equivalent(current, value)) {
if (options.metrics) options.metrics.equivalenceSuppressions++ if (options.metrics) options.metrics.equivalenceSuppressions++
return false return false
} }
@ -152,7 +156,7 @@ export namespace Keyed {
function neighbor(key: Key, offset: -1 | 1) { function neighbor(key: Key, offset: -1 | 1) {
const slot = byKey.get(key) const slot = byKey.get(key)
if (!slot) throw new Error(`Keyed value does not exist: ${String(key)}`) if (!slot) return undefined
const current = slots() const current = slots()
return current[current.indexOf(slot) + offset] return current[current.indexOf(slot) + offset]
} }

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,14 @@ export namespace State {
const state = signal(initial) const state = signal(initial)
const read = (() => state()) as Writable<A> const read = (() => state()) as Writable<A>
read.set = (value) => state(value) read.set = (value) => state(value)
read.update = (f) => state(f(state())) read.update = (f) => {
// Read untracked: calling update inside an effect must not make the
// effect depend on (and re-trigger from) this signal.
const active = setActiveSub()
const current = state()
setActiveSub(active)
state(f(current))
}
read.subscribe = (listener) => subscribe(read, listener) read.subscribe = (listener) => subscribe(read, listener)
return read return read
} }

View file

@ -127,7 +127,7 @@ describe("Keyed", () => {
expect(keyed.slots()[1]).toBe(two) expect(keyed.slots()[1]).toBe(two)
expect(two()).toEqual(item(2, "TWO")) expect(two()).toEqual(item(2, "TWO"))
expect(structures).toEqual([]) expect(structures).toEqual([])
expect(() => keyed.update(item(3, "three"))).toThrow("Keyed value does not exist: 3") expect(keyed.update(item(3, "three"))).toBe(false)
dispose() dispose()
}) })
@ -142,7 +142,7 @@ describe("Keyed", () => {
expect(keyed.slots()[0]).toBe(slot) expect(keyed.slots()[0]).toBe(slot)
expect(slot()).toEqual(item(1, "ONE")) expect(slot()).toEqual(item(1, "ONE"))
expect(() => keyed.modify(1, (value) => ({ ...value, id: 2 }))).toThrow("Keyed modify must preserve the value key") expect(() => keyed.modify(1, (value) => ({ ...value, id: 2 }))).toThrow("Keyed modify must preserve the value key")
expect(() => keyed.modify(2, (value) => value)).toThrow("Keyed value does not exist: 2") expect(keyed.modify(2, (value) => value)).toBe(false)
}) })
it("checks key membership without reading the aggregate", () => { it("checks key membership without reading the aggregate", () => {