r-state-tree 0.7.0 → 0.8.0
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/README.md +93 -51
- package/dist/api.d.ts +2 -2
- package/dist/decorators.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/model/Model.d.ts +5 -9
- package/dist/model/ModelAdministration.d.ts +11 -0
- package/dist/model/idMap.d.ts +4 -4
- package/dist/observables/preact.d.ts +1 -1
- package/dist/r-state-tree.cjs +428 -262
- package/dist/r-state-tree.js +428 -262
- package/dist/store/Store.d.ts +5 -4
- package/dist/store/StoreAdministration.d.ts +8 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ export default defineConfig({
|
|
|
62
62
|
|
|
63
63
|
## Core concepts
|
|
64
64
|
|
|
65
|
-
- Stores: application/view state containers. Create with `createStore()`, attach with `mount()`. Compose with `@child`
|
|
65
|
+
- Stores: application/view state containers. Create with `createStore()`, attach with `mount()`, and dispose with `Symbol.dispose`. Compose with `@child` and register owned `effect`/`reaction` behavior in constructors. Update reactive `props` via `updateStore()`.
|
|
66
66
|
- Models: domain state containers. Create with `Model.create()`. Persistent via snapshots (`toSnapshot`, `applySnapshot`, `onSnapshot`, diffs via `onSnapshotDiff`). Structure with `@state`, `@child`, identifiers via `@id`, and references via `@modelRef`.
|
|
67
67
|
- Context: pass data through Store/Model trees without prop drilling using `createContext<T>()`, `[Context.provide]`, and `Context.consume(this)`. Context is reactive and can be overridden by descendants.
|
|
68
68
|
- Reactivity: powered by signals. Use `observable()`, `computed` / `@computed`, `effect`, `reaction`, `batch`, and `untracked` for precise updates.
|
|
@@ -139,7 +139,7 @@ app.todo.title;
|
|
|
139
139
|
|
|
140
140
|
- Always create with `createStore()` and attach with `mount()`. Stores cannot be constructed with `new` directly.
|
|
141
141
|
- Prefer no custom constructor. Type stores as `Store<Props>` and access props via `this.props`.
|
|
142
|
-
-
|
|
142
|
+
- Constructors may register framework-owned reactions and effects after `super(props)`. Gate external resource acquisition on `isMounted` and return cleanup from effects.
|
|
143
143
|
- Do not shadow or re-declare `props` as a class field; `props` is read-only. Use the generic `Store<{ ... }>` for typing.
|
|
144
144
|
|
|
145
145
|
```ts
|
|
@@ -203,20 +203,28 @@ class ItemsStore extends Store {
|
|
|
203
203
|
}
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
###
|
|
206
|
+
### Store lifetime and owned effects
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
Mounted stores expose reactive `isMounted` state and implement `Disposable`:
|
|
209
209
|
|
|
210
210
|
```ts
|
|
211
211
|
class TodoStore extends Store {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
212
|
+
constructor(props) {
|
|
213
|
+
super(props);
|
|
214
|
+
this.effect(() => {
|
|
215
|
+
if (!this.isMounted) return;
|
|
216
|
+
const connection = connect();
|
|
217
|
+
return () => connection.close();
|
|
218
|
+
});
|
|
218
219
|
}
|
|
219
220
|
}
|
|
221
|
+
|
|
222
|
+
const store = mount(createStore(TodoStore));
|
|
223
|
+
store[Symbol.dispose]();
|
|
224
|
+
|
|
225
|
+
{
|
|
226
|
+
using store = mount(createStore(TodoStore));
|
|
227
|
+
} // Symbol.dispose is called automatically
|
|
220
228
|
```
|
|
221
229
|
|
|
222
230
|
### Reactions
|
|
@@ -225,10 +233,11 @@ Create side effects that run when reactive values change:
|
|
|
225
233
|
|
|
226
234
|
```ts
|
|
227
235
|
class TodoStore extends Store {
|
|
228
|
-
|
|
236
|
+
constructor(props) {
|
|
237
|
+
super(props);
|
|
229
238
|
this.reaction(
|
|
230
239
|
() => this.props.title,
|
|
231
|
-
(title) => console.log(
|
|
240
|
+
(title, previousTitle) => console.log(previousTitle, "->", title)
|
|
232
241
|
);
|
|
233
242
|
}
|
|
234
243
|
}
|
|
@@ -834,37 +843,55 @@ const off = onSnapshot(list, (snap) => {
|
|
|
834
843
|
|
|
835
844
|
Mutate Models through domain methods and let snapshots record changes automatically.
|
|
836
845
|
|
|
837
|
-
### Model
|
|
846
|
+
### Model creation and named factories
|
|
838
847
|
|
|
839
|
-
|
|
848
|
+
`Model.create()` accepts a canonical snapshot. For defaults, identifier generation, normalization, migrations, or external API formats, use a named static factory that prepares the input before calling `create()`:
|
|
840
849
|
|
|
841
850
|
```ts
|
|
842
851
|
class TodoModel extends Model {
|
|
843
|
-
@
|
|
852
|
+
@id id = "";
|
|
853
|
+
@state title = "";
|
|
844
854
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
855
|
+
static new(title = "Untitled") {
|
|
856
|
+
return this.create({
|
|
857
|
+
id: crypto.randomUUID(),
|
|
858
|
+
title: title.trim(),
|
|
859
|
+
});
|
|
849
860
|
}
|
|
850
861
|
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
862
|
+
static fromApi(input: ApiTodo) {
|
|
863
|
+
return this.create({
|
|
864
|
+
id: input.todo_id,
|
|
865
|
+
title: input.name.trim(),
|
|
866
|
+
});
|
|
854
867
|
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
const todo = TodoModel.new(" Write documentation ");
|
|
871
|
+
todo.title; // "Write documentation"
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
This keeps snapshot hydration predictable: `create(snapshot)` and `applySnapshot(model, snapshot)` both consume the same canonical shape. Named factories make non-canonical inputs and generated values explicit and independently typed. Nested snapshots must already be canonical.
|
|
875
|
+
|
|
876
|
+
### Model attachment and disposal
|
|
877
|
+
|
|
878
|
+
The public `parent` relationship is reactive. Register a model-owned reaction in the constructor to observe attachment and detachment:
|
|
855
879
|
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
880
|
+
```ts
|
|
881
|
+
class TodoModel extends Model {
|
|
882
|
+
@child tags: TagModel[] = [];
|
|
883
|
+
|
|
884
|
+
constructor() {
|
|
885
|
+
super();
|
|
886
|
+
this.reaction(() => this.parent, (parent, previousParent) => {
|
|
887
|
+
if (previousParent) console.log("detached", previousParent);
|
|
888
|
+
if (parent) console.log("attached", parent);
|
|
889
|
+
});
|
|
859
890
|
}
|
|
860
891
|
}
|
|
861
892
|
```
|
|
862
893
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
- `modelDidInit`: initialize/normalize data based on the initial snapshot.
|
|
866
|
-
- `modelDidAttach`: link to other models or read context after the model is part of a tree.
|
|
867
|
-
- `modelWillDetach`: cleanup before the model is removed or replaced.
|
|
894
|
+
Detachment is reversible; model-owned effects survive reattachment. `model[Symbol.dispose]()` is terminal and recursively disposes owned child models, but never model refs.
|
|
868
895
|
|
|
869
896
|
### Model configuration
|
|
870
897
|
|
|
@@ -883,7 +910,7 @@ class User extends Model {
|
|
|
883
910
|
class TodoModel extends Model {
|
|
884
911
|
@id id = 0;
|
|
885
912
|
@state title = "";
|
|
886
|
-
@modelRef assignee?: User; // Reference to another model by ID
|
|
913
|
+
@modelRef(User) assignee?: User; // Reference to another model by ID
|
|
887
914
|
@child metadata = MetadataModel.create(); // Nested child model
|
|
888
915
|
@child tags: TagModel[] = []; // Array of child models
|
|
889
916
|
}
|
|
@@ -928,14 +955,14 @@ class TodoModel extends Model {
|
|
|
928
955
|
|
|
929
956
|
### Model references
|
|
930
957
|
|
|
931
|
-
Reference models by ID using `@modelRef` (or `static types`):
|
|
958
|
+
Reference models by ID using `@modelRef(ModelType)` (or `modelRef(ModelType)` in `static types`). The model constructor is required because identifiers are namespaced by model type:
|
|
932
959
|
|
|
933
960
|
```ts
|
|
934
961
|
class ProjectModel extends Model {
|
|
935
962
|
@id id = 0;
|
|
936
963
|
@child users: User[] = [];
|
|
937
|
-
@modelRef owner?: User; // Single reference
|
|
938
|
-
@modelRef assignees: User[] = []; // Array of references
|
|
964
|
+
@modelRef(User) owner?: User; // Single reference
|
|
965
|
+
@modelRef(User) assignees: User[] = []; // Array of references
|
|
939
966
|
|
|
940
967
|
assignOwner(userId: number) {
|
|
941
968
|
// Find user by ID and set as owner
|
|
@@ -983,9 +1010,10 @@ class ContainerModel extends Model {
|
|
|
983
1010
|
## API surface
|
|
984
1011
|
|
|
985
1012
|
- Stores
|
|
986
|
-
- `Store`, `createStore`, `mount`, `
|
|
1013
|
+
- `Store`, `createStore`, `mount`, `updateStore`
|
|
987
1014
|
- Models
|
|
988
|
-
-
|
|
1015
|
+
- `Model`, `Model.create()`
|
|
1016
|
+
- configuration: decorators (`@state`, `@id`, `@child`, `@modelRef`) or `static types` with `state`, `id`, `child`, `modelRef`
|
|
989
1017
|
- Store configuration
|
|
990
1018
|
- decorators (`@child`, `@model`) or `static types` with `child`, `model`
|
|
991
1019
|
- Snapshots
|
|
@@ -1049,12 +1077,21 @@ Use the observers/renderers provided by the signals bindings for your UI library
|
|
|
1049
1077
|
|
|
1050
1078
|
### Identifier and reference rules
|
|
1051
1079
|
|
|
1052
|
-
- `@id` values are unique within a tree.
|
|
1053
|
-
- Identifiers can be reassigned
|
|
1054
|
-
- `@modelRef`
|
|
1080
|
+
- `@id` values are unique per exact runtime Model class within a tree. Different Model classes may use the same id; subclasses have their own identifier namespace. IDs cannot be cleared to `undefined` after assignment.
|
|
1081
|
+
- Identifiers are mutable and can be reassigned (including in snapshots) as long as the new id is unused by that exact Model class. A failed reassignment preserves the old id and its references.
|
|
1082
|
+
- Use `@modelRef(ModelType)` or `modelRef(ModelType)` when ids can overlap across Model classes; references resolve only within the declared Model class.
|
|
1083
|
+
- `@modelRef(ModelType)` requires an explicit model constructor. The referenced model must have an id and be attached to the tree; the ref becomes `undefined` when the model detaches.
|
|
1055
1084
|
- When a model is re-attached to the same tree, compatible refs restore automatically; attaching to a different root does not restore prior refs.
|
|
1056
1085
|
- `@modelRef` and `@child` can switch between single and array at runtime; reactions observe the property itself rather than internal array mutations.
|
|
1057
1086
|
|
|
1087
|
+
Use `findModelById` for an optional, typed lookup within a model tree:
|
|
1088
|
+
|
|
1089
|
+
```ts
|
|
1090
|
+
const user = findModelById(root, User, 1); // User | undefined
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
The lookup is reactive inside an effect or computed value. It returns `undefined` when the matching model changes its id, detaches, or is disposed.
|
|
1094
|
+
|
|
1058
1095
|
### Snapshot diffs
|
|
1059
1096
|
|
|
1060
1097
|
Use `onSnapshotDiff` to receive undo/redo payloads:
|
|
@@ -1167,17 +1204,22 @@ class ListModel extends Model {
|
|
|
1167
1204
|
}
|
|
1168
1205
|
```
|
|
1169
1206
|
|
|
1170
|
-
Lifecycle
|
|
1207
|
+
Lifecycle registration:
|
|
1171
1208
|
|
|
1172
1209
|
```ts
|
|
1173
1210
|
class M extends Model {
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1211
|
+
constructor() {
|
|
1212
|
+
super();
|
|
1213
|
+
this.reaction(() => this.parent, (parent, previousParent) => {});
|
|
1214
|
+
}
|
|
1177
1215
|
}
|
|
1178
1216
|
class S extends Store {
|
|
1179
|
-
|
|
1180
|
-
|
|
1217
|
+
constructor(props) {
|
|
1218
|
+
super(props);
|
|
1219
|
+
this.effect(() => {
|
|
1220
|
+
if (!this.isMounted) return;
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1181
1223
|
}
|
|
1182
1224
|
```
|
|
1183
1225
|
|
|
@@ -1199,11 +1241,11 @@ const off = onSnapshot(m, (snap) =>
|
|
|
1199
1241
|
- Mutating raw `@state` arrays/objects in place (`push`, `obj.x = 1`) and expecting snapshots to update. Snapshots are memoized; use reassignment or store `observable()` containers / `signal()` values in `@state`.
|
|
1200
1242
|
- Passing observables to third‑party APIs that expect cloneable/serializable values (e.g. `structuredClone`). Use `source(value)` to get the backing value. It will be observable-free for values written via r-state-tree’s observable APIs (unwrap-on-write), but `source(...)` is **not** guaranteed observable-free if you manually seed observables into backing sources.
|
|
1201
1243
|
- Creating child stores in constructors: `@child` must be on getters so identity and lifecycle can be managed by the framework.
|
|
1202
|
-
- Passing `models` into child stores during mount can create a recursive mount loop.
|
|
1244
|
+
- Passing `models` into child stores during mount can create a recursive mount loop. Break the ownership cycle rather than wiring models back through a child during mount.
|
|
1203
1245
|
|
|
1204
1246
|
### Circular store/model creation
|
|
1205
1247
|
|
|
1206
|
-
When child stores are created during mount with `models` that point back into the parent, it is easy to trigger an endless mount loop. The runtime
|
|
1248
|
+
When child stores are created during mount with `models` that point back into the parent, it is easy to trigger an endless mount loop. The runtime guards this with a descriptive circular-creation error. Break the cycle so models are produced independently of the child mount.
|
|
1207
1249
|
|
|
1208
1250
|
## LLM implementation checklist
|
|
1209
1251
|
|
|
@@ -1222,7 +1264,7 @@ When child stores are created during mount with `models` that point back into th
|
|
|
1222
1264
|
- For `createStore` props, extend `Record<string, unknown>` only if needed; otherwise rely on proper prop types and context.
|
|
1223
1265
|
- Avoid barrel files if they cause import confusion; prefer direct imports.
|
|
1224
1266
|
- Keep file boundaries clean: one model per file; avoid piling multiple models together.
|
|
1225
|
-
- Do not shadow `props
|
|
1267
|
+
- Do not shadow `props`; constructors are the registration phase for owned reactions and effects.
|
|
1226
1268
|
- Use `@model`/`model` for injected models; `@child`/`child` for child stores; stable keys for arrays.
|
|
1227
1269
|
|
|
1228
1270
|
## Typing recipes
|
|
@@ -1236,10 +1278,10 @@ When child stores are created during mount with `models` that point back into th
|
|
|
1236
1278
|
- Configuration (no decorators): `static types = { ... }` with `state`, `id`, `child`, `modelRef`, `model`, `computed`
|
|
1237
1279
|
- Decorators (Models): `@state`, `@id`, `@child`, `@modelRef`
|
|
1238
1280
|
- Decorators (Stores): `@child`, `@model`
|
|
1239
|
-
- Core: `createStore`, `mount`, `
|
|
1281
|
+
- Core: `createStore`, `mount`, `Symbol.dispose`, `updateStore`
|
|
1240
1282
|
- Snapshots: `onSnapshot`, `toSnapshot`, `applySnapshot`, `onSnapshotDiff`
|
|
1241
|
-
- Lifecycle:
|
|
1242
|
-
- Best practices: domain in Models; delegate from Stores; stable keys for `@child`;
|
|
1283
|
+
- Lifecycle: reactive `Store.isMounted`, reactive `Model.parent`, and owned `reaction`/`effect`
|
|
1284
|
+
- Best practices: domain in Models; delegate from Stores; stable keys for `@child`; gate resources on lifecycle state; don’t shadow `props`.
|
|
1243
1285
|
|
|
1244
1286
|
## Testing
|
|
1245
1287
|
|
package/dist/api.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Snapshot, SnapshotDiff } from "./types";
|
|
1
|
+
import type { Snapshot, SnapshotDiff, IdType } from "./types";
|
|
2
2
|
import type Store from "./store/Store";
|
|
3
3
|
import type Model from "./model/Model";
|
|
4
|
+
export declare function findModelById<T extends Model>(root: Model, ModelType: new (...args: any[]) => T, id: IdType): T | undefined;
|
|
4
5
|
export declare function mount<T extends Store>(container: T): T;
|
|
5
|
-
export declare function unmount<S extends Store>(container: S): void;
|
|
6
6
|
export declare function toSnapshot<T extends Model>(model: T): Snapshot<T>;
|
|
7
7
|
export declare function onSnapshot<T extends Model>(model: T, callback: (snapshot: Snapshot<T>, model: T) => void): () => void;
|
|
8
8
|
export declare function onSnapshotDiff<T extends Model>(model: T, callback: (snapshotDiff: SnapshotDiff<T>, model: T) => void): () => void;
|
package/dist/decorators.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@tsmetadata/polyfill";
|
|
2
2
|
export declare const child: any;
|
|
3
|
-
export declare
|
|
3
|
+
export declare function modelRef<T extends Function>(childCtor: T): any;
|
|
4
4
|
export declare const model: any;
|
|
5
5
|
export declare const id: any;
|
|
6
6
|
export declare const state: any;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "@tsmetadata/polyfill";
|
|
2
2
|
import Store, { createStore, updateStore } from "./store/Store";
|
|
3
3
|
import Model from "./model/Model";
|
|
4
|
-
import { mount,
|
|
4
|
+
import { mount, onSnapshot, toSnapshot, applySnapshot, onSnapshotDiff, findModelById } from "./api";
|
|
5
5
|
import { createContext } from "./context";
|
|
6
6
|
import { toObservableTree } from "./toObservableTree";
|
|
7
|
-
export { createStore, Store, Model, mount,
|
|
7
|
+
export { createStore, Store, Model, mount, updateStore, onSnapshot, onSnapshotDiff, toSnapshot, applySnapshot, findModelById, createContext, toObservableTree, };
|
|
8
8
|
export { observable, computed, source, reportChanged, reportObserved, getSignal, isObservable, reaction, Signal, type ReadonlySignal, batch, untracked, effect, signal, Observable, } from "./observables";
|
|
9
9
|
export * from "./decorators";
|
|
10
10
|
export type { Configuration, Snapshot, SnapshotValue, IdType, SnapshotDiff, } from "./types";
|
package/dist/model/Model.d.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import type { ModelConfiguration, Snapshot } from "../types";
|
|
2
|
-
|
|
3
|
-
modelDidInit(...args: infer Args): unknown;
|
|
4
|
-
} ? Args extends [infer Snapshot, ...infer Rest] ? Rest : [] : [];
|
|
5
|
-
export default class Model {
|
|
2
|
+
export default class Model implements Disposable {
|
|
6
3
|
static types?: ModelConfiguration<unknown>;
|
|
7
4
|
static childTypes: object;
|
|
8
5
|
static create<T extends Model = Model>(this: {
|
|
9
6
|
new (...args: unknown[]): T;
|
|
10
|
-
}, snapshot?: Snapshot<T
|
|
7
|
+
}, snapshot?: Snapshot<T>): T;
|
|
11
8
|
constructor();
|
|
12
9
|
get parent(): Model | null;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
reaction<T>(track: () => T, callback: (value: T, previousValue: T) => void): () => void;
|
|
11
|
+
effect(callback: () => void | (() => void)): () => void;
|
|
12
|
+
[Symbol.dispose](): void;
|
|
16
13
|
}
|
|
17
|
-
export {};
|
|
@@ -20,10 +20,16 @@ export declare class ModelAdministration extends PreactObjectAdministration<any>
|
|
|
20
20
|
private computedSnapshot;
|
|
21
21
|
private snapshotMap;
|
|
22
22
|
private contextCache;
|
|
23
|
+
private ownedDisposers;
|
|
24
|
+
private disposed;
|
|
23
25
|
parentName: PropertyKey | null;
|
|
24
26
|
get parent(): ModelAdministration | null;
|
|
25
27
|
set parent(value: ModelAdministration | null);
|
|
26
28
|
setConfiguration(configurationGetter: () => ModelConfiguration<any>): void;
|
|
29
|
+
assertUsable(): void;
|
|
30
|
+
private own;
|
|
31
|
+
reaction<T>(track: () => T, callback: (value: T, previousValue: T) => void): () => void;
|
|
32
|
+
effect(callback: () => void | (() => void)): () => void;
|
|
27
33
|
private get configuration();
|
|
28
34
|
private getReferencedAtom;
|
|
29
35
|
private setState;
|
|
@@ -35,12 +41,17 @@ export declare class ModelAdministration extends PreactObjectAdministration<any>
|
|
|
35
41
|
private getModelRefs;
|
|
36
42
|
private setModelRef;
|
|
37
43
|
private setModelRefs;
|
|
44
|
+
private getRequiredModelRefType;
|
|
45
|
+
private assertModelRefType;
|
|
38
46
|
private attach;
|
|
47
|
+
private getReactiveRoot;
|
|
39
48
|
private detach;
|
|
49
|
+
dispose(internal?: boolean): void;
|
|
40
50
|
getContextValue<T>(contextId: symbol, provideSymbol: symbol, defaultValue: T | undefined, hasDefault: boolean): T;
|
|
41
51
|
private lookupContextValue;
|
|
42
52
|
private toJSON;
|
|
43
53
|
onSnapshotChange(onChange: SnapshotChange<any>): () => void;
|
|
44
54
|
loadSnapshot(snapshot: Snapshot<any>): void;
|
|
45
55
|
getSnapshot(): Snapshot<any>;
|
|
56
|
+
getSnapshotForRollback(): Snapshot<any>;
|
|
46
57
|
}
|
package/dist/model/idMap.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { IdType } from "../types";
|
|
2
|
-
import
|
|
3
|
-
export
|
|
4
|
-
export declare function setIdentifier(model: Model, id:
|
|
2
|
+
import Model from "./Model";
|
|
3
|
+
export type ModelConstructor<T extends Model = Model> = new (...args: any[]) => T;
|
|
4
|
+
export declare function setIdentifier(model: Model, id: IdType): void;
|
|
5
5
|
export declare function getIdentifier(model: Model): IdType | undefined;
|
|
6
|
-
export declare function getModelById(root: Model, id: IdType):
|
|
6
|
+
export declare function getModelById<T extends Model>(root: Model, Type: ModelConstructor<T>, id: IdType): T | undefined;
|
|
7
7
|
export declare function onModelAttached(model: Model): void;
|
|
8
8
|
export declare function onModelDetached(model: Model): void;
|
|
@@ -41,7 +41,7 @@ export declare function createSignal<T>(initialValue: T): SignalNode<T>;
|
|
|
41
41
|
export declare function createAtom(): AtomNode;
|
|
42
42
|
export { effect, batch, untracked, Signal };
|
|
43
43
|
export type { ReadonlySignal };
|
|
44
|
-
export declare function reaction<T>(fn: () => T, callback: (value: T) => void): () => void;
|
|
44
|
+
export declare function reaction<T>(fn: () => T, callback: (value: T, previousValue: T) => void): () => void;
|
|
45
45
|
export type Listener = {
|
|
46
46
|
dispose: () => void;
|
|
47
47
|
track: <T>(trackFn: () => T) => T;
|