@actuallab/fusion 12.1.100 → 12.2.21

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/dist/index.cjs CHANGED
@@ -128,11 +128,16 @@ var Computed = class _Computed {
128
128
  static async capture(fn) {
129
129
  const captureComputed = new _Computed("__capture__");
130
130
  const captureCtx = new ComputeContext(captureComputed);
131
- const asyncCtx = import_core2.AsyncContext.getOrCreate().with(computeContextKey, captureCtx);
131
+ const asyncCtx = import_core2.AsyncContext.getOrCreate().with(
132
+ computeContextKey,
133
+ captureCtx
134
+ );
132
135
  await asyncCtx.run(fn);
133
136
  const deps = captureComputed.dependencies;
134
137
  if (deps.size === 0)
135
- throw new Error("No Computed was captured \u2014 fn must call a compute function.");
138
+ throw new Error(
139
+ "No Computed was captured \u2014 fn must call a compute function."
140
+ );
136
141
  return deps.values().next().value;
137
142
  }
138
143
  input;
@@ -153,7 +158,8 @@ var Computed = class _Computed {
153
158
  return this._version;
154
159
  }
155
160
  get output() {
156
- if (this._output === void 0) throw new Error("Computed has no output yet.");
161
+ if (this._output === void 0)
162
+ throw new Error("Computed has no output yet.");
157
163
  return this._output;
158
164
  }
159
165
  get hasValue() {
@@ -185,7 +191,9 @@ var Computed = class _Computed {
185
191
  const latest = this._latest();
186
192
  if (latest?.isConsistent) return latest;
187
193
  if (this._renewer !== void 0) return this._renewer();
188
- throw new Error("Cannot recompute: Computed is invalidated and has no renewer.");
194
+ throw new Error(
195
+ "Cannot recompute: Computed is invalidated and has no renewer."
196
+ );
189
197
  }
190
198
  _latest() {
191
199
  return ComputedRegistry.get(this.input);
@@ -203,7 +211,9 @@ var Computed = class _Computed {
203
211
  return updated.value;
204
212
  }
205
213
  useInconsistent(asyncContext) {
206
- ComputeContext.from(asyncContext)?.captureDependency(this);
214
+ ComputeContext.from(asyncContext)?.captureDependency(
215
+ this
216
+ );
207
217
  return this.value;
208
218
  }
209
219
  setOutput(output) {
@@ -213,7 +223,10 @@ var Computed = class _Computed {
213
223
  this._state = 1 /* Consistent */;
214
224
  this._register();
215
225
  if (this._output.hasError && _Computed.errorAutoInvalidateDelay > 0)
216
- setTimeout(() => this.invalidate(), _Computed.errorAutoInvalidateDelay);
226
+ setTimeout(
227
+ () => this.invalidate(),
228
+ _Computed.errorAutoInvalidateDelay
229
+ );
217
230
  }
218
231
  _register() {
219
232
  ComputedRegistry.register(this);
@@ -241,22 +254,26 @@ var Computed = class _Computed {
241
254
  const handler = () => ps.resolve(void 0);
242
255
  this.onInvalidated.add(handler);
243
256
  if (abortSignal !== void 0 && !abortSignal.aborted) {
244
- abortSignal.addEventListener("abort", () => {
245
- this.onInvalidated.remove(handler);
246
- ps.reject(abortSignal.reason);
247
- }, { once: true });
257
+ abortSignal.addEventListener(
258
+ "abort",
259
+ () => {
260
+ this.onInvalidated.remove(handler);
261
+ ps.reject(abortSignal.reason);
262
+ },
263
+ { once: true }
264
+ );
248
265
  }
249
266
  return ps.promise;
250
267
  }
251
268
  addDependency(dependency) {
252
269
  this._dependencies.add(dependency);
253
- dependency._dependants.set(this._version, new WeakRef(this));
270
+ dependency._dependants.set(
271
+ this._version,
272
+ new WeakRef(this)
273
+ );
254
274
  }
255
275
  };
256
276
  var StateBoundComputed = class extends Computed {
257
- constructor(state, renewer) {
258
- super(state, renewer);
259
- }
260
277
  _latest() {
261
278
  return this.input.computed;
262
279
  }
@@ -314,10 +331,15 @@ var ComputeFunction = class {
314
331
  const renewer = prevComputed?._renewer ?? (() => this.invoke(instance, argsWithoutCtx, newComputed));
315
332
  newComputed = new Computed(key, renewer);
316
333
  const childComputeCtx = new ComputeContext(newComputed);
317
- const childAsyncCtx = (asyncCtx ?? import_core3.AsyncContext.empty).with(computeContextKey, childComputeCtx);
334
+ const childAsyncCtx = (asyncCtx ?? import_core3.AsyncContext.empty).with(
335
+ computeContextKey,
336
+ childComputeCtx
337
+ );
318
338
  let fnResult;
319
339
  try {
320
- const value = childAsyncCtx.run(() => this._impl.call(instance, ...argsWithoutCtx));
340
+ const value = childAsyncCtx.run(
341
+ () => this._impl.call(instance, ...argsWithoutCtx)
342
+ );
321
343
  const resolved = value instanceof Promise ? await value : value;
322
344
  fnResult = (0, import_core3.result)(resolved);
323
345
  } catch (e) {
@@ -339,7 +361,11 @@ function getMethodsMeta(cls) {
339
361
  function computeMethod(target, context) {
340
362
  const methodName = String(context.name);
341
363
  const methods = context.metadata[METHODS_META] ??= {};
342
- methods[methodName] = { ...methods[methodName], compute: true, argCount: target.length };
364
+ methods[methodName] = {
365
+ ...methods[methodName],
366
+ compute: true,
367
+ argCount: target.length
368
+ };
343
369
  const cf = new ComputeFunction(methodName, target);
344
370
  const replacement = function(...allArgs) {
345
371
  return cf.invoke(this, allArgs).then((c) => c.value);
@@ -393,14 +419,20 @@ var FixedDelayer = class _FixedDelayer {
393
419
  if (abortSignal === void 0) return;
394
420
  if (abortSignal.aborted) {
395
421
  clearTimeout(timer);
396
- reject(abortSignal.reason);
422
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
397
423
  return;
398
424
  }
399
- abortSignal.addEventListener("abort", () => {
400
- clearTimeout(timer);
401
- reject(abortSignal.reason);
402
- }, { once: true });
403
- }) : () => new Promise((resolve) => setTimeout(resolve, this.ms));
425
+ abortSignal.addEventListener(
426
+ "abort",
427
+ () => {
428
+ clearTimeout(timer);
429
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
430
+ },
431
+ { once: true }
432
+ );
433
+ }) : () => new Promise(
434
+ (resolve) => setTimeout(resolve, this.ms)
435
+ );
404
436
  }
405
437
  };
406
438
  var defaultUpdateDelayer = FixedDelayer.get(1e3 / 60);
@@ -461,8 +493,7 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
461
493
  if (delayer !== void 0) return delayer;
462
494
  const t = uiActions;
463
495
  delayer = (abortSignal) => {
464
- if (t.isActive)
465
- return Promise.resolve();
496
+ if (t.isActive) return Promise.resolve();
466
497
  return new Promise((resolve, reject) => {
467
498
  const timer = setTimeout(resolve, ms);
468
499
  const onChanged = () => {
@@ -477,14 +508,18 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
477
508
  if (abortSignal.aborted) {
478
509
  clearTimeout(timer);
479
510
  t.changed.remove(onChanged);
480
- reject(abortSignal.reason);
511
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
481
512
  return;
482
513
  }
483
- abortSignal.addEventListener("abort", () => {
484
- clearTimeout(timer);
485
- t.changed.remove(onChanged);
486
- reject(abortSignal.reason);
487
- }, { once: true });
514
+ abortSignal.addEventListener(
515
+ "abort",
516
+ () => {
517
+ clearTimeout(timer);
518
+ t.changed.remove(onChanged);
519
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
520
+ },
521
+ { once: true }
522
+ );
488
523
  }
489
524
  });
490
525
  };
@@ -557,8 +592,7 @@ var State = class {
557
592
  _update(computed, output) {
558
593
  computed.setOutput(output);
559
594
  this._computed = computed;
560
- if (computed.hasValue)
561
- this._lastNonErrorValue = computed.value;
595
+ if (computed.hasValue) this._lastNonErrorValue = computed.value;
562
596
  this._updateIndex++;
563
597
  this._whenUpdatedSource?.resolve(void 0);
564
598
  this._whenUpdatedSource = null;
@@ -586,7 +620,10 @@ var ComputedState = class extends State {
586
620
  return this._computed;
587
621
  };
588
622
  if (options?.initialOutput !== void 0 || options?.initialValue !== void 0) {
589
- this._initialize(options.initialOutput ?? options.initialValue, this._renewer);
623
+ this._initialize(
624
+ options.initialOutput ?? options.initialValue,
625
+ this._renewer
626
+ );
590
627
  this._hasOutput = true;
591
628
  }
592
629
  void this._updateCycle();
@@ -600,9 +637,11 @@ var ComputedState = class extends State {
600
637
  return this._computed.hasError;
601
638
  }
602
639
  get value() {
603
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has no value yet.");
640
+ if (!this._hasOutput && this._updateIndex === 0)
641
+ throw new Error("ComputedState has no value yet.");
604
642
  if (this._computed.hasValue) return this._computed.value;
605
- if (this._lastNonErrorValue !== void 0) return this._lastNonErrorValue;
643
+ if (this._lastNonErrorValue !== void 0)
644
+ return this._lastNonErrorValue;
606
645
  throw new Error("ComputedState has no value yet.");
607
646
  }
608
647
  get error() {
@@ -614,26 +653,29 @@ var ComputedState = class extends State {
614
653
  return this._computed.valueOrUndefined ?? this._lastNonErrorValue;
615
654
  }
616
655
  get output() {
617
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has no output yet.");
656
+ if (!this._hasOutput && this._updateIndex === 0)
657
+ throw new Error("ComputedState has no output yet.");
618
658
  return this._computed.output;
619
659
  }
620
660
  get computed() {
621
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has not been computed yet.");
661
+ if (!this._hasOutput && this._updateIndex === 0)
662
+ throw new Error("ComputedState has not been computed yet.");
622
663
  return this._computed;
623
664
  }
624
665
  get isDisposed() {
625
666
  return this._disposeController.signal.aborted;
626
667
  }
627
668
  dispose() {
628
- if (!this.isDisposed)
629
- this._disposeController.abort();
669
+ if (!this.isDisposed) this._disposeController.abort();
630
670
  }
631
671
  async _updateCycle() {
632
672
  const disposeSignal = this._disposeController.signal;
633
673
  try {
634
674
  while (!disposeSignal.aborted) {
635
675
  const computed = new StateBoundComputed(this, this._renewer);
636
- const computeCtx = new ComputeContext(computed);
676
+ const computeCtx = new ComputeContext(
677
+ computed
678
+ );
637
679
  const asyncCtx = (import_core6.AsyncContext.current ?? import_core6.AsyncContext.empty).with(computeContextKey, computeCtx);
638
680
  let output;
639
681
  try {
@@ -656,7 +698,7 @@ var ComputedState = class extends State {
656
698
  this._cancelDelaySource.promise
657
699
  ]);
658
700
  }
659
- } catch (e) {
701
+ } catch {
660
702
  }
661
703
  }
662
704
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/computed-input.ts","../src/computed.ts","../src/computed-registry.ts","../src/compute-context.ts","../src/compute-function.ts","../src/compute-method.ts","../src/update-delayer.ts","../src/ui-action-tracker.ts","../src/ui-update-delayer.ts","../src/state.ts","../src/computed-state.ts","../src/mutable-state.ts"],"sourcesContent":["export { getInstanceId } from \"./computed-input.js\";\r\nexport type { ComputedInput } from \"./computed-input.js\";\r\nexport { Computed, StateBoundComputed, ConsistencyState } from \"./computed.js\";\r\nexport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nexport { ComputedRegistry } from \"./computed-registry.js\";\r\nexport { ComputeFunction } from \"./compute-function.js\";\r\nexport type { ComputeFunctionImpl } from \"./compute-function.js\";\r\nexport { computeMethod, wrapComputeMethod, getMethodsMeta } from \"./compute-method.js\";\r\nexport type { MethodMeta } from \"./compute-method.js\";\r\nexport type { UpdateDelayer } from \"./update-delayer.js\";\r\nexport { FixedDelayer, defaultUpdateDelayer } from \"./update-delayer.js\";\r\nexport { UIUpdateDelayer } from \"./ui-update-delayer.js\";\r\nexport { UIActionTracker, uiActions } from \"./ui-action-tracker.js\";\r\nexport { State } from \"./state.js\";\r\nexport { ComputedState } from \"./computed-state.js\";\r\nexport type { ComputedStateOptions, StateComputer } from \"./computed-state.js\";\r\nexport { MutableState } from \"./mutable-state.js\";\r\n","import type { State } from \"./state.js\";\r\n\r\n/** Auto-assigned numeric IDs for instance identity in compute method cache keys. */\r\nlet _nextInstanceId = 0;\r\nconst _instanceIds = new WeakMap<object, number>();\r\n\r\nexport function getInstanceId(instance: object): number {\r\n let id = _instanceIds.get(instance);\r\n if (id === undefined) {\r\n id = ++_nextInstanceId;\r\n _instanceIds.set(instance, id);\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Identity key for any computed value.\r\n * - String for compute method results (built from instance + function + args)\r\n * - State for state types (identity by reference)\r\n */\r\nexport type ComputedInput = string | State<any>;\r\n","import { AsyncContext, EventHandlerSet, type IResult, PromiseSource, Result, result } from \"@actuallab/core\";\r\nimport type { ComputedInput } from \"./computed-input.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport type { State } from \"./state.js\";\r\n\r\nlet _nextVersion = 0;\r\n\r\nexport const enum ConsistencyState {\r\n Computing = 0,\r\n Consistent = 1,\r\n Invalidated = 2,\r\n}\r\n\r\n/** Core Fusion abstraction — a cached computation with dependency tracking and invalidation. */\r\nexport class Computed<T> implements IResult<T> {\r\n /** Delay before auto-invalidating a Computed that holds an error result. 0 = disabled. */\r\n static errorAutoInvalidateDelay = 1000;\r\n\r\n /** Capture the Computed backing a computation — works with both local and RPC compute methods. */\r\n static async capture<T>(fn: () => T | Promise<T>): Promise<Computed<T>> {\r\n const captureComputed = new Computed<unknown>(\"__capture__\");\r\n const captureCtx = new ComputeContext(captureComputed);\r\n const asyncCtx = AsyncContext.getOrCreate().with(computeContextKey, captureCtx);\r\n await asyncCtx.run(fn);\r\n const deps = captureComputed.dependencies;\r\n if (deps.size === 0)\r\n throw new Error(\"No Computed was captured — fn must call a compute function.\");\r\n return deps.values().next().value! as Computed<T>;\r\n }\r\n\r\n readonly input: ComputedInput;\r\n private _version: number;\r\n private _state: ConsistencyState;\r\n private _output: Result<T> | undefined;\r\n private _dependencies = new Set<Computed<unknown>>();\r\n private _dependants = new Map<number, WeakRef<Computed<unknown>>>();\r\n readonly onInvalidated = new EventHandlerSet<void>();\r\n readonly _renewer: (() => Computed<T> | Promise<Computed<T>>) | undefined;\r\n\r\n constructor(\r\n input: ComputedInput,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>,\r\n ) {\r\n this.input = input;\r\n this._renewer = renewer;\r\n this._version = ++_nextVersion;\r\n this._state = ConsistencyState.Computing;\r\n }\r\n\r\n get version(): number {\r\n return this._version;\r\n }\r\n\r\n get output(): Result<T> {\r\n if (this._output === undefined) throw new Error(\"Computed has no output yet.\");\r\n return this._output;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this.output.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this.output.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this.output.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this.output.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.output.valueOrUndefined;\r\n }\r\n\r\n get state(): ConsistencyState {\r\n return this._state;\r\n }\r\n\r\n get isConsistent(): boolean {\r\n return this._state === ConsistencyState.Consistent;\r\n }\r\n\r\n get dependencies(): ReadonlySet<Computed<unknown>> {\r\n return this._dependencies;\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n if (this._state === ConsistencyState.Consistent) return this;\r\n const latest = this._latest();\r\n if (latest?.isConsistent) return latest;\r\n if (this._renewer !== undefined) return this._renewer();\r\n throw new Error(\"Cannot recompute: Computed is invalidated and has no renewer.\");\r\n }\r\n\r\n protected _latest(): Computed<T> | undefined {\r\n return ComputedRegistry.get(this.input as string) as Computed<T> | undefined;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n const ctx = ComputeContext.from(asyncContext);\r\n const updated = this.update();\r\n if (updated instanceof Promise) {\r\n return updated.then((c) => {\r\n ctx?.captureDependency(c as Computed<unknown>);\r\n return c.value;\r\n });\r\n }\r\n ctx?.captureDependency(updated as Computed<unknown>);\r\n return updated.value;\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n ComputeContext.from(asyncContext)?.captureDependency(this as Computed<unknown>);\r\n return this.value;\r\n }\r\n\r\n setOutput(output: Result<T> | T): void {\r\n if (this._state !== ConsistencyState.Computing)\r\n throw new Error(\"Cannot set output on a non-computing Computed.\");\r\n this._output = output instanceof Result ? output : result(output);\r\n this._state = ConsistencyState.Consistent;\r\n this._register();\r\n if (this._output.hasError && Computed.errorAutoInvalidateDelay > 0)\r\n setTimeout(() => this.invalidate(), Computed.errorAutoInvalidateDelay);\r\n }\r\n\r\n protected _register(): void {\r\n ComputedRegistry.register(this as Computed<unknown>);\r\n }\r\n\r\n protected _unregister(): void {\r\n ComputedRegistry.unregister(this as Computed<unknown>);\r\n }\r\n\r\n invalidate(): void {\r\n if (this._state === ConsistencyState.Invalidated) return;\r\n this._state = ConsistencyState.Invalidated;\r\n\r\n // Clear forward references\r\n this._dependencies.clear();\r\n\r\n // Notify dependants via WeakRef backward references\r\n for (const [, ref] of this._dependants) {\r\n const dependant = ref.deref();\r\n if (dependant != null) dependant.invalidate();\r\n }\r\n this._dependants.clear();\r\n\r\n this.onInvalidated.trigger();\r\n this.onInvalidated.clear();\r\n\r\n this._unregister();\r\n }\r\n\r\n whenInvalidated(abortSignal?: AbortSignal): Promise<void> {\r\n if (this._state === ConsistencyState.Invalidated)\r\n return Promise.resolve();\r\n\r\n const ps = new PromiseSource<void>();\r\n const handler = () => ps.resolve(undefined);\r\n this.onInvalidated.add(handler);\r\n\r\n if (abortSignal !== undefined && !abortSignal.aborted) {\r\n abortSignal.addEventListener(\"abort\", () => {\r\n this.onInvalidated.remove(handler);\r\n ps.reject(abortSignal.reason);\r\n }, { once: true });\r\n }\r\n\r\n return ps.promise;\r\n }\r\n\r\n addDependency(dependency: Computed<unknown>): void {\r\n this._dependencies.add(dependency);\r\n dependency._dependants.set(this._version, new WeakRef(this as Computed<unknown>));\r\n }\r\n}\r\n\r\n/** Computed variant for State types — skips registry registration since the State holds a direct reference. */\r\nexport class StateBoundComputed<T> extends Computed<T> {\r\n constructor(state: State<T>, renewer?: () => Computed<T> | Promise<Computed<T>>) {\r\n super(state, renewer);\r\n }\r\n\r\n protected override _latest(): Computed<T> | undefined {\r\n return (this.input as State<T>).computed;\r\n }\r\n\r\n protected override _register(): void {\r\n // No registration — state holds direct reference\r\n }\r\n\r\n protected override _unregister(): void {\r\n // No unregistration — was never registered\r\n }\r\n}\r\n","import type { Computed } from \"./computed.js\";\r\n\r\n/** WeakRef-based global cache of Computed instances — allows GC of unused computed values. */\r\nexport class ComputedRegistry {\r\n private static _entries = new Map<string, WeakRef<Computed<unknown>>>();\r\n private static _finalization = new FinalizationRegistry<string>((key) => {\r\n ComputedRegistry._entries.delete(key);\r\n });\r\n\r\n static get size(): number {\r\n return ComputedRegistry._entries.size;\r\n }\r\n\r\n static get(key: string): Computed<unknown> | undefined {\r\n const ref = ComputedRegistry._entries.get(key);\r\n if (ref === undefined) return undefined;\r\n const computed = ref.deref();\r\n if (computed === undefined) {\r\n ComputedRegistry._entries.delete(key);\r\n return undefined;\r\n }\r\n return computed;\r\n }\r\n\r\n static register(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.set(key, new WeakRef(computed));\r\n ComputedRegistry._finalization.register(computed, key, computed);\r\n }\r\n\r\n static unregister(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.delete(key);\r\n ComputedRegistry._finalization.unregister(computed);\r\n }\r\n}\r\n","import { AsyncContext, AsyncContextKey } from \"@actuallab/core\";\r\nimport type { Computed } from \"./computed.js\";\r\n\r\nexport const computeContextKey =\r\n new AsyncContextKey<ComputeContext | undefined>(\"ComputeContext\", undefined);\r\n\r\n/** Tracks the currently executing computation and captures dependencies. */\r\nexport class ComputeContext {\r\n readonly computed: Computed<unknown>;\r\n private _isCapturing = true;\r\n\r\n constructor(computed: Computed<unknown>) {\r\n this.computed = computed;\r\n }\r\n\r\n get isCapturing(): boolean {\r\n return this._isCapturing;\r\n }\r\n\r\n stopCapturing(): void {\r\n this._isCapturing = false;\r\n }\r\n\r\n captureDependency(dependency: Computed<unknown>): void {\r\n if (!this._isCapturing) return;\r\n this.computed.addDependency(dependency);\r\n }\r\n\r\n /** Resolve ComputeContext from an AsyncContext (or current). */\r\n static from(ctx: AsyncContext | undefined): ComputeContext | undefined {\r\n return AsyncContext.from(ctx)?.get(computeContextKey);\r\n }\r\n}\r\n","import { AsyncContext, AsyncLock, type Result, result, errorResult } from \"@actuallab/core\";\r\nimport { Computed } from \"./computed.js\";\r\nimport { getInstanceId } from \"./computed-input.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\n\r\nexport type ComputeFunctionImpl = (this: any, ...args: unknown[]) => unknown;\r\n\r\n/** Record Separator — delimiter between key components. */\r\nconst RS = \"\\x1E\";\r\n\r\nfunction defaultArgToString(arg: unknown): string {\r\n return JSON.stringify(arg) ?? \"undefined\";\r\n}\r\n\r\nlet _nextFunctionId = 0;\r\n\r\n/** Produces Computed<T> from a function — handles cache lookup, locking, dependency capture. */\r\nexport class ComputeFunction {\r\n readonly methodName: string;\r\n readonly id: string;\r\n argToString: (arg: unknown) => string = defaultArgToString;\r\n private _impl: ComputeFunctionImpl;\r\n private _locks = new Map<string, AsyncLock>();\r\n\r\n constructor(methodName: string, impl: ComputeFunctionImpl) {\r\n this.methodName = methodName;\r\n this.id = `${methodName}[${++_nextFunctionId}]`;\r\n this._impl = impl;\r\n }\r\n\r\n /** Build a string key for the given instance and arguments. */\r\n buildKey(instance: object, args: unknown[]): string {\r\n let key = String(getInstanceId(instance)) + RS + this.id;\r\n for (const arg of args) {\r\n key += RS + this.argToString(arg);\r\n }\r\n return key;\r\n }\r\n\r\n async invoke(instance: object, args: unknown[], prevComputed?: Computed<unknown>): Promise<Computed<unknown>> {\r\n // 1. Resolve AsyncContext ONCE via DRY helper\r\n const asyncCtx = AsyncContext.fromArgs(args);\r\n\r\n // 2. Pull caller's ComputeContext directly\r\n const callerComputeCtx = asyncCtx?.get(computeContextKey);\r\n\r\n // 3. Strip THIS context from args (reference equality — safe)\r\n const argsWithoutCtx = asyncCtx?.stripFromArgs(args) ?? args;\r\n\r\n // 4. Build string key and check cache\r\n const key = this.buildKey(instance, argsWithoutCtx);\r\n const existing = ComputedRegistry.get(key);\r\n if (existing?.isConsistent) {\r\n callerComputeCtx?.captureDependency(existing);\r\n return existing;\r\n }\r\n\r\n // 5. Lock per key to prevent duplicate computations\r\n let lock = this._locks.get(key);\r\n if (lock === undefined) {\r\n lock = new AsyncLock();\r\n this._locks.set(key, lock);\r\n }\r\n\r\n const computed = await lock.run(async () => {\r\n // Double-check after acquiring lock\r\n const cached = ComputedRegistry.get(key);\r\n if (cached?.isConsistent) return cached;\r\n\r\n // 6. Create new Computed + ComputeContext\r\n let newComputed: Computed<unknown>;\r\n const renewer = prevComputed?._renewer ?? (() => this.invoke(instance, argsWithoutCtx, newComputed));\r\n newComputed = new Computed<unknown>(key, renewer);\r\n\r\n const childComputeCtx = new ComputeContext(newComputed);\r\n const childAsyncCtx = (asyncCtx ?? AsyncContext.empty)\r\n .with(computeContextKey, childComputeCtx);\r\n\r\n // 7. Run with clean args — no stale AsyncContext to override .run()\r\n let fnResult: Result<unknown>;\r\n try {\r\n const value = childAsyncCtx.run(() => this._impl.call(instance, ...argsWithoutCtx));\r\n const resolved = value instanceof Promise ? await value : value;\r\n fnResult = result(resolved);\r\n } catch (e) {\r\n fnResult = errorResult(e);\r\n }\r\n\r\n newComputed.setOutput(fnResult);\r\n\r\n return newComputed;\r\n });\r\n\r\n // Register dependency from caller to the produced computed\r\n callerComputeCtx?.captureDependency(computed);\r\n return computed;\r\n }\r\n}\r\n","import { ComputeFunction } from \"./compute-function.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\n\r\nconst METHODS_META = Symbol.for(\"actuallab.methods\");\r\n\r\nexport interface MethodMeta {\r\n argCount: number;\r\n compute?: boolean;\r\n stream?: boolean;\r\n}\r\n\r\n/** Read method metadata from a decorated class. */\r\nexport function getMethodsMeta(cls: abstract new (...args: any[]) => any): Record<string, MethodMeta> | undefined {\r\n return (cls as any)[Symbol.metadata]?.[METHODS_META];\r\n}\r\n\r\n/** Method decorator — wraps a method to route through ComputeFunction for caching and dependency tracking. */\r\nexport function computeMethod<This, Args extends unknown[], Return>(\r\n target: (this: This, ...args: Args) => Return,\r\n context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,\r\n): (this: This, ...args: Args) => Return {\r\n const methodName = String(context.name);\r\n\r\n // Store metadata\r\n const methods: Record<string, MethodMeta> = ((context.metadata as any)[METHODS_META] ??= {});\r\n methods[methodName] = { ...methods[methodName], compute: true, argCount: target.length };\r\n\r\n // ONE ComputeFunction per class×method — created at decoration time\r\n const cf = new ComputeFunction(methodName, target as any);\r\n\r\n // Prototype-level replacement — unwraps Computed to return the value directly\r\n const replacement = function(this: This, ...allArgs: Args): Return {\r\n return cf.invoke(this as object, allArgs).then(c => c.value) as Return;\r\n };\r\n\r\n // Per-instance setup: create bound method with .invalidate pre-bound\r\n context.addInitializer(function(this: This) {\r\n const instance = this;\r\n const boundMethod = (...allArgs: unknown[]) => {\r\n return cf.invoke(instance as object, allArgs).then(c => c.value);\r\n };\r\n (boundMethod as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(instance as object, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n (this as any)[methodName] = boundMethod;\r\n });\r\n\r\n return replacement;\r\n}\r\n\r\n/** Wrap a standalone function as a compute function with caching and .invalidate(). */\r\nexport function wrapComputeMethod<Args extends unknown[], Return>(\r\n fn: (...args: Args) => Return,\r\n): ((...args: Args) => Promise<Return>) & { invalidate: (...args: Args) => void } {\r\n const syntheticInstance = {};\r\n const methodName = fn.name || \"anonymous\";\r\n const cf = new ComputeFunction(methodName, fn as any);\r\n\r\n const wrapped = (...allArgs: unknown[]) => {\r\n return cf.invoke(syntheticInstance, allArgs).then(c => c.value as Return);\r\n };\r\n\r\n (wrapped as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(syntheticInstance, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n\r\n return wrapped as any;\r\n}\r\n","/** Controls when state re-computation happens after invalidation. */\r\nexport type UpdateDelayer = (abortSignal?: AbortSignal) => Promise<void>;\r\n\r\n/** Re-computes after a fixed delay in milliseconds. */\r\nexport class FixedDelayer {\r\n static readonly zero: UpdateDelayer = () => Promise.resolve();\r\n\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = FixedDelayer._cache.get(ms);\r\n if (delayer === undefined) {\r\n delayer = new FixedDelayer(ms).delay;\r\n FixedDelayer._cache.set(ms, delayer);\r\n }\r\n return delayer;\r\n }\r\n\r\n readonly ms: number;\r\n readonly delay: UpdateDelayer;\r\n\r\n constructor(ms: number) {\r\n this.ms = ms;\r\n this.delay = ms > 10_000\r\n ? (abortSignal?: AbortSignal) => new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, this.ms);\r\n if (abortSignal === undefined) return;\r\n if (abortSignal.aborted) { clearTimeout(timer); reject(abortSignal.reason); return; }\r\n abortSignal.addEventListener(\"abort\", () => {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason);\r\n }, { once: true });\r\n })\r\n : () => new Promise<void>((resolve) => setTimeout(resolve, this.ms));\r\n }\r\n}\r\n\r\nexport let defaultUpdateDelayer: UpdateDelayer = FixedDelayer.get(1000 / 60);\r\n","import { EventHandlerSet } from \"@actuallab/core\";\r\n\r\n/** Singleton tracking active UI commands — mirrors .NET's UIActionTracker. */\r\nexport class UIActionTracker {\r\n private _activeCount = 0;\r\n readonly changed = new EventHandlerSet<void>();\r\n readonly errors: unknown[] = [];\r\n\r\n get isActive(): boolean {\r\n return this._activeCount > 0;\r\n }\r\n\r\n /** Run a command silently — errors are added to the error list but not thrown. */\r\n async run(fn: () => Promise<unknown>): Promise<void> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n } finally {\r\n this._activeCount--;\r\n // Buffer 50ms for invalidations to arrive before signaling completion\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n /** Call a command and return the result — errors are added to the error list AND thrown. */\r\n async call<T>(fn: () => Promise<T>): Promise<T> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n return await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n throw e;\r\n } finally {\r\n this._activeCount--;\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n dismissError(index: number): void {\r\n if (index >= 0 && index < this.errors.length) {\r\n this.errors.splice(index, 1);\r\n this.changed.trigger();\r\n }\r\n }\r\n}\r\n\r\nexport let uiActions = new UIActionTracker();\r\n","import { uiActions } from \"./ui-action-tracker.js\";\r\nimport { FixedDelayer, type UpdateDelayer } from \"./update-delayer.js\";\r\n\r\n/** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */\r\nexport class UIUpdateDelayer {\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = UIUpdateDelayer._cache.get(ms);\r\n if (delayer !== undefined) return delayer;\r\n\r\n const t = uiActions;\r\n delayer = (abortSignal?: AbortSignal) => {\r\n if (t.isActive)\r\n return Promise.resolve();\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, ms);\r\n\r\n // Cancel delay when tracker becomes active\r\n const onChanged = () => {\r\n if (t.isActive) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n resolve();\r\n }\r\n };\r\n t.changed.add(onChanged);\r\n\r\n if (abortSignal !== undefined) {\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason);\r\n return;\r\n }\r\n abortSignal.addEventListener(\"abort\", () => {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason);\r\n }, { once: true });\r\n }\r\n });\r\n };\r\n UIUpdateDelayer._cache.set(ms, delayer);\r\n return delayer;\r\n }\r\n}\r\n","import { type AsyncContext, type IResult, PromiseSource, resolvedVoidPromise, type Result } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\n\r\n/** Base class for all reactive state types. */\r\nexport abstract class State<T> implements IResult<T> {\r\n protected _computed!: Computed<T>;\r\n protected _updateIndex = 0;\r\n protected _lastNonErrorValue: T | undefined;\r\n private _whenUpdatedSource: PromiseSource<void> | null = null;\r\n\r\n get updateIndex(): number {\r\n return this._updateIndex;\r\n }\r\n\r\n get lastNonErrorValue(): T | undefined {\r\n return this._lastNonErrorValue;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this._computed.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this._computed.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this._computed.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this._computed.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this._computed.valueOrUndefined;\r\n }\r\n\r\n get output(): Result<T> {\r\n return this._computed.output;\r\n }\r\n\r\n get computed(): Computed<T> {\r\n return this._computed;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n return this._computed.use(asyncContext);\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n return this._computed.useInconsistent(asyncContext);\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n return this._computed.update();\r\n }\r\n\r\n recompute(): Computed<T> | Promise<Computed<T>> {\r\n this._computed.invalidate();\r\n return this.update();\r\n }\r\n\r\n whenInvalidated(): Promise<void> {\r\n return this._computed.whenInvalidated();\r\n }\r\n\r\n whenUpdated(): Promise<void> {\r\n return (this._whenUpdatedSource ??= new PromiseSource<void>()).promise;\r\n }\r\n\r\n whenFirstTimeUpdated(): Promise<void> {\r\n return this._updateIndex > 0 ? resolvedVoidPromise : this.whenUpdated();\r\n }\r\n\r\n protected _initialize(output: Result<T> | T, renewer?: () => Computed<T> | Promise<Computed<T>>): void {\r\n this._computed = new StateBoundComputed<T>(this, renewer);\r\n this._computed.setOutput(output);\r\n this._lastNonErrorValue = this._computed.valueOrUndefined;\r\n }\r\n\r\n protected _update(computed: Computed<T>, output: Result<T> | T): void {\r\n computed.setOutput(output);\r\n this._computed = computed;\r\n if (computed.hasValue)\r\n this._lastNonErrorValue = computed.value;\r\n this._updateIndex++;\r\n this._whenUpdatedSource?.resolve(undefined);\r\n this._whenUpdatedSource = null;\r\n }\r\n}\r\n","import { AsyncContext, PromiseSource, type Result, result, errorResult } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from \"./update-delayer.js\";\r\nimport { State } from \"./state.js\";\r\n\r\nexport type StateComputer<T> = () => T | Promise<T>;\r\n\r\n/** Constructor options for ComputedState. */\r\nexport interface ComputedStateOptions<T> {\r\n initialValue?: T;\r\n initialOutput?: Result<T>;\r\n updateDelayer?: UpdateDelayer;\r\n}\r\n\r\n/** Auto-updating reactive state wrapper — re-computes on invalidation with configurable delay. */\r\nexport class ComputedState<T> extends State<T> {\r\n private _computer: StateComputer<T>;\r\n private _updateDelayer: UpdateDelayer;\r\n private _disposeController: AbortController;\r\n private _cancelDelaySource = new PromiseSource<void>();\r\n private _renewer: () => Computed<T> | Promise<Computed<T>>;\r\n private _hasOutput = false;\r\n\r\n constructor(computer: StateComputer<T>, options?: ComputedStateOptions<T>) {\r\n super();\r\n this._computer = computer;\r\n this._updateDelayer = options?.updateDelayer ?? defaultUpdateDelayer;\r\n this._disposeController = new AbortController();\r\n this._renewer = async () => {\r\n const whenUpdated = this.whenUpdated();\r\n this._cancelDelaySource.resolve(undefined);\r\n await whenUpdated;\r\n return this._computed;\r\n };\r\n\r\n // Create initial computed — _updateCycle will replace it on first iteration\r\n if (options?.initialOutput !== undefined || options?.initialValue !== undefined) {\r\n this._initialize(options.initialOutput ?? options.initialValue as T, this._renewer);\r\n this._hasOutput = true;\r\n }\r\n // else: _computed stays unset until _updateCycle calls _update()\r\n\r\n void this._updateCycle();\r\n }\r\n\r\n override get hasValue(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasValue;\r\n }\r\n\r\n override get hasError(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasError;\r\n }\r\n\r\n override get value(): T {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has no value yet.\");\r\n if (this._computed.hasValue) return this._computed.value;\r\n if (this._lastNonErrorValue !== undefined) return this._lastNonErrorValue;\r\n throw new Error(\"ComputedState has no value yet.\");\r\n }\r\n\r\n override get error(): unknown {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.error;\r\n }\r\n\r\n override get valueOrUndefined(): T | undefined {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.valueOrUndefined ?? this._lastNonErrorValue;\r\n }\r\n\r\n override get output(): Result<T> {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has no output yet.\");\r\n return this._computed.output;\r\n }\r\n\r\n override get computed(): Computed<T> {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has not been computed yet.\");\r\n return this._computed;\r\n }\r\n\r\n get isDisposed(): boolean {\r\n return this._disposeController.signal.aborted;\r\n }\r\n\r\n dispose(): void {\r\n if (!this.isDisposed)\r\n this._disposeController.abort();\r\n }\r\n\r\n private async _updateCycle(): Promise<void> {\r\n const disposeSignal = this._disposeController.signal;\r\n try {\r\n while (!disposeSignal.aborted) {\r\n // Compute\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n const computeCtx = new ComputeContext(computed as StateBoundComputed<unknown>);\r\n const asyncCtx = (AsyncContext.current ?? AsyncContext.empty)\r\n .with(computeContextKey, computeCtx);\r\n\r\n let output: Result<T>;\r\n try {\r\n const value = asyncCtx.run(() => this._computer());\r\n const resolved = value instanceof Promise ? await value : value;\r\n output = result(resolved);\r\n } catch (e) {\r\n output = errorResult(e);\r\n }\r\n this._update(computed, output);\r\n if (this._cancelDelaySource.isCompleted)\r\n this._cancelDelaySource = new PromiseSource<void>();\r\n\r\n // Wait for invalidation (or cancellation via dispose)\r\n try {\r\n await computed.whenInvalidated(disposeSignal);\r\n } catch {\r\n return; // Cancelled via dispose\r\n }\r\n\r\n // Wait for delay (cancellable by renewer)\r\n await Promise.race([\r\n this._updateDelayer(disposeSignal),\r\n this._cancelDelaySource.promise,\r\n ]);\r\n }\r\n\r\n } catch (e) {\r\n // Intended, do nothing\r\n }\r\n }\r\n}\r\n","import { type AsyncContext, Result } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\nimport { State } from \"./state.js\";\r\n\r\n/** Manually-settable reactive state that can participate in the Fusion dependency graph. */\r\nexport class MutableState<T> extends State<T> {\r\n private _renewer = (): Computed<T> => {\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n this._update(computed, this._computed.output);\r\n return computed;\r\n };\r\n\r\n constructor(initialOutput: Result<T> | T) {\r\n super();\r\n this._initialize(initialOutput, this._renewer);\r\n }\r\n\r\n override use(asyncContext?: AsyncContext): T {\r\n return this._computed.use(asyncContext) as T;\r\n }\r\n\r\n set(output: Result<T> | T): void {\r\n this._computed.invalidate();\r\n this._update(new StateBoundComputed<T>(this, this._renewer), output);\r\n }\r\n}\r\n"],"mappings":"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","names":["import_core","ConsistencyState","import_core","import_core","import_core","import_core","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/computed-input.ts","../src/computed.ts","../src/computed-registry.ts","../src/compute-context.ts","../src/compute-function.ts","../src/compute-method.ts","../src/update-delayer.ts","../src/ui-action-tracker.ts","../src/ui-update-delayer.ts","../src/state.ts","../src/computed-state.ts","../src/mutable-state.ts"],"sourcesContent":["export { getInstanceId } from './computed-input.js';\r\nexport type { ComputedInput } from './computed-input.js';\r\nexport { Computed, StateBoundComputed, ConsistencyState } from './computed.js';\r\nexport { ComputeContext, computeContextKey } from './compute-context.js';\r\nexport { ComputedRegistry } from './computed-registry.js';\r\nexport { ComputeFunction } from './compute-function.js';\r\nexport type { ComputeFunctionImpl } from './compute-function.js';\r\nexport {\r\n computeMethod,\r\n wrapComputeMethod,\r\n getMethodsMeta,\r\n} from './compute-method.js';\r\nexport type { MethodMeta } from './compute-method.js';\r\nexport type { UpdateDelayer } from './update-delayer.js';\r\nexport { FixedDelayer, defaultUpdateDelayer } from './update-delayer.js';\r\nexport { UIUpdateDelayer } from './ui-update-delayer.js';\r\nexport { UIActionTracker, uiActions } from './ui-action-tracker.js';\r\nexport { State } from './state.js';\r\nexport { ComputedState } from './computed-state.js';\r\nexport type { ComputedStateOptions, StateComputer } from './computed-state.js';\r\nexport { MutableState } from './mutable-state.js';\r\n","import type { State } from './state.js';\r\n\r\n/** Auto-assigned numeric IDs for instance identity in compute method cache keys. */\r\nlet _nextInstanceId = 0;\r\nconst _instanceIds = new WeakMap<object, number>();\r\n\r\nexport function getInstanceId(instance: object): number {\r\n let id = _instanceIds.get(instance);\r\n if (id === undefined) {\r\n id = ++_nextInstanceId;\r\n _instanceIds.set(instance, id);\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Identity key for any computed value.\r\n * - String for compute method results (built from instance + function + args)\r\n * - State for state types (identity by reference)\r\n */\r\nexport type ComputedInput = string | State<any>;\r\n","import {\r\n AsyncContext,\r\n EventHandlerSet,\r\n type IResult,\r\n PromiseSource,\r\n Result,\r\n result,\r\n} from '@actuallab/core';\r\nimport type { ComputedInput } from './computed-input.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport type { State } from './state.js';\r\n\r\nlet _nextVersion = 0;\r\n\r\nexport const enum ConsistencyState {\r\n Computing = 0,\r\n Consistent = 1,\r\n Invalidated = 2,\r\n}\r\n\r\n/** Core Fusion abstraction — a cached computation with dependency tracking and invalidation. */\r\nexport class Computed<T> implements IResult<T> {\r\n /** Delay before auto-invalidating a Computed that holds an error result. 0 = disabled. */\r\n static errorAutoInvalidateDelay = 1000;\r\n\r\n /** Capture the Computed backing a computation — works with both local and RPC compute methods. */\r\n static async capture<T>(fn: () => T | Promise<T>): Promise<Computed<T>> {\r\n const captureComputed = new Computed<unknown>('__capture__');\r\n const captureCtx = new ComputeContext(captureComputed);\r\n const asyncCtx = AsyncContext.getOrCreate().with(\r\n computeContextKey,\r\n captureCtx\r\n );\r\n await asyncCtx.run(fn);\r\n const deps = captureComputed.dependencies;\r\n if (deps.size === 0)\r\n throw new Error(\r\n 'No Computed was captured — fn must call a compute function.'\r\n );\r\n return deps.values().next().value! as Computed<T>;\r\n }\r\n\r\n readonly input: ComputedInput;\r\n private _version: number;\r\n private _state: ConsistencyState;\r\n private _output: Result<T> | undefined;\r\n private _dependencies = new Set<Computed<unknown>>();\r\n private _dependants = new Map<number, WeakRef<Computed<unknown>>>();\r\n readonly onInvalidated = new EventHandlerSet<void>();\r\n readonly _renewer: (() => Computed<T> | Promise<Computed<T>>) | undefined;\r\n\r\n constructor(\r\n input: ComputedInput,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>\r\n ) {\r\n this.input = input;\r\n this._renewer = renewer;\r\n this._version = ++_nextVersion;\r\n this._state = ConsistencyState.Computing;\r\n }\r\n\r\n get version(): number {\r\n return this._version;\r\n }\r\n\r\n get output(): Result<T> {\r\n if (this._output === undefined)\r\n throw new Error('Computed has no output yet.');\r\n return this._output;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this.output.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this.output.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this.output.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this.output.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.output.valueOrUndefined;\r\n }\r\n\r\n get state(): ConsistencyState {\r\n return this._state;\r\n }\r\n\r\n get isConsistent(): boolean {\r\n return this._state === ConsistencyState.Consistent;\r\n }\r\n\r\n get dependencies(): ReadonlySet<Computed<unknown>> {\r\n return this._dependencies;\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n if (this._state === ConsistencyState.Consistent) return this;\r\n const latest = this._latest();\r\n if (latest?.isConsistent) return latest;\r\n if (this._renewer !== undefined) return this._renewer();\r\n throw new Error(\r\n 'Cannot recompute: Computed is invalidated and has no renewer.'\r\n );\r\n }\r\n\r\n protected _latest(): Computed<T> | undefined {\r\n return ComputedRegistry.get(this.input as string) as\r\n | Computed<T>\r\n | undefined;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n const ctx = ComputeContext.from(asyncContext);\r\n const updated = this.update();\r\n if (updated instanceof Promise) {\r\n return updated.then(c => {\r\n ctx?.captureDependency(c as Computed<unknown>);\r\n return c.value;\r\n });\r\n }\r\n ctx?.captureDependency(updated as Computed<unknown>);\r\n return updated.value;\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n ComputeContext.from(asyncContext)?.captureDependency(\r\n this as Computed<unknown>\r\n );\r\n return this.value;\r\n }\r\n\r\n setOutput(output: Result<T> | T): void {\r\n if (this._state !== ConsistencyState.Computing)\r\n throw new Error('Cannot set output on a non-computing Computed.');\r\n this._output = output instanceof Result ? output : result(output);\r\n this._state = ConsistencyState.Consistent;\r\n this._register();\r\n if (this._output.hasError && Computed.errorAutoInvalidateDelay > 0)\r\n setTimeout(\r\n () => this.invalidate(),\r\n Computed.errorAutoInvalidateDelay\r\n );\r\n }\r\n\r\n protected _register(): void {\r\n ComputedRegistry.register(this as Computed<unknown>);\r\n }\r\n\r\n protected _unregister(): void {\r\n ComputedRegistry.unregister(this as Computed<unknown>);\r\n }\r\n\r\n invalidate(): void {\r\n if (this._state === ConsistencyState.Invalidated) return;\r\n this._state = ConsistencyState.Invalidated;\r\n\r\n // Clear forward references\r\n this._dependencies.clear();\r\n\r\n // Notify dependants via WeakRef backward references\r\n for (const [, ref] of this._dependants) {\r\n const dependant = ref.deref();\r\n if (dependant != null) dependant.invalidate();\r\n }\r\n this._dependants.clear();\r\n\r\n this.onInvalidated.trigger();\r\n this.onInvalidated.clear();\r\n\r\n this._unregister();\r\n }\r\n\r\n whenInvalidated(abortSignal?: AbortSignal): Promise<void> {\r\n if (this._state === ConsistencyState.Invalidated)\r\n return Promise.resolve();\r\n\r\n const ps = new PromiseSource<void>();\r\n const handler = () => ps.resolve(undefined);\r\n this.onInvalidated.add(handler);\r\n\r\n if (abortSignal !== undefined && !abortSignal.aborted) {\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n this.onInvalidated.remove(handler);\r\n ps.reject(abortSignal.reason);\r\n },\r\n { once: true }\r\n );\r\n }\r\n\r\n return ps.promise;\r\n }\r\n\r\n addDependency(dependency: Computed<unknown>): void {\r\n this._dependencies.add(dependency);\r\n dependency._dependants.set(\r\n this._version,\r\n new WeakRef(this as Computed<unknown>)\r\n );\r\n }\r\n}\r\n\r\n/** Computed variant for State types — skips registry registration since the State holds a direct reference. */\r\nexport class StateBoundComputed<T> extends Computed<T> {\r\n protected override _latest(): Computed<T> | undefined {\r\n return (this.input as State<T>).computed;\r\n }\r\n\r\n protected override _register(): void {\r\n // No registration — state holds direct reference\r\n }\r\n\r\n protected override _unregister(): void {\r\n // No unregistration — was never registered\r\n }\r\n}\r\n","import type { Computed } from './computed.js';\r\n\r\n/** WeakRef-based global cache of Computed instances — allows GC of unused computed values. */\r\nexport class ComputedRegistry {\r\n private static _entries = new Map<string, WeakRef<Computed<unknown>>>();\r\n private static _finalization = new FinalizationRegistry<string>(key => {\r\n ComputedRegistry._entries.delete(key);\r\n });\r\n\r\n static get size(): number {\r\n return ComputedRegistry._entries.size;\r\n }\r\n\r\n static get(key: string): Computed<unknown> | undefined {\r\n const ref = ComputedRegistry._entries.get(key);\r\n if (ref === undefined) return undefined;\r\n const computed = ref.deref();\r\n if (computed === undefined) {\r\n ComputedRegistry._entries.delete(key);\r\n return undefined;\r\n }\r\n return computed;\r\n }\r\n\r\n static register(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.set(key, new WeakRef(computed));\r\n ComputedRegistry._finalization.register(computed, key, computed);\r\n }\r\n\r\n static unregister(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.delete(key);\r\n ComputedRegistry._finalization.unregister(computed);\r\n }\r\n}\r\n","import { AsyncContext, AsyncContextKey } from '@actuallab/core';\r\nimport type { Computed } from './computed.js';\r\n\r\nexport const computeContextKey = new AsyncContextKey<\r\n ComputeContext | undefined\r\n>('ComputeContext', undefined);\r\n\r\n/** Tracks the currently executing computation and captures dependencies. */\r\nexport class ComputeContext {\r\n readonly computed: Computed<unknown>;\r\n private _isCapturing = true;\r\n\r\n constructor(computed: Computed<unknown>) {\r\n this.computed = computed;\r\n }\r\n\r\n get isCapturing(): boolean {\r\n return this._isCapturing;\r\n }\r\n\r\n stopCapturing(): void {\r\n this._isCapturing = false;\r\n }\r\n\r\n captureDependency(dependency: Computed<unknown>): void {\r\n if (!this._isCapturing) return;\r\n this.computed.addDependency(dependency);\r\n }\r\n\r\n /** Resolve ComputeContext from an AsyncContext (or current). */\r\n static from(ctx: AsyncContext | undefined): ComputeContext | undefined {\r\n return AsyncContext.from(ctx)?.get(computeContextKey);\r\n }\r\n}\r\n","import {\r\n AsyncContext,\r\n AsyncLock,\r\n type Result,\r\n result,\r\n errorResult,\r\n} from '@actuallab/core';\r\nimport { Computed } from './computed.js';\r\nimport { getInstanceId } from './computed-input.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\n\r\nexport type ComputeFunctionImpl = (this: any, ...args: unknown[]) => unknown;\r\n\r\n/** Record Separator — delimiter between key components. */\r\nconst RS = '\\x1E';\r\n\r\nfunction defaultArgToString(arg: unknown): string {\r\n return JSON.stringify(arg) ?? 'undefined';\r\n}\r\n\r\nlet _nextFunctionId = 0;\r\n\r\n/** Produces Computed<T> from a function — handles cache lookup, locking, dependency capture. */\r\nexport class ComputeFunction {\r\n readonly methodName: string;\r\n readonly id: string;\r\n argToString: (arg: unknown) => string = defaultArgToString;\r\n private _impl: ComputeFunctionImpl;\r\n private _locks = new Map<string, AsyncLock>();\r\n\r\n constructor(methodName: string, impl: ComputeFunctionImpl) {\r\n this.methodName = methodName;\r\n this.id = `${methodName}[${++_nextFunctionId}]`;\r\n this._impl = impl;\r\n }\r\n\r\n /** Build a string key for the given instance and arguments. */\r\n buildKey(instance: object, args: unknown[]): string {\r\n let key = String(getInstanceId(instance)) + RS + this.id;\r\n for (const arg of args) {\r\n key += RS + this.argToString(arg);\r\n }\r\n return key;\r\n }\r\n\r\n async invoke(\r\n instance: object,\r\n args: unknown[],\r\n prevComputed?: Computed<unknown>\r\n ): Promise<Computed<unknown>> {\r\n // 1. Resolve AsyncContext ONCE via DRY helper\r\n const asyncCtx = AsyncContext.fromArgs(args);\r\n\r\n // 2. Pull caller's ComputeContext directly\r\n const callerComputeCtx = asyncCtx?.get(computeContextKey);\r\n\r\n // 3. Strip THIS context from args (reference equality — safe)\r\n const argsWithoutCtx = asyncCtx?.stripFromArgs(args) ?? args;\r\n\r\n // 4. Build string key and check cache\r\n const key = this.buildKey(instance, argsWithoutCtx);\r\n const existing = ComputedRegistry.get(key);\r\n if (existing?.isConsistent) {\r\n callerComputeCtx?.captureDependency(existing);\r\n return existing;\r\n }\r\n\r\n // 5. Lock per key to prevent duplicate computations\r\n let lock = this._locks.get(key);\r\n if (lock === undefined) {\r\n lock = new AsyncLock();\r\n this._locks.set(key, lock);\r\n }\r\n\r\n const computed = await lock.run(async () => {\r\n // Double-check after acquiring lock\r\n const cached = ComputedRegistry.get(key);\r\n if (cached?.isConsistent) return cached;\r\n\r\n // 6. Create new Computed + ComputeContext\r\n // eslint-disable-next-line prefer-const\r\n let newComputed: Computed<unknown>;\r\n const renewer =\r\n prevComputed?._renewer ??\r\n (() => this.invoke(instance, argsWithoutCtx, newComputed));\r\n newComputed = new Computed<unknown>(key, renewer);\r\n\r\n const childComputeCtx = new ComputeContext(newComputed);\r\n const childAsyncCtx = (asyncCtx ?? AsyncContext.empty).with(\r\n computeContextKey,\r\n childComputeCtx\r\n );\r\n\r\n // 7. Run with clean args — no stale AsyncContext to override .run()\r\n let fnResult: Result<unknown>;\r\n try {\r\n const value = childAsyncCtx.run(() =>\r\n this._impl.call(instance, ...argsWithoutCtx)\r\n );\r\n const resolved = value instanceof Promise ? await value : value;\r\n fnResult = result(resolved);\r\n } catch (e) {\r\n fnResult = errorResult(e);\r\n }\r\n\r\n newComputed.setOutput(fnResult);\r\n\r\n return newComputed;\r\n });\r\n\r\n // Register dependency from caller to the produced computed\r\n callerComputeCtx?.captureDependency(computed);\r\n return computed;\r\n }\r\n}\r\n","import { ComputeFunction } from './compute-function.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\n\r\nconst METHODS_META = Symbol.for('actuallab.methods');\r\n\r\nexport interface MethodMeta {\r\n argCount: number;\r\n compute?: boolean;\r\n stream?: boolean;\r\n}\r\n\r\n/** Read method metadata from a decorated class. */\r\nexport function getMethodsMeta(\r\n cls: abstract new (...args: any[]) => any\r\n): Record<string, MethodMeta> | undefined {\r\n return (cls as any)[Symbol.metadata]?.[METHODS_META];\r\n}\r\n\r\n/** Method decorator — wraps a method to route through ComputeFunction for caching and dependency tracking. */\r\nexport function computeMethod<This, Args extends unknown[], Return>(\r\n target: (this: This, ...args: Args) => Return,\r\n context: ClassMethodDecoratorContext<\r\n This,\r\n (this: This, ...args: Args) => Return\r\n >\r\n): (this: This, ...args: Args) => Return {\r\n const methodName = String(context.name);\r\n\r\n // Store metadata\r\n const methods: Record<string, MethodMeta> = ((context.metadata as any)[\r\n METHODS_META\r\n ] ??= {});\r\n methods[methodName] = {\r\n ...methods[methodName],\r\n compute: true,\r\n argCount: target.length,\r\n };\r\n\r\n // ONE ComputeFunction per class×method — created at decoration time\r\n const cf = new ComputeFunction(methodName, target as any);\r\n\r\n // Prototype-level replacement — unwraps Computed to return the value directly\r\n const replacement = function (this: This, ...allArgs: Args): Return {\r\n return cf.invoke(this as object, allArgs).then(c => c.value) as Return;\r\n };\r\n\r\n // Per-instance setup: create bound method with .invalidate pre-bound\r\n context.addInitializer(function (this: This) {\r\n const instance = this;\r\n const boundMethod = (...allArgs: unknown[]) => {\r\n return cf.invoke(instance as object, allArgs).then(c => c.value);\r\n };\r\n (boundMethod as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(instance as object, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n (this as any)[methodName] = boundMethod;\r\n });\r\n\r\n return replacement;\r\n}\r\n\r\n/** Wrap a standalone function as a compute function with caching and .invalidate(). */\r\nexport function wrapComputeMethod<Args extends unknown[], Return>(\r\n fn: (...args: Args) => Return\r\n): ((...args: Args) => Promise<Return>) & {\r\n invalidate: (...args: Args) => void;\r\n} {\r\n const syntheticInstance = {};\r\n const methodName = fn.name || 'anonymous';\r\n const cf = new ComputeFunction(methodName, fn as any);\r\n\r\n const wrapped = (...allArgs: unknown[]) => {\r\n return cf\r\n .invoke(syntheticInstance, allArgs)\r\n .then(c => c.value as Return);\r\n };\r\n\r\n (wrapped as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(syntheticInstance, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n\r\n return wrapped as any;\r\n}\r\n","/** Controls when state re-computation happens after invalidation. */\r\nexport type UpdateDelayer = (abortSignal?: AbortSignal) => Promise<void>;\r\n\r\n/** Re-computes after a fixed delay in milliseconds. */\r\nexport class FixedDelayer {\r\n static readonly zero: UpdateDelayer = () => Promise.resolve();\r\n\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = FixedDelayer._cache.get(ms);\r\n if (delayer === undefined) {\r\n delayer = new FixedDelayer(ms).delay;\r\n FixedDelayer._cache.set(ms, delayer);\r\n }\r\n return delayer;\r\n }\r\n\r\n readonly ms: number;\r\n readonly delay: UpdateDelayer;\r\n\r\n constructor(ms: number) {\r\n this.ms = ms;\r\n this.delay =\r\n ms > 10_000\r\n ? (abortSignal?: AbortSignal) =>\r\n new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, this.ms);\r\n if (abortSignal === undefined) return;\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n return;\r\n }\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n },\r\n { once: true }\r\n );\r\n })\r\n : () =>\r\n new Promise<void>(resolve =>\r\n setTimeout(resolve, this.ms)\r\n );\r\n }\r\n}\r\n\r\nexport const defaultUpdateDelayer: UpdateDelayer = FixedDelayer.get(1000 / 60);\r\n","import { EventHandlerSet } from '@actuallab/core';\r\n\r\n/** Singleton tracking active UI commands — mirrors .NET's UIActionTracker. */\r\nexport class UIActionTracker {\r\n private _activeCount = 0;\r\n readonly changed = new EventHandlerSet<void>();\r\n readonly errors: unknown[] = [];\r\n\r\n get isActive(): boolean {\r\n return this._activeCount > 0;\r\n }\r\n\r\n /** Run a command silently — errors are added to the error list but not thrown. */\r\n async run(fn: () => Promise<unknown>): Promise<void> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n } finally {\r\n this._activeCount--;\r\n // Buffer 50ms for invalidations to arrive before signaling completion\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n /** Call a command and return the result — errors are added to the error list AND thrown. */\r\n async call<T>(fn: () => Promise<T>): Promise<T> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n return await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n throw e;\r\n } finally {\r\n this._activeCount--;\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n dismissError(index: number): void {\r\n if (index >= 0 && index < this.errors.length) {\r\n this.errors.splice(index, 1);\r\n this.changed.trigger();\r\n }\r\n }\r\n}\r\n\r\nexport const uiActions = new UIActionTracker();\r\n","import { uiActions } from './ui-action-tracker.js';\r\nimport { FixedDelayer, type UpdateDelayer } from './update-delayer.js';\r\n\r\n/** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */\r\nexport class UIUpdateDelayer {\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = UIUpdateDelayer._cache.get(ms);\r\n if (delayer !== undefined) return delayer;\r\n\r\n const t = uiActions;\r\n delayer = (abortSignal?: AbortSignal) => {\r\n if (t.isActive) return Promise.resolve();\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, ms);\r\n\r\n // Cancel delay when tracker becomes active\r\n const onChanged = () => {\r\n if (t.isActive) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n resolve();\r\n }\r\n };\r\n t.changed.add(onChanged);\r\n\r\n if (abortSignal !== undefined) {\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n return;\r\n }\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n },\r\n { once: true }\r\n );\r\n }\r\n });\r\n };\r\n UIUpdateDelayer._cache.set(ms, delayer);\r\n return delayer;\r\n }\r\n}\r\n","import {\r\n type AsyncContext,\r\n type IResult,\r\n PromiseSource,\r\n resolvedVoidPromise,\r\n type Result,\r\n} from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\n\r\n/** Base class for all reactive state types. */\r\nexport abstract class State<T> implements IResult<T> {\r\n protected _computed!: Computed<T>;\r\n protected _updateIndex = 0;\r\n protected _lastNonErrorValue: T | undefined;\r\n private _whenUpdatedSource: PromiseSource<void> | null = null;\r\n\r\n get updateIndex(): number {\r\n return this._updateIndex;\r\n }\r\n\r\n get lastNonErrorValue(): T | undefined {\r\n return this._lastNonErrorValue;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this._computed.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this._computed.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this._computed.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this._computed.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this._computed.valueOrUndefined;\r\n }\r\n\r\n get output(): Result<T> {\r\n return this._computed.output;\r\n }\r\n\r\n get computed(): Computed<T> {\r\n return this._computed;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n return this._computed.use(asyncContext);\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n return this._computed.useInconsistent(asyncContext);\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n return this._computed.update();\r\n }\r\n\r\n recompute(): Computed<T> | Promise<Computed<T>> {\r\n this._computed.invalidate();\r\n return this.update();\r\n }\r\n\r\n whenInvalidated(): Promise<void> {\r\n return this._computed.whenInvalidated();\r\n }\r\n\r\n whenUpdated(): Promise<void> {\r\n return (this._whenUpdatedSource ??= new PromiseSource<void>()).promise;\r\n }\r\n\r\n whenFirstTimeUpdated(): Promise<void> {\r\n return this._updateIndex > 0 ? resolvedVoidPromise : this.whenUpdated();\r\n }\r\n\r\n protected _initialize(\r\n output: Result<T> | T,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>\r\n ): void {\r\n this._computed = new StateBoundComputed<T>(this, renewer);\r\n this._computed.setOutput(output);\r\n this._lastNonErrorValue = this._computed.valueOrUndefined;\r\n }\r\n\r\n protected _update(computed: Computed<T>, output: Result<T> | T): void {\r\n computed.setOutput(output);\r\n this._computed = computed;\r\n if (computed.hasValue) this._lastNonErrorValue = computed.value;\r\n this._updateIndex++;\r\n this._whenUpdatedSource?.resolve(undefined);\r\n this._whenUpdatedSource = null;\r\n }\r\n}\r\n","import {\r\n AsyncContext,\r\n PromiseSource,\r\n type Result,\r\n result,\r\n errorResult,\r\n} from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from './update-delayer.js';\r\nimport { State } from './state.js';\r\n\r\nexport type StateComputer<T> = () => T | Promise<T>;\r\n\r\n/** Constructor options for ComputedState. */\r\nexport interface ComputedStateOptions<T> {\r\n initialValue?: T;\r\n initialOutput?: Result<T>;\r\n updateDelayer?: UpdateDelayer;\r\n}\r\n\r\n/** Auto-updating reactive state wrapper — re-computes on invalidation with configurable delay. */\r\nexport class ComputedState<T> extends State<T> {\r\n private _computer: StateComputer<T>;\r\n private _updateDelayer: UpdateDelayer;\r\n private _disposeController: AbortController;\r\n private _cancelDelaySource = new PromiseSource<void>();\r\n private _renewer: () => Computed<T> | Promise<Computed<T>>;\r\n private _hasOutput = false;\r\n\r\n constructor(computer: StateComputer<T>, options?: ComputedStateOptions<T>) {\r\n super();\r\n this._computer = computer;\r\n this._updateDelayer = options?.updateDelayer ?? defaultUpdateDelayer;\r\n this._disposeController = new AbortController();\r\n this._renewer = async () => {\r\n const whenUpdated = this.whenUpdated();\r\n this._cancelDelaySource.resolve(undefined);\r\n await whenUpdated;\r\n return this._computed;\r\n };\r\n\r\n // Create initial computed — _updateCycle will replace it on first iteration\r\n if (\r\n options?.initialOutput !== undefined ||\r\n options?.initialValue !== undefined\r\n ) {\r\n this._initialize(\r\n options.initialOutput ?? (options.initialValue as T),\r\n this._renewer\r\n );\r\n this._hasOutput = true;\r\n }\r\n // else: _computed stays unset until _updateCycle calls _update()\r\n\r\n void this._updateCycle();\r\n }\r\n\r\n override get hasValue(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasValue;\r\n }\r\n\r\n override get hasError(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasError;\r\n }\r\n\r\n override get value(): T {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has no value yet.');\r\n if (this._computed.hasValue) return this._computed.value;\r\n if (this._lastNonErrorValue !== undefined)\r\n return this._lastNonErrorValue;\r\n throw new Error('ComputedState has no value yet.');\r\n }\r\n\r\n override get error(): unknown {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.error;\r\n }\r\n\r\n override get valueOrUndefined(): T | undefined {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.valueOrUndefined ?? this._lastNonErrorValue;\r\n }\r\n\r\n override get output(): Result<T> {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has no output yet.');\r\n return this._computed.output;\r\n }\r\n\r\n override get computed(): Computed<T> {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has not been computed yet.');\r\n return this._computed;\r\n }\r\n\r\n get isDisposed(): boolean {\r\n return this._disposeController.signal.aborted;\r\n }\r\n\r\n dispose(): void {\r\n if (!this.isDisposed) this._disposeController.abort();\r\n }\r\n\r\n private async _updateCycle(): Promise<void> {\r\n const disposeSignal = this._disposeController.signal;\r\n try {\r\n while (!disposeSignal.aborted) {\r\n // Compute\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n const computeCtx = new ComputeContext(\r\n computed as StateBoundComputed<unknown>\r\n );\r\n const asyncCtx = (\r\n AsyncContext.current ?? AsyncContext.empty\r\n ).with(computeContextKey, computeCtx);\r\n\r\n let output: Result<T>;\r\n try {\r\n const value = asyncCtx.run(() => this._computer());\r\n const resolved =\r\n value instanceof Promise ? await value : value;\r\n output = result(resolved);\r\n } catch (e) {\r\n output = errorResult(e);\r\n }\r\n this._update(computed, output);\r\n if (this._cancelDelaySource.isCompleted)\r\n this._cancelDelaySource = new PromiseSource<void>();\r\n\r\n // Wait for invalidation (or cancellation via dispose)\r\n try {\r\n await computed.whenInvalidated(disposeSignal);\r\n } catch {\r\n return; // Cancelled via dispose\r\n }\r\n\r\n // Wait for delay (cancellable by renewer)\r\n await Promise.race([\r\n this._updateDelayer(disposeSignal),\r\n this._cancelDelaySource.promise,\r\n ]);\r\n }\r\n } catch {\r\n // Intended, do nothing\r\n }\r\n }\r\n}\r\n","import { type AsyncContext, Result } from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\nimport { State } from './state.js';\r\n\r\n/** Manually-settable reactive state that can participate in the Fusion dependency graph. */\r\nexport class MutableState<T> extends State<T> {\r\n private _renewer = (): Computed<T> => {\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n this._update(computed, this._computed.output);\r\n return computed;\r\n };\r\n\r\n constructor(initialOutput: Result<T> | T) {\r\n super();\r\n this._initialize(initialOutput, this._renewer);\r\n }\r\n\r\n override use(asyncContext?: AsyncContext): T {\r\n return this._computed.use(asyncContext) as T;\r\n }\r\n\r\n set(output: Result<T> | T): void {\r\n this._computed.invalidate();\r\n this._update(new StateBoundComputed<T>(this, this._renewer), output);\r\n }\r\n}\r\n"],"mappings":"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","names":["import_core","ConsistencyState","import_core","import_core","import_core","import_core","import_core"]}
package/dist/index.d.cts CHANGED
@@ -43,7 +43,6 @@ declare class Computed<T> implements IResult<T> {
43
43
  }
44
44
  /** Computed variant for State types — skips registry registration since the State holds a direct reference. */
45
45
  declare class StateBoundComputed<T> extends Computed<T> {
46
- constructor(state: State<T>, renewer?: () => Computed<T> | Promise<Computed<T>>);
47
46
  protected _latest(): Computed<T> | undefined;
48
47
  protected _register(): void;
49
48
  protected _unregister(): void;
@@ -145,7 +144,7 @@ declare class FixedDelayer {
145
144
  readonly delay: UpdateDelayer;
146
145
  constructor(ms: number);
147
146
  }
148
- declare let defaultUpdateDelayer: UpdateDelayer;
147
+ declare const defaultUpdateDelayer: UpdateDelayer;
149
148
 
150
149
  /** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */
151
150
  declare class UIUpdateDelayer {
@@ -165,7 +164,7 @@ declare class UIActionTracker {
165
164
  call<T>(fn: () => Promise<T>): Promise<T>;
166
165
  dismissError(index: number): void;
167
166
  }
168
- declare let uiActions: UIActionTracker;
167
+ declare const uiActions: UIActionTracker;
169
168
 
170
169
  type StateComputer<T> = () => T | Promise<T>;
171
170
  /** Constructor options for ComputedState. */
package/dist/index.d.ts CHANGED
@@ -43,7 +43,6 @@ declare class Computed<T> implements IResult<T> {
43
43
  }
44
44
  /** Computed variant for State types — skips registry registration since the State holds a direct reference. */
45
45
  declare class StateBoundComputed<T> extends Computed<T> {
46
- constructor(state: State<T>, renewer?: () => Computed<T> | Promise<Computed<T>>);
47
46
  protected _latest(): Computed<T> | undefined;
48
47
  protected _register(): void;
49
48
  protected _unregister(): void;
@@ -145,7 +144,7 @@ declare class FixedDelayer {
145
144
  readonly delay: UpdateDelayer;
146
145
  constructor(ms: number);
147
146
  }
148
- declare let defaultUpdateDelayer: UpdateDelayer;
147
+ declare const defaultUpdateDelayer: UpdateDelayer;
149
148
 
150
149
  /** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */
151
150
  declare class UIUpdateDelayer {
@@ -165,7 +164,7 @@ declare class UIActionTracker {
165
164
  call<T>(fn: () => Promise<T>): Promise<T>;
166
165
  dismissError(index: number): void;
167
166
  }
168
- declare let uiActions: UIActionTracker;
167
+ declare const uiActions: UIActionTracker;
169
168
 
170
169
  type StateComputer<T> = () => T | Promise<T>;
171
170
  /** Constructor options for ComputedState. */
package/dist/index.js CHANGED
@@ -11,7 +11,13 @@ function getInstanceId(instance) {
11
11
  }
12
12
 
13
13
  // src/computed.ts
14
- import { AsyncContext as AsyncContext2, EventHandlerSet, PromiseSource, Result, result } from "@actuallab/core";
14
+ import {
15
+ AsyncContext as AsyncContext2,
16
+ EventHandlerSet,
17
+ PromiseSource,
18
+ Result,
19
+ result
20
+ } from "@actuallab/core";
15
21
 
16
22
  // src/computed-registry.ts
17
23
  var ComputedRegistry = class _ComputedRegistry {
@@ -84,11 +90,16 @@ var Computed = class _Computed {
84
90
  static async capture(fn) {
85
91
  const captureComputed = new _Computed("__capture__");
86
92
  const captureCtx = new ComputeContext(captureComputed);
87
- const asyncCtx = AsyncContext2.getOrCreate().with(computeContextKey, captureCtx);
93
+ const asyncCtx = AsyncContext2.getOrCreate().with(
94
+ computeContextKey,
95
+ captureCtx
96
+ );
88
97
  await asyncCtx.run(fn);
89
98
  const deps = captureComputed.dependencies;
90
99
  if (deps.size === 0)
91
- throw new Error("No Computed was captured \u2014 fn must call a compute function.");
100
+ throw new Error(
101
+ "No Computed was captured \u2014 fn must call a compute function."
102
+ );
92
103
  return deps.values().next().value;
93
104
  }
94
105
  input;
@@ -109,7 +120,8 @@ var Computed = class _Computed {
109
120
  return this._version;
110
121
  }
111
122
  get output() {
112
- if (this._output === void 0) throw new Error("Computed has no output yet.");
123
+ if (this._output === void 0)
124
+ throw new Error("Computed has no output yet.");
113
125
  return this._output;
114
126
  }
115
127
  get hasValue() {
@@ -141,7 +153,9 @@ var Computed = class _Computed {
141
153
  const latest = this._latest();
142
154
  if (latest?.isConsistent) return latest;
143
155
  if (this._renewer !== void 0) return this._renewer();
144
- throw new Error("Cannot recompute: Computed is invalidated and has no renewer.");
156
+ throw new Error(
157
+ "Cannot recompute: Computed is invalidated and has no renewer."
158
+ );
145
159
  }
146
160
  _latest() {
147
161
  return ComputedRegistry.get(this.input);
@@ -159,7 +173,9 @@ var Computed = class _Computed {
159
173
  return updated.value;
160
174
  }
161
175
  useInconsistent(asyncContext) {
162
- ComputeContext.from(asyncContext)?.captureDependency(this);
176
+ ComputeContext.from(asyncContext)?.captureDependency(
177
+ this
178
+ );
163
179
  return this.value;
164
180
  }
165
181
  setOutput(output) {
@@ -169,7 +185,10 @@ var Computed = class _Computed {
169
185
  this._state = 1 /* Consistent */;
170
186
  this._register();
171
187
  if (this._output.hasError && _Computed.errorAutoInvalidateDelay > 0)
172
- setTimeout(() => this.invalidate(), _Computed.errorAutoInvalidateDelay);
188
+ setTimeout(
189
+ () => this.invalidate(),
190
+ _Computed.errorAutoInvalidateDelay
191
+ );
173
192
  }
174
193
  _register() {
175
194
  ComputedRegistry.register(this);
@@ -197,22 +216,26 @@ var Computed = class _Computed {
197
216
  const handler = () => ps.resolve(void 0);
198
217
  this.onInvalidated.add(handler);
199
218
  if (abortSignal !== void 0 && !abortSignal.aborted) {
200
- abortSignal.addEventListener("abort", () => {
201
- this.onInvalidated.remove(handler);
202
- ps.reject(abortSignal.reason);
203
- }, { once: true });
219
+ abortSignal.addEventListener(
220
+ "abort",
221
+ () => {
222
+ this.onInvalidated.remove(handler);
223
+ ps.reject(abortSignal.reason);
224
+ },
225
+ { once: true }
226
+ );
204
227
  }
205
228
  return ps.promise;
206
229
  }
207
230
  addDependency(dependency) {
208
231
  this._dependencies.add(dependency);
209
- dependency._dependants.set(this._version, new WeakRef(this));
232
+ dependency._dependants.set(
233
+ this._version,
234
+ new WeakRef(this)
235
+ );
210
236
  }
211
237
  };
212
238
  var StateBoundComputed = class extends Computed {
213
- constructor(state, renewer) {
214
- super(state, renewer);
215
- }
216
239
  _latest() {
217
240
  return this.input.computed;
218
241
  }
@@ -223,7 +246,12 @@ var StateBoundComputed = class extends Computed {
223
246
  };
224
247
 
225
248
  // src/compute-function.ts
226
- import { AsyncContext as AsyncContext3, AsyncLock, result as result2, errorResult } from "@actuallab/core";
249
+ import {
250
+ AsyncContext as AsyncContext3,
251
+ AsyncLock,
252
+ result as result2,
253
+ errorResult
254
+ } from "@actuallab/core";
227
255
  var RS = "";
228
256
  function defaultArgToString(arg) {
229
257
  return JSON.stringify(arg) ?? "undefined";
@@ -270,10 +298,15 @@ var ComputeFunction = class {
270
298
  const renewer = prevComputed?._renewer ?? (() => this.invoke(instance, argsWithoutCtx, newComputed));
271
299
  newComputed = new Computed(key, renewer);
272
300
  const childComputeCtx = new ComputeContext(newComputed);
273
- const childAsyncCtx = (asyncCtx ?? AsyncContext3.empty).with(computeContextKey, childComputeCtx);
301
+ const childAsyncCtx = (asyncCtx ?? AsyncContext3.empty).with(
302
+ computeContextKey,
303
+ childComputeCtx
304
+ );
274
305
  let fnResult;
275
306
  try {
276
- const value = childAsyncCtx.run(() => this._impl.call(instance, ...argsWithoutCtx));
307
+ const value = childAsyncCtx.run(
308
+ () => this._impl.call(instance, ...argsWithoutCtx)
309
+ );
277
310
  const resolved = value instanceof Promise ? await value : value;
278
311
  fnResult = result2(resolved);
279
312
  } catch (e) {
@@ -295,7 +328,11 @@ function getMethodsMeta(cls) {
295
328
  function computeMethod(target, context) {
296
329
  const methodName = String(context.name);
297
330
  const methods = context.metadata[METHODS_META] ??= {};
298
- methods[methodName] = { ...methods[methodName], compute: true, argCount: target.length };
331
+ methods[methodName] = {
332
+ ...methods[methodName],
333
+ compute: true,
334
+ argCount: target.length
335
+ };
299
336
  const cf = new ComputeFunction(methodName, target);
300
337
  const replacement = function(...allArgs) {
301
338
  return cf.invoke(this, allArgs).then((c) => c.value);
@@ -349,14 +386,20 @@ var FixedDelayer = class _FixedDelayer {
349
386
  if (abortSignal === void 0) return;
350
387
  if (abortSignal.aborted) {
351
388
  clearTimeout(timer);
352
- reject(abortSignal.reason);
389
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
353
390
  return;
354
391
  }
355
- abortSignal.addEventListener("abort", () => {
356
- clearTimeout(timer);
357
- reject(abortSignal.reason);
358
- }, { once: true });
359
- }) : () => new Promise((resolve) => setTimeout(resolve, this.ms));
392
+ abortSignal.addEventListener(
393
+ "abort",
394
+ () => {
395
+ clearTimeout(timer);
396
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
397
+ },
398
+ { once: true }
399
+ );
400
+ }) : () => new Promise(
401
+ (resolve) => setTimeout(resolve, this.ms)
402
+ );
360
403
  }
361
404
  };
362
405
  var defaultUpdateDelayer = FixedDelayer.get(1e3 / 60);
@@ -417,8 +460,7 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
417
460
  if (delayer !== void 0) return delayer;
418
461
  const t = uiActions;
419
462
  delayer = (abortSignal) => {
420
- if (t.isActive)
421
- return Promise.resolve();
463
+ if (t.isActive) return Promise.resolve();
422
464
  return new Promise((resolve, reject) => {
423
465
  const timer = setTimeout(resolve, ms);
424
466
  const onChanged = () => {
@@ -433,14 +475,18 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
433
475
  if (abortSignal.aborted) {
434
476
  clearTimeout(timer);
435
477
  t.changed.remove(onChanged);
436
- reject(abortSignal.reason);
478
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
437
479
  return;
438
480
  }
439
- abortSignal.addEventListener("abort", () => {
440
- clearTimeout(timer);
441
- t.changed.remove(onChanged);
442
- reject(abortSignal.reason);
443
- }, { once: true });
481
+ abortSignal.addEventListener(
482
+ "abort",
483
+ () => {
484
+ clearTimeout(timer);
485
+ t.changed.remove(onChanged);
486
+ reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));
487
+ },
488
+ { once: true }
489
+ );
444
490
  }
445
491
  });
446
492
  };
@@ -450,7 +496,10 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
450
496
  };
451
497
 
452
498
  // src/state.ts
453
- import { PromiseSource as PromiseSource2, resolvedVoidPromise } from "@actuallab/core";
499
+ import {
500
+ PromiseSource as PromiseSource2,
501
+ resolvedVoidPromise
502
+ } from "@actuallab/core";
454
503
  var State = class {
455
504
  _computed;
456
505
  _updateIndex = 0;
@@ -513,8 +562,7 @@ var State = class {
513
562
  _update(computed, output) {
514
563
  computed.setOutput(output);
515
564
  this._computed = computed;
516
- if (computed.hasValue)
517
- this._lastNonErrorValue = computed.value;
565
+ if (computed.hasValue) this._lastNonErrorValue = computed.value;
518
566
  this._updateIndex++;
519
567
  this._whenUpdatedSource?.resolve(void 0);
520
568
  this._whenUpdatedSource = null;
@@ -522,7 +570,12 @@ var State = class {
522
570
  };
523
571
 
524
572
  // src/computed-state.ts
525
- import { AsyncContext as AsyncContext4, PromiseSource as PromiseSource3, result as result3, errorResult as errorResult2 } from "@actuallab/core";
573
+ import {
574
+ AsyncContext as AsyncContext4,
575
+ PromiseSource as PromiseSource3,
576
+ result as result3,
577
+ errorResult as errorResult2
578
+ } from "@actuallab/core";
526
579
  var ComputedState = class extends State {
527
580
  _computer;
528
581
  _updateDelayer;
@@ -542,7 +595,10 @@ var ComputedState = class extends State {
542
595
  return this._computed;
543
596
  };
544
597
  if (options?.initialOutput !== void 0 || options?.initialValue !== void 0) {
545
- this._initialize(options.initialOutput ?? options.initialValue, this._renewer);
598
+ this._initialize(
599
+ options.initialOutput ?? options.initialValue,
600
+ this._renewer
601
+ );
546
602
  this._hasOutput = true;
547
603
  }
548
604
  void this._updateCycle();
@@ -556,9 +612,11 @@ var ComputedState = class extends State {
556
612
  return this._computed.hasError;
557
613
  }
558
614
  get value() {
559
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has no value yet.");
615
+ if (!this._hasOutput && this._updateIndex === 0)
616
+ throw new Error("ComputedState has no value yet.");
560
617
  if (this._computed.hasValue) return this._computed.value;
561
- if (this._lastNonErrorValue !== void 0) return this._lastNonErrorValue;
618
+ if (this._lastNonErrorValue !== void 0)
619
+ return this._lastNonErrorValue;
562
620
  throw new Error("ComputedState has no value yet.");
563
621
  }
564
622
  get error() {
@@ -570,26 +628,29 @@ var ComputedState = class extends State {
570
628
  return this._computed.valueOrUndefined ?? this._lastNonErrorValue;
571
629
  }
572
630
  get output() {
573
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has no output yet.");
631
+ if (!this._hasOutput && this._updateIndex === 0)
632
+ throw new Error("ComputedState has no output yet.");
574
633
  return this._computed.output;
575
634
  }
576
635
  get computed() {
577
- if (!this._hasOutput && this._updateIndex === 0) throw new Error("ComputedState has not been computed yet.");
636
+ if (!this._hasOutput && this._updateIndex === 0)
637
+ throw new Error("ComputedState has not been computed yet.");
578
638
  return this._computed;
579
639
  }
580
640
  get isDisposed() {
581
641
  return this._disposeController.signal.aborted;
582
642
  }
583
643
  dispose() {
584
- if (!this.isDisposed)
585
- this._disposeController.abort();
644
+ if (!this.isDisposed) this._disposeController.abort();
586
645
  }
587
646
  async _updateCycle() {
588
647
  const disposeSignal = this._disposeController.signal;
589
648
  try {
590
649
  while (!disposeSignal.aborted) {
591
650
  const computed = new StateBoundComputed(this, this._renewer);
592
- const computeCtx = new ComputeContext(computed);
651
+ const computeCtx = new ComputeContext(
652
+ computed
653
+ );
593
654
  const asyncCtx = (AsyncContext4.current ?? AsyncContext4.empty).with(computeContextKey, computeCtx);
594
655
  let output;
595
656
  try {
@@ -612,7 +673,7 @@ var ComputedState = class extends State {
612
673
  this._cancelDelaySource.promise
613
674
  ]);
614
675
  }
615
- } catch (e) {
676
+ } catch {
616
677
  }
617
678
  }
618
679
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/computed-input.ts","../src/computed.ts","../src/computed-registry.ts","../src/compute-context.ts","../src/compute-function.ts","../src/compute-method.ts","../src/update-delayer.ts","../src/ui-action-tracker.ts","../src/ui-update-delayer.ts","../src/state.ts","../src/computed-state.ts","../src/mutable-state.ts"],"sourcesContent":["import type { State } from \"./state.js\";\r\n\r\n/** Auto-assigned numeric IDs for instance identity in compute method cache keys. */\r\nlet _nextInstanceId = 0;\r\nconst _instanceIds = new WeakMap<object, number>();\r\n\r\nexport function getInstanceId(instance: object): number {\r\n let id = _instanceIds.get(instance);\r\n if (id === undefined) {\r\n id = ++_nextInstanceId;\r\n _instanceIds.set(instance, id);\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Identity key for any computed value.\r\n * - String for compute method results (built from instance + function + args)\r\n * - State for state types (identity by reference)\r\n */\r\nexport type ComputedInput = string | State<any>;\r\n","import { AsyncContext, EventHandlerSet, type IResult, PromiseSource, Result, result } from \"@actuallab/core\";\r\nimport type { ComputedInput } from \"./computed-input.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport type { State } from \"./state.js\";\r\n\r\nlet _nextVersion = 0;\r\n\r\nexport const enum ConsistencyState {\r\n Computing = 0,\r\n Consistent = 1,\r\n Invalidated = 2,\r\n}\r\n\r\n/** Core Fusion abstraction — a cached computation with dependency tracking and invalidation. */\r\nexport class Computed<T> implements IResult<T> {\r\n /** Delay before auto-invalidating a Computed that holds an error result. 0 = disabled. */\r\n static errorAutoInvalidateDelay = 1000;\r\n\r\n /** Capture the Computed backing a computation — works with both local and RPC compute methods. */\r\n static async capture<T>(fn: () => T | Promise<T>): Promise<Computed<T>> {\r\n const captureComputed = new Computed<unknown>(\"__capture__\");\r\n const captureCtx = new ComputeContext(captureComputed);\r\n const asyncCtx = AsyncContext.getOrCreate().with(computeContextKey, captureCtx);\r\n await asyncCtx.run(fn);\r\n const deps = captureComputed.dependencies;\r\n if (deps.size === 0)\r\n throw new Error(\"No Computed was captured — fn must call a compute function.\");\r\n return deps.values().next().value! as Computed<T>;\r\n }\r\n\r\n readonly input: ComputedInput;\r\n private _version: number;\r\n private _state: ConsistencyState;\r\n private _output: Result<T> | undefined;\r\n private _dependencies = new Set<Computed<unknown>>();\r\n private _dependants = new Map<number, WeakRef<Computed<unknown>>>();\r\n readonly onInvalidated = new EventHandlerSet<void>();\r\n readonly _renewer: (() => Computed<T> | Promise<Computed<T>>) | undefined;\r\n\r\n constructor(\r\n input: ComputedInput,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>,\r\n ) {\r\n this.input = input;\r\n this._renewer = renewer;\r\n this._version = ++_nextVersion;\r\n this._state = ConsistencyState.Computing;\r\n }\r\n\r\n get version(): number {\r\n return this._version;\r\n }\r\n\r\n get output(): Result<T> {\r\n if (this._output === undefined) throw new Error(\"Computed has no output yet.\");\r\n return this._output;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this.output.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this.output.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this.output.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this.output.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.output.valueOrUndefined;\r\n }\r\n\r\n get state(): ConsistencyState {\r\n return this._state;\r\n }\r\n\r\n get isConsistent(): boolean {\r\n return this._state === ConsistencyState.Consistent;\r\n }\r\n\r\n get dependencies(): ReadonlySet<Computed<unknown>> {\r\n return this._dependencies;\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n if (this._state === ConsistencyState.Consistent) return this;\r\n const latest = this._latest();\r\n if (latest?.isConsistent) return latest;\r\n if (this._renewer !== undefined) return this._renewer();\r\n throw new Error(\"Cannot recompute: Computed is invalidated and has no renewer.\");\r\n }\r\n\r\n protected _latest(): Computed<T> | undefined {\r\n return ComputedRegistry.get(this.input as string) as Computed<T> | undefined;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n const ctx = ComputeContext.from(asyncContext);\r\n const updated = this.update();\r\n if (updated instanceof Promise) {\r\n return updated.then((c) => {\r\n ctx?.captureDependency(c as Computed<unknown>);\r\n return c.value;\r\n });\r\n }\r\n ctx?.captureDependency(updated as Computed<unknown>);\r\n return updated.value;\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n ComputeContext.from(asyncContext)?.captureDependency(this as Computed<unknown>);\r\n return this.value;\r\n }\r\n\r\n setOutput(output: Result<T> | T): void {\r\n if (this._state !== ConsistencyState.Computing)\r\n throw new Error(\"Cannot set output on a non-computing Computed.\");\r\n this._output = output instanceof Result ? output : result(output);\r\n this._state = ConsistencyState.Consistent;\r\n this._register();\r\n if (this._output.hasError && Computed.errorAutoInvalidateDelay > 0)\r\n setTimeout(() => this.invalidate(), Computed.errorAutoInvalidateDelay);\r\n }\r\n\r\n protected _register(): void {\r\n ComputedRegistry.register(this as Computed<unknown>);\r\n }\r\n\r\n protected _unregister(): void {\r\n ComputedRegistry.unregister(this as Computed<unknown>);\r\n }\r\n\r\n invalidate(): void {\r\n if (this._state === ConsistencyState.Invalidated) return;\r\n this._state = ConsistencyState.Invalidated;\r\n\r\n // Clear forward references\r\n this._dependencies.clear();\r\n\r\n // Notify dependants via WeakRef backward references\r\n for (const [, ref] of this._dependants) {\r\n const dependant = ref.deref();\r\n if (dependant != null) dependant.invalidate();\r\n }\r\n this._dependants.clear();\r\n\r\n this.onInvalidated.trigger();\r\n this.onInvalidated.clear();\r\n\r\n this._unregister();\r\n }\r\n\r\n whenInvalidated(abortSignal?: AbortSignal): Promise<void> {\r\n if (this._state === ConsistencyState.Invalidated)\r\n return Promise.resolve();\r\n\r\n const ps = new PromiseSource<void>();\r\n const handler = () => ps.resolve(undefined);\r\n this.onInvalidated.add(handler);\r\n\r\n if (abortSignal !== undefined && !abortSignal.aborted) {\r\n abortSignal.addEventListener(\"abort\", () => {\r\n this.onInvalidated.remove(handler);\r\n ps.reject(abortSignal.reason);\r\n }, { once: true });\r\n }\r\n\r\n return ps.promise;\r\n }\r\n\r\n addDependency(dependency: Computed<unknown>): void {\r\n this._dependencies.add(dependency);\r\n dependency._dependants.set(this._version, new WeakRef(this as Computed<unknown>));\r\n }\r\n}\r\n\r\n/** Computed variant for State types — skips registry registration since the State holds a direct reference. */\r\nexport class StateBoundComputed<T> extends Computed<T> {\r\n constructor(state: State<T>, renewer?: () => Computed<T> | Promise<Computed<T>>) {\r\n super(state, renewer);\r\n }\r\n\r\n protected override _latest(): Computed<T> | undefined {\r\n return (this.input as State<T>).computed;\r\n }\r\n\r\n protected override _register(): void {\r\n // No registration — state holds direct reference\r\n }\r\n\r\n protected override _unregister(): void {\r\n // No unregistration — was never registered\r\n }\r\n}\r\n","import type { Computed } from \"./computed.js\";\r\n\r\n/** WeakRef-based global cache of Computed instances — allows GC of unused computed values. */\r\nexport class ComputedRegistry {\r\n private static _entries = new Map<string, WeakRef<Computed<unknown>>>();\r\n private static _finalization = new FinalizationRegistry<string>((key) => {\r\n ComputedRegistry._entries.delete(key);\r\n });\r\n\r\n static get size(): number {\r\n return ComputedRegistry._entries.size;\r\n }\r\n\r\n static get(key: string): Computed<unknown> | undefined {\r\n const ref = ComputedRegistry._entries.get(key);\r\n if (ref === undefined) return undefined;\r\n const computed = ref.deref();\r\n if (computed === undefined) {\r\n ComputedRegistry._entries.delete(key);\r\n return undefined;\r\n }\r\n return computed;\r\n }\r\n\r\n static register(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.set(key, new WeakRef(computed));\r\n ComputedRegistry._finalization.register(computed, key, computed);\r\n }\r\n\r\n static unregister(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.delete(key);\r\n ComputedRegistry._finalization.unregister(computed);\r\n }\r\n}\r\n","import { AsyncContext, AsyncContextKey } from \"@actuallab/core\";\r\nimport type { Computed } from \"./computed.js\";\r\n\r\nexport const computeContextKey =\r\n new AsyncContextKey<ComputeContext | undefined>(\"ComputeContext\", undefined);\r\n\r\n/** Tracks the currently executing computation and captures dependencies. */\r\nexport class ComputeContext {\r\n readonly computed: Computed<unknown>;\r\n private _isCapturing = true;\r\n\r\n constructor(computed: Computed<unknown>) {\r\n this.computed = computed;\r\n }\r\n\r\n get isCapturing(): boolean {\r\n return this._isCapturing;\r\n }\r\n\r\n stopCapturing(): void {\r\n this._isCapturing = false;\r\n }\r\n\r\n captureDependency(dependency: Computed<unknown>): void {\r\n if (!this._isCapturing) return;\r\n this.computed.addDependency(dependency);\r\n }\r\n\r\n /** Resolve ComputeContext from an AsyncContext (or current). */\r\n static from(ctx: AsyncContext | undefined): ComputeContext | undefined {\r\n return AsyncContext.from(ctx)?.get(computeContextKey);\r\n }\r\n}\r\n","import { AsyncContext, AsyncLock, type Result, result, errorResult } from \"@actuallab/core\";\r\nimport { Computed } from \"./computed.js\";\r\nimport { getInstanceId } from \"./computed-input.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\n\r\nexport type ComputeFunctionImpl = (this: any, ...args: unknown[]) => unknown;\r\n\r\n/** Record Separator — delimiter between key components. */\r\nconst RS = \"\\x1E\";\r\n\r\nfunction defaultArgToString(arg: unknown): string {\r\n return JSON.stringify(arg) ?? \"undefined\";\r\n}\r\n\r\nlet _nextFunctionId = 0;\r\n\r\n/** Produces Computed<T> from a function — handles cache lookup, locking, dependency capture. */\r\nexport class ComputeFunction {\r\n readonly methodName: string;\r\n readonly id: string;\r\n argToString: (arg: unknown) => string = defaultArgToString;\r\n private _impl: ComputeFunctionImpl;\r\n private _locks = new Map<string, AsyncLock>();\r\n\r\n constructor(methodName: string, impl: ComputeFunctionImpl) {\r\n this.methodName = methodName;\r\n this.id = `${methodName}[${++_nextFunctionId}]`;\r\n this._impl = impl;\r\n }\r\n\r\n /** Build a string key for the given instance and arguments. */\r\n buildKey(instance: object, args: unknown[]): string {\r\n let key = String(getInstanceId(instance)) + RS + this.id;\r\n for (const arg of args) {\r\n key += RS + this.argToString(arg);\r\n }\r\n return key;\r\n }\r\n\r\n async invoke(instance: object, args: unknown[], prevComputed?: Computed<unknown>): Promise<Computed<unknown>> {\r\n // 1. Resolve AsyncContext ONCE via DRY helper\r\n const asyncCtx = AsyncContext.fromArgs(args);\r\n\r\n // 2. Pull caller's ComputeContext directly\r\n const callerComputeCtx = asyncCtx?.get(computeContextKey);\r\n\r\n // 3. Strip THIS context from args (reference equality — safe)\r\n const argsWithoutCtx = asyncCtx?.stripFromArgs(args) ?? args;\r\n\r\n // 4. Build string key and check cache\r\n const key = this.buildKey(instance, argsWithoutCtx);\r\n const existing = ComputedRegistry.get(key);\r\n if (existing?.isConsistent) {\r\n callerComputeCtx?.captureDependency(existing);\r\n return existing;\r\n }\r\n\r\n // 5. Lock per key to prevent duplicate computations\r\n let lock = this._locks.get(key);\r\n if (lock === undefined) {\r\n lock = new AsyncLock();\r\n this._locks.set(key, lock);\r\n }\r\n\r\n const computed = await lock.run(async () => {\r\n // Double-check after acquiring lock\r\n const cached = ComputedRegistry.get(key);\r\n if (cached?.isConsistent) return cached;\r\n\r\n // 6. Create new Computed + ComputeContext\r\n let newComputed: Computed<unknown>;\r\n const renewer = prevComputed?._renewer ?? (() => this.invoke(instance, argsWithoutCtx, newComputed));\r\n newComputed = new Computed<unknown>(key, renewer);\r\n\r\n const childComputeCtx = new ComputeContext(newComputed);\r\n const childAsyncCtx = (asyncCtx ?? AsyncContext.empty)\r\n .with(computeContextKey, childComputeCtx);\r\n\r\n // 7. Run with clean args — no stale AsyncContext to override .run()\r\n let fnResult: Result<unknown>;\r\n try {\r\n const value = childAsyncCtx.run(() => this._impl.call(instance, ...argsWithoutCtx));\r\n const resolved = value instanceof Promise ? await value : value;\r\n fnResult = result(resolved);\r\n } catch (e) {\r\n fnResult = errorResult(e);\r\n }\r\n\r\n newComputed.setOutput(fnResult);\r\n\r\n return newComputed;\r\n });\r\n\r\n // Register dependency from caller to the produced computed\r\n callerComputeCtx?.captureDependency(computed);\r\n return computed;\r\n }\r\n}\r\n","import { ComputeFunction } from \"./compute-function.js\";\r\nimport { ComputedRegistry } from \"./computed-registry.js\";\r\n\r\nconst METHODS_META = Symbol.for(\"actuallab.methods\");\r\n\r\nexport interface MethodMeta {\r\n argCount: number;\r\n compute?: boolean;\r\n stream?: boolean;\r\n}\r\n\r\n/** Read method metadata from a decorated class. */\r\nexport function getMethodsMeta(cls: abstract new (...args: any[]) => any): Record<string, MethodMeta> | undefined {\r\n return (cls as any)[Symbol.metadata]?.[METHODS_META];\r\n}\r\n\r\n/** Method decorator — wraps a method to route through ComputeFunction for caching and dependency tracking. */\r\nexport function computeMethod<This, Args extends unknown[], Return>(\r\n target: (this: This, ...args: Args) => Return,\r\n context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,\r\n): (this: This, ...args: Args) => Return {\r\n const methodName = String(context.name);\r\n\r\n // Store metadata\r\n const methods: Record<string, MethodMeta> = ((context.metadata as any)[METHODS_META] ??= {});\r\n methods[methodName] = { ...methods[methodName], compute: true, argCount: target.length };\r\n\r\n // ONE ComputeFunction per class×method — created at decoration time\r\n const cf = new ComputeFunction(methodName, target as any);\r\n\r\n // Prototype-level replacement — unwraps Computed to return the value directly\r\n const replacement = function(this: This, ...allArgs: Args): Return {\r\n return cf.invoke(this as object, allArgs).then(c => c.value) as Return;\r\n };\r\n\r\n // Per-instance setup: create bound method with .invalidate pre-bound\r\n context.addInitializer(function(this: This) {\r\n const instance = this;\r\n const boundMethod = (...allArgs: unknown[]) => {\r\n return cf.invoke(instance as object, allArgs).then(c => c.value);\r\n };\r\n (boundMethod as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(instance as object, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n (this as any)[methodName] = boundMethod;\r\n });\r\n\r\n return replacement;\r\n}\r\n\r\n/** Wrap a standalone function as a compute function with caching and .invalidate(). */\r\nexport function wrapComputeMethod<Args extends unknown[], Return>(\r\n fn: (...args: Args) => Return,\r\n): ((...args: Args) => Promise<Return>) & { invalidate: (...args: Args) => void } {\r\n const syntheticInstance = {};\r\n const methodName = fn.name || \"anonymous\";\r\n const cf = new ComputeFunction(methodName, fn as any);\r\n\r\n const wrapped = (...allArgs: unknown[]) => {\r\n return cf.invoke(syntheticInstance, allArgs).then(c => c.value as Return);\r\n };\r\n\r\n (wrapped as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(syntheticInstance, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n\r\n return wrapped as any;\r\n}\r\n","/** Controls when state re-computation happens after invalidation. */\r\nexport type UpdateDelayer = (abortSignal?: AbortSignal) => Promise<void>;\r\n\r\n/** Re-computes after a fixed delay in milliseconds. */\r\nexport class FixedDelayer {\r\n static readonly zero: UpdateDelayer = () => Promise.resolve();\r\n\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = FixedDelayer._cache.get(ms);\r\n if (delayer === undefined) {\r\n delayer = new FixedDelayer(ms).delay;\r\n FixedDelayer._cache.set(ms, delayer);\r\n }\r\n return delayer;\r\n }\r\n\r\n readonly ms: number;\r\n readonly delay: UpdateDelayer;\r\n\r\n constructor(ms: number) {\r\n this.ms = ms;\r\n this.delay = ms > 10_000\r\n ? (abortSignal?: AbortSignal) => new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, this.ms);\r\n if (abortSignal === undefined) return;\r\n if (abortSignal.aborted) { clearTimeout(timer); reject(abortSignal.reason); return; }\r\n abortSignal.addEventListener(\"abort\", () => {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason);\r\n }, { once: true });\r\n })\r\n : () => new Promise<void>((resolve) => setTimeout(resolve, this.ms));\r\n }\r\n}\r\n\r\nexport let defaultUpdateDelayer: UpdateDelayer = FixedDelayer.get(1000 / 60);\r\n","import { EventHandlerSet } from \"@actuallab/core\";\r\n\r\n/** Singleton tracking active UI commands — mirrors .NET's UIActionTracker. */\r\nexport class UIActionTracker {\r\n private _activeCount = 0;\r\n readonly changed = new EventHandlerSet<void>();\r\n readonly errors: unknown[] = [];\r\n\r\n get isActive(): boolean {\r\n return this._activeCount > 0;\r\n }\r\n\r\n /** Run a command silently — errors are added to the error list but not thrown. */\r\n async run(fn: () => Promise<unknown>): Promise<void> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n } finally {\r\n this._activeCount--;\r\n // Buffer 50ms for invalidations to arrive before signaling completion\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n /** Call a command and return the result — errors are added to the error list AND thrown. */\r\n async call<T>(fn: () => Promise<T>): Promise<T> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n return await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n throw e;\r\n } finally {\r\n this._activeCount--;\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n dismissError(index: number): void {\r\n if (index >= 0 && index < this.errors.length) {\r\n this.errors.splice(index, 1);\r\n this.changed.trigger();\r\n }\r\n }\r\n}\r\n\r\nexport let uiActions = new UIActionTracker();\r\n","import { uiActions } from \"./ui-action-tracker.js\";\r\nimport { FixedDelayer, type UpdateDelayer } from \"./update-delayer.js\";\r\n\r\n/** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */\r\nexport class UIUpdateDelayer {\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = UIUpdateDelayer._cache.get(ms);\r\n if (delayer !== undefined) return delayer;\r\n\r\n const t = uiActions;\r\n delayer = (abortSignal?: AbortSignal) => {\r\n if (t.isActive)\r\n return Promise.resolve();\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, ms);\r\n\r\n // Cancel delay when tracker becomes active\r\n const onChanged = () => {\r\n if (t.isActive) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n resolve();\r\n }\r\n };\r\n t.changed.add(onChanged);\r\n\r\n if (abortSignal !== undefined) {\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason);\r\n return;\r\n }\r\n abortSignal.addEventListener(\"abort\", () => {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason);\r\n }, { once: true });\r\n }\r\n });\r\n };\r\n UIUpdateDelayer._cache.set(ms, delayer);\r\n return delayer;\r\n }\r\n}\r\n","import { type AsyncContext, type IResult, PromiseSource, resolvedVoidPromise, type Result } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\n\r\n/** Base class for all reactive state types. */\r\nexport abstract class State<T> implements IResult<T> {\r\n protected _computed!: Computed<T>;\r\n protected _updateIndex = 0;\r\n protected _lastNonErrorValue: T | undefined;\r\n private _whenUpdatedSource: PromiseSource<void> | null = null;\r\n\r\n get updateIndex(): number {\r\n return this._updateIndex;\r\n }\r\n\r\n get lastNonErrorValue(): T | undefined {\r\n return this._lastNonErrorValue;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this._computed.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this._computed.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this._computed.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this._computed.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this._computed.valueOrUndefined;\r\n }\r\n\r\n get output(): Result<T> {\r\n return this._computed.output;\r\n }\r\n\r\n get computed(): Computed<T> {\r\n return this._computed;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n return this._computed.use(asyncContext);\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n return this._computed.useInconsistent(asyncContext);\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n return this._computed.update();\r\n }\r\n\r\n recompute(): Computed<T> | Promise<Computed<T>> {\r\n this._computed.invalidate();\r\n return this.update();\r\n }\r\n\r\n whenInvalidated(): Promise<void> {\r\n return this._computed.whenInvalidated();\r\n }\r\n\r\n whenUpdated(): Promise<void> {\r\n return (this._whenUpdatedSource ??= new PromiseSource<void>()).promise;\r\n }\r\n\r\n whenFirstTimeUpdated(): Promise<void> {\r\n return this._updateIndex > 0 ? resolvedVoidPromise : this.whenUpdated();\r\n }\r\n\r\n protected _initialize(output: Result<T> | T, renewer?: () => Computed<T> | Promise<Computed<T>>): void {\r\n this._computed = new StateBoundComputed<T>(this, renewer);\r\n this._computed.setOutput(output);\r\n this._lastNonErrorValue = this._computed.valueOrUndefined;\r\n }\r\n\r\n protected _update(computed: Computed<T>, output: Result<T> | T): void {\r\n computed.setOutput(output);\r\n this._computed = computed;\r\n if (computed.hasValue)\r\n this._lastNonErrorValue = computed.value;\r\n this._updateIndex++;\r\n this._whenUpdatedSource?.resolve(undefined);\r\n this._whenUpdatedSource = null;\r\n }\r\n}\r\n","import { AsyncContext, PromiseSource, type Result, result, errorResult } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\nimport { ComputeContext, computeContextKey } from \"./compute-context.js\";\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from \"./update-delayer.js\";\r\nimport { State } from \"./state.js\";\r\n\r\nexport type StateComputer<T> = () => T | Promise<T>;\r\n\r\n/** Constructor options for ComputedState. */\r\nexport interface ComputedStateOptions<T> {\r\n initialValue?: T;\r\n initialOutput?: Result<T>;\r\n updateDelayer?: UpdateDelayer;\r\n}\r\n\r\n/** Auto-updating reactive state wrapper — re-computes on invalidation with configurable delay. */\r\nexport class ComputedState<T> extends State<T> {\r\n private _computer: StateComputer<T>;\r\n private _updateDelayer: UpdateDelayer;\r\n private _disposeController: AbortController;\r\n private _cancelDelaySource = new PromiseSource<void>();\r\n private _renewer: () => Computed<T> | Promise<Computed<T>>;\r\n private _hasOutput = false;\r\n\r\n constructor(computer: StateComputer<T>, options?: ComputedStateOptions<T>) {\r\n super();\r\n this._computer = computer;\r\n this._updateDelayer = options?.updateDelayer ?? defaultUpdateDelayer;\r\n this._disposeController = new AbortController();\r\n this._renewer = async () => {\r\n const whenUpdated = this.whenUpdated();\r\n this._cancelDelaySource.resolve(undefined);\r\n await whenUpdated;\r\n return this._computed;\r\n };\r\n\r\n // Create initial computed — _updateCycle will replace it on first iteration\r\n if (options?.initialOutput !== undefined || options?.initialValue !== undefined) {\r\n this._initialize(options.initialOutput ?? options.initialValue as T, this._renewer);\r\n this._hasOutput = true;\r\n }\r\n // else: _computed stays unset until _updateCycle calls _update()\r\n\r\n void this._updateCycle();\r\n }\r\n\r\n override get hasValue(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasValue;\r\n }\r\n\r\n override get hasError(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasError;\r\n }\r\n\r\n override get value(): T {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has no value yet.\");\r\n if (this._computed.hasValue) return this._computed.value;\r\n if (this._lastNonErrorValue !== undefined) return this._lastNonErrorValue;\r\n throw new Error(\"ComputedState has no value yet.\");\r\n }\r\n\r\n override get error(): unknown {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.error;\r\n }\r\n\r\n override get valueOrUndefined(): T | undefined {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.valueOrUndefined ?? this._lastNonErrorValue;\r\n }\r\n\r\n override get output(): Result<T> {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has no output yet.\");\r\n return this._computed.output;\r\n }\r\n\r\n override get computed(): Computed<T> {\r\n if (!this._hasOutput && this._updateIndex === 0) throw new Error(\"ComputedState has not been computed yet.\");\r\n return this._computed;\r\n }\r\n\r\n get isDisposed(): boolean {\r\n return this._disposeController.signal.aborted;\r\n }\r\n\r\n dispose(): void {\r\n if (!this.isDisposed)\r\n this._disposeController.abort();\r\n }\r\n\r\n private async _updateCycle(): Promise<void> {\r\n const disposeSignal = this._disposeController.signal;\r\n try {\r\n while (!disposeSignal.aborted) {\r\n // Compute\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n const computeCtx = new ComputeContext(computed as StateBoundComputed<unknown>);\r\n const asyncCtx = (AsyncContext.current ?? AsyncContext.empty)\r\n .with(computeContextKey, computeCtx);\r\n\r\n let output: Result<T>;\r\n try {\r\n const value = asyncCtx.run(() => this._computer());\r\n const resolved = value instanceof Promise ? await value : value;\r\n output = result(resolved);\r\n } catch (e) {\r\n output = errorResult(e);\r\n }\r\n this._update(computed, output);\r\n if (this._cancelDelaySource.isCompleted)\r\n this._cancelDelaySource = new PromiseSource<void>();\r\n\r\n // Wait for invalidation (or cancellation via dispose)\r\n try {\r\n await computed.whenInvalidated(disposeSignal);\r\n } catch {\r\n return; // Cancelled via dispose\r\n }\r\n\r\n // Wait for delay (cancellable by renewer)\r\n await Promise.race([\r\n this._updateDelayer(disposeSignal),\r\n this._cancelDelaySource.promise,\r\n ]);\r\n }\r\n\r\n } catch (e) {\r\n // Intended, do nothing\r\n }\r\n }\r\n}\r\n","import { type AsyncContext, Result } from \"@actuallab/core\";\r\nimport { type Computed, StateBoundComputed } from \"./computed.js\";\r\nimport { State } from \"./state.js\";\r\n\r\n/** Manually-settable reactive state that can participate in the Fusion dependency graph. */\r\nexport class MutableState<T> extends State<T> {\r\n private _renewer = (): Computed<T> => {\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n this._update(computed, this._computed.output);\r\n return computed;\r\n };\r\n\r\n constructor(initialOutput: Result<T> | T) {\r\n super();\r\n this._initialize(initialOutput, this._renewer);\r\n }\r\n\r\n override use(asyncContext?: AsyncContext): T {\r\n return this._computed.use(asyncContext) as T;\r\n }\r\n\r\n set(output: Result<T> | T): void {\r\n this._computed.invalidate();\r\n this._update(new StateBoundComputed<T>(this, this._renewer), output);\r\n }\r\n}\r\n"],"mappings":"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","names":["AsyncContext","ConsistencyState","AsyncContext","AsyncContext","result","AsyncContext","result","EventHandlerSet","PromiseSource","PromiseSource","AsyncContext","PromiseSource","result","errorResult","PromiseSource","AsyncContext","result","errorResult"]}
1
+ {"version":3,"sources":["../src/computed-input.ts","../src/computed.ts","../src/computed-registry.ts","../src/compute-context.ts","../src/compute-function.ts","../src/compute-method.ts","../src/update-delayer.ts","../src/ui-action-tracker.ts","../src/ui-update-delayer.ts","../src/state.ts","../src/computed-state.ts","../src/mutable-state.ts"],"sourcesContent":["import type { State } from './state.js';\r\n\r\n/** Auto-assigned numeric IDs for instance identity in compute method cache keys. */\r\nlet _nextInstanceId = 0;\r\nconst _instanceIds = new WeakMap<object, number>();\r\n\r\nexport function getInstanceId(instance: object): number {\r\n let id = _instanceIds.get(instance);\r\n if (id === undefined) {\r\n id = ++_nextInstanceId;\r\n _instanceIds.set(instance, id);\r\n }\r\n return id;\r\n}\r\n\r\n/**\r\n * Identity key for any computed value.\r\n * - String for compute method results (built from instance + function + args)\r\n * - State for state types (identity by reference)\r\n */\r\nexport type ComputedInput = string | State<any>;\r\n","import {\r\n AsyncContext,\r\n EventHandlerSet,\r\n type IResult,\r\n PromiseSource,\r\n Result,\r\n result,\r\n} from '@actuallab/core';\r\nimport type { ComputedInput } from './computed-input.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport type { State } from './state.js';\r\n\r\nlet _nextVersion = 0;\r\n\r\nexport const enum ConsistencyState {\r\n Computing = 0,\r\n Consistent = 1,\r\n Invalidated = 2,\r\n}\r\n\r\n/** Core Fusion abstraction — a cached computation with dependency tracking and invalidation. */\r\nexport class Computed<T> implements IResult<T> {\r\n /** Delay before auto-invalidating a Computed that holds an error result. 0 = disabled. */\r\n static errorAutoInvalidateDelay = 1000;\r\n\r\n /** Capture the Computed backing a computation — works with both local and RPC compute methods. */\r\n static async capture<T>(fn: () => T | Promise<T>): Promise<Computed<T>> {\r\n const captureComputed = new Computed<unknown>('__capture__');\r\n const captureCtx = new ComputeContext(captureComputed);\r\n const asyncCtx = AsyncContext.getOrCreate().with(\r\n computeContextKey,\r\n captureCtx\r\n );\r\n await asyncCtx.run(fn);\r\n const deps = captureComputed.dependencies;\r\n if (deps.size === 0)\r\n throw new Error(\r\n 'No Computed was captured — fn must call a compute function.'\r\n );\r\n return deps.values().next().value! as Computed<T>;\r\n }\r\n\r\n readonly input: ComputedInput;\r\n private _version: number;\r\n private _state: ConsistencyState;\r\n private _output: Result<T> | undefined;\r\n private _dependencies = new Set<Computed<unknown>>();\r\n private _dependants = new Map<number, WeakRef<Computed<unknown>>>();\r\n readonly onInvalidated = new EventHandlerSet<void>();\r\n readonly _renewer: (() => Computed<T> | Promise<Computed<T>>) | undefined;\r\n\r\n constructor(\r\n input: ComputedInput,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>\r\n ) {\r\n this.input = input;\r\n this._renewer = renewer;\r\n this._version = ++_nextVersion;\r\n this._state = ConsistencyState.Computing;\r\n }\r\n\r\n get version(): number {\r\n return this._version;\r\n }\r\n\r\n get output(): Result<T> {\r\n if (this._output === undefined)\r\n throw new Error('Computed has no output yet.');\r\n return this._output;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this.output.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this.output.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this.output.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this.output.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this.output.valueOrUndefined;\r\n }\r\n\r\n get state(): ConsistencyState {\r\n return this._state;\r\n }\r\n\r\n get isConsistent(): boolean {\r\n return this._state === ConsistencyState.Consistent;\r\n }\r\n\r\n get dependencies(): ReadonlySet<Computed<unknown>> {\r\n return this._dependencies;\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n if (this._state === ConsistencyState.Consistent) return this;\r\n const latest = this._latest();\r\n if (latest?.isConsistent) return latest;\r\n if (this._renewer !== undefined) return this._renewer();\r\n throw new Error(\r\n 'Cannot recompute: Computed is invalidated and has no renewer.'\r\n );\r\n }\r\n\r\n protected _latest(): Computed<T> | undefined {\r\n return ComputedRegistry.get(this.input as string) as\r\n | Computed<T>\r\n | undefined;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n const ctx = ComputeContext.from(asyncContext);\r\n const updated = this.update();\r\n if (updated instanceof Promise) {\r\n return updated.then(c => {\r\n ctx?.captureDependency(c as Computed<unknown>);\r\n return c.value;\r\n });\r\n }\r\n ctx?.captureDependency(updated as Computed<unknown>);\r\n return updated.value;\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n ComputeContext.from(asyncContext)?.captureDependency(\r\n this as Computed<unknown>\r\n );\r\n return this.value;\r\n }\r\n\r\n setOutput(output: Result<T> | T): void {\r\n if (this._state !== ConsistencyState.Computing)\r\n throw new Error('Cannot set output on a non-computing Computed.');\r\n this._output = output instanceof Result ? output : result(output);\r\n this._state = ConsistencyState.Consistent;\r\n this._register();\r\n if (this._output.hasError && Computed.errorAutoInvalidateDelay > 0)\r\n setTimeout(\r\n () => this.invalidate(),\r\n Computed.errorAutoInvalidateDelay\r\n );\r\n }\r\n\r\n protected _register(): void {\r\n ComputedRegistry.register(this as Computed<unknown>);\r\n }\r\n\r\n protected _unregister(): void {\r\n ComputedRegistry.unregister(this as Computed<unknown>);\r\n }\r\n\r\n invalidate(): void {\r\n if (this._state === ConsistencyState.Invalidated) return;\r\n this._state = ConsistencyState.Invalidated;\r\n\r\n // Clear forward references\r\n this._dependencies.clear();\r\n\r\n // Notify dependants via WeakRef backward references\r\n for (const [, ref] of this._dependants) {\r\n const dependant = ref.deref();\r\n if (dependant != null) dependant.invalidate();\r\n }\r\n this._dependants.clear();\r\n\r\n this.onInvalidated.trigger();\r\n this.onInvalidated.clear();\r\n\r\n this._unregister();\r\n }\r\n\r\n whenInvalidated(abortSignal?: AbortSignal): Promise<void> {\r\n if (this._state === ConsistencyState.Invalidated)\r\n return Promise.resolve();\r\n\r\n const ps = new PromiseSource<void>();\r\n const handler = () => ps.resolve(undefined);\r\n this.onInvalidated.add(handler);\r\n\r\n if (abortSignal !== undefined && !abortSignal.aborted) {\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n this.onInvalidated.remove(handler);\r\n ps.reject(abortSignal.reason);\r\n },\r\n { once: true }\r\n );\r\n }\r\n\r\n return ps.promise;\r\n }\r\n\r\n addDependency(dependency: Computed<unknown>): void {\r\n this._dependencies.add(dependency);\r\n dependency._dependants.set(\r\n this._version,\r\n new WeakRef(this as Computed<unknown>)\r\n );\r\n }\r\n}\r\n\r\n/** Computed variant for State types — skips registry registration since the State holds a direct reference. */\r\nexport class StateBoundComputed<T> extends Computed<T> {\r\n protected override _latest(): Computed<T> | undefined {\r\n return (this.input as State<T>).computed;\r\n }\r\n\r\n protected override _register(): void {\r\n // No registration — state holds direct reference\r\n }\r\n\r\n protected override _unregister(): void {\r\n // No unregistration — was never registered\r\n }\r\n}\r\n","import type { Computed } from './computed.js';\r\n\r\n/** WeakRef-based global cache of Computed instances — allows GC of unused computed values. */\r\nexport class ComputedRegistry {\r\n private static _entries = new Map<string, WeakRef<Computed<unknown>>>();\r\n private static _finalization = new FinalizationRegistry<string>(key => {\r\n ComputedRegistry._entries.delete(key);\r\n });\r\n\r\n static get size(): number {\r\n return ComputedRegistry._entries.size;\r\n }\r\n\r\n static get(key: string): Computed<unknown> | undefined {\r\n const ref = ComputedRegistry._entries.get(key);\r\n if (ref === undefined) return undefined;\r\n const computed = ref.deref();\r\n if (computed === undefined) {\r\n ComputedRegistry._entries.delete(key);\r\n return undefined;\r\n }\r\n return computed;\r\n }\r\n\r\n static register(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.set(key, new WeakRef(computed));\r\n ComputedRegistry._finalization.register(computed, key, computed);\r\n }\r\n\r\n static unregister(computed: Computed<unknown>): void {\r\n const key = computed.input as string;\r\n ComputedRegistry._entries.delete(key);\r\n ComputedRegistry._finalization.unregister(computed);\r\n }\r\n}\r\n","import { AsyncContext, AsyncContextKey } from '@actuallab/core';\r\nimport type { Computed } from './computed.js';\r\n\r\nexport const computeContextKey = new AsyncContextKey<\r\n ComputeContext | undefined\r\n>('ComputeContext', undefined);\r\n\r\n/** Tracks the currently executing computation and captures dependencies. */\r\nexport class ComputeContext {\r\n readonly computed: Computed<unknown>;\r\n private _isCapturing = true;\r\n\r\n constructor(computed: Computed<unknown>) {\r\n this.computed = computed;\r\n }\r\n\r\n get isCapturing(): boolean {\r\n return this._isCapturing;\r\n }\r\n\r\n stopCapturing(): void {\r\n this._isCapturing = false;\r\n }\r\n\r\n captureDependency(dependency: Computed<unknown>): void {\r\n if (!this._isCapturing) return;\r\n this.computed.addDependency(dependency);\r\n }\r\n\r\n /** Resolve ComputeContext from an AsyncContext (or current). */\r\n static from(ctx: AsyncContext | undefined): ComputeContext | undefined {\r\n return AsyncContext.from(ctx)?.get(computeContextKey);\r\n }\r\n}\r\n","import {\r\n AsyncContext,\r\n AsyncLock,\r\n type Result,\r\n result,\r\n errorResult,\r\n} from '@actuallab/core';\r\nimport { Computed } from './computed.js';\r\nimport { getInstanceId } from './computed-input.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\n\r\nexport type ComputeFunctionImpl = (this: any, ...args: unknown[]) => unknown;\r\n\r\n/** Record Separator — delimiter between key components. */\r\nconst RS = '\\x1E';\r\n\r\nfunction defaultArgToString(arg: unknown): string {\r\n return JSON.stringify(arg) ?? 'undefined';\r\n}\r\n\r\nlet _nextFunctionId = 0;\r\n\r\n/** Produces Computed<T> from a function — handles cache lookup, locking, dependency capture. */\r\nexport class ComputeFunction {\r\n readonly methodName: string;\r\n readonly id: string;\r\n argToString: (arg: unknown) => string = defaultArgToString;\r\n private _impl: ComputeFunctionImpl;\r\n private _locks = new Map<string, AsyncLock>();\r\n\r\n constructor(methodName: string, impl: ComputeFunctionImpl) {\r\n this.methodName = methodName;\r\n this.id = `${methodName}[${++_nextFunctionId}]`;\r\n this._impl = impl;\r\n }\r\n\r\n /** Build a string key for the given instance and arguments. */\r\n buildKey(instance: object, args: unknown[]): string {\r\n let key = String(getInstanceId(instance)) + RS + this.id;\r\n for (const arg of args) {\r\n key += RS + this.argToString(arg);\r\n }\r\n return key;\r\n }\r\n\r\n async invoke(\r\n instance: object,\r\n args: unknown[],\r\n prevComputed?: Computed<unknown>\r\n ): Promise<Computed<unknown>> {\r\n // 1. Resolve AsyncContext ONCE via DRY helper\r\n const asyncCtx = AsyncContext.fromArgs(args);\r\n\r\n // 2. Pull caller's ComputeContext directly\r\n const callerComputeCtx = asyncCtx?.get(computeContextKey);\r\n\r\n // 3. Strip THIS context from args (reference equality — safe)\r\n const argsWithoutCtx = asyncCtx?.stripFromArgs(args) ?? args;\r\n\r\n // 4. Build string key and check cache\r\n const key = this.buildKey(instance, argsWithoutCtx);\r\n const existing = ComputedRegistry.get(key);\r\n if (existing?.isConsistent) {\r\n callerComputeCtx?.captureDependency(existing);\r\n return existing;\r\n }\r\n\r\n // 5. Lock per key to prevent duplicate computations\r\n let lock = this._locks.get(key);\r\n if (lock === undefined) {\r\n lock = new AsyncLock();\r\n this._locks.set(key, lock);\r\n }\r\n\r\n const computed = await lock.run(async () => {\r\n // Double-check after acquiring lock\r\n const cached = ComputedRegistry.get(key);\r\n if (cached?.isConsistent) return cached;\r\n\r\n // 6. Create new Computed + ComputeContext\r\n // eslint-disable-next-line prefer-const\r\n let newComputed: Computed<unknown>;\r\n const renewer =\r\n prevComputed?._renewer ??\r\n (() => this.invoke(instance, argsWithoutCtx, newComputed));\r\n newComputed = new Computed<unknown>(key, renewer);\r\n\r\n const childComputeCtx = new ComputeContext(newComputed);\r\n const childAsyncCtx = (asyncCtx ?? AsyncContext.empty).with(\r\n computeContextKey,\r\n childComputeCtx\r\n );\r\n\r\n // 7. Run with clean args — no stale AsyncContext to override .run()\r\n let fnResult: Result<unknown>;\r\n try {\r\n const value = childAsyncCtx.run(() =>\r\n this._impl.call(instance, ...argsWithoutCtx)\r\n );\r\n const resolved = value instanceof Promise ? await value : value;\r\n fnResult = result(resolved);\r\n } catch (e) {\r\n fnResult = errorResult(e);\r\n }\r\n\r\n newComputed.setOutput(fnResult);\r\n\r\n return newComputed;\r\n });\r\n\r\n // Register dependency from caller to the produced computed\r\n callerComputeCtx?.captureDependency(computed);\r\n return computed;\r\n }\r\n}\r\n","import { ComputeFunction } from './compute-function.js';\r\nimport { ComputedRegistry } from './computed-registry.js';\r\n\r\nconst METHODS_META = Symbol.for('actuallab.methods');\r\n\r\nexport interface MethodMeta {\r\n argCount: number;\r\n compute?: boolean;\r\n stream?: boolean;\r\n}\r\n\r\n/** Read method metadata from a decorated class. */\r\nexport function getMethodsMeta(\r\n cls: abstract new (...args: any[]) => any\r\n): Record<string, MethodMeta> | undefined {\r\n return (cls as any)[Symbol.metadata]?.[METHODS_META];\r\n}\r\n\r\n/** Method decorator — wraps a method to route through ComputeFunction for caching and dependency tracking. */\r\nexport function computeMethod<This, Args extends unknown[], Return>(\r\n target: (this: This, ...args: Args) => Return,\r\n context: ClassMethodDecoratorContext<\r\n This,\r\n (this: This, ...args: Args) => Return\r\n >\r\n): (this: This, ...args: Args) => Return {\r\n const methodName = String(context.name);\r\n\r\n // Store metadata\r\n const methods: Record<string, MethodMeta> = ((context.metadata as any)[\r\n METHODS_META\r\n ] ??= {});\r\n methods[methodName] = {\r\n ...methods[methodName],\r\n compute: true,\r\n argCount: target.length,\r\n };\r\n\r\n // ONE ComputeFunction per class×method — created at decoration time\r\n const cf = new ComputeFunction(methodName, target as any);\r\n\r\n // Prototype-level replacement — unwraps Computed to return the value directly\r\n const replacement = function (this: This, ...allArgs: Args): Return {\r\n return cf.invoke(this as object, allArgs).then(c => c.value) as Return;\r\n };\r\n\r\n // Per-instance setup: create bound method with .invalidate pre-bound\r\n context.addInitializer(function (this: This) {\r\n const instance = this;\r\n const boundMethod = (...allArgs: unknown[]) => {\r\n return cf.invoke(instance as object, allArgs).then(c => c.value);\r\n };\r\n (boundMethod as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(instance as object, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n (this as any)[methodName] = boundMethod;\r\n });\r\n\r\n return replacement;\r\n}\r\n\r\n/** Wrap a standalone function as a compute function with caching and .invalidate(). */\r\nexport function wrapComputeMethod<Args extends unknown[], Return>(\r\n fn: (...args: Args) => Return\r\n): ((...args: Args) => Promise<Return>) & {\r\n invalidate: (...args: Args) => void;\r\n} {\r\n const syntheticInstance = {};\r\n const methodName = fn.name || 'anonymous';\r\n const cf = new ComputeFunction(methodName, fn as any);\r\n\r\n const wrapped = (...allArgs: unknown[]) => {\r\n return cf\r\n .invoke(syntheticInstance, allArgs)\r\n .then(c => c.value as Return);\r\n };\r\n\r\n (wrapped as any).invalidate = (...args: unknown[]) => {\r\n const key = cf.buildKey(syntheticInstance, args);\r\n ComputedRegistry.get(key)?.invalidate();\r\n };\r\n\r\n return wrapped as any;\r\n}\r\n","/** Controls when state re-computation happens after invalidation. */\r\nexport type UpdateDelayer = (abortSignal?: AbortSignal) => Promise<void>;\r\n\r\n/** Re-computes after a fixed delay in milliseconds. */\r\nexport class FixedDelayer {\r\n static readonly zero: UpdateDelayer = () => Promise.resolve();\r\n\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = FixedDelayer._cache.get(ms);\r\n if (delayer === undefined) {\r\n delayer = new FixedDelayer(ms).delay;\r\n FixedDelayer._cache.set(ms, delayer);\r\n }\r\n return delayer;\r\n }\r\n\r\n readonly ms: number;\r\n readonly delay: UpdateDelayer;\r\n\r\n constructor(ms: number) {\r\n this.ms = ms;\r\n this.delay =\r\n ms > 10_000\r\n ? (abortSignal?: AbortSignal) =>\r\n new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, this.ms);\r\n if (abortSignal === undefined) return;\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n return;\r\n }\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n },\r\n { once: true }\r\n );\r\n })\r\n : () =>\r\n new Promise<void>(resolve =>\r\n setTimeout(resolve, this.ms)\r\n );\r\n }\r\n}\r\n\r\nexport const defaultUpdateDelayer: UpdateDelayer = FixedDelayer.get(1000 / 60);\r\n","import { EventHandlerSet } from '@actuallab/core';\r\n\r\n/** Singleton tracking active UI commands — mirrors .NET's UIActionTracker. */\r\nexport class UIActionTracker {\r\n private _activeCount = 0;\r\n readonly changed = new EventHandlerSet<void>();\r\n readonly errors: unknown[] = [];\r\n\r\n get isActive(): boolean {\r\n return this._activeCount > 0;\r\n }\r\n\r\n /** Run a command silently — errors are added to the error list but not thrown. */\r\n async run(fn: () => Promise<unknown>): Promise<void> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n } finally {\r\n this._activeCount--;\r\n // Buffer 50ms for invalidations to arrive before signaling completion\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n /** Call a command and return the result — errors are added to the error list AND thrown. */\r\n async call<T>(fn: () => Promise<T>): Promise<T> {\r\n this._activeCount++;\r\n this.changed.trigger();\r\n try {\r\n return await fn();\r\n } catch (e) {\r\n this.errors.push(e);\r\n throw e;\r\n } finally {\r\n this._activeCount--;\r\n await new Promise<void>(r => setTimeout(r, 50));\r\n this.changed.trigger();\r\n }\r\n }\r\n\r\n dismissError(index: number): void {\r\n if (index >= 0 && index < this.errors.length) {\r\n this.errors.splice(index, 1);\r\n this.changed.trigger();\r\n }\r\n }\r\n}\r\n\r\nexport const uiActions = new UIActionTracker();\r\n","import { uiActions } from './ui-action-tracker.js';\r\nimport { FixedDelayer, type UpdateDelayer } from './update-delayer.js';\r\n\r\n/** Re-computes after a fixed delay, but skips the delay when UIActionTracker is active. */\r\nexport class UIUpdateDelayer {\r\n private static _cache = new Map<number, UpdateDelayer>();\r\n\r\n static get(ms: number): UpdateDelayer {\r\n if (ms <= 0) return FixedDelayer.zero;\r\n let delayer = UIUpdateDelayer._cache.get(ms);\r\n if (delayer !== undefined) return delayer;\r\n\r\n const t = uiActions;\r\n delayer = (abortSignal?: AbortSignal) => {\r\n if (t.isActive) return Promise.resolve();\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, ms);\r\n\r\n // Cancel delay when tracker becomes active\r\n const onChanged = () => {\r\n if (t.isActive) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n resolve();\r\n }\r\n };\r\n t.changed.add(onChanged);\r\n\r\n if (abortSignal !== undefined) {\r\n if (abortSignal.aborted) {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n return;\r\n }\r\n abortSignal.addEventListener(\r\n 'abort',\r\n () => {\r\n clearTimeout(timer);\r\n t.changed.remove(onChanged);\r\n reject(abortSignal.reason instanceof Error ? abortSignal.reason : new Error(String(abortSignal.reason)));\r\n },\r\n { once: true }\r\n );\r\n }\r\n });\r\n };\r\n UIUpdateDelayer._cache.set(ms, delayer);\r\n return delayer;\r\n }\r\n}\r\n","import {\r\n type AsyncContext,\r\n type IResult,\r\n PromiseSource,\r\n resolvedVoidPromise,\r\n type Result,\r\n} from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\n\r\n/** Base class for all reactive state types. */\r\nexport abstract class State<T> implements IResult<T> {\r\n protected _computed!: Computed<T>;\r\n protected _updateIndex = 0;\r\n protected _lastNonErrorValue: T | undefined;\r\n private _whenUpdatedSource: PromiseSource<void> | null = null;\r\n\r\n get updateIndex(): number {\r\n return this._updateIndex;\r\n }\r\n\r\n get lastNonErrorValue(): T | undefined {\r\n return this._lastNonErrorValue;\r\n }\r\n\r\n get hasValue(): boolean {\r\n return this._computed.hasValue;\r\n }\r\n\r\n get hasError(): boolean {\r\n return this._computed.hasError;\r\n }\r\n\r\n get value(): T {\r\n return this._computed.value;\r\n }\r\n\r\n get error(): unknown {\r\n return this._computed.error;\r\n }\r\n\r\n get valueOrUndefined(): T | undefined {\r\n return this._computed.valueOrUndefined;\r\n }\r\n\r\n get output(): Result<T> {\r\n return this._computed.output;\r\n }\r\n\r\n get computed(): Computed<T> {\r\n return this._computed;\r\n }\r\n\r\n use(asyncContext?: AsyncContext): T | Promise<T> {\r\n return this._computed.use(asyncContext);\r\n }\r\n\r\n useInconsistent(asyncContext?: AsyncContext): T {\r\n return this._computed.useInconsistent(asyncContext);\r\n }\r\n\r\n update(): Computed<T> | Promise<Computed<T>> {\r\n return this._computed.update();\r\n }\r\n\r\n recompute(): Computed<T> | Promise<Computed<T>> {\r\n this._computed.invalidate();\r\n return this.update();\r\n }\r\n\r\n whenInvalidated(): Promise<void> {\r\n return this._computed.whenInvalidated();\r\n }\r\n\r\n whenUpdated(): Promise<void> {\r\n return (this._whenUpdatedSource ??= new PromiseSource<void>()).promise;\r\n }\r\n\r\n whenFirstTimeUpdated(): Promise<void> {\r\n return this._updateIndex > 0 ? resolvedVoidPromise : this.whenUpdated();\r\n }\r\n\r\n protected _initialize(\r\n output: Result<T> | T,\r\n renewer?: () => Computed<T> | Promise<Computed<T>>\r\n ): void {\r\n this._computed = new StateBoundComputed<T>(this, renewer);\r\n this._computed.setOutput(output);\r\n this._lastNonErrorValue = this._computed.valueOrUndefined;\r\n }\r\n\r\n protected _update(computed: Computed<T>, output: Result<T> | T): void {\r\n computed.setOutput(output);\r\n this._computed = computed;\r\n if (computed.hasValue) this._lastNonErrorValue = computed.value;\r\n this._updateIndex++;\r\n this._whenUpdatedSource?.resolve(undefined);\r\n this._whenUpdatedSource = null;\r\n }\r\n}\r\n","import {\r\n AsyncContext,\r\n PromiseSource,\r\n type Result,\r\n result,\r\n errorResult,\r\n} from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\nimport { ComputeContext, computeContextKey } from './compute-context.js';\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from './update-delayer.js';\r\nimport { State } from './state.js';\r\n\r\nexport type StateComputer<T> = () => T | Promise<T>;\r\n\r\n/** Constructor options for ComputedState. */\r\nexport interface ComputedStateOptions<T> {\r\n initialValue?: T;\r\n initialOutput?: Result<T>;\r\n updateDelayer?: UpdateDelayer;\r\n}\r\n\r\n/** Auto-updating reactive state wrapper — re-computes on invalidation with configurable delay. */\r\nexport class ComputedState<T> extends State<T> {\r\n private _computer: StateComputer<T>;\r\n private _updateDelayer: UpdateDelayer;\r\n private _disposeController: AbortController;\r\n private _cancelDelaySource = new PromiseSource<void>();\r\n private _renewer: () => Computed<T> | Promise<Computed<T>>;\r\n private _hasOutput = false;\r\n\r\n constructor(computer: StateComputer<T>, options?: ComputedStateOptions<T>) {\r\n super();\r\n this._computer = computer;\r\n this._updateDelayer = options?.updateDelayer ?? defaultUpdateDelayer;\r\n this._disposeController = new AbortController();\r\n this._renewer = async () => {\r\n const whenUpdated = this.whenUpdated();\r\n this._cancelDelaySource.resolve(undefined);\r\n await whenUpdated;\r\n return this._computed;\r\n };\r\n\r\n // Create initial computed — _updateCycle will replace it on first iteration\r\n if (\r\n options?.initialOutput !== undefined ||\r\n options?.initialValue !== undefined\r\n ) {\r\n this._initialize(\r\n options.initialOutput ?? (options.initialValue as T),\r\n this._renewer\r\n );\r\n this._hasOutput = true;\r\n }\r\n // else: _computed stays unset until _updateCycle calls _update()\r\n\r\n void this._updateCycle();\r\n }\r\n\r\n override get hasValue(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasValue;\r\n }\r\n\r\n override get hasError(): boolean {\r\n if (!this._hasOutput && this._updateIndex === 0) return false;\r\n return this._computed.hasError;\r\n }\r\n\r\n override get value(): T {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has no value yet.');\r\n if (this._computed.hasValue) return this._computed.value;\r\n if (this._lastNonErrorValue !== undefined)\r\n return this._lastNonErrorValue;\r\n throw new Error('ComputedState has no value yet.');\r\n }\r\n\r\n override get error(): unknown {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.error;\r\n }\r\n\r\n override get valueOrUndefined(): T | undefined {\r\n if (!this._hasOutput && this._updateIndex === 0) return undefined;\r\n return this._computed.valueOrUndefined ?? this._lastNonErrorValue;\r\n }\r\n\r\n override get output(): Result<T> {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has no output yet.');\r\n return this._computed.output;\r\n }\r\n\r\n override get computed(): Computed<T> {\r\n if (!this._hasOutput && this._updateIndex === 0)\r\n throw new Error('ComputedState has not been computed yet.');\r\n return this._computed;\r\n }\r\n\r\n get isDisposed(): boolean {\r\n return this._disposeController.signal.aborted;\r\n }\r\n\r\n dispose(): void {\r\n if (!this.isDisposed) this._disposeController.abort();\r\n }\r\n\r\n private async _updateCycle(): Promise<void> {\r\n const disposeSignal = this._disposeController.signal;\r\n try {\r\n while (!disposeSignal.aborted) {\r\n // Compute\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n const computeCtx = new ComputeContext(\r\n computed as StateBoundComputed<unknown>\r\n );\r\n const asyncCtx = (\r\n AsyncContext.current ?? AsyncContext.empty\r\n ).with(computeContextKey, computeCtx);\r\n\r\n let output: Result<T>;\r\n try {\r\n const value = asyncCtx.run(() => this._computer());\r\n const resolved =\r\n value instanceof Promise ? await value : value;\r\n output = result(resolved);\r\n } catch (e) {\r\n output = errorResult(e);\r\n }\r\n this._update(computed, output);\r\n if (this._cancelDelaySource.isCompleted)\r\n this._cancelDelaySource = new PromiseSource<void>();\r\n\r\n // Wait for invalidation (or cancellation via dispose)\r\n try {\r\n await computed.whenInvalidated(disposeSignal);\r\n } catch {\r\n return; // Cancelled via dispose\r\n }\r\n\r\n // Wait for delay (cancellable by renewer)\r\n await Promise.race([\r\n this._updateDelayer(disposeSignal),\r\n this._cancelDelaySource.promise,\r\n ]);\r\n }\r\n } catch {\r\n // Intended, do nothing\r\n }\r\n }\r\n}\r\n","import { type AsyncContext, Result } from '@actuallab/core';\r\nimport { type Computed, StateBoundComputed } from './computed.js';\r\nimport { State } from './state.js';\r\n\r\n/** Manually-settable reactive state that can participate in the Fusion dependency graph. */\r\nexport class MutableState<T> extends State<T> {\r\n private _renewer = (): Computed<T> => {\r\n const computed = new StateBoundComputed<T>(this, this._renewer);\r\n this._update(computed, this._computed.output);\r\n return computed;\r\n };\r\n\r\n constructor(initialOutput: Result<T> | T) {\r\n super();\r\n this._initialize(initialOutput, this._renewer);\r\n }\r\n\r\n override use(asyncContext?: AsyncContext): T {\r\n return this._computed.use(asyncContext) as T;\r\n }\r\n\r\n set(output: Result<T> | T): void {\r\n this._computed.invalidate();\r\n this._update(new StateBoundComputed<T>(this, this._renewer), output);\r\n }\r\n}\r\n"],"mappings":"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","names":["AsyncContext","ConsistencyState","AsyncContext","AsyncContext","result","AsyncContext","result","EventHandlerSet","PromiseSource","PromiseSource","AsyncContext","PromiseSource","result","errorResult","PromiseSource","AsyncContext","result","errorResult"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuallab/fusion",
3
- "version": "12.1.100",
3
+ "version": "12.2.21",
4
4
  "description": "TypeScript implementation of Fusion - real-time state synchronization framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,7 +26,7 @@
26
26
  "clean": "rm -rf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@actuallab/core": "12.1.100"
29
+ "@actuallab/core": "12.2.21"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public"