@zeix/cause-effect 0.15.2 → 0.16.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/.ai-context.md +254 -0
- package/.cursorrules +54 -0
- package/.github/copilot-instructions.md +132 -0
- package/CLAUDE.md +319 -0
- package/README.md +136 -166
- package/eslint.config.js +1 -1
- package/index.dev.js +125 -129
- package/index.js +1 -1
- package/index.ts +22 -22
- package/package.json +1 -1
- package/src/computed.ts +40 -29
- package/src/effect.ts +15 -12
- package/src/errors.ts +8 -0
- package/src/signal.ts +6 -6
- package/src/state.ts +27 -20
- package/src/store.ts +99 -121
- package/src/system.ts +122 -0
- package/src/util.ts +1 -6
- package/test/batch.test.ts +18 -11
- package/test/benchmark.test.ts +4 -4
- package/test/computed.test.ts +507 -71
- package/test/effect.test.ts +60 -60
- package/test/match.test.ts +25 -25
- package/test/resolve.test.ts +16 -16
- package/test/signal.test.ts +7 -7
- package/test/state.test.ts +212 -25
- package/test/store.test.ts +476 -183
- package/test/util/dependency-graph.ts +1 -1
- package/types/index.d.ts +8 -8
- package/types/src/collection.d.ts +26 -0
- package/types/src/computed.d.ts +9 -9
- package/types/src/effect.d.ts +3 -3
- package/types/src/errors.d.ts +4 -1
- package/types/src/state.d.ts +5 -5
- package/types/src/store.d.ts +27 -41
- package/types/src/system.d.ts +44 -0
- package/types/src/util.d.ts +1 -2
- package/src/scheduler.ts +0 -172
package/index.dev.js
CHANGED
|
@@ -6,6 +6,13 @@ class CircularDependencyError extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
class InvalidCallbackError extends TypeError {
|
|
10
|
+
constructor(where, value) {
|
|
11
|
+
super(`Invalid ${where} callback ${value}`);
|
|
12
|
+
this.name = "InvalidCallbackError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
class InvalidSignalValueError extends TypeError {
|
|
10
17
|
constructor(where, value) {
|
|
11
18
|
super(`Invalid signal value ${value} in ${where}`);
|
|
@@ -48,7 +55,6 @@ var isNumber = (value) => typeof value === "number";
|
|
|
48
55
|
var isSymbol = (value) => typeof value === "symbol";
|
|
49
56
|
var isFunction = (fn) => typeof fn === "function";
|
|
50
57
|
var isAsyncFunction = (fn) => isFunction(fn) && fn.constructor.name === "AsyncFunction";
|
|
51
|
-
var isDefinedObject = (value) => !!value && typeof value === "object";
|
|
52
58
|
var isObjectOfType = (value, type) => Object.prototype.toString.call(value) === `[object ${type}]`;
|
|
53
59
|
var isRecord = (value) => isObjectOfType(value, "Object");
|
|
54
60
|
var isRecordOrArray = (value) => isRecord(value) || Array.isArray(value);
|
|
@@ -70,7 +76,7 @@ var recordToArray = (record) => {
|
|
|
70
76
|
}
|
|
71
77
|
return array;
|
|
72
78
|
};
|
|
73
|
-
var valueString = (value) => isString(value) ? `"${value}"` :
|
|
79
|
+
var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
74
80
|
|
|
75
81
|
// src/diff.ts
|
|
76
82
|
var isEqual = (a, b, visited) => {
|
|
@@ -160,64 +166,46 @@ var diff = (oldObj, newObj) => {
|
|
|
160
166
|
};
|
|
161
167
|
};
|
|
162
168
|
|
|
163
|
-
// src/
|
|
164
|
-
var
|
|
165
|
-
var
|
|
169
|
+
// src/system.ts
|
|
170
|
+
var activeWatcher;
|
|
171
|
+
var pendingWatchers = new Set;
|
|
166
172
|
var batchDepth = 0;
|
|
167
|
-
var
|
|
168
|
-
var requestId;
|
|
169
|
-
var updateDOM = () => {
|
|
170
|
-
requestId = undefined;
|
|
171
|
-
const updates = Array.from(updateMap.values());
|
|
172
|
-
updateMap.clear();
|
|
173
|
-
for (const update of updates) {
|
|
174
|
-
update();
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
var requestTick = () => {
|
|
178
|
-
if (requestId)
|
|
179
|
-
cancelAnimationFrame(requestId);
|
|
180
|
-
requestId = requestAnimationFrame(updateDOM);
|
|
181
|
-
};
|
|
182
|
-
queueMicrotask(updateDOM);
|
|
183
|
-
var watch = (notice) => {
|
|
173
|
+
var createWatcher = (watch) => {
|
|
184
174
|
const cleanups = new Set;
|
|
185
|
-
const w =
|
|
186
|
-
w.
|
|
187
|
-
cleanups.add(
|
|
175
|
+
const w = watch;
|
|
176
|
+
w.unwatch = (cleanup) => {
|
|
177
|
+
cleanups.add(cleanup);
|
|
188
178
|
};
|
|
189
179
|
w.cleanup = () => {
|
|
190
|
-
for (const cleanup of cleanups)
|
|
180
|
+
for (const cleanup of cleanups)
|
|
191
181
|
cleanup();
|
|
192
|
-
}
|
|
193
182
|
cleanups.clear();
|
|
194
183
|
};
|
|
195
184
|
return w;
|
|
196
185
|
};
|
|
197
186
|
var subscribe = (watchers) => {
|
|
198
|
-
if (
|
|
199
|
-
const watcher =
|
|
200
|
-
|
|
201
|
-
active.off(() => {
|
|
187
|
+
if (activeWatcher && !watchers.has(activeWatcher)) {
|
|
188
|
+
const watcher = activeWatcher;
|
|
189
|
+
watcher.unwatch(() => {
|
|
202
190
|
watchers.delete(watcher);
|
|
203
191
|
});
|
|
192
|
+
watchers.add(watcher);
|
|
204
193
|
}
|
|
205
194
|
};
|
|
206
195
|
var notify = (watchers) => {
|
|
207
196
|
for (const watcher of watchers) {
|
|
208
197
|
if (batchDepth)
|
|
209
|
-
|
|
198
|
+
pendingWatchers.add(watcher);
|
|
210
199
|
else
|
|
211
200
|
watcher();
|
|
212
201
|
}
|
|
213
202
|
};
|
|
214
203
|
var flush = () => {
|
|
215
|
-
while (
|
|
216
|
-
const watchers = Array.from(
|
|
217
|
-
|
|
218
|
-
for (const watcher of watchers)
|
|
204
|
+
while (pendingWatchers.size) {
|
|
205
|
+
const watchers = Array.from(pendingWatchers);
|
|
206
|
+
pendingWatchers.clear();
|
|
207
|
+
for (const watcher of watchers)
|
|
219
208
|
watcher();
|
|
220
|
-
}
|
|
221
209
|
}
|
|
222
210
|
};
|
|
223
211
|
var batch = (fn) => {
|
|
@@ -230,30 +218,24 @@ var batch = (fn) => {
|
|
|
230
218
|
}
|
|
231
219
|
};
|
|
232
220
|
var observe = (run, watcher) => {
|
|
233
|
-
const prev =
|
|
234
|
-
|
|
221
|
+
const prev = activeWatcher;
|
|
222
|
+
activeWatcher = watcher;
|
|
235
223
|
try {
|
|
236
224
|
run();
|
|
237
225
|
} finally {
|
|
238
|
-
|
|
226
|
+
activeWatcher = prev;
|
|
239
227
|
}
|
|
240
228
|
};
|
|
241
|
-
var enqueue = (fn, dedupe) => new Promise((resolve, reject) => {
|
|
242
|
-
updateMap.set(dedupe || Symbol(), () => {
|
|
243
|
-
try {
|
|
244
|
-
resolve(fn());
|
|
245
|
-
} catch (error) {
|
|
246
|
-
reject(error);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
requestTick();
|
|
250
|
-
});
|
|
251
229
|
|
|
252
230
|
// src/computed.ts
|
|
253
231
|
var TYPE_COMPUTED = "Computed";
|
|
254
|
-
var
|
|
232
|
+
var createComputed = (callback, initialValue = UNSET) => {
|
|
233
|
+
if (!isComputedCallback(callback))
|
|
234
|
+
throw new InvalidCallbackError("computed", valueString(callback));
|
|
235
|
+
if (initialValue == null)
|
|
236
|
+
throw new NullishSignalValueError("computed");
|
|
255
237
|
const watchers = new Set;
|
|
256
|
-
let value =
|
|
238
|
+
let value = initialValue;
|
|
257
239
|
let error;
|
|
258
240
|
let controller;
|
|
259
241
|
let dirty = true;
|
|
@@ -278,29 +260,29 @@ var computed = (fn) => {
|
|
|
278
260
|
value = UNSET;
|
|
279
261
|
error = newError;
|
|
280
262
|
};
|
|
281
|
-
const settle = (
|
|
263
|
+
const settle = (fn) => (arg) => {
|
|
282
264
|
computing = false;
|
|
283
265
|
controller = undefined;
|
|
284
|
-
|
|
266
|
+
fn(arg);
|
|
285
267
|
if (changed)
|
|
286
268
|
notify(watchers);
|
|
287
269
|
};
|
|
288
|
-
const
|
|
270
|
+
const watcher = createWatcher(() => {
|
|
289
271
|
dirty = true;
|
|
290
272
|
controller?.abort();
|
|
291
273
|
if (watchers.size)
|
|
292
274
|
notify(watchers);
|
|
293
275
|
else
|
|
294
|
-
|
|
276
|
+
watcher.cleanup();
|
|
295
277
|
});
|
|
296
|
-
|
|
278
|
+
watcher.unwatch(() => {
|
|
297
279
|
controller?.abort();
|
|
298
280
|
});
|
|
299
281
|
const compute = () => observe(() => {
|
|
300
282
|
if (computing)
|
|
301
283
|
throw new CircularDependencyError("computed");
|
|
302
284
|
changed = false;
|
|
303
|
-
if (isAsyncFunction(
|
|
285
|
+
if (isAsyncFunction(callback)) {
|
|
304
286
|
if (controller)
|
|
305
287
|
return value;
|
|
306
288
|
controller = new AbortController;
|
|
@@ -315,7 +297,7 @@ var computed = (fn) => {
|
|
|
315
297
|
let result;
|
|
316
298
|
computing = true;
|
|
317
299
|
try {
|
|
318
|
-
result = controller ?
|
|
300
|
+
result = controller ? callback(value, controller.signal) : callback(value);
|
|
319
301
|
} catch (e) {
|
|
320
302
|
if (isAbortError(e))
|
|
321
303
|
nil();
|
|
@@ -331,8 +313,8 @@ var computed = (fn) => {
|
|
|
331
313
|
else
|
|
332
314
|
ok(result);
|
|
333
315
|
computing = false;
|
|
334
|
-
},
|
|
335
|
-
|
|
316
|
+
}, watcher);
|
|
317
|
+
return {
|
|
336
318
|
[Symbol.toStringTag]: TYPE_COMPUTED,
|
|
337
319
|
get: () => {
|
|
338
320
|
subscribe(watchers);
|
|
@@ -344,16 +326,17 @@ var computed = (fn) => {
|
|
|
344
326
|
return value;
|
|
345
327
|
}
|
|
346
328
|
};
|
|
347
|
-
return c;
|
|
348
329
|
};
|
|
349
330
|
var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
|
|
350
|
-
var isComputedCallback = (value) => isFunction(value) && value.length <
|
|
331
|
+
var isComputedCallback = (value) => isFunction(value) && value.length < 3;
|
|
351
332
|
// src/effect.ts
|
|
352
|
-
var
|
|
333
|
+
var createEffect = (callback) => {
|
|
334
|
+
if (!isFunction(callback) || callback.length > 1)
|
|
335
|
+
throw new InvalidCallbackError("effect", valueString(callback));
|
|
353
336
|
const isAsync = isAsyncFunction(callback);
|
|
354
337
|
let running = false;
|
|
355
338
|
let controller;
|
|
356
|
-
const
|
|
339
|
+
const watcher = createWatcher(() => observe(() => {
|
|
357
340
|
if (running)
|
|
358
341
|
throw new CircularDependencyError("effect");
|
|
359
342
|
running = true;
|
|
@@ -366,7 +349,7 @@ var effect = (callback) => {
|
|
|
366
349
|
const currentController = controller;
|
|
367
350
|
callback(controller.signal).then((cleanup2) => {
|
|
368
351
|
if (isFunction(cleanup2) && controller === currentController)
|
|
369
|
-
|
|
352
|
+
watcher.unwatch(cleanup2);
|
|
370
353
|
}).catch((error) => {
|
|
371
354
|
if (!isAbortError(error))
|
|
372
355
|
console.error("Async effect error:", error);
|
|
@@ -374,18 +357,18 @@ var effect = (callback) => {
|
|
|
374
357
|
} else {
|
|
375
358
|
cleanup = callback();
|
|
376
359
|
if (isFunction(cleanup))
|
|
377
|
-
|
|
360
|
+
watcher.unwatch(cleanup);
|
|
378
361
|
}
|
|
379
362
|
} catch (error) {
|
|
380
363
|
if (!isAbortError(error))
|
|
381
364
|
console.error("Effect callback error:", error);
|
|
382
365
|
}
|
|
383
366
|
running = false;
|
|
384
|
-
},
|
|
385
|
-
|
|
367
|
+
}, watcher));
|
|
368
|
+
watcher();
|
|
386
369
|
return () => {
|
|
387
370
|
controller?.abort();
|
|
388
|
-
|
|
371
|
+
watcher.cleanup();
|
|
389
372
|
};
|
|
390
373
|
};
|
|
391
374
|
// src/match.ts
|
|
@@ -407,20 +390,20 @@ function match(result, handlers) {
|
|
|
407
390
|
// src/resolve.ts
|
|
408
391
|
function resolve(signals) {
|
|
409
392
|
const errors = [];
|
|
410
|
-
let
|
|
393
|
+
let pending = false;
|
|
411
394
|
const values = {};
|
|
412
395
|
for (const [key, signal] of Object.entries(signals)) {
|
|
413
396
|
try {
|
|
414
397
|
const value = signal.get();
|
|
415
398
|
if (value === UNSET)
|
|
416
|
-
|
|
399
|
+
pending = true;
|
|
417
400
|
else
|
|
418
401
|
values[key] = value;
|
|
419
402
|
} catch (e) {
|
|
420
403
|
errors.push(toError(e));
|
|
421
404
|
}
|
|
422
405
|
}
|
|
423
|
-
if (
|
|
406
|
+
if (pending)
|
|
424
407
|
return { ok: false, pending: true };
|
|
425
408
|
if (errors.length > 0)
|
|
426
409
|
return { ok: false, errors };
|
|
@@ -428,46 +411,53 @@ function resolve(signals) {
|
|
|
428
411
|
}
|
|
429
412
|
// src/state.ts
|
|
430
413
|
var TYPE_STATE = "State";
|
|
431
|
-
var
|
|
414
|
+
var createState = (initialValue) => {
|
|
415
|
+
if (initialValue == null)
|
|
416
|
+
throw new NullishSignalValueError("state");
|
|
432
417
|
const watchers = new Set;
|
|
433
418
|
let value = initialValue;
|
|
434
|
-
const
|
|
419
|
+
const state = {
|
|
435
420
|
[Symbol.toStringTag]: TYPE_STATE,
|
|
436
421
|
get: () => {
|
|
437
422
|
subscribe(watchers);
|
|
438
423
|
return value;
|
|
439
424
|
},
|
|
440
|
-
set: (
|
|
441
|
-
if (
|
|
425
|
+
set: (newValue) => {
|
|
426
|
+
if (newValue == null)
|
|
442
427
|
throw new NullishSignalValueError("state");
|
|
443
|
-
if (isEqual(value,
|
|
428
|
+
if (isEqual(value, newValue))
|
|
444
429
|
return;
|
|
445
|
-
value =
|
|
430
|
+
value = newValue;
|
|
446
431
|
notify(watchers);
|
|
447
432
|
if (UNSET === value)
|
|
448
433
|
watchers.clear();
|
|
449
434
|
},
|
|
450
|
-
update: (
|
|
451
|
-
|
|
435
|
+
update: (updater) => {
|
|
436
|
+
if (!isFunction(updater))
|
|
437
|
+
throw new InvalidCallbackError("state update", valueString(updater));
|
|
438
|
+
state.set(updater(value));
|
|
452
439
|
}
|
|
453
440
|
};
|
|
454
|
-
return
|
|
441
|
+
return state;
|
|
455
442
|
};
|
|
456
443
|
var isState = (value) => isObjectOfType(value, TYPE_STATE);
|
|
457
444
|
|
|
458
445
|
// src/store.ts
|
|
459
446
|
var TYPE_STORE = "Store";
|
|
460
|
-
var
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
var STORE_EVENT_SORT = "store-sort";
|
|
464
|
-
var store = (initialValue) => {
|
|
447
|
+
var createStore = (initialValue) => {
|
|
448
|
+
if (initialValue == null)
|
|
449
|
+
throw new NullishSignalValueError("store");
|
|
465
450
|
const watchers = new Set;
|
|
466
|
-
const
|
|
451
|
+
const listeners = {
|
|
452
|
+
add: new Set,
|
|
453
|
+
change: new Set,
|
|
454
|
+
remove: new Set,
|
|
455
|
+
sort: new Set
|
|
456
|
+
};
|
|
467
457
|
const signals = new Map;
|
|
468
|
-
const
|
|
458
|
+
const signalWatchers = new Map;
|
|
469
459
|
const isArrayLike = Array.isArray(initialValue);
|
|
470
|
-
const size =
|
|
460
|
+
const size = createState(0);
|
|
471
461
|
const current = () => {
|
|
472
462
|
const record = {};
|
|
473
463
|
for (const [key, signal] of signals) {
|
|
@@ -475,7 +465,12 @@ var store = (initialValue) => {
|
|
|
475
465
|
}
|
|
476
466
|
return record;
|
|
477
467
|
};
|
|
478
|
-
const emit = (
|
|
468
|
+
const emit = (key, changes) => {
|
|
469
|
+
Object.freeze(changes);
|
|
470
|
+
for (const listener of listeners[key]) {
|
|
471
|
+
listener(changes);
|
|
472
|
+
}
|
|
473
|
+
};
|
|
479
474
|
const getSortedIndexes = () => Array.from(signals.keys()).map((k) => Number(k)).filter((n) => Number.isInteger(n)).sort((a, b) => a - b);
|
|
480
475
|
const isValidValue = (key, value) => {
|
|
481
476
|
if (value == null)
|
|
@@ -489,20 +484,19 @@ var store = (initialValue) => {
|
|
|
489
484
|
const addProperty = (key, value, single = false) => {
|
|
490
485
|
if (!isValidValue(key, value))
|
|
491
486
|
return false;
|
|
492
|
-
const signal = isState(value) || isStore(value) ? value : isRecord(value)
|
|
487
|
+
const signal = isState(value) || isStore(value) ? value : isRecord(value) || Array.isArray(value) ? createStore(value) : createState(value);
|
|
493
488
|
signals.set(key, signal);
|
|
494
|
-
const
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
cleanups.set(key, cleanup);
|
|
489
|
+
const watcher = createWatcher(() => observe(() => {
|
|
490
|
+
emit("change", {
|
|
491
|
+
[key]: signal.get()
|
|
492
|
+
});
|
|
493
|
+
}, watcher));
|
|
494
|
+
watcher();
|
|
495
|
+
signalWatchers.set(key, watcher);
|
|
502
496
|
if (single) {
|
|
503
497
|
size.set(signals.size);
|
|
504
498
|
notify(watchers);
|
|
505
|
-
emit(
|
|
499
|
+
emit("add", {
|
|
506
500
|
[key]: value
|
|
507
501
|
});
|
|
508
502
|
}
|
|
@@ -511,15 +505,15 @@ var store = (initialValue) => {
|
|
|
511
505
|
const removeProperty = (key, single = false) => {
|
|
512
506
|
const ok = signals.delete(key);
|
|
513
507
|
if (ok) {
|
|
514
|
-
const
|
|
515
|
-
if (
|
|
516
|
-
cleanup();
|
|
517
|
-
|
|
508
|
+
const watcher = signalWatchers.get(key);
|
|
509
|
+
if (watcher)
|
|
510
|
+
watcher.cleanup();
|
|
511
|
+
signalWatchers.delete(key);
|
|
518
512
|
}
|
|
519
513
|
if (single) {
|
|
520
514
|
size.set(signals.size);
|
|
521
515
|
notify(watchers);
|
|
522
|
-
emit(
|
|
516
|
+
emit("remove", {
|
|
523
517
|
[key]: UNSET
|
|
524
518
|
});
|
|
525
519
|
}
|
|
@@ -535,10 +529,10 @@ var store = (initialValue) => {
|
|
|
535
529
|
}
|
|
536
530
|
if (initialRun) {
|
|
537
531
|
setTimeout(() => {
|
|
538
|
-
emit(
|
|
532
|
+
emit("add", changes.add);
|
|
539
533
|
}, 0);
|
|
540
534
|
} else {
|
|
541
|
-
emit(
|
|
535
|
+
emit("add", changes.add);
|
|
542
536
|
}
|
|
543
537
|
}
|
|
544
538
|
if (Object.keys(changes.change).length) {
|
|
@@ -552,19 +546,19 @@ var store = (initialValue) => {
|
|
|
552
546
|
else
|
|
553
547
|
throw new StoreKeyReadonlyError(key, valueString(value));
|
|
554
548
|
}
|
|
555
|
-
emit(
|
|
549
|
+
emit("change", changes.change);
|
|
556
550
|
}
|
|
557
551
|
if (Object.keys(changes.remove).length) {
|
|
558
552
|
for (const key in changes.remove)
|
|
559
553
|
removeProperty(key);
|
|
560
|
-
emit(
|
|
554
|
+
emit("remove", changes.remove);
|
|
561
555
|
}
|
|
562
556
|
size.set(signals.size);
|
|
563
557
|
});
|
|
564
558
|
return changes.changed;
|
|
565
559
|
};
|
|
566
560
|
reconcile({}, initialValue, true);
|
|
567
|
-
const
|
|
561
|
+
const store = {
|
|
568
562
|
add: isArrayLike ? (v) => {
|
|
569
563
|
const nextIndex = signals.size;
|
|
570
564
|
const key = String(nextIndex);
|
|
@@ -622,11 +616,12 @@ var store = (initialValue) => {
|
|
|
622
616
|
signals.clear();
|
|
623
617
|
newSignals.forEach((signal, key) => signals.set(key, signal));
|
|
624
618
|
notify(watchers);
|
|
625
|
-
emit(
|
|
619
|
+
emit("sort", newOrder);
|
|
620
|
+
},
|
|
621
|
+
on: (type, listener) => {
|
|
622
|
+
listeners[type].add(listener);
|
|
623
|
+
return () => listeners[type].delete(listener);
|
|
626
624
|
},
|
|
627
|
-
addEventListener: eventTarget.addEventListener.bind(eventTarget),
|
|
628
|
-
removeEventListener: eventTarget.removeEventListener.bind(eventTarget),
|
|
629
|
-
dispatchEvent: eventTarget.dispatchEvent.bind(eventTarget),
|
|
630
625
|
size
|
|
631
626
|
};
|
|
632
627
|
return new Proxy({}, {
|
|
@@ -649,8 +644,8 @@ var store = (initialValue) => {
|
|
|
649
644
|
};
|
|
650
645
|
if (isSymbol(prop))
|
|
651
646
|
return;
|
|
652
|
-
if (prop in
|
|
653
|
-
return
|
|
647
|
+
if (prop in store)
|
|
648
|
+
return store[prop];
|
|
654
649
|
if (prop === "length" && isArrayLike) {
|
|
655
650
|
subscribe(watchers);
|
|
656
651
|
return size.get();
|
|
@@ -659,7 +654,7 @@ var store = (initialValue) => {
|
|
|
659
654
|
},
|
|
660
655
|
has(_target, prop) {
|
|
661
656
|
const stringProp = String(prop);
|
|
662
|
-
return stringProp && signals.has(stringProp) || Object.keys(
|
|
657
|
+
return stringProp && signals.has(stringProp) || Object.keys(store).includes(stringProp) || prop === Symbol.toStringTag || prop === Symbol.iterator || prop === Symbol.isConcatSpreadable || prop === "length" && isArrayLike;
|
|
663
658
|
},
|
|
664
659
|
ownKeys() {
|
|
665
660
|
return isArrayLike ? getSortedIndexes().map((key) => String(key)).concat(["length"]) : Array.from(signals.keys()).map((key) => String(key));
|
|
@@ -684,8 +679,8 @@ var store = (initialValue) => {
|
|
|
684
679
|
return nonEnumerable(TYPE_STORE);
|
|
685
680
|
if (isSymbol(prop))
|
|
686
681
|
return;
|
|
687
|
-
if (Object.keys(
|
|
688
|
-
return nonEnumerable(
|
|
682
|
+
if (Object.keys(store).includes(prop))
|
|
683
|
+
return nonEnumerable(store[prop]);
|
|
689
684
|
const signal = signals.get(prop);
|
|
690
685
|
return signal ? {
|
|
691
686
|
enumerable: true,
|
|
@@ -705,18 +700,16 @@ function toSignal(value) {
|
|
|
705
700
|
if (isSignal(value))
|
|
706
701
|
return value;
|
|
707
702
|
if (isComputedCallback(value))
|
|
708
|
-
return
|
|
703
|
+
return createComputed(value);
|
|
709
704
|
if (Array.isArray(value) || isRecord(value))
|
|
710
|
-
return
|
|
711
|
-
return
|
|
705
|
+
return createStore(value);
|
|
706
|
+
return createState(value);
|
|
712
707
|
}
|
|
713
708
|
export {
|
|
714
|
-
|
|
709
|
+
valueString,
|
|
715
710
|
toSignal,
|
|
716
711
|
toError,
|
|
717
712
|
subscribe,
|
|
718
|
-
store,
|
|
719
|
-
state,
|
|
720
713
|
resolve,
|
|
721
714
|
observe,
|
|
722
715
|
notify,
|
|
@@ -737,10 +730,12 @@ export {
|
|
|
737
730
|
isAsyncFunction,
|
|
738
731
|
isAbortError,
|
|
739
732
|
flush,
|
|
740
|
-
enqueue,
|
|
741
|
-
effect,
|
|
742
733
|
diff,
|
|
743
|
-
|
|
734
|
+
createWatcher,
|
|
735
|
+
createStore,
|
|
736
|
+
createState,
|
|
737
|
+
createEffect,
|
|
738
|
+
createComputed,
|
|
744
739
|
batch,
|
|
745
740
|
UNSET,
|
|
746
741
|
TYPE_STORE,
|
|
@@ -751,5 +746,6 @@ export {
|
|
|
751
746
|
StoreKeyExistsError,
|
|
752
747
|
NullishSignalValueError,
|
|
753
748
|
InvalidSignalValueError,
|
|
749
|
+
InvalidCallbackError,
|
|
754
750
|
CircularDependencyError
|
|
755
751
|
};
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class W extends Error{constructor($){super(`Circular dependency detected in ${$}`);this.name="CircularDependencyError"}}class P extends TypeError{constructor($,x){super(`Invalid ${$} callback ${x}`);this.name="InvalidCallbackError"}}class n extends TypeError{constructor($,x){super(`Invalid signal value ${x} in ${$}`);this.name="InvalidSignalValueError"}}class L extends TypeError{constructor($){super(`Nullish signal values are not allowed in ${$}`);this.name="NullishSignalValueError"}}class u extends Error{constructor($,x){super(`Could not add store key "${$}" with value ${x} because it already exists`);this.name="StoreKeyExistsError"}}class c extends RangeError{constructor($){super(`Could not remove store index ${String($)} because it is out of range`);this.name="StoreKeyRangeError"}}class t extends Error{constructor($,x){super(`Could not set store key "${$}" to ${x} because it is readonly`);this.name="StoreKeyReadonlyError"}}var K=Symbol(),x$=($)=>typeof $==="string",H$=($)=>typeof $==="number",p=($)=>typeof $==="symbol",Y=($)=>typeof $==="function",d=($)=>Y($)&&$.constructor.name==="AsyncFunction",E=($,x)=>Object.prototype.toString.call($)===`[object ${x}]`,A=($)=>E($,"Object"),s=($)=>A($)||Array.isArray($),K$=($)=>{if(!$.length)return null;let x=$.map((G)=>x$(G)?parseInt(G,10):H$(G)?G:NaN);return x.every((G)=>Number.isFinite(G)&&G>=0)?x.sort((G,J)=>G-J):null};var g=($)=>$ instanceof DOMException&&$.name==="AbortError",_=($)=>$ instanceof Error?$:Error(String($));var i=($)=>{let x=K$(Object.keys($));if(x===null)return $;let G=[];for(let J of x)G.push($[String(J)]);return G},U=($)=>x$($)?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($);var f=($,x,G)=>{if(Object.is($,x))return!0;if(typeof $!==typeof x)return!1;if(typeof $!=="object"||$===null||x===null)return!1;if(!G)G=new WeakSet;if(G.has($)||G.has(x))throw new W("isEqual");G.add($),G.add(x);try{if(Array.isArray($)&&Array.isArray(x)){if($.length!==x.length)return!1;for(let J=0;J<$.length;J++)if(!f($[J],x[J],G))return!1;return!0}if(Array.isArray($)!==Array.isArray(x))return!1;if(A($)&&A(x)){let J=Object.keys($),Q=Object.keys(x);if(J.length!==Q.length)return!1;for(let M of J){if(!(M in x))return!1;if(!f($[M],x[M],G))return!1}return!0}return!1}finally{G.delete($),G.delete(x)}},R$=($,x)=>{let G=s($),J=s(x);if(!G||!J){let q=!Object.is($,x);return{changed:q,add:q&&J?x:{},change:{},remove:q&&G?$:{}}}let Q=new WeakSet,M={},I={},C={},D=Object.keys($),j=Object.keys(x),O=new Set([...D,...j]);for(let q of O){let N=q in $,T=q in x;if(!N&&T){M[q]=x[q];continue}else if(N&&!T){C[q]=K;continue}let B=$[q],R=x[q];if(!f(B,R,Q))I[q]=R}return{changed:Object.keys(M).length>0||Object.keys(I).length>0||Object.keys(C).length>0,add:M,change:I,remove:C}};var w,r=new Set,B$=0,V=($)=>{let x=new Set,G=$;return G.unwatch=(J)=>{x.add(J)},G.cleanup=()=>{for(let J of x)J();x.clear()},G},m=($)=>{if(w&&!$.has(w)){let x=w;x.unwatch(()=>{$.delete(x)}),$.add(x)}},F=($)=>{for(let x of $)if(B$)r.add(x);else x()},l=()=>{while(r.size){let $=Array.from(r);r.clear();for(let x of $)x()}},J$=($)=>{B$++;try{$()}finally{l(),B$--}},y=($,x)=>{let G=w;w=x;try{$()}finally{w=G}};var G$="Computed",M$=($,x=K)=>{if(!a($))throw new P("computed",U($));if(x==null)throw new L("computed");let G=new Set,J=x,Q,M,I=!0,C=!1,D=!1,j=(B)=>{if(!f(B,J))J=B,C=!0;Q=void 0,I=!1},O=()=>{C=K!==J,J=K,Q=void 0},S=(B)=>{let R=_(B);C=!Q||R.name!==Q.name||R.message!==Q.message,J=K,Q=R},q=(B)=>(R)=>{if(D=!1,M=void 0,B(R),C)F(G)},N=V(()=>{if(I=!0,M?.abort(),G.size)F(G);else N.cleanup()});N.unwatch(()=>{M?.abort()});let T=()=>y(()=>{if(D)throw new W("computed");if(C=!1,d($)){if(M)return J;M=new AbortController,M.signal.addEventListener("abort",()=>{D=!1,M=void 0,T()},{once:!0})}let B;D=!0;try{B=M?$(J,M.signal):$(J)}catch(R){if(g(R))O();else S(R);D=!1;return}if(B instanceof Promise)B.then(q(j),q(S));else if(B==null||K===B)O();else j(B);D=!1},N);return{[Symbol.toStringTag]:G$,get:()=>{if(m(G),l(),I)T();if(Q)throw Q;return J}}},o=($)=>E($,G$),a=($)=>Y($)&&$.length<3;var q$=($)=>{if(!Y($)||$.length>1)throw new P("effect",U($));let x=d($),G=!1,J,Q=V(()=>y(()=>{if(G)throw new W("effect");G=!0,J?.abort(),J=void 0;let M;try{if(x){J=new AbortController;let I=J;$(J.signal).then((C)=>{if(Y(C)&&J===I)Q.unwatch(C)}).catch((C)=>{if(!g(C))console.error("Async effect error:",C)})}else if(M=$(),Y(M))Q.unwatch(M)}catch(I){if(!g(I))console.error("Effect callback error:",I)}G=!1},Q));return Q(),()=>{J?.abort(),Q.cleanup()}};function D$($,x){try{if($.pending)x.nil?.();else if($.errors)x.err?.($.errors);else if($.ok)x.ok($.values)}catch(G){if(x.err&&(!$.errors||!$.errors.includes(_(G))))x.err($.errors?[...$.errors,_(G)]:[_(G)]);else throw G}}function z$($){let x=[],G=!1,J={};for(let[Q,M]of Object.entries($))try{let I=M.get();if(I===K)G=!0;else J[Q]=I}catch(I){x.push(_(I))}if(G)return{ok:!1,pending:!0};if(x.length>0)return{ok:!1,errors:x};return{ok:!0,values:J}}var Q$="State",b=($)=>{if($==null)throw new L("state");let x=new Set,G=$,J={[Symbol.toStringTag]:Q$,get:()=>{return m(x),G},set:(Q)=>{if(Q==null)throw new L("state");if(f(G,Q))return;if(G=Q,F(x),K===G)x.clear()},update:(Q)=>{if(!Y(Q))throw new P("state update",U(Q));J.set(Q(G))}};return J},k=($)=>E($,Q$);var e="Store",$$=($)=>{if($==null)throw new L("store");let x=new Set,G={add:new Set,change:new Set,remove:new Set,sort:new Set},J=new Map,Q=new Map,M=Array.isArray($),I=b(0),C=()=>{let B={};for(let[R,X]of J)B[R]=X.get();return B},D=(B,R)=>{Object.freeze(R);for(let X of G[B])X(R)},j=()=>Array.from(J.keys()).map((B)=>Number(B)).filter((B)=>Number.isInteger(B)).sort((B,R)=>B-R),O=(B,R)=>{if(R==null)throw new L(`store for key "${B}"`);if(R===K)return!0;if(p(R)||Y(R)||o(R))throw new n(`store for key "${B}"`,U(R));return!0},S=(B,R,X=!1)=>{if(!O(B,R))return!1;let Z=k(R)||h(R)?R:A(R)||Array.isArray(R)?$$(R):b(R);J.set(B,Z);let H=V(()=>y(()=>{D("change",{[B]:Z.get()})},H));if(H(),Q.set(B,H),X)I.set(J.size),F(x),D("add",{[B]:R});return!0},q=(B,R=!1)=>{let X=J.delete(B);if(X){let Z=Q.get(B);if(Z)Z.cleanup();Q.delete(B)}if(R)I.set(J.size),F(x),D("remove",{[B]:K});return X},N=(B,R,X)=>{let Z=R$(B,R);return J$(()=>{if(Object.keys(Z.add).length){for(let H in Z.add){let z=Z.add[H]??K;S(H,z)}if(X)setTimeout(()=>{D("add",Z.add)},0);else D("add",Z.add)}if(Object.keys(Z.change).length){for(let H in Z.change){let z=Z.change[H];if(!O(H,z))continue;let v=J.get(H);if(X$(v))v.set(z);else throw new t(H,U(z))}D("change",Z.change)}if(Object.keys(Z.remove).length){for(let H in Z.remove)q(H);D("remove",Z.remove)}I.set(J.size)}),Z.changed};N({},$,!0);let T={add:M?(B)=>{let R=J.size,X=String(R);S(X,B,!0)}:(B,R)=>{if(!J.has(B))S(B,R,!0);else throw new u(B,U(R))},get:()=>{return m(x),i(C())},remove:M?(B)=>{let R=i(C()),X=J.size;if(!Array.isArray(R)||B<=-X||B>=X)throw new c(B);let Z=[...R];if(Z.splice(B,1),N(R,Z))F(x)}:(B)=>{if(J.has(B))q(B,!0)},set:(B)=>{if(N(C(),B)){if(F(x),K===B)x.clear()}},update:(B)=>{let R=C(),X=B(i(R));if(N(R,X)){if(F(x),K===X)x.clear()}},sort:(B)=>{let R=Array.from(J.entries()).map(([H,z])=>[H,z.get()]).sort(B?(H,z)=>B(H[1],z[1]):(H,z)=>String(H[1]).localeCompare(String(z[1]))),X=R.map(([H])=>String(H)),Z=new Map;R.forEach(([H],z)=>{let v=String(H),C$=M?String(z):String(H),Z$=J.get(v);if(Z$)Z.set(C$,Z$)}),J.clear(),Z.forEach((H,z)=>J.set(z,H)),F(x),D("sort",X)},on:(B,R)=>{return G[B].add(R),()=>G[B].delete(R)},size:I};return new Proxy({},{get(B,R){if(R===Symbol.toStringTag)return e;if(R===Symbol.isConcatSpreadable)return M;if(R===Symbol.iterator)return M?function*(){let X=j();for(let Z of X){let H=J.get(String(Z));if(H)yield H}}:function*(){for(let[X,Z]of J)yield[X,Z]};if(p(R))return;if(R in T)return T[R];if(R==="length"&&M)return m(x),I.get();return J.get(R)},has(B,R){let X=String(R);return X&&J.has(X)||Object.keys(T).includes(X)||R===Symbol.toStringTag||R===Symbol.iterator||R===Symbol.isConcatSpreadable||R==="length"&&M},ownKeys(){return M?j().map((B)=>String(B)).concat(["length"]):Array.from(J.keys()).map((B)=>String(B))},getOwnPropertyDescriptor(B,R){let X=(H)=>({enumerable:!1,configurable:!0,writable:!1,value:H});if(R==="length"&&M)return{enumerable:!0,configurable:!0,writable:!1,value:I.get()};if(R===Symbol.isConcatSpreadable)return X(M);if(R===Symbol.toStringTag)return X(e);if(p(R))return;if(Object.keys(T).includes(R))return X(T[R]);let Z=J.get(R);return Z?{enumerable:!0,configurable:!0,writable:!0,value:Z}:void 0}})},h=($)=>E($,e);var I$=($)=>k($)||o($)||h($),X$=($)=>k($)||h($);function F$($){if(I$($))return $;if(a($))return M$($);if(Array.isArray($)||A($))return $$($);return b($)}export{U as valueString,F$ as toSignal,_ as toError,m as subscribe,z$ as resolve,y as observe,F as notify,D$ as match,p as isSymbol,x$ as isString,h as isStore,k as isState,I$ as isSignal,s as isRecordOrArray,A as isRecord,H$ as isNumber,X$ as isMutableSignal,Y as isFunction,f as isEqual,a as isComputedCallback,o as isComputed,d as isAsyncFunction,g as isAbortError,l as flush,R$ as diff,V as createWatcher,$$ as createStore,b as createState,q$ as createEffect,M$ as createComputed,J$ as batch,K as UNSET,e as TYPE_STORE,Q$ as TYPE_STATE,G$ as TYPE_COMPUTED,t as StoreKeyReadonlyError,c as StoreKeyRangeError,u as StoreKeyExistsError,L as NullishSignalValueError,n as InvalidSignalValueError,P as InvalidCallbackError,W as CircularDependencyError};
|