gesso-framework 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -0
- package/README.md +2 -0
- package/dist/ChannelProtocol-ByNoHujM.d.ts +247 -0
- package/dist/{FunctionComponent-CgwLKE5d.d.ts → FunctionComponent-fYMdePtH.d.ts} +3 -247
- package/dist/agent/index.d.ts +317 -0
- package/dist/agent/index.js +184 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/app-BvlIO1G9.js +326 -0
- package/dist/app-BvlIO1G9.js.map +1 -0
- package/dist/{index-C9FAI_Kt.d.ts → index-Sff7qPGU.d.ts} +400 -269
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1013 -97
- package/dist/index.js.map +1 -1
- package/dist/jsx/jsx-runtime.d.ts +1 -1
- package/dist/{persisted-CsTPnjkc.js → persisted-pix1fS1D.js} +6 -1
- package/dist/{persisted-CsTPnjkc.js.map → persisted-pix1fS1D.js.map} +1 -1
- package/dist/remote-xxij8zXe.js +600 -0
- package/dist/remote-xxij8zXe.js.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/ui-U39HjNFA.d.ts +517 -0
- package/dist/webmcp-CJVFvAHe.js +77 -0
- package/dist/webmcp-CJVFvAHe.js.map +1 -0
- package/dist/worker/index.d.ts +4 -2
- package/dist/worker/index.js +1 -1
- package/package.json +12 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persisted-CsTPnjkc.js","names":["isPlainObject","MAX_DEPTH","isPlainObject"],"sources":["../src/Input.ts","../src/InternalState.ts","../src/channel/structuralEquals.ts","../src/derive.ts","../src/computed.ts","../src/select.ts","../src/resource.ts","../src/mutate.ts","../src/debounce.ts","../src/channel/ChannelToken.ts","../src/channel/ChannelProtocol.ts","../src/channel/StorePatch.ts","../src/channel/plainData.ts","../src/channel/provide.ts","../src/app/NodeReport.ts","../src/worker/captureConsole.ts","../src/worker/WorkerPorts.ts","../src/channel/serveChannels.ts","../src/channel/pick.ts","../src/storage/StorageAdapter.ts","../src/undo/UndoStack.ts","../src/undo/undoable.ts","../src/storage/OpfsStorage.ts","../src/storage/IndexedDbStorage.ts","../src/storage/persisted.ts"],"sourcesContent":["import { BehaviorSubject, type Observable, Subject } from 'rxjs';\n\n/**\n * Reactive cell holding a component input.\n *\n * Inputs must be cells because render() runs exactly once. A component\n * that read a plain input value during render would capture it for the\n * life of the instance, so a parent supplying new props under a\n * dynamic subtree would update the field while the rendered tree kept\n * showing the original value.\n *\n * The cell is written by the component host only: it accepts whatever\n * the parent passed, subscribing it first when the parent passed an\n * Observable. `value` is deliberately read-only, so `this.label.value =\n * x` inside a component is a compile error rather than a silent\n * violation of the one-way data flow.\n */\nexport class InputCell<T> extends BehaviorSubject<T> {\n /**\n * What to call this cell in a warning: `Component.prop`, or\n * `channel.key`. Set by whoever creates it; a cell without one is\n * reported as \"a cell\".\n */\n label: string | undefined;\n /** The component whose body read `.value`, for the stale-read warning below. */\n private snapshotBy: string | null = null;\n private warnedStale = false;\n /** Everything emitted through `emit`, created on the first `events` read. */\n private emitted: Subject<unknown> | null = null;\n\n constructor(initialValue: T) {\n super(initialValue);\n }\n\n /**\n * Fires the output this cell stands for.\n *\n * An output is a cell whose value is what the parent gave to be\n * called: a function, or a target made by `into(subject)`. `emit`\n * calls it with the arguments, and also pushes the first argument\n * through `events`, so the component can fire from three places\n * without passing the cell around and a parent that wants a stream\n * can have one. A parent that passed nothing is fine: the call\n * simply reaches nobody.\n */\n emit(...args: EmitArgs<T>): void {\n const handler = super.getValue() as unknown;\n if (typeof handler === 'function') {\n (handler as (...values: unknown[]) => void)(...args);\n }\n this.emitted?.next(args[0]);\n }\n\n /** What `emit` has fired, as a stream: the first argument of each call. */\n get events(): Observable<EmitValue<T>> {\n if (this.emitted === null) {\n this.emitted = new Subject<unknown>();\n }\n return this.emitted.asObservable() as Observable<EmitValue<T>>;\n }\n\n override get value(): T {\n trackRead(this);\n // A read a `computed` is collecting is not the body's snapshot: the\n // computed follows this cell from here on and carries the change,\n // and a body that read the computed itself is the computed's own\n // stale watch to report. Recording it here as well warned, wrongly,\n // for a screen row whose `computed` input had let go with the row.\n if (bodyOf !== null && tracking === null && this.snapshotBy === null) {\n this.snapshotBy = bodyOf;\n }\n return super.getValue();\n }\n\n /**\n * The one place the run-once model goes quietly wrong is a body that\n * reads `props.x.value`, uses the value to build the tree, and never\n * hears that it changed. Nothing crashes; the screen is simply stale.\n * So a cell remembers being read while a body ran, and if it later\n * changes with nobody subscribed to it, it says so once. A cell that\n * something is following is fine: the follower carries the change.\n */\n override next(value: T): void {\n if (this.snapshotBy !== null && !this.warnedStale && !this.observed && !Object.is(value, super.getValue())) {\n this.warnedStale = true;\n warnStaleRead(this.snapshotBy, this.label, super.getValue(), value);\n }\n super.next(value);\n }\n}\n\n/** The component whose function body is running, while one is. */\nlet bodyOf: string | null = null;\n\n/** The component whose body is running, for a cell that wants to remember being read there. */\nexport function currentBody(): string | null {\n return bodyOf;\n}\n\n/**\n * Anything with a current value that can be followed: an input, an\n * internal state, a channel view key, a computed. What `computed`\n * collects as it runs.\n */\nexport interface ReadableCell<T> extends Observable<T> {\n readonly value: T;\n}\n\n/** The set a running `computed` is collecting its reads into, while one is. */\nlet tracking: Set<ReadableCell<unknown>> | null = null;\n\n/** Records a `.value` read for whatever `computed` is running, if one is. */\nexport function trackRead(cell: ReadableCell<unknown>): void {\n tracking?.add(cell);\n}\n\n/** Runs `run` with every `.value` read on the way recorded into `into`. */\nexport function withTracking<T>(into: Set<ReadableCell<unknown>>, run: () => T): T {\n const previous = tracking;\n tracking = into;\n try {\n return run();\n } finally {\n tracking = previous;\n }\n}\n\n/**\n * Runs a component's body with its name on record, so a `.value` read\n * inside it can be told apart from one in an event handler later, which\n * is the ordinary way to read the current value and warns about nothing.\n */\nexport function withBodyOf<T>(tag: string, run: () => T): T {\n const previous = bodyOf;\n bodyOf = tag;\n try {\n return run();\n } finally {\n bodyOf = previous;\n }\n}\n\nfunction warnStaleRead(tag: string, label: string | undefined, from: unknown, to: unknown): void {\n const what = label === undefined ? 'a cell' : `\\`${label}\\``;\n const change = describeChange(from, to);\n console.warn(\n `Component '${tag}' read ${what} with .value while its body ran, and nothing is following that cell. ` +\n `It has since changed ${change}, and whatever was built from the first value still shows it. ` +\n `A component body runs once: bind the cell instead (pass it, or pipe it, into the prop it feeds), ` +\n `or give the component a key so a new value builds a new one.`\n );\n}\n\n/**\n * \"from X to Y\", or for two plain objects the first field that differs,\n * because two objects that print alike for sixty characters say nothing\n * about what actually moved.\n */\nfunction describeChange(from: unknown, to: unknown): string {\n if (isPlainObject(from) && isPlainObject(to)) {\n for (const key of new Set([...Object.keys(from), ...Object.keys(to)])) {\n const before = from[key];\n const after = to[key];\n if (!Object.is(before, after) && safeJson(before) !== safeJson(after)) {\n return `at .${key}, from ${describe(before)} to ${describe(after)}`;\n }\n }\n return 'to an equal-looking object';\n }\n return `from ${describe(from)} to ${describe(to)}`;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction describe(value: unknown): string {\n let text: string;\n try {\n text = typeof value === 'function' ? 'a function' : (JSON.stringify(value) ?? String(value));\n } catch {\n text = String(value);\n }\n return text.length > 60 ? `${text.slice(0, 57)}...` : text;\n}\n\n/**\n * Creates a component input cell.\n *\n * Inside a class component the argument is the default the cell holds\n * until the parent supplies a value:\n *\n * @Input() label = input('Count');\n *\n * Inside a functional component the props are already cells; the\n * two-argument form derives a cell that replaces `undefined` with a\n * fallback, which is how an optional prop gets its default:\n *\n * function Counter(inputs: Inputs<{ label?: string }>) {\n * const label = input(inputs.label, 'Count'); // InputCell<string>\n * return Text({ text: label });\n * }\n *\n * The derived cell follows the source for the life of the component\n * and completes when the source does, so it needs no teardown.\n */\nexport function input<T>(initialValue: T): InputCell<T>;\nexport function input<T>(source: InputCell<T | undefined>, fallback: T): InputCell<T>;\nexport function input<T>(first: T | InputCell<T | undefined>, fallback?: T): InputCell<T> {\n if (arguments.length < 2 || !(first instanceof InputCell)) {\n return new InputCell(first as T);\n }\n const source = first as InputCell<T | undefined>;\n const withFallback = (value: T | undefined): T => (value === undefined ? (fallback as T) : value);\n const derived = new InputCell<T>(withFallback(source.value));\n derived.label = source.label;\n source.subscribe({\n next: value => derived.next(withFallback(value)),\n complete: () => derived.complete()\n });\n return derived;\n}\n\n/** The arguments `emit` takes for a cell holding a handler of type `T`. */\nexport type EmitArgs<T> = NonNullable<T> extends (...args: infer A) => void ? A : never;\n\n/** What `events` carries for a cell holding a handler of type `T`: the handler's first argument. */\nexport type EmitValue<T> = NonNullable<T> extends (first: infer V, ...rest: never[]) => void ? V : void;\n\n/**\n * A component's output: an input cell that holds whatever the parent\n * gave to be called, fired through `emit`. Every function-typed member\n * of a component's inputs is one, so on a component declared with\n * `onOpen: (id: string) => void`, `inputs.onOpen.emit(id)` is how the\n * component speaks, and a parent may pass a function or `into(subject)`.\n * The name is for a class field: `@Output() changed = output<[number]>()`.\n */\nexport type OutputCell<A extends unknown[]> = InputCell<((...args: A) => void) | undefined>;\n\n/**\n * An output a class component declares as a field:\n *\n * @Output() changed = output<[value: number]>();\n *\n * The host wires the parent's handler into it exactly as it wires an\n * input, and `this.changed.emit(next)` fires it.\n */\nexport function output<A extends unknown[]>(): OutputCell<A> {\n return new InputCell<((...args: A) => void) | undefined>(undefined);\n}\n\nconst OUTPUT_TARGET: unique symbol = Symbol('gesso:output-target');\n\n/**\n * A parent's way of receiving an output as a stream rather than a call:\n *\n * const opened = new Subject<string>();\n * <Card onOpen={into(opened)} />\n *\n * Wrapped rather than passed bare, because a bare `Subject` is an\n * Observable and would be read as an *input* the parent is feeding the\n * child, which is the opposite direction.\n */\nexport interface OutputTarget<V> {\n readonly [OUTPUT_TARGET]: { next(value: V): void };\n}\n\nexport function into<V>(target: { next(value: V): void }): OutputTarget<V> {\n return { [OUTPUT_TARGET]: target };\n}\n\nexport function isOutputTarget(value: unknown): value is OutputTarget<unknown> {\n return typeof value === 'object' && value !== null && OUTPUT_TARGET in value;\n}\n\n/** The receiver an `into()` target wraps. */\nexport function outputTargetOf<V>(target: OutputTarget<V>): { next(value: V): void } {\n return target[OUTPUT_TARGET];\n}\n","import { BehaviorSubject } from 'rxjs';\nimport { trackRead } from './Input';\n\n/**\n * A component's own state: originated here, and never crossing the\n * barrier.\n *\n * The writable counterpart to `InputCell`. The two are the same\n * `BehaviorSubject` and differ by one accessor — this one has a\n * `.value` setter — and that difference is the whole semantics:\n *\n * internalState() never crosses I write it\n * input() crosses inward someone else writes it\n *\n * Named on that axis deliberately. It used to be `state()`, which\n * described *what* a thing was while `input()` described *where it\n * came from*; two names on two axes made neither of them tell you\n * anything about the other. `internalState(products)` reads as a\n * mistake at the call site in a way `state(products)` never did.\n *\n * For values that originate on this thread and die with the component:\n * a tooltip's open flag, a caret, a scroll offset, the active tab.\n * Anything that survives a reload, or that another screen cares about,\n * is application state and belongs on a channel. Anything derived from\n * other cells is a `computed`.\n *\n * It is not only for components. The thread that owns a channel's data\n * writes cells too, and wrote them as a `BehaviorSubject` mirrored\n * into an `asObservable()` because this was reachable only through the\n * framework's main entry. `gesso-framework/worker` is the same cell\n * with none of the renderer behind it, so an application worker holds\n * one cell rather than a subject and a copy of it, and reads it with\n * `.value` in a `computed` rather than listing it in a\n * `combineLatest`. \"Internal\" still means what it says there: written\n * here, and crossing the barrier only as the plain data a view key\n * publishes.\n */\nexport class InternalState<T> extends BehaviorSubject<T> {\n /** What to call this cell in a warning or the inspector; optional. */\n label: string | undefined;\n constructor(initialValue: T) {\n super(initialValue);\n }\n\n override get value(): T {\n trackRead(this);\n return super.getValue();\n }\n\n override set value(next: T) {\n this.next(next);\n }\n}\n\n/**\n * Creates a reactive state cell.\n *\n * Usage inside a component:\n *\n * private readonly count = state(0);\n *\n * increment() {\n * this.count.value++;\n * }\n */\nexport function internalState<T>(initialValue: T, label?: string): InternalState<T> {\n const state = new InternalState(initialValue);\n if (label !== undefined) {\n state.label = label;\n }\n return state;\n}\n","/**\n * Deep comparison for store read models.\n *\n * Projections and selectors allocate a fresh value on every\n * evaluation, so reference equality reports a change on every\n * unrelated state emission. That invalidates bindings and dirties\n * nodes across the whole tree for state the view never read.\n *\n * Scope is deliberately narrow: primitives, arrays, and plain objects\n * — what a projection is allowed to return. Anything else (class\n * instances, Date, Map, Set, functions) compares by reference, which\n * is conservative: it reports a change, so the UI updates when it did\n * not need to rather than failing to update when it did.\n *\n * The same comparison becomes the equality half of the patch differ\n * in Phase E, so a store behaves identically local or remote.\n */\nconst MAX_DEPTH = 100;\n\nexport function structurallyEqual<T>(a: T, b: T): boolean {\n return compare(a, b, 0);\n}\n\nfunction compare(a: unknown, b: unknown, depth: number): boolean {\n if (Object.is(a, b)) {\n return true;\n }\n if (depth > MAX_DEPTH) {\n // Deeper than any sane view model, or cyclic. Report \"changed\"\n // rather than risk a non-terminating walk.\n return false;\n }\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {\n return false;\n }\n\n const aIsArray = Array.isArray(a);\n if (aIsArray !== Array.isArray(b)) {\n return false;\n }\n\n if (aIsArray) {\n const left = a as unknown[];\n const right = b as unknown[];\n if (left.length !== right.length) {\n return false;\n }\n for (let i = 0; i < left.length; i++) {\n if (!compare(left[i], right[i], depth + 1)) {\n return false;\n }\n }\n return true;\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) {\n return false;\n }\n\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n const leftKeys = Object.keys(left);\n if (leftKeys.length !== Object.keys(right).length) {\n return false;\n }\n for (const key of leftKeys) {\n if (!Object.prototype.hasOwnProperty.call(right, key)) {\n return false;\n }\n if (!compare(left[key], right[key], depth + 1)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Objects created from an object literal or a null prototype. Class\n * instances are excluded so they keep reference semantics.\n */\nfunction isPlainObject(value: object): boolean {\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","import { combineLatest, distinctUntilChanged, map, type Observable } from 'rxjs';\n\nimport { structurallyEqual } from './channel/structuralEquals';\n\n/** How `derive` decides that a new value is not a change. */\nexport type Equality<T> = 'reference' | 'structural' | ((a: T, b: T) => boolean);\n\nexport interface DeriveOptions<T> {\n /**\n * `reference` (the default) is `Object.is`; `structural` compares\n * plain data by content, so a projection that builds a fresh object\n * of the same shape does not re-bind everything reading it; a\n * function is your own rule.\n */\n readonly equal?: Equality<T>;\n}\n\ntype Values<S extends readonly Observable<unknown>[]> = {\n [K in keyof S]: S[K] extends Observable<infer V> ? V : never;\n};\n\n/**\n * One value from several, kept equal to `project` of the latest of each\n * source, and emitted only when it changes.\n *\n * This is `combineLatest(...).pipe(map(...), distinctUntilChanged())`,\n * which is what nearly every derived binding in a component body wants\n * and what nearly every one had to write out. Sources are cells or any\n * Observables; the result is what a prop takes.\n *\n * const playing = derive([queue.view.playlistId, audio.state], (id, state) =>\n * id === card.id && state.status === 'playing'\n * );\n *\n * @deprecated Write it as a `computed`, which is the one derivation the\n * documentation teaches. A cell is read with\n * `.value` and anything else through the `read` the function is handed,\n * so the sources are the reads themselves and there is no list beside\n * the expression to keep in step with it:\n *\n * const playing = computed(read =>\n * queue.view.playlistId.value === card.id && read(audio.state).status === 'playing'\n * );\n *\n * It still works and nothing that uses it needs changing today.\n */\nexport function derive<S extends readonly Observable<unknown>[], T>(\n sources: readonly [...S],\n project: (...values: Values<S>) => T,\n options: DeriveOptions<T> = {}\n): Observable<T> {\n const equal = equalityOf(options.equal ?? 'reference');\n return combineLatest(sources as unknown as Observable<unknown>[]).pipe(\n map(values => project(...(values as Values<S>))),\n distinctUntilChanged(equal)\n );\n}\n\n/** The comparison an `Equality` names. Shared with `computed`. */\nexport function equalityOf<T>(equal: Equality<T>): (a: T, b: T) => boolean {\n if (equal === 'reference') {\n return Object.is;\n }\n if (equal === 'structural') {\n return (a, b) => structurallyEqual(a, b);\n }\n return equal;\n}\n","import { Observable, Subject, Subscription } from 'rxjs';\nimport { equalityOf, type Equality } from './derive';\nimport { currentBody, trackRead, withTracking, type ReadableCell } from './Input';\n\nexport interface ComputedOptions<T> {\n /** How a new result is judged unchanged; `reference` by default. */\n readonly equal?: Equality<T>;\n /** What to call this cell in a warning. */\n readonly label?: string;\n}\n\n/**\n * Reads a stream that is not a cell, inside a `computed`.\n *\n * A cell is read with `.value`; a plain Observable has no current value\n * to read, so the function is handed this instead:\n *\n * const playing = computed(read => read(audio.actions) === 'play');\n *\n * It answers with the stream's latest value and records the stream as a\n * source, so the computed follows it exactly as it follows a cell. A\n * cell passed to it is simply read, which means one call site works for\n * either and a service that later turns a stream into a cell breaks\n * nothing.\n */\nexport type ReadSource = <V>(source: Observable<V>) => V;\n\n/**\n * A cell whose value is a function of other cells.\n *\n * `computed(() => quantity.value * price.value)` reads like the value it\n * is. The cells its function reads through `.value` are its sources,\n * found by running the function and watching what it touches, so there\n * is no list to keep in step with the expression; a read the function\n * did not make this time is a source it no longer has.\n *\n * A stream that is not a cell is read through the `read` the function\n * is handed: `computed(read => read(stream).status)` follows the stream\n * as it follows a cell. That is what makes this the only derivation an\n * application needs, whether or not the thing it derives from happens\n * to have a current value of its own.\n *\n * It is a cell and nothing else. Bound to a prop it is an Observable\n * like every other cell, so a component written with it and one written\n * with `pipe` compose without translation. Read in a handler with\n * `.value` it is the current result, computed on the spot if nothing is\n * following it. RxJS is underneath and nothing here replaces it.\n *\n * Nothing runs until someone asks. With no subscriber the function runs\n * only when `.value` is read; with one, the cell follows its sources and\n * emits a result when it differs from the last by `equal`. When the last\n * subscriber leaves it lets go of its sources, so a computed made in a\n * component body dies with the component's bindings and needs no\n * disposal of its own.\n *\n * Reading it with `.value` while a component body runs is the same\n * snapshot an input read there is, and it warns the same way: once, if\n * it later changes with nobody following.\n */\nexport class ComputedCell<T> extends Observable<T> implements ReadableCell<T> {\n label: string | undefined;\n private readonly equal: (a: T, b: T) => boolean;\n private readonly changes = new Subject<T>();\n private sources = new Set<ReadableCell<unknown>>();\n private cached!: T;\n private hasValue = false;\n private upstream: Subscription | null = null;\n private subscribers = 0;\n private attaching = false;\n private snapshotBy: string | null = null;\n private warnedStale = false;\n /** Follows the sources after a body read, only to notice the change the body will not. */\n private staleWatch: Subscription | null = null;\n\n constructor(\n private readonly compute: (read: ReadSource) => T,\n options: ComputedOptions<T> = {}\n ) {\n super(subscriber => {\n this.subscribers++;\n // A follower makes the body-read watch moot: the change reaches the screen.\n this.staleWatch?.unsubscribe();\n this.staleWatch = null;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.cached);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.subscribers--;\n if (this.subscribers === 0) {\n this.detach();\n }\n };\n });\n this.equal = equalityOf(options.equal ?? 'reference');\n this.label = options.label;\n }\n\n /** The current result: kept by the sources while followed, computed now when not. */\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n this.recompute();\n }\n const body = currentBody();\n if (body !== null && this.snapshotBy === null) {\n this.snapshotBy = body;\n this.watchForStaleRead();\n }\n return this.cached;\n }\n\n /**\n * A body read the value once; if a source now changes with nothing\n * following this cell, the screen built from that read is stale and\n * nobody would know. So the sources are watched for exactly that, and\n * the watch ends with the warning or with a real subscriber arriving.\n */\n private watchForStaleRead(): void {\n this.staleWatch = new Subscription();\n let settling = true;\n for (const source of this.sources) {\n this.staleWatch.add(\n source.subscribe(() => {\n if (settling || this.observed) {\n return;\n }\n if (this.recompute()) {\n this.warnStale();\n this.staleWatch?.unsubscribe();\n this.staleWatch = null;\n }\n })\n );\n }\n settling = false;\n }\n\n private warnStale(): void {\n if (this.snapshotBy === null || this.warnedStale) {\n return;\n }\n this.warnedStale = true;\n console.warn(\n `Component '${this.snapshotBy}' read ${this.label === undefined ? 'a computed cell' : `\\`${this.label}\\``} with .value while its body ran, ` +\n `and nothing is following that cell. It has since changed, and whatever was built from the first value still shows it. ` +\n `A component body runs once: bind the cell instead.`\n );\n }\n\n /** Whether anything is following this cell; the stale-read warning's question. */\n get observed(): boolean {\n return this.subscribers > 0;\n }\n\n /** Runs the function, watching what it reads; true when the result changed. */\n private recompute(): boolean {\n const touched = new Set<ReadableCell<unknown>>();\n const next = withTracking(touched, () => this.compute(readSource));\n this.sources = touched;\n const changed = !this.hasValue || !this.equal(this.cached, next);\n this.hasValue = true;\n this.cached = next;\n return changed;\n }\n\n /** Follows the current sources, re-running on any change to them. */\n private attach(): void {\n this.attaching = true;\n this.recompute();\n this.upstream = new Subscription();\n for (const source of this.sources) {\n this.upstream.add(source.subscribe(() => this.onSourceChanged()));\n }\n this.attaching = false;\n }\n\n private detach(): void {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n\n private onSourceChanged(): void {\n if (this.attaching) {\n return; // a cell replays its current value on subscribe; that is not a change\n }\n const before = new Set(this.sources);\n const changed = this.recompute();\n if (!sameSet(before, this.sources)) {\n // The function read different cells this time: follow those.\n this.detach();\n this.attaching = true;\n this.upstream = new Subscription();\n for (const source of this.sources) {\n this.upstream.add(source.subscribe(() => this.onSourceChanged()));\n }\n this.attaching = false;\n }\n if (changed) {\n this.changes.next(this.cached);\n }\n }\n}\n\n/**\n * A cell computed from what its function reads. See `ComputedCell`.\n *\n * const total = computed(() => quantity.value * PRICE * RATES[currency.value]);\n * <text text={computed(() => String(count.value))} />\n *\n * Cells are read with `.value`; anything else is read through the\n * `read` the function is given, which follows it the same way:\n *\n * const late = computed(read => read(clock) > deadline);\n */\nexport function computed<T>(compute: (read: ReadSource) => T, options: ComputedOptions<T> = {}): ComputedCell<T> {\n return new ComputedCell(compute, options);\n}\n\n/**\n * The cell standing for a stream, one per stream.\n *\n * Anything that already has a current value is its own cell, so a\n * `read` of an input, an internal state or another computed costs a\n * property access and nothing more. Everything else gets a `StreamCell`\n * held against it here, so several computeds reading one stream share a\n * single subscription to it rather than opening one each.\n *\n * Weak on purpose: the entry is reachable only while the stream is, so\n * a stream made in a component body is collected with the component.\n */\nconst streamCells = new WeakMap<Observable<unknown>, StreamCell<unknown>>();\n\n/**\n * Whether a source's `.value` announces itself to the running computed,\n * decided once per source and remembered.\n *\n * Having a `value` is not enough. A framework cell records its reads\n * through `trackRead`, which is what lets a computed learn what it\n * depends on; a plain `BehaviorSubject` has a `value` too and records\n * nothing, so a computed that trusted the property would read it once\n * and never hear it change. That is exactly what happened to three\n * data-layer specs that fed a raw subject where the application feeds\n * a channel view. The probe reads `.value` once under a tracking set\n * of its own and asks whether the source turned up in it.\n */\nconst tracksReads = new WeakMap<Observable<unknown>, boolean>();\n\nfunction announcesItsReads(source: ReadableCell<unknown>): boolean {\n let known = tracksReads.get(source);\n if (known === undefined) {\n const seen = new Set<ReadableCell<unknown>>();\n withTracking(seen, () => void source.value);\n known = seen.has(source);\n tracksReads.set(source, known);\n }\n return known;\n}\n\nfunction cellFor<T>(source: Observable<T>): ReadableCell<T> {\n if ('value' in source && announcesItsReads(source as ReadableCell<T>)) {\n return source as ReadableCell<T>;\n }\n let cell = streamCells.get(source as Observable<unknown>);\n if (cell === undefined) {\n cell = new StreamCell(source as Observable<unknown>);\n streamCells.set(source as Observable<unknown>, cell);\n }\n return cell as ReadableCell<T>;\n}\n\n/** The `read` every computed's function is handed. */\nconst readSource: ReadSource = <V>(source: Observable<V>): V => cellFor(source).value;\n\n/**\n * A plain stream, seen as a cell.\n *\n * It holds the last value it saw and hands it to whoever asks, which is\n * the one thing a cell has and an Observable does not. While something\n * follows it, it follows the stream; when the last follower leaves it\n * lets go, so it costs nothing between uses and needs no disposal, on\n * the same terms as `ComputedCell`.\n *\n * A `.value` read with nothing following takes one synchronous\n * subscription and drops it again, which is how a `BehaviorSubject`\n * behind an `asObservable()`, or a `combineLatest` over such subjects,\n * answers with what it already holds. A stream that has nothing to say\n * synchronously answers `undefined` until its first emission arrives,\n * which is the honest answer: there is no value yet.\n */\nclass StreamCell<T> extends Observable<T> implements ReadableCell<T> {\n private last!: T;\n private followers = 0;\n private upstream: Subscription | null = null;\n private readonly changes = new Subject<T>();\n\n constructor(private readonly stream: Observable<T>) {\n super(subscriber => {\n this.followers++;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.last);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.followers--;\n if (this.followers === 0) {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n };\n });\n }\n\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n const asking = this.stream.subscribe(value => {\n this.last = value;\n });\n asking.unsubscribe();\n }\n return this.last;\n }\n\n private attach(): void {\n this.upstream = this.stream.subscribe(value => {\n this.last = value;\n this.changes.next(value);\n });\n }\n}\n\nfunction sameSet<T>(a: ReadonlySet<T>, b: ReadonlySet<T>): boolean {\n if (a.size !== b.size) {\n return false;\n }\n for (const item of a) {\n if (!b.has(item)) {\n return false;\n }\n }\n return true;\n}\n","import type { Observable } from 'rxjs';\n\nimport { computed, type ComputedCell } from './computed';\nimport type { Equality } from './derive';\n\nexport interface SelectOptions<T> {\n /**\n * How a projected value is judged unchanged; `structural` by default,\n * because a projection nearly always builds a value rather than\n * passing one through, and a rebuilt equal one is not a change.\n */\n readonly equal?: Equality<T>;\n /** What to call the cell in a warning. */\n readonly label?: string;\n}\n\n/**\n * One field of a cell, or one projection of it, as a cell.\n *\n * const title = select(inputs.track, 'title');\n * const names = select(inputs.track, entry => entry?.tags ?? []);\n *\n * Reading four fields of one input costs four of these rather than four\n * `pipe(map(...), distinctUntilChanged(...))`, which is what the two\n * applications wrote by hand often enough to invent their own `field()`\n * and `text()` helpers for it.\n *\n * The source may be any Observable, not only a cell: `select` is a\n * `computed` over one source, and reads it the way a computed reads\n * anything. The comparison is structural by default, since the reason\n * for nearly every hand-written comparator is exactly this: a\n * projection that rebuilds an equal array or object each time should\n * not re-bind everything reading it.\n *\n * There is no `inputs.track.title` proxy. A cell is an Observable, so\n * its own members (`value`, `pipe`, `subscribe`, `source`) would shadow\n * the fields of anything projected through it, and a data type that\n * happens to have a field called `value` would read as the cell's\n * current value instead. `select` names the field explicitly and cannot\n * collide.\n */\nexport function select<T extends object, K extends keyof T>(\n source: Observable<T>,\n key: K,\n options?: SelectOptions<T[K]>\n): ComputedCell<T[K]>;\nexport function select<T, R>(\n source: Observable<T>,\n project: (value: T) => R,\n options?: SelectOptions<R>\n): ComputedCell<R>;\nexport function select(\n source: Observable<unknown>,\n keyOrProject: PropertyKey | ((value: unknown) => unknown),\n options: SelectOptions<unknown> = {}\n): ComputedCell<unknown> {\n const project =\n typeof keyOrProject === 'function'\n ? keyOrProject\n : // A stream that has not spoken yet has no value to read a field\n // off, and neither has a source that is legitimately null. Both\n // answer `undefined` rather than throwing on the first frame.\n (value: unknown) =>\n value === null || value === undefined ? undefined : (value as Record<PropertyKey, unknown>)[keyOrProject];\n return computed(read => project(read(source)), {\n equal: options.equal ?? 'structural',\n ...(options.label === undefined ? {} : { label: options.label })\n });\n}\n","import { Subscription, type Observable } from 'rxjs';\n\nimport type { ComputedCell } from './computed';\nimport type { ReadableCell } from './Input';\nimport { internalState, type InternalState } from './InternalState';\nimport { select } from './select';\n\n/**\n * What a request has come to, in the five words every screen needs.\n *\n * Chosen once so screens stop inventing them. The tree had three\n * enums saying nearly the same thing in different words\n * (`'loading' | 'ready' | 'empty' | 'failed'`,\n * `'idle' | 'loading' | 'ready' | 'missing' | 'failed'`,\n * `'idle' | 'searching' | 'done' | 'failed'`), which meant a screen\n * reading two of them had two vocabularies for one idea.\n *\n * - `idle`: nothing has been asked for. The key is `null`.\n * - `loading`: a request is out and there is nothing to show yet.\n * - `ready`: there is a value. A refresh may still be in the air, and\n * that is deliberately not a separate status: what is on screen is\n * real, and saying \"loading\" over it would be a lie.\n * - `missing`: the answer was that there is no such thing. A fetch\n * says so by resolving `null`.\n * - `failed`: the request could not be answered at all.\n *\n * `missing` and `failed` are reported only when there is nothing to\n * fall back on. A refresh that fails over a value already held leaves\n * it on screen and stays `ready`, because a stale answer is stale and\n * not wrong, and an empty page would be worse. The error is still\n * there to read.\n *\n * What is *not* here is `empty`. A list that loaded and has no rows is\n * `ready` with an empty array, which is a judgement about the value\n * rather than about the request, and the screen that cares makes it.\n */\nexport type ResourceStatus = 'idle' | 'loading' | 'ready' | 'missing' | 'failed';\n\n/**\n * A resource as one record, so it can be a channel view key.\n *\n * Plain data throughout: the error is its message rather than the\n * `Error`, because a message is what a screen shows and what survives\n * the barrier, and an `Error` is neither.\n */\nexport interface ResourceState<T> {\n readonly status: ResourceStatus;\n readonly value: T | null;\n readonly error: string | null;\n}\n\nexport interface ResourceOptions<K, T> {\n /**\n * What is already known for this key, shown at once while the\n * request runs behind it.\n *\n * This is the store-first rule in one function: a hit is on screen\n * synchronously and marked `ready` even though a request is on its\n * way, so a page opened twice is instant the second time and correct\n * a moment later. Answering `null` or `undefined` means nothing is\n * held, and the resource says `loading`.\n */\n readonly peek?: (key: K) => T | null | undefined;\n /** What to call this resource in a warning; optional. */\n readonly label?: string;\n}\n\n/**\n * A request, keyed, so a stale answer cannot win.\n *\n * The key says what to fetch, and every value the key source emits is\n * a request. An answer is published only if its request is still the\n * current one, which is the generation counter every screen that loads\n * anything was writing by hand, and the reason opening a page, going\n * back and opening another before the first answers does not end with\n * the first answer on screen.\n *\n * private readonly ref = internalState<PageRef | null>(null);\n * readonly page = resource(this.ref, ref => api.trackPage(ref));\n *\n * show(ref: PageRef | null): Promise<void> {\n * this.ref.value = ref;\n * return this.page.settled;\n * }\n *\n * A `null` key is \"nothing is being asked for\": the status is `idle`,\n * the value is `null`, and no fetch runs. That is what a screen showing\n * nothing yet actually means, and it saves every caller a branch.\n *\n * Unlike `computed`, a resource is eager: it follows its key from the\n * moment it is made, because a request is an effect and an effect that\n * waits for a subscriber is a request that never happens. It takes one\n * subscription to the key source for its whole life, however many\n * requests run through it, and `dispose()` gives that back.\n *\n * It is a helper and not a data layer. Nothing in the framework\n * requires one, a channel is reached exactly as it was, and an\n * application that would rather write its own is writing against the\n * same barrier this is written against.\n */\nexport class Resource<K, T> {\n /** The one cell everything else here is a projection of. */\n private readonly cell: InternalState<ResourceState<T>>;\n /** Bumped per request; an answer from an older one is dropped. */\n private requests = 0;\n private asked: K | null = null;\n private settling: Promise<void> = Promise.resolve();\n private readonly following: Subscription;\n\n /** Status, value and error as one record: what a channel view key takes. */\n readonly state: ReadableCell<ResourceState<T>>;\n readonly status: ComputedCell<ResourceStatus>;\n /** What is loaded, or `null` while there is nothing to show. */\n readonly value: ComputedCell<T | null>;\n /** Why the last request failed, as its message; `null` when it did not. */\n readonly error: ComputedCell<string | null>;\n\n constructor(\n key: Observable<K | null | undefined>,\n private readonly fetch: (key: K) => Promise<T | null>,\n private readonly options: ResourceOptions<K, T> = {}\n ) {\n this.cell = internalState<ResourceState<T>>({ status: 'idle', value: null, error: null }, options.label);\n this.state = this.cell;\n this.status = select(this.cell, 'status', named(options.label, 'status'));\n // Compared by identity rather than structurally: a fetch builds a\n // new value every time, and walking a page-sized object to\n // discover that is exactly the cost the differ already pays once.\n this.value = select(this.cell, 'value', { ...named(options.label, 'value'), equal: 'reference' });\n this.error = select(this.cell, 'error', named(options.label, 'error'));\n this.following = key.subscribe(next => this.request(next ?? null));\n }\n\n /** What is being asked for, for a caller that needs to guard on it. */\n get requested(): K | null {\n return this.asked;\n }\n\n /**\n * The request in the air, as a promise that resolves when it settles.\n *\n * Already resolved when nothing is in flight, so a caller that sets\n * the key and returns this reads as an ordinary async method. Each\n * request keeps its own promise, so a dropped one still resolves for\n * whoever is awaiting it; it simply changes nothing on the way.\n */\n get settled(): Promise<void> {\n return this.settling;\n }\n\n /**\n * Asks again for the same key, keeping what is on screen.\n *\n * This is the retry button. It does not clear the value the way a\n * new key does, because a person pressing retry is asking for the\n * thing they can already see to be brought up to date, and blanking\n * it first would be a worse answer than the stale one.\n */\n retry(): Promise<void> {\n if (this.asked === null) {\n return this.settling;\n }\n const generation = ++this.requests;\n const held = this.cell.value;\n if (held.value === null && held.status !== 'loading') {\n this.write({ status: 'loading', value: null, error: null });\n }\n this.settling = this.run(this.asked, generation);\n return this.settling;\n }\n\n /**\n * Replaces what is loaded, for a change made here rather than\n * fetched.\n *\n * A page of comments appended to the answer already held, an\n * optimistic edit: the resource holds the value, so something has to\n * be able to write it. It does not touch the request in flight, so a\n * refresh that lands afterwards still wins, which is what it should\n * do: it is the newer truth.\n */\n set(value: T): void {\n this.write({ status: 'ready', value, error: null });\n }\n\n /** Gives back the subscription to the key source. */\n dispose(): void {\n this.following.unsubscribe();\n }\n\n private request(key: K | null): void {\n this.asked = key;\n const generation = ++this.requests;\n if (key === null) {\n this.write({ status: 'idle', value: null, error: null });\n this.settling = Promise.resolve();\n return;\n }\n const held = this.options.peek?.(key) ?? null;\n this.write({ status: held === null ? 'loading' : 'ready', value: held, error: null });\n this.settling = this.run(key, generation);\n }\n\n private run(key: K, generation: number): Promise<void> {\n return this.fetch(key).then(\n answer => this.answered(generation, answer),\n (error: unknown) => this.refused(generation, error)\n );\n }\n\n private answered(generation: number, answer: T | null): void {\n if (generation !== this.requests) {\n return;\n }\n if (answer === null) {\n const held = this.cell.value.value;\n this.write({ status: held === null ? 'missing' : 'ready', value: held, error: null });\n return;\n }\n this.write({ status: 'ready', value: answer, error: null });\n }\n\n private refused(generation: number, error: unknown): void {\n if (generation !== this.requests) {\n return;\n }\n const held = this.cell.value.value;\n this.write({ status: held === null ? 'failed' : 'ready', value: held, error: messageOf(error) });\n }\n\n private write(next: ResourceState<T>): void {\n this.cell.value = next;\n }\n}\n\n/**\n * A keyed request with a status, a value, an error and a retry.\n *\n * const page = resource(ref, key => api.page(key), { peek: key => store.get(key) });\n * <Show when={computed(() => page.status.value === 'loading')}>{() => <Spinner />}</Show>\n *\n * See `Resource` for what each status means and when a stale value is\n * kept. The key is an Observable so that setting a cell is what asks\n * for something: `computed` and `internalState` both work, and so does\n * a channel view key or a router match.\n */\nexport function resource<K, T>(\n key: Observable<K | null | undefined>,\n fetch: (key: K) => Promise<T | null>,\n options: ResourceOptions<K, T> = {}\n): Resource<K, T> {\n return new Resource(key, fetch, options);\n}\n\nfunction named(base: string | undefined, part: string): { label?: string } {\n return base === undefined ? {} : { label: `${base}.${part}` };\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { equalityOf, type Equality } from './derive';\nimport type { ReadableCell } from './Input';\nimport { internalState, type InternalState } from './InternalState';\n\nexport interface MutateOptions<T> {\n /**\n * How the rollback decides the cell still holds what was applied;\n * `structural` by default, because an optimistic change nearly\n * always builds a new list or a new record rather than passing one\n * through, so identity would never match and nothing would ever roll\n * back.\n */\n readonly equal?: Equality<T>;\n /** What to call the in-flight count in a warning; optional. */\n readonly label?: string;\n}\n\n/** A change that is made locally at once and confirmed afterwards. */\nexport interface Mutation<A> {\n /**\n * How many writes are in the air, for a saving indicator.\n *\n * A count rather than a flag, because two presses in quick\n * succession are two writes and a flag cleared by the first would\n * say the second had finished.\n */\n readonly pending: ReadableCell<number>;\n /**\n * Applies the change, commits it, and puts it back if the commit\n * refuses. Answers whether it stuck.\n */\n run(argument: A): Promise<boolean>;\n}\n\n/**\n * An optimistic change to a cell, with a rollback that does not fight\n * the person.\n *\n * private readonly favourites = internalState<readonly string[]>([]);\n * private readonly like = mutate(this.favourites, toggled, id => api.favourite(id));\n *\n * toggle(id: string): void {\n * void this.like.run(id);\n * }\n *\n * Three things happen and the order is the whole point. `apply` runs\n * first and writes the cell, so the screen changes on the press rather\n * than a round trip later. `commit` then does the real write. If it\n * rejects, or resolves `false`, the cell goes back to what it held\n * before.\n *\n * **The rollback is guarded.** It happens only while the cell still\n * holds exactly what `apply` wrote. Without that, a slow rejection\n * would fight a fast second press and the cell would end up saying the\n * opposite of the last thing anyone did, which is the guard every\n * optimistic screen writes by hand and half of them get wrong.\n *\n * The cell is named first, and not because it was first written\n * `mutate(apply, commit)`: the cell is what makes the guard possible.\n * A mutation handed only two functions can undo its own change but\n * cannot tell whether undoing it is still the right thing to do.\n *\n * A helper and not a data layer: nothing in the framework requires\n * one, and an application that would rather write the four lines out\n * is writing the same four lines this does.\n */\nexport function mutate<T, A = void>(\n cell: InternalState<T>,\n apply: (current: T, argument: A) => T,\n commit: (argument: A, applied: T) => Promise<unknown>,\n options: MutateOptions<T> = {}\n): Mutation<A> {\n const equal = equalityOf<T>(options.equal ?? 'structural');\n const inFlight = internalState(0, options.label);\n\n const revert = (before: T, applied: T): void => {\n if (!equal(cell.value, applied)) {\n // Changed again since, by whoever is using the screen. Their\n // change is newer than this answer and wins.\n return;\n }\n cell.value = before;\n };\n\n return {\n pending: inFlight,\n async run(argument: A): Promise<boolean> {\n const before = cell.value;\n const applied = apply(before, argument);\n cell.value = applied;\n inFlight.value = inFlight.value + 1;\n try {\n // `false` and a rejection mean the same thing: the write did\n // not happen. Anything else, `undefined` included, is a\n // commit that went through.\n if ((await commit(argument, applied)) === false) {\n revert(before, applied);\n return false;\n }\n return true;\n } catch {\n revert(before, applied);\n return false;\n } finally {\n inFlight.value = Math.max(0, inFlight.value - 1);\n }\n }\n };\n}\n","import {\n debounceTime,\n Observable,\n Subject,\n Subscription,\n tap,\n throttleTime,\n type MonoTypeOperatorFunction\n} from 'rxjs';\n\nimport { trackRead, type ReadableCell } from './Input';\n\n/**\n * A cell that lets its source through on a timer.\n *\n * The two operators below are the same machinery with a different\n * gate, and both are cells rather than plain streams on purpose: a\n * `computed` reads a cell with `.value` and follows it, so a debounced\n * search term composes with everything else in the dialect instead of\n * being the one value in a screen that has to be piped.\n *\n * It holds the last value the gate let through, which is what `.value`\n * answers while something is following it. With nothing following\n * there is no timer running to hold anything back, so `.value` reads\n * the source directly, which is the honest answer rather than a value\n * frozen at whatever moment the last follower left.\n *\n * A value equal to the one it already holds is not a change and is not\n * emitted, the same rule `computed` follows. Without it the first pass\n * of the gate after a subscription would repeat the value the\n * subscriber had just been handed.\n *\n * One subscription upstream however many followers it has, given back\n * when the last of them leaves, on the same terms as `ComputedCell`.\n */\nclass TimedCell<T> extends Observable<T> implements ReadableCell<T> {\n private current!: T;\n private hasCurrent = false;\n private followers = 0;\n private seeding = false;\n private upstream: Subscription | null = null;\n private readonly changes = new Subject<T>();\n\n constructor(\n private readonly stream: Observable<T>,\n private readonly gate: MonoTypeOperatorFunction<T>\n ) {\n super(subscriber => {\n this.followers++;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.current);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.followers--;\n if (this.followers === 0) {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n };\n });\n }\n\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n const asking = this.stream.subscribe(value => {\n this.current = value;\n this.hasCurrent = true;\n });\n asking.unsubscribe();\n }\n return this.current;\n }\n\n private attach(): void {\n // Seeds the current value from whatever the source already holds,\n // so a cell behind a gate has a value on the first frame rather\n // than after the first delay. Only during the subscribe itself: a\n // value arriving later is a change, and absorbing it here would\n // let it past the gate without telling anybody.\n this.seeding = true;\n this.upstream = this.stream\n .pipe(\n tap(value => {\n if (this.seeding && !this.hasCurrent) {\n this.current = value;\n this.hasCurrent = true;\n }\n }),\n this.gate\n )\n .subscribe(value => {\n if (this.hasCurrent && Object.is(this.current, value)) {\n return;\n }\n this.current = value;\n this.hasCurrent = true;\n this.changes.next(value);\n });\n this.seeding = false;\n }\n}\n\n/**\n * A cell that follows its source once it has stopped moving.\n *\n * const query = internalState('');\n * const term = debounced(query, 200);\n * const results = computed(() => index.search(term.value));\n *\n * Nothing is emitted while values keep arriving; `ms` after the last\n * one, the last one is. This is what a search field wants and what\n * every search field in the tree was reaching the router without: a\n * keystroke is not a question, and a pause is.\n *\n * The value the source already held is there immediately, so a screen\n * built from this draws on the first frame rather than `ms` later.\n */\nexport function debounced<T>(source: Observable<T>, ms: number): ReadableCell<T> {\n return new TimedCell(source, debounceTime<T>(ms));\n}\n\n/**\n * A cell that follows its source at most once every `ms`.\n *\n * const position = throttled(scrollOffset, 100);\n *\n * The first value goes straight through and the last of a burst\n * follows at the end of the window, so a value that arrives while the\n * window is open is late rather than lost. That pairing is what makes\n * this usable for a position or a progress reading, where the\n * beginning and the end of a movement both matter and the middle does\n * not.\n *\n * Use this for something that is continuously true, and `debounced`\n * for something a person has finished saying.\n */\nexport function throttled<T>(source: Observable<T>, ms: number): ReadableCell<T> {\n return new TimedCell(source, throttleTime<T>(ms, undefined, { leading: true, trailing: true }));\n}\n","/**\n * The barrier between the application and the view, declared once.\n *\n * A token is a name, a shape and an initial value — and no\n * implementation at all. Both threads import it, which is the point:\n * the module holding it has nothing in it to bundle, so an app's api\n * client and domain logic never reach the render worker the way a\n * shared `Store` class dragged them there.\n *\n * What the framework knows about a channel ends here. It diffs plain\n * data and ships patches; where the observables came from — a single\n * subject, or an api → repository → domain → view-model stack — is the\n * application's business and the framework cannot tell the difference.\n *\n * export interface CatalogView {\n * products: ProductRow[];\n * status: 'loading' | 'ready' | 'error';\n * }\n * export interface CatalogCommands {\n * addToCart(id: string): void;\n * }\n * export const Catalog = channel<CatalogView, CatalogCommands>('catalog', {\n * products: [],\n * status: 'loading'\n * });\n */\n\n/**\n * A command a component can send back across the barrier.\n *\n * The arguments are what cross: each is structured-cloned onto the\n * owning thread, so they must be plain data. There may be as many as\n * the command needs, which is why `move(from, to)` is written the way\n * anyone would write it rather than as `move({ from, to })`; a command\n * used to carry one payload and the second argument was dropped on the\n * floor with a warning.\n *\n * Commands return nothing: the effect comes back as a patch, never as\n * a return value, since there is no synchronous answer to be had\n * across a thread.\n */\nexport type Command = (...args: never[]) => void;\n\n/**\n * The internal view of a command set: a bag of callables by name.\n *\n * Public signatures constrain to `object`, not to this. An application\n * declares its commands as an ordinary interface —\n * `interface CatalogCommands { addToCart(id: string): void }` — and an\n * interface has no index signature, so it does not satisfy a\n * `Record<string, …>` constraint however well it fits in spirit.\n * Constraining to `object` accepts what people actually write; this\n * alias is what the implementation casts to when it looks a command up\n * by name.\n */\nexport type CommandMap = Record<string, Command>;\n\n/** The declared barrier for one area of an application. */\nexport interface ChannelToken<View extends object, Commands extends object = Record<string, never>> {\n readonly name: string;\n /**\n * What every view key holds before the first patch arrives.\n *\n * Required rather than optional, so the render thread never observes\n * `undefined` for a declared key. A channel that is genuinely still\n * loading says so in its own shape — a `status` field — rather than\n * leaving the view to infer it from an absence.\n */\n readonly initial: View;\n /** Phantom, carrying the command types to `send`. Never read. */\n readonly commands?: Commands;\n}\n\n/**\n * Declares a channel.\n *\n * The name identifies it across the thread boundary and must be\n * stable; unlike a class name it survives minification, which is why\n * it is written out rather than derived.\n */\nexport function channel<View extends object, Commands extends object = Record<string, never>>(\n name: string,\n initial: View\n): ChannelToken<View, Commands> {\n if (name.length === 0) {\n throw new Error('A channel needs a name: it is how the two threads agree on which one this is.');\n }\n return { name, initial };\n}\n\n/** A channel written as one object: the view with its values, and the commands. */\nexport interface ChannelSpec<View extends object, Commands extends object> {\n /**\n * Every view key with the value it holds before the first patch.\n *\n * The type of the channel's view is the type of this object, so the\n * keys and their initial values are written once instead of in an\n * interface and again in a literal that has to agree with it.\n */\n readonly view: View;\n /**\n * The commands, as a type rather than as implementations.\n *\n * Written `{} as { addToCart(id: string, quantity: number): void }`:\n * the handlers live on the thread that owns the data and are passed\n * to `provide`, so what belongs in the token is only their shape.\n */\n readonly commands?: Commands;\n}\n\n/**\n * Declares a channel from one object.\n *\n * export const Catalog = defineChannel('catalog', {\n * view: {\n * products: [] as readonly ProductRow[],\n * status: 'loading' as ShelfStatus\n * },\n * commands: {} as {\n * addToCart(id: string, quantity: number): void;\n * move(from: number, to: number): void;\n * }\n * });\n *\n * export type CatalogView = ViewOf<typeof Catalog>;\n *\n * The same token `channel()` returns, declared once instead of three\n * times. `channel<View, Commands>(name, initial)` wrote the view as an\n * interface, then as an initial literal that had to agree with it, and\n * a key added to one and forgotten in the other was a type error in a\n * third file. Here the object is the type.\n *\n * A field whose initial value is narrower than the type it holds is\n * given the type it holds: `[]` is `never[]` and `'loading'` is\n * `string` unless it is said, which is what the `as` clauses above are\n * for. `ViewOf` and `CommandsOf` name the resulting types wherever the\n * application used to name its own interface.\n *\n * `channel()` is not deprecated and keeps working exactly as it did.\n * An application with interfaces it wants to keep, because they are\n * shared with something else or because the initial values are built\n * elsewhere, has nothing to migrate.\n */\nexport function defineChannel<View extends object, Commands extends object = Record<string, never>>(\n name: string,\n spec: ChannelSpec<View, Commands>\n): ChannelToken<View, Commands> {\n return channel<View, Commands>(name, spec.view);\n}\n\n/** The view type of a channel token, for an application that wants to name it. */\nexport type ViewOf<T> = T extends ChannelToken<infer View, object> ? View : never;\n\n/** The command type of a channel token. */\nexport type CommandsOf<T> = T extends ChannelToken<object, infer Commands> ? Commands : never;\n\n/**\n * The keys a channel publishes.\n *\n * Structural in its parameter rather than generic over the token, so\n * it does not have to agree with any particular command type to read\n * what is only ever the initial value's shape.\n */\nexport function viewKeys(token: { initial: object }): string[] {\n return Object.keys(token.initial);\n}\n","import type { Patch } from './StorePatch';\n\n/**\n * A two-way channel endpoint. `MessagePort` satisfies it, as does a\n * test double, so nothing in the channel layer depends on Worker.\n */\nexport interface ChannelPort {\n postMessage(message: unknown): void;\n onmessage: ((event: { data: unknown }) => void) | null;\n}\n\n/**\n * Render thread → the thread that owns the channel.\n *\n * A command's first argument stayed `payload` when commands learned to\n * take more than one, and the rest travel beside it. That is not\n * tidiness: an older view talking to a newer application worker sends\n * no `rest`, which reads as the one-argument call it is, and an older\n * application worker ignores the field, which is exactly what it did\n * before the field existed.\n */\nexport type ChannelClientMessage =\n | { type: 'channel:sync' }\n | { type: 'channel:command'; command: string; payload: unknown; rest?: unknown[] };\n\n/** The owning thread → render thread. */\nexport type ChannelHostMessage =\n | { type: 'channel:patch'; patches: Patch[] }\n | { type: 'channel:error'; message: string; stack?: string };\n\nexport function isChannelClientMessage(value: unknown): value is ChannelClientMessage {\n const type = (value as { type?: unknown } | null)?.type;\n return type === 'channel:sync' || type === 'channel:command';\n}\n\nexport function isChannelHostMessage(value: unknown): value is ChannelHostMessage {\n const type = (value as { type?: unknown } | null)?.type;\n return type === 'channel:patch' || type === 'channel:error';\n}\n","import { structurallyEqual } from './structuralEquals';\n\nexport type PatchPath = readonly (string | number)[];\n\n/**\n * A change to one projection, as sent from a data worker to a replica.\n *\n * Paths are relative to the projection's root value, so a patch is\n * self-contained: the replica never needs the previous value to apply\n * one, only the value it already holds.\n */\nexport type Patch =\n | { op: 'set'; projection: string; path: PatchPath; value: unknown }\n | { op: 'delete'; projection: string; path: PatchPath }\n | {\n op: 'splice';\n projection: string;\n path: PatchPath;\n index: number;\n deleteCount: number;\n items: readonly unknown[];\n };\n\n/**\n * Describes how to turn `previous` into `current` for one projection.\n *\n * Returns an empty list when nothing changed, which is the common case\n * and the reason this exists: the point of a projection is that most\n * state changes do not alter it, and the ones that do usually alter a\n * small part.\n */\nexport function diffProjection(projection: string, previous: unknown, current: unknown): Patch[] {\n const patches: Patch[] = [];\n diff(projection, [], previous, current, patches);\n return patches;\n}\n\nfunction diff(projection: string, path: PatchPath, previous: unknown, current: unknown, out: Patch[]): void {\n if (structurallyEqual(previous, current)) {\n return;\n }\n\n if (Array.isArray(previous) && Array.isArray(current)) {\n diffArray(projection, path, previous, current, out);\n return;\n }\n\n if (isPlainObject(previous) && isPlainObject(current)) {\n for (const key of Object.keys(current)) {\n if (Object.prototype.hasOwnProperty.call(previous, key)) {\n diff(projection, [...path, key], previous[key], current[key], out);\n } else {\n out.push({ op: 'set', projection, path: [...path, key], value: current[key] });\n }\n }\n for (const key of Object.keys(previous)) {\n if (!Object.prototype.hasOwnProperty.call(current, key)) {\n out.push({ op: 'delete', projection, path: [...path, key] });\n }\n }\n return;\n }\n\n out.push({ op: 'set', projection, path, value: current });\n}\n\n/**\n * Diffs two arrays by trimming the common prefix and suffix.\n *\n * This is not a minimal edit script — a shuffle degrades to replacing\n * the middle wholesale. It is chosen because the operations lists\n * actually undergo (append, prepend, remove one, edit in place) all\n * reduce to a single small patch, and computing a true LCS on every\n * store change would cost more than it saves.\n */\nfunction diffArray(projection: string, path: PatchPath, previous: unknown[], current: unknown[], out: Patch[]): void {\n let start = 0;\n while (start < previous.length && start < current.length && structurallyEqual(previous[start], current[start])) {\n start++;\n }\n\n let previousEnd = previous.length - 1;\n let currentEnd = current.length - 1;\n while (previousEnd >= start && currentEnd >= start && structurallyEqual(previous[previousEnd], current[currentEnd])) {\n previousEnd--;\n currentEnd--;\n }\n\n const previousCount = previousEnd - start + 1;\n const currentCount = currentEnd - start + 1;\n\n if (previousCount === 0 && currentCount === 0) {\n return;\n }\n\n if (previousCount === currentCount) {\n // Same span on both sides: these are edits in place, so recurse\n // and let nested diffs stay small rather than resending elements.\n for (let offset = 0; offset < previousCount; offset++) {\n const index = start + offset;\n diff(projection, [...path, index], previous[index], current[index], out);\n }\n return;\n }\n\n out.push({\n op: 'splice',\n projection,\n path,\n index: start,\n deleteCount: previousCount,\n items: current.slice(start, currentEnd + 1)\n });\n}\n\n/**\n * Applies patches to a projection value, sharing structure with the\n * original everywhere the patch did not reach.\n *\n * Nothing handed in is mutated: bindings hold onto emitted values, so a\n * replica that edited in place would change data a component already\n * rendered.\n *\n * **Each container on a patched path is copied once per batch, not once\n * per patch.** A batch of N patches into one K-key object used to cost\n * N × K: every patch spread the whole object again to change one key.\n * A snapshot keyed by id is exactly that shape — gessologic published\n * `Record<netId, 0 | 1>` for ten thousand nets, about nine hundred\n * patches a publish, and the render worker's patch phase fell minutes\n * behind a 60 Hz stream it could never catch. So the batch remembers\n * the containers it has copied, and writes into those in place: they\n * are its own, made during this call and seen by nobody yet. Values\n * that arrived inside a patch are never written into, because they are\n * the patch's — a devtools log replays the same patch objects again.\n */\nexport function applyPatches(root: unknown, patches: readonly Patch[]): unknown {\n const owned = new Set<object>();\n let next = root;\n for (const patch of patches) {\n next = applyOne(next, patch, owned);\n }\n return next;\n}\n\nexport function applyPatch(root: unknown, patch: Patch): unknown {\n return applyOne(root, patch, new Set());\n}\n\n/** The containers this batch copied, and may therefore write into. */\ntype Owned = Set<object>;\n\nfunction applyOne(root: unknown, patch: Patch, owned: Owned): unknown {\n switch (patch.op) {\n case 'set':\n return setIn(root, patch.path, 0, patch.value, owned);\n case 'delete':\n if (patch.path.length === 0) {\n return undefined;\n }\n return deleteIn(root, patch.path, 0, owned);\n case 'splice':\n return updateIn(root, patch.path, 0, owned, node => {\n // Concatenation rather than `splice(..., ...items)`: spreading\n // the items passes each as an argument, and a batch of two\n // hundred thousand overflows the call stack.\n const array = Array.isArray(node) ? node : [];\n const spliced = array.slice(0, patch.index).concat(patch.items, array.slice(patch.index + patch.deleteCount));\n owned.add(spliced);\n return spliced;\n });\n }\n}\n\nfunction setIn(node: unknown, path: PatchPath, index: number, value: unknown, owned: Owned): unknown {\n if (index === path.length) {\n return value;\n }\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n setKey(copy, key, setIn(readKey(node, key), path, index + 1, value, owned));\n return copy;\n}\n\nfunction deleteIn(node: unknown, path: PatchPath, index: number, owned: Owned): unknown {\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n if (index === path.length - 1) {\n if (Array.isArray(copy)) {\n copy.splice(Number(key), 1);\n } else {\n delete (copy as Record<string, unknown>)[String(key)];\n }\n return copy;\n }\n setKey(copy, key, deleteIn(readKey(node, key), path, index + 1, owned));\n return copy;\n}\n\nfunction updateIn(\n node: unknown,\n path: PatchPath,\n index: number,\n owned: Owned,\n update: (node: unknown) => unknown\n): unknown {\n if (index === path.length) {\n return update(node);\n }\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n setKey(copy, key, updateIn(readKey(node, key), path, index + 1, owned, update));\n return copy;\n}\n\n/**\n * The container to write `key` into: `node` itself when this batch\n * already copied it, and a fresh copy, remembered, when it did not.\n */\nfunction cloneContainer(node: unknown, key: string | number, owned: Owned): unknown[] | Record<string, unknown> {\n if (typeof node === 'object' && node !== null && owned.has(node)) {\n return node as unknown[] | Record<string, unknown>;\n }\n let copy: unknown[] | Record<string, unknown>;\n if (Array.isArray(node)) {\n copy = node.slice();\n } else if (isPlainObject(node)) {\n copy = { ...node };\n } else {\n // The path runs past the end of what the replica holds, which\n // happens when a patch fills in a branch that did not exist yet.\n copy = typeof key === 'number' ? [] : {};\n }\n owned.add(copy);\n return copy;\n}\n\nfunction readKey(node: unknown, key: string | number): unknown {\n if (node === null || node === undefined) {\n return undefined;\n }\n return (node as Record<string | number, unknown>)[key];\n}\n\nfunction setKey(container: unknown[] | Record<string, unknown>, key: string | number, value: unknown): void {\n (container as Record<string | number, unknown>)[key] = value;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","/**\n * Checks that a value can cross the barrier.\n *\n * `structurallyEqual` understands primitives, arrays and plain\n * objects, and falls back to reference equality for everything else —\n * which for a freshly built value reports \"changed\" every single time.\n * A view key holding a `Date`, a `Map` or a domain object therefore\n * re-emits on every unrelated update and dirties the subtree bound to\n * it, forever, while looking perfectly correct.\n *\n * That failure is invisible in a test and shows up as a vague slowness\n * much later, so `provide` checks each key's first emission and throws\n * naming the path. The view-model layer is where rich objects become\n * flat data; this is what makes that a rule rather than a convention.\n *\n * The check runs once per key, on the first value only. It is a\n * development guard against a design mistake, not a validator on the\n * hot path.\n */\n\nconst MAX_DEPTH = 100;\n\n/**\n * Returns the path to the first value that cannot cross, or null when\n * the whole tree is plain data.\n */\nexport function findUnplainPath(value: unknown, path: readonly (string | number)[] = []): string | null {\n if (path.length > MAX_DEPTH) {\n return format(path);\n }\n if (value === null) {\n return null;\n }\n const type = typeof value;\n if (type === 'string' || type === 'number' || type === 'boolean' || type === 'undefined') {\n return null;\n }\n if (type === 'function' || type === 'symbol' || type === 'bigint') {\n return format(path);\n }\n if (Array.isArray(value)) {\n for (let index = 0; index < value.length; index++) {\n const found = findUnplainPath(value[index], [...path, index]);\n if (found !== null) {\n return found;\n }\n }\n return null;\n }\n const prototype = Object.getPrototypeOf(value as object);\n if (prototype !== Object.prototype && prototype !== null) {\n return format(path);\n }\n for (const [key, member] of Object.entries(value as Record<string, unknown>)) {\n const found = findUnplainPath(member, [...path, key]);\n if (found !== null) {\n return found;\n }\n }\n return null;\n}\n\n/**\n * Throws when `value` cannot cross the barrier, naming the channel,\n * the key and the path within it.\n */\nexport function requirePlainData(channelName: string, key: string, value: unknown): void {\n const path = findUnplainPath(value);\n if (path === null) {\n return;\n }\n const where = path === '' ? `'${key}'` : `'${key}'${path}`;\n throw new Error(\n `Channel '${channelName}' published ${where}, which is not plain data. ` +\n `Only primitives, arrays and plain objects cross the barrier: a Date, Map, Set, ` +\n `class instance or function compares by reference, so it would report a change on ` +\n `every update and rebuild the subtree bound to it. Flatten it in the view model.`\n );\n}\n\nfunction format(path: readonly (string | number)[]): string {\n return path.map(step => (typeof step === 'number' ? `[${step}]` : `.${step}`)).join('');\n}\n","import { Subscription, type Observable } from 'rxjs';\n\nimport { diffProjection, type Patch } from './StorePatch';\nimport { isChannelClientMessage, type ChannelHostMessage, type ChannelPort } from './ChannelProtocol';\nimport { requirePlainData } from './plainData';\nimport { viewKeys, type ChannelToken, type CommandMap } from './ChannelToken';\n\n/** What the owning thread supplies for a channel. */\nexport interface ChannelSource<View extends object, Commands extends object> {\n /** One observable per declared view key. */\n view: { readonly [K in keyof View]: Observable<View[K]> };\n /** One handler per declared command. */\n commands?: Commands;\n}\n\n/**\n * Publishes a channel from the thread that owns its data.\n *\n * Each view key is subscribed, diffed against what the other side last\n * saw, and sent as patches. Whatever produced the observable — a bare\n * subject or a stack of layers — stays here; only plain data crosses.\n *\n * Keys are subscribed on the first sync request, so a channel nobody\n * is watching costs nothing.\n */\nexport function provide<View extends object, Commands extends object>(\n token: ChannelToken<View, Commands>,\n source: ChannelSource<View, Commands>,\n port: ChannelPort\n): ProvidedChannel {\n return new ProvidedChannel(\n token as ChannelToken<object, CommandMap>,\n source as ChannelSource<object, CommandMap>,\n port\n );\n}\n\nexport class ProvidedChannel {\n private readonly subscriptions = new Subscription();\n /**\n * What the other side is known to hold, seeded from the token's\n * initial value — which the replica also starts from, so an app\n * whose first emission equals the initial sends nothing at all.\n */\n private readonly previous = new Map<string, unknown>();\n private readonly checked = new Set<string>();\n\n private synced = false;\n\n constructor(\n private readonly token: ChannelToken<object, CommandMap>,\n private readonly source: ChannelSource<object, CommandMap>,\n private readonly port: ChannelPort\n ) {\n for (const key of viewKeys(token)) {\n this.previous.set(key, (token.initial as Record<string, unknown>)[key]);\n }\n this.port.onmessage = event => this.receive(event.data);\n }\n\n private receive(data: unknown): void {\n if (!isChannelClientMessage(data)) {\n return;\n }\n try {\n if (data.type === 'channel:sync') {\n this.sync();\n return;\n }\n this.runCommand(data.command, data.payload, data.rest);\n } catch (error) {\n // Reported rather than thrown: this runs on the thread that owns\n // the data, and a throw here would leave the view waiting for a\n // patch that never comes, with nothing said about why.\n this.post({\n type: 'channel:error',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined\n });\n }\n }\n\n private runCommand(name: string, payload: unknown, rest?: readonly unknown[]): void {\n const handler = this.source.commands?.[name];\n if (handler === undefined) {\n const names = Object.keys(this.source.commands ?? {})\n .sort()\n .join(', ');\n throw new Error(\n `Channel '${this.token.name}' has no command '${name}'. ` +\n `Declared commands: ${names.length > 0 ? names : '(none)'}.`\n );\n }\n // Spread rather than passed as one payload: a command carries as\n // many arguments as it declares. A client that sent none beyond\n // the first sends no `rest`, so this is the single-argument call\n // it always was.\n (handler as (...args: unknown[]) => void)(payload, ...(rest ?? []));\n }\n\n private sync(): void {\n if (this.synced) {\n this.resend();\n return;\n }\n this.synced = true;\n\n for (const key of viewKeys(this.token)) {\n const observable = (this.source.view as Record<string, Observable<unknown> | undefined>)[key];\n if (observable === undefined) {\n this.post({\n type: 'channel:error',\n message: `Channel '${this.token.name}' declares view key '${key}' but nothing was provided for it.`\n });\n continue;\n }\n this.subscriptions.add(\n observable.subscribe({\n next: value => this.publish(key, value),\n error: (error: unknown) =>\n this.post({\n type: 'channel:error',\n message: `Channel '${this.token.name}' view key '${key}' errored: ${\n error instanceof Error ? error.message : String(error)\n }`,\n stack: error instanceof Error ? error.stack : undefined\n })\n })\n );\n }\n }\n\n private publish(key: string, value: unknown): void {\n if (!this.checked.has(key)) {\n this.checked.add(key);\n try {\n // Once per key, on the first value: a design mistake, caught at\n // startup rather than felt as slowness later. See `plainData`.\n requirePlainData(this.token.name, key, value);\n } catch (error) {\n // Reported, not rethrown. This runs inside an observer's `next`,\n // and RxJS routes a throw there to its unhandled-error hook\n // rather than back to the subscriber — so a throw would surface\n // as a stray async error on this thread and say nothing at all\n // on the thread that needs to know.\n this.post({\n type: 'channel:error',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined\n });\n return;\n }\n }\n const patches = diffProjection(key, this.previous.get(key), value);\n this.previous.set(key, value);\n if (patches.length > 0) {\n this.post({ type: 'channel:patch', patches });\n }\n }\n\n /** Re-sends every key in full, for a client that reattached. */\n private resend(): void {\n const patches: Patch[] = [];\n for (const [key, value] of this.previous) {\n patches.push({ op: 'set', projection: key, path: [], value });\n }\n if (patches.length > 0) {\n this.post({ type: 'channel:patch', patches });\n }\n }\n\n private post(message: ChannelHostMessage): void {\n this.port.postMessage(message);\n }\n\n dispose(): void {\n this.subscriptions.unsubscribe();\n this.port.onmessage = null;\n }\n}\n","/**\n * What a node is, as plain data (the inspector).\n *\n * The inspector shows a node's props, its resolved environment, its\n * bindings and their sources, its layout explanation and which\n * component owns it. Every one of those lives in the render thread,\n * and none of them can cross a `postMessage`: a `UiNode` is a live\n * object, an `Observable` is a subscription, a component instance is a\n * class. So the report is built where the tree is and only strings\n * cross, which is the same rule the existing `inspect` message follows\n * with `formatExplanation`'s text, and the same reason.\n *\n * That makes the report lossy on purpose. It is a description of a\n * node for a person to read, not a handle on one: nothing in it can be\n * clicked back to the object it came from, and nothing in it is worth\n * asserting on beyond the fact that it says what the tree says.\n */\nexport interface UiNodeReport {\n readonly id: string;\n /** `UiNodeType`, as its string value. */\n readonly type: string;\n readonly box: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };\n /**\n * The components that rendered this node, nearest first.\n *\n * A node has no backpointer to a component: the builder gives every\n * component slot a Fragment anchor whose id carries `:component:`,\n * and the resolver keeps one host per anchor id. Walking up the\n * ancestors for those anchors is therefore the only way to answer\n * \"who rendered this\", and it answers it exactly, because that\n * anchor *is* the component's identity.\n */\n readonly owners: readonly UiOwnerReport[];\n readonly props: readonly UiPropReport[];\n readonly environment: readonly UiEnvironmentReport[];\n /** Attached modifier kinds, in the order the element listed them. */\n readonly modifiers: readonly string[];\n /** The event types this node has listeners for, e.g. `click`. */\n readonly listens: readonly string[];\n /**\n * What lies under the pointer beneath this node, topmost first: the\n * nodes this one is painted over and would take a press from. The\n * answer to \"I clicked the button and nothing happened\": the node the\n * inspector shows is the one that took the press, and this is the\n * button it covered. Empty when the pointer is not over the node.\n */\n readonly beneath: readonly UiBeneathReport[];\n readonly semantics?: UiSemanticsReport;\n /** `formatExplanation` of the node's layout, which is L8's answer. */\n readonly explanation: string;\n}\n\n/** A node under the inspected one at the pointer. */\nexport interface UiBeneathReport {\n readonly id: string;\n readonly type: string;\n /** The component that rendered it, if one did. */\n readonly owner?: string;\n /** The event types it listens for, so a covered button reads as one. */\n readonly listens: readonly string[];\n}\n\nexport interface UiOwnerReport {\n /** The `@Define` tag, else the class or function name. */\n readonly name: string;\n readonly anchorId: string;\n}\n\n/** As much of a node as a one-line path needs. */\nexport interface NodePathTarget {\n /** `UiNodeType`, as its string value. */\n readonly type: string;\n readonly id: string;\n /** The node's accessible name, when it has one. */\n readonly label?: string;\n}\n\n/**\n * A node as a path somebody can read: `App > TrackScreen > ActionRow >\n * Button \"Like\"`.\n *\n * Written for error messages rather than for the inspector, and the\n * difference decides the shape. A report is read beside the tree it\n * came from, so an id is a handle; an error is read in a console or an\n * overlay with no tree beside it, and `node-4821` there is a fact\n * about nothing. The owner chain is what a person recognises, because\n * it is the components they wrote.\n *\n * Owners arrive nearest-first, as `UiNodeReport.owners` computes them,\n * and read outermost-first, as a path does. The accessible name is the\n * leaf when there is one: two `Button`s in the same row are only told\n * apart by what they say.\n */\nexport function formatNodePath(owners: readonly UiOwnerReport[], node: NodePathTarget): string {\n const names = owners.map(owner => owner.name).reverse();\n if (names.length === 0) {\n // Nothing rendered it: a node built without a component around it,\n // which is rare enough that the id is the only thing to say.\n return node.label === undefined || node.label === '' ? `${node.type} ${node.id}` : `${node.type} \"${node.label}\"`;\n }\n const path = names.join(' > ');\n return node.label === undefined || node.label === '' ? path : `${path} \"${node.label}\"`;\n}\n\n/** Where a property's current value came from. */\nexport type UiPropOrigin = 'element' | 'binding' | 'modifier';\n\nexport interface UiPropReport {\n readonly name: string;\n readonly value: string;\n readonly origin: UiPropOrigin;\n /**\n * For a modifier write, the modifiers writing it and what the\n * element declared; for a binding, that it is bound. Absent for a\n * plain element value.\n */\n readonly source?: string;\n /** For a bound property, the stream feeding it. Absent otherwise. */\n readonly stream?: UiStreamReport;\n}\n\n/**\n * The stream behind a bound property: which one, what it last said,\n * and when.\n *\n * \"Is this value bound\" was the third question the inspector set\n * out to answer, and the report answered it with a yes. A yes is not\n * enough to debug with: a prop that is not updating and a prop whose\n * stream has not emitted since the screen was built look identical on\n * the node, and so did they in the report.\n *\n * `emittedAt` is on the epoch clock rather than the thread's own,\n * because the panel reading it is one or two threads away and\n * `performance.now()` counts from each thread's creation. The panel\n * subtracts its own `Date.now()`.\n *\n * An epoch stamp rather than an age for a second reason: an age\n * changes on every frame, and the runtime decides whether to re-send a\n * selected node's report by comparing it with the last one. A report\n * carrying an age would differ from itself sixty times a second and\n * the panel would be redrawn for a clock tick.\n */\nexport interface UiStreamReport {\n /**\n * What feeds it: a labelled cell's own name (`queue.current`), else\n * what kind of stream it is.\n */\n readonly source: string;\n /** `cell` when the stream named itself, `observable` when it did not. */\n readonly kind: 'cell' | 'observable';\n /** The last value the stream produced, printed. */\n readonly value: string;\n /** How many values it has produced since the property was bound. */\n readonly emissions: number;\n /** When the last value arrived, as epoch milliseconds, or null before the first. */\n readonly emittedAt: number | null;\n /** Whether the subscription is still live. A false here is a torn-down binding still on the node. */\n readonly connected: boolean;\n}\n\n/**\n * A bound property's stream, as far as the report is concerned.\n *\n * Structural rather than `UiBinding`, so this module keeps its one\n * rule: it describes a node and imports nothing that holds one.\n */\nexport interface BoundStream {\n readonly id: number;\n readonly observable: unknown;\n value(): unknown;\n emissionCount(): number;\n emittedAt(): number | null;\n connected(): boolean;\n}\n\n/**\n * Describes the stream driving a property.\n *\n * `timeOrigin` turns the binding's own reading into an epoch stamp:\n * `performance.timeOrigin` on a thread that has one, and zero where\n * the reading is already an epoch.\n */\nexport function describeStream(binding: BoundStream, timeOrigin: number): UiStreamReport {\n // A labelled cell says where the value comes from: `Card.title`,\n // `queue.current`. An anonymous pipe only has the binding's id.\n const label = (binding.observable as { label?: unknown } | null)?.label;\n const labelled = typeof label === 'string' && label !== '';\n const emittedAt = binding.emittedAt();\n return {\n source: labelled ? label : `observable #${binding.id}`,\n kind: labelled ? 'cell' : 'observable',\n value: printPropValue(binding.value()),\n emissions: binding.emissionCount(),\n emittedAt: emittedAt === null ? null : timeOrigin + emittedAt,\n connected: binding.connected()\n };\n}\n\n/** A stream as one line: what feeds the prop, and how long ago it said so. */\nexport function formatStream(stream: UiStreamReport, now: number = Date.now()): string {\n const when = stream.emittedAt === null ? 'no value yet' : `${formatAge(Math.max(0, now - stream.emittedAt))} ago`;\n const emissions = `${stream.emissions} emission${stream.emissions === 1 ? '' : 's'}`;\n return `${stream.source} · ${emissions} · ${when}${stream.connected ? '' : ' · disconnected'}`;\n}\n\n/** An age in the largest unit that stays readable. */\nexport function formatAge(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n return `${Math.round(ms / 60_000)}m`;\n}\n\nexport interface UiEnvironmentReport {\n readonly key: string;\n readonly value: string;\n /** Whether this node provides the value rather than inheriting it. */\n readonly provided: boolean;\n}\n\nexport interface UiSemanticsReport {\n readonly role?: string;\n readonly label?: string;\n readonly value?: string;\n readonly states?: readonly string[];\n}\n\n/**\n * A value as one line a person can read.\n *\n * `JSON.stringify` alone is not enough: the two values a canvas UI\n * puts in a property that it cannot handle are a `Set` (a node's\n * visual states) and a function (an event handler), and it prints both\n * as `{}`, which in an inspector reads as a bug in the application\n * rather than one in the inspector.\n */\nexport function printPropValue(value: unknown): string {\n if (value === undefined) {\n return 'undefined';\n }\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'function') {\n return `ƒ ${value.name === '' ? '(anonymous)' : value.name}`;\n }\n if (typeof value === 'symbol') {\n return value.toString();\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n if (value instanceof Set) {\n return `Set { ${[...value].map(printPropValue).join(', ')} }`;\n }\n if (value instanceof Map) {\n return `Map { ${[...value].map(([key, entry]) => `${printPropValue(key)}: ${printPropValue(entry)}`).join(', ')} }`;\n }\n if (Array.isArray(value)) {\n return `[${value.map(printPropValue).join(', ')}]`;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n // A cyclic value, or one with a throwing getter. The inspector\n // must not be the thing that breaks while explaining a break.\n return String(value);\n }\n}\n\n/** The report as text, for a console or a test failure. */\nexport function formatNodeReport(report: UiNodeReport): string {\n const lines: string[] = [`${report.type} '${report.id}'`];\n if (report.owners.length > 0) {\n lines.push(`rendered by ${report.owners.map(owner => owner.name).join(' inside ')}`);\n }\n if (report.modifiers.length > 0) {\n lines.push(`modifiers: ${report.modifiers.join(', ')}`);\n }\n if (report.listens.length > 0) {\n lines.push(`listens: ${report.listens.join(', ')}`);\n }\n if (report.beneath.length > 0) {\n lines.push('beneath, at the pointer:');\n for (const under of report.beneath) {\n const owner = under.owner === undefined ? '' : ` (${under.owner})`;\n const listens = under.listens.length === 0 ? '' : `, listens: ${under.listens.join(', ')}`;\n lines.push(` ${under.type} ${under.id}${owner}${listens}`);\n }\n }\n if (report.props.length > 0) {\n lines.push('props:');\n for (const prop of report.props) {\n lines.push(` ${prop.name} = ${prop.value}${prop.source === undefined ? '' : ` (${prop.source})`}`);\n if (prop.stream !== undefined) {\n lines.push(` ${formatStream(prop.stream)}`);\n }\n }\n }\n if (report.environment.length > 0) {\n lines.push('environment:');\n for (const entry of report.environment) {\n lines.push(` ${entry.key} = ${entry.value}${entry.provided ? ' (provided here)' : ''}`);\n }\n }\n if (report.semantics !== undefined) {\n const parts = [\n report.semantics.role === undefined ? undefined : `role ${report.semantics.role}`,\n report.semantics.label === undefined ? undefined : `label ${report.semantics.label}`,\n report.semantics.value === undefined ? undefined : `value ${report.semantics.value}`,\n report.semantics.states === undefined || report.semantics.states.length === 0\n ? undefined\n : `states ${report.semantics.states.join(', ')}`\n ].filter(part => part !== undefined);\n if (parts.length > 0) {\n lines.push(`semantics: ${parts.join(' · ')}`);\n }\n }\n lines.push(report.explanation);\n return lines.join('\\n');\n}\n","import { printPropValue } from '../app/NodeReport';\nimport type { ConsoleEntry } from '../app/DevtoolsProtocol';\n\n/**\n * Forwarding a worker's `console.*`.\n *\n * A worker's console is real, but it is in devtools' worker target,\n * which a developer has to know to select and cannot read alongside\n * the page's. So while a devtools panel asks for it, each `console.*`\n * call in the worker is also handed to a sink as plain strings, with\n * the thread named, and the panel shows the three threads as one log.\n *\n * The call still reaches the worker's own console: this is a copy,\n * not a redirect, so turning a panel on changes nothing about what\n * devtools' worker target shows.\n */\n\nexport type ConsoleLevel = ConsoleEntry['level'];\n\nconst LEVELS: readonly ConsoleLevel[] = ['log', 'info', 'warn', 'error', 'debug'];\n\n/** An entry before the shell has said which thread it came from. */\nexport type ConsoleEntryBody = Omit<ConsoleEntry, 'thread'>;\n\n/**\n * Copies every `console.*` call on `target` (the worker global's\n * console by default) to `sink`. Returns a function that restores the\n * original methods.\n *\n * Idempotent per target: a second capture on the same console replaces\n * the first's sink rather than nesting, so toggling a panel on twice\n * does not log twice.\n */\nexport function captureConsole(sink: (entry: ConsoleEntryBody) => void, target: Console = console): () => void {\n const installed = (target as Console & { [CAPTURED]?: { sink: typeof sink; restore: () => void } })[CAPTURED];\n if (installed !== undefined) {\n installed.sink = sink;\n return installed.restore;\n }\n const originals = new Map<ConsoleLevel, (...args: unknown[]) => void>();\n const state = {\n sink,\n restore: (): void => {\n for (const [level, original] of originals) {\n target[level] = original;\n }\n delete (target as Console & { [CAPTURED]?: unknown })[CAPTURED];\n }\n };\n for (const level of LEVELS) {\n const original = target[level] as (...args: unknown[]) => void;\n originals.set(level, original);\n target[level] = (...args: unknown[]): void => {\n original.apply(target, args);\n // A sink that throws must not break the application's logging,\n // least of all while a developer is trying to read it.\n try {\n state.sink({ level, args: args.map(formatConsoleArg), at: Date.now() });\n } catch {\n // Nothing to do: the original call already ran.\n }\n };\n }\n (target as Console & { [CAPTURED]?: typeof state })[CAPTURED] = state;\n return state.restore;\n}\n\nconst CAPTURED = Symbol.for('gesso:console-captured');\n\n/**\n * One console argument as the panel prints it.\n *\n * `printPropValue` already prints the values a canvas UI is likely to\n * log; an Error is the one thing it prints badly (`{}`), and the one\n * thing a developer most wants to read whole.\n */\nexport function formatConsoleArg(value: unknown): string {\n if (value instanceof Error) {\n return value.stack !== undefined && value.stack !== '' ? value.stack : `${value.name}: ${value.message}`;\n }\n return printPropValue(value);\n}\n\n/** The shell's request to an application worker to start or stop forwarding. */\nexport interface ConsoleForwardingMessage {\n type: 'gesso:console';\n enabled: boolean;\n}\n\n/** An application worker's forwarded entry. */\nexport interface ConsoleEntryMessage {\n type: 'gesso:console';\n entry: ConsoleEntryBody;\n}\n\nexport function isConsoleForwardingMessage(value: unknown): value is ConsoleForwardingMessage {\n const message = value as { type?: unknown; enabled?: unknown } | null;\n return message?.type === 'gesso:console' && typeof message.enabled === 'boolean';\n}\n\nexport function isConsoleEntryMessage(value: unknown): value is ConsoleEntryMessage {\n const message = value as { type?: unknown; entry?: unknown } | null;\n return message?.type === 'gesso:console' && typeof message.entry === 'object' && message.entry !== null;\n}\n","/**\n * Named `MessagePort`s into a worker.\n *\n * A worker's global `onmessage` is a single channel, so a worker that\n * receives messages on it can host exactly one conversation. That is\n * why a store in a data worker used to mean a worker per store: the\n * client claimed the `Worker` object itself, and a second one had\n * nowhere to go.\n *\n * A handshake fixes it. The client opens a `MessageChannel`, keeps one\n * end and transfers the other with a name; the worker serves that name\n * and the two ends talk privately from then on. The global channel is\n * used once per conversation and carries nothing else.\n *\n * Nothing here knows what travels over a port. It is the transport the\n * store replication in `../store/worker` runs on today and the barrier\n * contract will run on next.\n */\n\nimport { captureConsole, isConsoleForwardingMessage, type ConsoleEntryMessage } from './captureConsole';\n\n/** A port-shaped thing: `MessagePort` and `Worker` both satisfy it. */\nexport interface MessageEndpoint {\n postMessage(message: unknown): void;\n onmessage: ((event: { data: unknown }) => void) | null;\n}\n\n/** The one message the global channel carries. */\nexport interface PortHandshake {\n type: 'gesso:port';\n key: string;\n}\n\nexport function isPortHandshake(value: unknown): value is PortHandshake {\n const message = value as { type?: unknown; key?: unknown } | null;\n return message?.type === 'gesso:port' && typeof message.key === 'string';\n}\n\n/**\n * A worker spawned at most once, serving any number of named ports.\n *\n * Handed to several `useChannel` calls, it is what lets one worker\n * hold a whole application layer instead of one channel. Spawning is\n * deferred to the first `open`, so a handle nobody uses costs nothing.\n */\nexport interface WorkerHandle {\n /**\n * Opens a private channel under `key`, spawning the worker if this\n * is the first one.\n */\n open(key: string): MessagePort;\n /** Whether the worker has been spawned. */\n readonly spawned: boolean;\n /** Stops the worker, if it was ever started. */\n terminate(): void;\n}\n\n/**\n * Stands for \"whichever worker the shell spawned for the application\".\n *\n * A registration inside the render worker cannot name that worker: it\n * is created by the shell and its port only arrives with `init`, long\n * after `useChannel` and `useService` have run. This sentinel is what a\n * registration puts there instead, and the render worker swaps it for\n * the real handle once the port shows up.\n *\n * Opening a port on it before then is a bug rather than a race, so it\n * says so.\n */\nexport const APPLICATION_WORKER: WorkerHandle = {\n open(): MessagePort {\n throw new Error(\n 'APPLICATION_WORKER was used directly. It is a placeholder the render worker ' +\n \"replaces with the shell's port; reaching it means no application-logic worker was supplied. \" +\n 'Pass appLogicWorker to createApp.'\n );\n },\n spawned: false,\n terminate(): void {}\n};\n\n/**\n * Anything a handshake can be posted to with a port attached.\n * `Worker` and `MessagePort` both satisfy it.\n */\nexport interface TransferTarget {\n postMessage(message: unknown, transfer: Transferable[]): void;\n}\n\n/**\n * A handle over an endpoint someone else owns.\n *\n * The shell spawns the application worker and hands the render worker\n * one end of a channel to it; this is what the render worker opens\n * named ports over. `terminate` is a no-op — the lifetime belongs to\n * whoever created the endpoint, and a handle that could kill a worker\n * it did not spawn would be a surprising thing to hand out.\n */\nexport function portHandle(endpoint: TransferTarget): WorkerHandle {\n return {\n open(key: string): MessagePort {\n const channel = new MessageChannel();\n endpoint.postMessage({ type: 'gesso:port', key } satisfies PortHandshake, [channel.port2]);\n return channel.port1;\n },\n get spawned(): boolean {\n return true;\n },\n terminate(): void {}\n };\n}\n\n/**\n * Routes handshakes arriving on a transferred port through the same\n * handlers as the worker's own global channel.\n *\n * The shell owns the application worker and gives the render worker a\n * port to it, so handshakes reach this worker two ways: on its global\n * channel (whoever spawned it) and on that port (whoever was given\n * it). Both should be served by the same handlers, and neither end\n * should have to know which route a channel came in on.\n */\nexport interface HubMessage {\n type: 'gesso:hub';\n}\n\nexport function isHubMessage(value: unknown): value is HubMessage {\n return (value as { type?: unknown } | null)?.type === 'gesso:hub';\n}\n\nconst BASE_INSTALLED = Symbol.for('gesso:port-base-installed');\nconst CONSOLE_RESTORE = Symbol.for('gesso:port-console-restore');\n\n/**\n * Starts or stops copying this worker's console to whoever posts to\n * it, as `ConsoleEntryMessage`s. A host with no `postMessage` (a test's\n * bare object) has nowhere to send them and forwards nothing.\n */\nfunction setConsoleForwarding(host: PortHost & { [CONSOLE_RESTORE]?: () => void }, enabled: boolean): void {\n host[CONSOLE_RESTORE]?.();\n delete host[CONSOLE_RESTORE];\n const post = (host as { postMessage?: (message: unknown) => void }).postMessage;\n if (!enabled || typeof post !== 'function') {\n return;\n }\n host[CONSOLE_RESTORE] = captureConsole(entry => {\n const message: ConsoleEntryMessage = { type: 'gesso:console', entry };\n post.call(host, message);\n });\n}\n\n/**\n * The handler every `servePorts` chain sits on top of.\n *\n * It owns the two things no individual server can: routing a hub port\n * through the whole chain, and answering a handshake that nobody\n * accepted. Both have to be innermost — the first because the chain is\n * only complete once every server has wrapped `onmessage`, the second\n * because \"nobody accepted\" is only known after every server has\n * declined.\n */\nfunction installBase(host: PortHost & { [BASE_INSTALLED]?: boolean }): void {\n if (host[BASE_INSTALLED] === true) {\n return;\n }\n host[BASE_INSTALLED] = true;\n const previous = host.onmessage;\n const registered = (host as HostWithNames)[SERVED_NAMES] ?? [];\n\n host.onmessage = event => {\n if (isConsoleForwardingMessage(event.data)) {\n // The shell, on behalf of a devtools panel, asking for this\n // worker's console. Answered here because this is the one handler\n // every application worker has, whatever it serves.\n setConsoleForwarding(host, event.data.enabled);\n return;\n }\n if (isHubMessage(event.data)) {\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error('A hub message arrived with no port attached.');\n }\n // The whole chain, not just this handler: by now every\n // `servePorts` on this host has wrapped `onmessage`, and a\n // handshake arriving on the port should reach all of them.\n port.onmessage = host.onmessage;\n return;\n }\n if (!isPortHandshake(event.data)) {\n previous?.(event);\n return;\n }\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error(`Port handshake for '${event.data.key}' arrived with no port attached.`);\n }\n // Reaching here means every server declined. Silence would leave\n // the client waiting forever with nothing said.\n const served = registered.flatMap(get => [...get()]).sort();\n const error: PortErrorMessage = {\n type: 'port:error',\n message: `Nothing is served under '${event.data.key}'. This worker serves: ${\n served.length > 0 ? served.join(', ') : '(nothing)'\n }.`\n };\n port.postMessage(error);\n };\n}\n\n/**\n * Wraps a worker factory so the worker is created once and shared.\n *\n * A factory rather than a URL for the same reason the render worker\n * takes one: a bundler only emits a chunk for a worker it can see\n * constructed literally in the calling module.\n *\n * const data = workerHandle(\n * () => new Worker(new URL('./data.worker.ts', import.meta.url), { type: 'module' })\n * );\n */\nexport function workerHandle(factory: () => Worker): WorkerHandle {\n let worker: Worker | undefined;\n return {\n open(key: string): MessagePort {\n worker ??= factory();\n const channel = new MessageChannel();\n // The worker may not have run its module body yet. Messages\n // posted to a worker queue until it installs a handler, so the\n // handshake is safe as long as `servePorts` is called\n // synchronously at the top level of the worker module — the same\n // guarantee `renderRoot` relies on.\n worker.postMessage({ type: 'gesso:port', key } satisfies PortHandshake, [channel.port2]);\n return channel.port1;\n },\n get spawned(): boolean {\n return worker !== undefined;\n },\n terminate(): void {\n worker?.terminate();\n worker = undefined;\n }\n };\n}\n\n/**\n * Minimal view of a worker's global scope, so this module type-checks\n * against the DOM lib without pulling in the WebWorker lib.\n */\nexport interface PortHost {\n onmessage: ((event: { data: unknown; ports?: readonly MessagePort[] }) => void) | null;\n}\n\n/**\n * What a port is answered with when no handler claimed its name.\n *\n * Its own message type rather than a store's or a channel's, because\n * the transport does not know which of them the client is: both\n * recognise it, so a mismatched name is loud either way.\n */\nexport interface PortErrorMessage {\n type: 'port:error';\n message: string;\n}\n\nexport function isPortErrorMessage(value: unknown): value is PortErrorMessage {\n const message = value as { type?: unknown; message?: unknown } | null;\n return message?.type === 'port:error' && typeof message.message === 'string';\n}\n\n/** Every name served on a host, across all `servePorts` calls on it. */\nconst SERVED_NAMES = Symbol.for('gesso:served-port-names');\n\ninterface HostWithNames extends PortHost {\n [SERVED_NAMES]?: Array<() => readonly string[]>;\n}\n\n/**\n * Serves named ports inside a worker.\n *\n * Call it synchronously at the top level of the worker module, before\n * any await, so no handshake is missed.\n *\n * `onPort` returns whether it took the port. Returning false passes\n * the handshake to whatever was serving before, which is what lets two\n * kinds of thing — stores and channels, during the migration — share\n * one worker: each answers for its own names and declines the rest.\n * When nobody accepts, the port is answered with an error naming\n * everything the worker does serve, because a handshake that silently\n * matched nothing leaves the client waiting forever with nothing said.\n *\n * `names` is only read to build that message.\n *\n * Returns a function that stops serving.\n */\nexport function servePorts(\n onPort: (key: string, port: MessagePort) => boolean,\n names: () => readonly string[],\n host: PortHost = self as unknown as PortHost\n): () => void {\n const withNames = host as HostWithNames;\n const registered = (withNames[SERVED_NAMES] ??= []);\n registered.push(names);\n // Before this handler wraps `onmessage`, so the base ends up\n // innermost: it answers a handshake only once every server above it\n // has declined.\n installBase(host);\n\n const previous = host.onmessage;\n host.onmessage = event => {\n if (!isPortHandshake(event.data)) {\n // Not ours. A worker that also speaks its own protocol on the\n // global channel keeps working.\n previous?.(event);\n return;\n }\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error(`Port handshake for '${event.data.key}' arrived with no port attached.`);\n }\n if (onPort(event.data.key, port)) {\n return;\n }\n // Declined. Another server may take it; the base answers if none\n // does.\n previous?.(event);\n };\n return () => {\n host.onmessage = previous;\n const index = registered.indexOf(names);\n if (index >= 0) {\n registered.splice(index, 1);\n }\n };\n}\n","import type { Observable } from 'rxjs';\n\nimport { servePorts, type PortHost } from '../worker/WorkerPorts';\nimport { provide, type ChannelSource, ProvidedChannel } from './provide';\nimport type { ChannelPort } from './ChannelProtocol';\nimport type { ChannelToken, Command, CommandMap } from './ChannelToken';\n\n/**\n * One channel a worker offers: its token and what feeds it.\n *\n * Types erased structurally, for the same reason `ChannelRegistration`\n * erases them — a list of channels has no single generic\n * instantiation, and making every caller cast to reach one is worse\n * than describing what is actually needed.\n */\nexport interface ServedChannel {\n token: { name: string; initial: object };\n source: {\n view: Record<string, Observable<unknown>>;\n commands?: Record<string, Command>;\n };\n}\n\n/**\n * One served channel, with its source checked against its token.\n *\n * `ServedChannel` is erased on purpose, so one list can hold channels\n * of every shape; the cost is that a view key the token declares and\n * the source forgets is found at startup, by the error `provide`\n * reports, rather than by the compiler. This is the typed seam: the\n * source must hold an Observable for every key of the token's view and\n * a handler for every command, and each handler takes the arguments\n * the token declares, so none of them needs an annotation.\n *\n * serveChannels([\n * serve(Catalog, { view: catalog, commands: { add: name => catalog.add(name) } })\n * ]);\n *\n * The view may be any object with the right observables on it, which\n * is often the domain object itself when its properties are named\n * after the keys. Only the declared keys are read from it.\n */\nexport function serve<View extends object, Commands extends object>(\n token: ChannelToken<View, Commands>,\n source: ChannelSource<View, Commands>\n): ServedChannel {\n return { token, source: source as unknown as ServedChannel['source'] };\n}\n\n/**\n * Publishes channels from an application worker.\n *\n * Call it synchronously at the top level of the worker module, before\n * any await, so no handshake is missed:\n *\n * const catalog = new CatalogViewModel(new CatalogDomain(new OpfsStore()));\n * serveChannels([\n * serve(Catalog, { view: { products: catalog.products$ }, commands: { … } })\n * ]);\n *\n * Everything above this call is the application's own — plain classes,\n * plain observables, no framework import. This function is the entire\n * seam between it and the view.\n *\n * Returns a function that stops serving and disposes what it provided.\n */\nexport function serveChannels(channels: readonly ServedChannel[], host?: PortHost): () => void {\n const byName = new Map<string, ServedChannel>();\n for (const served of channels) {\n byName.set(served.token.name, served);\n }\n const provided: ProvidedChannel[] = [];\n\n const stop = servePorts(\n (key, port) => {\n const served = byName.get(key);\n if (served === undefined) {\n // Declined rather than answered, so a worker serving more than\n // one kind of thing can pass the handshake along. `servePorts`\n // reports it if nothing takes it.\n return false;\n }\n provided.push(\n provide(\n served.token as ChannelToken<object, CommandMap>,\n served.source as unknown as ChannelSource<object, CommandMap>,\n port as unknown as ChannelPort\n )\n );\n return true;\n },\n () => [...byName.keys()],\n host\n );\n\n return () => {\n stop();\n for (const channel of provided) {\n channel.dispose();\n }\n provided.length = 0;\n };\n}\n","import { distinctUntilChanged, map, type Observable } from 'rxjs';\n\n/**\n * One key of a view model, as its own Observable, emitting only when\n * that key's value changes.\n *\n * `provide` and `serveChannels` want one Observable per view key, so\n * the differ can patch each key on its own, while a view model is most\n * naturally one Observable of one object. This is the seam between the\n * two, and every application worker was about to write it.\n */\nexport function pick<T, K extends keyof T>(source: Observable<T>, key: K): Observable<T[K]> {\n return source.pipe(\n map(value => value[key]),\n distinctUntilChanged()\n );\n}\n\n/**\n * Every key of a view model as its own Observable: the `view` a channel\n * source wants, from the one Observable a view model has.\n *\n * serveChannels([{ token: Queue, source: { view: pickKeys(queue.view, QUEUE_KEYS), commands } }])\n */\nexport function pickKeys<T extends object, K extends keyof T>(\n source: Observable<T>,\n keys: readonly K[]\n): { readonly [P in K]: Observable<T[P]> } {\n const out: Partial<{ [P in K]: Observable<T[P]> }> = {};\n for (const key of keys) {\n out[key] = pick(source, key);\n }\n return out as { readonly [P in K]: Observable<T[P]> };\n}\n","/**\n * What a store did with a request.\n *\n * Four words rather than an exception, because three of them are\n * ordinary outcomes an application routes around rather than faults it\n * reports. A browser that refuses storage in a private window, and a\n * quota that has run out, are both things a running application has to\n * carry on through, and making every caller wrap a `try` around a read\n * to discover which one happened is how storage code ends up assuming\n * success.\n *\n * - `ok`: the store answered. For a read that includes \"there is no\n * such record\", which is `value: null` and not a failure.\n * - `denied`: the platform will not let this origin store anything.\n * No OPFS in this browser, a private window that refuses IndexedDB,\n * `localStorage` blocked by a site setting. Permanent for the\n * session: nothing an application does will change the answer, so\n * asking again is wasted work.\n * - `full`: the quota is spent. Temporary, and worth trying again\n * after something has been given back, which is why it is not\n * `denied`.\n * - `failed`: anything else. A half-written file, a corrupt database,\n * a transaction that aborted for a reason the platform did not\n * explain.\n */\nexport type StorageOutcome = 'ok' | 'denied' | 'full' | 'failed';\n\n/** What came back from a read. */\nexport interface StorageRead {\n readonly outcome: StorageOutcome;\n /** The record, or null when there is none or the read did not answer. */\n readonly value: string | null;\n /** Why it did not answer, as a message; null when it did. */\n readonly error: string | null;\n}\n\n/**\n * Somewhere an application's state survives being closed.\n *\n * Four methods over text keyed by a string, which is the shape all\n * three implementations can actually keep. Bytes are deliberately not\n * in it: `localStorage` cannot hold them, so an interface that\n * promised them would be one the shell route could not implement, and\n * an application storing pictures wants a store of its own with an\n * eviction policy rather than this. the\n * artwork cache is that other thing.\n *\n * Nothing rejects. Every method answers with an outcome, and the\n * per-failure behaviour is the implementation's to document; the three\n * in this package all follow `classifyStorageError`.\n *\n * It is a shape and not a service. Nothing in the framework holds one,\n * `persisted` takes whichever one it is given, and an application with\n * its own store implements four methods rather than adopting anything.\n */\nexport interface StorageAdapter {\n /** Reads one record. */\n read(key: string): Promise<StorageRead>;\n /** Writes one record, replacing whatever was there. */\n write(key: string, value: string): Promise<StorageOutcome>;\n /** Removes one record. Removing what is not there is `ok`. */\n remove(key: string): Promise<StorageOutcome>;\n /** Every key this store holds, for an application that evicts its own. */\n keys(): Promise<readonly string[]>;\n}\n\n/**\n * Which of the four outcomes a thrown platform error is.\n *\n * The names are the ones the storage APIs actually throw.\n * `QuotaExceededError` is the DOM's word for full, and every browser\n * uses it for OPFS, IndexedDB and `localStorage` alike. `SecurityError`\n * and `NotAllowedError` are what a blocked origin gets. A missing API\n * (no `navigator.storage`, no `indexedDB`) is a `TypeError` here and\n * is `denied` for the same reason: nothing the application does will\n * produce a store.\n */\nexport function classifyStorageError(error: unknown): StorageOutcome {\n const name = error instanceof Error ? error.name : '';\n if (name === 'QuotaExceededError' || name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n return 'full';\n }\n if (name === 'SecurityError' || name === 'NotAllowedError' || name === 'TypeError') {\n return 'denied';\n }\n return 'failed';\n}\n\n/** A thrown value as the message a screen could show. */\nexport function storageErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** A read that could not answer, as one record. */\nexport function storageReadFailure(error: unknown): StorageRead {\n return { outcome: classifyStorageError(error), value: null, error: storageErrorMessage(error) };\n}\n\n/** A read that answered, whether or not it found anything. */\nexport function storageReadValue(value: string | null): StorageRead {\n return { outcome: 'ok', value, error: null };\n}\n\n/**\n * The same contract in memory, for specs and for a platform with no\n * store at all.\n *\n * Not a fallback anything installs on its own. An application that\n * would rather run with an unremembered session than fail says so by\n * passing one of these; one that would rather tell the person its\n * settings will not be kept reads the `denied` outcome and says so.\n * Choosing between those two on an application's behalf is exactly the\n * kind of decision the thread model keeps out of the framework.\n */\nexport class MemoryStorage implements StorageAdapter {\n private readonly records = new Map<string, string>();\n /** Written by a spec that wants to see what a full store does. */\n full = false;\n\n read(key: string): Promise<StorageRead> {\n return Promise.resolve(storageReadValue(this.records.get(key) ?? null));\n }\n\n write(key: string, value: string): Promise<StorageOutcome> {\n if (this.full) {\n return Promise.resolve('full');\n }\n this.records.set(key, value);\n return Promise.resolve('ok');\n }\n\n remove(key: string): Promise<StorageOutcome> {\n this.records.delete(key);\n return Promise.resolve('ok');\n }\n\n keys(): Promise<readonly string[]> {\n return Promise.resolve([...this.records.keys()]);\n }\n}\n","import { computed, type ComputedCell } from '../computed';\nimport { internalState, type InternalState } from '../InternalState';\nimport { select } from '../select';\n\n/** One undoable change, as the two functions that make and unmake it. */\nexport interface UndoTransaction {\n /**\n * What a menu item or a toast calls this change: \"Move Sunset\",\n * \"Remove Sunset from the queue\".\n *\n * A phrase rather than a sentence, because the words around it are\n * the caller's: an application writes \"Undo \" in front of it.\n */\n readonly label: string;\n /** Puts the world back the way it was before `redo` ran. */\n readonly undo: () => void;\n /** Makes the change again, from wherever `undo` left things. */\n readonly redo: () => void;\n /**\n * Merges this into the entry before it when the two keys match.\n *\n * A drag reports a crossing per row and a typed name reports a\n * keystroke, and neither is a change a person means to undo one step\n * at a time. Entries pushed one after another under the same key\n * become one entry: **the first one's `undo` and the last one's\n * `redo`**, with everything between them dropped.\n *\n * That merge rule is what makes the two functions above worth\n * writing as absolute moves rather than as deltas. `undo` should say\n * where the thing goes, not how far back it goes, because after\n * three more coalesced steps a delta is wrong and a position is\n * still right. See `endRun` for where a run stops.\n */\n readonly coalesce?: string;\n}\n\nexport interface UndoStackOptions {\n /**\n * How many entries are kept, oldest dropped first. Default 100.\n *\n * A bound rather than a growing list, for the reason\n * `EditableTextModel` has one: an application that is used for an\n * afternoon would otherwise hold every intermediate state of that\n * afternoon, and nobody undoes a hundred steps.\n */\n readonly limit?: number;\n /** What to call the stack in a devtools reading; optional. */\n readonly label?: string;\n}\n\n/** The two labels, as one record so a menu reads them in one go. */\ninterface UndoLabels {\n readonly undo: string | null;\n readonly redo: string | null;\n}\n\nconst NOTHING: UndoLabels = { undo: null, redo: null };\n\n/**\n * The application's undo, as a stack of named transactions.\n *\n * A component registers what it did and how to unmake it, and a menu,\n * a button or a keyboard shortcut drives the stack. Nothing here\n * listens to anything or knows what an application's state is: the two\n * functions in a transaction are the whole of the coupling, which is\n * why this can sit on either thread and why it does not become a data\n * layer.\n *\n * const undo = ctx.inject(UndoStack);\n *\n * queue.send.remove(at);\n * undo.push({\n * label: `Remove ${track.title}`,\n * undo: () => queue.send.addToQueue(track.id),\n * redo: () => queue.send.remove(at)\n * });\n *\n * ## How this relates to the undo inside a text field\n *\n * `EditableTextModel` has had its own undo since text became editable,\n * and the two are deliberately separate. A field's undo is a stack of\n * **snapshots of one string**, private to the field, and it has to be:\n * the model is the only thing that knows where the caret was, which\n * run of typing coalesces with which, and what an IME composition is\n * doing. This one is a stack of **inverse operations** over whatever\n * an application's state happens to be, and it cannot see inside a\n * field at all.\n *\n * They meet at one key press, and the rule there is that the focused\n * field wins: `registerUndoShortcuts` skips Mod+Z while something is\n * being typed into, so undo in a field undoes typing and undo\n * everywhere else undoes the application's last change. Merging the\n * two stacks would mean a keystroke and a queue reorder sharing one\n * history, which is not what either of them means.\n *\n * ## Reentrancy\n *\n * A push while an undo or a redo is running is dropped. Without it an\n * application whose edit path records itself would record the undo as\n * a new edit and the stack would never empty. Write the inverse\n * functions to call the state directly rather than through the same\n * path that records, and the guard never fires.\n */\nexport class UndoStack {\n private readonly entries: UndoTransaction[] = [];\n private readonly undone: UndoTransaction[] = [];\n private readonly limit: number;\n /** True while `undo()` or `redo()` is running one of the functions. */\n private running = false;\n /** Set by `endRun`, so the next push starts a new entry whatever its key. */\n private sealed = false;\n\n private readonly labels: InternalState<UndoLabels>;\n\n /** What undoing would undo, or null when there is nothing to undo. */\n readonly undoLabel: ComputedCell<string | null>;\n /** What redoing would redo, or null when there is nothing to redo. */\n readonly redoLabel: ComputedCell<string | null>;\n /** Whether there is anything to undo, for a menu item's `disabled`. */\n readonly canUndo: ComputedCell<boolean>;\n readonly canRedo: ComputedCell<boolean>;\n\n constructor(options: UndoStackOptions = {}) {\n this.limit = Math.max(1, options.limit ?? 100);\n this.labels = internalState<UndoLabels>(NOTHING, options.label);\n this.undoLabel = select(this.labels, 'undo');\n this.redoLabel = select(this.labels, 'redo');\n this.canUndo = computed(() => this.undoLabel.value !== null);\n this.canRedo = computed(() => this.redoLabel.value !== null);\n }\n\n /** How many entries are held, for a spec or a budget. */\n get size(): number {\n return this.entries.length;\n }\n\n /** How many redos are waiting, for a spec or a budget. */\n get redoSize(): number {\n return this.undone.length;\n }\n\n /**\n * Records a change that has already been made.\n *\n * Pushing is what discards the redo branch: making a change after\n * undoing two is the person choosing the other future, and keeping\n * the abandoned one would mean redoing into a state that no longer\n * follows from what is on screen.\n */\n push(transaction: UndoTransaction): void {\n if (this.running) {\n return;\n }\n this.undone.length = 0;\n const previous = this.entries[this.entries.length - 1];\n const sealed = this.sealed;\n this.sealed = false;\n if (\n !sealed &&\n previous !== undefined &&\n transaction.coalesce !== undefined &&\n previous.coalesce === transaction.coalesce\n ) {\n // The run's own undo, kept from its first step, and its newest\n // redo. Every step in between is released here, which is the\n // whole of what stops a drag across sixty rows retaining sixty\n // closures and the sixty values they close over.\n this.entries[this.entries.length - 1] = {\n label: transaction.label,\n undo: previous.undo,\n redo: transaction.redo,\n coalesce: transaction.coalesce\n };\n this.publish();\n return;\n }\n this.entries.push(transaction);\n while (this.entries.length > this.limit) {\n this.entries.shift();\n }\n this.publish();\n }\n\n /**\n * Groups everything pushed inside `body` into one entry.\n *\n * For a change an application makes as several calls and a person\n * made as one press: undoing runs the group's undos in reverse, and\n * redoing runs its redos in order. Unlike `coalesce`, a group keeps\n * every step, because a group is written down as a group rather than\n * discovered from a run of similar pushes.\n */\n transact<R>(label: string, body: () => R): R {\n if (this.running) {\n return body();\n }\n const outer = this.entries.length;\n const result = body();\n const collected = this.entries.splice(outer);\n if (collected.length > 0) {\n this.entries.push({\n label,\n undo: () => {\n for (let at = collected.length - 1; at >= 0; at--) {\n collected[at]!.undo();\n }\n },\n redo: () => {\n for (const step of collected) {\n step.redo();\n }\n }\n });\n this.sealed = true;\n this.publish();\n }\n return result;\n }\n\n /**\n * Ends the current run, so the next push starts its own entry.\n *\n * The twin of `EditableTextModel.endTypingRun`. A drag calls it when\n * the pointer comes up: without it, dragging a row, letting go, and\n * dragging the same row again would coalesce into one entry, and one\n * undo would put the row back where it was two gestures ago.\n */\n endRun(): void {\n this.sealed = true;\n }\n\n /** Undoes the last change. False when there was nothing to undo. */\n undo(): boolean {\n const entry = this.entries.pop();\n if (entry === undefined) {\n return false;\n }\n this.run(entry.undo);\n this.undone.push(entry);\n this.sealed = true;\n this.publish();\n return true;\n }\n\n /** Redoes the last undone change. False when there was nothing to redo. */\n redo(): boolean {\n const entry = this.undone.pop();\n if (entry === undefined) {\n return false;\n }\n this.run(entry.redo);\n this.entries.push(entry);\n this.sealed = true;\n this.publish();\n return true;\n }\n\n /**\n * Forgets everything, in both directions.\n *\n * What an application calls when the thing the entries refer to is\n * gone: a queue emptied, a document closed, a signed-out account's\n * library replaced. `EditableTextModel.setText` does the same for\n * the same reason, and the reason is that an inverse function whose\n * subject no longer exists is not an undo, it is a surprise.\n */\n clear(): void {\n this.entries.length = 0;\n this.undone.length = 0;\n this.sealed = false;\n this.publish();\n }\n\n private run(action: () => void): void {\n this.running = true;\n try {\n action();\n } finally {\n this.running = false;\n }\n }\n\n private publish(): void {\n const next: UndoLabels = {\n undo: this.entries[this.entries.length - 1]?.label ?? null,\n redo: this.undone[this.undone.length - 1]?.label ?? null\n };\n // Structural comparison rather than a write per push: coalescing a\n // drag rewrites the same label sixty times, and a menu bound to\n // these should redraw when the words change and not before.\n if (next.undo !== this.labels.value.undo || next.redo !== this.labels.value.redo) {\n this.labels.value = next;\n }\n }\n}\n","import type { Mutation } from '../mutate';\nimport type { UndoStack } from './UndoStack';\n\nexport interface UndoableOptions<A> {\n /** What the entry is called, from the argument that made it. */\n readonly label: string | ((argument: A) => string);\n /** The coalescing key, from the argument; see `UndoTransaction.coalesce`. */\n readonly coalesce?: string | ((argument: A) => string);\n}\n\n/**\n * Puts a `mutate` on an undo stack, by way of its own inverse.\n *\n * private readonly liked = internalState<readonly string[]>([]);\n * private readonly like = mutate(this.liked, toggled, id => api.favourite(id));\n * readonly toggleLike = undoable(undo, this.like, id => id, { label: () => 'Like' });\n *\n * The whole of it is that undoing an optimistic change is another\n * optimistic change. Nothing here writes the cell behind the\n * mutation's back, which is the thing that would go wrong if an undo\n * stack held values rather than operations: it would restore a value\n * the server has not been told about, and the next rollback would\n * fight it.\n *\n * `invert` answers the argument that undoes this one. For a toggle\n * that is the same argument again, which is why the example above\n * looks like it does nothing.\n *\n * **A refused write is not on the stack.** `mutate` already puts the\n * cell back when a commit rejects or resolves `false`, so the change\n * did not happen and there is nothing to undo; pushing it would give a\n * person an undo that undoes something they never saw.\n *\n * The undo and the redo call `mutation.run` rather than this wrapper,\n * so running them records nothing and the stack's reentrancy guard\n * never has to fire.\n */\nexport function undoable<A>(\n stack: UndoStack,\n mutation: Mutation<A>,\n invert: (argument: A) => A,\n options: UndoableOptions<A>\n): (argument: A) => Promise<boolean> {\n const { label, coalesce } = options;\n return async (argument: A): Promise<boolean> => {\n if (!(await mutation.run(argument))) {\n return false;\n }\n stack.push({\n label: typeof label === 'function' ? label(argument) : label,\n undo: () => void mutation.run(invert(argument)),\n redo: () => void mutation.run(argument),\n ...(coalesce === undefined ? {} : { coalesce: typeof coalesce === 'function' ? coalesce(argument) : coalesce })\n });\n return true;\n };\n}\n","import {\n classifyStorageError,\n storageReadFailure,\n storageReadValue,\n type StorageAdapter,\n type StorageOutcome,\n type StorageRead\n} from './StorageAdapter';\n\n/**\n * As much of the Origin Private File System as a store needs.\n *\n * Written out rather than taken from `lib.dom`, for two reasons. The\n * workspace's `lib` is `ES2023` and `DOM`, which has the handles but\n * not the async iteration `values()` needs, and a structural type is\n * what lets a spec hand this a directory of its own instead of\n * standing up a file system to test four methods.\n */\nexport interface OpfsDirectory {\n getFileHandle(name: string, options?: { create?: boolean }): Promise<OpfsFileHandle>;\n getDirectoryHandle(name: string, options?: { create?: boolean }): Promise<OpfsDirectory>;\n removeEntry(name: string): Promise<void>;\n keys(): AsyncIterable<string>;\n}\n\nexport interface OpfsFileHandle {\n getFile(): Promise<{ text(): Promise<string> }>;\n createWritable(): Promise<OpfsWritable>;\n}\n\nexport interface OpfsWritable {\n write(data: string): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface OpfsStorageOptions {\n /**\n * The folder under the origin's private root, so two stores in one\n * application do not share a namespace. Default `'gesso'`.\n */\n readonly directory?: string;\n /** The root, for a spec. Default `navigator.storage.getDirectory()`. */\n readonly root?: () => Promise<OpfsDirectory>;\n}\n\n/**\n * A store in the origin's private file system.\n *\n * The right default for an application's own state. It is reachable\n * from a worker, which `localStorage` is not, so the thread that owns\n * the state is the thread that writes it and nothing has to cross the\n * barrier to be remembered. It is asynchronous throughout, so nothing\n * it does blocks a frame. And it is per-origin and invisible to the\n * person, which is the right place for a queue or a draft and the\n * wrong place for anything they should be able to find and delete.\n *\n * One file per key, named by the key with the characters a file system\n * would refuse escaped, so a key is recoverable from a listing and a\n * key containing a slash cannot reach out of the folder.\n *\n * What happens on each failure:\n *\n * - **The platform has no OPFS**, or the browser refuses it (a private\n * window, a blocked origin): every method answers `denied` and the\n * error message says which. The store is not usable this session and\n * `persisted` stops writing to it after the first denial.\n * - **The quota is spent**: the write answers `full`. Nothing is\n * rolled back, because the value the application holds is the real\n * one and only the remembering failed.\n * - **There is no such record**: the read answers `ok` with `null`.\n * Not having been written yet is the ordinary first run, not a\n * failure.\n * - **Anything else**: `failed`, with the platform's message. A file\n * whose *contents* are not what this version writes is a different\n * thing and is `persisted`'s to judge, which it does by discarding\n * it, the same call `Tokens.ts` makes.\n */\nexport class OpfsStorage implements StorageAdapter {\n private readonly folder: string;\n private readonly rootOf: () => Promise<OpfsDirectory>;\n /** The folder, once opened. Reused, because opening it is a round trip. */\n private opening: Promise<OpfsDirectory> | null = null;\n\n constructor(options: OpfsStorageOptions = {}) {\n this.folder = options.directory ?? 'gesso';\n this.rootOf = options.root ?? defaultRoot;\n }\n\n async read(key: string): Promise<StorageRead> {\n try {\n const directory = await this.open();\n const handle = await directory.getFileHandle(fileFor(key));\n return storageReadValue(await (await handle.getFile()).text());\n } catch (error) {\n // A file that is not there is the ordinary answer to \"is\n // anything remembered\", and the platform says so by throwing\n // `NotFoundError`. It is not a failure and it is not `denied`.\n if (error instanceof Error && error.name === 'NotFoundError') {\n return storageReadValue(null);\n }\n return storageReadFailure(error);\n }\n }\n\n async write(key: string, value: string): Promise<StorageOutcome> {\n try {\n const directory = await this.open();\n const handle = await directory.getFileHandle(fileFor(key), { create: true });\n const writable = await handle.createWritable();\n // Written and closed in one go rather than kept open: a handle\n // held across frames is a handle a reload can leave locked.\n await writable.write(value);\n await writable.close();\n return 'ok';\n } catch (error) {\n return classifyStorageError(error);\n }\n }\n\n async remove(key: string): Promise<StorageOutcome> {\n try {\n await (await this.open()).removeEntry(fileFor(key));\n return 'ok';\n } catch (error) {\n if (error instanceof Error && error.name === 'NotFoundError') {\n return 'ok';\n }\n return classifyStorageError(error);\n }\n }\n\n async keys(): Promise<readonly string[]> {\n try {\n const found: string[] = [];\n for await (const name of (await this.open()).keys()) {\n found.push(keyFor(name));\n }\n return found;\n } catch {\n // A listing that cannot be taken is an empty one. The caller is\n // an application evicting its own records, and evicting nothing\n // is the safe answer to not knowing what is there.\n return [];\n }\n }\n\n /**\n * The folder, opened once and kept.\n *\n * A failed open is *not* kept. A rejected promise left in `opening`\n * would answer every later call with the same rejection, so one\n * refusal at start-up would be a store that never worked again even\n * after the person granted storage or made room. Kept when it\n * succeeds, dropped when it does not, which is one line and the\n * difference between a cache and a poison.\n */\n private open(): Promise<OpfsDirectory> {\n if (this.opening === null) {\n const opening = this.rootOf().then(root => root.getDirectoryHandle(this.folder, { create: true }));\n this.opening = opening;\n opening.catch(() => {\n if (this.opening === opening) {\n this.opening = null;\n }\n });\n }\n return this.opening;\n }\n}\n\nfunction defaultRoot(): Promise<OpfsDirectory> {\n const storage = (globalThis as { navigator?: { storage?: { getDirectory?: () => Promise<OpfsDirectory> } } })\n .navigator?.storage;\n if (storage?.getDirectory === undefined) {\n // A `TypeError`, which `classifyStorageError` reads as `denied`:\n // there is no store here and there will not be one.\n return Promise.reject(new TypeError('This environment has no Origin Private File System.'));\n }\n return storage.getDirectory();\n}\n\n/**\n * A key as a file name.\n *\n * `encodeURIComponent` and not a hash, so a listing of the folder in\n * devtools reads as the keys the application wrote. It escapes the\n * slash and the dot, which is what stops a key reaching a directory it\n * was not given.\n */\nfunction fileFor(key: string): string {\n return `${encodeURIComponent(key)}.json`;\n}\n\nfunction keyFor(name: string): string {\n return decodeURIComponent(name.replace(/\\.json$/, ''));\n}\n","import {\n classifyStorageError,\n storageReadFailure,\n storageReadValue,\n type StorageAdapter,\n type StorageOutcome,\n type StorageRead\n} from './StorageAdapter';\n\nexport interface IndexedDbStorageOptions {\n /** The database. Default `'gesso'`. */\n readonly database?: string;\n /** The object store inside it. Default `'records'`. */\n readonly store?: string;\n /** The factory, for a spec. Default `globalThis.indexedDB`. */\n readonly factory?: IDBFactory;\n}\n\n/**\n * A store in IndexedDB.\n *\n * Beside OPFS rather than instead of it, because the two fail in\n * different places and an application picks by which failure it\n * minds. IndexedDB is reachable from every thread, survives longer\n * under a browser's own eviction, and is what a Safari that has\n * disabled OPFS still has; OPFS is faster for one large record and\n * simpler to inspect. Neither is a default the framework picks: an\n * application names the one it wants.\n *\n * One object store of strings keyed by string, which is the shape\n * `StorageAdapter` describes and no more. Indexes, versions past the\n * first, and cursors over ranges are what an application builds when\n * it has outgrown a key-value store, and at that point it is writing\n * against IndexedDB rather than against this.\n *\n * What happens on each failure:\n *\n * - **No `indexedDB`, or an origin that may not open one** (a private\n * window in some browsers, a blocked third-party context): every\n * method answers `denied`, and the open is retried next time rather\n * than cached, because a `denied` can be lifted by a site setting\n * mid-session.\n * - **The quota is spent**: the write answers `full`. IndexedDB\n * reports this on the transaction rather than on the request, which\n * is why the write waits for `oncomplete` and not for\n * `onsuccess`: a put that succeeded into a transaction that then\n * aborted has not been written, and answering `ok` for it would be\n * the adapter assuming success.\n * - **A version change from another tab**: the connection is closed\n * and dropped, so the next call opens a fresh one. Answering\n * `failed` and holding a dead connection would make every later\n * call fail too.\n * - **Anything else**: `failed`, with the platform's message.\n */\nexport class IndexedDbStorage implements StorageAdapter {\n private readonly database: string;\n private readonly store: string;\n private readonly factory: IDBFactory | undefined;\n private connecting: Promise<IDBDatabase> | null = null;\n\n constructor(options: IndexedDbStorageOptions = {}) {\n this.database = options.database ?? 'gesso';\n this.store = options.store ?? 'records';\n this.factory = options.factory ?? (globalThis as { indexedDB?: IDBFactory }).indexedDB;\n }\n\n async read(key: string): Promise<StorageRead> {\n try {\n const value = await this.transact('readonly', store => store.get(key));\n return storageReadValue(typeof value === 'string' ? value : null);\n } catch (error) {\n return storageReadFailure(error);\n }\n }\n\n async write(key: string, value: string): Promise<StorageOutcome> {\n return this.outcomeOf(() => this.transact('readwrite', store => store.put(value, key)));\n }\n\n async remove(key: string): Promise<StorageOutcome> {\n return this.outcomeOf(() => this.transact('readwrite', store => store.delete(key)));\n }\n\n async keys(): Promise<readonly string[]> {\n try {\n const found = await this.transact('readonly', store => store.getAllKeys());\n return Array.isArray(found) ? found.filter((key): key is string => typeof key === 'string') : [];\n } catch {\n return [];\n }\n }\n\n /** Lets go of the connection, for a spec or an application shutting down. */\n close(): void {\n const connecting = this.connecting;\n this.connecting = null;\n void connecting?.then(\n database => database.close(),\n () => undefined\n );\n }\n\n private async outcomeOf(work: () => Promise<unknown>): Promise<StorageOutcome> {\n try {\n await work();\n return 'ok';\n } catch (error) {\n const outcome = classifyStorageError(error);\n if (outcome === 'denied') {\n this.connecting = null;\n }\n return outcome;\n }\n }\n\n /**\n * Runs one request inside one transaction and answers its result.\n *\n * A write resolves on the transaction completing rather than on the\n * request succeeding, because those are two different claims: the\n * second says the put was accepted, and only the first says it\n * reached the disk.\n */\n private async transact<T>(mode: IDBTransactionMode, run: (store: IDBObjectStore) => IDBRequest<T>): Promise<T> {\n const database = await this.connect();\n return new Promise<T>((resolve, reject) => {\n let answer: T;\n const transaction = database.transaction(this.store, mode);\n const request = run(transaction.objectStore(this.store));\n request.onsuccess = () => {\n answer = request.result;\n };\n request.onerror = () => reject(request.error ?? new Error('The request failed.'));\n transaction.oncomplete = () => resolve(answer);\n transaction.onabort = () => reject(transaction.error ?? new Error('The transaction was aborted.'));\n });\n }\n\n private connect(): Promise<IDBDatabase> {\n this.connecting ??= this.open();\n return this.connecting;\n }\n\n private open(): Promise<IDBDatabase> {\n const factory = this.factory;\n if (factory === undefined) {\n // A `TypeError`, which `classifyStorageError` reads as `denied`.\n return Promise.reject(new TypeError('This environment has no IndexedDB.'));\n }\n return new Promise<IDBDatabase>((resolve, reject) => {\n let request: IDBOpenDBRequest;\n try {\n request = factory.open(this.database, 1);\n } catch (error) {\n reject(error);\n return;\n }\n request.onupgradeneeded = () => {\n if (!request.result.objectStoreNames.contains(this.store)) {\n request.result.createObjectStore(this.store);\n }\n };\n request.onsuccess = () => {\n // Another tab asking for a newer version cannot proceed while\n // this connection is open, so it is given up rather than held.\n request.result.onversionchange = () => this.close();\n resolve(request.result);\n };\n request.onerror = () => reject(request.error ?? new Error('The database could not be opened.'));\n request.onblocked = () => reject(new Error('The database is open in another tab at a different version.'));\n });\n }\n}\n","import { of, skip, type Subscription } from 'rxjs';\n\nimport { debounced } from '../debounce';\nimport type { ReadableCell } from '../Input';\nimport { internalState, type InternalState } from '../InternalState';\nimport { resource, type Resource, type ResourceStatus } from '../resource';\nimport type { StorageAdapter } from './StorageAdapter';\n\nexport interface PersistedOptions<T> {\n /**\n * What the value is before anything has been read, and what it goes\n * back to when nothing was stored.\n *\n * Required, and that is the whole answer to the race between\n * hydration and the first frame: a screen reading this on the frame\n * it mounts gets the default, with `status` saying `loading`, and\n * gets the remembered value a moment later if there was one. There\n * is no fourth state to draw and no null to guard against.\n */\n readonly initial: T;\n /**\n * Reads a record back, refusing one this version does not\n * understand.\n *\n * Answer `null` and the record is treated as not being there, which\n * is what a record written by an older build should be: the cost is\n * one default, and the alternative is state holding `undefined`\n * where a field belongs. `Tokens.isStoredTokens` in Segue is the\n * same check written by hand.\n *\n * Without one the parsed JSON is trusted as-is, which is fine while\n * the shape has only ever had one version and is not fine\n * afterwards.\n */\n readonly revive?: (raw: unknown) => T | null;\n /**\n * How long a change waits for the next one before being written, in\n * milliseconds. Default 250.\n *\n * A `debounced` cell rather than a timer of its own, so this is the\n * same gate a search field uses. It is what makes a value changed\n * sixty times a second cost one write rather than sixty: see\n * `persisted.budget.spec.ts`, which asserts exactly that.\n */\n readonly settle?: number;\n /** What to call this in a devtools reading; optional. */\n readonly label?: string;\n}\n\nconst MESSAGES: Readonly<Record<string, string>> = {\n denied: 'This browser will not let the application store anything.',\n full: 'There is no room left to store this.',\n failed: 'The store could not be written to.'\n};\n\n/**\n * A value that survives the application being closed.\n *\n * Hydration is a `resource`, which is not a detail: reading from a\n * disk is a keyed request that can be slow, can answer \"there is\n * nothing\", and can fail, which is the same set of outcomes a request\n * over the network has. So the statuses here are `ResourceStatus`\n * itself rather than a fourth enum saying the same five things in\n * different words.\n *\n * readonly draft = persisted(new OpfsStorage(), 'draft', { initial: '' });\n *\n * // on a screen\n * <TextInput value={draft.value} onChange={text => draft.set(text)} />\n *\n * ## What a screen sees before hydration finishes\n *\n * The default, and `status` reading `loading`. Nothing waits, nothing\n * is null, and no screen has a shape it only has for the first eighty\n * milliseconds. When the read lands the value changes like any other\n * cell change, and a screen that wants to say \"restoring\" reads\n * `status`.\n *\n * The one race that needs a rule is a person changing the value before\n * the disk has answered, which is not rare: a queue is a press away\n * and OPFS is a round trip away. **What they did wins.** A hydration\n * answer is applied only if nothing has been `set` since, on the same\n * reasoning as `mutate`'s guarded rollback: an answer that was\n * overtaken is stale, and putting it on screen would undo something\n * the person just did.\n *\n * ## What happens when storing fails\n *\n * - `denied`: nothing is written this session and nothing is tried\n * again, because the answer will not change. `status` is `failed`\n * and `saveError` says so once rather than on every keystroke.\n * - `full`: the write failed and the value in memory is kept. Nothing\n * is rolled back: the change is real and only the remembering of it\n * failed. The next change is still attempted, because a quota can be\n * given back.\n * - `failed`: the same as `full`, and for the same reason.\n * - A record that parses but is not the shape `revive` accepts is\n * treated as `missing`: the application starts from its default\n * rather than showing an error about a file the person cannot see.\n *\n * ## It is a helper\n *\n * Nothing in the framework holds one, and nothing is reachable only\n * through it. A channel is served from plain Observables as it always\n * was, and an application that would rather read and write a store\n * itself is writing against the same `StorageAdapter` this is written\n * against. The thread model declined to own an application's data\n * architecture, and remembering a value is not the exception to that.\n */\nexport class PersistedState<T> {\n private readonly held: InternalState<T>;\n private readonly saves: InternalState<number>;\n private readonly failure: InternalState<string | null>;\n private readonly record: Resource<string, T>;\n private readonly writing: Subscription;\n /** True once the application has written a value of its own. */\n private touched = false;\n /** Set when the store said `denied`, which is permanent for the session. */\n private refused = false;\n /** The text last known to be on disk, so hydration does not write itself back. */\n private stored: string | null = null;\n /** What `forget` goes back to. */\n private readonly initial: T;\n\n /** Where the first read got to; the same five words `resource` uses. */\n readonly status: ReadableCell<ResourceStatus>;\n /** Why the read did not answer, as a message; null when it did. */\n readonly error: ReadableCell<string | null>;\n /** What is remembered: the default until the read lands. */\n readonly value: ReadableCell<T>;\n /** Writes in the air, for a saving indicator. A count, as `mutate.pending` is. */\n readonly saving: ReadableCell<number>;\n /** Why the last write did not happen, as a message; null when it did. */\n readonly saveError: ReadableCell<string | null>;\n /** Resolves when the first read has settled, whatever it found. */\n readonly hydrated: Promise<void>;\n\n constructor(\n private readonly adapter: StorageAdapter,\n private readonly key: string,\n options: PersistedOptions<T>\n ) {\n const label = options.label;\n this.initial = options.initial;\n this.held = internalState<T>(options.initial, label);\n this.saves = internalState(0, label === undefined ? undefined : `${label}.saving`);\n this.failure = internalState<string | null>(null, label === undefined ? undefined : `${label}.saveError`);\n this.value = this.held;\n this.saving = this.saves;\n this.saveError = this.failure;\n // A constant key, because the record being read is named once. The\n // resource is eager, so constructing this is what starts the read,\n // which is what \"hydration on start\" means: nothing has to\n // remember to call a `load()`.\n this.record = resource(\n of(key),\n () => this.load(options.revive),\n label === undefined ? {} : { label: `${label}.hydration` }\n );\n this.status = this.record.status;\n this.error = this.record.error;\n this.hydrated = this.record.settled.then(() => this.apply());\n this.writing = debounced(this.held, options.settle ?? 250)\n // The gate hands a new follower the value the cell already has,\n // which here is the default nobody asked to be written. Only\n // what comes after it is a change.\n .pipe(skip(1))\n .subscribe(value => void this.flush(value));\n }\n\n /** What is remembered right now, for code that is not subscribing. */\n get current(): T {\n return this.held.value;\n }\n\n /** Remembers a new value. The write follows once the changes stop. */\n set(value: T): void {\n this.touched = true;\n this.held.value = value;\n }\n\n /**\n * Writes what is held now, without waiting for the gate.\n *\n * For the moment an application knows it is about to lose the thread:\n * a `visibilitychange`, a route away from an editor, a sign-out.\n */\n save(): Promise<void> {\n return this.flush(this.held.value);\n }\n\n /**\n * Forgets the record and goes back to the default.\n *\n * Both halves, because a stored value removed while the cell still\n * holds it would be written straight back by the next change.\n */\n async forget(): Promise<void> {\n this.stored = null;\n this.touched = true;\n this.held.value = this.initial;\n await this.adapter.remove(this.key);\n }\n\n /** Gives back the write subscription and the resource's. */\n dispose(): void {\n this.writing.unsubscribe();\n this.record.dispose();\n }\n\n private async load(revive: ((raw: unknown) => T | null) | undefined): Promise<T | null> {\n const read = await this.adapter.read(this.key);\n if (read.outcome !== 'ok') {\n if (read.outcome === 'denied') {\n this.refused = true;\n }\n throw new Error(read.error ?? MESSAGES[read.outcome] ?? 'The store could not be read.');\n }\n if (read.value === null) {\n return null;\n }\n this.stored = read.value;\n let parsed: unknown;\n try {\n parsed = JSON.parse(read.value);\n } catch {\n // Half-written, or written by something else entirely. Treated\n // as nothing stored rather than as a failure: there is nothing a\n // person can do about it and a default is a working application.\n return null;\n }\n return revive === undefined ? (parsed as T) : revive(parsed);\n }\n\n private apply(): void {\n const found = this.record.value.value;\n if (found === null || this.touched) {\n // Nothing stored, or the person got there first. Theirs is the\n // newer truth and it stays.\n return;\n }\n this.held.value = found;\n }\n\n private async flush(value: T): Promise<void> {\n if (this.refused) {\n return;\n }\n let text: string;\n try {\n text = JSON.stringify(value);\n } catch (error) {\n this.failure.value = error instanceof Error ? error.message : String(error);\n return;\n }\n if (text === this.stored) {\n // Hydration writing what it just read, or a change that came\n // back round to where it started. Either way there is nothing\n // to say to the disk.\n return;\n }\n this.saves.value = this.saves.value + 1;\n try {\n const outcome = await this.adapter.write(this.key, text);\n if (outcome === 'ok') {\n this.stored = text;\n this.failure.value = null;\n return;\n }\n if (outcome === 'denied') {\n this.refused = true;\n }\n this.failure.value = MESSAGES[outcome] ?? 'The store could not be written to.';\n } finally {\n this.saves.value = Math.max(0, this.saves.value - 1);\n }\n }\n}\n\n/**\n * A value read from a store on start and written back as it changes.\n *\n * const settings = persisted(new IndexedDbStorage(), 'settings', {\n * initial: DEFAULTS,\n * revive: raw => (isSettings(raw) ? raw : null)\n * });\n *\n * See `PersistedState` for what a screen sees before the read lands\n * and what each kind of storage failure does.\n */\nexport function persisted<T>(adapter: StorageAdapter, key: string, options: PersistedOptions<T>): PersistedState<T> {\n return new PersistedState(adapter, key, options);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persisted-pix1fS1D.js","names":["isPlainObject","MAX_DEPTH","isPlainObject"],"sources":["../src/Input.ts","../src/InternalState.ts","../src/channel/structuralEquals.ts","../src/derive.ts","../src/computed.ts","../src/select.ts","../src/resource.ts","../src/mutate.ts","../src/debounce.ts","../src/channel/ChannelToken.ts","../src/channel/ChannelProtocol.ts","../src/channel/StorePatch.ts","../src/channel/plainData.ts","../src/channel/provide.ts","../src/app/NodeReport.ts","../src/worker/captureConsole.ts","../src/worker/WorkerPorts.ts","../src/channel/serveChannels.ts","../src/channel/pick.ts","../src/storage/StorageAdapter.ts","../src/undo/UndoStack.ts","../src/undo/undoable.ts","../src/storage/OpfsStorage.ts","../src/storage/IndexedDbStorage.ts","../src/storage/persisted.ts"],"sourcesContent":["import { BehaviorSubject, type Observable, Subject } from 'rxjs';\n\n/**\n * Reactive cell holding a component input.\n *\n * Inputs must be cells because render() runs exactly once. A component\n * that read a plain input value during render would capture it for the\n * life of the instance, so a parent supplying new props under a\n * dynamic subtree would update the field while the rendered tree kept\n * showing the original value.\n *\n * The cell is written by the component host only: it accepts whatever\n * the parent passed, subscribing it first when the parent passed an\n * Observable. `value` is deliberately read-only, so `this.label.value =\n * x` inside a component is a compile error rather than a silent\n * violation of the one-way data flow.\n */\nexport class InputCell<T> extends BehaviorSubject<T> {\n /**\n * What to call this cell in a warning: `Component.prop`, or\n * `channel.key`. Set by whoever creates it; a cell without one is\n * reported as \"a cell\".\n */\n label: string | undefined;\n /** The component whose body read `.value`, for the stale-read warning below. */\n private snapshotBy: string | null = null;\n private warnedStale = false;\n /** Everything emitted through `emit`, created on the first `events` read. */\n private emitted: Subject<unknown> | null = null;\n\n constructor(initialValue: T) {\n super(initialValue);\n }\n\n /**\n * Fires the output this cell stands for.\n *\n * An output is a cell whose value is what the parent gave to be\n * called: a function, or a target made by `into(subject)`. `emit`\n * calls it with the arguments, and also pushes the first argument\n * through `events`, so the component can fire from three places\n * without passing the cell around and a parent that wants a stream\n * can have one. A parent that passed nothing is fine: the call\n * simply reaches nobody.\n */\n emit(...args: EmitArgs<T>): void {\n const handler = super.getValue() as unknown;\n if (typeof handler === 'function') {\n (handler as (...values: unknown[]) => void)(...args);\n }\n this.emitted?.next(args[0]);\n }\n\n /** What `emit` has fired, as a stream: the first argument of each call. */\n get events(): Observable<EmitValue<T>> {\n if (this.emitted === null) {\n this.emitted = new Subject<unknown>();\n }\n return this.emitted.asObservable() as Observable<EmitValue<T>>;\n }\n\n override get value(): T {\n trackRead(this);\n // A read a `computed` is collecting is not the body's snapshot: the\n // computed follows this cell from here on and carries the change,\n // and a body that read the computed itself is the computed's own\n // stale watch to report. Recording it here as well warned, wrongly,\n // for a screen row whose `computed` input had let go with the row.\n if (bodyOf !== null && tracking === null && this.snapshotBy === null) {\n this.snapshotBy = bodyOf;\n }\n return super.getValue();\n }\n\n /**\n * The one place the run-once model goes quietly wrong is a body that\n * reads `props.x.value`, uses the value to build the tree, and never\n * hears that it changed. Nothing crashes; the screen is simply stale.\n * So a cell remembers being read while a body ran, and if it later\n * changes with nobody subscribed to it, it says so once. A cell that\n * something is following is fine: the follower carries the change.\n */\n override next(value: T): void {\n if (this.snapshotBy !== null && !this.warnedStale && !this.observed && !Object.is(value, super.getValue())) {\n this.warnedStale = true;\n warnStaleRead(this.snapshotBy, this.label, super.getValue(), value);\n }\n super.next(value);\n }\n}\n\n/** The component whose function body is running, while one is. */\nlet bodyOf: string | null = null;\n\n/** The component whose body is running, for a cell that wants to remember being read there. */\nexport function currentBody(): string | null {\n return bodyOf;\n}\n\n/**\n * Anything with a current value that can be followed: an input, an\n * internal state, a channel view key, a computed. What `computed`\n * collects as it runs.\n */\nexport interface ReadableCell<T> extends Observable<T> {\n readonly value: T;\n}\n\n/** The set a running `computed` is collecting its reads into, while one is. */\nlet tracking: Set<ReadableCell<unknown>> | null = null;\n\n/** Records a `.value` read for whatever `computed` is running, if one is. */\nexport function trackRead(cell: ReadableCell<unknown>): void {\n tracking?.add(cell);\n}\n\n/** Runs `run` with every `.value` read on the way recorded into `into`. */\nexport function withTracking<T>(into: Set<ReadableCell<unknown>>, run: () => T): T {\n const previous = tracking;\n tracking = into;\n try {\n return run();\n } finally {\n tracking = previous;\n }\n}\n\n/**\n * Runs a component's body with its name on record, so a `.value` read\n * inside it can be told apart from one in an event handler later, which\n * is the ordinary way to read the current value and warns about nothing.\n */\nexport function withBodyOf<T>(tag: string, run: () => T): T {\n const previous = bodyOf;\n bodyOf = tag;\n try {\n return run();\n } finally {\n bodyOf = previous;\n }\n}\n\nfunction warnStaleRead(tag: string, label: string | undefined, from: unknown, to: unknown): void {\n const what = label === undefined ? 'a cell' : `\\`${label}\\``;\n const change = describeChange(from, to);\n console.warn(\n `Component '${tag}' read ${what} with .value while its body ran, and nothing is following that cell. ` +\n `It has since changed ${change}, and whatever was built from the first value still shows it. ` +\n `A component body runs once: bind the cell instead (pass it, or pipe it, into the prop it feeds), ` +\n `or give the component a key so a new value builds a new one.`\n );\n}\n\n/**\n * \"from X to Y\", or for two plain objects the first field that differs,\n * because two objects that print alike for sixty characters say nothing\n * about what actually moved.\n */\nfunction describeChange(from: unknown, to: unknown): string {\n if (isPlainObject(from) && isPlainObject(to)) {\n for (const key of new Set([...Object.keys(from), ...Object.keys(to)])) {\n const before = from[key];\n const after = to[key];\n if (!Object.is(before, after) && safeJson(before) !== safeJson(after)) {\n return `at .${key}, from ${describe(before)} to ${describe(after)}`;\n }\n }\n return 'to an equal-looking object';\n }\n return `from ${describe(from)} to ${describe(to)}`;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction safeJson(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction describe(value: unknown): string {\n let text: string;\n try {\n text = typeof value === 'function' ? 'a function' : (JSON.stringify(value) ?? String(value));\n } catch {\n text = String(value);\n }\n return text.length > 60 ? `${text.slice(0, 57)}...` : text;\n}\n\n/**\n * Creates a component input cell.\n *\n * Inside a class component the argument is the default the cell holds\n * until the parent supplies a value:\n *\n * @Input() label = input('Count');\n *\n * Inside a functional component the props are already cells; the\n * two-argument form derives a cell that replaces `undefined` with a\n * fallback, which is how an optional prop gets its default:\n *\n * function Counter(inputs: Inputs<{ label?: string }>) {\n * const label = input(inputs.label, 'Count'); // InputCell<string>\n * return Text({ text: label });\n * }\n *\n * The derived cell follows the source for the life of the component\n * and completes when the source does, so it needs no teardown.\n */\nexport function input<T>(initialValue: T): InputCell<T>;\nexport function input<T>(source: InputCell<T | undefined>, fallback: T): InputCell<T>;\nexport function input<T>(first: T | InputCell<T | undefined>, fallback?: T): InputCell<T> {\n if (arguments.length < 2 || !(first instanceof InputCell)) {\n return new InputCell(first as T);\n }\n const source = first as InputCell<T | undefined>;\n const withFallback = (value: T | undefined): T => (value === undefined ? (fallback as T) : value);\n const derived = new InputCell<T>(withFallback(source.value));\n derived.label = source.label;\n source.subscribe({\n next: value => derived.next(withFallback(value)),\n complete: () => derived.complete()\n });\n return derived;\n}\n\n/** The arguments `emit` takes for a cell holding a handler of type `T`. */\nexport type EmitArgs<T> = NonNullable<T> extends (...args: infer A) => void ? A : never;\n\n/** What `events` carries for a cell holding a handler of type `T`: the handler's first argument. */\nexport type EmitValue<T> = NonNullable<T> extends (first: infer V, ...rest: never[]) => void ? V : void;\n\n/**\n * A component's output: an input cell that holds whatever the parent\n * gave to be called, fired through `emit`. Every function-typed member\n * of a component's inputs is one, so on a component declared with\n * `onOpen: (id: string) => void`, `inputs.onOpen.emit(id)` is how the\n * component speaks, and a parent may pass a function or `into(subject)`.\n * The name is for a class field: `@Output() changed = output<[number]>()`.\n */\nexport type OutputCell<A extends unknown[]> = InputCell<((...args: A) => void) | undefined>;\n\n/**\n * An output a class component declares as a field:\n *\n * @Output() changed = output<[value: number]>();\n *\n * The host wires the parent's handler into it exactly as it wires an\n * input, and `this.changed.emit(next)` fires it.\n */\nexport function output<A extends unknown[]>(): OutputCell<A> {\n return new InputCell<((...args: A) => void) | undefined>(undefined);\n}\n\nconst OUTPUT_TARGET: unique symbol = Symbol('gesso:output-target');\n\n/**\n * A parent's way of receiving an output as a stream rather than a call:\n *\n * const opened = new Subject<string>();\n * <Card onOpen={into(opened)} />\n *\n * Wrapped rather than passed bare, because a bare `Subject` is an\n * Observable and would be read as an *input* the parent is feeding the\n * child, which is the opposite direction.\n */\nexport interface OutputTarget<V> {\n readonly [OUTPUT_TARGET]: { next(value: V): void };\n}\n\nexport function into<V>(target: { next(value: V): void }): OutputTarget<V> {\n return { [OUTPUT_TARGET]: target };\n}\n\nexport function isOutputTarget(value: unknown): value is OutputTarget<unknown> {\n return typeof value === 'object' && value !== null && OUTPUT_TARGET in value;\n}\n\n/** The receiver an `into()` target wraps. */\nexport function outputTargetOf<V>(target: OutputTarget<V>): { next(value: V): void } {\n return target[OUTPUT_TARGET];\n}\n","import { BehaviorSubject } from 'rxjs';\nimport { trackRead } from './Input';\n\n/**\n * A component's own state: originated here, and never crossing the\n * barrier.\n *\n * The writable counterpart to `InputCell`. The two are the same\n * `BehaviorSubject` and differ by one accessor — this one has a\n * `.value` setter — and that difference is the whole semantics:\n *\n * internalState() never crosses I write it\n * input() crosses inward someone else writes it\n *\n * Named on that axis deliberately. It used to be `state()`, which\n * described *what* a thing was while `input()` described *where it\n * came from*; two names on two axes made neither of them tell you\n * anything about the other. `internalState(products)` reads as a\n * mistake at the call site in a way `state(products)` never did.\n *\n * For values that originate on this thread and die with the component:\n * a tooltip's open flag, a caret, a scroll offset, the active tab.\n * Anything that survives a reload, or that another screen cares about,\n * is application state and belongs on a channel. Anything derived from\n * other cells is a `computed`.\n *\n * It is not only for components. The thread that owns a channel's data\n * writes cells too, and wrote them as a `BehaviorSubject` mirrored\n * into an `asObservable()` because this was reachable only through the\n * framework's main entry. `gesso-framework/worker` is the same cell\n * with none of the renderer behind it, so an application worker holds\n * one cell rather than a subject and a copy of it, and reads it with\n * `.value` in a `computed` rather than listing it in a\n * `combineLatest`. \"Internal\" still means what it says there: written\n * here, and crossing the barrier only as the plain data a view key\n * publishes.\n */\nexport class InternalState<T> extends BehaviorSubject<T> {\n /** What to call this cell in a warning or the inspector; optional. */\n label: string | undefined;\n constructor(initialValue: T) {\n super(initialValue);\n }\n\n override get value(): T {\n trackRead(this);\n return super.getValue();\n }\n\n override set value(next: T) {\n this.next(next);\n }\n}\n\n/**\n * Creates a reactive state cell.\n *\n * Usage inside a component:\n *\n * private readonly count = state(0);\n *\n * increment() {\n * this.count.value++;\n * }\n */\nexport function internalState<T>(initialValue: T, label?: string): InternalState<T> {\n const state = new InternalState(initialValue);\n if (label !== undefined) {\n state.label = label;\n }\n return state;\n}\n","/**\n * Deep comparison for store read models.\n *\n * Projections and selectors allocate a fresh value on every\n * evaluation, so reference equality reports a change on every\n * unrelated state emission. That invalidates bindings and dirties\n * nodes across the whole tree for state the view never read.\n *\n * Scope is deliberately narrow: primitives, arrays, and plain objects\n * — what a projection is allowed to return. Anything else (class\n * instances, Date, Map, Set, functions) compares by reference, which\n * is conservative: it reports a change, so the UI updates when it did\n * not need to rather than failing to update when it did.\n *\n * The same comparison becomes the equality half of the patch differ\n * in Phase E, so a store behaves identically local or remote.\n */\nconst MAX_DEPTH = 100;\n\nexport function structurallyEqual<T>(a: T, b: T): boolean {\n return compare(a, b, 0);\n}\n\nfunction compare(a: unknown, b: unknown, depth: number): boolean {\n if (Object.is(a, b)) {\n return true;\n }\n if (depth > MAX_DEPTH) {\n // Deeper than any sane view model, or cyclic. Report \"changed\"\n // rather than risk a non-terminating walk.\n return false;\n }\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {\n return false;\n }\n\n const aIsArray = Array.isArray(a);\n if (aIsArray !== Array.isArray(b)) {\n return false;\n }\n\n if (aIsArray) {\n const left = a as unknown[];\n const right = b as unknown[];\n if (left.length !== right.length) {\n return false;\n }\n for (let i = 0; i < left.length; i++) {\n if (!compare(left[i], right[i], depth + 1)) {\n return false;\n }\n }\n return true;\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) {\n return false;\n }\n\n const left = a as Record<string, unknown>;\n const right = b as Record<string, unknown>;\n const leftKeys = Object.keys(left);\n if (leftKeys.length !== Object.keys(right).length) {\n return false;\n }\n for (const key of leftKeys) {\n if (!Object.prototype.hasOwnProperty.call(right, key)) {\n return false;\n }\n if (!compare(left[key], right[key], depth + 1)) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Objects created from an object literal or a null prototype. Class\n * instances are excluded so they keep reference semantics.\n */\nfunction isPlainObject(value: object): boolean {\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","import { combineLatest, distinctUntilChanged, map, type Observable } from 'rxjs';\n\nimport { structurallyEqual } from './channel/structuralEquals';\n\n/** How `derive` decides that a new value is not a change. */\nexport type Equality<T> = 'reference' | 'structural' | ((a: T, b: T) => boolean);\n\nexport interface DeriveOptions<T> {\n /**\n * `reference` (the default) is `Object.is`; `structural` compares\n * plain data by content, so a projection that builds a fresh object\n * of the same shape does not re-bind everything reading it; a\n * function is your own rule.\n */\n readonly equal?: Equality<T>;\n}\n\ntype Values<S extends readonly Observable<unknown>[]> = {\n [K in keyof S]: S[K] extends Observable<infer V> ? V : never;\n};\n\n/**\n * One value from several, kept equal to `project` of the latest of each\n * source, and emitted only when it changes.\n *\n * This is `combineLatest(...).pipe(map(...), distinctUntilChanged())`,\n * which is what nearly every derived binding in a component body wants\n * and what nearly every one had to write out. Sources are cells or any\n * Observables; the result is what a prop takes.\n *\n * const playing = derive([queue.view.playlistId, audio.state], (id, state) =>\n * id === card.id && state.status === 'playing'\n * );\n *\n * @deprecated Write it as a `computed`, which is the one derivation the\n * documentation teaches. A cell is read with\n * `.value` and anything else through the `read` the function is handed,\n * so the sources are the reads themselves and there is no list beside\n * the expression to keep in step with it:\n *\n * const playing = computed(read =>\n * queue.view.playlistId.value === card.id && read(audio.state).status === 'playing'\n * );\n *\n * It still works and nothing that uses it needs changing today.\n */\nexport function derive<S extends readonly Observable<unknown>[], T>(\n sources: readonly [...S],\n project: (...values: Values<S>) => T,\n options: DeriveOptions<T> = {}\n): Observable<T> {\n const equal = equalityOf(options.equal ?? 'reference');\n return combineLatest(sources as unknown as Observable<unknown>[]).pipe(\n map(values => project(...(values as Values<S>))),\n distinctUntilChanged(equal)\n );\n}\n\n/** The comparison an `Equality` names. Shared with `computed`. */\nexport function equalityOf<T>(equal: Equality<T>): (a: T, b: T) => boolean {\n if (equal === 'reference') {\n return Object.is;\n }\n if (equal === 'structural') {\n return (a, b) => structurallyEqual(a, b);\n }\n return equal;\n}\n","import { Observable, Subject, Subscription } from 'rxjs';\nimport { equalityOf, type Equality } from './derive';\nimport { currentBody, trackRead, withTracking, type ReadableCell } from './Input';\n\nexport interface ComputedOptions<T> {\n /** How a new result is judged unchanged; `reference` by default. */\n readonly equal?: Equality<T>;\n /** What to call this cell in a warning. */\n readonly label?: string;\n}\n\n/**\n * Reads a stream that is not a cell, inside a `computed`.\n *\n * A cell is read with `.value`; a plain Observable has no current value\n * to read, so the function is handed this instead:\n *\n * const playing = computed(read => read(audio.actions) === 'play');\n *\n * It answers with the stream's latest value and records the stream as a\n * source, so the computed follows it exactly as it follows a cell. A\n * cell passed to it is simply read, which means one call site works for\n * either and a service that later turns a stream into a cell breaks\n * nothing.\n */\nexport type ReadSource = <V>(source: Observable<V>) => V;\n\n/**\n * A cell whose value is a function of other cells.\n *\n * `computed(() => quantity.value * price.value)` reads like the value it\n * is. The cells its function reads through `.value` are its sources,\n * found by running the function and watching what it touches, so there\n * is no list to keep in step with the expression; a read the function\n * did not make this time is a source it no longer has.\n *\n * A stream that is not a cell is read through the `read` the function\n * is handed: `computed(read => read(stream).status)` follows the stream\n * as it follows a cell. That is what makes this the only derivation an\n * application needs, whether or not the thing it derives from happens\n * to have a current value of its own.\n *\n * It is a cell and nothing else. Bound to a prop it is an Observable\n * like every other cell, so a component written with it and one written\n * with `pipe` compose without translation. Read in a handler with\n * `.value` it is the current result, computed on the spot if nothing is\n * following it. RxJS is underneath and nothing here replaces it.\n *\n * Nothing runs until someone asks. With no subscriber the function runs\n * only when `.value` is read; with one, the cell follows its sources and\n * emits a result when it differs from the last by `equal`. When the last\n * subscriber leaves it lets go of its sources, so a computed made in a\n * component body dies with the component's bindings and needs no\n * disposal of its own.\n *\n * Reading it with `.value` while a component body runs is the same\n * snapshot an input read there is, and it warns the same way: once, if\n * it later changes with nobody following.\n */\nexport class ComputedCell<T> extends Observable<T> implements ReadableCell<T> {\n label: string | undefined;\n private readonly equal: (a: T, b: T) => boolean;\n private readonly changes = new Subject<T>();\n private sources = new Set<ReadableCell<unknown>>();\n private cached!: T;\n private hasValue = false;\n private upstream: Subscription | null = null;\n private subscribers = 0;\n private attaching = false;\n private snapshotBy: string | null = null;\n private warnedStale = false;\n /** Follows the sources after a body read, only to notice the change the body will not. */\n private staleWatch: Subscription | null = null;\n\n constructor(\n private readonly compute: (read: ReadSource) => T,\n options: ComputedOptions<T> = {}\n ) {\n super(subscriber => {\n this.subscribers++;\n // A follower makes the body-read watch moot: the change reaches the screen.\n this.staleWatch?.unsubscribe();\n this.staleWatch = null;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.cached);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.subscribers--;\n if (this.subscribers === 0) {\n this.detach();\n }\n };\n });\n this.equal = equalityOf(options.equal ?? 'reference');\n this.label = options.label;\n }\n\n /** The current result: kept by the sources while followed, computed now when not. */\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n this.recompute();\n }\n const body = currentBody();\n if (body !== null && this.snapshotBy === null) {\n this.snapshotBy = body;\n this.watchForStaleRead();\n }\n return this.cached;\n }\n\n /**\n * A body read the value once; if a source now changes with nothing\n * following this cell, the screen built from that read is stale and\n * nobody would know. So the sources are watched for exactly that, and\n * the watch ends with the warning or with a real subscriber arriving.\n */\n private watchForStaleRead(): void {\n this.staleWatch = new Subscription();\n let settling = true;\n for (const source of this.sources) {\n this.staleWatch.add(\n source.subscribe(() => {\n if (settling || this.observed) {\n return;\n }\n if (this.recompute()) {\n this.warnStale();\n this.staleWatch?.unsubscribe();\n this.staleWatch = null;\n }\n })\n );\n }\n settling = false;\n }\n\n private warnStale(): void {\n if (this.snapshotBy === null || this.warnedStale) {\n return;\n }\n this.warnedStale = true;\n console.warn(\n `Component '${this.snapshotBy}' read ${this.label === undefined ? 'a computed cell' : `\\`${this.label}\\``} with .value while its body ran, ` +\n `and nothing is following that cell. It has since changed, and whatever was built from the first value still shows it. ` +\n `A component body runs once: bind the cell instead.`\n );\n }\n\n /** Whether anything is following this cell; the stale-read warning's question. */\n get observed(): boolean {\n return this.subscribers > 0;\n }\n\n /** Runs the function, watching what it reads; true when the result changed. */\n private recompute(): boolean {\n const touched = new Set<ReadableCell<unknown>>();\n const next = withTracking(touched, () => this.compute(readSource));\n this.sources = touched;\n const changed = !this.hasValue || !this.equal(this.cached, next);\n this.hasValue = true;\n this.cached = next;\n return changed;\n }\n\n /** Follows the current sources, re-running on any change to them. */\n private attach(): void {\n this.attaching = true;\n this.recompute();\n this.upstream = new Subscription();\n for (const source of this.sources) {\n this.upstream.add(source.subscribe(() => this.onSourceChanged()));\n }\n this.attaching = false;\n }\n\n private detach(): void {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n\n private onSourceChanged(): void {\n if (this.attaching) {\n return; // a cell replays its current value on subscribe; that is not a change\n }\n const before = new Set(this.sources);\n const changed = this.recompute();\n if (!sameSet(before, this.sources)) {\n // The function read different cells this time: follow those.\n this.detach();\n this.attaching = true;\n this.upstream = new Subscription();\n for (const source of this.sources) {\n this.upstream.add(source.subscribe(() => this.onSourceChanged()));\n }\n this.attaching = false;\n }\n if (changed) {\n this.changes.next(this.cached);\n }\n }\n}\n\n/**\n * A cell computed from what its function reads. See `ComputedCell`.\n *\n * const total = computed(() => quantity.value * PRICE * RATES[currency.value]);\n * <text text={computed(() => String(count.value))} />\n *\n * Cells are read with `.value`; anything else is read through the\n * `read` the function is given, which follows it the same way:\n *\n * const late = computed(read => read(clock) > deadline);\n */\nexport function computed<T>(compute: (read: ReadSource) => T, options: ComputedOptions<T> = {}): ComputedCell<T> {\n return new ComputedCell(compute, options);\n}\n\n/**\n * The cell standing for a stream, one per stream.\n *\n * Anything that already has a current value is its own cell, so a\n * `read` of an input, an internal state or another computed costs a\n * property access and nothing more. Everything else gets a `StreamCell`\n * held against it here, so several computeds reading one stream share a\n * single subscription to it rather than opening one each.\n *\n * Weak on purpose: the entry is reachable only while the stream is, so\n * a stream made in a component body is collected with the component.\n */\nconst streamCells = new WeakMap<Observable<unknown>, StreamCell<unknown>>();\n\n/**\n * Whether a source's `.value` announces itself to the running computed,\n * decided once per source and remembered.\n *\n * Having a `value` is not enough. A framework cell records its reads\n * through `trackRead`, which is what lets a computed learn what it\n * depends on; a plain `BehaviorSubject` has a `value` too and records\n * nothing, so a computed that trusted the property would read it once\n * and never hear it change. That is exactly what happened to three\n * data-layer specs that fed a raw subject where the application feeds\n * a channel view. The probe reads `.value` once under a tracking set\n * of its own and asks whether the source turned up in it.\n */\nconst tracksReads = new WeakMap<Observable<unknown>, boolean>();\n\nfunction announcesItsReads(source: ReadableCell<unknown>): boolean {\n let known = tracksReads.get(source);\n if (known === undefined) {\n const seen = new Set<ReadableCell<unknown>>();\n withTracking(seen, () => void source.value);\n known = seen.has(source);\n tracksReads.set(source, known);\n }\n return known;\n}\n\nfunction cellFor<T>(source: Observable<T>): ReadableCell<T> {\n if ('value' in source && announcesItsReads(source as ReadableCell<T>)) {\n return source as ReadableCell<T>;\n }\n let cell = streamCells.get(source as Observable<unknown>);\n if (cell === undefined) {\n cell = new StreamCell(source as Observable<unknown>);\n streamCells.set(source as Observable<unknown>, cell);\n }\n return cell as ReadableCell<T>;\n}\n\n/** The `read` every computed's function is handed. */\nconst readSource: ReadSource = <V>(source: Observable<V>): V => cellFor(source).value;\n\n/**\n * A plain stream, seen as a cell.\n *\n * It holds the last value it saw and hands it to whoever asks, which is\n * the one thing a cell has and an Observable does not. While something\n * follows it, it follows the stream; when the last follower leaves it\n * lets go, so it costs nothing between uses and needs no disposal, on\n * the same terms as `ComputedCell`.\n *\n * A `.value` read with nothing following takes one synchronous\n * subscription and drops it again, which is how a `BehaviorSubject`\n * behind an `asObservable()`, or a `combineLatest` over such subjects,\n * answers with what it already holds. A stream that has nothing to say\n * synchronously answers `undefined` until its first emission arrives,\n * which is the honest answer: there is no value yet.\n */\nclass StreamCell<T> extends Observable<T> implements ReadableCell<T> {\n private last!: T;\n private followers = 0;\n private upstream: Subscription | null = null;\n private readonly changes = new Subject<T>();\n\n constructor(private readonly stream: Observable<T>) {\n super(subscriber => {\n this.followers++;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.last);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.followers--;\n if (this.followers === 0) {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n };\n });\n }\n\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n const asking = this.stream.subscribe(value => {\n this.last = value;\n });\n asking.unsubscribe();\n }\n return this.last;\n }\n\n private attach(): void {\n this.upstream = this.stream.subscribe(value => {\n this.last = value;\n this.changes.next(value);\n });\n }\n}\n\nfunction sameSet<T>(a: ReadonlySet<T>, b: ReadonlySet<T>): boolean {\n if (a.size !== b.size) {\n return false;\n }\n for (const item of a) {\n if (!b.has(item)) {\n return false;\n }\n }\n return true;\n}\n","import type { Observable } from 'rxjs';\n\nimport { computed, type ComputedCell } from './computed';\nimport type { Equality } from './derive';\n\nexport interface SelectOptions<T> {\n /**\n * How a projected value is judged unchanged; `structural` by default,\n * because a projection nearly always builds a value rather than\n * passing one through, and a rebuilt equal one is not a change.\n */\n readonly equal?: Equality<T>;\n /** What to call the cell in a warning. */\n readonly label?: string;\n}\n\n/**\n * One field of a cell, or one projection of it, as a cell.\n *\n * const title = select(inputs.track, 'title');\n * const names = select(inputs.track, entry => entry?.tags ?? []);\n *\n * Reading four fields of one input costs four of these rather than four\n * `pipe(map(...), distinctUntilChanged(...))`, which is what the two\n * applications wrote by hand often enough to invent their own `field()`\n * and `text()` helpers for it.\n *\n * The source may be any Observable, not only a cell: `select` is a\n * `computed` over one source, and reads it the way a computed reads\n * anything. The comparison is structural by default, since the reason\n * for nearly every hand-written comparator is exactly this: a\n * projection that rebuilds an equal array or object each time should\n * not re-bind everything reading it.\n *\n * There is no `inputs.track.title` proxy. A cell is an Observable, so\n * its own members (`value`, `pipe`, `subscribe`, `source`) would shadow\n * the fields of anything projected through it, and a data type that\n * happens to have a field called `value` would read as the cell's\n * current value instead. `select` names the field explicitly and cannot\n * collide.\n */\nexport function select<T extends object, K extends keyof T>(\n source: Observable<T>,\n key: K,\n options?: SelectOptions<T[K]>\n): ComputedCell<T[K]>;\nexport function select<T, R>(\n source: Observable<T>,\n project: (value: T) => R,\n options?: SelectOptions<R>\n): ComputedCell<R>;\nexport function select(\n source: Observable<unknown>,\n keyOrProject: PropertyKey | ((value: unknown) => unknown),\n options: SelectOptions<unknown> = {}\n): ComputedCell<unknown> {\n const project =\n typeof keyOrProject === 'function'\n ? keyOrProject\n : // A stream that has not spoken yet has no value to read a field\n // off, and neither has a source that is legitimately null. Both\n // answer `undefined` rather than throwing on the first frame.\n (value: unknown) =>\n value === null || value === undefined ? undefined : (value as Record<PropertyKey, unknown>)[keyOrProject];\n return computed(read => project(read(source)), {\n equal: options.equal ?? 'structural',\n ...(options.label === undefined ? {} : { label: options.label })\n });\n}\n","import { Subscription, type Observable } from 'rxjs';\n\nimport type { ComputedCell } from './computed';\nimport type { ReadableCell } from './Input';\nimport { internalState, type InternalState } from './InternalState';\nimport { select } from './select';\n\n/**\n * What a request has come to, in the five words every screen needs.\n *\n * Chosen once so screens stop inventing them. The tree had three\n * enums saying nearly the same thing in different words\n * (`'loading' | 'ready' | 'empty' | 'failed'`,\n * `'idle' | 'loading' | 'ready' | 'missing' | 'failed'`,\n * `'idle' | 'searching' | 'done' | 'failed'`), which meant a screen\n * reading two of them had two vocabularies for one idea.\n *\n * - `idle`: nothing has been asked for. The key is `null`.\n * - `loading`: a request is out and there is nothing to show yet.\n * - `ready`: there is a value. A refresh may still be in the air, and\n * that is deliberately not a separate status: what is on screen is\n * real, and saying \"loading\" over it would be a lie.\n * - `missing`: the answer was that there is no such thing. A fetch\n * says so by resolving `null`.\n * - `failed`: the request could not be answered at all.\n *\n * `missing` and `failed` are reported only when there is nothing to\n * fall back on. A refresh that fails over a value already held leaves\n * it on screen and stays `ready`, because a stale answer is stale and\n * not wrong, and an empty page would be worse. The error is still\n * there to read.\n *\n * What is *not* here is `empty`. A list that loaded and has no rows is\n * `ready` with an empty array, which is a judgement about the value\n * rather than about the request, and the screen that cares makes it.\n */\nexport type ResourceStatus = 'idle' | 'loading' | 'ready' | 'missing' | 'failed';\n\n/**\n * A resource as one record, so it can be a channel view key.\n *\n * Plain data throughout: the error is its message rather than the\n * `Error`, because a message is what a screen shows and what survives\n * the barrier, and an `Error` is neither.\n */\nexport interface ResourceState<T> {\n readonly status: ResourceStatus;\n readonly value: T | null;\n readonly error: string | null;\n}\n\nexport interface ResourceOptions<K, T> {\n /**\n * What is already known for this key, shown at once while the\n * request runs behind it.\n *\n * This is the store-first rule in one function: a hit is on screen\n * synchronously and marked `ready` even though a request is on its\n * way, so a page opened twice is instant the second time and correct\n * a moment later. Answering `null` or `undefined` means nothing is\n * held, and the resource says `loading`.\n */\n readonly peek?: (key: K) => T | null | undefined;\n /** What to call this resource in a warning; optional. */\n readonly label?: string;\n}\n\n/**\n * A request, keyed, so a stale answer cannot win.\n *\n * The key says what to fetch, and every value the key source emits is\n * a request. An answer is published only if its request is still the\n * current one, which is the generation counter every screen that loads\n * anything was writing by hand, and the reason opening a page, going\n * back and opening another before the first answers does not end with\n * the first answer on screen.\n *\n * private readonly ref = internalState<PageRef | null>(null);\n * readonly page = resource(this.ref, ref => api.trackPage(ref));\n *\n * show(ref: PageRef | null): Promise<void> {\n * this.ref.value = ref;\n * return this.page.settled;\n * }\n *\n * A `null` key is \"nothing is being asked for\": the status is `idle`,\n * the value is `null`, and no fetch runs. That is what a screen showing\n * nothing yet actually means, and it saves every caller a branch.\n *\n * Unlike `computed`, a resource is eager: it follows its key from the\n * moment it is made, because a request is an effect and an effect that\n * waits for a subscriber is a request that never happens. It takes one\n * subscription to the key source for its whole life, however many\n * requests run through it, and `dispose()` gives that back.\n *\n * It is a helper and not a data layer. Nothing in the framework\n * requires one, a channel is reached exactly as it was, and an\n * application that would rather write its own is writing against the\n * same barrier this is written against.\n */\nexport class Resource<K, T> {\n /** The one cell everything else here is a projection of. */\n private readonly cell: InternalState<ResourceState<T>>;\n /** Bumped per request; an answer from an older one is dropped. */\n private requests = 0;\n private asked: K | null = null;\n private settling: Promise<void> = Promise.resolve();\n private readonly following: Subscription;\n\n /** Status, value and error as one record: what a channel view key takes. */\n readonly state: ReadableCell<ResourceState<T>>;\n readonly status: ComputedCell<ResourceStatus>;\n /** What is loaded, or `null` while there is nothing to show. */\n readonly value: ComputedCell<T | null>;\n /** Why the last request failed, as its message; `null` when it did not. */\n readonly error: ComputedCell<string | null>;\n\n constructor(\n key: Observable<K | null | undefined>,\n private readonly fetch: (key: K) => Promise<T | null>,\n private readonly options: ResourceOptions<K, T> = {}\n ) {\n this.cell = internalState<ResourceState<T>>({ status: 'idle', value: null, error: null }, options.label);\n this.state = this.cell;\n this.status = select(this.cell, 'status', named(options.label, 'status'));\n // Compared by identity rather than structurally: a fetch builds a\n // new value every time, and walking a page-sized object to\n // discover that is exactly the cost the differ already pays once.\n this.value = select(this.cell, 'value', { ...named(options.label, 'value'), equal: 'reference' });\n this.error = select(this.cell, 'error', named(options.label, 'error'));\n this.following = key.subscribe(next => this.request(next ?? null));\n }\n\n /** What is being asked for, for a caller that needs to guard on it. */\n get requested(): K | null {\n return this.asked;\n }\n\n /**\n * The request in the air, as a promise that resolves when it settles.\n *\n * Already resolved when nothing is in flight, so a caller that sets\n * the key and returns this reads as an ordinary async method. Each\n * request keeps its own promise, so a dropped one still resolves for\n * whoever is awaiting it; it simply changes nothing on the way.\n */\n get settled(): Promise<void> {\n return this.settling;\n }\n\n /**\n * Asks again for the same key, keeping what is on screen.\n *\n * This is the retry button. It does not clear the value the way a\n * new key does, because a person pressing retry is asking for the\n * thing they can already see to be brought up to date, and blanking\n * it first would be a worse answer than the stale one.\n */\n retry(): Promise<void> {\n if (this.asked === null) {\n return this.settling;\n }\n const generation = ++this.requests;\n const held = this.cell.value;\n if (held.value === null && held.status !== 'loading') {\n this.write({ status: 'loading', value: null, error: null });\n }\n this.settling = this.run(this.asked, generation);\n return this.settling;\n }\n\n /**\n * Replaces what is loaded, for a change made here rather than\n * fetched.\n *\n * A page of comments appended to the answer already held, an\n * optimistic edit: the resource holds the value, so something has to\n * be able to write it. It does not touch the request in flight, so a\n * refresh that lands afterwards still wins, which is what it should\n * do: it is the newer truth.\n */\n set(value: T): void {\n this.write({ status: 'ready', value, error: null });\n }\n\n /** Gives back the subscription to the key source. */\n dispose(): void {\n this.following.unsubscribe();\n }\n\n private request(key: K | null): void {\n this.asked = key;\n const generation = ++this.requests;\n if (key === null) {\n this.write({ status: 'idle', value: null, error: null });\n this.settling = Promise.resolve();\n return;\n }\n const held = this.options.peek?.(key) ?? null;\n this.write({ status: held === null ? 'loading' : 'ready', value: held, error: null });\n this.settling = this.run(key, generation);\n }\n\n private run(key: K, generation: number): Promise<void> {\n return this.fetch(key).then(\n answer => this.answered(generation, answer),\n (error: unknown) => this.refused(generation, error)\n );\n }\n\n private answered(generation: number, answer: T | null): void {\n if (generation !== this.requests) {\n return;\n }\n if (answer === null) {\n const held = this.cell.value.value;\n this.write({ status: held === null ? 'missing' : 'ready', value: held, error: null });\n return;\n }\n this.write({ status: 'ready', value: answer, error: null });\n }\n\n private refused(generation: number, error: unknown): void {\n if (generation !== this.requests) {\n return;\n }\n const held = this.cell.value.value;\n this.write({ status: held === null ? 'failed' : 'ready', value: held, error: messageOf(error) });\n }\n\n private write(next: ResourceState<T>): void {\n this.cell.value = next;\n }\n}\n\n/**\n * A keyed request with a status, a value, an error and a retry.\n *\n * const page = resource(ref, key => api.page(key), { peek: key => store.get(key) });\n * <Show when={computed(() => page.status.value === 'loading')}>{() => <Spinner />}</Show>\n *\n * See `Resource` for what each status means and when a stale value is\n * kept. The key is an Observable so that setting a cell is what asks\n * for something: `computed` and `internalState` both work, and so does\n * a channel view key or a router match.\n */\nexport function resource<K, T>(\n key: Observable<K | null | undefined>,\n fetch: (key: K) => Promise<T | null>,\n options: ResourceOptions<K, T> = {}\n): Resource<K, T> {\n return new Resource(key, fetch, options);\n}\n\nfunction named(base: string | undefined, part: string): { label?: string } {\n return base === undefined ? {} : { label: `${base}.${part}` };\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import { equalityOf, type Equality } from './derive';\nimport type { ReadableCell } from './Input';\nimport { internalState, type InternalState } from './InternalState';\n\nexport interface MutateOptions<T> {\n /**\n * How the rollback decides the cell still holds what was applied;\n * `structural` by default, because an optimistic change nearly\n * always builds a new list or a new record rather than passing one\n * through, so identity would never match and nothing would ever roll\n * back.\n */\n readonly equal?: Equality<T>;\n /** What to call the in-flight count in a warning; optional. */\n readonly label?: string;\n}\n\n/** A change that is made locally at once and confirmed afterwards. */\nexport interface Mutation<A> {\n /**\n * How many writes are in the air, for a saving indicator.\n *\n * A count rather than a flag, because two presses in quick\n * succession are two writes and a flag cleared by the first would\n * say the second had finished.\n */\n readonly pending: ReadableCell<number>;\n /**\n * Applies the change, commits it, and puts it back if the commit\n * refuses. Answers whether it stuck.\n */\n run(argument: A): Promise<boolean>;\n}\n\n/**\n * An optimistic change to a cell, with a rollback that does not fight\n * the person.\n *\n * private readonly favourites = internalState<readonly string[]>([]);\n * private readonly like = mutate(this.favourites, toggled, id => api.favourite(id));\n *\n * toggle(id: string): void {\n * void this.like.run(id);\n * }\n *\n * Three things happen and the order is the whole point. `apply` runs\n * first and writes the cell, so the screen changes on the press rather\n * than a round trip later. `commit` then does the real write. If it\n * rejects, or resolves `false`, the cell goes back to what it held\n * before.\n *\n * **The rollback is guarded.** It happens only while the cell still\n * holds exactly what `apply` wrote. Without that, a slow rejection\n * would fight a fast second press and the cell would end up saying the\n * opposite of the last thing anyone did, which is the guard every\n * optimistic screen writes by hand and half of them get wrong.\n *\n * The cell is named first, and not because it was first written\n * `mutate(apply, commit)`: the cell is what makes the guard possible.\n * A mutation handed only two functions can undo its own change but\n * cannot tell whether undoing it is still the right thing to do.\n *\n * A helper and not a data layer: nothing in the framework requires\n * one, and an application that would rather write the four lines out\n * is writing the same four lines this does.\n */\nexport function mutate<T, A = void>(\n cell: InternalState<T>,\n apply: (current: T, argument: A) => T,\n commit: (argument: A, applied: T) => Promise<unknown>,\n options: MutateOptions<T> = {}\n): Mutation<A> {\n const equal = equalityOf<T>(options.equal ?? 'structural');\n const inFlight = internalState(0, options.label);\n\n const revert = (before: T, applied: T): void => {\n if (!equal(cell.value, applied)) {\n // Changed again since, by whoever is using the screen. Their\n // change is newer than this answer and wins.\n return;\n }\n cell.value = before;\n };\n\n return {\n pending: inFlight,\n async run(argument: A): Promise<boolean> {\n const before = cell.value;\n const applied = apply(before, argument);\n cell.value = applied;\n inFlight.value = inFlight.value + 1;\n try {\n // `false` and a rejection mean the same thing: the write did\n // not happen. Anything else, `undefined` included, is a\n // commit that went through.\n if ((await commit(argument, applied)) === false) {\n revert(before, applied);\n return false;\n }\n return true;\n } catch {\n revert(before, applied);\n return false;\n } finally {\n inFlight.value = Math.max(0, inFlight.value - 1);\n }\n }\n };\n}\n","import {\n debounceTime,\n Observable,\n Subject,\n Subscription,\n tap,\n throttleTime,\n type MonoTypeOperatorFunction\n} from 'rxjs';\n\nimport { trackRead, type ReadableCell } from './Input';\n\n/**\n * A cell that lets its source through on a timer.\n *\n * The two operators below are the same machinery with a different\n * gate, and both are cells rather than plain streams on purpose: a\n * `computed` reads a cell with `.value` and follows it, so a debounced\n * search term composes with everything else in the dialect instead of\n * being the one value in a screen that has to be piped.\n *\n * It holds the last value the gate let through, which is what `.value`\n * answers while something is following it. With nothing following\n * there is no timer running to hold anything back, so `.value` reads\n * the source directly, which is the honest answer rather than a value\n * frozen at whatever moment the last follower left.\n *\n * A value equal to the one it already holds is not a change and is not\n * emitted, the same rule `computed` follows. Without it the first pass\n * of the gate after a subscription would repeat the value the\n * subscriber had just been handed.\n *\n * One subscription upstream however many followers it has, given back\n * when the last of them leaves, on the same terms as `ComputedCell`.\n */\nclass TimedCell<T> extends Observable<T> implements ReadableCell<T> {\n private current!: T;\n private hasCurrent = false;\n private followers = 0;\n private seeding = false;\n private upstream: Subscription | null = null;\n private readonly changes = new Subject<T>();\n\n constructor(\n private readonly stream: Observable<T>,\n private readonly gate: MonoTypeOperatorFunction<T>\n ) {\n super(subscriber => {\n this.followers++;\n if (this.upstream === null) {\n this.attach();\n }\n subscriber.next(this.current);\n const following = this.changes.subscribe(subscriber);\n return () => {\n following.unsubscribe();\n this.followers--;\n if (this.followers === 0) {\n this.upstream?.unsubscribe();\n this.upstream = null;\n }\n };\n });\n }\n\n get value(): T {\n trackRead(this);\n if (this.upstream === null) {\n const asking = this.stream.subscribe(value => {\n this.current = value;\n this.hasCurrent = true;\n });\n asking.unsubscribe();\n }\n return this.current;\n }\n\n private attach(): void {\n // Seeds the current value from whatever the source already holds,\n // so a cell behind a gate has a value on the first frame rather\n // than after the first delay. Only during the subscribe itself: a\n // value arriving later is a change, and absorbing it here would\n // let it past the gate without telling anybody.\n this.seeding = true;\n this.upstream = this.stream\n .pipe(\n tap(value => {\n if (this.seeding && !this.hasCurrent) {\n this.current = value;\n this.hasCurrent = true;\n }\n }),\n this.gate\n )\n .subscribe(value => {\n if (this.hasCurrent && Object.is(this.current, value)) {\n return;\n }\n this.current = value;\n this.hasCurrent = true;\n this.changes.next(value);\n });\n this.seeding = false;\n }\n}\n\n/**\n * A cell that follows its source once it has stopped moving.\n *\n * const query = internalState('');\n * const term = debounced(query, 200);\n * const results = computed(() => index.search(term.value));\n *\n * Nothing is emitted while values keep arriving; `ms` after the last\n * one, the last one is. This is what a search field wants and what\n * every search field in the tree was reaching the router without: a\n * keystroke is not a question, and a pause is.\n *\n * The value the source already held is there immediately, so a screen\n * built from this draws on the first frame rather than `ms` later.\n */\nexport function debounced<T>(source: Observable<T>, ms: number): ReadableCell<T> {\n return new TimedCell(source, debounceTime<T>(ms));\n}\n\n/**\n * A cell that follows its source at most once every `ms`.\n *\n * const position = throttled(scrollOffset, 100);\n *\n * The first value goes straight through and the last of a burst\n * follows at the end of the window, so a value that arrives while the\n * window is open is late rather than lost. That pairing is what makes\n * this usable for a position or a progress reading, where the\n * beginning and the end of a movement both matter and the middle does\n * not.\n *\n * Use this for something that is continuously true, and `debounced`\n * for something a person has finished saying.\n */\nexport function throttled<T>(source: Observable<T>, ms: number): ReadableCell<T> {\n return new TimedCell(source, throttleTime<T>(ms, undefined, { leading: true, trailing: true }));\n}\n","/**\n * The barrier between the application and the view, declared once.\n *\n * A token is a name, a shape and an initial value — and no\n * implementation at all. Both threads import it, which is the point:\n * the module holding it has nothing in it to bundle, so an app's api\n * client and domain logic never reach the render worker the way a\n * shared `Store` class dragged them there.\n *\n * What the framework knows about a channel ends here. It diffs plain\n * data and ships patches; where the observables came from — a single\n * subject, or an api → repository → domain → view-model stack — is the\n * application's business and the framework cannot tell the difference.\n *\n * export interface CatalogView {\n * products: ProductRow[];\n * status: 'loading' | 'ready' | 'error';\n * }\n * export interface CatalogCommands {\n * addToCart(id: string): void;\n * }\n * export const Catalog = channel<CatalogView, CatalogCommands>('catalog', {\n * products: [],\n * status: 'loading'\n * });\n */\n\n/**\n * A command a component can send back across the barrier.\n *\n * The arguments are what cross: each is structured-cloned onto the\n * owning thread, so they must be plain data. There may be as many as\n * the command needs, which is why `move(from, to)` is written the way\n * anyone would write it rather than as `move({ from, to })`; a command\n * used to carry one payload and the second argument was dropped on the\n * floor with a warning.\n *\n * Commands return nothing: the effect comes back as a patch, never as\n * a return value, since there is no synchronous answer to be had\n * across a thread.\n */\nexport type Command = (...args: never[]) => void;\n\n/**\n * The internal view of a command set: a bag of callables by name.\n *\n * Public signatures constrain to `object`, not to this. An application\n * declares its commands as an ordinary interface —\n * `interface CatalogCommands { addToCart(id: string): void }` — and an\n * interface has no index signature, so it does not satisfy a\n * `Record<string, …>` constraint however well it fits in spirit.\n * Constraining to `object` accepts what people actually write; this\n * alias is what the implementation casts to when it looks a command up\n * by name.\n */\nexport type CommandMap = Record<string, Command>;\n\n/** The declared barrier for one area of an application. */\nexport interface ChannelToken<View extends object, Commands extends object = Record<string, never>> {\n readonly name: string;\n /**\n * What every view key holds before the first patch arrives.\n *\n * Required rather than optional, so the render thread never observes\n * `undefined` for a declared key. A channel that is genuinely still\n * loading says so in its own shape — a `status` field — rather than\n * leaving the view to infer it from an absence.\n */\n readonly initial: View;\n /** Phantom, carrying the command types to `send`. Never read. */\n readonly commands?: Commands;\n}\n\n/**\n * Declares a channel.\n *\n * The name identifies it across the thread boundary and must be\n * stable; unlike a class name it survives minification, which is why\n * it is written out rather than derived.\n */\nexport function channel<View extends object, Commands extends object = Record<string, never>>(\n name: string,\n initial: View\n): ChannelToken<View, Commands> {\n if (name.length === 0) {\n throw new Error('A channel needs a name: it is how the two threads agree on which one this is.');\n }\n return { name, initial };\n}\n\n/** A channel written as one object: the view with its values, and the commands. */\nexport interface ChannelSpec<View extends object, Commands extends object> {\n /**\n * Every view key with the value it holds before the first patch.\n *\n * The type of the channel's view is the type of this object, so the\n * keys and their initial values are written once instead of in an\n * interface and again in a literal that has to agree with it.\n */\n readonly view: View;\n /**\n * The commands, as a type rather than as implementations.\n *\n * Written `{} as { addToCart(id: string, quantity: number): void }`:\n * the handlers live on the thread that owns the data and are passed\n * to `provide`, so what belongs in the token is only their shape.\n */\n readonly commands?: Commands;\n}\n\n/**\n * Declares a channel from one object.\n *\n * export const Catalog = defineChannel('catalog', {\n * view: {\n * products: [] as readonly ProductRow[],\n * status: 'loading' as ShelfStatus\n * },\n * commands: {} as {\n * addToCart(id: string, quantity: number): void;\n * move(from: number, to: number): void;\n * }\n * });\n *\n * export type CatalogView = ViewOf<typeof Catalog>;\n *\n * The same token `channel()` returns, declared once instead of three\n * times. `channel<View, Commands>(name, initial)` wrote the view as an\n * interface, then as an initial literal that had to agree with it, and\n * a key added to one and forgotten in the other was a type error in a\n * third file. Here the object is the type.\n *\n * A field whose initial value is narrower than the type it holds is\n * given the type it holds: `[]` is `never[]` and `'loading'` is\n * `string` unless it is said, which is what the `as` clauses above are\n * for. `ViewOf` and `CommandsOf` name the resulting types wherever the\n * application used to name its own interface.\n *\n * `channel()` is not deprecated and keeps working exactly as it did.\n * An application with interfaces it wants to keep, because they are\n * shared with something else or because the initial values are built\n * elsewhere, has nothing to migrate.\n */\nexport function defineChannel<View extends object, Commands extends object = Record<string, never>>(\n name: string,\n spec: ChannelSpec<View, Commands>\n): ChannelToken<View, Commands> {\n return channel<View, Commands>(name, spec.view);\n}\n\n/** The view type of a channel token, for an application that wants to name it. */\nexport type ViewOf<T> = T extends ChannelToken<infer View, object> ? View : never;\n\n/** The command type of a channel token. */\nexport type CommandsOf<T> = T extends ChannelToken<object, infer Commands> ? Commands : never;\n\n/**\n * The keys a channel publishes.\n *\n * Structural in its parameter rather than generic over the token, so\n * it does not have to agree with any particular command type to read\n * what is only ever the initial value's shape.\n */\nexport function viewKeys(token: { initial: object }): string[] {\n return Object.keys(token.initial);\n}\n","import type { Patch } from './StorePatch';\n\n/**\n * A two-way channel endpoint. `MessagePort` satisfies it, as does a\n * test double, so nothing in the channel layer depends on Worker.\n */\nexport interface ChannelPort {\n postMessage(message: unknown): void;\n onmessage: ((event: { data: unknown }) => void) | null;\n}\n\n/**\n * Render thread → the thread that owns the channel.\n *\n * A command's first argument stayed `payload` when commands learned to\n * take more than one, and the rest travel beside it. That is not\n * tidiness: an older view talking to a newer application worker sends\n * no `rest`, which reads as the one-argument call it is, and an older\n * application worker ignores the field, which is exactly what it did\n * before the field existed.\n */\nexport type ChannelClientMessage =\n | { type: 'channel:sync' }\n | { type: 'channel:command'; command: string; payload: unknown; rest?: unknown[] };\n\n/** The owning thread → render thread. */\nexport type ChannelHostMessage =\n | { type: 'channel:patch'; patches: Patch[] }\n | { type: 'channel:error'; message: string; stack?: string };\n\nexport function isChannelClientMessage(value: unknown): value is ChannelClientMessage {\n const type = (value as { type?: unknown } | null)?.type;\n return type === 'channel:sync' || type === 'channel:command';\n}\n\nexport function isChannelHostMessage(value: unknown): value is ChannelHostMessage {\n const type = (value as { type?: unknown } | null)?.type;\n return type === 'channel:patch' || type === 'channel:error';\n}\n","import { structurallyEqual } from './structuralEquals';\n\nexport type PatchPath = readonly (string | number)[];\n\n/**\n * A change to one projection, as sent from a data worker to a replica.\n *\n * Paths are relative to the projection's root value, so a patch is\n * self-contained: the replica never needs the previous value to apply\n * one, only the value it already holds.\n */\nexport type Patch =\n | { op: 'set'; projection: string; path: PatchPath; value: unknown }\n | { op: 'delete'; projection: string; path: PatchPath }\n | {\n op: 'splice';\n projection: string;\n path: PatchPath;\n index: number;\n deleteCount: number;\n items: readonly unknown[];\n };\n\n/**\n * Describes how to turn `previous` into `current` for one projection.\n *\n * Returns an empty list when nothing changed, which is the common case\n * and the reason this exists: the point of a projection is that most\n * state changes do not alter it, and the ones that do usually alter a\n * small part.\n */\nexport function diffProjection(projection: string, previous: unknown, current: unknown): Patch[] {\n const patches: Patch[] = [];\n diff(projection, [], previous, current, patches);\n return patches;\n}\n\nfunction diff(projection: string, path: PatchPath, previous: unknown, current: unknown, out: Patch[]): void {\n if (structurallyEqual(previous, current)) {\n return;\n }\n\n if (Array.isArray(previous) && Array.isArray(current)) {\n diffArray(projection, path, previous, current, out);\n return;\n }\n\n if (isPlainObject(previous) && isPlainObject(current)) {\n for (const key of Object.keys(current)) {\n if (Object.prototype.hasOwnProperty.call(previous, key)) {\n diff(projection, [...path, key], previous[key], current[key], out);\n } else {\n out.push({ op: 'set', projection, path: [...path, key], value: current[key] });\n }\n }\n for (const key of Object.keys(previous)) {\n if (!Object.prototype.hasOwnProperty.call(current, key)) {\n out.push({ op: 'delete', projection, path: [...path, key] });\n }\n }\n return;\n }\n\n out.push({ op: 'set', projection, path, value: current });\n}\n\n/**\n * Diffs two arrays by trimming the common prefix and suffix.\n *\n * This is not a minimal edit script — a shuffle degrades to replacing\n * the middle wholesale. It is chosen because the operations lists\n * actually undergo (append, prepend, remove one, edit in place) all\n * reduce to a single small patch, and computing a true LCS on every\n * store change would cost more than it saves.\n */\nfunction diffArray(projection: string, path: PatchPath, previous: unknown[], current: unknown[], out: Patch[]): void {\n let start = 0;\n while (start < previous.length && start < current.length && structurallyEqual(previous[start], current[start])) {\n start++;\n }\n\n let previousEnd = previous.length - 1;\n let currentEnd = current.length - 1;\n while (previousEnd >= start && currentEnd >= start && structurallyEqual(previous[previousEnd], current[currentEnd])) {\n previousEnd--;\n currentEnd--;\n }\n\n const previousCount = previousEnd - start + 1;\n const currentCount = currentEnd - start + 1;\n\n if (previousCount === 0 && currentCount === 0) {\n return;\n }\n\n if (previousCount === currentCount) {\n // Same span on both sides: these are edits in place, so recurse\n // and let nested diffs stay small rather than resending elements.\n for (let offset = 0; offset < previousCount; offset++) {\n const index = start + offset;\n diff(projection, [...path, index], previous[index], current[index], out);\n }\n return;\n }\n\n out.push({\n op: 'splice',\n projection,\n path,\n index: start,\n deleteCount: previousCount,\n items: current.slice(start, currentEnd + 1)\n });\n}\n\n/**\n * Applies patches to a projection value, sharing structure with the\n * original everywhere the patch did not reach.\n *\n * Nothing handed in is mutated: bindings hold onto emitted values, so a\n * replica that edited in place would change data a component already\n * rendered.\n *\n * **Each container on a patched path is copied once per batch, not once\n * per patch.** A batch of N patches into one K-key object used to cost\n * N × K: every patch spread the whole object again to change one key.\n * A snapshot keyed by id is exactly that shape — gessologic published\n * `Record<netId, 0 | 1>` for ten thousand nets, about nine hundred\n * patches a publish, and the render worker's patch phase fell minutes\n * behind a 60 Hz stream it could never catch. So the batch remembers\n * the containers it has copied, and writes into those in place: they\n * are its own, made during this call and seen by nobody yet. Values\n * that arrived inside a patch are never written into, because they are\n * the patch's — a devtools log replays the same patch objects again.\n */\nexport function applyPatches(root: unknown, patches: readonly Patch[]): unknown {\n const owned = new Set<object>();\n let next = root;\n for (const patch of patches) {\n next = applyOne(next, patch, owned);\n }\n return next;\n}\n\nexport function applyPatch(root: unknown, patch: Patch): unknown {\n return applyOne(root, patch, new Set());\n}\n\n/** The containers this batch copied, and may therefore write into. */\ntype Owned = Set<object>;\n\nfunction applyOne(root: unknown, patch: Patch, owned: Owned): unknown {\n switch (patch.op) {\n case 'set':\n return setIn(root, patch.path, 0, patch.value, owned);\n case 'delete':\n if (patch.path.length === 0) {\n return undefined;\n }\n return deleteIn(root, patch.path, 0, owned);\n case 'splice':\n return updateIn(root, patch.path, 0, owned, node => {\n // Concatenation rather than `splice(..., ...items)`: spreading\n // the items passes each as an argument, and a batch of two\n // hundred thousand overflows the call stack.\n const array = Array.isArray(node) ? node : [];\n const spliced = array.slice(0, patch.index).concat(patch.items, array.slice(patch.index + patch.deleteCount));\n owned.add(spliced);\n return spliced;\n });\n }\n}\n\nfunction setIn(node: unknown, path: PatchPath, index: number, value: unknown, owned: Owned): unknown {\n if (index === path.length) {\n return value;\n }\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n setKey(copy, key, setIn(readKey(node, key), path, index + 1, value, owned));\n return copy;\n}\n\nfunction deleteIn(node: unknown, path: PatchPath, index: number, owned: Owned): unknown {\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n if (index === path.length - 1) {\n if (Array.isArray(copy)) {\n copy.splice(Number(key), 1);\n } else {\n delete (copy as Record<string, unknown>)[String(key)];\n }\n return copy;\n }\n setKey(copy, key, deleteIn(readKey(node, key), path, index + 1, owned));\n return copy;\n}\n\nfunction updateIn(\n node: unknown,\n path: PatchPath,\n index: number,\n owned: Owned,\n update: (node: unknown) => unknown\n): unknown {\n if (index === path.length) {\n return update(node);\n }\n const key = path[index];\n const copy = cloneContainer(node, key, owned);\n setKey(copy, key, updateIn(readKey(node, key), path, index + 1, owned, update));\n return copy;\n}\n\n/**\n * The container to write `key` into: `node` itself when this batch\n * already copied it, and a fresh copy, remembered, when it did not.\n */\nfunction cloneContainer(node: unknown, key: string | number, owned: Owned): unknown[] | Record<string, unknown> {\n if (typeof node === 'object' && node !== null && owned.has(node)) {\n return node as unknown[] | Record<string, unknown>;\n }\n let copy: unknown[] | Record<string, unknown>;\n if (Array.isArray(node)) {\n copy = node.slice();\n } else if (isPlainObject(node)) {\n copy = { ...node };\n } else {\n // The path runs past the end of what the replica holds, which\n // happens when a patch fills in a branch that did not exist yet.\n copy = typeof key === 'number' ? [] : {};\n }\n owned.add(copy);\n return copy;\n}\n\nfunction readKey(node: unknown, key: string | number): unknown {\n if (node === null || node === undefined) {\n return undefined;\n }\n return (node as Record<string | number, unknown>)[key];\n}\n\nfunction setKey(container: unknown[] | Record<string, unknown>, key: string | number, value: unknown): void {\n (container as Record<string | number, unknown>)[key] = value;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n","/**\n * Checks that a value can cross the barrier.\n *\n * `structurallyEqual` understands primitives, arrays and plain\n * objects, and falls back to reference equality for everything else —\n * which for a freshly built value reports \"changed\" every single time.\n * A view key holding a `Date`, a `Map` or a domain object therefore\n * re-emits on every unrelated update and dirties the subtree bound to\n * it, forever, while looking perfectly correct.\n *\n * That failure is invisible in a test and shows up as a vague slowness\n * much later, so `provide` checks each key's first emission and throws\n * naming the path. The view-model layer is where rich objects become\n * flat data; this is what makes that a rule rather than a convention.\n *\n * The check runs once per key, on the first value only. It is a\n * development guard against a design mistake, not a validator on the\n * hot path.\n */\n\nconst MAX_DEPTH = 100;\n\n/**\n * Returns the path to the first value that cannot cross, or null when\n * the whole tree is plain data.\n */\nexport function findUnplainPath(value: unknown, path: readonly (string | number)[] = []): string | null {\n if (path.length > MAX_DEPTH) {\n return format(path);\n }\n if (value === null) {\n return null;\n }\n const type = typeof value;\n if (type === 'string' || type === 'number' || type === 'boolean' || type === 'undefined') {\n return null;\n }\n if (type === 'function' || type === 'symbol' || type === 'bigint') {\n return format(path);\n }\n if (Array.isArray(value)) {\n for (let index = 0; index < value.length; index++) {\n const found = findUnplainPath(value[index], [...path, index]);\n if (found !== null) {\n return found;\n }\n }\n return null;\n }\n const prototype = Object.getPrototypeOf(value as object);\n if (prototype !== Object.prototype && prototype !== null) {\n return format(path);\n }\n for (const [key, member] of Object.entries(value as Record<string, unknown>)) {\n const found = findUnplainPath(member, [...path, key]);\n if (found !== null) {\n return found;\n }\n }\n return null;\n}\n\n/**\n * Throws when `value` cannot cross the barrier, naming the channel,\n * the key and the path within it.\n */\nexport function requirePlainData(channelName: string, key: string, value: unknown): void {\n const path = findUnplainPath(value);\n if (path === null) {\n return;\n }\n const where = path === '' ? `'${key}'` : `'${key}'${path}`;\n throw new Error(\n `Channel '${channelName}' published ${where}, which is not plain data. ` +\n `Only primitives, arrays and plain objects cross the barrier: a Date, Map, Set, ` +\n `class instance or function compares by reference, so it would report a change on ` +\n `every update and rebuild the subtree bound to it. Flatten it in the view model.`\n );\n}\n\nfunction format(path: readonly (string | number)[]): string {\n return path.map(step => (typeof step === 'number' ? `[${step}]` : `.${step}`)).join('');\n}\n","import { Subscription, type Observable } from 'rxjs';\n\nimport { diffProjection, type Patch } from './StorePatch';\nimport { isChannelClientMessage, type ChannelHostMessage, type ChannelPort } from './ChannelProtocol';\nimport { requirePlainData } from './plainData';\nimport { viewKeys, type ChannelToken, type CommandMap } from './ChannelToken';\n\n/** What the owning thread supplies for a channel. */\nexport interface ChannelSource<View extends object, Commands extends object> {\n /** One observable per declared view key. */\n view: { readonly [K in keyof View]: Observable<View[K]> };\n /** One handler per declared command. */\n commands?: Commands;\n}\n\n/**\n * Publishes a channel from the thread that owns its data.\n *\n * Each view key is subscribed, diffed against what the other side last\n * saw, and sent as patches. Whatever produced the observable — a bare\n * subject or a stack of layers — stays here; only plain data crosses.\n *\n * Keys are subscribed on the first sync request, so a channel nobody\n * is watching costs nothing.\n */\nexport function provide<View extends object, Commands extends object>(\n token: ChannelToken<View, Commands>,\n source: ChannelSource<View, Commands>,\n port: ChannelPort\n): ProvidedChannel {\n return new ProvidedChannel(\n token as ChannelToken<object, CommandMap>,\n source as ChannelSource<object, CommandMap>,\n port\n );\n}\n\nexport class ProvidedChannel {\n private readonly subscriptions = new Subscription();\n /**\n * What the other side is known to hold, seeded from the token's\n * initial value — which the replica also starts from, so an app\n * whose first emission equals the initial sends nothing at all.\n */\n private readonly previous = new Map<string, unknown>();\n private readonly checked = new Set<string>();\n\n private synced = false;\n\n constructor(\n private readonly token: ChannelToken<object, CommandMap>,\n private readonly source: ChannelSource<object, CommandMap>,\n private readonly port: ChannelPort\n ) {\n for (const key of viewKeys(token)) {\n this.previous.set(key, (token.initial as Record<string, unknown>)[key]);\n }\n this.port.onmessage = event => this.receive(event.data);\n }\n\n private receive(data: unknown): void {\n if (!isChannelClientMessage(data)) {\n return;\n }\n try {\n if (data.type === 'channel:sync') {\n this.sync();\n return;\n }\n this.runCommand(data.command, data.payload, data.rest);\n } catch (error) {\n // Reported rather than thrown: this runs on the thread that owns\n // the data, and a throw here would leave the view waiting for a\n // patch that never comes, with nothing said about why.\n this.post({\n type: 'channel:error',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined\n });\n }\n }\n\n private runCommand(name: string, payload: unknown, rest?: readonly unknown[]): void {\n const handler = this.source.commands?.[name];\n if (handler === undefined) {\n const names = Object.keys(this.source.commands ?? {})\n .sort()\n .join(', ');\n throw new Error(\n `Channel '${this.token.name}' has no command '${name}'. ` +\n `Declared commands: ${names.length > 0 ? names : '(none)'}.`\n );\n }\n // Spread rather than passed as one payload: a command carries as\n // many arguments as it declares. A client that sent none beyond\n // the first sends no `rest`, so this is the single-argument call\n // it always was.\n (handler as (...args: unknown[]) => void)(payload, ...(rest ?? []));\n }\n\n private sync(): void {\n if (this.synced) {\n this.resend();\n return;\n }\n this.synced = true;\n\n for (const key of viewKeys(this.token)) {\n const observable = (this.source.view as Record<string, Observable<unknown> | undefined>)[key];\n if (observable === undefined) {\n this.post({\n type: 'channel:error',\n message: `Channel '${this.token.name}' declares view key '${key}' but nothing was provided for it.`\n });\n continue;\n }\n this.subscriptions.add(\n observable.subscribe({\n next: value => this.publish(key, value),\n error: (error: unknown) =>\n this.post({\n type: 'channel:error',\n message: `Channel '${this.token.name}' view key '${key}' errored: ${\n error instanceof Error ? error.message : String(error)\n }`,\n stack: error instanceof Error ? error.stack : undefined\n })\n })\n );\n }\n }\n\n private publish(key: string, value: unknown): void {\n if (!this.checked.has(key)) {\n this.checked.add(key);\n try {\n // Once per key, on the first value: a design mistake, caught at\n // startup rather than felt as slowness later. See `plainData`.\n requirePlainData(this.token.name, key, value);\n } catch (error) {\n // Reported, not rethrown. This runs inside an observer's `next`,\n // and RxJS routes a throw there to its unhandled-error hook\n // rather than back to the subscriber — so a throw would surface\n // as a stray async error on this thread and say nothing at all\n // on the thread that needs to know.\n this.post({\n type: 'channel:error',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined\n });\n return;\n }\n }\n const patches = diffProjection(key, this.previous.get(key), value);\n this.previous.set(key, value);\n if (patches.length > 0) {\n this.post({ type: 'channel:patch', patches });\n }\n }\n\n /** Re-sends every key in full, for a client that reattached. */\n private resend(): void {\n const patches: Patch[] = [];\n for (const [key, value] of this.previous) {\n patches.push({ op: 'set', projection: key, path: [], value });\n }\n if (patches.length > 0) {\n this.post({ type: 'channel:patch', patches });\n }\n }\n\n private post(message: ChannelHostMessage): void {\n this.port.postMessage(message);\n }\n\n dispose(): void {\n this.subscriptions.unsubscribe();\n this.port.onmessage = null;\n }\n}\n","/**\n * What a node is, as plain data (the inspector).\n *\n * The inspector shows a node's props, its resolved environment, its\n * bindings and their sources, its layout explanation and which\n * component owns it. Every one of those lives in the render thread,\n * and none of them can cross a `postMessage`: a `UiNode` is a live\n * object, an `Observable` is a subscription, a component instance is a\n * class. So the report is built where the tree is and only strings\n * cross, which is the same rule the existing `inspect` message follows\n * with `formatExplanation`'s text, and the same reason.\n *\n * That makes the report lossy on purpose. It is a description of a\n * node for a person to read, not a handle on one: nothing in it can be\n * clicked back to the object it came from, and nothing in it is worth\n * asserting on beyond the fact that it says what the tree says.\n */\nexport interface UiNodeReport {\n readonly id: string;\n /** `UiNodeType`, as its string value. */\n readonly type: string;\n readonly box: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };\n /**\n * The components that rendered this node, nearest first.\n *\n * A node has no backpointer to a component: the builder gives every\n * component slot a Fragment anchor whose id carries `:component:`,\n * and the resolver keeps one host per anchor id. Walking up the\n * ancestors for those anchors is therefore the only way to answer\n * \"who rendered this\", and it answers it exactly, because that\n * anchor *is* the component's identity.\n */\n readonly owners: readonly UiOwnerReport[];\n readonly props: readonly UiPropReport[];\n readonly environment: readonly UiEnvironmentReport[];\n /** Attached modifier kinds, in the order the element listed them. */\n readonly modifiers: readonly string[];\n /** The event types this node has listeners for, e.g. `click`. */\n readonly listens: readonly string[];\n /**\n * What lies under the pointer beneath this node, topmost first: the\n * nodes this one is painted over and would take a press from. The\n * answer to \"I clicked the button and nothing happened\": the node the\n * inspector shows is the one that took the press, and this is the\n * button it covered. Empty when the pointer is not over the node.\n */\n readonly beneath: readonly UiBeneathReport[];\n readonly semantics?: UiSemanticsReport;\n /** `formatExplanation` of the node's layout, which is L8's answer. */\n readonly explanation: string;\n}\n\n/** A node under the inspected one at the pointer. */\nexport interface UiBeneathReport {\n readonly id: string;\n readonly type: string;\n /** The component that rendered it, if one did. */\n readonly owner?: string;\n /** The event types it listens for, so a covered button reads as one. */\n readonly listens: readonly string[];\n}\n\nexport interface UiOwnerReport {\n /** The `@Define` tag, else the class or function name. */\n readonly name: string;\n readonly anchorId: string;\n}\n\n/** As much of a node as a one-line path needs. */\nexport interface NodePathTarget {\n /** `UiNodeType`, as its string value. */\n readonly type: string;\n readonly id: string;\n /** The node's accessible name, when it has one. */\n readonly label?: string;\n}\n\n/**\n * A node as a path somebody can read: `App > TrackScreen > ActionRow >\n * Button \"Like\"`.\n *\n * Written for error messages rather than for the inspector, and the\n * difference decides the shape. A report is read beside the tree it\n * came from, so an id is a handle; an error is read in a console or an\n * overlay with no tree beside it, and `node-4821` there is a fact\n * about nothing. The owner chain is what a person recognises, because\n * it is the components they wrote.\n *\n * Owners arrive nearest-first, as `UiNodeReport.owners` computes them,\n * and read outermost-first, as a path does. The accessible name is the\n * leaf when there is one: two `Button`s in the same row are only told\n * apart by what they say.\n */\nexport function formatNodePath(owners: readonly UiOwnerReport[], node: NodePathTarget): string {\n const names = owners.map(owner => owner.name).reverse();\n if (names.length === 0) {\n // Nothing rendered it: a node built without a component around it,\n // which is rare enough that the id is the only thing to say.\n return node.label === undefined || node.label === '' ? `${node.type} ${node.id}` : `${node.type} \"${node.label}\"`;\n }\n const path = names.join(' > ');\n return node.label === undefined || node.label === '' ? path : `${path} \"${node.label}\"`;\n}\n\n/** Where a property's current value came from. */\nexport type UiPropOrigin = 'element' | 'binding' | 'modifier';\n\nexport interface UiPropReport {\n readonly name: string;\n readonly value: string;\n readonly origin: UiPropOrigin;\n /**\n * For a modifier write, the modifiers writing it and what the\n * element declared; for a binding, that it is bound. Absent for a\n * plain element value.\n */\n readonly source?: string;\n /** For a bound property, the stream feeding it. Absent otherwise. */\n readonly stream?: UiStreamReport;\n}\n\n/**\n * The stream behind a bound property: which one, what it last said,\n * and when.\n *\n * \"Is this value bound\" was the third question the inspector set\n * out to answer, and the report answered it with a yes. A yes is not\n * enough to debug with: a prop that is not updating and a prop whose\n * stream has not emitted since the screen was built look identical on\n * the node, and so did they in the report.\n *\n * `emittedAt` is on the epoch clock rather than the thread's own,\n * because the panel reading it is one or two threads away and\n * `performance.now()` counts from each thread's creation. The panel\n * subtracts its own `Date.now()`.\n *\n * An epoch stamp rather than an age for a second reason: an age\n * changes on every frame, and the runtime decides whether to re-send a\n * selected node's report by comparing it with the last one. A report\n * carrying an age would differ from itself sixty times a second and\n * the panel would be redrawn for a clock tick.\n */\nexport interface UiStreamReport {\n /**\n * What feeds it: a labelled cell's own name (`queue.current`), else\n * what kind of stream it is.\n */\n readonly source: string;\n /** `cell` when the stream named itself, `observable` when it did not. */\n readonly kind: 'cell' | 'observable';\n /** The last value the stream produced, printed. */\n readonly value: string;\n /** How many values it has produced since the property was bound. */\n readonly emissions: number;\n /** When the last value arrived, as epoch milliseconds, or null before the first. */\n readonly emittedAt: number | null;\n /** Whether the subscription is still live. A false here is a torn-down binding still on the node. */\n readonly connected: boolean;\n}\n\n/**\n * A bound property's stream, as far as the report is concerned.\n *\n * Structural rather than `UiBinding`, so this module keeps its one\n * rule: it describes a node and imports nothing that holds one.\n */\nexport interface BoundStream {\n readonly id: number;\n readonly observable: unknown;\n value(): unknown;\n emissionCount(): number;\n emittedAt(): number | null;\n connected(): boolean;\n}\n\n/**\n * Describes the stream driving a property.\n *\n * `timeOrigin` turns the binding's own reading into an epoch stamp:\n * `performance.timeOrigin` on a thread that has one, and zero where\n * the reading is already an epoch.\n */\nexport function describeStream(binding: BoundStream, timeOrigin: number): UiStreamReport {\n // A labelled cell says where the value comes from: `Card.title`,\n // `queue.current`. An anonymous pipe only has the binding's id.\n const label = (binding.observable as { label?: unknown } | null)?.label;\n const labelled = typeof label === 'string' && label !== '';\n const emittedAt = binding.emittedAt();\n return {\n source: labelled ? label : `observable #${binding.id}`,\n kind: labelled ? 'cell' : 'observable',\n value: printPropValue(binding.value()),\n emissions: binding.emissionCount(),\n emittedAt: emittedAt === null ? null : timeOrigin + emittedAt,\n connected: binding.connected()\n };\n}\n\n/** A stream as one line: what feeds the prop, and how long ago it said so. */\nexport function formatStream(stream: UiStreamReport, now: number = Date.now()): string {\n const when = stream.emittedAt === null ? 'no value yet' : `${formatAge(Math.max(0, now - stream.emittedAt))} ago`;\n const emissions = `${stream.emissions} emission${stream.emissions === 1 ? '' : 's'}`;\n return `${stream.source} · ${emissions} · ${when}${stream.connected ? '' : ' · disconnected'}`;\n}\n\n/** An age in the largest unit that stays readable. */\nexport function formatAge(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(1)}s`;\n }\n return `${Math.round(ms / 60_000)}m`;\n}\n\nexport interface UiEnvironmentReport {\n readonly key: string;\n readonly value: string;\n /** Whether this node provides the value rather than inheriting it. */\n readonly provided: boolean;\n}\n\nexport interface UiSemanticsReport {\n readonly role?: string;\n readonly label?: string;\n readonly value?: string;\n readonly states?: readonly string[];\n}\n\n/**\n * A value as one line a person can read.\n *\n * `JSON.stringify` alone is not enough: the two values a canvas UI\n * puts in a property that it cannot handle are a `Set` (a node's\n * visual states) and a function (an event handler), and it prints both\n * as `{}`, which in an inspector reads as a bug in the application\n * rather than one in the inspector.\n */\nexport function printPropValue(value: unknown): string {\n if (value === undefined) {\n return 'undefined';\n }\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'function') {\n return `ƒ ${value.name === '' ? '(anonymous)' : value.name}`;\n }\n if (typeof value === 'symbol') {\n return value.toString();\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n if (value instanceof Set) {\n return `Set { ${[...value].map(printPropValue).join(', ')} }`;\n }\n if (value instanceof Map) {\n return `Map { ${[...value].map(([key, entry]) => `${printPropValue(key)}: ${printPropValue(entry)}`).join(', ')} }`;\n }\n if (Array.isArray(value)) {\n return `[${value.map(printPropValue).join(', ')}]`;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n // A cyclic value, or one with a throwing getter. The inspector\n // must not be the thing that breaks while explaining a break.\n return String(value);\n }\n}\n\n/** The report as text, for a console or a test failure. */\nexport function formatNodeReport(report: UiNodeReport): string {\n const lines: string[] = [`${report.type} '${report.id}'`];\n if (report.owners.length > 0) {\n lines.push(`rendered by ${report.owners.map(owner => owner.name).join(' inside ')}`);\n }\n if (report.modifiers.length > 0) {\n lines.push(`modifiers: ${report.modifiers.join(', ')}`);\n }\n if (report.listens.length > 0) {\n lines.push(`listens: ${report.listens.join(', ')}`);\n }\n if (report.beneath.length > 0) {\n lines.push('beneath, at the pointer:');\n for (const under of report.beneath) {\n const owner = under.owner === undefined ? '' : ` (${under.owner})`;\n const listens = under.listens.length === 0 ? '' : `, listens: ${under.listens.join(', ')}`;\n lines.push(` ${under.type} ${under.id}${owner}${listens}`);\n }\n }\n if (report.props.length > 0) {\n lines.push('props:');\n for (const prop of report.props) {\n lines.push(` ${prop.name} = ${prop.value}${prop.source === undefined ? '' : ` (${prop.source})`}`);\n if (prop.stream !== undefined) {\n lines.push(` ${formatStream(prop.stream)}`);\n }\n }\n }\n if (report.environment.length > 0) {\n lines.push('environment:');\n for (const entry of report.environment) {\n lines.push(` ${entry.key} = ${entry.value}${entry.provided ? ' (provided here)' : ''}`);\n }\n }\n if (report.semantics !== undefined) {\n const parts = [\n report.semantics.role === undefined ? undefined : `role ${report.semantics.role}`,\n report.semantics.label === undefined ? undefined : `label ${report.semantics.label}`,\n report.semantics.value === undefined ? undefined : `value ${report.semantics.value}`,\n report.semantics.states === undefined || report.semantics.states.length === 0\n ? undefined\n : `states ${report.semantics.states.join(', ')}`\n ].filter(part => part !== undefined);\n if (parts.length > 0) {\n lines.push(`semantics: ${parts.join(' · ')}`);\n }\n }\n lines.push(report.explanation);\n return lines.join('\\n');\n}\n","import { printPropValue } from '../app/NodeReport';\nimport type { ConsoleEntry } from '../app/DevtoolsProtocol';\n\n/**\n * Forwarding a worker's `console.*`.\n *\n * A worker's console is real, but it is in devtools' worker target,\n * which a developer has to know to select and cannot read alongside\n * the page's. So while a devtools panel asks for it, each `console.*`\n * call in the worker is also handed to a sink as plain strings, with\n * the thread named, and the panel shows the three threads as one log.\n *\n * The call still reaches the worker's own console: this is a copy,\n * not a redirect, so turning a panel on changes nothing about what\n * devtools' worker target shows.\n */\n\nexport type ConsoleLevel = ConsoleEntry['level'];\n\nconst LEVELS: readonly ConsoleLevel[] = ['log', 'info', 'warn', 'error', 'debug'];\n\n/** An entry before the shell has said which thread it came from. */\nexport type ConsoleEntryBody = Omit<ConsoleEntry, 'thread'>;\n\n/**\n * Copies every `console.*` call on `target` (the worker global's\n * console by default) to `sink`. Returns a function that restores the\n * original methods.\n *\n * Idempotent per target: a second capture on the same console replaces\n * the first's sink rather than nesting, so toggling a panel on twice\n * does not log twice.\n */\nexport function captureConsole(sink: (entry: ConsoleEntryBody) => void, target: Console = console): () => void {\n const installed = (target as Console & { [CAPTURED]?: { sink: typeof sink; restore: () => void } })[CAPTURED];\n if (installed !== undefined) {\n installed.sink = sink;\n return installed.restore;\n }\n const originals = new Map<ConsoleLevel, (...args: unknown[]) => void>();\n const state = {\n sink,\n restore: (): void => {\n for (const [level, original] of originals) {\n target[level] = original;\n }\n delete (target as Console & { [CAPTURED]?: unknown })[CAPTURED];\n }\n };\n for (const level of LEVELS) {\n const original = target[level] as (...args: unknown[]) => void;\n originals.set(level, original);\n target[level] = (...args: unknown[]): void => {\n original.apply(target, args);\n // A sink that throws must not break the application's logging,\n // least of all while a developer is trying to read it.\n try {\n state.sink({ level, args: args.map(formatConsoleArg), at: Date.now() });\n } catch {\n // Nothing to do: the original call already ran.\n }\n };\n }\n (target as Console & { [CAPTURED]?: typeof state })[CAPTURED] = state;\n return state.restore;\n}\n\nconst CAPTURED = Symbol.for('gesso:console-captured');\n\n/**\n * One console argument as the panel prints it.\n *\n * `printPropValue` already prints the values a canvas UI is likely to\n * log; an Error is the one thing it prints badly (`{}`), and the one\n * thing a developer most wants to read whole.\n */\nexport function formatConsoleArg(value: unknown): string {\n if (value instanceof Error) {\n return value.stack !== undefined && value.stack !== '' ? value.stack : `${value.name}: ${value.message}`;\n }\n return printPropValue(value);\n}\n\n/** The shell's request to an application worker to start or stop forwarding. */\nexport interface ConsoleForwardingMessage {\n type: 'gesso:console';\n enabled: boolean;\n}\n\n/** An application worker's forwarded entry. */\nexport interface ConsoleEntryMessage {\n type: 'gesso:console';\n entry: ConsoleEntryBody;\n}\n\nexport function isConsoleForwardingMessage(value: unknown): value is ConsoleForwardingMessage {\n const message = value as { type?: unknown; enabled?: unknown } | null;\n return message?.type === 'gesso:console' && typeof message.enabled === 'boolean';\n}\n\nexport function isConsoleEntryMessage(value: unknown): value is ConsoleEntryMessage {\n const message = value as { type?: unknown; entry?: unknown } | null;\n return message?.type === 'gesso:console' && typeof message.entry === 'object' && message.entry !== null;\n}\n","/**\n * Named `MessagePort`s into a worker.\n *\n * A worker's global `onmessage` is a single channel, so a worker that\n * receives messages on it can host exactly one conversation. That is\n * why a store in a data worker used to mean a worker per store: the\n * client claimed the `Worker` object itself, and a second one had\n * nowhere to go.\n *\n * A handshake fixes it. The client opens a `MessageChannel`, keeps one\n * end and transfers the other with a name; the worker serves that name\n * and the two ends talk privately from then on. The global channel is\n * used once per conversation and carries nothing else.\n *\n * Nothing here knows what travels over a port. It is the transport the\n * store replication in `../store/worker` runs on today and the barrier\n * contract will run on next.\n */\n\nimport { captureConsole, isConsoleForwardingMessage, type ConsoleEntryMessage } from './captureConsole';\n\n/** A port-shaped thing: `MessagePort` and `Worker` both satisfy it. */\nexport interface MessageEndpoint {\n postMessage(message: unknown): void;\n onmessage: ((event: { data: unknown }) => void) | null;\n}\n\n/** The one message the global channel carries. */\nexport interface PortHandshake {\n type: 'gesso:port';\n key: string;\n}\n\nexport function isPortHandshake(value: unknown): value is PortHandshake {\n const message = value as { type?: unknown; key?: unknown } | null;\n return message?.type === 'gesso:port' && typeof message.key === 'string';\n}\n\n/**\n * A worker spawned at most once, serving any number of named ports.\n *\n * Handed to several `useChannel` calls, it is what lets one worker\n * hold a whole application layer instead of one channel. Spawning is\n * deferred to the first `open`, so a handle nobody uses costs nothing.\n */\nexport interface WorkerHandle {\n /**\n * Opens a private channel under `key`, spawning the worker if this\n * is the first one.\n */\n open(key: string): MessagePort;\n /** Whether the worker has been spawned. */\n readonly spawned: boolean;\n /** Stops the worker, if it was ever started. */\n terminate(): void;\n}\n\n/**\n * Stands for \"whichever worker the shell spawned for the application\".\n *\n * A registration inside the render worker cannot name that worker: it\n * is created by the shell and its port only arrives with `init`, long\n * after `useChannel` and `useService` have run. This sentinel is what a\n * registration puts there instead, and the render worker swaps it for\n * the real handle once the port shows up.\n *\n * Opening a port on it before then is a bug rather than a race, so it\n * says so.\n */\nexport const APPLICATION_WORKER: WorkerHandle = {\n open(): MessagePort {\n throw new Error(\n 'APPLICATION_WORKER was used directly. It is a placeholder the render worker ' +\n \"replaces with the shell's port; reaching it means no application-logic worker was supplied. \" +\n 'Pass appLogicWorker to createApp.'\n );\n },\n spawned: false,\n terminate(): void {}\n};\n\n/**\n * Anything a handshake can be posted to with a port attached.\n * `Worker` and `MessagePort` both satisfy it.\n */\nexport interface TransferTarget {\n postMessage(message: unknown, transfer: Transferable[]): void;\n}\n\n/**\n * A handle over an endpoint someone else owns.\n *\n * The shell spawns the application worker and hands the render worker\n * one end of a channel to it; this is what the render worker opens\n * named ports over. `terminate` is a no-op — the lifetime belongs to\n * whoever created the endpoint, and a handle that could kill a worker\n * it did not spawn would be a surprising thing to hand out.\n */\nexport function portHandle(endpoint: TransferTarget): WorkerHandle {\n return {\n open(key: string): MessagePort {\n const channel = new MessageChannel();\n endpoint.postMessage({ type: 'gesso:port', key } satisfies PortHandshake, [channel.port2]);\n return channel.port1;\n },\n get spawned(): boolean {\n return true;\n },\n terminate(): void {}\n };\n}\n\n/**\n * Routes handshakes arriving on a transferred port through the same\n * handlers as the worker's own global channel.\n *\n * The shell owns the application worker and gives the render worker a\n * port to it, so handshakes reach this worker two ways: on its global\n * channel (whoever spawned it) and on that port (whoever was given\n * it). Both should be served by the same handlers, and neither end\n * should have to know which route a channel came in on.\n */\nexport interface HubMessage {\n type: 'gesso:hub';\n}\n\nexport function isHubMessage(value: unknown): value is HubMessage {\n return (value as { type?: unknown } | null)?.type === 'gesso:hub';\n}\n\nconst BASE_INSTALLED = Symbol.for('gesso:port-base-installed');\nconst CONSOLE_RESTORE = Symbol.for('gesso:port-console-restore');\n\n/**\n * Starts or stops copying this worker's console to whoever posts to\n * it, as `ConsoleEntryMessage`s. A host with no `postMessage` (a test's\n * bare object) has nowhere to send them and forwards nothing.\n */\nfunction setConsoleForwarding(host: PortHost & { [CONSOLE_RESTORE]?: () => void }, enabled: boolean): void {\n host[CONSOLE_RESTORE]?.();\n delete host[CONSOLE_RESTORE];\n const post = (host as { postMessage?: (message: unknown) => void }).postMessage;\n if (!enabled || typeof post !== 'function') {\n return;\n }\n host[CONSOLE_RESTORE] = captureConsole(entry => {\n const message: ConsoleEntryMessage = { type: 'gesso:console', entry };\n post.call(host, message);\n });\n}\n\n/**\n * The handler every `servePorts` chain sits on top of.\n *\n * It owns the two things no individual server can: routing a hub port\n * through the whole chain, and answering a handshake that nobody\n * accepted. Both have to be innermost — the first because the chain is\n * only complete once every server has wrapped `onmessage`, the second\n * because \"nobody accepted\" is only known after every server has\n * declined.\n */\nfunction installBase(host: PortHost & { [BASE_INSTALLED]?: boolean }): void {\n if (host[BASE_INSTALLED] === true) {\n return;\n }\n host[BASE_INSTALLED] = true;\n const previous = host.onmessage;\n const registered = (host as HostWithNames)[SERVED_NAMES] ?? [];\n\n host.onmessage = event => {\n if (isConsoleForwardingMessage(event.data)) {\n // The shell, on behalf of a devtools panel, asking for this\n // worker's console. Answered here because this is the one handler\n // every application worker has, whatever it serves.\n setConsoleForwarding(host, event.data.enabled);\n return;\n }\n if (isHubMessage(event.data)) {\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error('A hub message arrived with no port attached.');\n }\n // The whole chain, not just this handler: by now every\n // `servePorts` on this host has wrapped `onmessage`, and a\n // handshake arriving on the port should reach all of them.\n port.onmessage = host.onmessage;\n return;\n }\n if (!isPortHandshake(event.data)) {\n previous?.(event);\n return;\n }\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error(`Port handshake for '${event.data.key}' arrived with no port attached.`);\n }\n // Reaching here means every server declined. Silence would leave\n // the client waiting forever with nothing said.\n const served = registered.flatMap(get => [...get()]).sort();\n const error: PortErrorMessage = {\n type: 'port:error',\n message: `Nothing is served under '${event.data.key}'. This worker serves: ${\n served.length > 0 ? served.join(', ') : '(nothing)'\n }.`\n };\n port.postMessage(error);\n };\n}\n\n/**\n * Wraps a worker factory so the worker is created once and shared.\n *\n * A factory rather than a URL for the same reason the render worker\n * takes one: a bundler only emits a chunk for a worker it can see\n * constructed literally in the calling module.\n *\n * const data = workerHandle(\n * () => new Worker(new URL('./data.worker.ts', import.meta.url), { type: 'module' })\n * );\n */\nexport function workerHandle(factory: () => Worker): WorkerHandle {\n let worker: Worker | undefined;\n return {\n open(key: string): MessagePort {\n worker ??= factory();\n const channel = new MessageChannel();\n // The worker may not have run its module body yet. Messages\n // posted to a worker queue until it installs a handler, so the\n // handshake is safe as long as `servePorts` is called\n // synchronously at the top level of the worker module — the same\n // guarantee `renderRoot` relies on.\n worker.postMessage({ type: 'gesso:port', key } satisfies PortHandshake, [channel.port2]);\n return channel.port1;\n },\n get spawned(): boolean {\n return worker !== undefined;\n },\n terminate(): void {\n worker?.terminate();\n worker = undefined;\n }\n };\n}\n\n/**\n * Minimal view of a worker's global scope, so this module type-checks\n * against the DOM lib without pulling in the WebWorker lib.\n */\nexport interface PortHost {\n onmessage: ((event: { data: unknown; ports?: readonly MessagePort[] }) => void) | null;\n}\n\n/**\n * What a port is answered with when no handler claimed its name.\n *\n * Its own message type rather than a store's or a channel's, because\n * the transport does not know which of them the client is: both\n * recognise it, so a mismatched name is loud either way.\n */\nexport interface PortErrorMessage {\n type: 'port:error';\n message: string;\n}\n\nexport function isPortErrorMessage(value: unknown): value is PortErrorMessage {\n const message = value as { type?: unknown; message?: unknown } | null;\n return message?.type === 'port:error' && typeof message.message === 'string';\n}\n\n/** Every name served on a host, across all `servePorts` calls on it. */\nconst SERVED_NAMES = Symbol.for('gesso:served-port-names');\n\ninterface HostWithNames extends PortHost {\n [SERVED_NAMES]?: Array<() => readonly string[]>;\n}\n\n/**\n * Serves named ports inside a worker.\n *\n * Call it synchronously at the top level of the worker module, before\n * any await, so no handshake is missed.\n *\n * `onPort` returns whether it took the port. Returning false passes\n * the handshake to whatever was serving before, which is what lets two\n * kinds of thing — stores and channels, during the migration — share\n * one worker: each answers for its own names and declines the rest.\n * When nobody accepts, the port is answered with an error naming\n * everything the worker does serve, because a handshake that silently\n * matched nothing leaves the client waiting forever with nothing said.\n *\n * `names` is only read to build that message.\n *\n * Returns a function that stops serving.\n */\nexport function servePorts(\n onPort: (key: string, port: MessagePort) => boolean,\n names: () => readonly string[],\n host: PortHost = self as unknown as PortHost\n): () => void {\n const withNames = host as HostWithNames;\n const registered = (withNames[SERVED_NAMES] ??= []);\n registered.push(names);\n // Before this handler wraps `onmessage`, so the base ends up\n // innermost: it answers a handshake only once every server above it\n // has declined.\n installBase(host);\n\n const previous = host.onmessage;\n host.onmessage = event => {\n if (!isPortHandshake(event.data)) {\n // Not ours. A worker that also speaks its own protocol on the\n // global channel keeps working.\n previous?.(event);\n return;\n }\n const port = event.ports?.[0];\n if (port === undefined) {\n throw new Error(`Port handshake for '${event.data.key}' arrived with no port attached.`);\n }\n if (onPort(event.data.key, port)) {\n return;\n }\n // Declined. Another server may take it; the base answers if none\n // does.\n previous?.(event);\n };\n return () => {\n host.onmessage = previous;\n const index = registered.indexOf(names);\n if (index >= 0) {\n registered.splice(index, 1);\n }\n };\n}\n","import type { Observable } from 'rxjs';\n\nimport { agentSurface } from '../agent/AgentSurface';\nimport { AGENT_PORT, serveAgentPort } from '../agent/remote';\nimport { servePorts, type PortHost } from '../worker/WorkerPorts';\nimport { provide, type ChannelSource, ProvidedChannel } from './provide';\nimport type { ChannelPort } from './ChannelProtocol';\nimport type { ChannelToken, Command, CommandMap } from './ChannelToken';\n\n/**\n * One channel a worker offers: its token and what feeds it.\n *\n * Types erased structurally, for the same reason `ChannelRegistration`\n * erases them — a list of channels has no single generic\n * instantiation, and making every caller cast to reach one is worse\n * than describing what is actually needed.\n */\nexport interface ServedChannel {\n token: { name: string; initial: object };\n source: {\n view: Record<string, Observable<unknown>>;\n commands?: Record<string, Command>;\n };\n}\n\n/**\n * One served channel, with its source checked against its token.\n *\n * `ServedChannel` is erased on purpose, so one list can hold channels\n * of every shape; the cost is that a view key the token declares and\n * the source forgets is found at startup, by the error `provide`\n * reports, rather than by the compiler. This is the typed seam: the\n * source must hold an Observable for every key of the token's view and\n * a handler for every command, and each handler takes the arguments\n * the token declares, so none of them needs an annotation.\n *\n * serveChannels([\n * serve(Catalog, { view: catalog, commands: { add: name => catalog.add(name) } })\n * ]);\n *\n * The view may be any object with the right observables on it, which\n * is often the domain object itself when its properties are named\n * after the keys. Only the declared keys are read from it.\n */\nexport function serve<View extends object, Commands extends object>(\n token: ChannelToken<View, Commands>,\n source: ChannelSource<View, Commands>\n): ServedChannel {\n return { token, source: source as unknown as ServedChannel['source'] };\n}\n\n/**\n * Publishes channels from an application worker.\n *\n * Call it synchronously at the top level of the worker module, before\n * any await, so no handshake is missed:\n *\n * const catalog = new CatalogViewModel(new CatalogDomain(new OpfsStore()));\n * serveChannels([\n * serve(Catalog, { view: { products: catalog.products$ }, commands: { … } })\n * ]);\n *\n * Everything above this call is the application's own — plain classes,\n * plain observables, no framework import. This function is the entire\n * seam between it and the view.\n *\n * Returns a function that stops serving and disposes what it provided.\n */\nexport function serveChannels(channels: readonly ServedChannel[], host?: PortHost): () => void {\n const byName = new Map<string, ServedChannel>();\n for (const served of channels) {\n byName.set(served.token.name, served);\n }\n const provided: ProvidedChannel[] = [];\n\n const stop = servePorts(\n (key, port) => {\n if (key === AGENT_PORT) {\n // An agent asking, through the page, what this worker serves.\n // Imported rather than loaded on demand: a worker built as an\n // IIFE, which is Vite's default, cannot split off a chunk, and\n // a dynamic import here failed every such build.\n serveAgentPort(port, confirm => agentSurface(channels, { confirm }));\n return true;\n }\n const served = byName.get(key);\n if (served === undefined) {\n // Declined rather than answered, so a worker serving more than\n // one kind of thing can pass the handshake along. `servePorts`\n // reports it if nothing takes it.\n return false;\n }\n provided.push(\n provide(\n served.token as ChannelToken<object, CommandMap>,\n served.source as unknown as ChannelSource<object, CommandMap>,\n port as unknown as ChannelPort\n )\n );\n return true;\n },\n () => [...byName.keys()],\n host\n );\n\n return () => {\n stop();\n for (const channel of provided) {\n channel.dispose();\n }\n provided.length = 0;\n };\n}\n","import { distinctUntilChanged, map, type Observable } from 'rxjs';\n\n/**\n * One key of a view model, as its own Observable, emitting only when\n * that key's value changes.\n *\n * `provide` and `serveChannels` want one Observable per view key, so\n * the differ can patch each key on its own, while a view model is most\n * naturally one Observable of one object. This is the seam between the\n * two, and every application worker was about to write it.\n */\nexport function pick<T, K extends keyof T>(source: Observable<T>, key: K): Observable<T[K]> {\n return source.pipe(\n map(value => value[key]),\n distinctUntilChanged()\n );\n}\n\n/**\n * Every key of a view model as its own Observable: the `view` a channel\n * source wants, from the one Observable a view model has.\n *\n * serveChannels([{ token: Queue, source: { view: pickKeys(queue.view, QUEUE_KEYS), commands } }])\n */\nexport function pickKeys<T extends object, K extends keyof T>(\n source: Observable<T>,\n keys: readonly K[]\n): { readonly [P in K]: Observable<T[P]> } {\n const out: Partial<{ [P in K]: Observable<T[P]> }> = {};\n for (const key of keys) {\n out[key] = pick(source, key);\n }\n return out as { readonly [P in K]: Observable<T[P]> };\n}\n","/**\n * What a store did with a request.\n *\n * Four words rather than an exception, because three of them are\n * ordinary outcomes an application routes around rather than faults it\n * reports. A browser that refuses storage in a private window, and a\n * quota that has run out, are both things a running application has to\n * carry on through, and making every caller wrap a `try` around a read\n * to discover which one happened is how storage code ends up assuming\n * success.\n *\n * - `ok`: the store answered. For a read that includes \"there is no\n * such record\", which is `value: null` and not a failure.\n * - `denied`: the platform will not let this origin store anything.\n * No OPFS in this browser, a private window that refuses IndexedDB,\n * `localStorage` blocked by a site setting. Permanent for the\n * session: nothing an application does will change the answer, so\n * asking again is wasted work.\n * - `full`: the quota is spent. Temporary, and worth trying again\n * after something has been given back, which is why it is not\n * `denied`.\n * - `failed`: anything else. A half-written file, a corrupt database,\n * a transaction that aborted for a reason the platform did not\n * explain.\n */\nexport type StorageOutcome = 'ok' | 'denied' | 'full' | 'failed';\n\n/** What came back from a read. */\nexport interface StorageRead {\n readonly outcome: StorageOutcome;\n /** The record, or null when there is none or the read did not answer. */\n readonly value: string | null;\n /** Why it did not answer, as a message; null when it did. */\n readonly error: string | null;\n}\n\n/**\n * Somewhere an application's state survives being closed.\n *\n * Four methods over text keyed by a string, which is the shape all\n * three implementations can actually keep. Bytes are deliberately not\n * in it: `localStorage` cannot hold them, so an interface that\n * promised them would be one the shell route could not implement, and\n * an application storing pictures wants a store of its own with an\n * eviction policy rather than this. the\n * artwork cache is that other thing.\n *\n * Nothing rejects. Every method answers with an outcome, and the\n * per-failure behaviour is the implementation's to document; the three\n * in this package all follow `classifyStorageError`.\n *\n * It is a shape and not a service. Nothing in the framework holds one,\n * `persisted` takes whichever one it is given, and an application with\n * its own store implements four methods rather than adopting anything.\n */\nexport interface StorageAdapter {\n /** Reads one record. */\n read(key: string): Promise<StorageRead>;\n /** Writes one record, replacing whatever was there. */\n write(key: string, value: string): Promise<StorageOutcome>;\n /** Removes one record. Removing what is not there is `ok`. */\n remove(key: string): Promise<StorageOutcome>;\n /** Every key this store holds, for an application that evicts its own. */\n keys(): Promise<readonly string[]>;\n}\n\n/**\n * Which of the four outcomes a thrown platform error is.\n *\n * The names are the ones the storage APIs actually throw.\n * `QuotaExceededError` is the DOM's word for full, and every browser\n * uses it for OPFS, IndexedDB and `localStorage` alike. `SecurityError`\n * and `NotAllowedError` are what a blocked origin gets. A missing API\n * (no `navigator.storage`, no `indexedDB`) is a `TypeError` here and\n * is `denied` for the same reason: nothing the application does will\n * produce a store.\n */\nexport function classifyStorageError(error: unknown): StorageOutcome {\n const name = error instanceof Error ? error.name : '';\n if (name === 'QuotaExceededError' || name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n return 'full';\n }\n if (name === 'SecurityError' || name === 'NotAllowedError' || name === 'TypeError') {\n return 'denied';\n }\n return 'failed';\n}\n\n/** A thrown value as the message a screen could show. */\nexport function storageErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** A read that could not answer, as one record. */\nexport function storageReadFailure(error: unknown): StorageRead {\n return { outcome: classifyStorageError(error), value: null, error: storageErrorMessage(error) };\n}\n\n/** A read that answered, whether or not it found anything. */\nexport function storageReadValue(value: string | null): StorageRead {\n return { outcome: 'ok', value, error: null };\n}\n\n/**\n * The same contract in memory, for specs and for a platform with no\n * store at all.\n *\n * Not a fallback anything installs on its own. An application that\n * would rather run with an unremembered session than fail says so by\n * passing one of these; one that would rather tell the person its\n * settings will not be kept reads the `denied` outcome and says so.\n * Choosing between those two on an application's behalf is exactly the\n * kind of decision the thread model keeps out of the framework.\n */\nexport class MemoryStorage implements StorageAdapter {\n private readonly records = new Map<string, string>();\n /** Written by a spec that wants to see what a full store does. */\n full = false;\n\n read(key: string): Promise<StorageRead> {\n return Promise.resolve(storageReadValue(this.records.get(key) ?? null));\n }\n\n write(key: string, value: string): Promise<StorageOutcome> {\n if (this.full) {\n return Promise.resolve('full');\n }\n this.records.set(key, value);\n return Promise.resolve('ok');\n }\n\n remove(key: string): Promise<StorageOutcome> {\n this.records.delete(key);\n return Promise.resolve('ok');\n }\n\n keys(): Promise<readonly string[]> {\n return Promise.resolve([...this.records.keys()]);\n }\n}\n","import { computed, type ComputedCell } from '../computed';\nimport { internalState, type InternalState } from '../InternalState';\nimport { select } from '../select';\n\n/** One undoable change, as the two functions that make and unmake it. */\nexport interface UndoTransaction {\n /**\n * What a menu item or a toast calls this change: \"Move Sunset\",\n * \"Remove Sunset from the queue\".\n *\n * A phrase rather than a sentence, because the words around it are\n * the caller's: an application writes \"Undo \" in front of it.\n */\n readonly label: string;\n /** Puts the world back the way it was before `redo` ran. */\n readonly undo: () => void;\n /** Makes the change again, from wherever `undo` left things. */\n readonly redo: () => void;\n /**\n * Merges this into the entry before it when the two keys match.\n *\n * A drag reports a crossing per row and a typed name reports a\n * keystroke, and neither is a change a person means to undo one step\n * at a time. Entries pushed one after another under the same key\n * become one entry: **the first one's `undo` and the last one's\n * `redo`**, with everything between them dropped.\n *\n * That merge rule is what makes the two functions above worth\n * writing as absolute moves rather than as deltas. `undo` should say\n * where the thing goes, not how far back it goes, because after\n * three more coalesced steps a delta is wrong and a position is\n * still right. See `endRun` for where a run stops.\n */\n readonly coalesce?: string;\n}\n\nexport interface UndoStackOptions {\n /**\n * How many entries are kept, oldest dropped first. Default 100.\n *\n * A bound rather than a growing list, for the reason\n * `EditableTextModel` has one: an application that is used for an\n * afternoon would otherwise hold every intermediate state of that\n * afternoon, and nobody undoes a hundred steps.\n */\n readonly limit?: number;\n /** What to call the stack in a devtools reading; optional. */\n readonly label?: string;\n}\n\n/** The two labels, as one record so a menu reads them in one go. */\ninterface UndoLabels {\n readonly undo: string | null;\n readonly redo: string | null;\n}\n\nconst NOTHING: UndoLabels = { undo: null, redo: null };\n\n/**\n * The application's undo, as a stack of named transactions.\n *\n * A component registers what it did and how to unmake it, and a menu,\n * a button or a keyboard shortcut drives the stack. Nothing here\n * listens to anything or knows what an application's state is: the two\n * functions in a transaction are the whole of the coupling, which is\n * why this can sit on either thread and why it does not become a data\n * layer.\n *\n * const undo = ctx.inject(UndoStack);\n *\n * queue.send.remove(at);\n * undo.push({\n * label: `Remove ${track.title}`,\n * undo: () => queue.send.addToQueue(track.id),\n * redo: () => queue.send.remove(at)\n * });\n *\n * ## How this relates to the undo inside a text field\n *\n * `EditableTextModel` has had its own undo since text became editable,\n * and the two are deliberately separate. A field's undo is a stack of\n * **snapshots of one string**, private to the field, and it has to be:\n * the model is the only thing that knows where the caret was, which\n * run of typing coalesces with which, and what an IME composition is\n * doing. This one is a stack of **inverse operations** over whatever\n * an application's state happens to be, and it cannot see inside a\n * field at all.\n *\n * They meet at one key press, and the rule there is that the focused\n * field wins: `registerUndoShortcuts` skips Mod+Z while something is\n * being typed into, so undo in a field undoes typing and undo\n * everywhere else undoes the application's last change. Merging the\n * two stacks would mean a keystroke and a queue reorder sharing one\n * history, which is not what either of them means.\n *\n * ## Reentrancy\n *\n * A push while an undo or a redo is running is dropped. Without it an\n * application whose edit path records itself would record the undo as\n * a new edit and the stack would never empty. Write the inverse\n * functions to call the state directly rather than through the same\n * path that records, and the guard never fires.\n */\nexport class UndoStack {\n private readonly entries: UndoTransaction[] = [];\n private readonly undone: UndoTransaction[] = [];\n private readonly limit: number;\n /** True while `undo()` or `redo()` is running one of the functions. */\n private running = false;\n /** Set by `endRun`, so the next push starts a new entry whatever its key. */\n private sealed = false;\n\n private readonly labels: InternalState<UndoLabels>;\n\n /** What undoing would undo, or null when there is nothing to undo. */\n readonly undoLabel: ComputedCell<string | null>;\n /** What redoing would redo, or null when there is nothing to redo. */\n readonly redoLabel: ComputedCell<string | null>;\n /** Whether there is anything to undo, for a menu item's `disabled`. */\n readonly canUndo: ComputedCell<boolean>;\n readonly canRedo: ComputedCell<boolean>;\n\n constructor(options: UndoStackOptions = {}) {\n this.limit = Math.max(1, options.limit ?? 100);\n this.labels = internalState<UndoLabels>(NOTHING, options.label);\n this.undoLabel = select(this.labels, 'undo');\n this.redoLabel = select(this.labels, 'redo');\n this.canUndo = computed(() => this.undoLabel.value !== null);\n this.canRedo = computed(() => this.redoLabel.value !== null);\n }\n\n /** How many entries are held, for a spec or a budget. */\n get size(): number {\n return this.entries.length;\n }\n\n /** How many redos are waiting, for a spec or a budget. */\n get redoSize(): number {\n return this.undone.length;\n }\n\n /**\n * Records a change that has already been made.\n *\n * Pushing is what discards the redo branch: making a change after\n * undoing two is the person choosing the other future, and keeping\n * the abandoned one would mean redoing into a state that no longer\n * follows from what is on screen.\n */\n push(transaction: UndoTransaction): void {\n if (this.running) {\n return;\n }\n this.undone.length = 0;\n const previous = this.entries[this.entries.length - 1];\n const sealed = this.sealed;\n this.sealed = false;\n if (\n !sealed &&\n previous !== undefined &&\n transaction.coalesce !== undefined &&\n previous.coalesce === transaction.coalesce\n ) {\n // The run's own undo, kept from its first step, and its newest\n // redo. Every step in between is released here, which is the\n // whole of what stops a drag across sixty rows retaining sixty\n // closures and the sixty values they close over.\n this.entries[this.entries.length - 1] = {\n label: transaction.label,\n undo: previous.undo,\n redo: transaction.redo,\n coalesce: transaction.coalesce\n };\n this.publish();\n return;\n }\n this.entries.push(transaction);\n while (this.entries.length > this.limit) {\n this.entries.shift();\n }\n this.publish();\n }\n\n /**\n * Groups everything pushed inside `body` into one entry.\n *\n * For a change an application makes as several calls and a person\n * made as one press: undoing runs the group's undos in reverse, and\n * redoing runs its redos in order. Unlike `coalesce`, a group keeps\n * every step, because a group is written down as a group rather than\n * discovered from a run of similar pushes.\n */\n transact<R>(label: string, body: () => R): R {\n if (this.running) {\n return body();\n }\n const outer = this.entries.length;\n const result = body();\n const collected = this.entries.splice(outer);\n if (collected.length > 0) {\n this.entries.push({\n label,\n undo: () => {\n for (let at = collected.length - 1; at >= 0; at--) {\n collected[at]!.undo();\n }\n },\n redo: () => {\n for (const step of collected) {\n step.redo();\n }\n }\n });\n this.sealed = true;\n this.publish();\n }\n return result;\n }\n\n /**\n * Ends the current run, so the next push starts its own entry.\n *\n * The twin of `EditableTextModel.endTypingRun`. A drag calls it when\n * the pointer comes up: without it, dragging a row, letting go, and\n * dragging the same row again would coalesce into one entry, and one\n * undo would put the row back where it was two gestures ago.\n */\n endRun(): void {\n this.sealed = true;\n }\n\n /** Undoes the last change. False when there was nothing to undo. */\n undo(): boolean {\n const entry = this.entries.pop();\n if (entry === undefined) {\n return false;\n }\n this.run(entry.undo);\n this.undone.push(entry);\n this.sealed = true;\n this.publish();\n return true;\n }\n\n /** Redoes the last undone change. False when there was nothing to redo. */\n redo(): boolean {\n const entry = this.undone.pop();\n if (entry === undefined) {\n return false;\n }\n this.run(entry.redo);\n this.entries.push(entry);\n this.sealed = true;\n this.publish();\n return true;\n }\n\n /**\n * Forgets everything, in both directions.\n *\n * What an application calls when the thing the entries refer to is\n * gone: a queue emptied, a document closed, a signed-out account's\n * library replaced. `EditableTextModel.setText` does the same for\n * the same reason, and the reason is that an inverse function whose\n * subject no longer exists is not an undo, it is a surprise.\n */\n clear(): void {\n this.entries.length = 0;\n this.undone.length = 0;\n this.sealed = false;\n this.publish();\n }\n\n private run(action: () => void): void {\n this.running = true;\n try {\n action();\n } finally {\n this.running = false;\n }\n }\n\n private publish(): void {\n const next: UndoLabels = {\n undo: this.entries[this.entries.length - 1]?.label ?? null,\n redo: this.undone[this.undone.length - 1]?.label ?? null\n };\n // Structural comparison rather than a write per push: coalescing a\n // drag rewrites the same label sixty times, and a menu bound to\n // these should redraw when the words change and not before.\n if (next.undo !== this.labels.value.undo || next.redo !== this.labels.value.redo) {\n this.labels.value = next;\n }\n }\n}\n","import type { Mutation } from '../mutate';\nimport type { UndoStack } from './UndoStack';\n\nexport interface UndoableOptions<A> {\n /** What the entry is called, from the argument that made it. */\n readonly label: string | ((argument: A) => string);\n /** The coalescing key, from the argument; see `UndoTransaction.coalesce`. */\n readonly coalesce?: string | ((argument: A) => string);\n}\n\n/**\n * Puts a `mutate` on an undo stack, by way of its own inverse.\n *\n * private readonly liked = internalState<readonly string[]>([]);\n * private readonly like = mutate(this.liked, toggled, id => api.favourite(id));\n * readonly toggleLike = undoable(undo, this.like, id => id, { label: () => 'Like' });\n *\n * The whole of it is that undoing an optimistic change is another\n * optimistic change. Nothing here writes the cell behind the\n * mutation's back, which is the thing that would go wrong if an undo\n * stack held values rather than operations: it would restore a value\n * the server has not been told about, and the next rollback would\n * fight it.\n *\n * `invert` answers the argument that undoes this one. For a toggle\n * that is the same argument again, which is why the example above\n * looks like it does nothing.\n *\n * **A refused write is not on the stack.** `mutate` already puts the\n * cell back when a commit rejects or resolves `false`, so the change\n * did not happen and there is nothing to undo; pushing it would give a\n * person an undo that undoes something they never saw.\n *\n * The undo and the redo call `mutation.run` rather than this wrapper,\n * so running them records nothing and the stack's reentrancy guard\n * never has to fire.\n */\nexport function undoable<A>(\n stack: UndoStack,\n mutation: Mutation<A>,\n invert: (argument: A) => A,\n options: UndoableOptions<A>\n): (argument: A) => Promise<boolean> {\n const { label, coalesce } = options;\n return async (argument: A): Promise<boolean> => {\n if (!(await mutation.run(argument))) {\n return false;\n }\n stack.push({\n label: typeof label === 'function' ? label(argument) : label,\n undo: () => void mutation.run(invert(argument)),\n redo: () => void mutation.run(argument),\n ...(coalesce === undefined ? {} : { coalesce: typeof coalesce === 'function' ? coalesce(argument) : coalesce })\n });\n return true;\n };\n}\n","import {\n classifyStorageError,\n storageReadFailure,\n storageReadValue,\n type StorageAdapter,\n type StorageOutcome,\n type StorageRead\n} from './StorageAdapter';\n\n/**\n * As much of the Origin Private File System as a store needs.\n *\n * Written out rather than taken from `lib.dom`, for two reasons. The\n * workspace's `lib` is `ES2023` and `DOM`, which has the handles but\n * not the async iteration `values()` needs, and a structural type is\n * what lets a spec hand this a directory of its own instead of\n * standing up a file system to test four methods.\n */\nexport interface OpfsDirectory {\n getFileHandle(name: string, options?: { create?: boolean }): Promise<OpfsFileHandle>;\n getDirectoryHandle(name: string, options?: { create?: boolean }): Promise<OpfsDirectory>;\n removeEntry(name: string): Promise<void>;\n keys(): AsyncIterable<string>;\n}\n\nexport interface OpfsFileHandle {\n getFile(): Promise<{ text(): Promise<string> }>;\n createWritable(): Promise<OpfsWritable>;\n}\n\nexport interface OpfsWritable {\n write(data: string): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface OpfsStorageOptions {\n /**\n * The folder under the origin's private root, so two stores in one\n * application do not share a namespace. Default `'gesso'`.\n */\n readonly directory?: string;\n /** The root, for a spec. Default `navigator.storage.getDirectory()`. */\n readonly root?: () => Promise<OpfsDirectory>;\n}\n\n/**\n * A store in the origin's private file system.\n *\n * The right default for an application's own state. It is reachable\n * from a worker, which `localStorage` is not, so the thread that owns\n * the state is the thread that writes it and nothing has to cross the\n * barrier to be remembered. It is asynchronous throughout, so nothing\n * it does blocks a frame. And it is per-origin and invisible to the\n * person, which is the right place for a queue or a draft and the\n * wrong place for anything they should be able to find and delete.\n *\n * One file per key, named by the key with the characters a file system\n * would refuse escaped, so a key is recoverable from a listing and a\n * key containing a slash cannot reach out of the folder.\n *\n * What happens on each failure:\n *\n * - **The platform has no OPFS**, or the browser refuses it (a private\n * window, a blocked origin): every method answers `denied` and the\n * error message says which. The store is not usable this session and\n * `persisted` stops writing to it after the first denial.\n * - **The quota is spent**: the write answers `full`. Nothing is\n * rolled back, because the value the application holds is the real\n * one and only the remembering failed.\n * - **There is no such record**: the read answers `ok` with `null`.\n * Not having been written yet is the ordinary first run, not a\n * failure.\n * - **Anything else**: `failed`, with the platform's message. A file\n * whose *contents* are not what this version writes is a different\n * thing and is `persisted`'s to judge, which it does by discarding\n * it, the same call `Tokens.ts` makes.\n */\nexport class OpfsStorage implements StorageAdapter {\n private readonly folder: string;\n private readonly rootOf: () => Promise<OpfsDirectory>;\n /** The folder, once opened. Reused, because opening it is a round trip. */\n private opening: Promise<OpfsDirectory> | null = null;\n\n constructor(options: OpfsStorageOptions = {}) {\n this.folder = options.directory ?? 'gesso';\n this.rootOf = options.root ?? defaultRoot;\n }\n\n async read(key: string): Promise<StorageRead> {\n try {\n const directory = await this.open();\n const handle = await directory.getFileHandle(fileFor(key));\n return storageReadValue(await (await handle.getFile()).text());\n } catch (error) {\n // A file that is not there is the ordinary answer to \"is\n // anything remembered\", and the platform says so by throwing\n // `NotFoundError`. It is not a failure and it is not `denied`.\n if (error instanceof Error && error.name === 'NotFoundError') {\n return storageReadValue(null);\n }\n return storageReadFailure(error);\n }\n }\n\n async write(key: string, value: string): Promise<StorageOutcome> {\n try {\n const directory = await this.open();\n const handle = await directory.getFileHandle(fileFor(key), { create: true });\n const writable = await handle.createWritable();\n // Written and closed in one go rather than kept open: a handle\n // held across frames is a handle a reload can leave locked.\n await writable.write(value);\n await writable.close();\n return 'ok';\n } catch (error) {\n return classifyStorageError(error);\n }\n }\n\n async remove(key: string): Promise<StorageOutcome> {\n try {\n await (await this.open()).removeEntry(fileFor(key));\n return 'ok';\n } catch (error) {\n if (error instanceof Error && error.name === 'NotFoundError') {\n return 'ok';\n }\n return classifyStorageError(error);\n }\n }\n\n async keys(): Promise<readonly string[]> {\n try {\n const found: string[] = [];\n for await (const name of (await this.open()).keys()) {\n found.push(keyFor(name));\n }\n return found;\n } catch {\n // A listing that cannot be taken is an empty one. The caller is\n // an application evicting its own records, and evicting nothing\n // is the safe answer to not knowing what is there.\n return [];\n }\n }\n\n /**\n * The folder, opened once and kept.\n *\n * A failed open is *not* kept. A rejected promise left in `opening`\n * would answer every later call with the same rejection, so one\n * refusal at start-up would be a store that never worked again even\n * after the person granted storage or made room. Kept when it\n * succeeds, dropped when it does not, which is one line and the\n * difference between a cache and a poison.\n */\n private open(): Promise<OpfsDirectory> {\n if (this.opening === null) {\n const opening = this.rootOf().then(root => root.getDirectoryHandle(this.folder, { create: true }));\n this.opening = opening;\n opening.catch(() => {\n if (this.opening === opening) {\n this.opening = null;\n }\n });\n }\n return this.opening;\n }\n}\n\nfunction defaultRoot(): Promise<OpfsDirectory> {\n const storage = (globalThis as { navigator?: { storage?: { getDirectory?: () => Promise<OpfsDirectory> } } })\n .navigator?.storage;\n if (storage?.getDirectory === undefined) {\n // A `TypeError`, which `classifyStorageError` reads as `denied`:\n // there is no store here and there will not be one.\n return Promise.reject(new TypeError('This environment has no Origin Private File System.'));\n }\n return storage.getDirectory();\n}\n\n/**\n * A key as a file name.\n *\n * `encodeURIComponent` and not a hash, so a listing of the folder in\n * devtools reads as the keys the application wrote. It escapes the\n * slash and the dot, which is what stops a key reaching a directory it\n * was not given.\n */\nfunction fileFor(key: string): string {\n return `${encodeURIComponent(key)}.json`;\n}\n\nfunction keyFor(name: string): string {\n return decodeURIComponent(name.replace(/\\.json$/, ''));\n}\n","import {\n classifyStorageError,\n storageReadFailure,\n storageReadValue,\n type StorageAdapter,\n type StorageOutcome,\n type StorageRead\n} from './StorageAdapter';\n\nexport interface IndexedDbStorageOptions {\n /** The database. Default `'gesso'`. */\n readonly database?: string;\n /** The object store inside it. Default `'records'`. */\n readonly store?: string;\n /** The factory, for a spec. Default `globalThis.indexedDB`. */\n readonly factory?: IDBFactory;\n}\n\n/**\n * A store in IndexedDB.\n *\n * Beside OPFS rather than instead of it, because the two fail in\n * different places and an application picks by which failure it\n * minds. IndexedDB is reachable from every thread, survives longer\n * under a browser's own eviction, and is what a Safari that has\n * disabled OPFS still has; OPFS is faster for one large record and\n * simpler to inspect. Neither is a default the framework picks: an\n * application names the one it wants.\n *\n * One object store of strings keyed by string, which is the shape\n * `StorageAdapter` describes and no more. Indexes, versions past the\n * first, and cursors over ranges are what an application builds when\n * it has outgrown a key-value store, and at that point it is writing\n * against IndexedDB rather than against this.\n *\n * What happens on each failure:\n *\n * - **No `indexedDB`, or an origin that may not open one** (a private\n * window in some browsers, a blocked third-party context): every\n * method answers `denied`, and the open is retried next time rather\n * than cached, because a `denied` can be lifted by a site setting\n * mid-session.\n * - **The quota is spent**: the write answers `full`. IndexedDB\n * reports this on the transaction rather than on the request, which\n * is why the write waits for `oncomplete` and not for\n * `onsuccess`: a put that succeeded into a transaction that then\n * aborted has not been written, and answering `ok` for it would be\n * the adapter assuming success.\n * - **A version change from another tab**: the connection is closed\n * and dropped, so the next call opens a fresh one. Answering\n * `failed` and holding a dead connection would make every later\n * call fail too.\n * - **Anything else**: `failed`, with the platform's message.\n */\nexport class IndexedDbStorage implements StorageAdapter {\n private readonly database: string;\n private readonly store: string;\n private readonly factory: IDBFactory | undefined;\n private connecting: Promise<IDBDatabase> | null = null;\n\n constructor(options: IndexedDbStorageOptions = {}) {\n this.database = options.database ?? 'gesso';\n this.store = options.store ?? 'records';\n this.factory = options.factory ?? (globalThis as { indexedDB?: IDBFactory }).indexedDB;\n }\n\n async read(key: string): Promise<StorageRead> {\n try {\n const value = await this.transact('readonly', store => store.get(key));\n return storageReadValue(typeof value === 'string' ? value : null);\n } catch (error) {\n return storageReadFailure(error);\n }\n }\n\n async write(key: string, value: string): Promise<StorageOutcome> {\n return this.outcomeOf(() => this.transact('readwrite', store => store.put(value, key)));\n }\n\n async remove(key: string): Promise<StorageOutcome> {\n return this.outcomeOf(() => this.transact('readwrite', store => store.delete(key)));\n }\n\n async keys(): Promise<readonly string[]> {\n try {\n const found = await this.transact('readonly', store => store.getAllKeys());\n return Array.isArray(found) ? found.filter((key): key is string => typeof key === 'string') : [];\n } catch {\n return [];\n }\n }\n\n /** Lets go of the connection, for a spec or an application shutting down. */\n close(): void {\n const connecting = this.connecting;\n this.connecting = null;\n void connecting?.then(\n database => database.close(),\n () => undefined\n );\n }\n\n private async outcomeOf(work: () => Promise<unknown>): Promise<StorageOutcome> {\n try {\n await work();\n return 'ok';\n } catch (error) {\n const outcome = classifyStorageError(error);\n if (outcome === 'denied') {\n this.connecting = null;\n }\n return outcome;\n }\n }\n\n /**\n * Runs one request inside one transaction and answers its result.\n *\n * A write resolves on the transaction completing rather than on the\n * request succeeding, because those are two different claims: the\n * second says the put was accepted, and only the first says it\n * reached the disk.\n */\n private async transact<T>(mode: IDBTransactionMode, run: (store: IDBObjectStore) => IDBRequest<T>): Promise<T> {\n const database = await this.connect();\n return new Promise<T>((resolve, reject) => {\n let answer: T;\n const transaction = database.transaction(this.store, mode);\n const request = run(transaction.objectStore(this.store));\n request.onsuccess = () => {\n answer = request.result;\n };\n request.onerror = () => reject(request.error ?? new Error('The request failed.'));\n transaction.oncomplete = () => resolve(answer);\n transaction.onabort = () => reject(transaction.error ?? new Error('The transaction was aborted.'));\n });\n }\n\n private connect(): Promise<IDBDatabase> {\n this.connecting ??= this.open();\n return this.connecting;\n }\n\n private open(): Promise<IDBDatabase> {\n const factory = this.factory;\n if (factory === undefined) {\n // A `TypeError`, which `classifyStorageError` reads as `denied`.\n return Promise.reject(new TypeError('This environment has no IndexedDB.'));\n }\n return new Promise<IDBDatabase>((resolve, reject) => {\n let request: IDBOpenDBRequest;\n try {\n request = factory.open(this.database, 1);\n } catch (error) {\n reject(error);\n return;\n }\n request.onupgradeneeded = () => {\n if (!request.result.objectStoreNames.contains(this.store)) {\n request.result.createObjectStore(this.store);\n }\n };\n request.onsuccess = () => {\n // Another tab asking for a newer version cannot proceed while\n // this connection is open, so it is given up rather than held.\n request.result.onversionchange = () => this.close();\n resolve(request.result);\n };\n request.onerror = () => reject(request.error ?? new Error('The database could not be opened.'));\n request.onblocked = () => reject(new Error('The database is open in another tab at a different version.'));\n });\n }\n}\n","import { of, skip, type Subscription } from 'rxjs';\n\nimport { debounced } from '../debounce';\nimport type { ReadableCell } from '../Input';\nimport { internalState, type InternalState } from '../InternalState';\nimport { resource, type Resource, type ResourceStatus } from '../resource';\nimport type { StorageAdapter } from './StorageAdapter';\n\nexport interface PersistedOptions<T> {\n /**\n * What the value is before anything has been read, and what it goes\n * back to when nothing was stored.\n *\n * Required, and that is the whole answer to the race between\n * hydration and the first frame: a screen reading this on the frame\n * it mounts gets the default, with `status` saying `loading`, and\n * gets the remembered value a moment later if there was one. There\n * is no fourth state to draw and no null to guard against.\n */\n readonly initial: T;\n /**\n * Reads a record back, refusing one this version does not\n * understand.\n *\n * Answer `null` and the record is treated as not being there, which\n * is what a record written by an older build should be: the cost is\n * one default, and the alternative is state holding `undefined`\n * where a field belongs. `Tokens.isStoredTokens` in Segue is the\n * same check written by hand.\n *\n * Without one the parsed JSON is trusted as-is, which is fine while\n * the shape has only ever had one version and is not fine\n * afterwards.\n */\n readonly revive?: (raw: unknown) => T | null;\n /**\n * How long a change waits for the next one before being written, in\n * milliseconds. Default 250.\n *\n * A `debounced` cell rather than a timer of its own, so this is the\n * same gate a search field uses. It is what makes a value changed\n * sixty times a second cost one write rather than sixty: see\n * `persisted.budget.spec.ts`, which asserts exactly that.\n */\n readonly settle?: number;\n /** What to call this in a devtools reading; optional. */\n readonly label?: string;\n}\n\nconst MESSAGES: Readonly<Record<string, string>> = {\n denied: 'This browser will not let the application store anything.',\n full: 'There is no room left to store this.',\n failed: 'The store could not be written to.'\n};\n\n/**\n * A value that survives the application being closed.\n *\n * Hydration is a `resource`, which is not a detail: reading from a\n * disk is a keyed request that can be slow, can answer \"there is\n * nothing\", and can fail, which is the same set of outcomes a request\n * over the network has. So the statuses here are `ResourceStatus`\n * itself rather than a fourth enum saying the same five things in\n * different words.\n *\n * readonly draft = persisted(new OpfsStorage(), 'draft', { initial: '' });\n *\n * // on a screen\n * <TextInput value={draft.value} onChange={text => draft.set(text)} />\n *\n * ## What a screen sees before hydration finishes\n *\n * The default, and `status` reading `loading`. Nothing waits, nothing\n * is null, and no screen has a shape it only has for the first eighty\n * milliseconds. When the read lands the value changes like any other\n * cell change, and a screen that wants to say \"restoring\" reads\n * `status`.\n *\n * The one race that needs a rule is a person changing the value before\n * the disk has answered, which is not rare: a queue is a press away\n * and OPFS is a round trip away. **What they did wins.** A hydration\n * answer is applied only if nothing has been `set` since, on the same\n * reasoning as `mutate`'s guarded rollback: an answer that was\n * overtaken is stale, and putting it on screen would undo something\n * the person just did.\n *\n * ## What happens when storing fails\n *\n * - `denied`: nothing is written this session and nothing is tried\n * again, because the answer will not change. `status` is `failed`\n * and `saveError` says so once rather than on every keystroke.\n * - `full`: the write failed and the value in memory is kept. Nothing\n * is rolled back: the change is real and only the remembering of it\n * failed. The next change is still attempted, because a quota can be\n * given back.\n * - `failed`: the same as `full`, and for the same reason.\n * - A record that parses but is not the shape `revive` accepts is\n * treated as `missing`: the application starts from its default\n * rather than showing an error about a file the person cannot see.\n *\n * ## It is a helper\n *\n * Nothing in the framework holds one, and nothing is reachable only\n * through it. A channel is served from plain Observables as it always\n * was, and an application that would rather read and write a store\n * itself is writing against the same `StorageAdapter` this is written\n * against. The thread model declined to own an application's data\n * architecture, and remembering a value is not the exception to that.\n */\nexport class PersistedState<T> {\n private readonly held: InternalState<T>;\n private readonly saves: InternalState<number>;\n private readonly failure: InternalState<string | null>;\n private readonly record: Resource<string, T>;\n private readonly writing: Subscription;\n /** True once the application has written a value of its own. */\n private touched = false;\n /** Set when the store said `denied`, which is permanent for the session. */\n private refused = false;\n /** The text last known to be on disk, so hydration does not write itself back. */\n private stored: string | null = null;\n /** What `forget` goes back to. */\n private readonly initial: T;\n\n /** Where the first read got to; the same five words `resource` uses. */\n readonly status: ReadableCell<ResourceStatus>;\n /** Why the read did not answer, as a message; null when it did. */\n readonly error: ReadableCell<string | null>;\n /** What is remembered: the default until the read lands. */\n readonly value: ReadableCell<T>;\n /** Writes in the air, for a saving indicator. A count, as `mutate.pending` is. */\n readonly saving: ReadableCell<number>;\n /** Why the last write did not happen, as a message; null when it did. */\n readonly saveError: ReadableCell<string | null>;\n /** Resolves when the first read has settled, whatever it found. */\n readonly hydrated: Promise<void>;\n\n constructor(\n private readonly adapter: StorageAdapter,\n private readonly key: string,\n options: PersistedOptions<T>\n ) {\n const label = options.label;\n this.initial = options.initial;\n this.held = internalState<T>(options.initial, label);\n this.saves = internalState(0, label === undefined ? undefined : `${label}.saving`);\n this.failure = internalState<string | null>(null, label === undefined ? undefined : `${label}.saveError`);\n this.value = this.held;\n this.saving = this.saves;\n this.saveError = this.failure;\n // A constant key, because the record being read is named once. The\n // resource is eager, so constructing this is what starts the read,\n // which is what \"hydration on start\" means: nothing has to\n // remember to call a `load()`.\n this.record = resource(\n of(key),\n () => this.load(options.revive),\n label === undefined ? {} : { label: `${label}.hydration` }\n );\n this.status = this.record.status;\n this.error = this.record.error;\n this.hydrated = this.record.settled.then(() => this.apply());\n this.writing = debounced(this.held, options.settle ?? 250)\n // The gate hands a new follower the value the cell already has,\n // which here is the default nobody asked to be written. Only\n // what comes after it is a change.\n .pipe(skip(1))\n .subscribe(value => void this.flush(value));\n }\n\n /** What is remembered right now, for code that is not subscribing. */\n get current(): T {\n return this.held.value;\n }\n\n /** Remembers a new value. The write follows once the changes stop. */\n set(value: T): void {\n this.touched = true;\n this.held.value = value;\n }\n\n /**\n * Writes what is held now, without waiting for the gate.\n *\n * For the moment an application knows it is about to lose the thread:\n * a `visibilitychange`, a route away from an editor, a sign-out.\n */\n save(): Promise<void> {\n return this.flush(this.held.value);\n }\n\n /**\n * Forgets the record and goes back to the default.\n *\n * Both halves, because a stored value removed while the cell still\n * holds it would be written straight back by the next change.\n */\n async forget(): Promise<void> {\n this.stored = null;\n this.touched = true;\n this.held.value = this.initial;\n await this.adapter.remove(this.key);\n }\n\n /** Gives back the write subscription and the resource's. */\n dispose(): void {\n this.writing.unsubscribe();\n this.record.dispose();\n }\n\n private async load(revive: ((raw: unknown) => T | null) | undefined): Promise<T | null> {\n const read = await this.adapter.read(this.key);\n if (read.outcome !== 'ok') {\n if (read.outcome === 'denied') {\n this.refused = true;\n }\n throw new Error(read.error ?? MESSAGES[read.outcome] ?? 'The store could not be read.');\n }\n if (read.value === null) {\n return null;\n }\n this.stored = read.value;\n let parsed: unknown;\n try {\n parsed = JSON.parse(read.value);\n } catch {\n // Half-written, or written by something else entirely. Treated\n // as nothing stored rather than as a failure: there is nothing a\n // person can do about it and a default is a working application.\n return null;\n }\n return revive === undefined ? (parsed as T) : revive(parsed);\n }\n\n private apply(): void {\n const found = this.record.value.value;\n if (found === null || this.touched) {\n // Nothing stored, or the person got there first. Theirs is the\n // newer truth and it stays.\n return;\n }\n this.held.value = found;\n }\n\n private async flush(value: T): Promise<void> {\n if (this.refused) {\n return;\n }\n let text: string;\n try {\n text = JSON.stringify(value);\n } catch (error) {\n this.failure.value = error instanceof Error ? error.message : String(error);\n return;\n }\n if (text === this.stored) {\n // Hydration writing what it just read, or a change that came\n // back round to where it started. Either way there is nothing\n // to say to the disk.\n return;\n }\n this.saves.value = this.saves.value + 1;\n try {\n const outcome = await this.adapter.write(this.key, text);\n if (outcome === 'ok') {\n this.stored = text;\n this.failure.value = null;\n return;\n }\n if (outcome === 'denied') {\n this.refused = true;\n }\n this.failure.value = MESSAGES[outcome] ?? 'The store could not be written to.';\n } finally {\n this.saves.value = Math.max(0, this.saves.value - 1);\n }\n }\n}\n\n/**\n * A value read from a store on start and written back as it changes.\n *\n * const settings = persisted(new IndexedDbStorage(), 'settings', {\n * initial: DEFAULTS,\n * revive: raw => (isSettings(raw) ? raw : null)\n * });\n *\n * See `PersistedState` for what a screen sees before the read lands\n * and what each kind of storage failure does.\n */\nexport function persisted<T>(adapter: StorageAdapter, key: string, options: PersistedOptions<T>): PersistedState<T> {\n return new PersistedState(adapter, key, options);\n}\n"],"mappings":"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"}
|