@actuallab/fusion 14.3.26 → 14.3.34

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.
Files changed (2) hide show
  1. package/README.md +112 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @actuallab/fusion
2
+
3
+ [![npm](https://img.shields.io/npm/v/@actuallab/fusion)](https://www.npmjs.com/package/@actuallab/fusion)
4
+ [![Documentation](https://img.shields.io/badge/Documentation-6B5B95)](https://fusion.actuallab.net/PartTS-Fusion)
5
+ [![License](https://img.shields.io/npm/l/@actuallab/fusion)](https://github.com/ActualLab/Fusion/blob/master/LICENSE)
6
+
7
+ The TypeScript implementation of [Fusion](https://fusion.actuallab.net/)'s core: memoized
8
+ computations with automatic dependency tracking and cascading invalidation. It gives you
9
+ `Computed<T>`, the `@computeMethod` decorator, `ComputedState<T>`, `MutableState<T>`, and
10
+ `UIActionTracker` — the same abstractions Fusion provides on .NET.
11
+
12
+ This package works standalone (client-side reactive state, no server needed). Add
13
+ [`@actuallab/fusion-rpc`](https://www.npmjs.com/package/@actuallab/fusion-rpc) to consume
14
+ invalidation-aware Compute Services from a .NET server, and
15
+ [`@actuallab/fusion-react`](https://www.npmjs.com/package/@actuallab/fusion-react) to render them
16
+ in React.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @actuallab/fusion
22
+ ```
23
+
24
+ ESM-first with a CJS fallback; ships its own `.d.ts`. Depends only on `@actuallab/core`.
25
+
26
+ ## Compute methods
27
+
28
+ `@computeMethod` is the equivalent of .NET's `[ComputeMethod]` — it wraps a method with caching and
29
+ dependency tracking. Results are keyed by `JSON.stringify` of the arguments.
30
+
31
+ ```ts
32
+ import { computeMethod } from '@actuallab/fusion';
33
+
34
+ class CounterService {
35
+ private _counters = new Map<string, number>();
36
+
37
+ @computeMethod
38
+ async get(key: string): Promise<number> {
39
+ return this._counters.get(key) ?? 0;
40
+ }
41
+
42
+ @computeMethod
43
+ async sum(key1: string, key2: string): Promise<number> {
44
+ // sum() automatically depends on get(key1) and get(key2)
45
+ return (await this.get(key1)) + (await this.get(key2));
46
+ }
47
+
48
+ increment(key: string): void {
49
+ this._counters.set(key, (this._counters.get(key) ?? 0) + 1);
50
+ (this.get as any).invalidate(key); // cascades into sum()
51
+ }
52
+ }
53
+ ```
54
+
55
+ There is no `Invalidation.Begin()` block here: every bound compute method carries an
56
+ `.invalidate(...args)` function. For standalone functions, use `wrapComputeMethod`.
57
+
58
+ ## Reactive states
59
+
60
+ `ComputedState<T>` recomputes itself whenever anything it used gets invalidated;
61
+ `MutableState<T>` is set by hand and participates in the same dependency graph.
62
+
63
+ ```ts
64
+ import { ComputedState, MutableState, FixedDelayer } from '@actuallab/fusion';
65
+
66
+ const state = new ComputedState(
67
+ async () => `Count: ${await counters.get('a')}`,
68
+ { initialValue: 'loading...', updateDelayer: FixedDelayer.get(500) },
69
+ );
70
+
71
+ await state.whenFirstTimeUpdated();
72
+ state.value; // "Count: 0" — and it updates on its own from here on
73
+ state.dispose(); // required: stops the update loop
74
+
75
+ const query = new MutableState('');
76
+ query.set('fusion'); // invalidates every computation that called query.use()
77
+ ```
78
+
79
+ ## API surface
80
+
81
+ | API | Description |
82
+ |-----|-------------|
83
+ | `Computed<T>`, `ConsistencyState` | Cached computation result: `.value`, `.update()`, `.use()`, `.invalidate()`, `.whenInvalidated()` |
84
+ | `Computed.capture(fn)` | Capture the `Computed<T>` a compute call produced |
85
+ | `computeMethod`, `wrapComputeMethod` | Turn a method / function into a compute function |
86
+ | `ComputedOptions` | Per-method options, e.g. `errorAutoInvalidateDelay` |
87
+ | `ComputedRegistry`, `ComputeFunction`, `ComputeContext` | The kernel, for advanced/custom integrations |
88
+ | `State<T>`, `ComputedState<T>`, `MutableState<T>` | Reactive states |
89
+ | `UpdateDelayer`, `FixedDelayer`, `UIUpdateDelayer`, `defaultUpdateDelayer` | Recompute pacing (≈32 ms floor, retry backoff) |
90
+ | `UIActionTracker`, `uiActions` | Tracks running UI commands, collects errors, enables instant updates |
91
+
92
+ ## Notes
93
+
94
+ - **Dependency tracking across `await`.** On Node ≥ 20.16 `AsyncContext` is backed by
95
+ `AsyncLocalStorage`, so it just works. In browsers the child `AsyncContext` is passed to your
96
+ compute method as a trailing argument — accept it and forward it into nested compute calls. See
97
+ [AsyncContext: Why It Matters](https://fusion.actuallab.net/PartTS#asynccontext-why-it-matters).
98
+ - **Dispose your `ComputedState`s.** Otherwise their update loops keep running.
99
+ - **Errors.** Compute methods auto-invalidate an error output after 1 s by default (configurable
100
+ via `@computeMethod({ errorAutoInvalidateDelay })`); states never do — they retry with backoff.
101
+ Cancellation-shaped errors are never cached.
102
+
103
+ ## Documentation
104
+
105
+ - [`@actuallab/fusion` reference](https://fusion.actuallab.net/PartTS-Fusion) — full API tables and semantics
106
+ - [TypeScript port overview](https://fusion.actuallab.net/PartTS)
107
+ - [Compute Services](https://fusion.actuallab.net/PartF) and [States](https://fusion.actuallab.net/PartF-ST) — the concepts, in .NET terms
108
+ - [TodoApp sample (React + Fusion)](https://github.com/ActualLab/Fusion.Samples/tree/master/src/TodoApp)
109
+
110
+ ## License
111
+
112
+ MIT — see [LICENSE](https://github.com/ActualLab/Fusion/blob/master/LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actuallab/fusion",
3
- "version": "14.3.26",
3
+ "version": "14.3.34",
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": "14.3.26"
29
+ "@actuallab/core": "14.3.34"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public"