@zeix/cause-effect 0.15.2 → 0.16.1

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/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);
@@ -65,12 +71,11 @@ var recordToArray = (record) => {
65
71
  if (indexes === null)
66
72
  return record;
67
73
  const array = [];
68
- for (const index of indexes) {
74
+ for (const index of indexes)
69
75
  array.push(record[String(index)]);
70
- }
71
76
  return array;
72
77
  };
73
- var valueString = (value) => isString(value) ? `"${value}"` : isDefinedObject(value) ? JSON.stringify(value) : String(value);
78
+ var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
74
79
 
75
80
  // src/diff.ts
76
81
  var isEqual = (a, b, visited) => {
@@ -160,64 +165,46 @@ var diff = (oldObj, newObj) => {
160
165
  };
161
166
  };
162
167
 
163
- // src/scheduler.ts
164
- var active;
165
- var pending = new Set;
168
+ // src/system.ts
169
+ var activeWatcher;
170
+ var pendingWatchers = new Set;
166
171
  var batchDepth = 0;
167
- var updateMap = new Map;
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) => {
172
+ var createWatcher = (watch) => {
184
173
  const cleanups = new Set;
185
- const w = notice;
186
- w.off = (on) => {
187
- cleanups.add(on);
174
+ const w = watch;
175
+ w.unwatch = (cleanup) => {
176
+ cleanups.add(cleanup);
188
177
  };
189
178
  w.cleanup = () => {
190
- for (const cleanup of cleanups) {
179
+ for (const cleanup of cleanups)
191
180
  cleanup();
192
- }
193
181
  cleanups.clear();
194
182
  };
195
183
  return w;
196
184
  };
197
185
  var subscribe = (watchers) => {
198
- if (active && !watchers.has(active)) {
199
- const watcher = active;
200
- watchers.add(watcher);
201
- active.off(() => {
186
+ if (activeWatcher && !watchers.has(activeWatcher)) {
187
+ const watcher = activeWatcher;
188
+ watcher.unwatch(() => {
202
189
  watchers.delete(watcher);
203
190
  });
191
+ watchers.add(watcher);
204
192
  }
205
193
  };
206
194
  var notify = (watchers) => {
207
195
  for (const watcher of watchers) {
208
196
  if (batchDepth)
209
- pending.add(watcher);
197
+ pendingWatchers.add(watcher);
210
198
  else
211
199
  watcher();
212
200
  }
213
201
  };
214
202
  var flush = () => {
215
- while (pending.size) {
216
- const watchers = Array.from(pending);
217
- pending.clear();
218
- for (const watcher of watchers) {
203
+ while (pendingWatchers.size) {
204
+ const watchers = Array.from(pendingWatchers);
205
+ pendingWatchers.clear();
206
+ for (const watcher of watchers)
219
207
  watcher();
220
- }
221
208
  }
222
209
  };
223
210
  var batch = (fn) => {
@@ -230,30 +217,24 @@ var batch = (fn) => {
230
217
  }
231
218
  };
232
219
  var observe = (run, watcher) => {
233
- const prev = active;
234
- active = watcher;
220
+ const prev = activeWatcher;
221
+ activeWatcher = watcher;
235
222
  try {
236
223
  run();
237
224
  } finally {
238
- active = prev;
225
+ activeWatcher = prev;
239
226
  }
240
227
  };
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
228
 
252
229
  // src/computed.ts
253
230
  var TYPE_COMPUTED = "Computed";
254
- var computed = (fn) => {
231
+ var createComputed = (callback, initialValue = UNSET) => {
232
+ if (!isComputedCallback(callback))
233
+ throw new InvalidCallbackError("computed", valueString(callback));
234
+ if (initialValue == null)
235
+ throw new NullishSignalValueError("computed");
255
236
  const watchers = new Set;
256
- let value = UNSET;
237
+ let value = initialValue;
257
238
  let error;
258
239
  let controller;
259
240
  let dirty = true;
@@ -278,29 +259,29 @@ var computed = (fn) => {
278
259
  value = UNSET;
279
260
  error = newError;
280
261
  };
281
- const settle = (settleFn) => (arg) => {
262
+ const settle = (fn) => (arg) => {
282
263
  computing = false;
283
264
  controller = undefined;
284
- settleFn(arg);
265
+ fn(arg);
285
266
  if (changed)
286
267
  notify(watchers);
287
268
  };
288
- const mark = watch(() => {
269
+ const watcher = createWatcher(() => {
289
270
  dirty = true;
290
271
  controller?.abort();
291
272
  if (watchers.size)
292
273
  notify(watchers);
293
274
  else
294
- mark.cleanup();
275
+ watcher.cleanup();
295
276
  });
296
- mark.off(() => {
277
+ watcher.unwatch(() => {
297
278
  controller?.abort();
298
279
  });
299
280
  const compute = () => observe(() => {
300
281
  if (computing)
301
282
  throw new CircularDependencyError("computed");
302
283
  changed = false;
303
- if (isAsyncFunction(fn)) {
284
+ if (isAsyncFunction(callback)) {
304
285
  if (controller)
305
286
  return value;
306
287
  controller = new AbortController;
@@ -315,7 +296,7 @@ var computed = (fn) => {
315
296
  let result;
316
297
  computing = true;
317
298
  try {
318
- result = controller ? fn(controller.signal) : fn();
299
+ result = controller ? callback(value, controller.signal) : callback(value);
319
300
  } catch (e) {
320
301
  if (isAbortError(e))
321
302
  nil();
@@ -331,29 +312,36 @@ var computed = (fn) => {
331
312
  else
332
313
  ok(result);
333
314
  computing = false;
334
- }, mark);
335
- const c = {
336
- [Symbol.toStringTag]: TYPE_COMPUTED,
337
- get: () => {
338
- subscribe(watchers);
339
- flush();
340
- if (dirty)
341
- compute();
342
- if (error)
343
- throw error;
344
- return value;
315
+ }, watcher);
316
+ const computed = {};
317
+ Object.defineProperties(computed, {
318
+ [Symbol.toStringTag]: {
319
+ value: TYPE_COMPUTED
320
+ },
321
+ get: {
322
+ value: () => {
323
+ subscribe(watchers);
324
+ flush();
325
+ if (dirty)
326
+ compute();
327
+ if (error)
328
+ throw error;
329
+ return value;
330
+ }
345
331
  }
346
- };
347
- return c;
332
+ });
333
+ return computed;
348
334
  };
349
335
  var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
350
- var isComputedCallback = (value) => isFunction(value) && value.length < 2;
336
+ var isComputedCallback = (value) => isFunction(value) && value.length < 3;
351
337
  // src/effect.ts
352
- var effect = (callback) => {
338
+ var createEffect = (callback) => {
339
+ if (!isFunction(callback) || callback.length > 1)
340
+ throw new InvalidCallbackError("effect", valueString(callback));
353
341
  const isAsync = isAsyncFunction(callback);
354
342
  let running = false;
355
343
  let controller;
356
- const run = watch(() => observe(() => {
344
+ const watcher = createWatcher(() => observe(() => {
357
345
  if (running)
358
346
  throw new CircularDependencyError("effect");
359
347
  running = true;
@@ -366,7 +354,7 @@ var effect = (callback) => {
366
354
  const currentController = controller;
367
355
  callback(controller.signal).then((cleanup2) => {
368
356
  if (isFunction(cleanup2) && controller === currentController)
369
- run.off(cleanup2);
357
+ watcher.unwatch(cleanup2);
370
358
  }).catch((error) => {
371
359
  if (!isAbortError(error))
372
360
  console.error("Async effect error:", error);
@@ -374,18 +362,18 @@ var effect = (callback) => {
374
362
  } else {
375
363
  cleanup = callback();
376
364
  if (isFunction(cleanup))
377
- run.off(cleanup);
365
+ watcher.unwatch(cleanup);
378
366
  }
379
367
  } catch (error) {
380
368
  if (!isAbortError(error))
381
369
  console.error("Effect callback error:", error);
382
370
  }
383
371
  running = false;
384
- }, run));
385
- run();
372
+ }, watcher));
373
+ watcher();
386
374
  return () => {
387
375
  controller?.abort();
388
- run.cleanup();
376
+ watcher.cleanup();
389
377
  };
390
378
  };
391
379
  // src/match.ts
@@ -407,20 +395,20 @@ function match(result, handlers) {
407
395
  // src/resolve.ts
408
396
  function resolve(signals) {
409
397
  const errors = [];
410
- let pending2 = false;
398
+ let pending = false;
411
399
  const values = {};
412
400
  for (const [key, signal] of Object.entries(signals)) {
413
401
  try {
414
402
  const value = signal.get();
415
403
  if (value === UNSET)
416
- pending2 = true;
404
+ pending = true;
417
405
  else
418
406
  values[key] = value;
419
407
  } catch (e) {
420
408
  errors.push(toError(e));
421
409
  }
422
410
  }
423
- if (pending2)
411
+ if (pending)
424
412
  return { ok: false, pending: true };
425
413
  if (errors.length > 0)
426
414
  return { ok: false, errors };
@@ -428,54 +416,75 @@ function resolve(signals) {
428
416
  }
429
417
  // src/state.ts
430
418
  var TYPE_STATE = "State";
431
- var state = (initialValue) => {
419
+ var createState = (initialValue) => {
420
+ if (initialValue == null)
421
+ throw new NullishSignalValueError("state");
432
422
  const watchers = new Set;
433
423
  let value = initialValue;
434
- const s = {
435
- [Symbol.toStringTag]: TYPE_STATE,
436
- get: () => {
437
- subscribe(watchers);
438
- return value;
424
+ const setValue = (newValue) => {
425
+ if (newValue == null)
426
+ throw new NullishSignalValueError("state");
427
+ if (isEqual(value, newValue))
428
+ return;
429
+ value = newValue;
430
+ notify(watchers);
431
+ if (UNSET === value)
432
+ watchers.clear();
433
+ };
434
+ const state = {};
435
+ Object.defineProperties(state, {
436
+ [Symbol.toStringTag]: {
437
+ value: TYPE_STATE
439
438
  },
440
- set: (v) => {
441
- if (v == null)
442
- throw new NullishSignalValueError("state");
443
- if (isEqual(value, v))
444
- return;
445
- value = v;
446
- notify(watchers);
447
- if (UNSET === value)
448
- watchers.clear();
439
+ get: {
440
+ value: () => {
441
+ subscribe(watchers);
442
+ return value;
443
+ }
444
+ },
445
+ set: {
446
+ value: (newValue) => {
447
+ setValue(newValue);
448
+ }
449
449
  },
450
- update: (fn) => {
451
- s.set(fn(value));
450
+ update: {
451
+ value: (updater) => {
452
+ if (!isFunction(updater))
453
+ throw new InvalidCallbackError("state update", valueString(updater));
454
+ setValue(updater(value));
455
+ }
452
456
  }
453
- };
454
- return s;
457
+ });
458
+ return state;
455
459
  };
456
460
  var isState = (value) => isObjectOfType(value, TYPE_STATE);
457
461
 
458
462
  // src/store.ts
459
463
  var TYPE_STORE = "Store";
460
- var STORE_EVENT_ADD = "store-add";
461
- var STORE_EVENT_CHANGE = "store-change";
462
- var STORE_EVENT_REMOVE = "store-remove";
463
- var STORE_EVENT_SORT = "store-sort";
464
- var store = (initialValue) => {
464
+ var createStore = (initialValue) => {
465
+ if (initialValue == null)
466
+ throw new NullishSignalValueError("store");
465
467
  const watchers = new Set;
466
- const eventTarget = new EventTarget;
468
+ const listeners = {
469
+ add: new Set,
470
+ change: new Set,
471
+ remove: new Set,
472
+ sort: new Set
473
+ };
467
474
  const signals = new Map;
468
- const cleanups = new Map;
475
+ const signalWatchers = new Map;
469
476
  const isArrayLike = Array.isArray(initialValue);
470
- const size = state(0);
471
477
  const current = () => {
472
478
  const record = {};
473
- for (const [key, signal] of signals) {
479
+ for (const [key, signal] of signals)
474
480
  record[key] = signal.get();
475
- }
476
481
  return record;
477
482
  };
478
- const emit = (type, detail) => eventTarget.dispatchEvent(new CustomEvent(type, { detail }));
483
+ const emit = (key, changes) => {
484
+ Object.freeze(changes);
485
+ for (const listener of listeners[key])
486
+ listener(changes);
487
+ };
479
488
  const getSortedIndexes = () => Array.from(signals.keys()).map((k) => Number(k)).filter((n) => Number.isInteger(n)).sort((a, b) => a - b);
480
489
  const isValidValue = (key, value) => {
481
490
  if (value == null)
@@ -489,39 +498,30 @@ var store = (initialValue) => {
489
498
  const addProperty = (key, value, single = false) => {
490
499
  if (!isValidValue(key, value))
491
500
  return false;
492
- const signal = isState(value) || isStore(value) ? value : isRecord(value) ? store(value) : Array.isArray(value) ? store(value) : state(value);
501
+ const signal = isState(value) || isStore(value) ? value : isRecord(value) || Array.isArray(value) ? createStore(value) : createState(value);
493
502
  signals.set(key, signal);
494
- const cleanup = effect(() => {
495
- const currentValue = signal.get();
496
- if (currentValue != null)
497
- emit(STORE_EVENT_CHANGE, {
498
- [key]: currentValue
499
- });
500
- });
501
- cleanups.set(key, cleanup);
503
+ const watcher = createWatcher(() => observe(() => {
504
+ emit("change", { [key]: signal.get() });
505
+ }, watcher));
506
+ watcher();
507
+ signalWatchers.set(key, watcher);
502
508
  if (single) {
503
- size.set(signals.size);
504
509
  notify(watchers);
505
- emit(STORE_EVENT_ADD, {
506
- [key]: value
507
- });
510
+ emit("add", { [key]: value });
508
511
  }
509
512
  return true;
510
513
  };
511
514
  const removeProperty = (key, single = false) => {
512
515
  const ok = signals.delete(key);
513
516
  if (ok) {
514
- const cleanup = cleanups.get(key);
515
- if (cleanup)
516
- cleanup();
517
- cleanups.delete(key);
517
+ const watcher = signalWatchers.get(key);
518
+ if (watcher)
519
+ watcher.cleanup();
520
+ signalWatchers.delete(key);
518
521
  }
519
522
  if (single) {
520
- size.set(signals.size);
521
523
  notify(watchers);
522
- emit(STORE_EVENT_REMOVE, {
523
- [key]: UNSET
524
- });
524
+ emit("remove", { [key]: UNSET });
525
525
  }
526
526
  return ok;
527
527
  };
@@ -529,16 +529,14 @@ var store = (initialValue) => {
529
529
  const changes = diff(oldValue, newValue);
530
530
  batch(() => {
531
531
  if (Object.keys(changes.add).length) {
532
- for (const key in changes.add) {
533
- const value = changes.add[key] ?? UNSET;
534
- addProperty(key, value);
535
- }
532
+ for (const key in changes.add)
533
+ addProperty(key, changes.add[key] ?? UNSET);
536
534
  if (initialRun) {
537
535
  setTimeout(() => {
538
- emit(STORE_EVENT_ADD, changes.add);
536
+ emit("add", changes.add);
539
537
  }, 0);
540
538
  } else {
541
- emit(STORE_EVENT_ADD, changes.add);
539
+ emit("add", changes.add);
542
540
  }
543
541
  }
544
542
  if (Object.keys(changes.change).length) {
@@ -552,141 +550,142 @@ var store = (initialValue) => {
552
550
  else
553
551
  throw new StoreKeyReadonlyError(key, valueString(value));
554
552
  }
555
- emit(STORE_EVENT_CHANGE, changes.change);
553
+ emit("change", changes.change);
556
554
  }
557
555
  if (Object.keys(changes.remove).length) {
558
556
  for (const key in changes.remove)
559
557
  removeProperty(key);
560
- emit(STORE_EVENT_REMOVE, changes.remove);
558
+ emit("remove", changes.remove);
561
559
  }
562
- size.set(signals.size);
563
560
  });
564
561
  return changes.changed;
565
562
  };
566
563
  reconcile({}, initialValue, true);
567
- const s = {
568
- add: isArrayLike ? (v) => {
569
- const nextIndex = signals.size;
570
- const key = String(nextIndex);
571
- addProperty(key, v, true);
572
- } : (k, v) => {
573
- if (!signals.has(k))
574
- addProperty(k, v, true);
575
- else
576
- throw new StoreKeyExistsError(k, valueString(v));
564
+ const store = {};
565
+ Object.defineProperties(store, {
566
+ [Symbol.toStringTag]: {
567
+ value: TYPE_STORE
577
568
  },
578
- get: () => {
579
- subscribe(watchers);
580
- return recordToArray(current());
569
+ [Symbol.isConcatSpreadable]: {
570
+ value: isArrayLike
581
571
  },
582
- remove: isArrayLike ? (index) => {
583
- const currentArray = recordToArray(current());
584
- const currentLength = signals.size;
585
- if (!Array.isArray(currentArray) || index <= -currentLength || index >= currentLength)
586
- throw new StoreKeyRangeError(index);
587
- const newArray = [...currentArray];
588
- newArray.splice(index, 1);
589
- if (reconcile(currentArray, newArray))
590
- notify(watchers);
591
- } : (k) => {
592
- if (signals.has(k))
593
- removeProperty(k, true);
572
+ [Symbol.iterator]: {
573
+ value: isArrayLike ? function* () {
574
+ const indexes = getSortedIndexes();
575
+ for (const index of indexes) {
576
+ const signal = signals.get(String(index));
577
+ if (signal)
578
+ yield signal;
579
+ }
580
+ } : function* () {
581
+ for (const [key, signal] of signals)
582
+ yield [key, signal];
583
+ }
594
584
  },
595
- set: (v) => {
596
- if (reconcile(current(), v)) {
597
- notify(watchers);
598
- if (UNSET === v)
599
- watchers.clear();
585
+ add: {
586
+ value: isArrayLike ? (v) => {
587
+ addProperty(String(signals.size), v, true);
588
+ } : (k, v) => {
589
+ if (!signals.has(k))
590
+ addProperty(k, v, true);
591
+ else
592
+ throw new StoreKeyExistsError(k, valueString(v));
593
+ }
594
+ },
595
+ get: {
596
+ value: () => {
597
+ subscribe(watchers);
598
+ return recordToArray(current());
599
+ }
600
+ },
601
+ remove: {
602
+ value: isArrayLike ? (index) => {
603
+ const currentArray = recordToArray(current());
604
+ const currentLength = signals.size;
605
+ if (!Array.isArray(currentArray) || index <= -currentLength || index >= currentLength)
606
+ throw new StoreKeyRangeError(index);
607
+ const newArray = [...currentArray];
608
+ newArray.splice(index, 1);
609
+ if (reconcile(currentArray, newArray))
610
+ notify(watchers);
611
+ } : (k) => {
612
+ if (signals.has(k))
613
+ removeProperty(k, true);
614
+ }
615
+ },
616
+ set: {
617
+ value: (v) => {
618
+ if (reconcile(current(), v)) {
619
+ notify(watchers);
620
+ if (UNSET === v)
621
+ watchers.clear();
622
+ }
600
623
  }
601
624
  },
602
- update: (fn) => {
603
- const oldValue = current();
604
- const newValue = fn(recordToArray(oldValue));
605
- if (reconcile(oldValue, newValue)) {
625
+ update: {
626
+ value: (fn) => {
627
+ const oldValue = current();
628
+ const newValue = fn(recordToArray(oldValue));
629
+ if (reconcile(oldValue, newValue)) {
630
+ notify(watchers);
631
+ if (UNSET === newValue)
632
+ watchers.clear();
633
+ }
634
+ }
635
+ },
636
+ sort: {
637
+ value: (compareFn) => {
638
+ const entries = Array.from(signals.entries()).map(([key, signal]) => [key, signal.get()]).sort(compareFn ? (a, b) => compareFn(a[1], b[1]) : (a, b) => String(a[1]).localeCompare(String(b[1])));
639
+ const newOrder = entries.map(([key]) => String(key));
640
+ const newSignals = new Map;
641
+ entries.forEach(([key], newIndex) => {
642
+ const oldKey = String(key);
643
+ const newKey = isArrayLike ? String(newIndex) : String(key);
644
+ const signal = signals.get(oldKey);
645
+ if (signal)
646
+ newSignals.set(newKey, signal);
647
+ });
648
+ signals.clear();
649
+ newSignals.forEach((signal, key) => signals.set(key, signal));
606
650
  notify(watchers);
607
- if (UNSET === newValue)
608
- watchers.clear();
651
+ emit("sort", newOrder);
609
652
  }
610
653
  },
611
- sort: (compareFn) => {
612
- const entries = Array.from(signals.entries()).map(([key, signal]) => [key, signal.get()]).sort(compareFn ? (a, b) => compareFn(a[1], b[1]) : (a, b) => String(a[1]).localeCompare(String(b[1])));
613
- const newOrder = entries.map(([key]) => String(key));
614
- const newSignals = new Map;
615
- entries.forEach(([key], newIndex) => {
616
- const oldKey = String(key);
617
- const newKey = isArrayLike ? String(newIndex) : String(key);
618
- const signal = signals.get(oldKey);
619
- if (signal)
620
- newSignals.set(newKey, signal);
621
- });
622
- signals.clear();
623
- newSignals.forEach((signal, key) => signals.set(key, signal));
624
- notify(watchers);
625
- emit(STORE_EVENT_SORT, newOrder);
654
+ on: {
655
+ value: (type, listener) => {
656
+ listeners[type].add(listener);
657
+ return () => listeners[type].delete(listener);
658
+ }
626
659
  },
627
- addEventListener: eventTarget.addEventListener.bind(eventTarget),
628
- removeEventListener: eventTarget.removeEventListener.bind(eventTarget),
629
- dispatchEvent: eventTarget.dispatchEvent.bind(eventTarget),
630
- size
631
- };
632
- return new Proxy({}, {
633
- get(_target, prop) {
634
- if (prop === Symbol.toStringTag)
635
- return TYPE_STORE;
636
- if (prop === Symbol.isConcatSpreadable)
637
- return isArrayLike;
638
- if (prop === Symbol.iterator)
639
- return isArrayLike ? function* () {
640
- const indexes = getSortedIndexes();
641
- for (const index of indexes) {
642
- const signal = signals.get(String(index));
643
- if (signal)
644
- yield signal;
645
- }
646
- } : function* () {
647
- for (const [key, signal] of signals)
648
- yield [key, signal];
649
- };
650
- if (isSymbol(prop))
651
- return;
652
- if (prop in s)
653
- return s[prop];
654
- if (prop === "length" && isArrayLike) {
660
+ length: {
661
+ get() {
655
662
  subscribe(watchers);
656
- return size.get();
663
+ return signals.size;
657
664
  }
665
+ }
666
+ });
667
+ return new Proxy(store, {
668
+ get(target, prop) {
669
+ if (prop in target)
670
+ return Reflect.get(target, prop);
671
+ if (isSymbol(prop))
672
+ return;
658
673
  return signals.get(prop);
659
674
  },
660
- has(_target, prop) {
661
- const stringProp = String(prop);
662
- return stringProp && signals.has(stringProp) || Object.keys(s).includes(stringProp) || prop === Symbol.toStringTag || prop === Symbol.iterator || prop === Symbol.isConcatSpreadable || prop === "length" && isArrayLike;
675
+ has(target, prop) {
676
+ if (prop in target)
677
+ return true;
678
+ return signals.has(String(prop));
663
679
  },
664
- ownKeys() {
665
- return isArrayLike ? getSortedIndexes().map((key) => String(key)).concat(["length"]) : Array.from(signals.keys()).map((key) => String(key));
680
+ ownKeys(target) {
681
+ const staticKeys = Reflect.ownKeys(target);
682
+ const signalKeys = isArrayLike ? getSortedIndexes().map((key) => String(key)) : Array.from(signals.keys());
683
+ return [...new Set([...signalKeys, ...staticKeys])];
666
684
  },
667
- getOwnPropertyDescriptor(_target, prop) {
668
- const nonEnumerable = (value) => ({
669
- enumerable: false,
670
- configurable: true,
671
- writable: false,
672
- value
673
- });
674
- if (prop === "length" && isArrayLike)
675
- return {
676
- enumerable: true,
677
- configurable: true,
678
- writable: false,
679
- value: size.get()
680
- };
681
- if (prop === Symbol.isConcatSpreadable)
682
- return nonEnumerable(isArrayLike);
683
- if (prop === Symbol.toStringTag)
684
- return nonEnumerable(TYPE_STORE);
685
- if (isSymbol(prop))
686
- return;
687
- if (Object.keys(s).includes(prop))
688
- return nonEnumerable(s[prop]);
689
- const signal = signals.get(prop);
685
+ getOwnPropertyDescriptor(target, prop) {
686
+ if (prop in target)
687
+ return Reflect.getOwnPropertyDescriptor(target, prop);
688
+ const signal = signals.get(String(prop));
690
689
  return signal ? {
691
690
  enumerable: true,
692
691
  configurable: true,
@@ -705,18 +704,16 @@ function toSignal(value) {
705
704
  if (isSignal(value))
706
705
  return value;
707
706
  if (isComputedCallback(value))
708
- return computed(value);
707
+ return createComputed(value);
709
708
  if (Array.isArray(value) || isRecord(value))
710
- return store(value);
711
- return state(value);
709
+ return createStore(value);
710
+ return createState(value);
712
711
  }
713
712
  export {
714
- watch,
713
+ valueString,
715
714
  toSignal,
716
715
  toError,
717
716
  subscribe,
718
- store,
719
- state,
720
717
  resolve,
721
718
  observe,
722
719
  notify,
@@ -728,6 +725,7 @@ export {
728
725
  isSignal,
729
726
  isRecordOrArray,
730
727
  isRecord,
728
+ isObjectOfType,
731
729
  isNumber,
732
730
  isMutableSignal,
733
731
  isFunction,
@@ -737,10 +735,12 @@ export {
737
735
  isAsyncFunction,
738
736
  isAbortError,
739
737
  flush,
740
- enqueue,
741
- effect,
742
738
  diff,
743
- computed,
739
+ createWatcher,
740
+ createStore,
741
+ createState,
742
+ createEffect,
743
+ createComputed,
744
744
  batch,
745
745
  UNSET,
746
746
  TYPE_STORE,
@@ -751,5 +751,6 @@ export {
751
751
  StoreKeyExistsError,
752
752
  NullishSignalValueError,
753
753
  InvalidSignalValueError,
754
+ InvalidCallbackError,
754
755
  CircularDependencyError
755
756
  };