@zeix/cause-effect 0.17.1 → 0.17.2
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/.ai-context.md +7 -0
- package/.github/copilot-instructions.md +4 -0
- package/CLAUDE.md +96 -1
- package/README.md +44 -7
- package/archive/collection.ts +23 -25
- package/archive/computed.ts +3 -2
- package/archive/list.ts +21 -28
- package/archive/memo.ts +2 -1
- package/archive/state.ts +2 -1
- package/archive/store.ts +21 -32
- package/archive/task.ts +4 -7
- package/index.dev.js +356 -198
- package/index.js +1 -1
- package/index.ts +15 -6
- package/package.json +1 -1
- package/src/classes/collection.ts +69 -53
- package/src/classes/composite.ts +28 -33
- package/src/classes/computed.ts +87 -28
- package/src/classes/list.ts +31 -26
- package/src/classes/ref.ts +33 -5
- package/src/classes/state.ts +41 -8
- package/src/classes/store.ts +47 -30
- package/src/diff.ts +2 -1
- package/src/effect.ts +19 -9
- package/src/errors.ts +10 -1
- package/src/resolve.ts +1 -1
- package/src/signal.ts +0 -1
- package/src/system.ts +159 -43
- package/src/util.ts +0 -6
- package/test/collection.test.ts +279 -20
- package/test/computed.test.ts +268 -11
- package/test/effect.test.ts +2 -2
- package/test/list.test.ts +249 -21
- package/test/ref.test.ts +154 -0
- package/test/state.test.ts +13 -13
- package/test/store.test.ts +473 -28
- package/types/index.d.ts +3 -3
- package/types/src/classes/collection.d.ts +8 -7
- package/types/src/classes/composite.d.ts +4 -4
- package/types/src/classes/computed.d.ts +17 -0
- package/types/src/classes/list.d.ts +2 -2
- package/types/src/classes/ref.d.ts +10 -1
- package/types/src/classes/state.d.ts +9 -0
- package/types/src/classes/store.d.ts +4 -4
- package/types/src/effect.d.ts +1 -2
- package/types/src/errors.d.ts +4 -1
- package/types/src/system.d.ts +40 -24
- package/types/src/util.d.ts +1 -2
package/index.dev.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/util.ts
|
|
2
|
-
var UNSET = Symbol();
|
|
3
2
|
var isString = (value) => typeof value === "string";
|
|
4
3
|
var isNumber = (value) => typeof value === "number";
|
|
5
4
|
var isSymbol = (value) => typeof value === "symbol";
|
|
@@ -14,6 +13,143 @@ var isUniformArray = (value, guard = (item) => item != null) => Array.isArray(va
|
|
|
14
13
|
var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
|
|
15
14
|
var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
16
15
|
|
|
16
|
+
// src/system.ts
|
|
17
|
+
var activeWatcher;
|
|
18
|
+
var unwatchMap = new WeakMap;
|
|
19
|
+
var pendingReactions = new Set;
|
|
20
|
+
var batchDepth = 0;
|
|
21
|
+
var UNSET = Symbol();
|
|
22
|
+
var HOOK_ADD = "add";
|
|
23
|
+
var HOOK_CHANGE = "change";
|
|
24
|
+
var HOOK_CLEANUP = "cleanup";
|
|
25
|
+
var HOOK_REMOVE = "remove";
|
|
26
|
+
var HOOK_SORT = "sort";
|
|
27
|
+
var HOOK_WATCH = "watch";
|
|
28
|
+
var createWatcher = (react) => {
|
|
29
|
+
const cleanups = new Set;
|
|
30
|
+
const watcher = react;
|
|
31
|
+
watcher.on = (type, cleanup) => {
|
|
32
|
+
if (type === HOOK_CLEANUP)
|
|
33
|
+
cleanups.add(cleanup);
|
|
34
|
+
else
|
|
35
|
+
throw new InvalidHookError("watcher", type);
|
|
36
|
+
};
|
|
37
|
+
watcher.stop = () => {
|
|
38
|
+
try {
|
|
39
|
+
for (const cleanup of cleanups)
|
|
40
|
+
cleanup();
|
|
41
|
+
} finally {
|
|
42
|
+
cleanups.clear();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return watcher;
|
|
46
|
+
};
|
|
47
|
+
var subscribeActiveWatcher = (watchers, watchHookCallbacks) => {
|
|
48
|
+
if (!watchers.size && watchHookCallbacks?.size) {
|
|
49
|
+
const unwatch = triggerHook(watchHookCallbacks);
|
|
50
|
+
if (unwatch) {
|
|
51
|
+
const unwatchCallbacks = unwatchMap.get(watchers) ?? new Set;
|
|
52
|
+
unwatchCallbacks.add(unwatch);
|
|
53
|
+
if (!unwatchMap.has(watchers))
|
|
54
|
+
unwatchMap.set(watchers, unwatchCallbacks);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (activeWatcher && !watchers.has(activeWatcher)) {
|
|
58
|
+
const watcher = activeWatcher;
|
|
59
|
+
watcher.on(HOOK_CLEANUP, () => {
|
|
60
|
+
watchers.delete(watcher);
|
|
61
|
+
if (!watchers.size) {
|
|
62
|
+
const unwatchCallbacks = unwatchMap.get(watchers);
|
|
63
|
+
if (unwatchCallbacks) {
|
|
64
|
+
try {
|
|
65
|
+
for (const unwatch of unwatchCallbacks)
|
|
66
|
+
unwatch();
|
|
67
|
+
} finally {
|
|
68
|
+
unwatchCallbacks.clear();
|
|
69
|
+
unwatchMap.delete(watchers);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
watchers.add(watcher);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var notifyWatchers = (watchers) => {
|
|
78
|
+
if (!watchers.size)
|
|
79
|
+
return false;
|
|
80
|
+
for (const react of watchers) {
|
|
81
|
+
if (batchDepth)
|
|
82
|
+
pendingReactions.add(react);
|
|
83
|
+
else
|
|
84
|
+
react();
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
};
|
|
88
|
+
var flushPendingReactions = () => {
|
|
89
|
+
while (pendingReactions.size) {
|
|
90
|
+
const watchers = Array.from(pendingReactions);
|
|
91
|
+
pendingReactions.clear();
|
|
92
|
+
for (const watcher of watchers)
|
|
93
|
+
watcher();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var batchSignalWrites = (callback) => {
|
|
97
|
+
batchDepth++;
|
|
98
|
+
try {
|
|
99
|
+
callback();
|
|
100
|
+
} finally {
|
|
101
|
+
flushPendingReactions();
|
|
102
|
+
batchDepth--;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var trackSignalReads = (watcher, run) => {
|
|
106
|
+
const prev = activeWatcher;
|
|
107
|
+
activeWatcher = watcher || undefined;
|
|
108
|
+
try {
|
|
109
|
+
run();
|
|
110
|
+
} finally {
|
|
111
|
+
activeWatcher = prev;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var triggerHook = (callbacks, payload) => {
|
|
115
|
+
if (!callbacks)
|
|
116
|
+
return;
|
|
117
|
+
const cleanups = [];
|
|
118
|
+
const errors = [];
|
|
119
|
+
const throwError = (inCleanup) => {
|
|
120
|
+
if (errors.length) {
|
|
121
|
+
if (errors.length === 1)
|
|
122
|
+
throw errors[0];
|
|
123
|
+
throw new AggregateError(errors, `Errors in hook ${inCleanup ? "cleanup" : "callback"}:`);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
for (const callback of callbacks) {
|
|
127
|
+
try {
|
|
128
|
+
const cleanup = callback(payload);
|
|
129
|
+
if (isFunction(cleanup))
|
|
130
|
+
cleanups.push(cleanup);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
errors.push(createError(error));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
throwError();
|
|
136
|
+
if (!cleanups.length)
|
|
137
|
+
return;
|
|
138
|
+
if (cleanups.length === 1)
|
|
139
|
+
return cleanups[0];
|
|
140
|
+
return () => {
|
|
141
|
+
for (const cleanup of cleanups) {
|
|
142
|
+
try {
|
|
143
|
+
cleanup();
|
|
144
|
+
} catch (error) {
|
|
145
|
+
errors.push(createError(error));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
throwError(true);
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
var isHandledHook = (type, handled) => handled.includes(type);
|
|
152
|
+
|
|
17
153
|
// src/diff.ts
|
|
18
154
|
var isEqual = (a, b, visited) => {
|
|
19
155
|
if (Object.is(a, b))
|
|
@@ -101,73 +237,6 @@ var diff = (oldObj, newObj) => {
|
|
|
101
237
|
};
|
|
102
238
|
};
|
|
103
239
|
|
|
104
|
-
// src/system.ts
|
|
105
|
-
var activeWatcher;
|
|
106
|
-
var pendingReactions = new Set;
|
|
107
|
-
var batchDepth = 0;
|
|
108
|
-
var createWatcher = (react) => {
|
|
109
|
-
const cleanups = new Set;
|
|
110
|
-
const watcher = react;
|
|
111
|
-
watcher.onCleanup = (cleanup) => {
|
|
112
|
-
cleanups.add(cleanup);
|
|
113
|
-
};
|
|
114
|
-
watcher.stop = () => {
|
|
115
|
-
for (const cleanup of cleanups)
|
|
116
|
-
cleanup();
|
|
117
|
-
cleanups.clear();
|
|
118
|
-
};
|
|
119
|
-
return watcher;
|
|
120
|
-
};
|
|
121
|
-
var subscribeActiveWatcher = (watchers) => {
|
|
122
|
-
if (activeWatcher && !watchers.has(activeWatcher)) {
|
|
123
|
-
const watcher = activeWatcher;
|
|
124
|
-
watcher.onCleanup(() => watchers.delete(watcher));
|
|
125
|
-
watchers.add(watcher);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
var notifyWatchers = (watchers) => {
|
|
129
|
-
for (const react of watchers) {
|
|
130
|
-
if (batchDepth)
|
|
131
|
-
pendingReactions.add(react);
|
|
132
|
-
else
|
|
133
|
-
react();
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
var flushPendingReactions = () => {
|
|
137
|
-
while (pendingReactions.size) {
|
|
138
|
-
const watchers = Array.from(pendingReactions);
|
|
139
|
-
pendingReactions.clear();
|
|
140
|
-
for (const watcher of watchers)
|
|
141
|
-
watcher();
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
var batchSignalWrites = (callback) => {
|
|
145
|
-
batchDepth++;
|
|
146
|
-
try {
|
|
147
|
-
callback();
|
|
148
|
-
} finally {
|
|
149
|
-
flushPendingReactions();
|
|
150
|
-
batchDepth--;
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
var trackSignalReads = (watcher, run) => {
|
|
154
|
-
const prev = activeWatcher;
|
|
155
|
-
activeWatcher = watcher || undefined;
|
|
156
|
-
try {
|
|
157
|
-
run();
|
|
158
|
-
} finally {
|
|
159
|
-
activeWatcher = prev;
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
var emitNotification = (listeners, payload) => {
|
|
163
|
-
for (const listener of listeners) {
|
|
164
|
-
if (batchDepth)
|
|
165
|
-
pendingReactions.add(() => listener(payload));
|
|
166
|
-
else
|
|
167
|
-
listener(payload);
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
240
|
// src/classes/computed.ts
|
|
172
241
|
var TYPE_COMPUTED = "Computed";
|
|
173
242
|
|
|
@@ -179,27 +248,35 @@ class Memo {
|
|
|
179
248
|
#dirty = true;
|
|
180
249
|
#computing = false;
|
|
181
250
|
#watcher;
|
|
251
|
+
#watchHookCallbacks;
|
|
182
252
|
constructor(callback, initialValue = UNSET) {
|
|
183
|
-
validateCallback(
|
|
184
|
-
validateSignalValue(
|
|
253
|
+
validateCallback(this.constructor.name, callback, isMemoCallback);
|
|
254
|
+
validateSignalValue(this.constructor.name, initialValue);
|
|
185
255
|
this.#callback = callback;
|
|
186
256
|
this.#value = initialValue;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.#
|
|
193
|
-
|
|
257
|
+
}
|
|
258
|
+
#getWatcher() {
|
|
259
|
+
if (!this.#watcher) {
|
|
260
|
+
this.#watcher = createWatcher(() => {
|
|
261
|
+
this.#dirty = true;
|
|
262
|
+
if (!notifyWatchers(this.#watchers))
|
|
263
|
+
this.#watcher?.stop();
|
|
264
|
+
});
|
|
265
|
+
this.#watcher.on(HOOK_CLEANUP, () => {
|
|
266
|
+
this.#watcher = undefined;
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return this.#watcher;
|
|
194
270
|
}
|
|
195
271
|
get [Symbol.toStringTag]() {
|
|
196
272
|
return TYPE_COMPUTED;
|
|
197
273
|
}
|
|
198
274
|
get() {
|
|
199
|
-
subscribeActiveWatcher(this.#watchers);
|
|
275
|
+
subscribeActiveWatcher(this.#watchers, this.#watchHookCallbacks);
|
|
200
276
|
flushPendingReactions();
|
|
201
277
|
if (this.#dirty) {
|
|
202
|
-
|
|
278
|
+
const watcher = this.#getWatcher();
|
|
279
|
+
trackSignalReads(watcher, () => {
|
|
203
280
|
if (this.#computing)
|
|
204
281
|
throw new CircularDependencyError("memo");
|
|
205
282
|
let result;
|
|
@@ -227,6 +304,16 @@ class Memo {
|
|
|
227
304
|
throw this.#error;
|
|
228
305
|
return this.#value;
|
|
229
306
|
}
|
|
307
|
+
on(type, callback) {
|
|
308
|
+
if (type === HOOK_WATCH) {
|
|
309
|
+
this.#watchHookCallbacks ||= new Set;
|
|
310
|
+
this.#watchHookCallbacks.add(callback);
|
|
311
|
+
return () => {
|
|
312
|
+
this.#watchHookCallbacks?.delete(callback);
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
throw new InvalidHookError(this.constructor.name, type);
|
|
316
|
+
}
|
|
230
317
|
}
|
|
231
318
|
|
|
232
319
|
class Task {
|
|
@@ -239,28 +326,34 @@ class Task {
|
|
|
239
326
|
#changed = false;
|
|
240
327
|
#watcher;
|
|
241
328
|
#controller;
|
|
329
|
+
#watchHookCallbacks;
|
|
242
330
|
constructor(callback, initialValue = UNSET) {
|
|
243
|
-
validateCallback(
|
|
244
|
-
validateSignalValue(
|
|
331
|
+
validateCallback(this.constructor.name, callback, isTaskCallback);
|
|
332
|
+
validateSignalValue(this.constructor.name, initialValue);
|
|
245
333
|
this.#callback = callback;
|
|
246
334
|
this.#value = initialValue;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.#
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.#
|
|
257
|
-
|
|
335
|
+
}
|
|
336
|
+
#getWatcher() {
|
|
337
|
+
if (!this.#watcher) {
|
|
338
|
+
this.#watcher = createWatcher(() => {
|
|
339
|
+
this.#dirty = true;
|
|
340
|
+
this.#controller?.abort();
|
|
341
|
+
if (!notifyWatchers(this.#watchers))
|
|
342
|
+
this.#watcher?.stop();
|
|
343
|
+
});
|
|
344
|
+
this.#watcher.on(HOOK_CLEANUP, () => {
|
|
345
|
+
this.#controller?.abort();
|
|
346
|
+
this.#controller = undefined;
|
|
347
|
+
this.#watcher = undefined;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return this.#watcher;
|
|
258
351
|
}
|
|
259
352
|
get [Symbol.toStringTag]() {
|
|
260
353
|
return TYPE_COMPUTED;
|
|
261
354
|
}
|
|
262
355
|
get() {
|
|
263
|
-
subscribeActiveWatcher(this.#watchers);
|
|
356
|
+
subscribeActiveWatcher(this.#watchers, this.#watchHookCallbacks);
|
|
264
357
|
flushPendingReactions();
|
|
265
358
|
const ok = (v) => {
|
|
266
359
|
if (!isEqual(v, this.#value)) {
|
|
@@ -285,10 +378,10 @@ class Task {
|
|
|
285
378
|
this.#computing = false;
|
|
286
379
|
this.#controller = undefined;
|
|
287
380
|
fn(arg);
|
|
288
|
-
if (this.#changed)
|
|
289
|
-
|
|
381
|
+
if (this.#changed && !notifyWatchers(this.#watchers))
|
|
382
|
+
this.#watcher?.stop();
|
|
290
383
|
};
|
|
291
|
-
const compute = () => trackSignalReads(this.#
|
|
384
|
+
const compute = () => trackSignalReads(this.#getWatcher(), () => {
|
|
292
385
|
if (this.#computing)
|
|
293
386
|
throw new CircularDependencyError("task");
|
|
294
387
|
this.#changed = false;
|
|
@@ -328,6 +421,16 @@ class Task {
|
|
|
328
421
|
throw this.#error;
|
|
329
422
|
return this.#value;
|
|
330
423
|
}
|
|
424
|
+
on(type, callback) {
|
|
425
|
+
if (type === HOOK_WATCH) {
|
|
426
|
+
this.#watchHookCallbacks ||= new Set;
|
|
427
|
+
this.#watchHookCallbacks.add(callback);
|
|
428
|
+
return () => {
|
|
429
|
+
this.#watchHookCallbacks?.delete(callback);
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
throw new InvalidHookError(this.constructor.name, type);
|
|
433
|
+
}
|
|
331
434
|
}
|
|
332
435
|
var createComputed = (callback, initialValue = UNSET) => isAsyncFunction(callback) ? new Task(callback, initialValue) : new Memo(callback, initialValue);
|
|
333
436
|
var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
|
|
@@ -340,11 +443,7 @@ class Composite {
|
|
|
340
443
|
#validate;
|
|
341
444
|
#create;
|
|
342
445
|
#watchers = new Map;
|
|
343
|
-
#
|
|
344
|
-
add: new Set,
|
|
345
|
-
change: new Set,
|
|
346
|
-
remove: new Set
|
|
347
|
-
};
|
|
446
|
+
#hookCallbacks = {};
|
|
348
447
|
#batching = false;
|
|
349
448
|
constructor(values, validate, create) {
|
|
350
449
|
this.#validate = validate;
|
|
@@ -361,7 +460,7 @@ class Composite {
|
|
|
361
460
|
trackSignalReads(watcher, () => {
|
|
362
461
|
this.signals.get(key)?.get();
|
|
363
462
|
if (!this.#batching)
|
|
364
|
-
|
|
463
|
+
triggerHook(this.#hookCallbacks.change, [key]);
|
|
365
464
|
});
|
|
366
465
|
});
|
|
367
466
|
this.#watchers.set(key, watcher);
|
|
@@ -371,10 +470,10 @@ class Composite {
|
|
|
371
470
|
if (!this.#validate(key, value))
|
|
372
471
|
return false;
|
|
373
472
|
this.signals.set(key, this.#create(value));
|
|
374
|
-
if (this.#
|
|
473
|
+
if (this.#hookCallbacks.change?.size)
|
|
375
474
|
this.#addWatcher(key);
|
|
376
475
|
if (!this.#batching)
|
|
377
|
-
|
|
476
|
+
triggerHook(this.#hookCallbacks.add, [key]);
|
|
378
477
|
return true;
|
|
379
478
|
}
|
|
380
479
|
remove(key) {
|
|
@@ -387,7 +486,7 @@ class Composite {
|
|
|
387
486
|
this.#watchers.delete(key);
|
|
388
487
|
}
|
|
389
488
|
if (!this.#batching)
|
|
390
|
-
|
|
489
|
+
triggerHook(this.#hookCallbacks.remove, [key]);
|
|
391
490
|
return true;
|
|
392
491
|
}
|
|
393
492
|
change(changes, initialRun) {
|
|
@@ -395,7 +494,7 @@ class Composite {
|
|
|
395
494
|
if (Object.keys(changes.add).length) {
|
|
396
495
|
for (const key in changes.add)
|
|
397
496
|
this.add(key, changes.add[key]);
|
|
398
|
-
const notify = () =>
|
|
497
|
+
const notify = () => triggerHook(this.#hookCallbacks.add, Object.keys(changes.add));
|
|
399
498
|
if (initialRun)
|
|
400
499
|
setTimeout(notify, 0);
|
|
401
500
|
else
|
|
@@ -412,12 +511,12 @@ class Composite {
|
|
|
412
511
|
signal.set(value);
|
|
413
512
|
}
|
|
414
513
|
});
|
|
415
|
-
|
|
514
|
+
triggerHook(this.#hookCallbacks.change, Object.keys(changes.change));
|
|
416
515
|
}
|
|
417
516
|
if (Object.keys(changes.remove).length) {
|
|
418
517
|
for (const key in changes.remove)
|
|
419
518
|
this.remove(key);
|
|
420
|
-
|
|
519
|
+
triggerHook(this.#hookCallbacks.remove, Object.keys(changes.remove));
|
|
421
520
|
}
|
|
422
521
|
this.#batching = false;
|
|
423
522
|
return changes.changed;
|
|
@@ -426,20 +525,23 @@ class Composite {
|
|
|
426
525
|
const keys = Array.from(this.signals.keys());
|
|
427
526
|
this.signals.clear();
|
|
428
527
|
this.#watchers.clear();
|
|
429
|
-
|
|
528
|
+
triggerHook(this.#hookCallbacks.remove, keys);
|
|
430
529
|
return true;
|
|
431
530
|
}
|
|
432
|
-
on(type,
|
|
433
|
-
|
|
434
|
-
|
|
531
|
+
on(type, callback) {
|
|
532
|
+
if (!isHandledHook(type, [HOOK_ADD, HOOK_CHANGE, HOOK_REMOVE]))
|
|
533
|
+
throw new InvalidHookError("Composite", type);
|
|
534
|
+
this.#hookCallbacks[type] ||= new Set;
|
|
535
|
+
this.#hookCallbacks[type].add(callback);
|
|
536
|
+
if (type === HOOK_CHANGE && !this.#watchers.size) {
|
|
435
537
|
this.#batching = true;
|
|
436
538
|
for (const key of this.signals.keys())
|
|
437
539
|
this.#addWatcher(key);
|
|
438
540
|
this.#batching = false;
|
|
439
541
|
}
|
|
440
542
|
return () => {
|
|
441
|
-
this.#
|
|
442
|
-
if (type ===
|
|
543
|
+
this.#hookCallbacks[type]?.delete(callback);
|
|
544
|
+
if (type === HOOK_CHANGE && !this.#hookCallbacks.change?.size) {
|
|
443
545
|
if (this.#watchers.size) {
|
|
444
546
|
for (const watcher of this.#watchers.values())
|
|
445
547
|
watcher.stop();
|
|
@@ -456,30 +558,42 @@ var TYPE_STATE = "State";
|
|
|
456
558
|
class State {
|
|
457
559
|
#watchers = new Set;
|
|
458
560
|
#value;
|
|
561
|
+
#watchHookCallbacks;
|
|
459
562
|
constructor(initialValue) {
|
|
460
|
-
validateSignalValue(
|
|
563
|
+
validateSignalValue(TYPE_STATE, initialValue);
|
|
461
564
|
this.#value = initialValue;
|
|
462
565
|
}
|
|
463
566
|
get [Symbol.toStringTag]() {
|
|
464
567
|
return TYPE_STATE;
|
|
465
568
|
}
|
|
466
569
|
get() {
|
|
467
|
-
subscribeActiveWatcher(this.#watchers);
|
|
570
|
+
subscribeActiveWatcher(this.#watchers, this.#watchHookCallbacks);
|
|
468
571
|
return this.#value;
|
|
469
572
|
}
|
|
470
573
|
set(newValue) {
|
|
471
|
-
validateSignalValue(
|
|
574
|
+
validateSignalValue(TYPE_STATE, newValue);
|
|
472
575
|
if (isEqual(this.#value, newValue))
|
|
473
576
|
return;
|
|
474
577
|
this.#value = newValue;
|
|
475
|
-
|
|
578
|
+
if (this.#watchers.size)
|
|
579
|
+
notifyWatchers(this.#watchers);
|
|
476
580
|
if (UNSET === this.#value)
|
|
477
581
|
this.#watchers.clear();
|
|
478
582
|
}
|
|
479
583
|
update(updater) {
|
|
480
|
-
validateCallback(
|
|
584
|
+
validateCallback(`${TYPE_STATE} update`, updater);
|
|
481
585
|
this.set(updater(this.#value));
|
|
482
586
|
}
|
|
587
|
+
on(type, callback) {
|
|
588
|
+
if (type === HOOK_WATCH) {
|
|
589
|
+
this.#watchHookCallbacks ||= new Set;
|
|
590
|
+
this.#watchHookCallbacks.add(callback);
|
|
591
|
+
return () => {
|
|
592
|
+
this.#watchHookCallbacks?.delete(callback);
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
throw new InvalidHookError(this.constructor.name, type);
|
|
596
|
+
}
|
|
483
597
|
}
|
|
484
598
|
var isState = (value) => isObjectOfType(value, TYPE_STATE);
|
|
485
599
|
|
|
@@ -489,17 +603,15 @@ var TYPE_LIST = "List";
|
|
|
489
603
|
class List {
|
|
490
604
|
#composite;
|
|
491
605
|
#watchers = new Set;
|
|
492
|
-
#
|
|
493
|
-
sort: new Set
|
|
494
|
-
};
|
|
606
|
+
#hookCallbacks = {};
|
|
495
607
|
#order = [];
|
|
496
608
|
#generateKey;
|
|
497
609
|
constructor(initialValue, keyConfig) {
|
|
498
|
-
validateSignalValue(
|
|
610
|
+
validateSignalValue(TYPE_LIST, initialValue, Array.isArray);
|
|
499
611
|
let keyCounter = 0;
|
|
500
612
|
this.#generateKey = isString(keyConfig) ? () => `${keyConfig}${keyCounter++}` : isFunction(keyConfig) ? (item) => keyConfig(item) : () => String(keyCounter++);
|
|
501
613
|
this.#composite = new Composite(this.#toRecord(initialValue), (key, value) => {
|
|
502
|
-
validateSignalValue(
|
|
614
|
+
validateSignalValue(`${TYPE_LIST} for key "${key}"`, value);
|
|
503
615
|
return true;
|
|
504
616
|
}, (value) => new State(value));
|
|
505
617
|
}
|
|
@@ -535,11 +647,11 @@ class List {
|
|
|
535
647
|
}
|
|
536
648
|
}
|
|
537
649
|
get length() {
|
|
538
|
-
subscribeActiveWatcher(this.#watchers);
|
|
650
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH]);
|
|
539
651
|
return this.#order.length;
|
|
540
652
|
}
|
|
541
653
|
get() {
|
|
542
|
-
subscribeActiveWatcher(this.#watchers);
|
|
654
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH]);
|
|
543
655
|
return this.#value;
|
|
544
656
|
}
|
|
545
657
|
set(newValue) {
|
|
@@ -609,7 +721,7 @@ class List {
|
|
|
609
721
|
if (!isEqual(this.#order, newOrder)) {
|
|
610
722
|
this.#order = newOrder;
|
|
611
723
|
notifyWatchers(this.#watchers);
|
|
612
|
-
|
|
724
|
+
triggerHook(this.#hookCallbacks.sort, this.#order);
|
|
613
725
|
}
|
|
614
726
|
}
|
|
615
727
|
splice(start, deleteCount, ...items) {
|
|
@@ -647,14 +759,17 @@ class List {
|
|
|
647
759
|
}
|
|
648
760
|
return Object.values(remove);
|
|
649
761
|
}
|
|
650
|
-
on(type,
|
|
651
|
-
if (type
|
|
652
|
-
this.#
|
|
762
|
+
on(type, callback) {
|
|
763
|
+
if (isHandledHook(type, [HOOK_SORT, HOOK_WATCH])) {
|
|
764
|
+
this.#hookCallbacks[type] ||= new Set;
|
|
765
|
+
this.#hookCallbacks[type].add(callback);
|
|
653
766
|
return () => {
|
|
654
|
-
this.#
|
|
767
|
+
this.#hookCallbacks[type]?.delete(callback);
|
|
655
768
|
};
|
|
769
|
+
} else if (isHandledHook(type, [HOOK_ADD, HOOK_CHANGE, HOOK_REMOVE])) {
|
|
770
|
+
return this.#composite.on(type, callback);
|
|
656
771
|
}
|
|
657
|
-
|
|
772
|
+
throw new InvalidHookError(TYPE_LIST, type);
|
|
658
773
|
}
|
|
659
774
|
deriveCollection(callback) {
|
|
660
775
|
return new DerivedCollection(this, callback);
|
|
@@ -668,10 +783,11 @@ var TYPE_STORE = "Store";
|
|
|
668
783
|
class BaseStore {
|
|
669
784
|
#composite;
|
|
670
785
|
#watchers = new Set;
|
|
786
|
+
#watchHookCallbacks;
|
|
671
787
|
constructor(initialValue) {
|
|
672
|
-
validateSignalValue(
|
|
788
|
+
validateSignalValue(TYPE_STORE, initialValue, isRecord);
|
|
673
789
|
this.#composite = new Composite(initialValue, (key, value) => {
|
|
674
|
-
validateSignalValue(
|
|
790
|
+
validateSignalValue(`${TYPE_STORE} for key "${key}"`, value);
|
|
675
791
|
return true;
|
|
676
792
|
}, (value) => createMutableSignal(value));
|
|
677
793
|
}
|
|
@@ -691,8 +807,14 @@ class BaseStore {
|
|
|
691
807
|
for (const [key, signal] of this.#composite.signals.entries())
|
|
692
808
|
yield [key, signal];
|
|
693
809
|
}
|
|
810
|
+
keys() {
|
|
811
|
+
return this.#composite.signals.keys();
|
|
812
|
+
}
|
|
813
|
+
byKey(key) {
|
|
814
|
+
return this.#composite.signals.get(key);
|
|
815
|
+
}
|
|
694
816
|
get() {
|
|
695
|
-
subscribeActiveWatcher(this.#watchers);
|
|
817
|
+
subscribeActiveWatcher(this.#watchers, this.#watchHookCallbacks);
|
|
696
818
|
return this.#value;
|
|
697
819
|
}
|
|
698
820
|
set(newValue) {
|
|
@@ -707,18 +829,12 @@ class BaseStore {
|
|
|
707
829
|
if (changed)
|
|
708
830
|
notifyWatchers(this.#watchers);
|
|
709
831
|
}
|
|
710
|
-
keys() {
|
|
711
|
-
return this.#composite.signals.keys();
|
|
712
|
-
}
|
|
713
|
-
byKey(key) {
|
|
714
|
-
return this.#composite.signals.get(key);
|
|
715
|
-
}
|
|
716
832
|
update(fn) {
|
|
717
833
|
this.set(fn(this.get()));
|
|
718
834
|
}
|
|
719
835
|
add(key, value) {
|
|
720
836
|
if (this.#composite.signals.has(key))
|
|
721
|
-
throw new DuplicateKeyError(
|
|
837
|
+
throw new DuplicateKeyError(TYPE_STORE, key, value);
|
|
722
838
|
const ok = this.#composite.add(key, value);
|
|
723
839
|
if (ok)
|
|
724
840
|
notifyWatchers(this.#watchers);
|
|
@@ -729,8 +845,17 @@ class BaseStore {
|
|
|
729
845
|
if (ok)
|
|
730
846
|
notifyWatchers(this.#watchers);
|
|
731
847
|
}
|
|
732
|
-
on(type,
|
|
733
|
-
|
|
848
|
+
on(type, callback) {
|
|
849
|
+
if (type === HOOK_WATCH) {
|
|
850
|
+
this.#watchHookCallbacks ||= new Set;
|
|
851
|
+
this.#watchHookCallbacks.add(callback);
|
|
852
|
+
return () => {
|
|
853
|
+
this.#watchHookCallbacks?.delete(callback);
|
|
854
|
+
};
|
|
855
|
+
} else if (isHandledHook(type, [HOOK_ADD, HOOK_CHANGE, HOOK_REMOVE])) {
|
|
856
|
+
return this.#composite.on(type, callback);
|
|
857
|
+
}
|
|
858
|
+
throw new InvalidHookError(TYPE_STORE, type);
|
|
734
859
|
}
|
|
735
860
|
}
|
|
736
861
|
var createStore = (initialValue) => {
|
|
@@ -820,6 +945,13 @@ class InvalidCollectionSourceError extends TypeError {
|
|
|
820
945
|
}
|
|
821
946
|
}
|
|
822
947
|
|
|
948
|
+
class InvalidHookError extends TypeError {
|
|
949
|
+
constructor(where, type) {
|
|
950
|
+
super(`Invalid hook "${type}" in ${where}`);
|
|
951
|
+
this.name = "InvalidHookError";
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
823
955
|
class InvalidSignalValueError extends TypeError {
|
|
824
956
|
constructor(where, value) {
|
|
825
957
|
super(`Invalid signal value ${valueString(value)} in ${where}`);
|
|
@@ -866,19 +998,14 @@ class DerivedCollection {
|
|
|
866
998
|
#callback;
|
|
867
999
|
#signals = new Map;
|
|
868
1000
|
#ownWatchers = new Map;
|
|
869
|
-
#
|
|
870
|
-
add: new Set,
|
|
871
|
-
change: new Set,
|
|
872
|
-
remove: new Set,
|
|
873
|
-
sort: new Set
|
|
874
|
-
};
|
|
1001
|
+
#hookCallbacks = {};
|
|
875
1002
|
#order = [];
|
|
876
1003
|
constructor(source, callback) {
|
|
877
|
-
validateCallback(
|
|
1004
|
+
validateCallback(TYPE_COLLECTION, callback);
|
|
878
1005
|
if (isFunction(source))
|
|
879
1006
|
source = source();
|
|
880
1007
|
if (!isCollectionSource(source))
|
|
881
|
-
throw new InvalidCollectionSourceError(
|
|
1008
|
+
throw new InvalidCollectionSourceError(TYPE_COLLECTION, source);
|
|
882
1009
|
this.#source = source;
|
|
883
1010
|
this.#callback = callback;
|
|
884
1011
|
for (let i = 0;i < this.#source.length; i++) {
|
|
@@ -887,7 +1014,9 @@ class DerivedCollection {
|
|
|
887
1014
|
continue;
|
|
888
1015
|
this.#add(key);
|
|
889
1016
|
}
|
|
890
|
-
this.#source.on(
|
|
1017
|
+
this.#source.on(HOOK_ADD, (additions) => {
|
|
1018
|
+
if (!additions)
|
|
1019
|
+
return;
|
|
891
1020
|
for (const key of additions) {
|
|
892
1021
|
if (!this.#signals.has(key)) {
|
|
893
1022
|
this.#add(key);
|
|
@@ -897,9 +1026,11 @@ class DerivedCollection {
|
|
|
897
1026
|
}
|
|
898
1027
|
}
|
|
899
1028
|
notifyWatchers(this.#watchers);
|
|
900
|
-
|
|
1029
|
+
triggerHook(this.#hookCallbacks.add, additions);
|
|
901
1030
|
});
|
|
902
|
-
this.#source.on(
|
|
1031
|
+
this.#source.on(HOOK_REMOVE, (removals) => {
|
|
1032
|
+
if (!removals)
|
|
1033
|
+
return;
|
|
903
1034
|
for (const key of removals) {
|
|
904
1035
|
if (!this.#signals.has(key))
|
|
905
1036
|
continue;
|
|
@@ -915,28 +1046,23 @@ class DerivedCollection {
|
|
|
915
1046
|
}
|
|
916
1047
|
this.#order = this.#order.filter(() => true);
|
|
917
1048
|
notifyWatchers(this.#watchers);
|
|
918
|
-
|
|
1049
|
+
triggerHook(this.#hookCallbacks.remove, removals);
|
|
919
1050
|
});
|
|
920
|
-
this.#source.on(
|
|
921
|
-
|
|
1051
|
+
this.#source.on(HOOK_SORT, (newOrder) => {
|
|
1052
|
+
if (newOrder)
|
|
1053
|
+
this.#order = [...newOrder];
|
|
922
1054
|
notifyWatchers(this.#watchers);
|
|
923
|
-
|
|
1055
|
+
triggerHook(this.#hookCallbacks.sort, newOrder);
|
|
924
1056
|
});
|
|
925
1057
|
}
|
|
926
1058
|
#add(key) {
|
|
927
1059
|
const computedCallback = isAsyncCollectionCallback(this.#callback) ? async (_, abort) => {
|
|
928
|
-
const
|
|
929
|
-
if (!sourceSignal)
|
|
930
|
-
return UNSET;
|
|
931
|
-
const sourceValue = sourceSignal.get();
|
|
1060
|
+
const sourceValue = this.#source.byKey(key)?.get();
|
|
932
1061
|
if (sourceValue === UNSET)
|
|
933
1062
|
return UNSET;
|
|
934
1063
|
return this.#callback(sourceValue, abort);
|
|
935
1064
|
} : () => {
|
|
936
|
-
const
|
|
937
|
-
if (!sourceSignal)
|
|
938
|
-
return UNSET;
|
|
939
|
-
const sourceValue = sourceSignal.get();
|
|
1065
|
+
const sourceValue = this.#source.byKey(key)?.get();
|
|
940
1066
|
if (sourceValue === UNSET)
|
|
941
1067
|
return UNSET;
|
|
942
1068
|
return this.#callback(sourceValue);
|
|
@@ -945,7 +1071,7 @@ class DerivedCollection {
|
|
|
945
1071
|
this.#signals.set(key, signal);
|
|
946
1072
|
if (!this.#order.includes(key))
|
|
947
1073
|
this.#order.push(key);
|
|
948
|
-
if (this.#
|
|
1074
|
+
if (this.#hookCallbacks.change?.size)
|
|
949
1075
|
this.#addWatcher(key);
|
|
950
1076
|
return true;
|
|
951
1077
|
}
|
|
@@ -971,20 +1097,16 @@ class DerivedCollection {
|
|
|
971
1097
|
yield signal;
|
|
972
1098
|
}
|
|
973
1099
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return this.#order.length;
|
|
1100
|
+
keys() {
|
|
1101
|
+
return this.#order.values();
|
|
977
1102
|
}
|
|
978
1103
|
get() {
|
|
979
|
-
subscribeActiveWatcher(this.#watchers);
|
|
1104
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH]);
|
|
980
1105
|
return this.#order.map((key) => this.#signals.get(key)?.get()).filter((v) => v != null && v !== UNSET);
|
|
981
1106
|
}
|
|
982
1107
|
at(index) {
|
|
983
1108
|
return this.#signals.get(this.#order[index]);
|
|
984
1109
|
}
|
|
985
|
-
keys() {
|
|
986
|
-
return this.#order.values();
|
|
987
|
-
}
|
|
988
1110
|
byKey(key) {
|
|
989
1111
|
return this.#signals.get(key);
|
|
990
1112
|
}
|
|
@@ -994,26 +1116,40 @@ class DerivedCollection {
|
|
|
994
1116
|
indexOfKey(key) {
|
|
995
1117
|
return this.#order.indexOf(key);
|
|
996
1118
|
}
|
|
997
|
-
on(type,
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
this.#
|
|
1010
|
-
}
|
|
1119
|
+
on(type, callback) {
|
|
1120
|
+
if (isHandledHook(type, [
|
|
1121
|
+
HOOK_ADD,
|
|
1122
|
+
HOOK_CHANGE,
|
|
1123
|
+
HOOK_REMOVE,
|
|
1124
|
+
HOOK_SORT,
|
|
1125
|
+
HOOK_WATCH
|
|
1126
|
+
])) {
|
|
1127
|
+
this.#hookCallbacks[type] ||= new Set;
|
|
1128
|
+
this.#hookCallbacks[type].add(callback);
|
|
1129
|
+
if (type === HOOK_CHANGE && !this.#ownWatchers.size) {
|
|
1130
|
+
for (const key of this.#signals.keys())
|
|
1131
|
+
this.#addWatcher(key);
|
|
1011
1132
|
}
|
|
1012
|
-
|
|
1133
|
+
return () => {
|
|
1134
|
+
this.#hookCallbacks[type]?.delete(callback);
|
|
1135
|
+
if (type === HOOK_CHANGE && !this.#hookCallbacks.change?.size) {
|
|
1136
|
+
if (this.#ownWatchers.size) {
|
|
1137
|
+
for (const watcher of this.#ownWatchers.values())
|
|
1138
|
+
watcher.stop();
|
|
1139
|
+
this.#ownWatchers.clear();
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
}
|
|
1144
|
+
throw new InvalidHookError(TYPE_COLLECTION, type);
|
|
1013
1145
|
}
|
|
1014
1146
|
deriveCollection(callback) {
|
|
1015
1147
|
return new DerivedCollection(this, callback);
|
|
1016
1148
|
}
|
|
1149
|
+
get length() {
|
|
1150
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH]);
|
|
1151
|
+
return this.#order.length;
|
|
1152
|
+
}
|
|
1017
1153
|
}
|
|
1018
1154
|
var isCollection = (value) => isObjectOfType(value, TYPE_COLLECTION);
|
|
1019
1155
|
var isCollectionSource = (value) => isList(value) || isCollection(value);
|
|
@@ -1024,20 +1160,31 @@ var TYPE_REF = "Ref";
|
|
|
1024
1160
|
class Ref {
|
|
1025
1161
|
#watchers = new Set;
|
|
1026
1162
|
#value;
|
|
1163
|
+
#watchHookCallbacks;
|
|
1027
1164
|
constructor(value, guard) {
|
|
1028
|
-
validateSignalValue(
|
|
1165
|
+
validateSignalValue(TYPE_REF, value, guard);
|
|
1029
1166
|
this.#value = value;
|
|
1030
1167
|
}
|
|
1031
1168
|
get [Symbol.toStringTag]() {
|
|
1032
1169
|
return TYPE_REF;
|
|
1033
1170
|
}
|
|
1034
1171
|
get() {
|
|
1035
|
-
subscribeActiveWatcher(this.#watchers);
|
|
1172
|
+
subscribeActiveWatcher(this.#watchers, this.#watchHookCallbacks);
|
|
1036
1173
|
return this.#value;
|
|
1037
1174
|
}
|
|
1038
1175
|
notify() {
|
|
1039
1176
|
notifyWatchers(this.#watchers);
|
|
1040
1177
|
}
|
|
1178
|
+
on(type, callback) {
|
|
1179
|
+
if (type === HOOK_WATCH) {
|
|
1180
|
+
this.#watchHookCallbacks ||= new Set;
|
|
1181
|
+
this.#watchHookCallbacks.add(callback);
|
|
1182
|
+
return () => {
|
|
1183
|
+
this.#watchHookCallbacks?.delete(callback);
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
throw new InvalidHookError(TYPE_REF, type);
|
|
1187
|
+
}
|
|
1041
1188
|
}
|
|
1042
1189
|
var isRef = (value) => isObjectOfType(value, TYPE_REF);
|
|
1043
1190
|
// src/effect.ts
|
|
@@ -1060,26 +1207,30 @@ var createEffect = (callback) => {
|
|
|
1060
1207
|
const currentController = controller;
|
|
1061
1208
|
callback(controller.signal).then((cleanup2) => {
|
|
1062
1209
|
if (isFunction(cleanup2) && controller === currentController)
|
|
1063
|
-
watcher.
|
|
1210
|
+
watcher.on(HOOK_CLEANUP, cleanup2);
|
|
1064
1211
|
}).catch((error) => {
|
|
1065
1212
|
if (!isAbortError(error))
|
|
1066
|
-
console.error("
|
|
1213
|
+
console.error("Error in async effect callback:", error);
|
|
1067
1214
|
});
|
|
1068
1215
|
} else {
|
|
1069
1216
|
cleanup = callback();
|
|
1070
1217
|
if (isFunction(cleanup))
|
|
1071
|
-
watcher.
|
|
1218
|
+
watcher.on(HOOK_CLEANUP, cleanup);
|
|
1072
1219
|
}
|
|
1073
1220
|
} catch (error) {
|
|
1074
1221
|
if (!isAbortError(error))
|
|
1075
|
-
console.error("
|
|
1222
|
+
console.error("Error in effect callback:", error);
|
|
1076
1223
|
}
|
|
1077
1224
|
running = false;
|
|
1078
1225
|
}));
|
|
1079
1226
|
watcher();
|
|
1080
1227
|
return () => {
|
|
1081
1228
|
controller?.abort();
|
|
1082
|
-
|
|
1229
|
+
try {
|
|
1230
|
+
watcher.stop();
|
|
1231
|
+
} catch (error) {
|
|
1232
|
+
console.error("Error in effect cleanup:", error);
|
|
1233
|
+
}
|
|
1083
1234
|
};
|
|
1084
1235
|
};
|
|
1085
1236
|
// src/match.ts
|
|
@@ -1125,6 +1276,7 @@ export {
|
|
|
1125
1276
|
valueString,
|
|
1126
1277
|
validateSignalValue,
|
|
1127
1278
|
validateCallback,
|
|
1279
|
+
triggerHook,
|
|
1128
1280
|
trackSignalReads,
|
|
1129
1281
|
subscribeActiveWatcher,
|
|
1130
1282
|
resolve,
|
|
@@ -1144,6 +1296,7 @@ export {
|
|
|
1144
1296
|
isMutableSignal,
|
|
1145
1297
|
isMemoCallback,
|
|
1146
1298
|
isList,
|
|
1299
|
+
isHandledHook,
|
|
1147
1300
|
isFunction,
|
|
1148
1301
|
isEqual,
|
|
1149
1302
|
isComputed,
|
|
@@ -1152,7 +1305,6 @@ export {
|
|
|
1152
1305
|
isAbortError,
|
|
1153
1306
|
guardMutableSignal,
|
|
1154
1307
|
flushPendingReactions,
|
|
1155
|
-
emitNotification,
|
|
1156
1308
|
diff,
|
|
1157
1309
|
createWatcher,
|
|
1158
1310
|
createStore,
|
|
@@ -1178,6 +1330,12 @@ export {
|
|
|
1178
1330
|
InvalidSignalValueError,
|
|
1179
1331
|
InvalidCollectionSourceError,
|
|
1180
1332
|
InvalidCallbackError,
|
|
1333
|
+
HOOK_WATCH,
|
|
1334
|
+
HOOK_SORT,
|
|
1335
|
+
HOOK_REMOVE,
|
|
1336
|
+
HOOK_CLEANUP,
|
|
1337
|
+
HOOK_CHANGE,
|
|
1338
|
+
HOOK_ADD,
|
|
1181
1339
|
DuplicateKeyError,
|
|
1182
1340
|
DerivedCollection,
|
|
1183
1341
|
CircularDependencyError,
|