@zeix/cause-effect 0.17.2 → 0.17.3
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 +11 -5
- package/.github/copilot-instructions.md +1 -1
- package/.zed/settings.json +3 -0
- package/CLAUDE.md +18 -79
- package/README.md +23 -37
- package/archive/benchmark.ts +0 -5
- package/archive/collection.ts +5 -62
- package/archive/composite.ts +85 -0
- package/archive/computed.ts +17 -20
- package/archive/list.ts +6 -67
- package/archive/memo.ts +13 -14
- package/archive/store.ts +7 -66
- package/archive/task.ts +18 -20
- package/index.dev.js +438 -614
- package/index.js +1 -1
- package/index.ts +8 -19
- package/package.json +6 -6
- package/src/classes/collection.ts +59 -112
- package/src/classes/computed.ts +146 -189
- package/src/classes/list.ts +138 -105
- package/src/classes/ref.ts +16 -42
- package/src/classes/state.ts +16 -45
- package/src/classes/store.ts +107 -72
- package/src/effect.ts +9 -12
- package/src/errors.ts +12 -8
- package/src/signal.ts +3 -1
- package/src/system.ts +136 -154
- package/test/batch.test.ts +4 -11
- package/test/benchmark.test.ts +4 -2
- package/test/collection.test.ts +46 -306
- package/test/computed.test.ts +205 -223
- package/test/list.test.ts +35 -303
- package/test/ref.test.ts +38 -66
- package/test/state.test.ts +6 -12
- package/test/store.test.ts +37 -489
- package/test/util/dependency-graph.ts +2 -2
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +5 -7
- package/types/index.d.ts +2 -2
- package/types/src/classes/collection.d.ts +4 -6
- package/types/src/classes/computed.d.ts +17 -37
- package/types/src/classes/list.d.ts +8 -6
- package/types/src/classes/ref.d.ts +7 -20
- package/types/src/classes/state.d.ts +5 -17
- package/types/src/classes/store.d.ts +12 -11
- package/types/src/errors.d.ts +2 -4
- package/types/src/signal.d.ts +3 -2
- package/types/src/system.d.ts +41 -44
- package/src/classes/composite.ts +0 -171
- package/types/src/classes/composite.d.ts +0 -15
package/index.dev.js
CHANGED
|
@@ -1,38 +1,25 @@
|
|
|
1
|
-
// src/util.ts
|
|
2
|
-
var isString = (value) => typeof value === "string";
|
|
3
|
-
var isNumber = (value) => typeof value === "number";
|
|
4
|
-
var isSymbol = (value) => typeof value === "symbol";
|
|
5
|
-
var isFunction = (fn) => typeof fn === "function";
|
|
6
|
-
var isAsyncFunction = (fn) => isFunction(fn) && fn.constructor.name === "AsyncFunction";
|
|
7
|
-
var isSyncFunction = (fn) => isFunction(fn) && fn.constructor.name !== "AsyncFunction";
|
|
8
|
-
var isNonNullObject = (value) => value != null && typeof value === "object";
|
|
9
|
-
var isObjectOfType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
|
|
10
|
-
var isRecord = (value) => isObjectOfType(value, "Object");
|
|
11
|
-
var isRecordOrArray = (value) => isRecord(value) || Array.isArray(value);
|
|
12
|
-
var isUniformArray = (value, guard = (item) => item != null) => Array.isArray(value) && value.every(guard);
|
|
13
|
-
var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
|
|
14
|
-
var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
15
|
-
|
|
16
1
|
// src/system.ts
|
|
17
2
|
var activeWatcher;
|
|
18
|
-
var
|
|
3
|
+
var watchersMap = new WeakMap;
|
|
4
|
+
var watchedCallbackMap = new WeakMap;
|
|
5
|
+
var unwatchedCallbackMap = new WeakMap;
|
|
19
6
|
var pendingReactions = new Set;
|
|
20
7
|
var batchDepth = 0;
|
|
21
8
|
var UNSET = Symbol();
|
|
22
|
-
var
|
|
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) => {
|
|
9
|
+
var createWatcher = (push, pull) => {
|
|
29
10
|
const cleanups = new Set;
|
|
30
|
-
const watcher =
|
|
31
|
-
watcher.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
11
|
+
const watcher = push;
|
|
12
|
+
watcher.run = () => {
|
|
13
|
+
const prev = activeWatcher;
|
|
14
|
+
activeWatcher = watcher;
|
|
15
|
+
try {
|
|
16
|
+
pull();
|
|
17
|
+
} finally {
|
|
18
|
+
activeWatcher = prev;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
watcher.onCleanup = (cleanup) => {
|
|
22
|
+
cleanups.add(cleanup);
|
|
36
23
|
};
|
|
37
24
|
watcher.stop = () => {
|
|
38
25
|
try {
|
|
@@ -44,38 +31,55 @@ var createWatcher = (react) => {
|
|
|
44
31
|
};
|
|
45
32
|
return watcher;
|
|
46
33
|
};
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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);
|
|
34
|
+
var untrack = (callback) => {
|
|
35
|
+
const prev = activeWatcher;
|
|
36
|
+
activeWatcher = undefined;
|
|
37
|
+
try {
|
|
38
|
+
callback();
|
|
39
|
+
} finally {
|
|
40
|
+
activeWatcher = prev;
|
|
75
41
|
}
|
|
76
42
|
};
|
|
77
|
-
var
|
|
78
|
-
|
|
43
|
+
var registerWatchCallbacks = (signal, watched, unwatched) => {
|
|
44
|
+
watchedCallbackMap.set(signal, watched);
|
|
45
|
+
if (unwatched)
|
|
46
|
+
unwatchedCallbackMap.set(signal, unwatched);
|
|
47
|
+
};
|
|
48
|
+
var subscribeTo = (signal) => {
|
|
49
|
+
if (!activeWatcher || watchersMap.get(signal)?.has(activeWatcher))
|
|
50
|
+
return false;
|
|
51
|
+
const watcher = activeWatcher;
|
|
52
|
+
if (!watchersMap.has(signal))
|
|
53
|
+
watchersMap.set(signal, new Set);
|
|
54
|
+
const watchers = watchersMap.get(signal);
|
|
55
|
+
assert(watchers);
|
|
56
|
+
if (!watchers.size) {
|
|
57
|
+
const watchedCallback = watchedCallbackMap.get(signal);
|
|
58
|
+
if (watchedCallback)
|
|
59
|
+
untrack(watchedCallback);
|
|
60
|
+
}
|
|
61
|
+
watchers.add(watcher);
|
|
62
|
+
watcher.onCleanup(() => {
|
|
63
|
+
watchers.delete(watcher);
|
|
64
|
+
if (!watchers.size) {
|
|
65
|
+
const unwatchedCallback = unwatchedCallbackMap.get(signal);
|
|
66
|
+
if (unwatchedCallback)
|
|
67
|
+
untrack(unwatchedCallback);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return true;
|
|
71
|
+
};
|
|
72
|
+
var unsubscribeAllFrom = (signal) => {
|
|
73
|
+
const watchers = watchersMap.get(signal);
|
|
74
|
+
if (!watchers)
|
|
75
|
+
return;
|
|
76
|
+
for (const watcher of watchers)
|
|
77
|
+
watcher.stop();
|
|
78
|
+
watchers.clear();
|
|
79
|
+
};
|
|
80
|
+
var notifyOf = (signal) => {
|
|
81
|
+
const watchers = watchersMap.get(signal);
|
|
82
|
+
if (!watchers?.size)
|
|
79
83
|
return false;
|
|
80
84
|
for (const react of watchers) {
|
|
81
85
|
if (batchDepth)
|
|
@@ -85,24 +89,24 @@ var notifyWatchers = (watchers) => {
|
|
|
85
89
|
}
|
|
86
90
|
return true;
|
|
87
91
|
};
|
|
88
|
-
var
|
|
92
|
+
var flush = () => {
|
|
89
93
|
while (pendingReactions.size) {
|
|
90
94
|
const watchers = Array.from(pendingReactions);
|
|
91
95
|
pendingReactions.clear();
|
|
92
|
-
for (const
|
|
93
|
-
|
|
96
|
+
for (const react of watchers)
|
|
97
|
+
react();
|
|
94
98
|
}
|
|
95
99
|
};
|
|
96
|
-
var
|
|
100
|
+
var batch = (callback) => {
|
|
97
101
|
batchDepth++;
|
|
98
102
|
try {
|
|
99
103
|
callback();
|
|
100
104
|
} finally {
|
|
101
|
-
|
|
105
|
+
flush();
|
|
102
106
|
batchDepth--;
|
|
103
107
|
}
|
|
104
108
|
};
|
|
105
|
-
var
|
|
109
|
+
var track = (watcher, run) => {
|
|
106
110
|
const prev = activeWatcher;
|
|
107
111
|
activeWatcher = watcher || undefined;
|
|
108
112
|
try {
|
|
@@ -111,44 +115,21 @@ var trackSignalReads = (watcher, run) => {
|
|
|
111
115
|
activeWatcher = prev;
|
|
112
116
|
}
|
|
113
117
|
};
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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);
|
|
118
|
+
|
|
119
|
+
// src/util.ts
|
|
120
|
+
var isString = (value) => typeof value === "string";
|
|
121
|
+
var isNumber = (value) => typeof value === "number";
|
|
122
|
+
var isSymbol = (value) => typeof value === "symbol";
|
|
123
|
+
var isFunction = (fn) => typeof fn === "function";
|
|
124
|
+
var isAsyncFunction = (fn) => isFunction(fn) && fn.constructor.name === "AsyncFunction";
|
|
125
|
+
var isSyncFunction = (fn) => isFunction(fn) && fn.constructor.name !== "AsyncFunction";
|
|
126
|
+
var isNonNullObject = (value) => value != null && typeof value === "object";
|
|
127
|
+
var isObjectOfType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
|
|
128
|
+
var isRecord = (value) => isObjectOfType(value, "Object");
|
|
129
|
+
var isRecordOrArray = (value) => isRecord(value) || Array.isArray(value);
|
|
130
|
+
var isUniformArray = (value, guard = (item) => item != null) => Array.isArray(value) && value.every(guard);
|
|
131
|
+
var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
|
|
132
|
+
var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
152
133
|
|
|
153
134
|
// src/diff.ts
|
|
154
135
|
var isEqual = (a, b, visited) => {
|
|
@@ -241,83 +222,69 @@ var diff = (oldObj, newObj) => {
|
|
|
241
222
|
var TYPE_COMPUTED = "Computed";
|
|
242
223
|
|
|
243
224
|
class Memo {
|
|
244
|
-
#watchers = new Set;
|
|
245
225
|
#callback;
|
|
246
226
|
#value;
|
|
247
227
|
#error;
|
|
248
228
|
#dirty = true;
|
|
249
229
|
#computing = false;
|
|
250
230
|
#watcher;
|
|
251
|
-
|
|
252
|
-
constructor(callback, initialValue = UNSET) {
|
|
231
|
+
constructor(callback, options) {
|
|
253
232
|
validateCallback(this.constructor.name, callback, isMemoCallback);
|
|
254
|
-
|
|
233
|
+
const initialValue = options?.initialValue ?? UNSET;
|
|
234
|
+
validateSignalValue(this.constructor.name, initialValue, options?.guard);
|
|
255
235
|
this.#callback = callback;
|
|
256
236
|
this.#value = initialValue;
|
|
237
|
+
if (options?.watched)
|
|
238
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
257
239
|
}
|
|
258
240
|
#getWatcher() {
|
|
259
|
-
|
|
260
|
-
this.#
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
241
|
+
this.#watcher ||= createWatcher(() => {
|
|
242
|
+
this.#dirty = true;
|
|
243
|
+
if (!notifyOf(this))
|
|
244
|
+
this.#watcher?.stop();
|
|
245
|
+
}, () => {
|
|
246
|
+
if (this.#computing)
|
|
247
|
+
throw new CircularDependencyError("memo");
|
|
248
|
+
let result;
|
|
249
|
+
this.#computing = true;
|
|
250
|
+
try {
|
|
251
|
+
result = this.#callback(this.#value);
|
|
252
|
+
} catch (e) {
|
|
253
|
+
this.#value = UNSET;
|
|
254
|
+
this.#error = createError(e);
|
|
255
|
+
this.#computing = false;
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (result == null || UNSET === result) {
|
|
259
|
+
this.#value = UNSET;
|
|
260
|
+
this.#error = undefined;
|
|
261
|
+
} else {
|
|
262
|
+
this.#value = result;
|
|
263
|
+
this.#error = undefined;
|
|
264
|
+
this.#dirty = false;
|
|
265
|
+
}
|
|
266
|
+
this.#computing = false;
|
|
267
|
+
});
|
|
268
|
+
this.#watcher.onCleanup(() => {
|
|
269
|
+
this.#watcher = undefined;
|
|
270
|
+
});
|
|
269
271
|
return this.#watcher;
|
|
270
272
|
}
|
|
271
273
|
get [Symbol.toStringTag]() {
|
|
272
274
|
return TYPE_COMPUTED;
|
|
273
275
|
}
|
|
274
276
|
get() {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (this.#dirty)
|
|
278
|
-
|
|
279
|
-
trackSignalReads(watcher, () => {
|
|
280
|
-
if (this.#computing)
|
|
281
|
-
throw new CircularDependencyError("memo");
|
|
282
|
-
let result;
|
|
283
|
-
this.#computing = true;
|
|
284
|
-
try {
|
|
285
|
-
result = this.#callback(this.#value);
|
|
286
|
-
} catch (e) {
|
|
287
|
-
this.#value = UNSET;
|
|
288
|
-
this.#error = createError(e);
|
|
289
|
-
this.#computing = false;
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
if (result == null || UNSET === result) {
|
|
293
|
-
this.#value = UNSET;
|
|
294
|
-
this.#error = undefined;
|
|
295
|
-
} else {
|
|
296
|
-
this.#value = result;
|
|
297
|
-
this.#error = undefined;
|
|
298
|
-
this.#dirty = false;
|
|
299
|
-
}
|
|
300
|
-
this.#computing = false;
|
|
301
|
-
});
|
|
302
|
-
}
|
|
277
|
+
subscribeTo(this);
|
|
278
|
+
flush();
|
|
279
|
+
if (this.#dirty)
|
|
280
|
+
this.#getWatcher().run();
|
|
303
281
|
if (this.#error)
|
|
304
282
|
throw this.#error;
|
|
305
283
|
return this.#value;
|
|
306
284
|
}
|
|
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
|
-
}
|
|
317
285
|
}
|
|
318
286
|
|
|
319
287
|
class Task {
|
|
320
|
-
#watchers = new Set;
|
|
321
288
|
#callback;
|
|
322
289
|
#value;
|
|
323
290
|
#error;
|
|
@@ -326,22 +293,83 @@ class Task {
|
|
|
326
293
|
#changed = false;
|
|
327
294
|
#watcher;
|
|
328
295
|
#controller;
|
|
329
|
-
|
|
330
|
-
constructor(callback, initialValue = UNSET) {
|
|
296
|
+
constructor(callback, options) {
|
|
331
297
|
validateCallback(this.constructor.name, callback, isTaskCallback);
|
|
332
|
-
|
|
298
|
+
const initialValue = options?.initialValue ?? UNSET;
|
|
299
|
+
validateSignalValue(this.constructor.name, initialValue, options?.guard);
|
|
333
300
|
this.#callback = callback;
|
|
334
301
|
this.#value = initialValue;
|
|
302
|
+
if (options?.watched)
|
|
303
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
335
304
|
}
|
|
336
305
|
#getWatcher() {
|
|
337
306
|
if (!this.#watcher) {
|
|
307
|
+
const ok = (v) => {
|
|
308
|
+
if (!isEqual(v, this.#value)) {
|
|
309
|
+
this.#value = v;
|
|
310
|
+
this.#changed = true;
|
|
311
|
+
}
|
|
312
|
+
this.#error = undefined;
|
|
313
|
+
this.#dirty = false;
|
|
314
|
+
};
|
|
315
|
+
const nil = () => {
|
|
316
|
+
this.#changed = UNSET !== this.#value;
|
|
317
|
+
this.#value = UNSET;
|
|
318
|
+
this.#error = undefined;
|
|
319
|
+
};
|
|
320
|
+
const err = (e) => {
|
|
321
|
+
const newError = createError(e);
|
|
322
|
+
this.#changed = !this.#error || newError.name !== this.#error.name || newError.message !== this.#error.message;
|
|
323
|
+
this.#value = UNSET;
|
|
324
|
+
this.#error = newError;
|
|
325
|
+
};
|
|
326
|
+
const settle = (fn) => (arg) => {
|
|
327
|
+
this.#computing = false;
|
|
328
|
+
this.#controller = undefined;
|
|
329
|
+
fn(arg);
|
|
330
|
+
if (this.#changed && !notifyOf(this))
|
|
331
|
+
this.#watcher?.stop();
|
|
332
|
+
};
|
|
338
333
|
this.#watcher = createWatcher(() => {
|
|
339
334
|
this.#dirty = true;
|
|
340
335
|
this.#controller?.abort();
|
|
341
|
-
if (!
|
|
336
|
+
if (!notifyOf(this))
|
|
342
337
|
this.#watcher?.stop();
|
|
338
|
+
}, () => {
|
|
339
|
+
if (this.#computing)
|
|
340
|
+
throw new CircularDependencyError("task");
|
|
341
|
+
this.#changed = false;
|
|
342
|
+
if (this.#controller)
|
|
343
|
+
return this.#value;
|
|
344
|
+
this.#controller = new AbortController;
|
|
345
|
+
this.#controller.signal.addEventListener("abort", () => {
|
|
346
|
+
this.#computing = false;
|
|
347
|
+
this.#controller = undefined;
|
|
348
|
+
this.#getWatcher().run();
|
|
349
|
+
}, {
|
|
350
|
+
once: true
|
|
351
|
+
});
|
|
352
|
+
let result;
|
|
353
|
+
this.#computing = true;
|
|
354
|
+
try {
|
|
355
|
+
result = this.#callback(this.#value, this.#controller.signal);
|
|
356
|
+
} catch (e) {
|
|
357
|
+
if (isAbortError(e))
|
|
358
|
+
nil();
|
|
359
|
+
else
|
|
360
|
+
err(e);
|
|
361
|
+
this.#computing = false;
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (result instanceof Promise)
|
|
365
|
+
result.then(settle(ok), settle(err));
|
|
366
|
+
else if (result == null || UNSET === result)
|
|
367
|
+
nil();
|
|
368
|
+
else
|
|
369
|
+
ok(result);
|
|
370
|
+
this.#computing = false;
|
|
343
371
|
});
|
|
344
|
-
this.#watcher.
|
|
372
|
+
this.#watcher.onCleanup(() => {
|
|
345
373
|
this.#controller?.abort();
|
|
346
374
|
this.#controller = undefined;
|
|
347
375
|
this.#watcher = undefined;
|
|
@@ -353,221 +381,36 @@ class Task {
|
|
|
353
381
|
return TYPE_COMPUTED;
|
|
354
382
|
}
|
|
355
383
|
get() {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const ok = (v) => {
|
|
359
|
-
if (!isEqual(v, this.#value)) {
|
|
360
|
-
this.#value = v;
|
|
361
|
-
this.#changed = true;
|
|
362
|
-
}
|
|
363
|
-
this.#error = undefined;
|
|
364
|
-
this.#dirty = false;
|
|
365
|
-
};
|
|
366
|
-
const nil = () => {
|
|
367
|
-
this.#changed = UNSET !== this.#value;
|
|
368
|
-
this.#value = UNSET;
|
|
369
|
-
this.#error = undefined;
|
|
370
|
-
};
|
|
371
|
-
const err = (e) => {
|
|
372
|
-
const newError = createError(e);
|
|
373
|
-
this.#changed = !this.#error || newError.name !== this.#error.name || newError.message !== this.#error.message;
|
|
374
|
-
this.#value = UNSET;
|
|
375
|
-
this.#error = newError;
|
|
376
|
-
};
|
|
377
|
-
const settle = (fn) => (arg) => {
|
|
378
|
-
this.#computing = false;
|
|
379
|
-
this.#controller = undefined;
|
|
380
|
-
fn(arg);
|
|
381
|
-
if (this.#changed && !notifyWatchers(this.#watchers))
|
|
382
|
-
this.#watcher?.stop();
|
|
383
|
-
};
|
|
384
|
-
const compute = () => trackSignalReads(this.#getWatcher(), () => {
|
|
385
|
-
if (this.#computing)
|
|
386
|
-
throw new CircularDependencyError("task");
|
|
387
|
-
this.#changed = false;
|
|
388
|
-
if (this.#controller)
|
|
389
|
-
return this.#value;
|
|
390
|
-
this.#controller = new AbortController;
|
|
391
|
-
this.#controller.signal.addEventListener("abort", () => {
|
|
392
|
-
this.#computing = false;
|
|
393
|
-
this.#controller = undefined;
|
|
394
|
-
compute();
|
|
395
|
-
}, {
|
|
396
|
-
once: true
|
|
397
|
-
});
|
|
398
|
-
let result;
|
|
399
|
-
this.#computing = true;
|
|
400
|
-
try {
|
|
401
|
-
result = this.#callback(this.#value, this.#controller.signal);
|
|
402
|
-
} catch (e) {
|
|
403
|
-
if (isAbortError(e))
|
|
404
|
-
nil();
|
|
405
|
-
else
|
|
406
|
-
err(e);
|
|
407
|
-
this.#computing = false;
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
if (result instanceof Promise)
|
|
411
|
-
result.then(settle(ok), settle(err));
|
|
412
|
-
else if (result == null || UNSET === result)
|
|
413
|
-
nil();
|
|
414
|
-
else
|
|
415
|
-
ok(result);
|
|
416
|
-
this.#computing = false;
|
|
417
|
-
});
|
|
384
|
+
subscribeTo(this);
|
|
385
|
+
flush();
|
|
418
386
|
if (this.#dirty)
|
|
419
|
-
|
|
387
|
+
this.#getWatcher().run();
|
|
420
388
|
if (this.#error)
|
|
421
389
|
throw this.#error;
|
|
422
390
|
return this.#value;
|
|
423
391
|
}
|
|
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
|
-
}
|
|
434
392
|
}
|
|
435
|
-
var createComputed = (callback,
|
|
393
|
+
var createComputed = (callback, options) => isAsyncFunction(callback) ? new Task(callback, options) : new Memo(callback, options);
|
|
436
394
|
var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
|
|
437
395
|
var isMemoCallback = (value) => isSyncFunction(value) && value.length < 2;
|
|
438
396
|
var isTaskCallback = (value) => isAsyncFunction(value) && value.length < 3;
|
|
439
397
|
|
|
440
|
-
// src/classes/composite.ts
|
|
441
|
-
class Composite {
|
|
442
|
-
signals = new Map;
|
|
443
|
-
#validate;
|
|
444
|
-
#create;
|
|
445
|
-
#watchers = new Map;
|
|
446
|
-
#hookCallbacks = {};
|
|
447
|
-
#batching = false;
|
|
448
|
-
constructor(values, validate, create) {
|
|
449
|
-
this.#validate = validate;
|
|
450
|
-
this.#create = create;
|
|
451
|
-
this.change({
|
|
452
|
-
add: values,
|
|
453
|
-
change: {},
|
|
454
|
-
remove: {},
|
|
455
|
-
changed: true
|
|
456
|
-
}, true);
|
|
457
|
-
}
|
|
458
|
-
#addWatcher(key) {
|
|
459
|
-
const watcher = createWatcher(() => {
|
|
460
|
-
trackSignalReads(watcher, () => {
|
|
461
|
-
this.signals.get(key)?.get();
|
|
462
|
-
if (!this.#batching)
|
|
463
|
-
triggerHook(this.#hookCallbacks.change, [key]);
|
|
464
|
-
});
|
|
465
|
-
});
|
|
466
|
-
this.#watchers.set(key, watcher);
|
|
467
|
-
watcher();
|
|
468
|
-
}
|
|
469
|
-
add(key, value) {
|
|
470
|
-
if (!this.#validate(key, value))
|
|
471
|
-
return false;
|
|
472
|
-
this.signals.set(key, this.#create(value));
|
|
473
|
-
if (this.#hookCallbacks.change?.size)
|
|
474
|
-
this.#addWatcher(key);
|
|
475
|
-
if (!this.#batching)
|
|
476
|
-
triggerHook(this.#hookCallbacks.add, [key]);
|
|
477
|
-
return true;
|
|
478
|
-
}
|
|
479
|
-
remove(key) {
|
|
480
|
-
const ok = this.signals.delete(key);
|
|
481
|
-
if (!ok)
|
|
482
|
-
return false;
|
|
483
|
-
const watcher = this.#watchers.get(key);
|
|
484
|
-
if (watcher) {
|
|
485
|
-
watcher.stop();
|
|
486
|
-
this.#watchers.delete(key);
|
|
487
|
-
}
|
|
488
|
-
if (!this.#batching)
|
|
489
|
-
triggerHook(this.#hookCallbacks.remove, [key]);
|
|
490
|
-
return true;
|
|
491
|
-
}
|
|
492
|
-
change(changes, initialRun) {
|
|
493
|
-
this.#batching = true;
|
|
494
|
-
if (Object.keys(changes.add).length) {
|
|
495
|
-
for (const key in changes.add)
|
|
496
|
-
this.add(key, changes.add[key]);
|
|
497
|
-
const notify = () => triggerHook(this.#hookCallbacks.add, Object.keys(changes.add));
|
|
498
|
-
if (initialRun)
|
|
499
|
-
setTimeout(notify, 0);
|
|
500
|
-
else
|
|
501
|
-
notify();
|
|
502
|
-
}
|
|
503
|
-
if (Object.keys(changes.change).length) {
|
|
504
|
-
batchSignalWrites(() => {
|
|
505
|
-
for (const key in changes.change) {
|
|
506
|
-
const value = changes.change[key];
|
|
507
|
-
if (!this.#validate(key, value))
|
|
508
|
-
continue;
|
|
509
|
-
const signal = this.signals.get(key);
|
|
510
|
-
if (guardMutableSignal(`list item "${key}"`, value, signal))
|
|
511
|
-
signal.set(value);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
triggerHook(this.#hookCallbacks.change, Object.keys(changes.change));
|
|
515
|
-
}
|
|
516
|
-
if (Object.keys(changes.remove).length) {
|
|
517
|
-
for (const key in changes.remove)
|
|
518
|
-
this.remove(key);
|
|
519
|
-
triggerHook(this.#hookCallbacks.remove, Object.keys(changes.remove));
|
|
520
|
-
}
|
|
521
|
-
this.#batching = false;
|
|
522
|
-
return changes.changed;
|
|
523
|
-
}
|
|
524
|
-
clear() {
|
|
525
|
-
const keys = Array.from(this.signals.keys());
|
|
526
|
-
this.signals.clear();
|
|
527
|
-
this.#watchers.clear();
|
|
528
|
-
triggerHook(this.#hookCallbacks.remove, keys);
|
|
529
|
-
return true;
|
|
530
|
-
}
|
|
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) {
|
|
537
|
-
this.#batching = true;
|
|
538
|
-
for (const key of this.signals.keys())
|
|
539
|
-
this.#addWatcher(key);
|
|
540
|
-
this.#batching = false;
|
|
541
|
-
}
|
|
542
|
-
return () => {
|
|
543
|
-
this.#hookCallbacks[type]?.delete(callback);
|
|
544
|
-
if (type === HOOK_CHANGE && !this.#hookCallbacks.change?.size) {
|
|
545
|
-
if (this.#watchers.size) {
|
|
546
|
-
for (const watcher of this.#watchers.values())
|
|
547
|
-
watcher.stop();
|
|
548
|
-
this.#watchers.clear();
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
398
|
// src/classes/state.ts
|
|
556
399
|
var TYPE_STATE = "State";
|
|
557
400
|
|
|
558
401
|
class State {
|
|
559
|
-
#watchers = new Set;
|
|
560
402
|
#value;
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
validateSignalValue(TYPE_STATE, initialValue);
|
|
403
|
+
constructor(initialValue, options) {
|
|
404
|
+
validateSignalValue(TYPE_STATE, initialValue, options?.guard);
|
|
564
405
|
this.#value = initialValue;
|
|
406
|
+
if (options?.watched)
|
|
407
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
565
408
|
}
|
|
566
409
|
get [Symbol.toStringTag]() {
|
|
567
410
|
return TYPE_STATE;
|
|
568
411
|
}
|
|
569
412
|
get() {
|
|
570
|
-
|
|
413
|
+
subscribeTo(this);
|
|
571
414
|
return this.#value;
|
|
572
415
|
}
|
|
573
416
|
set(newValue) {
|
|
@@ -575,25 +418,14 @@ class State {
|
|
|
575
418
|
if (isEqual(this.#value, newValue))
|
|
576
419
|
return;
|
|
577
420
|
this.#value = newValue;
|
|
578
|
-
|
|
579
|
-
notifyWatchers(this.#watchers);
|
|
421
|
+
notifyOf(this);
|
|
580
422
|
if (UNSET === this.#value)
|
|
581
|
-
this
|
|
423
|
+
unsubscribeAllFrom(this);
|
|
582
424
|
}
|
|
583
425
|
update(updater) {
|
|
584
426
|
validateCallback(`${TYPE_STATE} update`, updater);
|
|
585
427
|
this.set(updater(this.#value));
|
|
586
428
|
}
|
|
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
|
-
}
|
|
597
429
|
}
|
|
598
430
|
var isState = (value) => isObjectOfType(value, TYPE_STATE);
|
|
599
431
|
|
|
@@ -601,19 +433,27 @@ var isState = (value) => isObjectOfType(value, TYPE_STATE);
|
|
|
601
433
|
var TYPE_LIST = "List";
|
|
602
434
|
|
|
603
435
|
class List {
|
|
604
|
-
#
|
|
605
|
-
#
|
|
606
|
-
#hookCallbacks = {};
|
|
607
|
-
#order = [];
|
|
436
|
+
#signals = new Map;
|
|
437
|
+
#keys = [];
|
|
608
438
|
#generateKey;
|
|
609
|
-
|
|
439
|
+
#validate;
|
|
440
|
+
constructor(initialValue, options) {
|
|
610
441
|
validateSignalValue(TYPE_LIST, initialValue, Array.isArray);
|
|
611
442
|
let keyCounter = 0;
|
|
443
|
+
const keyConfig = options?.keyConfig;
|
|
612
444
|
this.#generateKey = isString(keyConfig) ? () => `${keyConfig}${keyCounter++}` : isFunction(keyConfig) ? (item) => keyConfig(item) : () => String(keyCounter++);
|
|
613
|
-
this.#
|
|
614
|
-
validateSignalValue(`${TYPE_LIST} for key "${key}"`, value);
|
|
445
|
+
this.#validate = (key, value) => {
|
|
446
|
+
validateSignalValue(`${TYPE_LIST} item for key "${key}"`, value, options?.guard);
|
|
615
447
|
return true;
|
|
616
|
-
}
|
|
448
|
+
};
|
|
449
|
+
this.#change({
|
|
450
|
+
add: this.#toRecord(initialValue),
|
|
451
|
+
change: {},
|
|
452
|
+
remove: {},
|
|
453
|
+
changed: true
|
|
454
|
+
});
|
|
455
|
+
if (options?.watched)
|
|
456
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
617
457
|
}
|
|
618
458
|
#toRecord(array) {
|
|
619
459
|
const record = {};
|
|
@@ -621,17 +461,51 @@ class List {
|
|
|
621
461
|
const value = array[i];
|
|
622
462
|
if (value === undefined)
|
|
623
463
|
continue;
|
|
624
|
-
let key = this.#
|
|
464
|
+
let key = this.#keys[i];
|
|
625
465
|
if (!key) {
|
|
626
466
|
key = this.#generateKey(value);
|
|
627
|
-
this.#
|
|
467
|
+
this.#keys[i] = key;
|
|
628
468
|
}
|
|
629
469
|
record[key] = value;
|
|
630
470
|
}
|
|
631
471
|
return record;
|
|
632
472
|
}
|
|
473
|
+
#add(key, value) {
|
|
474
|
+
if (!this.#validate(key, value))
|
|
475
|
+
return false;
|
|
476
|
+
this.#signals.set(key, new State(value));
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
#change(changes) {
|
|
480
|
+
if (Object.keys(changes.add).length) {
|
|
481
|
+
for (const key in changes.add)
|
|
482
|
+
this.#add(key, changes.add[key]);
|
|
483
|
+
}
|
|
484
|
+
if (Object.keys(changes.change).length) {
|
|
485
|
+
batch(() => {
|
|
486
|
+
for (const key in changes.change) {
|
|
487
|
+
const value = changes.change[key];
|
|
488
|
+
if (!this.#validate(key, value))
|
|
489
|
+
continue;
|
|
490
|
+
const signal = this.#signals.get(key);
|
|
491
|
+
if (guardMutableSignal(`${TYPE_LIST} item "${key}"`, value, signal))
|
|
492
|
+
signal.set(value);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
if (Object.keys(changes.remove).length) {
|
|
497
|
+
for (const key in changes.remove) {
|
|
498
|
+
this.#signals.delete(key);
|
|
499
|
+
const index = this.#keys.indexOf(key);
|
|
500
|
+
if (index !== -1)
|
|
501
|
+
this.#keys.splice(index, 1);
|
|
502
|
+
}
|
|
503
|
+
this.#keys = this.#keys.filter(() => true);
|
|
504
|
+
}
|
|
505
|
+
return changes.changed;
|
|
506
|
+
}
|
|
633
507
|
get #value() {
|
|
634
|
-
return this.#
|
|
508
|
+
return this.#keys.map((key) => this.#signals.get(key)?.get()).filter((v) => v !== undefined);
|
|
635
509
|
}
|
|
636
510
|
get [Symbol.toStringTag]() {
|
|
637
511
|
return TYPE_LIST;
|
|
@@ -640,139 +514,117 @@ class List {
|
|
|
640
514
|
return true;
|
|
641
515
|
}
|
|
642
516
|
*[Symbol.iterator]() {
|
|
643
|
-
for (const key of this.#
|
|
644
|
-
const signal = this.#
|
|
517
|
+
for (const key of this.#keys) {
|
|
518
|
+
const signal = this.#signals.get(key);
|
|
645
519
|
if (signal)
|
|
646
520
|
yield signal;
|
|
647
521
|
}
|
|
648
522
|
}
|
|
649
523
|
get length() {
|
|
650
|
-
|
|
651
|
-
return this.#
|
|
524
|
+
subscribeTo(this);
|
|
525
|
+
return this.#keys.length;
|
|
652
526
|
}
|
|
653
527
|
get() {
|
|
654
|
-
|
|
528
|
+
subscribeTo(this);
|
|
655
529
|
return this.#value;
|
|
656
530
|
}
|
|
657
531
|
set(newValue) {
|
|
658
532
|
if (UNSET === newValue) {
|
|
659
|
-
this.#
|
|
660
|
-
|
|
661
|
-
this
|
|
533
|
+
this.#signals.clear();
|
|
534
|
+
notifyOf(this);
|
|
535
|
+
unsubscribeAllFrom(this);
|
|
662
536
|
return;
|
|
663
537
|
}
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
const changed = this.#composite.change(changes);
|
|
668
|
-
if (changed) {
|
|
669
|
-
for (const key of removedKeys) {
|
|
670
|
-
const index = this.#order.indexOf(key);
|
|
671
|
-
if (index !== -1)
|
|
672
|
-
this.#order.splice(index, 1);
|
|
673
|
-
}
|
|
674
|
-
this.#order = this.#order.filter(() => true);
|
|
675
|
-
notifyWatchers(this.#watchers);
|
|
676
|
-
}
|
|
538
|
+
const changes = diff(this.#toRecord(this.#value), this.#toRecord(newValue));
|
|
539
|
+
if (this.#change(changes))
|
|
540
|
+
notifyOf(this);
|
|
677
541
|
}
|
|
678
542
|
update(fn) {
|
|
679
543
|
this.set(fn(this.get()));
|
|
680
544
|
}
|
|
681
545
|
at(index) {
|
|
682
|
-
return this.#
|
|
546
|
+
return this.#signals.get(this.#keys[index]);
|
|
683
547
|
}
|
|
684
548
|
keys() {
|
|
685
|
-
|
|
549
|
+
subscribeTo(this);
|
|
550
|
+
return this.#keys.values();
|
|
686
551
|
}
|
|
687
552
|
byKey(key) {
|
|
688
|
-
return this.#
|
|
553
|
+
return this.#signals.get(key);
|
|
689
554
|
}
|
|
690
555
|
keyAt(index) {
|
|
691
|
-
return this.#
|
|
556
|
+
return this.#keys[index];
|
|
692
557
|
}
|
|
693
558
|
indexOfKey(key) {
|
|
694
|
-
return this.#
|
|
559
|
+
return this.#keys.indexOf(key);
|
|
695
560
|
}
|
|
696
561
|
add(value) {
|
|
697
562
|
const key = this.#generateKey(value);
|
|
698
|
-
if (this.#
|
|
563
|
+
if (this.#signals.has(key))
|
|
699
564
|
throw new DuplicateKeyError("store", key, value);
|
|
700
|
-
if (!this.#
|
|
701
|
-
this.#
|
|
702
|
-
const ok = this.#
|
|
565
|
+
if (!this.#keys.includes(key))
|
|
566
|
+
this.#keys.push(key);
|
|
567
|
+
const ok = this.#add(key, value);
|
|
703
568
|
if (ok)
|
|
704
|
-
|
|
569
|
+
notifyOf(this);
|
|
705
570
|
return key;
|
|
706
571
|
}
|
|
707
572
|
remove(keyOrIndex) {
|
|
708
|
-
const key = isNumber(keyOrIndex) ? this.#
|
|
709
|
-
const ok = this.#
|
|
573
|
+
const key = isNumber(keyOrIndex) ? this.#keys[keyOrIndex] : keyOrIndex;
|
|
574
|
+
const ok = this.#signals.delete(key);
|
|
710
575
|
if (ok) {
|
|
711
|
-
const index = isNumber(keyOrIndex) ? keyOrIndex : this.#
|
|
576
|
+
const index = isNumber(keyOrIndex) ? keyOrIndex : this.#keys.indexOf(key);
|
|
712
577
|
if (index >= 0)
|
|
713
|
-
this.#
|
|
714
|
-
this.#
|
|
715
|
-
|
|
578
|
+
this.#keys.splice(index, 1);
|
|
579
|
+
this.#keys = this.#keys.filter(() => true);
|
|
580
|
+
notifyOf(this);
|
|
716
581
|
}
|
|
717
582
|
}
|
|
718
583
|
sort(compareFn) {
|
|
719
|
-
const entries = this.#
|
|
584
|
+
const entries = this.#keys.map((key) => [key, this.#signals.get(key)?.get()]).sort(isFunction(compareFn) ? (a, b) => compareFn(a[1], b[1]) : (a, b) => String(a[1]).localeCompare(String(b[1])));
|
|
720
585
|
const newOrder = entries.map(([key]) => key);
|
|
721
|
-
if (!isEqual(this.#
|
|
722
|
-
this.#
|
|
723
|
-
|
|
724
|
-
triggerHook(this.#hookCallbacks.sort, this.#order);
|
|
586
|
+
if (!isEqual(this.#keys, newOrder)) {
|
|
587
|
+
this.#keys = newOrder;
|
|
588
|
+
notifyOf(this);
|
|
725
589
|
}
|
|
726
590
|
}
|
|
727
591
|
splice(start, deleteCount, ...items) {
|
|
728
|
-
const length = this.#
|
|
592
|
+
const length = this.#keys.length;
|
|
729
593
|
const actualStart = start < 0 ? Math.max(0, length + start) : Math.min(start, length);
|
|
730
594
|
const actualDeleteCount = Math.max(0, Math.min(deleteCount ?? Math.max(0, length - Math.max(0, actualStart)), length - actualStart));
|
|
731
595
|
const add = {};
|
|
732
596
|
const remove = {};
|
|
733
597
|
for (let i = 0;i < actualDeleteCount; i++) {
|
|
734
598
|
const index = actualStart + i;
|
|
735
|
-
const key = this.#
|
|
599
|
+
const key = this.#keys[index];
|
|
736
600
|
if (key) {
|
|
737
|
-
const signal = this.#
|
|
601
|
+
const signal = this.#signals.get(key);
|
|
738
602
|
if (signal)
|
|
739
603
|
remove[key] = signal.get();
|
|
740
604
|
}
|
|
741
605
|
}
|
|
742
|
-
const newOrder = this.#
|
|
606
|
+
const newOrder = this.#keys.slice(0, actualStart);
|
|
743
607
|
for (const item of items) {
|
|
744
608
|
const key = this.#generateKey(item);
|
|
745
609
|
newOrder.push(key);
|
|
746
610
|
add[key] = item;
|
|
747
611
|
}
|
|
748
|
-
newOrder.push(...this.#
|
|
612
|
+
newOrder.push(...this.#keys.slice(actualStart + actualDeleteCount));
|
|
749
613
|
const changed = !!(Object.keys(add).length || Object.keys(remove).length);
|
|
750
614
|
if (changed) {
|
|
751
|
-
this.#
|
|
615
|
+
this.#change({
|
|
752
616
|
add,
|
|
753
617
|
change: {},
|
|
754
618
|
remove,
|
|
755
619
|
changed
|
|
756
620
|
});
|
|
757
|
-
this.#
|
|
758
|
-
|
|
621
|
+
this.#keys = newOrder.filter(() => true);
|
|
622
|
+
notifyOf(this);
|
|
759
623
|
}
|
|
760
624
|
return Object.values(remove);
|
|
761
625
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
this.#hookCallbacks[type] ||= new Set;
|
|
765
|
-
this.#hookCallbacks[type].add(callback);
|
|
766
|
-
return () => {
|
|
767
|
-
this.#hookCallbacks[type]?.delete(callback);
|
|
768
|
-
};
|
|
769
|
-
} else if (isHandledHook(type, [HOOK_ADD, HOOK_CHANGE, HOOK_REMOVE])) {
|
|
770
|
-
return this.#composite.on(type, callback);
|
|
771
|
-
}
|
|
772
|
-
throw new InvalidHookError(TYPE_LIST, type);
|
|
773
|
-
}
|
|
774
|
-
deriveCollection(callback) {
|
|
775
|
-
return new DerivedCollection(this, callback);
|
|
626
|
+
deriveCollection(callback, options) {
|
|
627
|
+
return new DerivedCollection(this, callback, options);
|
|
776
628
|
}
|
|
777
629
|
}
|
|
778
630
|
var isList = (value) => isObjectOfType(value, TYPE_LIST);
|
|
@@ -781,22 +633,57 @@ var isList = (value) => isObjectOfType(value, TYPE_LIST);
|
|
|
781
633
|
var TYPE_STORE = "Store";
|
|
782
634
|
|
|
783
635
|
class BaseStore {
|
|
784
|
-
#
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
}
|
|
636
|
+
#signals = new Map;
|
|
637
|
+
constructor(initialValue, options) {
|
|
638
|
+
validateSignalValue(TYPE_STORE, initialValue, options?.guard ?? isRecord);
|
|
639
|
+
this.#change({
|
|
640
|
+
add: initialValue,
|
|
641
|
+
change: {},
|
|
642
|
+
remove: {},
|
|
643
|
+
changed: true
|
|
644
|
+
});
|
|
645
|
+
if (options?.watched)
|
|
646
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
793
647
|
}
|
|
794
648
|
get #value() {
|
|
795
649
|
const record = {};
|
|
796
|
-
for (const [key, signal] of this.#
|
|
650
|
+
for (const [key, signal] of this.#signals.entries())
|
|
797
651
|
record[key] = signal.get();
|
|
798
652
|
return record;
|
|
799
653
|
}
|
|
654
|
+
#validate(key, value) {
|
|
655
|
+
validateSignalValue(`${TYPE_STORE} for key "${key}"`, value);
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
#add(key, value) {
|
|
659
|
+
if (!this.#validate(key, value))
|
|
660
|
+
return false;
|
|
661
|
+
this.#signals.set(key, createMutableSignal(value));
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
#change(changes) {
|
|
665
|
+
if (Object.keys(changes.add).length) {
|
|
666
|
+
for (const key in changes.add)
|
|
667
|
+
this.#add(key, changes.add[key]);
|
|
668
|
+
}
|
|
669
|
+
if (Object.keys(changes.change).length) {
|
|
670
|
+
batch(() => {
|
|
671
|
+
for (const key in changes.change) {
|
|
672
|
+
const value = changes.change[key];
|
|
673
|
+
if (!this.#validate(key, value))
|
|
674
|
+
continue;
|
|
675
|
+
const signal = this.#signals.get(key);
|
|
676
|
+
if (guardMutableSignal(`list item "${key}"`, value, signal))
|
|
677
|
+
signal.set(value);
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
if (Object.keys(changes.remove).length) {
|
|
682
|
+
for (const key in changes.remove)
|
|
683
|
+
this.remove(key);
|
|
684
|
+
}
|
|
685
|
+
return changes.changed;
|
|
686
|
+
}
|
|
800
687
|
get [Symbol.toStringTag]() {
|
|
801
688
|
return TYPE_STORE;
|
|
802
689
|
}
|
|
@@ -804,62 +691,50 @@ class BaseStore {
|
|
|
804
691
|
return false;
|
|
805
692
|
}
|
|
806
693
|
*[Symbol.iterator]() {
|
|
807
|
-
for (const [key, signal] of this.#
|
|
694
|
+
for (const [key, signal] of this.#signals.entries())
|
|
808
695
|
yield [key, signal];
|
|
809
696
|
}
|
|
810
697
|
keys() {
|
|
811
|
-
|
|
698
|
+
subscribeTo(this);
|
|
699
|
+
return this.#signals.keys();
|
|
812
700
|
}
|
|
813
701
|
byKey(key) {
|
|
814
|
-
return this.#
|
|
702
|
+
return this.#signals.get(key);
|
|
815
703
|
}
|
|
816
704
|
get() {
|
|
817
|
-
|
|
705
|
+
subscribeTo(this);
|
|
818
706
|
return this.#value;
|
|
819
707
|
}
|
|
820
708
|
set(newValue) {
|
|
821
709
|
if (UNSET === newValue) {
|
|
822
|
-
this.#
|
|
823
|
-
|
|
824
|
-
this
|
|
710
|
+
this.#signals.clear();
|
|
711
|
+
notifyOf(this);
|
|
712
|
+
unsubscribeAllFrom(this);
|
|
825
713
|
return;
|
|
826
714
|
}
|
|
827
|
-
const
|
|
828
|
-
const changed = this.#composite.change(diff(oldValue, newValue));
|
|
715
|
+
const changed = this.#change(diff(this.#value, newValue));
|
|
829
716
|
if (changed)
|
|
830
|
-
|
|
717
|
+
notifyOf(this);
|
|
831
718
|
}
|
|
832
719
|
update(fn) {
|
|
833
720
|
this.set(fn(this.get()));
|
|
834
721
|
}
|
|
835
722
|
add(key, value) {
|
|
836
|
-
if (this.#
|
|
723
|
+
if (this.#signals.has(key))
|
|
837
724
|
throw new DuplicateKeyError(TYPE_STORE, key, value);
|
|
838
|
-
const ok = this.#
|
|
725
|
+
const ok = this.#add(key, value);
|
|
839
726
|
if (ok)
|
|
840
|
-
|
|
727
|
+
notifyOf(this);
|
|
841
728
|
return key;
|
|
842
729
|
}
|
|
843
730
|
remove(key) {
|
|
844
|
-
const ok = this.#
|
|
731
|
+
const ok = this.#signals.delete(key);
|
|
845
732
|
if (ok)
|
|
846
|
-
|
|
847
|
-
}
|
|
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);
|
|
733
|
+
notifyOf(this);
|
|
859
734
|
}
|
|
860
735
|
}
|
|
861
|
-
var createStore = (initialValue) => {
|
|
862
|
-
const instance = new BaseStore(initialValue);
|
|
736
|
+
var createStore = (initialValue, options) => {
|
|
737
|
+
const instance = new BaseStore(initialValue, options);
|
|
863
738
|
return new Proxy(instance, {
|
|
864
739
|
get(target, prop) {
|
|
865
740
|
if (prop in target) {
|
|
@@ -931,6 +806,13 @@ class DuplicateKeyError extends Error {
|
|
|
931
806
|
}
|
|
932
807
|
}
|
|
933
808
|
|
|
809
|
+
class FailedAssertionError extends Error {
|
|
810
|
+
constructor(message = "unexpected condition") {
|
|
811
|
+
super(`Assertion failed: ${message}`);
|
|
812
|
+
this.name = "FailedAssertionError";
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
934
816
|
class InvalidCallbackError extends TypeError {
|
|
935
817
|
constructor(where, value) {
|
|
936
818
|
super(`Invalid ${where} callback ${valueString(value)}`);
|
|
@@ -945,13 +827,6 @@ class InvalidCollectionSourceError extends TypeError {
|
|
|
945
827
|
}
|
|
946
828
|
}
|
|
947
829
|
|
|
948
|
-
class InvalidHookError extends TypeError {
|
|
949
|
-
constructor(where, type) {
|
|
950
|
-
super(`Invalid hook "${type}" in ${where}`);
|
|
951
|
-
this.name = "InvalidHookError";
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
|
|
955
830
|
class InvalidSignalValueError extends TypeError {
|
|
956
831
|
constructor(where, value) {
|
|
957
832
|
super(`Invalid signal value ${valueString(value)} in ${where}`);
|
|
@@ -972,6 +847,10 @@ class ReadonlySignalError extends Error {
|
|
|
972
847
|
this.name = "ReadonlySignalError";
|
|
973
848
|
}
|
|
974
849
|
}
|
|
850
|
+
function assert(condition, msg) {
|
|
851
|
+
if (!condition)
|
|
852
|
+
throw new FailedAssertionError(msg);
|
|
853
|
+
}
|
|
975
854
|
var createError = (reason) => reason instanceof Error ? reason : Error(String(reason));
|
|
976
855
|
var validateCallback = (where, value, guard = isFunction) => {
|
|
977
856
|
if (!guard(value))
|
|
@@ -993,14 +872,13 @@ var guardMutableSignal = (what, value, signal) => {
|
|
|
993
872
|
var TYPE_COLLECTION = "Collection";
|
|
994
873
|
|
|
995
874
|
class DerivedCollection {
|
|
996
|
-
#watchers = new Set;
|
|
997
875
|
#source;
|
|
998
876
|
#callback;
|
|
999
877
|
#signals = new Map;
|
|
1000
|
-
#
|
|
1001
|
-
#
|
|
1002
|
-
#
|
|
1003
|
-
constructor(source, callback) {
|
|
878
|
+
#keys = [];
|
|
879
|
+
#dirty = true;
|
|
880
|
+
#watcher;
|
|
881
|
+
constructor(source, callback, options) {
|
|
1004
882
|
validateCallback(TYPE_COLLECTION, callback);
|
|
1005
883
|
if (isFunction(source))
|
|
1006
884
|
source = source();
|
|
@@ -1014,46 +892,38 @@ class DerivedCollection {
|
|
|
1014
892
|
continue;
|
|
1015
893
|
this.#add(key);
|
|
1016
894
|
}
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
895
|
+
if (options?.watched)
|
|
896
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
897
|
+
}
|
|
898
|
+
#getWatcher() {
|
|
899
|
+
this.#watcher ||= createWatcher(() => {
|
|
900
|
+
this.#dirty = true;
|
|
901
|
+
if (!notifyOf(this))
|
|
902
|
+
this.#watcher?.stop();
|
|
903
|
+
}, () => {
|
|
904
|
+
const newKeys = Array.from(this.#source.keys());
|
|
905
|
+
const allKeys = new Set([...this.#keys, ...newKeys]);
|
|
906
|
+
const addedKeys = [];
|
|
907
|
+
const removedKeys = [];
|
|
908
|
+
for (const key of allKeys) {
|
|
909
|
+
const oldHas = this.#keys.includes(key);
|
|
910
|
+
const newHas = newKeys.includes(key);
|
|
911
|
+
if (!oldHas && newHas)
|
|
912
|
+
addedKeys.push(key);
|
|
913
|
+
else if (oldHas && !newHas)
|
|
914
|
+
removedKeys.push(key);
|
|
1027
915
|
}
|
|
1028
|
-
|
|
1029
|
-
triggerHook(this.#hookCallbacks.add, additions);
|
|
1030
|
-
});
|
|
1031
|
-
this.#source.on(HOOK_REMOVE, (removals) => {
|
|
1032
|
-
if (!removals)
|
|
1033
|
-
return;
|
|
1034
|
-
for (const key of removals) {
|
|
1035
|
-
if (!this.#signals.has(key))
|
|
1036
|
-
continue;
|
|
916
|
+
for (const key of removedKeys)
|
|
1037
917
|
this.#signals.delete(key);
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
if (watcher) {
|
|
1043
|
-
watcher.stop();
|
|
1044
|
-
this.#ownWatchers.delete(key);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
this.#order = this.#order.filter(() => true);
|
|
1048
|
-
notifyWatchers(this.#watchers);
|
|
1049
|
-
triggerHook(this.#hookCallbacks.remove, removals);
|
|
918
|
+
for (const key of addedKeys)
|
|
919
|
+
this.#add(key);
|
|
920
|
+
this.#keys = newKeys;
|
|
921
|
+
this.#dirty = false;
|
|
1050
922
|
});
|
|
1051
|
-
this.#
|
|
1052
|
-
|
|
1053
|
-
this.#order = [...newOrder];
|
|
1054
|
-
notifyWatchers(this.#watchers);
|
|
1055
|
-
triggerHook(this.#hookCallbacks.sort, newOrder);
|
|
923
|
+
this.#watcher.onCleanup(() => {
|
|
924
|
+
this.#watcher = undefined;
|
|
1056
925
|
});
|
|
926
|
+
return this.#watcher;
|
|
1057
927
|
}
|
|
1058
928
|
#add(key) {
|
|
1059
929
|
const computedCallback = isAsyncCollectionCallback(this.#callback) ? async (_, abort) => {
|
|
@@ -1069,21 +939,10 @@ class DerivedCollection {
|
|
|
1069
939
|
};
|
|
1070
940
|
const signal = createComputed(computedCallback);
|
|
1071
941
|
this.#signals.set(key, signal);
|
|
1072
|
-
if (!this.#
|
|
1073
|
-
this.#
|
|
1074
|
-
if (this.#hookCallbacks.change?.size)
|
|
1075
|
-
this.#addWatcher(key);
|
|
942
|
+
if (!this.#keys.includes(key))
|
|
943
|
+
this.#keys.push(key);
|
|
1076
944
|
return true;
|
|
1077
945
|
}
|
|
1078
|
-
#addWatcher(key) {
|
|
1079
|
-
const watcher = createWatcher(() => {
|
|
1080
|
-
trackSignalReads(watcher, () => {
|
|
1081
|
-
this.#signals.get(key)?.get();
|
|
1082
|
-
});
|
|
1083
|
-
});
|
|
1084
|
-
this.#ownWatchers.set(key, watcher);
|
|
1085
|
-
watcher();
|
|
1086
|
-
}
|
|
1087
946
|
get [Symbol.toStringTag]() {
|
|
1088
947
|
return TYPE_COLLECTION;
|
|
1089
948
|
}
|
|
@@ -1091,64 +950,44 @@ class DerivedCollection {
|
|
|
1091
950
|
return true;
|
|
1092
951
|
}
|
|
1093
952
|
*[Symbol.iterator]() {
|
|
1094
|
-
for (const key of this.#
|
|
953
|
+
for (const key of this.#keys) {
|
|
1095
954
|
const signal = this.#signals.get(key);
|
|
1096
955
|
if (signal)
|
|
1097
956
|
yield signal;
|
|
1098
957
|
}
|
|
1099
958
|
}
|
|
1100
959
|
keys() {
|
|
1101
|
-
|
|
960
|
+
subscribeTo(this);
|
|
961
|
+
if (this.#dirty)
|
|
962
|
+
this.#getWatcher().run();
|
|
963
|
+
return this.#keys.values();
|
|
1102
964
|
}
|
|
1103
965
|
get() {
|
|
1104
|
-
|
|
1105
|
-
|
|
966
|
+
subscribeTo(this);
|
|
967
|
+
if (this.#dirty)
|
|
968
|
+
this.#getWatcher().run();
|
|
969
|
+
return this.#keys.map((key) => this.#signals.get(key)?.get()).filter((v) => v != null && v !== UNSET);
|
|
1106
970
|
}
|
|
1107
971
|
at(index) {
|
|
1108
|
-
return this.#signals.get(this.#
|
|
972
|
+
return this.#signals.get(this.#keys[index]);
|
|
1109
973
|
}
|
|
1110
974
|
byKey(key) {
|
|
1111
975
|
return this.#signals.get(key);
|
|
1112
976
|
}
|
|
1113
977
|
keyAt(index) {
|
|
1114
|
-
return this.#
|
|
978
|
+
return this.#keys[index];
|
|
1115
979
|
}
|
|
1116
980
|
indexOfKey(key) {
|
|
1117
|
-
return this.#
|
|
1118
|
-
}
|
|
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);
|
|
1132
|
-
}
|
|
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);
|
|
981
|
+
return this.#keys.indexOf(key);
|
|
1145
982
|
}
|
|
1146
|
-
deriveCollection(callback) {
|
|
1147
|
-
return new DerivedCollection(this, callback);
|
|
983
|
+
deriveCollection(callback, options) {
|
|
984
|
+
return new DerivedCollection(this, callback, options);
|
|
1148
985
|
}
|
|
1149
986
|
get length() {
|
|
1150
|
-
|
|
1151
|
-
|
|
987
|
+
subscribeTo(this);
|
|
988
|
+
if (this.#dirty)
|
|
989
|
+
this.#getWatcher().run();
|
|
990
|
+
return this.#keys.length;
|
|
1152
991
|
}
|
|
1153
992
|
}
|
|
1154
993
|
var isCollection = (value) => isObjectOfType(value, TYPE_COLLECTION);
|
|
@@ -1158,32 +997,22 @@ var isAsyncCollectionCallback = (callback) => isAsyncFunction(callback);
|
|
|
1158
997
|
var TYPE_REF = "Ref";
|
|
1159
998
|
|
|
1160
999
|
class Ref {
|
|
1161
|
-
#watchers = new Set;
|
|
1162
1000
|
#value;
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
validateSignalValue(TYPE_REF, value, guard);
|
|
1001
|
+
constructor(value, options) {
|
|
1002
|
+
validateSignalValue(TYPE_REF, value, options?.guard);
|
|
1166
1003
|
this.#value = value;
|
|
1004
|
+
if (options?.watched)
|
|
1005
|
+
registerWatchCallbacks(this, options.watched, options.unwatched);
|
|
1167
1006
|
}
|
|
1168
1007
|
get [Symbol.toStringTag]() {
|
|
1169
1008
|
return TYPE_REF;
|
|
1170
1009
|
}
|
|
1171
1010
|
get() {
|
|
1172
|
-
|
|
1011
|
+
subscribeTo(this);
|
|
1173
1012
|
return this.#value;
|
|
1174
1013
|
}
|
|
1175
1014
|
notify() {
|
|
1176
|
-
|
|
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);
|
|
1015
|
+
notifyOf(this);
|
|
1187
1016
|
}
|
|
1188
1017
|
}
|
|
1189
1018
|
var isRef = (value) => isObjectOfType(value, TYPE_REF);
|
|
@@ -1194,7 +1023,9 @@ var createEffect = (callback) => {
|
|
|
1194
1023
|
const isAsync = isAsyncFunction(callback);
|
|
1195
1024
|
let running = false;
|
|
1196
1025
|
let controller;
|
|
1197
|
-
const watcher = createWatcher(() =>
|
|
1026
|
+
const watcher = createWatcher(() => {
|
|
1027
|
+
watcher.run();
|
|
1028
|
+
}, () => {
|
|
1198
1029
|
if (running)
|
|
1199
1030
|
throw new CircularDependencyError("effect");
|
|
1200
1031
|
running = true;
|
|
@@ -1207,7 +1038,7 @@ var createEffect = (callback) => {
|
|
|
1207
1038
|
const currentController = controller;
|
|
1208
1039
|
callback(controller.signal).then((cleanup2) => {
|
|
1209
1040
|
if (isFunction(cleanup2) && controller === currentController)
|
|
1210
|
-
watcher.
|
|
1041
|
+
watcher.onCleanup(cleanup2);
|
|
1211
1042
|
}).catch((error) => {
|
|
1212
1043
|
if (!isAbortError(error))
|
|
1213
1044
|
console.error("Error in async effect callback:", error);
|
|
@@ -1215,14 +1046,14 @@ var createEffect = (callback) => {
|
|
|
1215
1046
|
} else {
|
|
1216
1047
|
cleanup = callback();
|
|
1217
1048
|
if (isFunction(cleanup))
|
|
1218
|
-
watcher.
|
|
1049
|
+
watcher.onCleanup(cleanup);
|
|
1219
1050
|
}
|
|
1220
1051
|
} catch (error) {
|
|
1221
1052
|
if (!isAbortError(error))
|
|
1222
1053
|
console.error("Error in effect callback:", error);
|
|
1223
1054
|
}
|
|
1224
1055
|
running = false;
|
|
1225
|
-
})
|
|
1056
|
+
});
|
|
1226
1057
|
watcher();
|
|
1227
1058
|
return () => {
|
|
1228
1059
|
controller?.abort();
|
|
@@ -1276,11 +1107,11 @@ export {
|
|
|
1276
1107
|
valueString,
|
|
1277
1108
|
validateSignalValue,
|
|
1278
1109
|
validateCallback,
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1110
|
+
untrack,
|
|
1111
|
+
track,
|
|
1112
|
+
subscribeTo,
|
|
1282
1113
|
resolve,
|
|
1283
|
-
|
|
1114
|
+
notifyOf,
|
|
1284
1115
|
match,
|
|
1285
1116
|
isTaskCallback,
|
|
1286
1117
|
isSymbol,
|
|
@@ -1296,7 +1127,6 @@ export {
|
|
|
1296
1127
|
isMutableSignal,
|
|
1297
1128
|
isMemoCallback,
|
|
1298
1129
|
isList,
|
|
1299
|
-
isHandledHook,
|
|
1300
1130
|
isFunction,
|
|
1301
1131
|
isEqual,
|
|
1302
1132
|
isComputed,
|
|
@@ -1304,7 +1134,7 @@ export {
|
|
|
1304
1134
|
isAsyncFunction,
|
|
1305
1135
|
isAbortError,
|
|
1306
1136
|
guardMutableSignal,
|
|
1307
|
-
|
|
1137
|
+
flush,
|
|
1308
1138
|
diff,
|
|
1309
1139
|
createWatcher,
|
|
1310
1140
|
createStore,
|
|
@@ -1312,7 +1142,7 @@ export {
|
|
|
1312
1142
|
createError,
|
|
1313
1143
|
createEffect,
|
|
1314
1144
|
createComputed,
|
|
1315
|
-
|
|
1145
|
+
batch,
|
|
1316
1146
|
UNSET,
|
|
1317
1147
|
Task,
|
|
1318
1148
|
TYPE_STORE,
|
|
@@ -1330,12 +1160,6 @@ export {
|
|
|
1330
1160
|
InvalidSignalValueError,
|
|
1331
1161
|
InvalidCollectionSourceError,
|
|
1332
1162
|
InvalidCallbackError,
|
|
1333
|
-
HOOK_WATCH,
|
|
1334
|
-
HOOK_SORT,
|
|
1335
|
-
HOOK_REMOVE,
|
|
1336
|
-
HOOK_CLEANUP,
|
|
1337
|
-
HOOK_CHANGE,
|
|
1338
|
-
HOOK_ADD,
|
|
1339
1163
|
DuplicateKeyError,
|
|
1340
1164
|
DerivedCollection,
|
|
1341
1165
|
CircularDependencyError,
|