@zeix/cause-effect 0.16.0 → 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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Cause & Effect
2
2
 
3
- Version 0.16.0
3
+ Version 0.16.1
4
4
 
5
5
  **Cause & Effect** is a lightweight, reactive state management library for JavaScript applications. It uses fine-grained reactivity with signals to create predictable and efficient data flow in your app.
6
6
 
package/index.dev.js CHANGED
@@ -71,9 +71,8 @@ var recordToArray = (record) => {
71
71
  if (indexes === null)
72
72
  return record;
73
73
  const array = [];
74
- for (const index of indexes) {
74
+ for (const index of indexes)
75
75
  array.push(record[String(index)]);
76
- }
77
76
  return array;
78
77
  };
79
78
  var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
@@ -314,18 +313,24 @@ var createComputed = (callback, initialValue = UNSET) => {
314
313
  ok(result);
315
314
  computing = false;
316
315
  }, watcher);
317
- return {
318
- [Symbol.toStringTag]: TYPE_COMPUTED,
319
- get: () => {
320
- subscribe(watchers);
321
- flush();
322
- if (dirty)
323
- compute();
324
- if (error)
325
- throw error;
326
- return value;
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
+ }
327
331
  }
328
- };
332
+ });
333
+ return computed;
329
334
  };
330
335
  var isComputed = (value) => isObjectOfType(value, TYPE_COMPUTED);
331
336
  var isComputedCallback = (value) => isFunction(value) && value.length < 3;
@@ -416,28 +421,40 @@ var createState = (initialValue) => {
416
421
  throw new NullishSignalValueError("state");
417
422
  const watchers = new Set;
418
423
  let value = initialValue;
419
- const state = {
420
- [Symbol.toStringTag]: TYPE_STATE,
421
- get: () => {
422
- subscribe(watchers);
423
- 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
424
438
  },
425
- set: (newValue) => {
426
- if (newValue == null)
427
- throw new NullishSignalValueError("state");
428
- if (isEqual(value, newValue))
429
- return;
430
- value = newValue;
431
- notify(watchers);
432
- if (UNSET === value)
433
- watchers.clear();
439
+ get: {
440
+ value: () => {
441
+ subscribe(watchers);
442
+ return value;
443
+ }
444
+ },
445
+ set: {
446
+ value: (newValue) => {
447
+ setValue(newValue);
448
+ }
434
449
  },
435
- update: (updater) => {
436
- if (!isFunction(updater))
437
- throw new InvalidCallbackError("state update", valueString(updater));
438
- state.set(updater(value));
450
+ update: {
451
+ value: (updater) => {
452
+ if (!isFunction(updater))
453
+ throw new InvalidCallbackError("state update", valueString(updater));
454
+ setValue(updater(value));
455
+ }
439
456
  }
440
- };
457
+ });
441
458
  return state;
442
459
  };
443
460
  var isState = (value) => isObjectOfType(value, TYPE_STATE);
@@ -457,19 +474,16 @@ var createStore = (initialValue) => {
457
474
  const signals = new Map;
458
475
  const signalWatchers = new Map;
459
476
  const isArrayLike = Array.isArray(initialValue);
460
- const size = createState(0);
461
477
  const current = () => {
462
478
  const record = {};
463
- for (const [key, signal] of signals) {
479
+ for (const [key, signal] of signals)
464
480
  record[key] = signal.get();
465
- }
466
481
  return record;
467
482
  };
468
483
  const emit = (key, changes) => {
469
484
  Object.freeze(changes);
470
- for (const listener of listeners[key]) {
485
+ for (const listener of listeners[key])
471
486
  listener(changes);
472
- }
473
487
  };
474
488
  const getSortedIndexes = () => Array.from(signals.keys()).map((k) => Number(k)).filter((n) => Number.isInteger(n)).sort((a, b) => a - b);
475
489
  const isValidValue = (key, value) => {
@@ -487,18 +501,13 @@ var createStore = (initialValue) => {
487
501
  const signal = isState(value) || isStore(value) ? value : isRecord(value) || Array.isArray(value) ? createStore(value) : createState(value);
488
502
  signals.set(key, signal);
489
503
  const watcher = createWatcher(() => observe(() => {
490
- emit("change", {
491
- [key]: signal.get()
492
- });
504
+ emit("change", { [key]: signal.get() });
493
505
  }, watcher));
494
506
  watcher();
495
507
  signalWatchers.set(key, watcher);
496
508
  if (single) {
497
- size.set(signals.size);
498
509
  notify(watchers);
499
- emit("add", {
500
- [key]: value
501
- });
510
+ emit("add", { [key]: value });
502
511
  }
503
512
  return true;
504
513
  };
@@ -511,11 +520,8 @@ var createStore = (initialValue) => {
511
520
  signalWatchers.delete(key);
512
521
  }
513
522
  if (single) {
514
- size.set(signals.size);
515
523
  notify(watchers);
516
- emit("remove", {
517
- [key]: UNSET
518
- });
524
+ emit("remove", { [key]: UNSET });
519
525
  }
520
526
  return ok;
521
527
  };
@@ -523,10 +529,8 @@ var createStore = (initialValue) => {
523
529
  const changes = diff(oldValue, newValue);
524
530
  batch(() => {
525
531
  if (Object.keys(changes.add).length) {
526
- for (const key in changes.add) {
527
- const value = changes.add[key] ?? UNSET;
528
- addProperty(key, value);
529
- }
532
+ for (const key in changes.add)
533
+ addProperty(key, changes.add[key] ?? UNSET);
530
534
  if (initialRun) {
531
535
  setTimeout(() => {
532
536
  emit("add", changes.add);
@@ -553,135 +557,135 @@ var createStore = (initialValue) => {
553
557
  removeProperty(key);
554
558
  emit("remove", changes.remove);
555
559
  }
556
- size.set(signals.size);
557
560
  });
558
561
  return changes.changed;
559
562
  };
560
563
  reconcile({}, initialValue, true);
561
- const store = {
562
- add: isArrayLike ? (v) => {
563
- const nextIndex = signals.size;
564
- const key = String(nextIndex);
565
- addProperty(key, v, true);
566
- } : (k, v) => {
567
- if (!signals.has(k))
568
- addProperty(k, v, true);
569
- else
570
- throw new StoreKeyExistsError(k, valueString(v));
564
+ const store = {};
565
+ Object.defineProperties(store, {
566
+ [Symbol.toStringTag]: {
567
+ value: TYPE_STORE
571
568
  },
572
- get: () => {
573
- subscribe(watchers);
574
- return recordToArray(current());
569
+ [Symbol.isConcatSpreadable]: {
570
+ value: isArrayLike
575
571
  },
576
- remove: isArrayLike ? (index) => {
577
- const currentArray = recordToArray(current());
578
- const currentLength = signals.size;
579
- if (!Array.isArray(currentArray) || index <= -currentLength || index >= currentLength)
580
- throw new StoreKeyRangeError(index);
581
- const newArray = [...currentArray];
582
- newArray.splice(index, 1);
583
- if (reconcile(currentArray, newArray))
584
- notify(watchers);
585
- } : (k) => {
586
- if (signals.has(k))
587
- 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
+ }
588
584
  },
589
- set: (v) => {
590
- if (reconcile(current(), v)) {
591
- notify(watchers);
592
- if (UNSET === v)
593
- 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));
594
593
  }
595
594
  },
596
- update: (fn) => {
597
- const oldValue = current();
598
- const newValue = fn(recordToArray(oldValue));
599
- if (reconcile(oldValue, newValue)) {
600
- notify(watchers);
601
- if (UNSET === newValue)
602
- watchers.clear();
595
+ get: {
596
+ value: () => {
597
+ subscribe(watchers);
598
+ return recordToArray(current());
603
599
  }
604
600
  },
605
- sort: (compareFn) => {
606
- 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])));
607
- const newOrder = entries.map(([key]) => String(key));
608
- const newSignals = new Map;
609
- entries.forEach(([key], newIndex) => {
610
- const oldKey = String(key);
611
- const newKey = isArrayLike ? String(newIndex) : String(key);
612
- const signal = signals.get(oldKey);
613
- if (signal)
614
- newSignals.set(newKey, signal);
615
- });
616
- signals.clear();
617
- newSignals.forEach((signal, key) => signals.set(key, signal));
618
- notify(watchers);
619
- emit("sort", newOrder);
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
+ }
620
615
  },
621
- on: (type, listener) => {
622
- listeners[type].add(listener);
623
- return () => listeners[type].delete(listener);
616
+ set: {
617
+ value: (v) => {
618
+ if (reconcile(current(), v)) {
619
+ notify(watchers);
620
+ if (UNSET === v)
621
+ watchers.clear();
622
+ }
623
+ }
624
624
  },
625
- size
626
- };
627
- return new Proxy({}, {
628
- get(_target, prop) {
629
- if (prop === Symbol.toStringTag)
630
- return TYPE_STORE;
631
- if (prop === Symbol.isConcatSpreadable)
632
- return isArrayLike;
633
- if (prop === Symbol.iterator)
634
- return isArrayLike ? function* () {
635
- const indexes = getSortedIndexes();
636
- for (const index of indexes) {
637
- const signal = signals.get(String(index));
638
- if (signal)
639
- yield signal;
640
- }
641
- } : function* () {
642
- for (const [key, signal] of signals)
643
- yield [key, signal];
644
- };
645
- if (isSymbol(prop))
646
- return;
647
- if (prop in store)
648
- return store[prop];
649
- if (prop === "length" && isArrayLike) {
650
- subscribe(watchers);
651
- return size.get();
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
+ }
652
634
  }
653
- return signals.get(prop);
654
635
  },
655
- has(_target, prop) {
656
- const stringProp = String(prop);
657
- return stringProp && signals.has(stringProp) || Object.keys(store).includes(stringProp) || prop === Symbol.toStringTag || prop === Symbol.iterator || prop === Symbol.isConcatSpreadable || prop === "length" && isArrayLike;
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));
650
+ notify(watchers);
651
+ emit("sort", newOrder);
652
+ }
658
653
  },
659
- ownKeys() {
660
- return isArrayLike ? getSortedIndexes().map((key) => String(key)).concat(["length"]) : Array.from(signals.keys()).map((key) => String(key));
654
+ on: {
655
+ value: (type, listener) => {
656
+ listeners[type].add(listener);
657
+ return () => listeners[type].delete(listener);
658
+ }
661
659
  },
662
- getOwnPropertyDescriptor(_target, prop) {
663
- const nonEnumerable = (value) => ({
664
- enumerable: false,
665
- configurable: true,
666
- writable: false,
667
- value
668
- });
669
- if (prop === "length" && isArrayLike)
670
- return {
671
- enumerable: true,
672
- configurable: true,
673
- writable: false,
674
- value: size.get()
675
- };
676
- if (prop === Symbol.isConcatSpreadable)
677
- return nonEnumerable(isArrayLike);
678
- if (prop === Symbol.toStringTag)
679
- return nonEnumerable(TYPE_STORE);
660
+ length: {
661
+ get() {
662
+ subscribe(watchers);
663
+ return signals.size;
664
+ }
665
+ }
666
+ });
667
+ return new Proxy(store, {
668
+ get(target, prop) {
669
+ if (prop in target)
670
+ return Reflect.get(target, prop);
680
671
  if (isSymbol(prop))
681
672
  return;
682
- if (Object.keys(store).includes(prop))
683
- return nonEnumerable(store[prop]);
684
- const signal = signals.get(prop);
673
+ return signals.get(prop);
674
+ },
675
+ has(target, prop) {
676
+ if (prop in target)
677
+ return true;
678
+ return signals.has(String(prop));
679
+ },
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])];
684
+ },
685
+ getOwnPropertyDescriptor(target, prop) {
686
+ if (prop in target)
687
+ return Reflect.getOwnPropertyDescriptor(target, prop);
688
+ const signal = signals.get(String(prop));
685
689
  return signal ? {
686
690
  enumerable: true,
687
691
  configurable: true,
@@ -721,6 +725,7 @@ export {
721
725
  isSignal,
722
726
  isRecordOrArray,
723
727
  isRecord,
728
+ isObjectOfType,
724
729
  isNumber,
725
730
  isMutableSignal,
726
731
  isFunction,
package/index.js CHANGED
@@ -1 +1 @@
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};
1
+ class _ extends Error{constructor($){super(`Circular dependency detected in ${$}`);this.name="CircularDependencyError"}}class W extends TypeError{constructor($,x){super(`Invalid ${$} callback ${x}`);this.name="InvalidCallbackError"}}class h 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 v extends Error{constructor($,x){super(`Could not add store key "${$}" with value ${x} because it already exists`);this.name="StoreKeyExistsError"}}class n extends RangeError{constructor($){super(`Could not remove store index ${String($)} because it is out of range`);this.name="StoreKeyRangeError"}}class u extends Error{constructor($,x){super(`Could not set store key "${$}" to ${x} because it is readonly`);this.name="StoreKeyReadonlyError"}}var q=Symbol(),e=($)=>typeof $==="string",X$=($)=>typeof $==="number",c=($)=>typeof $==="symbol",K=($)=>typeof $==="function",g=($)=>K($)&&$.constructor.name==="AsyncFunction",m=($,x)=>Object.prototype.toString.call($)===`[object ${x}]`,A=($)=>m($,"Object"),s=($)=>A($)||Array.isArray($),H$=($)=>{if(!$.length)return null;let x=$.map((z)=>e(z)?parseInt(z,10):X$(z)?z:NaN);return x.every((z)=>Number.isFinite(z)&&z>=0)?x.sort((z,J)=>z-J):null};var y=($)=>$ instanceof DOMException&&$.name==="AbortError",U=($)=>$ instanceof Error?$:Error(String($));var t=($)=>{let x=H$(Object.keys($));if(x===null)return $;let z=[];for(let J of x)z.push($[String(J)]);return z},F=($)=>e($)?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($);var f=($,x,z)=>{if(Object.is($,x))return!0;if(typeof $!==typeof x)return!1;if(typeof $!=="object"||$===null||x===null)return!1;if(!z)z=new WeakSet;if(z.has($)||z.has(x))throw new _("isEqual");z.add($),z.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],z))return!1;return!0}if(Array.isArray($)!==Array.isArray(x))return!1;if(A($)&&A(x)){let J=Object.keys($),X=Object.keys(x);if(J.length!==X.length)return!1;for(let M of J){if(!(M in x))return!1;if(!f($[M],x[M],z))return!1}return!0}return!1}finally{z.delete($),z.delete(x)}},$$=($,x)=>{let z=s($),J=s(x);if(!z||!J){let C=!Object.is($,x);return{changed:C,add:C&&J?x:{},change:{},remove:C&&z?$:{}}}let X=new WeakSet,M={},H={},I={},Y=Object.keys($),E=Object.keys(x),P=new Set([...Y,...E]);for(let C of P){let N=C in $,R=C in x;if(!N&&R){M[C]=x[C];continue}else if(N&&!R){I[C]=q;continue}let B=$[C],G=x[C];if(!f(B,G,X))H[C]=G}return{changed:Object.keys(M).length>0||Object.keys(H).length>0||Object.keys(I).length>0,add:M,change:H,remove:I}};var p,i=new Set,x$=0,O=($)=>{let x=new Set,z=$;return z.unwatch=(J)=>{x.add(J)},z.cleanup=()=>{for(let J of x)J();x.clear()},z},j=($)=>{if(p&&!$.has(p)){let x=p;x.unwatch(()=>{$.delete(x)}),$.add(x)}},T=($)=>{for(let x of $)if(x$)i.add(x);else x()},r=()=>{while(i.size){let $=Array.from(i);i.clear();for(let x of $)x()}},R$=($)=>{x$++;try{$()}finally{r(),x$--}},S=($,x)=>{let z=p;p=x;try{$()}finally{p=z}};var B$="Computed",J$=($,x=q)=>{if(!l($))throw new W("computed",F($));if(x==null)throw new L("computed");let z=new Set,J=x,X,M,H=!0,I=!1,Y=!1,E=(G)=>{if(!f(G,J))J=G,I=!0;X=void 0,H=!1},P=()=>{I=q!==J,J=q,X=void 0},V=(G)=>{let Q=U(G);I=!X||Q.name!==X.name||Q.message!==X.message,J=q,X=Q},C=(G)=>(Q)=>{if(Y=!1,M=void 0,G(Q),I)T(z)},N=O(()=>{if(H=!0,M?.abort(),z.size)T(z);else N.cleanup()});N.unwatch(()=>{M?.abort()});let R=()=>S(()=>{if(Y)throw new _("computed");if(I=!1,g($)){if(M)return J;M=new AbortController,M.signal.addEventListener("abort",()=>{Y=!1,M=void 0,R()},{once:!0})}let G;Y=!0;try{G=M?$(J,M.signal):$(J)}catch(Q){if(y(Q))P();else V(Q);Y=!1;return}if(G instanceof Promise)G.then(C(E),C(V));else if(G==null||q===G)P();else E(G);Y=!1},N),B={};return Object.defineProperties(B,{[Symbol.toStringTag]:{value:B$},get:{value:()=>{if(j(z),r(),H)R();if(X)throw X;return J}}}),B},w=($)=>m($,B$),l=($)=>K($)&&$.length<3;var C$=($)=>{if(!K($)||$.length>1)throw new W("effect",F($));let x=g($),z=!1,J,X=O(()=>S(()=>{if(z)throw new _("effect");z=!0,J?.abort(),J=void 0;let M;try{if(x){J=new AbortController;let H=J;$(J.signal).then((I)=>{if(K(I)&&J===H)X.unwatch(I)}).catch((I)=>{if(!y(I))console.error("Async effect error:",I)})}else if(M=$(),K(M))X.unwatch(M)}catch(H){if(!y(H))console.error("Effect callback error:",H)}z=!1},X));return X(),()=>{J?.abort(),X.cleanup()}};function q$($,x){try{if($.pending)x.nil?.();else if($.errors)x.err?.($.errors);else if($.ok)x.ok($.values)}catch(z){if(x.err&&(!$.errors||!$.errors.includes(U(z))))x.err($.errors?[...$.errors,U(z)]:[U(z)]);else throw z}}function D$($){let x=[],z=!1,J={};for(let[X,M]of Object.entries($))try{let H=M.get();if(H===q)z=!0;else J[X]=H}catch(H){x.push(U(H))}if(z)return{ok:!1,pending:!0};if(x.length>0)return{ok:!1,errors:x};return{ok:!0,values:J}}var z$="State",k=($)=>{if($==null)throw new L("state");let x=new Set,z=$,J=(M)=>{if(M==null)throw new L("state");if(f(z,M))return;if(z=M,T(x),q===z)x.clear()},X={};return Object.defineProperties(X,{[Symbol.toStringTag]:{value:z$},get:{value:()=>{return j(x),z}},set:{value:(M)=>{J(M)}},update:{value:(M)=>{if(!K(M))throw new W("state update",F(M));J(M(z))}}}),X},b=($)=>m($,z$);var G$="Store",a=($)=>{if($==null)throw new L("store");let x=new Set,z={add:new Set,change:new Set,remove:new Set,sort:new Set},J=new Map,X=new Map,M=Array.isArray($),H=()=>{let R={};for(let[B,G]of J)R[B]=G.get();return R},I=(R,B)=>{Object.freeze(B);for(let G of z[R])G(B)},Y=()=>Array.from(J.keys()).map((R)=>Number(R)).filter((R)=>Number.isInteger(R)).sort((R,B)=>R-B),E=(R,B)=>{if(B==null)throw new L(`store for key "${R}"`);if(B===q)return!0;if(c(B)||K(B)||w(B))throw new h(`store for key "${R}"`,F(B));return!0},P=(R,B,G=!1)=>{if(!E(R,B))return!1;let Q=b(B)||o(B)?B:A(B)||Array.isArray(B)?a(B):k(B);J.set(R,Q);let Z=O(()=>S(()=>{I("change",{[R]:Q.get()})},Z));if(Z(),X.set(R,Z),G)T(x),I("add",{[R]:B});return!0},V=(R,B=!1)=>{let G=J.delete(R);if(G){let Q=X.get(R);if(Q)Q.cleanup();X.delete(R)}if(B)T(x),I("remove",{[R]:q});return G},C=(R,B,G)=>{let Q=$$(R,B);return R$(()=>{if(Object.keys(Q.add).length){for(let Z in Q.add)P(Z,Q.add[Z]??q);if(G)setTimeout(()=>{I("add",Q.add)},0);else I("add",Q.add)}if(Object.keys(Q.change).length){for(let Z in Q.change){let D=Q.change[Z];if(!E(Z,D))continue;let d=J.get(Z);if(M$(d))d.set(D);else throw new u(Z,F(D))}I("change",Q.change)}if(Object.keys(Q.remove).length){for(let Z in Q.remove)V(Z);I("remove",Q.remove)}}),Q.changed};C({},$,!0);let N={};return Object.defineProperties(N,{[Symbol.toStringTag]:{value:G$},[Symbol.isConcatSpreadable]:{value:M},[Symbol.iterator]:{value:M?function*(){let R=Y();for(let B of R){let G=J.get(String(B));if(G)yield G}}:function*(){for(let[R,B]of J)yield[R,B]}},add:{value:M?(R)=>{P(String(J.size),R,!0)}:(R,B)=>{if(!J.has(R))P(R,B,!0);else throw new v(R,F(B))}},get:{value:()=>{return j(x),t(H())}},remove:{value:M?(R)=>{let B=t(H()),G=J.size;if(!Array.isArray(B)||R<=-G||R>=G)throw new n(R);let Q=[...B];if(Q.splice(R,1),C(B,Q))T(x)}:(R)=>{if(J.has(R))V(R,!0)}},set:{value:(R)=>{if(C(H(),R)){if(T(x),q===R)x.clear()}}},update:{value:(R)=>{let B=H(),G=R(t(B));if(C(B,G)){if(T(x),q===G)x.clear()}}},sort:{value:(R)=>{let B=Array.from(J.entries()).map(([Z,D])=>[Z,D.get()]).sort(R?(Z,D)=>R(Z[1],D[1]):(Z,D)=>String(Z[1]).localeCompare(String(D[1]))),G=B.map(([Z])=>String(Z)),Q=new Map;B.forEach(([Z],D)=>{let d=String(Z),I$=M?String(D):String(Z),Q$=J.get(d);if(Q$)Q.set(I$,Q$)}),J.clear(),Q.forEach((Z,D)=>J.set(D,Z)),T(x),I("sort",G)}},on:{value:(R,B)=>{return z[R].add(B),()=>z[R].delete(B)}},length:{get(){return j(x),J.size}}}),new Proxy(N,{get(R,B){if(B in R)return Reflect.get(R,B);if(c(B))return;return J.get(B)},has(R,B){if(B in R)return!0;return J.has(String(B))},ownKeys(R){let B=Reflect.ownKeys(R),G=M?Y().map((Q)=>String(Q)):Array.from(J.keys());return[...new Set([...G,...B])]},getOwnPropertyDescriptor(R,B){if(B in R)return Reflect.getOwnPropertyDescriptor(R,B);let G=J.get(String(B));return G?{enumerable:!0,configurable:!0,writable:!0,value:G}:void 0}})},o=($)=>m($,G$);var Z$=($)=>b($)||w($)||o($),M$=($)=>b($)||o($);function T$($){if(Z$($))return $;if(l($))return J$($);if(Array.isArray($)||A($))return a($);return k($)}export{F as valueString,T$ as toSignal,U as toError,j as subscribe,D$ as resolve,S as observe,T as notify,q$ as match,c as isSymbol,e as isString,o as isStore,b as isState,Z$ as isSignal,s as isRecordOrArray,A as isRecord,m as isObjectOfType,X$ as isNumber,M$ as isMutableSignal,K as isFunction,f as isEqual,l as isComputedCallback,w as isComputed,g as isAsyncFunction,y as isAbortError,r as flush,$$ as diff,O as createWatcher,a as createStore,k as createState,C$ as createEffect,J$ as createComputed,R$ as batch,q as UNSET,G$ as TYPE_STORE,z$ as TYPE_STATE,B$ as TYPE_COMPUTED,u as StoreKeyReadonlyError,n as StoreKeyRangeError,v as StoreKeyExistsError,L as NullishSignalValueError,h as InvalidSignalValueError,W as InvalidCallbackError,_ as CircularDependencyError};
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @name Cause & Effect
3
- * @version 0.16.0
3
+ * @version 0.16.1
4
4
  * @author Esther Brunner
5
5
  */
6
6
 
@@ -16,9 +16,9 @@ export {
16
16
  type DiffResult,
17
17
  diff,
18
18
  isEqual,
19
+ type PartialRecord,
19
20
  type UnknownArray,
20
21
  type UnknownRecord,
21
- type UnknownRecordOrArray,
22
22
  } from './src/diff'
23
23
  export {
24
24
  createEffect,
@@ -67,6 +67,7 @@ export {
67
67
  isAsyncFunction,
68
68
  isFunction,
69
69
  isNumber,
70
+ isObjectOfType,
70
71
  isRecord,
71
72
  isRecordOrArray,
72
73
  isString,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeix/cause-effect",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "author": "Esther Brunner",
5
5
  "main": "index.js",
6
6
  "module": "index.ts",
package/src/computed.ts CHANGED
@@ -145,23 +145,22 @@ const createComputed = <T extends {}>(
145
145
  computing = false
146
146
  }, watcher)
147
147
 
148
- return {
149
- [Symbol.toStringTag]: TYPE_COMPUTED,
150
-
151
- /**
152
- * Get the current value of the computed
153
- *
154
- * @since 0.9.0
155
- * @returns {T} - Current value of the computed
156
- */
157
- get: (): T => {
158
- subscribe(watchers)
159
- flush()
160
- if (dirty) compute()
161
- if (error) throw error
162
- return value
148
+ const computed: Record<PropertyKey, unknown> = {}
149
+ Object.defineProperties(computed, {
150
+ [Symbol.toStringTag]: {
151
+ value: TYPE_COMPUTED,
163
152
  },
164
- }
153
+ get: {
154
+ value: (): T => {
155
+ subscribe(watchers)
156
+ flush()
157
+ if (dirty) compute()
158
+ if (error) throw error
159
+ return value
160
+ },
161
+ },
162
+ })
163
+ return computed as Computed<T>
165
164
  }
166
165
 
167
166
  /**