@actuallab/fusion 12.3.29 → 12.3.31
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 +49 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -36,12 +36,27 @@ __export(index_exports, {
|
|
|
36
36
|
computeMethod: () => computeMethod,
|
|
37
37
|
defaultUpdateDelayer: () => defaultUpdateDelayer,
|
|
38
38
|
getInstanceId: () => getInstanceId,
|
|
39
|
+
getLogs: () => getLogs,
|
|
39
40
|
getMethodsMeta: () => getMethodsMeta,
|
|
40
41
|
uiActions: () => uiActions,
|
|
41
42
|
wrapComputeMethod: () => wrapComputeMethod
|
|
42
43
|
});
|
|
43
44
|
module.exports = __toCommonJS(index_exports);
|
|
44
45
|
|
|
46
|
+
// src/logging.ts
|
|
47
|
+
var import_core = require("@actuallab/core");
|
|
48
|
+
var scopeDefaults = {
|
|
49
|
+
Computed: import_core.LogLevel.Warn,
|
|
50
|
+
ComputedRegistry: import_core.LogLevel.Warn,
|
|
51
|
+
ComputedState: import_core.LogLevel.Warn,
|
|
52
|
+
ComputeFunction: import_core.LogLevel.Warn,
|
|
53
|
+
MutableState: import_core.LogLevel.Warn,
|
|
54
|
+
State: import_core.LogLevel.Warn,
|
|
55
|
+
UIActionTracker: import_core.LogLevel.Warn,
|
|
56
|
+
UIUpdateDelayer: import_core.LogLevel.Warn
|
|
57
|
+
};
|
|
58
|
+
var getLogs = (0, import_core.createLogProvider)("fusion.", scopeDefaults);
|
|
59
|
+
|
|
45
60
|
// src/computed-input.ts
|
|
46
61
|
var _nextInstanceId = 0;
|
|
47
62
|
var _instanceIds = /* @__PURE__ */ new WeakMap();
|
|
@@ -55,7 +70,7 @@ function getInstanceId(instance) {
|
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
// src/computed.ts
|
|
58
|
-
var
|
|
73
|
+
var import_core3 = require("@actuallab/core");
|
|
59
74
|
|
|
60
75
|
// src/computed-registry.ts
|
|
61
76
|
var ComputedRegistry = class _ComputedRegistry {
|
|
@@ -89,8 +104,8 @@ var ComputedRegistry = class _ComputedRegistry {
|
|
|
89
104
|
};
|
|
90
105
|
|
|
91
106
|
// src/compute-context.ts
|
|
92
|
-
var
|
|
93
|
-
var computeContextKey = new
|
|
107
|
+
var import_core2 = require("@actuallab/core");
|
|
108
|
+
var computeContextKey = new import_core2.AsyncContextKey("ComputeContext", void 0);
|
|
94
109
|
var ComputeContext = class {
|
|
95
110
|
computed;
|
|
96
111
|
_isCapturing = true;
|
|
@@ -109,7 +124,7 @@ var ComputeContext = class {
|
|
|
109
124
|
}
|
|
110
125
|
/** Resolve ComputeContext from an AsyncContext (or current). */
|
|
111
126
|
static from(ctx) {
|
|
112
|
-
return
|
|
127
|
+
return import_core2.AsyncContext.from(ctx)?.get(computeContextKey);
|
|
113
128
|
}
|
|
114
129
|
};
|
|
115
130
|
|
|
@@ -128,7 +143,7 @@ var Computed = class _Computed {
|
|
|
128
143
|
static async capture(fn) {
|
|
129
144
|
const captureComputed = new _Computed("__capture__");
|
|
130
145
|
const captureCtx = new ComputeContext(captureComputed);
|
|
131
|
-
const asyncCtx =
|
|
146
|
+
const asyncCtx = import_core3.AsyncContext.getOrCreate().with(
|
|
132
147
|
computeContextKey,
|
|
133
148
|
captureCtx
|
|
134
149
|
);
|
|
@@ -146,7 +161,7 @@ var Computed = class _Computed {
|
|
|
146
161
|
_output;
|
|
147
162
|
_dependencies = /* @__PURE__ */ new Set();
|
|
148
163
|
_dependants = /* @__PURE__ */ new Map();
|
|
149
|
-
onInvalidated = new
|
|
164
|
+
onInvalidated = new import_core3.EventHandlerSet();
|
|
150
165
|
_renewer;
|
|
151
166
|
constructor(input, renewer) {
|
|
152
167
|
this.input = input;
|
|
@@ -219,7 +234,7 @@ var Computed = class _Computed {
|
|
|
219
234
|
setOutput(output) {
|
|
220
235
|
if (this._state !== 0 /* Computing */)
|
|
221
236
|
throw new Error("Cannot set output on a non-computing Computed.");
|
|
222
|
-
this._output = output instanceof
|
|
237
|
+
this._output = output instanceof import_core3.Result ? output : (0, import_core3.result)(output);
|
|
223
238
|
this._state = 1 /* Consistent */;
|
|
224
239
|
this._register();
|
|
225
240
|
if (this._output.hasError && _Computed.errorAutoInvalidateDelay > 0)
|
|
@@ -250,7 +265,7 @@ var Computed = class _Computed {
|
|
|
250
265
|
whenInvalidated(abortSignal) {
|
|
251
266
|
if (this._state === 2 /* Invalidated */)
|
|
252
267
|
return Promise.resolve();
|
|
253
|
-
const ps = new
|
|
268
|
+
const ps = new import_core3.PromiseSource();
|
|
254
269
|
const handler = () => ps.resolve(void 0);
|
|
255
270
|
this.onInvalidated.add(handler);
|
|
256
271
|
if (abortSignal !== void 0 && !abortSignal.aborted) {
|
|
@@ -284,7 +299,7 @@ var StateBoundComputed = class extends Computed {
|
|
|
284
299
|
};
|
|
285
300
|
|
|
286
301
|
// src/compute-function.ts
|
|
287
|
-
var
|
|
302
|
+
var import_core4 = require("@actuallab/core");
|
|
288
303
|
var RS = "";
|
|
289
304
|
function defaultArgToString(arg) {
|
|
290
305
|
return JSON.stringify(arg) ?? "undefined";
|
|
@@ -310,7 +325,7 @@ var ComputeFunction = class {
|
|
|
310
325
|
return key;
|
|
311
326
|
}
|
|
312
327
|
async invoke(instance, args, prevComputed) {
|
|
313
|
-
const asyncCtx =
|
|
328
|
+
const asyncCtx = import_core4.AsyncContext.fromArgs(args);
|
|
314
329
|
const callerComputeCtx = asyncCtx?.get(computeContextKey);
|
|
315
330
|
const argsWithoutCtx = asyncCtx?.stripFromArgs(args) ?? args;
|
|
316
331
|
const key = this.buildKey(instance, argsWithoutCtx);
|
|
@@ -321,7 +336,7 @@ var ComputeFunction = class {
|
|
|
321
336
|
}
|
|
322
337
|
let lock = this._locks.get(key);
|
|
323
338
|
if (lock === void 0) {
|
|
324
|
-
lock = new
|
|
339
|
+
lock = new import_core4.AsyncLock();
|
|
325
340
|
this._locks.set(key, lock);
|
|
326
341
|
}
|
|
327
342
|
const computed = await lock.run(async () => {
|
|
@@ -331,7 +346,7 @@ var ComputeFunction = class {
|
|
|
331
346
|
const renewer = prevComputed?._renewer ?? (() => this.invoke(instance, argsWithoutCtx, newComputed));
|
|
332
347
|
newComputed = new Computed(key, renewer);
|
|
333
348
|
const childComputeCtx = new ComputeContext(newComputed);
|
|
334
|
-
const childAsyncCtx = (asyncCtx ??
|
|
349
|
+
const childAsyncCtx = (asyncCtx ?? import_core4.AsyncContext.empty).with(
|
|
335
350
|
computeContextKey,
|
|
336
351
|
childComputeCtx
|
|
337
352
|
);
|
|
@@ -341,9 +356,9 @@ var ComputeFunction = class {
|
|
|
341
356
|
() => this._impl.call(instance, ...argsWithoutCtx)
|
|
342
357
|
);
|
|
343
358
|
const resolved = value instanceof Promise ? await value : value;
|
|
344
|
-
fnResult = (0,
|
|
359
|
+
fnResult = (0, import_core4.result)(resolved);
|
|
345
360
|
} catch (e) {
|
|
346
|
-
fnResult = (0,
|
|
361
|
+
fnResult = (0, import_core4.errorResult)(e);
|
|
347
362
|
}
|
|
348
363
|
newComputed.setOutput(fnResult);
|
|
349
364
|
return newComputed;
|
|
@@ -438,10 +453,11 @@ var FixedDelayer = class _FixedDelayer {
|
|
|
438
453
|
var defaultUpdateDelayer = FixedDelayer.get(1e3 / 60);
|
|
439
454
|
|
|
440
455
|
// src/ui-action-tracker.ts
|
|
441
|
-
var
|
|
456
|
+
var import_core5 = require("@actuallab/core");
|
|
457
|
+
var { errorLog } = getLogs("UIActionTracker");
|
|
442
458
|
var UIActionTracker = class {
|
|
443
459
|
_activeCount = 0;
|
|
444
|
-
changed = new
|
|
460
|
+
changed = new import_core5.EventHandlerSet();
|
|
445
461
|
errors = [];
|
|
446
462
|
get isActive() {
|
|
447
463
|
return this._activeCount > 0;
|
|
@@ -453,6 +469,7 @@ var UIActionTracker = class {
|
|
|
453
469
|
try {
|
|
454
470
|
await fn();
|
|
455
471
|
} catch (e) {
|
|
472
|
+
errorLog?.log("UI action failed", e);
|
|
456
473
|
this.errors.push(e);
|
|
457
474
|
} finally {
|
|
458
475
|
this._activeCount--;
|
|
@@ -467,6 +484,7 @@ var UIActionTracker = class {
|
|
|
467
484
|
try {
|
|
468
485
|
return await fn();
|
|
469
486
|
} catch (e) {
|
|
487
|
+
errorLog?.log("UI action failed", e);
|
|
470
488
|
this.errors.push(e);
|
|
471
489
|
throw e;
|
|
472
490
|
} finally {
|
|
@@ -529,7 +547,7 @@ var UIUpdateDelayer = class _UIUpdateDelayer {
|
|
|
529
547
|
};
|
|
530
548
|
|
|
531
549
|
// src/state.ts
|
|
532
|
-
var
|
|
550
|
+
var import_core6 = require("@actuallab/core");
|
|
533
551
|
var State = class {
|
|
534
552
|
_computed;
|
|
535
553
|
_updateIndex = 0;
|
|
@@ -579,10 +597,10 @@ var State = class {
|
|
|
579
597
|
return this._computed.whenInvalidated();
|
|
580
598
|
}
|
|
581
599
|
whenUpdated() {
|
|
582
|
-
return (this._whenUpdatedSource ??= new
|
|
600
|
+
return (this._whenUpdatedSource ??= new import_core6.PromiseSource()).promise;
|
|
583
601
|
}
|
|
584
602
|
whenFirstTimeUpdated() {
|
|
585
|
-
return this._updateIndex > 0 ?
|
|
603
|
+
return this._updateIndex > 0 ? import_core6.resolvedVoidPromise : this.whenUpdated();
|
|
586
604
|
}
|
|
587
605
|
_initialize(output, renewer) {
|
|
588
606
|
this._computed = new StateBoundComputed(this, renewer);
|
|
@@ -600,12 +618,13 @@ var State = class {
|
|
|
600
618
|
};
|
|
601
619
|
|
|
602
620
|
// src/computed-state.ts
|
|
603
|
-
var
|
|
621
|
+
var import_core7 = require("@actuallab/core");
|
|
622
|
+
var { errorLog: errorLog2 } = getLogs("ComputedState");
|
|
604
623
|
var ComputedState = class extends State {
|
|
605
624
|
_computer;
|
|
606
625
|
_updateDelayer;
|
|
607
626
|
_disposeController;
|
|
608
|
-
_cancelDelaySource = new
|
|
627
|
+
_cancelDelaySource = new import_core7.PromiseSource();
|
|
609
628
|
_renewer;
|
|
610
629
|
_hasOutput = false;
|
|
611
630
|
constructor(computer, options) {
|
|
@@ -676,18 +695,18 @@ var ComputedState = class extends State {
|
|
|
676
695
|
const computeCtx = new ComputeContext(
|
|
677
696
|
computed
|
|
678
697
|
);
|
|
679
|
-
const asyncCtx = (
|
|
698
|
+
const asyncCtx = (import_core7.AsyncContext.current ?? import_core7.AsyncContext.empty).with(computeContextKey, computeCtx);
|
|
680
699
|
let output;
|
|
681
700
|
try {
|
|
682
701
|
const value = asyncCtx.run(() => this._computer());
|
|
683
702
|
const resolved = value instanceof Promise ? await value : value;
|
|
684
|
-
output = (0,
|
|
703
|
+
output = (0, import_core7.result)(resolved);
|
|
685
704
|
} catch (e) {
|
|
686
|
-
output = (0,
|
|
705
|
+
output = (0, import_core7.errorResult)(e);
|
|
687
706
|
}
|
|
688
707
|
this._update(computed, output);
|
|
689
708
|
if (this._cancelDelaySource.isCompleted)
|
|
690
|
-
this._cancelDelaySource = new
|
|
709
|
+
this._cancelDelaySource = new import_core7.PromiseSource();
|
|
691
710
|
try {
|
|
692
711
|
await computed.whenInvalidated(disposeSignal);
|
|
693
712
|
} catch {
|
|
@@ -698,13 +717,15 @@ var ComputedState = class extends State {
|
|
|
698
717
|
this._cancelDelaySource.promise
|
|
699
718
|
]);
|
|
700
719
|
}
|
|
701
|
-
} catch {
|
|
720
|
+
} catch (e) {
|
|
721
|
+
if (!disposeSignal.aborted)
|
|
722
|
+
errorLog2?.log("UpdateCycle() failed and stopped", e);
|
|
702
723
|
}
|
|
703
724
|
}
|
|
704
725
|
};
|
|
705
726
|
|
|
706
727
|
// src/mutable-state.ts
|
|
707
|
-
var
|
|
728
|
+
var import_core8 = require("@actuallab/core");
|
|
708
729
|
var MutableState = class extends State {
|
|
709
730
|
_renewer = () => {
|
|
710
731
|
const computed = new StateBoundComputed(this, this._renewer);
|
|
@@ -741,6 +762,7 @@ var MutableState = class extends State {
|
|
|
741
762
|
computeMethod,
|
|
742
763
|
defaultUpdateDelayer,
|
|
743
764
|
getInstanceId,
|
|
765
|
+
getLogs,
|
|
744
766
|
getMethodsMeta,
|
|
745
767
|
uiActions,
|
|
746
768
|
wrapComputeMethod
|
package/dist/index.cjs.map
CHANGED
|
@@ -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 {\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- JSON.stringify returns undefined for undefined input\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-this-alias */\r\nimport { 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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/logging.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 type { FusionLogScope } from './logging.js';\r\nexport { getLogs } from './logging.js';\r\n\r\nexport { 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 { createLogProvider, LogLevel } from '@actuallab/core';\n\n// Per-package log scopes. Use createLogProvider to get a typed helper:\n// const { debugLog, warnLog } = getLogs('Computed');\n// Final scope name is 'fusion.Computed' — the prefix isolates this package's\n// scopes from other packages' scopes when overriding levels at runtime.\nexport type FusionLogScope =\n | 'Computed'\n | 'ComputedRegistry'\n | 'ComputedState'\n | 'ComputeFunction'\n | 'MutableState'\n | 'State'\n | 'UIActionTracker'\n | 'UIUpdateDelayer';\n\n// Per-scope defaults. All Warn — Fusion is mostly hot-path compute graph code;\n// noisy scopes need to be opted-in for development.\nconst scopeDefaults: Record<FusionLogScope, LogLevel> = {\n Computed: LogLevel.Warn,\n ComputedRegistry: LogLevel.Warn,\n ComputedState: LogLevel.Warn,\n ComputeFunction: LogLevel.Warn,\n MutableState: LogLevel.Warn,\n State: LogLevel.Warn,\n UIActionTracker: LogLevel.Warn,\n UIUpdateDelayer: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<FusionLogScope>('fusion.', scopeDefaults);\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- JSON.stringify returns undefined for undefined input\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-this-alias */\r\nimport { 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\nimport { getLogs } from './logging.js';\r\n\r\nconst { errorLog } = getLogs('UIActionTracker');\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 // Mirrors UIActionTracker.cs:58 — UI action failure.\r\n errorLog?.log('UI action failed', 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 // Mirrors UIActionTracker.cs:58 — UI action failure.\r\n errorLog?.log('UI action failed', 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 { getLogs } from './logging.js';\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from './update-delayer.js';\r\nimport { State } from './state.js';\r\n\r\nconst { errorLog } = getLogs('ComputedState');\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 (e) {\r\n // Mirrors ComputedState.cs:188 — UpdateCycle failed and stopped.\r\n if (!disposeSignal.aborted)\r\n errorLog?.log('UpdateCycle() failed and stopped', e);\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","import_core","ConsistencyState","import_core","import_core","import_core","import_core","errorLog","import_core"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import * as _actuallab_core from '@actuallab/core';
|
|
1
2
|
import { IResult, EventHandlerSet, Result, AsyncContext, AsyncContextKey } from '@actuallab/core';
|
|
2
3
|
|
|
4
|
+
type FusionLogScope = 'Computed' | 'ComputedRegistry' | 'ComputedState' | 'ComputeFunction' | 'MutableState' | 'State' | 'UIActionTracker' | 'UIUpdateDelayer';
|
|
5
|
+
declare const getLogs: (scope: FusionLogScope) => _actuallab_core.LogScopeFns;
|
|
6
|
+
|
|
3
7
|
declare const enum ConsistencyState {
|
|
4
8
|
Computing = 0,
|
|
5
9
|
Consistent = 1,
|
|
@@ -202,4 +206,4 @@ declare class MutableState<T> extends State<T> {
|
|
|
202
206
|
set(output: Result<T> | T): void;
|
|
203
207
|
}
|
|
204
208
|
|
|
205
|
-
export { ComputeContext, ComputeFunction, type ComputeFunctionImpl, Computed, type ComputedInput, ComputedRegistry, ComputedState, type ComputedStateOptions, ConsistencyState, FixedDelayer, type MethodMeta, MutableState, State, StateBoundComputed, type StateComputer, UIActionTracker, UIUpdateDelayer, type UpdateDelayer, computeContextKey, computeMethod, defaultUpdateDelayer, getInstanceId, getMethodsMeta, uiActions, wrapComputeMethod };
|
|
209
|
+
export { ComputeContext, ComputeFunction, type ComputeFunctionImpl, Computed, type ComputedInput, ComputedRegistry, ComputedState, type ComputedStateOptions, ConsistencyState, FixedDelayer, type FusionLogScope, type MethodMeta, MutableState, State, StateBoundComputed, type StateComputer, UIActionTracker, UIUpdateDelayer, type UpdateDelayer, computeContextKey, computeMethod, defaultUpdateDelayer, getInstanceId, getLogs, getMethodsMeta, uiActions, wrapComputeMethod };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import * as _actuallab_core from '@actuallab/core';
|
|
1
2
|
import { IResult, EventHandlerSet, Result, AsyncContext, AsyncContextKey } from '@actuallab/core';
|
|
2
3
|
|
|
4
|
+
type FusionLogScope = 'Computed' | 'ComputedRegistry' | 'ComputedState' | 'ComputeFunction' | 'MutableState' | 'State' | 'UIActionTracker' | 'UIUpdateDelayer';
|
|
5
|
+
declare const getLogs: (scope: FusionLogScope) => _actuallab_core.LogScopeFns;
|
|
6
|
+
|
|
3
7
|
declare const enum ConsistencyState {
|
|
4
8
|
Computing = 0,
|
|
5
9
|
Consistent = 1,
|
|
@@ -202,4 +206,4 @@ declare class MutableState<T> extends State<T> {
|
|
|
202
206
|
set(output: Result<T> | T): void;
|
|
203
207
|
}
|
|
204
208
|
|
|
205
|
-
export { ComputeContext, ComputeFunction, type ComputeFunctionImpl, Computed, type ComputedInput, ComputedRegistry, ComputedState, type ComputedStateOptions, ConsistencyState, FixedDelayer, type MethodMeta, MutableState, State, StateBoundComputed, type StateComputer, UIActionTracker, UIUpdateDelayer, type UpdateDelayer, computeContextKey, computeMethod, defaultUpdateDelayer, getInstanceId, getMethodsMeta, uiActions, wrapComputeMethod };
|
|
209
|
+
export { ComputeContext, ComputeFunction, type ComputeFunctionImpl, Computed, type ComputedInput, ComputedRegistry, ComputedState, type ComputedStateOptions, ConsistencyState, FixedDelayer, type FusionLogScope, type MethodMeta, MutableState, State, StateBoundComputed, type StateComputer, UIActionTracker, UIUpdateDelayer, type UpdateDelayer, computeContextKey, computeMethod, defaultUpdateDelayer, getInstanceId, getLogs, getMethodsMeta, uiActions, wrapComputeMethod };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// src/logging.ts
|
|
2
|
+
import { createLogProvider, LogLevel } from "@actuallab/core";
|
|
3
|
+
var scopeDefaults = {
|
|
4
|
+
Computed: LogLevel.Warn,
|
|
5
|
+
ComputedRegistry: LogLevel.Warn,
|
|
6
|
+
ComputedState: LogLevel.Warn,
|
|
7
|
+
ComputeFunction: LogLevel.Warn,
|
|
8
|
+
MutableState: LogLevel.Warn,
|
|
9
|
+
State: LogLevel.Warn,
|
|
10
|
+
UIActionTracker: LogLevel.Warn,
|
|
11
|
+
UIUpdateDelayer: LogLevel.Warn
|
|
12
|
+
};
|
|
13
|
+
var getLogs = createLogProvider("fusion.", scopeDefaults);
|
|
14
|
+
|
|
1
15
|
// src/computed-input.ts
|
|
2
16
|
var _nextInstanceId = 0;
|
|
3
17
|
var _instanceIds = /* @__PURE__ */ new WeakMap();
|
|
@@ -406,6 +420,7 @@ var defaultUpdateDelayer = FixedDelayer.get(1e3 / 60);
|
|
|
406
420
|
|
|
407
421
|
// src/ui-action-tracker.ts
|
|
408
422
|
import { EventHandlerSet as EventHandlerSet2 } from "@actuallab/core";
|
|
423
|
+
var { errorLog } = getLogs("UIActionTracker");
|
|
409
424
|
var UIActionTracker = class {
|
|
410
425
|
_activeCount = 0;
|
|
411
426
|
changed = new EventHandlerSet2();
|
|
@@ -420,6 +435,7 @@ var UIActionTracker = class {
|
|
|
420
435
|
try {
|
|
421
436
|
await fn();
|
|
422
437
|
} catch (e) {
|
|
438
|
+
errorLog?.log("UI action failed", e);
|
|
423
439
|
this.errors.push(e);
|
|
424
440
|
} finally {
|
|
425
441
|
this._activeCount--;
|
|
@@ -434,6 +450,7 @@ var UIActionTracker = class {
|
|
|
434
450
|
try {
|
|
435
451
|
return await fn();
|
|
436
452
|
} catch (e) {
|
|
453
|
+
errorLog?.log("UI action failed", e);
|
|
437
454
|
this.errors.push(e);
|
|
438
455
|
throw e;
|
|
439
456
|
} finally {
|
|
@@ -576,6 +593,7 @@ import {
|
|
|
576
593
|
result as result3,
|
|
577
594
|
errorResult as errorResult2
|
|
578
595
|
} from "@actuallab/core";
|
|
596
|
+
var { errorLog: errorLog2 } = getLogs("ComputedState");
|
|
579
597
|
var ComputedState = class extends State {
|
|
580
598
|
_computer;
|
|
581
599
|
_updateDelayer;
|
|
@@ -673,7 +691,9 @@ var ComputedState = class extends State {
|
|
|
673
691
|
this._cancelDelaySource.promise
|
|
674
692
|
]);
|
|
675
693
|
}
|
|
676
|
-
} catch {
|
|
694
|
+
} catch (e) {
|
|
695
|
+
if (!disposeSignal.aborted)
|
|
696
|
+
errorLog2?.log("UpdateCycle() failed and stopped", e);
|
|
677
697
|
}
|
|
678
698
|
}
|
|
679
699
|
};
|
|
@@ -715,6 +735,7 @@ export {
|
|
|
715
735
|
computeMethod,
|
|
716
736
|
defaultUpdateDelayer,
|
|
717
737
|
getInstanceId,
|
|
738
|
+
getLogs,
|
|
718
739
|
getMethodsMeta,
|
|
719
740
|
uiActions,
|
|
720
741
|
wrapComputeMethod
|
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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- JSON.stringify returns undefined for undefined input\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-this-alias */\r\nimport { 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"]}
|
|
1
|
+
{"version":3,"sources":["../src/logging.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":["import { createLogProvider, LogLevel } from '@actuallab/core';\n\n// Per-package log scopes. Use createLogProvider to get a typed helper:\n// const { debugLog, warnLog } = getLogs('Computed');\n// Final scope name is 'fusion.Computed' — the prefix isolates this package's\n// scopes from other packages' scopes when overriding levels at runtime.\nexport type FusionLogScope =\n | 'Computed'\n | 'ComputedRegistry'\n | 'ComputedState'\n | 'ComputeFunction'\n | 'MutableState'\n | 'State'\n | 'UIActionTracker'\n | 'UIUpdateDelayer';\n\n// Per-scope defaults. All Warn — Fusion is mostly hot-path compute graph code;\n// noisy scopes need to be opted-in for development.\nconst scopeDefaults: Record<FusionLogScope, LogLevel> = {\n Computed: LogLevel.Warn,\n ComputedRegistry: LogLevel.Warn,\n ComputedState: LogLevel.Warn,\n ComputeFunction: LogLevel.Warn,\n MutableState: LogLevel.Warn,\n State: LogLevel.Warn,\n UIActionTracker: LogLevel.Warn,\n UIUpdateDelayer: LogLevel.Warn,\n};\n\nexport const getLogs = createLogProvider<FusionLogScope>('fusion.', scopeDefaults);\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- JSON.stringify returns undefined for undefined input\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 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\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","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-this-alias */\r\nimport { 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\nimport { getLogs } from './logging.js';\r\n\r\nconst { errorLog } = getLogs('UIActionTracker');\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 // Mirrors UIActionTracker.cs:58 — UI action failure.\r\n errorLog?.log('UI action failed', 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 // Mirrors UIActionTracker.cs:58 — UI action failure.\r\n errorLog?.log('UI action failed', 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 { getLogs } from './logging.js';\r\nimport { defaultUpdateDelayer, type UpdateDelayer } from './update-delayer.js';\r\nimport { State } from './state.js';\r\n\r\nconst { errorLog } = getLogs('ComputedState');\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 (e) {\r\n // Mirrors ComputedState.cs:188 — UpdateCycle failed and stopped.\r\n if (!disposeSignal.aborted)\r\n errorLog?.log('UpdateCycle() failed and stopped', e);\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","EventHandlerSet","PromiseSource","PromiseSource","AsyncContext","PromiseSource","result","errorResult","errorLog","PromiseSource","AsyncContext","result","errorResult"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actuallab/fusion",
|
|
3
|
-
"version": "12.3.
|
|
3
|
+
"version": "12.3.31",
|
|
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.3.
|
|
29
|
+
"@actuallab/core": "12.3.31"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|