@zeix/cause-effect 0.18.3 → 0.18.5

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.18.3
3
+ Version 0.18.5
4
4
 
5
5
  **Cause & Effect** is a reactive state management primitives library for TypeScript. It provides the foundational building blocks for managing complex, dynamic, composite, and asynchronous state — correctly and performantly — in a unified signal graph.
6
6
 
package/index.dev.js CHANGED
@@ -199,10 +199,12 @@ function propagate(node, newFlag = FLAG_DIRTY) {
199
199
  for (let e = node.sinks;e; e = e.nextSink)
200
200
  propagate(e.sink, FLAG_CHECK);
201
201
  } else {
202
- if (flags & FLAG_DIRTY)
202
+ if ((flags & (FLAG_DIRTY | FLAG_CHECK)) >= newFlag)
203
203
  return;
204
- node.flags = FLAG_DIRTY;
205
- queuedEffects.push(node);
204
+ const wasQueued = flags & (FLAG_DIRTY | FLAG_CHECK);
205
+ node.flags = newFlag;
206
+ if (!wasQueued)
207
+ queuedEffects.push(node);
206
208
  }
207
209
  }
208
210
  function setState(node, next) {
@@ -354,7 +356,7 @@ function flush() {
354
356
  try {
355
357
  for (let i = 0;i < queuedEffects.length; i++) {
356
358
  const effect = queuedEffects[i];
357
- if (effect.flags & FLAG_DIRTY)
359
+ if (effect.flags & (FLAG_DIRTY | FLAG_CHECK))
358
360
  refresh(effect);
359
361
  }
360
362
  queuedEffects.length = 0;
@@ -397,6 +399,15 @@ function createScope(fn) {
397
399
  activeOwner = prevOwner;
398
400
  }
399
401
  }
402
+ function unown(fn) {
403
+ const prev = activeOwner;
404
+ activeOwner = null;
405
+ try {
406
+ return fn();
407
+ } finally {
408
+ activeOwner = prev;
409
+ }
410
+ }
400
411
  // src/nodes/state.ts
401
412
  function createState(value, options) {
402
413
  validateSignalValue(TYPE_STATE, value, options?.guard);
@@ -797,9 +808,7 @@ function createMemo(fn, options) {
797
808
  if (activeSink) {
798
809
  if (!node.sinks)
799
810
  node.stop = watched(() => {
800
- node.flags |= FLAG_DIRTY;
801
- for (let e = node.sinks;e; e = e.nextSink)
802
- propagate(e.sink);
811
+ propagate(node);
803
812
  if (batchDepth === 0)
804
813
  flush();
805
814
  });
@@ -848,9 +857,7 @@ function createTask(fn, options) {
848
857
  if (activeSink) {
849
858
  if (!node.sinks)
850
859
  node.stop = watched(() => {
851
- node.flags |= FLAG_DIRTY;
852
- for (let e = node.sinks;e; e = e.nextSink)
853
- propagate(e.sink);
860
+ propagate(node);
854
861
  if (batchDepth === 0)
855
862
  flush();
856
863
  });
@@ -1606,6 +1613,7 @@ function isSlot(value) {
1606
1613
  export {
1607
1614
  valueString,
1608
1615
  untrack,
1616
+ unown,
1609
1617
  match,
1610
1618
  isTask,
1611
1619
  isStore,
package/index.js CHANGED
@@ -1 +1 @@
1
- function g($){return typeof $==="function"}function i($){return g($)&&$.constructor.name==="AsyncFunction"}function z$($){return g($)&&$.constructor.name!=="AsyncFunction"}function A($,J){return Object.prototype.toString.call($)===`[object ${J}]`}function L($){return A($,"Object")}function A$($,J=(z)=>z!=null){return Array.isArray($)&&$.every(J)}function m$($){return typeof $==="string"?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($)}class X$ extends Error{constructor($){super(`[${$}] Circular dependency detected`);this.name="CircularDependencyError"}}class Y$ extends TypeError{constructor($){super(`[${$}] Signal value cannot be null or undefined`);this.name="NullishSignalValueError"}}class o extends Error{constructor($){super(`[${$}] Signal value is unset`);this.name="UnsetSignalValueError"}}class Z$ extends TypeError{constructor($,J){super(`[${$}] Signal value ${m$(J)} is invalid`);this.name="InvalidSignalValueError"}}class b$ extends TypeError{constructor($,J){super(`[${$}] Callback ${m$(J)} is invalid`);this.name="InvalidCallbackError"}}class P$ extends Error{constructor($){super(`[${$}] Signal is read-only`);this.name="ReadonlySignalError"}}class D$ extends Error{constructor($){super(`[${$}] Active owner is required`);this.name="RequiredOwnerError"}}class e extends Error{constructor($,J,z){super(`[${$}] Could not add key "${J}"${z?` with value ${JSON.stringify(z)}`:""} because it already exists`);this.name="DuplicateKeyError"}}function K($,J,z){if(J==null)throw new Y$($);if(z&&!z(J))throw new Z$($,J)}function j$($,J){if(J==null)throw new o($)}function T($,J,z=g){if(!z(J))throw new b$($,J)}var c="State",u="Memo",d="Task",t="Sensor",E="List",l="Collection",r="Store",s="Slot",S=0,C$=1,D=2,M$=4,b=8,N=null,y=null,G$=[],R=0,_$=!1,k=($,J)=>$===J,L$=($,J)=>!1;function g$($,J){let z=J.sourcesTail;if(z){let X=J.sources;while(X){if(X===$)return!0;if(X===z)break;X=X.nextSource}}return!1}function F($,J){let z=J.sourcesTail;if(z?.source===$)return;let X=null,W=J.flags&M$;if(W){if(X=z?z.nextSource:J.sources,X?.source===$){J.sourcesTail=X;return}}let H=$.sinksTail;if(H?.sink===J&&(!W||g$(H,J)))return;let P={source:$,sink:J,nextSource:X,prevSink:H,nextSink:null};if(J.sourcesTail=$.sinksTail=P,z)z.nextSource=P;else J.sources=P;if(H)H.nextSink=P;else $.sinks=P}function k$($){let{source:J,nextSource:z,nextSink:X,prevSink:W}=$;if(X)X.prevSink=W;else J.sinksTail=W;if(W)W.nextSink=X;else J.sinks=X;if(!J.sinks){if(J.stop)J.stop(),J.stop=void 0;if("sources"in J&&J.sources){let H=J;H.sourcesTail=null,W$(H)}}return z}function W$($){let J=$.sourcesTail,z=J?J.nextSource:$.sources;while(z)z=k$(z);if(J)J.nextSource=null;else $.sources=null}function x($,J=D){let z=$.flags;if("sinks"in $){if((z&(D|C$))>=J)return;if($.flags=z|J,"controller"in $&&$.controller)$.controller.abort(),$.controller=void 0;for(let X=$.sinks;X;X=X.nextSink)x(X.sink,C$)}else{if(z&D)return;$.flags=D,G$.push($)}}function U$($,J){if($.equals($.value,J))return;$.value=J;for(let z=$.sinks;z;z=z.nextSink)x(z.sink);if(R===0)w()}function $$($,J){if(!$.cleanup)$.cleanup=J;else if(Array.isArray($.cleanup))$.cleanup.push(J);else $.cleanup=[$.cleanup,J]}function K$($){if(!$.cleanup)return;if(Array.isArray($.cleanup))for(let J=0;J<$.cleanup.length;J++)$.cleanup[J]();else $.cleanup();$.cleanup=null}function v$($){let J=N;N=$,$.sourcesTail=null,$.flags=M$;let z=!1;try{let X=$.fn($.value);if($.error||!$.equals(X,$.value))$.value=X,$.error=void 0,z=!0}catch(X){z=!0,$.error=X instanceof Error?X:Error(String(X))}finally{N=J,W$($)}if(z){for(let X=$.sinks;X;X=X.nextSink)if(X.sink.flags&C$)X.sink.flags|=D}$.flags=S}function c$($){$.controller?.abort();let J=new AbortController;$.controller=J,$.error=void 0;let z=N;N=$,$.sourcesTail=null,$.flags=M$;let X;try{X=$.fn($.value,J.signal)}catch(W){$.controller=void 0,$.error=W instanceof Error?W:Error(String(W));return}finally{N=z,W$($)}X.then((W)=>{if(J.signal.aborted)return;if($.controller=void 0,$.error||!$.equals(W,$.value)){$.value=W,$.error=void 0;for(let H=$.sinks;H;H=H.nextSink)x(H.sink);if(R===0)w()}},(W)=>{if(J.signal.aborted)return;$.controller=void 0;let H=W instanceof Error?W:Error(String(W));if(!$.error||H.name!==$.error.name||H.message!==$.error.message){$.error=H;for(let P=$.sinks;P;P=P.nextSink)x(P.sink);if(R===0)w()}}),$.flags=S}function T$($){K$($);let J=N,z=y;N=y=$,$.sourcesTail=null,$.flags=M$;try{let X=$.fn();if(typeof X==="function")$$($,X)}finally{N=J,y=z,W$($)}$.flags=S}function I($){if($.flags&C$)for(let J=$.sources;J;J=J.nextSource){if("fn"in J.source)I(J.source);if($.flags&D)break}if($.flags&M$)throw new X$("controller"in $?d:("value"in $)?u:"Effect");if($.flags&D)if("controller"in $)c$($);else if("value"in $)v$($);else T$($);else $.flags=S}function w(){if(_$)return;_$=!0;try{for(let $=0;$<G$.length;$++){let J=G$[$];if(J.flags&D)I(J)}G$.length=0}finally{_$=!1}}function J$($){R++;try{$()}finally{if(R--,R===0)w()}}function v($){let J=N;N=null;try{return $()}finally{N=J}}function u$($){let J=y,z={cleanup:null};y=z;try{let X=$();if(typeof X==="function")$$(z,X);let W=()=>K$(z);if(J)$$(J,W);return W}finally{y=J}}function p($,J){K(c,$,J?.guard);let z={value:$,sinks:null,sinksTail:null,equals:J?.equals??k,guard:J?.guard};return{[Symbol.toStringTag]:c,get(){if(N)F(z,N);return z.value},set(X){K(c,X,z.guard),U$(z,X)},update(X){T(c,X);let W=X(z.value);K(c,W,z.guard),U$(z,W)}}}function N$($){return A($,c)}function n($,J,z){if(Object.is($,J))return!0;if(typeof $!==typeof J)return!1;if($==null||typeof $!=="object"||J==null||typeof J!=="object")return!1;if(!z)z=new WeakSet;if(z.has($)||z.has(J))throw new X$("isEqual");z.add($),z.add(J);try{let X=Array.isArray($);if(X!==Array.isArray(J))return!1;if(X){let W=$,H=J;if(W.length!==H.length)return!1;for(let P=0;P<W.length;P++)if(!n(W[P],H[P],z))return!1;return!0}if(L($)&&L(J)){let W=Object.keys($),H=Object.keys(J);if(W.length!==H.length)return!1;for(let P of W){if(!(P in J))return!1;if(!n($[P],J[P],z))return!1}return!0}return!1}finally{z.delete($),z.delete(J)}}function O$($,J){if($.length!==J.length)return!1;for(let z=0;z<$.length;z++)if($[z]!==J[z])return!1;return!0}function E$($){let J=0,z=typeof $==="function";return[typeof $==="string"?()=>`${$}${J++}`:z?(X)=>$(X)||String(J++):()=>String(J++),z]}function d$($,J,z,X,W){let H=new WeakSet,P={},M={},C={},U=[],Q=!1,j=new Map;for(let q=0;q<$.length;q++){let Z=z[q];if(Z&&$[q])j.set(Z,$[q])}let G=new Set;for(let q=0;q<J.length;q++){let Z=J[q];if(Z===void 0)continue;let B=W?X(Z):z[q]??X(Z);if(G.has(B))throw new e(E,B,Z);if(U.push(B),G.add(B),!j.has(B))P[B]=Z,Q=!0;else if(!n(j.get(B),Z,H))M[B]=Z,Q=!0}for(let[q]of j)if(!G.has(q))C[q]=null,Q=!0;if(!Q&&!O$(z,U))Q=!0;return{add:P,change:M,remove:C,newKeys:U,changed:Q}}function H$($,J){K(E,$,Array.isArray);let z=new Map,X=[],[W,H]=E$(J?.keyConfig),P=()=>X.map((Z)=>z.get(Z)?.get()).filter((Z)=>Z!==void 0),M={fn:P,value:$,flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:n,error:void 0},C=(Z)=>{let B={};for(let V=0;V<Z.length;V++){let m=Z[V];if(m===void 0)continue;let O=X[V];if(!O)O=W(m),X[V]=O;B[O]=m}return B},U=(Z)=>{let B=!1;for(let V in Z.add){let m=Z.add[V];K(`${E} item for key "${V}"`,m),z.set(V,p(m)),B=!0}if(Object.keys(Z.change).length)J$(()=>{for(let V in Z.change){let m=Z.change[V];K(`${E} item for key "${V}"`,m);let O=z.get(V);if(O)O.set(m)}});for(let V in Z.remove){z.delete(V);let m=X.indexOf(V);if(m!==-1)X.splice(m,1);B=!0}if(B)M.flags|=b;return Z.changed},Q=J?.watched,j=Q?()=>{if(N){if(!M.sinks)M.stop=Q();F(M,N)}}:()=>{if(N)F(M,N)},G=C($);for(let Z in G){let B=G[Z];K(`${E} item for key "${Z}"`,B),z.set(Z,p(B))}M.value=$,M.flags=0;let q={[Symbol.toStringTag]:E,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let Z of X){let B=z.get(Z);if(B)yield B}},get length(){return j(),X.length},get(){if(j(),M.sources){if(M.flags){let Z=M.flags&b;if(M.value=v(P),Z){if(M.flags=D,I(M),M.error)throw M.error}else M.flags=S}}else if(I(M),M.error)throw M.error;return M.value},set(Z){let B=M.flags&D?P():M.value,V=d$(B,Z,X,W,H);if(V.changed){X=V.newKeys,U(V),M.flags|=D;for(let m=M.sinks;m;m=m.nextSink)x(m.sink);if(R===0)w()}},update(Z){q.set(Z(q.get()))},at(Z){return z.get(X[Z])},keys(){return j(),X.values()},byKey(Z){return z.get(Z)},keyAt(Z){return X[Z]},indexOfKey(Z){return X.indexOf(Z)},add(Z){let B=W(Z);if(z.has(B))throw new e(E,B,Z);if(!X.includes(B))X.push(B);K(`${E} item for key "${B}"`,Z),z.set(B,p(Z)),M.flags|=D|b;for(let V=M.sinks;V;V=V.nextSink)x(V.sink);if(R===0)w();return B},remove(Z){let B=typeof Z==="number"?X[Z]:Z;if(z.delete(B)){let m=typeof Z==="number"?Z:X.indexOf(B);if(m>=0)X.splice(m,1);M.flags|=D|b;for(let O=M.sinks;O;O=O.nextSink)x(O.sink);if(R===0)w()}},sort(Z){let V=X.map((m)=>[m,z.get(m)?.get()]).sort(g(Z)?(m,O)=>Z(m[1],O[1]):(m,O)=>String(m[1]).localeCompare(String(O[1]))).map(([m])=>m);if(!O$(X,V)){X=V,M.flags|=D;for(let m=M.sinks;m;m=m.nextSink)x(m.sink);if(R===0)w()}},splice(Z,B,...V){let m=X.length,O=Z<0?Math.max(0,m+Z):Math.min(Z,m),f=Math.max(0,Math.min(B??Math.max(0,m-Math.max(0,O)),m-O)),Y={},_={};for(let h=0;h<f;h++){let a=O+h,f$=X[a];if(f$){let y$=z.get(f$);if(y$)_[f$]=y$.get()}}let I$=X.slice(0,O);for(let h of V){let a=W(h);if(z.has(a)&&!(a in _))throw new e(E,a,h);I$.push(a),Y[a]=h}I$.push(...X.slice(O+f));let p$=!!(Object.keys(Y).length||Object.keys(_).length);if(p$){U({add:Y,change:{},remove:_,changed:p$}),X=I$,M.flags|=D;for(let h=M.sinks;h;h=h.nextSink)x(h.sink);if(R===0)w()}return Object.values(_)},deriveCollection(Z){return R$(q,Z)}};return q}function F$($){return A($,E)}function Q$($,J){if(T(u,$,z$),J?.value!==void 0)K(u,J.value,J?.guard);let z={fn:$,value:J?.value,flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:J?.equals??k,error:void 0,stop:void 0},X=J?.watched,W=X?()=>{if(N){if(!z.sinks)z.stop=X(()=>{z.flags|=D;for(let H=z.sinks;H;H=H.nextSink)x(H.sink);if(R===0)w()});F(z,N)}}:()=>{if(N)F(z,N)};return{[Symbol.toStringTag]:u,get(){if(W(),I(z),z.error)throw z.error;return j$(u,z.value),z.value}}}function S$($){return A($,u)}function B$($,J){if(T(d,$,i),J?.value!==void 0)K(d,J.value,J?.guard);let z={fn:$,value:J?.value,sources:null,sourcesTail:null,sinks:null,sinksTail:null,flags:D,equals:J?.equals??k,controller:void 0,error:void 0,stop:void 0},X=J?.watched,W=X?()=>{if(N){if(!z.sinks)z.stop=X(()=>{z.flags|=D;for(let H=z.sinks;H;H=H.nextSink)x(H.sink);if(R===0)w()});F(z,N)}}:()=>{if(N)F(z,N)};return{[Symbol.toStringTag]:d,get(){if(W(),I(z),z.error)throw z.error;return j$(d,z.value),z.value},isPending(){return!!z.controller},abort(){z.controller?.abort(),z.controller=void 0}}}function h$($){return A($,d)}function R$($,J){T(l,J);let z=i(J),X=new Map,W=[],H=(q)=>{let Z=z?B$(async(B,V)=>{let m=$.byKey(q)?.get();if(m==null)return B;return J(m,V)}):Q$(()=>{let B=$.byKey(q)?.get();if(B==null)return;return J(B)});X.set(q,Z)};function P(q){if(!O$(W,q)){let Z=new Set(W),B=new Set(q);for(let V of W)if(!B.has(V))X.delete(V);for(let V of q)if(!Z.has(V))H(V);W=q,U.flags|=b}}function M(){P(Array.from($.keys()));let q=[];for(let Z of W)try{let B=X.get(Z)?.get();if(B!=null)q.push(B)}catch(B){if(!(B instanceof o))throw B}return q}let U={fn:M,value:[],flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:(q,Z)=>{if(q.length!==Z.length)return!1;for(let B=0;B<q.length;B++)if(q[B]!==Z[B])return!1;return!0},error:void 0};function Q(){if(U.sources){if(U.flags)if(U.value=v(M),U.flags&b){if(U.flags=D,I(U),U.error)throw U.error}else U.flags=S}else if(U.sinks){if(I(U),U.error)throw U.error}else U.value=v(M)}let j=Array.from(v(()=>$.keys()));for(let q of j)H(q);W=j;let G={[Symbol.toStringTag]:l,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let q of W){let Z=X.get(q);if(Z)yield Z}},get length(){if(N)F(U,N);return Q(),W.length},keys(){if(N)F(U,N);return Q(),W.values()},get(){if(N)F(U,N);return Q(),U.value},at(q){return X.get(W[q])},byKey(q){return X.get(q)},keyAt(q){return W[q]},indexOfKey(q){return W.indexOf(q)},deriveCollection(q){return R$(G,q)}};return G}function t$($,J){let z=J?.value??[];if(z.length)K(l,z,Array.isArray);T(l,$,z$);let X=new Map,W=[],H=new Map,[P,M]=E$(J?.keyConfig),C=(Z)=>H.get(Z)??(M?P(Z):void 0),U=J?.createItem??p;function Q(){let Z=[];for(let B of W)try{let V=X.get(B)?.get();if(V!=null)Z.push(V)}catch(V){if(!(V instanceof o))throw V}return Z}let j={fn:Q,value:z,flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:L$,error:void 0};for(let Z of z){let B=P(Z);X.set(B,U(Z)),H.set(Z,B),W.push(B)}j.value=z,j.flags=D;function G(){if(N){if(!j.sinks)j.stop=$((Z)=>{let{add:B,change:V,remove:m}=Z;if(!B?.length&&!V?.length&&!m?.length)return;let O=!1;J$(()=>{if(B)for(let f of B){let Y=P(f);if(X.set(Y,U(f)),H.set(f,Y),!W.includes(Y))W.push(Y);O=!0}if(V)for(let f of V){let Y=C(f);if(!Y)continue;let _=X.get(Y);if(_&&N$(_))H.delete(_.get()),_.set(f),H.set(f,Y)}if(m)for(let f of m){let Y=C(f);if(!Y)continue;H.delete(f),X.delete(Y);let _=W.indexOf(Y);if(_!==-1)W.splice(_,1);O=!0}j.flags=D|(O?b:0);for(let f=j.sinks;f;f=f.nextSink)x(f.sink)})});F(j,N)}}let q={[Symbol.toStringTag]:l,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let Z of W){let B=X.get(Z);if(B)yield B}},get length(){return G(),W.length},keys(){return G(),W.values()},get(){if(G(),j.sources){if(j.flags){let Z=j.flags&b;if(j.value=v(Q),Z){if(j.flags=D,I(j),j.error)throw j.error}else j.flags=S}}else if(I(j),j.error)throw j.error;return j.value},at(Z){return X.get(W[Z])},byKey(Z){return X.get(Z)},keyAt(Z){return W[Z]},indexOfKey(Z){return W.indexOf(Z)},deriveCollection(Z){return R$(q,Z)}};return q}function l$($){return A($,l)}function r$($){T("Effect",$);let J={fn:$,flags:D,sources:null,sourcesTail:null,cleanup:null},z=()=>{K$(J),J.fn=void 0,J.flags=S,J.sourcesTail=null,W$(J)};if(y)$$(y,z);return T$(J),z}function s$($,J){if(!y)throw new D$("match");let{ok:z,err:X=console.error,nil:W}=J,H,P=!1,M=Array($.length);for(let U=0;U<$.length;U++)try{M[U]=$[U].get()}catch(Q){if(Q instanceof o){P=!0;continue}if(!H)H=[];H.push(Q instanceof Error?Q:Error(String(Q)))}let C;try{if(P)C=W?.();else if(H)C=X(H);else C=z(M)}catch(U){X([U instanceof Error?U:Error(String(U))])}if(typeof C==="function")return C;if(C instanceof Promise){let U=y,Q=new AbortController;$$(U,()=>Q.abort()),C.then((j)=>{if(!Q.signal.aborted&&typeof j==="function")$$(U,j)}).catch((j)=>{X([j instanceof Error?j:Error(String(j))])})}}function i$($,J){if(T(t,$,z$),J?.value!==void 0)K(t,J.value,J?.guard);let z={value:J?.value,sinks:null,sinksTail:null,equals:J?.equals??k,guard:J?.guard,stop:void 0};return{[Symbol.toStringTag]:t,get(){if(N){if(!z.sinks)z.stop=$((X)=>{K(t,X,z.guard),U$(z,X)});F(z,N)}return j$(t,z.value),z.value}}}function o$($){return A($,t)}function n$($,J){let z=L($)||Array.isArray($),X=L(J)||Array.isArray(J);if(!z||!X){let j=!Object.is($,J);return{changed:j,add:j&&X?J:{},change:{},remove:j&&z?$:{}}}let W=new WeakSet,H={},P={},M={},C=!1,U=Object.keys($),Q=Object.keys(J);for(let j of Q)if(j in $){if(!n($[j],J[j],W))P[j]=J[j],C=!0}else H[j]=J[j],C=!0;for(let j of U)if(!(j in J))M[j]=void 0,C=!0;return{add:H,change:P,remove:M,changed:C}}function V$($,J){K(r,$,L);let z=new Map,X=(Q,j)=>{if(K(`${r} for key "${Q}"`,j),Array.isArray(j))z.set(Q,H$(j));else if(L(j))z.set(Q,V$(j));else z.set(Q,p(j))},W=()=>{let Q={};return z.forEach((j,G)=>{Q[G]=j.get()}),Q},H={fn:W,value:$,flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:n,error:void 0},P=(Q)=>{let j=!1;for(let G in Q.add)X(G,Q.add[G]),j=!0;if(Object.keys(Q.change).length)J$(()=>{for(let G in Q.change){let q=Q.change[G];K(`${r} for key "${G}"`,q);let Z=z.get(G);if(Z)if(L(q)!==x$(Z))X(G,q),j=!0;else Z.set(q)}});for(let G in Q.remove)z.delete(G),j=!0;if(j)H.flags|=b;return Q.changed},M=J?.watched,C=M?()=>{if(N){if(!H.sinks)H.stop=M();F(H,N)}}:()=>{if(N)F(H,N)};for(let Q of Object.keys($))X(Q,$[Q]);let U={[Symbol.toStringTag]:r,[Symbol.isConcatSpreadable]:!1,*[Symbol.iterator](){for(let Q of Array.from(z.keys())){let j=z.get(Q);if(j)yield[Q,j]}},keys(){return C(),z.keys()},byKey(Q){return z.get(Q)},get(){if(C(),H.sources){if(H.flags){let Q=H.flags&b;if(H.value=v(W),Q){if(H.flags=D,I(H),H.error)throw H.error}else H.flags=S}}else if(I(H),H.error)throw H.error;return H.value},set(Q){let j=H.flags&D?W():H.value,G=n$(j,Q);if(P(G)){H.flags|=D;for(let q=H.sinks;q;q=q.nextSink)x(q.sink);if(R===0)w()}},update(Q){U.set(Q(U.get()))},add(Q,j){if(z.has(Q))throw new e(r,Q,j);X(Q,j),H.flags|=D|b;for(let G=H.sinks;G;G=G.nextSink)x(G.sink);if(R===0)w();return Q},remove(Q){if(z.delete(Q)){H.flags|=D|b;for(let G=H.sinks;G;G=G.nextSink)x(G.sink);if(R===0)w()}}};return new Proxy(U,{get(Q,j){if(j in Q)return Reflect.get(Q,j);if(typeof j!=="symbol")return Q.byKey(j)},has(Q,j){if(j in Q)return!0;return Q.byKey(String(j))!==void 0},ownKeys(Q){return Array.from(Q.keys())},getOwnPropertyDescriptor(Q,j){if(j in Q)return Reflect.getOwnPropertyDescriptor(Q,j);if(typeof j==="symbol")return;let G=Q.byKey(String(j));return G?{enumerable:!0,configurable:!0,writable:!0,value:G}:void 0}})}function x$($){return A($,r)}function a$($,J){return i($)?B$($,J):Q$($,J)}function e$($){if(q$($))return $;if($==null)throw new Z$("createSignal",$);if(i($))return B$($);if(g($))return Q$($);if(A$($))return H$($);if(L($))return V$($);return p($)}function $J($){if(w$($))return $;if($==null||g($)||q$($))throw new Z$("createMutableSignal",$);if(A$($))return H$($);if(L($))return V$($);return p($)}function JJ($){return S$($)||h$($)}function q$($){let J=[c,u,d,t,s,E,l,r],z=Object.prototype.toString.call($).slice(8,-1);return J.includes(z)}function w$($){return N$($)||x$($)||F$($)}function zJ($,J){K(s,$,q$);let z=$,X=J?.guard,W={fn:()=>z.get(),value:void 0,flags:D,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:J?.equals??k,error:void 0},H=()=>{if(N)F(W,N);if(I(W),W.error)throw W.error;return W.value},P=(C)=>{if(!w$(z))throw new P$(s);K(s,C,X),z.set(C)},M=(C)=>{K(s,C,q$),z=C,W.flags|=D;for(let U=W.sinks;U;U=U.nextSink)x(U.sink);if(R===0)w()};return{[Symbol.toStringTag]:s,configurable:!0,enumerable:!0,get:H,set:P,replace:M,current:()=>z}}function XJ($){return A($,s)}export{m$ as valueString,v as untrack,s$ as match,h$ as isTask,x$ as isStore,N$ as isState,XJ as isSlot,q$ as isSignal,o$ as isSensor,L as isRecord,A as isObjectOfType,w$ as isMutableSignal,S$ as isMemo,F$ as isList,g as isFunction,n as isEqual,JJ as isComputed,l$ as isCollection,i as isAsyncFunction,B$ as createTask,V$ as createStore,p as createState,zJ as createSlot,e$ as createSignal,i$ as createSensor,u$ as createScope,$J as createMutableSignal,Q$ as createMemo,H$ as createList,r$ as createEffect,a$ as createComputed,t$ as createCollection,J$ as batch,o as UnsetSignalValueError,L$ as SKIP_EQUALITY,D$ as RequiredOwnerError,P$ as ReadonlySignalError,Y$ as NullishSignalValueError,Z$ as InvalidSignalValueError,b$ as InvalidCallbackError,X$ as CircularDependencyError};
1
+ function g($){return typeof $==="function"}function o($){return g($)&&$.constructor.name==="AsyncFunction"}function X$($){return g($)&&$.constructor.name!=="AsyncFunction"}function Y($,J){return Object.prototype.toString.call($)===`[object ${J}]`}function T($){return Y($,"Object")}function Y$($,J=(z)=>z!=null){return Array.isArray($)&&$.every(J)}function D$($){return typeof $==="string"?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($)}class Z$ extends Error{constructor($){super(`[${$}] Circular dependency detected`);this.name="CircularDependencyError"}}class A$ extends TypeError{constructor($){super(`[${$}] Signal value cannot be null or undefined`);this.name="NullishSignalValueError"}}class i extends Error{constructor($){super(`[${$}] Signal value is unset`);this.name="UnsetSignalValueError"}}class j$ extends TypeError{constructor($,J){super(`[${$}] Signal value ${D$(J)} is invalid`);this.name="InvalidSignalValueError"}}class b$ extends TypeError{constructor($,J){super(`[${$}] Callback ${D$(J)} is invalid`);this.name="InvalidCallbackError"}}class P$ extends Error{constructor($){super(`[${$}] Signal is read-only`);this.name="ReadonlySignalError"}}class G$ extends Error{constructor($){super(`[${$}] Active owner is required`);this.name="RequiredOwnerError"}}class e extends Error{constructor($,J,z){super(`[${$}] Could not add key "${J}"${z?` with value ${JSON.stringify(z)}`:""} because it already exists`);this.name="DuplicateKeyError"}}function O($,J,z){if(J==null)throw new A$($);if(z&&!z(J))throw new j$($,J)}function W$($,J){if(J==null)throw new i($)}function E($,J,z=g){if(!z(J))throw new b$($,J)}var c="State",u="Memo",d="Task",t="Sensor",S="List",s="Collection",l="Store",r="Slot",p=0,$$=1,G=2,U$=4,b=8,m=null,_=null,C$=[],x=0,_$=!1,k=($,J)=>$===J,L$=($,J)=>!1;function g$($,J){let z=J.sourcesTail;if(z){let X=J.sources;while(X){if(X===$)return!0;if(X===z)break;X=X.nextSource}}return!1}function R($,J){let z=J.sourcesTail;if(z?.source===$)return;let X=null,W=J.flags&U$;if(W){if(X=z?z.nextSource:J.sources,X?.source===$){J.sourcesTail=X;return}}let Q=$.sinksTail;if(Q?.sink===J&&(!W||g$(Q,J)))return;let D={source:$,sink:J,nextSource:X,prevSink:Q,nextSink:null};if(J.sourcesTail=$.sinksTail=D,z)z.nextSource=D;else J.sources=D;if(Q)Q.nextSink=D;else $.sinks=D}function k$($){let{source:J,nextSource:z,nextSink:X,prevSink:W}=$;if(X)X.prevSink=W;else J.sinksTail=W;if(W)W.nextSink=X;else J.sinks=X;if(!J.sinks){if(J.stop)J.stop(),J.stop=void 0;if("sources"in J&&J.sources){let Q=J;Q.sourcesTail=null,H$(Q)}}return z}function H$($){let J=$.sourcesTail,z=J?J.nextSource:$.sources;while(z)z=k$(z);if(J)J.nextSource=null;else $.sources=null}function F($,J=G){let z=$.flags;if("sinks"in $){if((z&(G|$$))>=J)return;if($.flags=z|J,"controller"in $&&$.controller)$.controller.abort(),$.controller=void 0;for(let X=$.sinks;X;X=X.nextSink)F(X.sink,$$)}else{if((z&(G|$$))>=J)return;let X=z&(G|$$);if($.flags=J,!X)C$.push($)}}function m$($,J){if($.equals($.value,J))return;$.value=J;for(let z=$.sinks;z;z=z.nextSink)F(z.sink);if(x===0)I()}function J$($,J){if(!$.cleanup)$.cleanup=J;else if(Array.isArray($.cleanup))$.cleanup.push(J);else $.cleanup=[$.cleanup,J]}function O$($){if(!$.cleanup)return;if(Array.isArray($.cleanup))for(let J=0;J<$.cleanup.length;J++)$.cleanup[J]();else $.cleanup();$.cleanup=null}function v$($){let J=m;m=$,$.sourcesTail=null,$.flags=U$;let z=!1;try{let X=$.fn($.value);if($.error||!$.equals(X,$.value))$.value=X,$.error=void 0,z=!0}catch(X){z=!0,$.error=X instanceof Error?X:Error(String(X))}finally{m=J,H$($)}if(z){for(let X=$.sinks;X;X=X.nextSink)if(X.sink.flags&$$)X.sink.flags|=G}$.flags=p}function c$($){$.controller?.abort();let J=new AbortController;$.controller=J,$.error=void 0;let z=m;m=$,$.sourcesTail=null,$.flags=U$;let X;try{X=$.fn($.value,J.signal)}catch(W){$.controller=void 0,$.error=W instanceof Error?W:Error(String(W));return}finally{m=z,H$($)}X.then((W)=>{if(J.signal.aborted)return;if($.controller=void 0,$.error||!$.equals(W,$.value)){$.value=W,$.error=void 0;for(let Q=$.sinks;Q;Q=Q.nextSink)F(Q.sink);if(x===0)I()}},(W)=>{if(J.signal.aborted)return;$.controller=void 0;let Q=W instanceof Error?W:Error(String(W));if(!$.error||Q.name!==$.error.name||Q.message!==$.error.message){$.error=Q;for(let D=$.sinks;D;D=D.nextSink)F(D.sink);if(x===0)I()}}),$.flags=p}function T$($){O$($);let J=m,z=_;m=_=$,$.sourcesTail=null,$.flags=U$;try{let X=$.fn();if(typeof X==="function")J$($,X)}finally{m=J,_=z,H$($)}$.flags=p}function f($){if($.flags&$$)for(let J=$.sources;J;J=J.nextSource){if("fn"in J.source)f(J.source);if($.flags&G)break}if($.flags&U$)throw new Z$("controller"in $?d:("value"in $)?u:"Effect");if($.flags&G)if("controller"in $)c$($);else if("value"in $)v$($);else T$($);else $.flags=p}function I(){if(_$)return;_$=!0;try{for(let $=0;$<C$.length;$++){let J=C$[$];if(J.flags&(G|$$))f(J)}C$.length=0}finally{_$=!1}}function z$($){x++;try{$()}finally{if(x--,x===0)I()}}function v($){let J=m;m=null;try{return $()}finally{m=J}}function u$($){let J=_,z={cleanup:null};_=z;try{let X=$();if(typeof X==="function")J$(z,X);let W=()=>O$(z);if(J)J$(J,W);return W}finally{_=J}}function d$($){let J=_;_=null;try{return $()}finally{_=J}}function y($,J){O(c,$,J?.guard);let z={value:$,sinks:null,sinksTail:null,equals:J?.equals??k,guard:J?.guard};return{[Symbol.toStringTag]:c,get(){if(m)R(z,m);return z.value},set(X){O(c,X,z.guard),m$(z,X)},update(X){E(c,X);let W=X(z.value);O(c,W,z.guard),m$(z,W)}}}function N$($){return Y($,c)}function n($,J,z){if(Object.is($,J))return!0;if(typeof $!==typeof J)return!1;if($==null||typeof $!=="object"||J==null||typeof J!=="object")return!1;if(!z)z=new WeakSet;if(z.has($)||z.has(J))throw new Z$("isEqual");z.add($),z.add(J);try{let X=Array.isArray($);if(X!==Array.isArray(J))return!1;if(X){let W=$,Q=J;if(W.length!==Q.length)return!1;for(let D=0;D<W.length;D++)if(!n(W[D],Q[D],z))return!1;return!0}if(T($)&&T(J)){let W=Object.keys($),Q=Object.keys(J);if(W.length!==Q.length)return!1;for(let D of W){if(!(D in J))return!1;if(!n($[D],J[D],z))return!1}return!0}return!1}finally{z.delete($),z.delete(J)}}function K$($,J){if($.length!==J.length)return!1;for(let z=0;z<$.length;z++)if($[z]!==J[z])return!1;return!0}function E$($){let J=0,z=typeof $==="function";return[typeof $==="string"?()=>`${$}${J++}`:z?(X)=>$(X)||String(J++):()=>String(J++),z]}function t$($,J,z,X,W){let Q=new WeakSet,D={},M={},C={},U=[],H=!1,j=new Map;for(let q=0;q<$.length;q++){let Z=z[q];if(Z&&$[q])j.set(Z,$[q])}let P=new Set;for(let q=0;q<J.length;q++){let Z=J[q];if(Z===void 0)continue;let B=W?X(Z):z[q]??X(Z);if(P.has(B))throw new e(S,B,Z);if(U.push(B),P.add(B),!j.has(B))D[B]=Z,H=!0;else if(!n(j.get(B),Z,Q))M[B]=Z,H=!0}for(let[q]of j)if(!P.has(q))C[q]=null,H=!0;if(!H&&!K$(z,U))H=!0;return{add:D,change:M,remove:C,newKeys:U,changed:H}}function Q$($,J){O(S,$,Array.isArray);let z=new Map,X=[],[W,Q]=E$(J?.keyConfig),D=()=>X.map((Z)=>z.get(Z)?.get()).filter((Z)=>Z!==void 0),M={fn:D,value:$,flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:n,error:void 0},C=(Z)=>{let B={};for(let N=0;N<Z.length;N++){let V=Z[N];if(V===void 0)continue;let K=X[N];if(!K)K=W(V),X[N]=K;B[K]=V}return B},U=(Z)=>{let B=!1;for(let N in Z.add){let V=Z.add[N];O(`${S} item for key "${N}"`,V),z.set(N,y(V)),B=!0}if(Object.keys(Z.change).length)z$(()=>{for(let N in Z.change){let V=Z.change[N];O(`${S} item for key "${N}"`,V);let K=z.get(N);if(K)K.set(V)}});for(let N in Z.remove){z.delete(N);let V=X.indexOf(N);if(V!==-1)X.splice(V,1);B=!0}if(B)M.flags|=b;return Z.changed},H=J?.watched,j=H?()=>{if(m){if(!M.sinks)M.stop=H();R(M,m)}}:()=>{if(m)R(M,m)},P=C($);for(let Z in P){let B=P[Z];O(`${S} item for key "${Z}"`,B),z.set(Z,y(B))}M.value=$,M.flags=0;let q={[Symbol.toStringTag]:S,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let Z of X){let B=z.get(Z);if(B)yield B}},get length(){return j(),X.length},get(){if(j(),M.sources){if(M.flags){let Z=M.flags&b;if(M.value=v(D),Z){if(M.flags=G,f(M),M.error)throw M.error}else M.flags=p}}else if(f(M),M.error)throw M.error;return M.value},set(Z){let B=M.flags&G?D():M.value,N=t$(B,Z,X,W,Q);if(N.changed){X=N.newKeys,U(N),M.flags|=G;for(let V=M.sinks;V;V=V.nextSink)F(V.sink);if(x===0)I()}},update(Z){q.set(Z(q.get()))},at(Z){return z.get(X[Z])},keys(){return j(),X.values()},byKey(Z){return z.get(Z)},keyAt(Z){return X[Z]},indexOfKey(Z){return X.indexOf(Z)},add(Z){let B=W(Z);if(z.has(B))throw new e(S,B,Z);if(!X.includes(B))X.push(B);O(`${S} item for key "${B}"`,Z),z.set(B,y(Z)),M.flags|=G|b;for(let N=M.sinks;N;N=N.nextSink)F(N.sink);if(x===0)I();return B},remove(Z){let B=typeof Z==="number"?X[Z]:Z;if(z.delete(B)){let V=typeof Z==="number"?Z:X.indexOf(B);if(V>=0)X.splice(V,1);M.flags|=G|b;for(let K=M.sinks;K;K=K.nextSink)F(K.sink);if(x===0)I()}},sort(Z){let N=X.map((V)=>[V,z.get(V)?.get()]).sort(g(Z)?(V,K)=>Z(V[1],K[1]):(V,K)=>String(V[1]).localeCompare(String(K[1]))).map(([V])=>V);if(!K$(X,N)){X=N,M.flags|=G;for(let V=M.sinks;V;V=V.nextSink)F(V.sink);if(x===0)I()}},splice(Z,B,...N){let V=X.length,K=Z<0?Math.max(0,V+Z):Math.min(Z,V),w=Math.max(0,Math.min(B??Math.max(0,V-Math.max(0,K)),V-K)),A={},L={};for(let h=0;h<w;h++){let a=K+h,w$=X[a];if(w$){let y$=z.get(w$);if(y$)L[w$]=y$.get()}}let f$=X.slice(0,K);for(let h of N){let a=W(h);if(z.has(a)&&!(a in L))throw new e(S,a,h);f$.push(a),A[a]=h}f$.push(...X.slice(K+w));let h$=!!(Object.keys(A).length||Object.keys(L).length);if(h$){U({add:A,change:{},remove:L,changed:h$}),X=f$,M.flags|=G;for(let h=M.sinks;h;h=h.nextSink)F(h.sink);if(x===0)I()}return Object.values(L)},deriveCollection(Z){return x$(q,Z)}};return q}function R$($){return Y($,S)}function B$($,J){if(E(u,$,X$),J?.value!==void 0)O(u,J.value,J?.guard);let z={fn:$,value:J?.value,flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:J?.equals??k,error:void 0,stop:void 0},X=J?.watched,W=X?()=>{if(m){if(!z.sinks)z.stop=X(()=>{if(F(z),x===0)I()});R(z,m)}}:()=>{if(m)R(z,m)};return{[Symbol.toStringTag]:u,get(){if(W(),f(z),z.error)throw z.error;return W$(u,z.value),z.value}}}function S$($){return Y($,u)}function q$($,J){if(E(d,$,o),J?.value!==void 0)O(d,J.value,J?.guard);let z={fn:$,value:J?.value,sources:null,sourcesTail:null,sinks:null,sinksTail:null,flags:G,equals:J?.equals??k,controller:void 0,error:void 0,stop:void 0},X=J?.watched,W=X?()=>{if(m){if(!z.sinks)z.stop=X(()=>{if(F(z),x===0)I()});R(z,m)}}:()=>{if(m)R(z,m)};return{[Symbol.toStringTag]:d,get(){if(W(),f(z),z.error)throw z.error;return W$(d,z.value),z.value},isPending(){return!!z.controller},abort(){z.controller?.abort(),z.controller=void 0}}}function p$($){return Y($,d)}function x$($,J){E(s,J);let z=o(J),X=new Map,W=[],Q=(q)=>{let Z=z?q$(async(B,N)=>{let V=$.byKey(q)?.get();if(V==null)return B;return J(V,N)}):B$(()=>{let B=$.byKey(q)?.get();if(B==null)return;return J(B)});X.set(q,Z)};function D(q){if(!K$(W,q)){let Z=new Set(W),B=new Set(q);for(let N of W)if(!B.has(N))X.delete(N);for(let N of q)if(!Z.has(N))Q(N);W=q,U.flags|=b}}function M(){D(Array.from($.keys()));let q=[];for(let Z of W)try{let B=X.get(Z)?.get();if(B!=null)q.push(B)}catch(B){if(!(B instanceof i))throw B}return q}let U={fn:M,value:[],flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:(q,Z)=>{if(q.length!==Z.length)return!1;for(let B=0;B<q.length;B++)if(q[B]!==Z[B])return!1;return!0},error:void 0};function H(){if(U.sources){if(U.flags)if(U.value=v(M),U.flags&b){if(U.flags=G,f(U),U.error)throw U.error}else U.flags=p}else if(U.sinks){if(f(U),U.error)throw U.error}else U.value=v(M)}let j=Array.from(v(()=>$.keys()));for(let q of j)Q(q);W=j;let P={[Symbol.toStringTag]:s,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let q of W){let Z=X.get(q);if(Z)yield Z}},get length(){if(m)R(U,m);return H(),W.length},keys(){if(m)R(U,m);return H(),W.values()},get(){if(m)R(U,m);return H(),U.value},at(q){return X.get(W[q])},byKey(q){return X.get(q)},keyAt(q){return W[q]},indexOfKey(q){return W.indexOf(q)},deriveCollection(q){return x$(P,q)}};return P}function s$($,J){let z=J?.value??[];if(z.length)O(s,z,Array.isArray);E(s,$,X$);let X=new Map,W=[],Q=new Map,[D,M]=E$(J?.keyConfig),C=(Z)=>Q.get(Z)??(M?D(Z):void 0),U=J?.createItem??y;function H(){let Z=[];for(let B of W)try{let N=X.get(B)?.get();if(N!=null)Z.push(N)}catch(N){if(!(N instanceof i))throw N}return Z}let j={fn:H,value:z,flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:L$,error:void 0};for(let Z of z){let B=D(Z);X.set(B,U(Z)),Q.set(Z,B),W.push(B)}j.value=z,j.flags=G;function P(){if(m){if(!j.sinks)j.stop=$((Z)=>{let{add:B,change:N,remove:V}=Z;if(!B?.length&&!N?.length&&!V?.length)return;let K=!1;z$(()=>{if(B)for(let w of B){let A=D(w);if(X.set(A,U(w)),Q.set(w,A),!W.includes(A))W.push(A);K=!0}if(N)for(let w of N){let A=C(w);if(!A)continue;let L=X.get(A);if(L&&N$(L))Q.delete(L.get()),L.set(w),Q.set(w,A)}if(V)for(let w of V){let A=C(w);if(!A)continue;Q.delete(w),X.delete(A);let L=W.indexOf(A);if(L!==-1)W.splice(L,1);K=!0}j.flags=G|(K?b:0);for(let w=j.sinks;w;w=w.nextSink)F(w.sink)})});R(j,m)}}let q={[Symbol.toStringTag]:s,[Symbol.isConcatSpreadable]:!0,*[Symbol.iterator](){for(let Z of W){let B=X.get(Z);if(B)yield B}},get length(){return P(),W.length},keys(){return P(),W.values()},get(){if(P(),j.sources){if(j.flags){let Z=j.flags&b;if(j.value=v(H),Z){if(j.flags=G,f(j),j.error)throw j.error}else j.flags=p}}else if(f(j),j.error)throw j.error;return j.value},at(Z){return X.get(W[Z])},byKey(Z){return X.get(Z)},keyAt(Z){return W[Z]},indexOfKey(Z){return W.indexOf(Z)},deriveCollection(Z){return x$(q,Z)}};return q}function l$($){return Y($,s)}function r$($){E("Effect",$);let J={fn:$,flags:G,sources:null,sourcesTail:null,cleanup:null},z=()=>{O$(J),J.fn=void 0,J.flags=p,J.sourcesTail=null,H$(J)};if(_)J$(_,z);return T$(J),z}function o$($,J){if(!_)throw new G$("match");let{ok:z,err:X=console.error,nil:W}=J,Q,D=!1,M=Array($.length);for(let U=0;U<$.length;U++)try{M[U]=$[U].get()}catch(H){if(H instanceof i){D=!0;continue}if(!Q)Q=[];Q.push(H instanceof Error?H:Error(String(H)))}let C;try{if(D)C=W?.();else if(Q)C=X(Q);else C=z(M)}catch(U){X([U instanceof Error?U:Error(String(U))])}if(typeof C==="function")return C;if(C instanceof Promise){let U=_,H=new AbortController;J$(U,()=>H.abort()),C.then((j)=>{if(!H.signal.aborted&&typeof j==="function")J$(U,j)}).catch((j)=>{X([j instanceof Error?j:Error(String(j))])})}}function i$($,J){if(E(t,$,X$),J?.value!==void 0)O(t,J.value,J?.guard);let z={value:J?.value,sinks:null,sinksTail:null,equals:J?.equals??k,guard:J?.guard,stop:void 0};return{[Symbol.toStringTag]:t,get(){if(m){if(!z.sinks)z.stop=$((X)=>{O(t,X,z.guard),m$(z,X)});R(z,m)}return W$(t,z.value),z.value}}}function n$($){return Y($,t)}function a$($,J){let z=T($)||Array.isArray($),X=T(J)||Array.isArray(J);if(!z||!X){let j=!Object.is($,J);return{changed:j,add:j&&X?J:{},change:{},remove:j&&z?$:{}}}let W=new WeakSet,Q={},D={},M={},C=!1,U=Object.keys($),H=Object.keys(J);for(let j of H)if(j in $){if(!n($[j],J[j],W))D[j]=J[j],C=!0}else Q[j]=J[j],C=!0;for(let j of U)if(!(j in J))M[j]=void 0,C=!0;return{add:Q,change:D,remove:M,changed:C}}function V$($,J){O(l,$,T);let z=new Map,X=(H,j)=>{if(O(`${l} for key "${H}"`,j),Array.isArray(j))z.set(H,Q$(j));else if(T(j))z.set(H,V$(j));else z.set(H,y(j))},W=()=>{let H={};return z.forEach((j,P)=>{H[P]=j.get()}),H},Q={fn:W,value:$,flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:n,error:void 0},D=(H)=>{let j=!1;for(let P in H.add)X(P,H.add[P]),j=!0;if(Object.keys(H.change).length)z$(()=>{for(let P in H.change){let q=H.change[P];O(`${l} for key "${P}"`,q);let Z=z.get(P);if(Z)if(T(q)!==F$(Z))X(P,q),j=!0;else Z.set(q)}});for(let P in H.remove)z.delete(P),j=!0;if(j)Q.flags|=b;return H.changed},M=J?.watched,C=M?()=>{if(m){if(!Q.sinks)Q.stop=M();R(Q,m)}}:()=>{if(m)R(Q,m)};for(let H of Object.keys($))X(H,$[H]);let U={[Symbol.toStringTag]:l,[Symbol.isConcatSpreadable]:!1,*[Symbol.iterator](){for(let H of Array.from(z.keys())){let j=z.get(H);if(j)yield[H,j]}},keys(){return C(),z.keys()},byKey(H){return z.get(H)},get(){if(C(),Q.sources){if(Q.flags){let H=Q.flags&b;if(Q.value=v(W),H){if(Q.flags=G,f(Q),Q.error)throw Q.error}else Q.flags=p}}else if(f(Q),Q.error)throw Q.error;return Q.value},set(H){let j=Q.flags&G?W():Q.value,P=a$(j,H);if(D(P)){Q.flags|=G;for(let q=Q.sinks;q;q=q.nextSink)F(q.sink);if(x===0)I()}},update(H){U.set(H(U.get()))},add(H,j){if(z.has(H))throw new e(l,H,j);X(H,j),Q.flags|=G|b;for(let P=Q.sinks;P;P=P.nextSink)F(P.sink);if(x===0)I();return H},remove(H){if(z.delete(H)){Q.flags|=G|b;for(let P=Q.sinks;P;P=P.nextSink)F(P.sink);if(x===0)I()}}};return new Proxy(U,{get(H,j){if(j in H)return Reflect.get(H,j);if(typeof j!=="symbol")return H.byKey(j)},has(H,j){if(j in H)return!0;return H.byKey(String(j))!==void 0},ownKeys(H){return Array.from(H.keys())},getOwnPropertyDescriptor(H,j){if(j in H)return Reflect.getOwnPropertyDescriptor(H,j);if(typeof j==="symbol")return;let P=H.byKey(String(j));return P?{enumerable:!0,configurable:!0,writable:!0,value:P}:void 0}})}function F$($){return Y($,l)}function e$($,J){return o($)?q$($,J):B$($,J)}function $J($){if(M$($))return $;if($==null)throw new j$("createSignal",$);if(o($))return q$($);if(g($))return B$($);if(Y$($))return Q$($);if(T($))return V$($);return y($)}function JJ($){if(I$($))return $;if($==null||g($)||M$($))throw new j$("createMutableSignal",$);if(Y$($))return Q$($);if(T($))return V$($);return y($)}function zJ($){return S$($)||p$($)}function M$($){let J=[c,u,d,t,r,S,s,l],z=Object.prototype.toString.call($).slice(8,-1);return J.includes(z)}function I$($){return N$($)||F$($)||R$($)}function XJ($,J){O(r,$,M$);let z=$,X=J?.guard,W={fn:()=>z.get(),value:void 0,flags:G,sources:null,sourcesTail:null,sinks:null,sinksTail:null,equals:J?.equals??k,error:void 0},Q=()=>{if(m)R(W,m);if(f(W),W.error)throw W.error;return W.value},D=(C)=>{if(!I$(z))throw new P$(r);O(r,C,X),z.set(C)},M=(C)=>{O(r,C,M$),z=C,W.flags|=G;for(let U=W.sinks;U;U=U.nextSink)F(U.sink);if(x===0)I()};return{[Symbol.toStringTag]:r,configurable:!0,enumerable:!0,get:Q,set:D,replace:M,current:()=>z}}function ZJ($){return Y($,r)}export{D$ as valueString,v as untrack,d$ as unown,o$ as match,p$ as isTask,F$ as isStore,N$ as isState,ZJ as isSlot,M$ as isSignal,n$ as isSensor,T as isRecord,Y as isObjectOfType,I$ as isMutableSignal,S$ as isMemo,R$ as isList,g as isFunction,n as isEqual,zJ as isComputed,l$ as isCollection,o as isAsyncFunction,q$ as createTask,V$ as createStore,y as createState,XJ as createSlot,$J as createSignal,i$ as createSensor,u$ as createScope,JJ as createMutableSignal,B$ as createMemo,Q$ as createList,r$ as createEffect,e$ as createComputed,s$ as createCollection,z$ as batch,i as UnsetSignalValueError,L$ as SKIP_EQUALITY,G$ as RequiredOwnerError,P$ as ReadonlySignalError,A$ as NullishSignalValueError,j$ as InvalidSignalValueError,b$ as InvalidCallbackError,Z$ as CircularDependencyError};
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @name Cause & Effect
3
- * @version 0.18.3
3
+ * @version 0.18.5
4
4
  * @author Esther Brunner
5
5
  */
6
6
 
@@ -26,6 +26,7 @@ export {
26
26
  type SignalOptions,
27
27
  SKIP_EQUALITY,
28
28
  type TaskCallback,
29
+ unown,
29
30
  untrack,
30
31
  } from './src/graph'
31
32
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeix/cause-effect",
3
- "version": "0.18.3",
3
+ "version": "0.18.5",
4
4
  "author": "Esther Brunner",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/graph.ts CHANGED
@@ -292,11 +292,12 @@ function propagate(node: SinkNode, newFlag = FLAG_DIRTY): void {
292
292
  for (let e = node.sinks; e; e = e.nextSink)
293
293
  propagate(e.sink, FLAG_CHECK)
294
294
  } else {
295
- if (flags & FLAG_DIRTY) return
295
+ if ((flags & (FLAG_DIRTY | FLAG_CHECK)) >= newFlag) return
296
296
 
297
297
  // Enqueue effect for later execution
298
- node.flags = FLAG_DIRTY
299
- queuedEffects.push(node as EffectNode)
298
+ const wasQueued = flags & (FLAG_DIRTY | FLAG_CHECK)
299
+ node.flags = newFlag
300
+ if (!wasQueued) queuedEffects.push(node as EffectNode)
300
301
  }
301
302
  }
302
303
 
@@ -471,7 +472,7 @@ function flush(): void {
471
472
  try {
472
473
  for (let i = 0; i < queuedEffects.length; i++) {
473
474
  const effect = queuedEffects[i]
474
- if (effect.flags & FLAG_DIRTY) refresh(effect)
475
+ if (effect.flags & (FLAG_DIRTY | FLAG_CHECK)) refresh(effect)
475
476
  }
476
477
  queuedEffects.length = 0
477
478
  } finally {
@@ -579,6 +580,25 @@ function createScope(fn: () => MaybeCleanup): Cleanup {
579
580
  }
580
581
  }
581
582
 
583
+ /**
584
+ * Runs a callback without any active owner.
585
+ * Any scopes or effects created inside the callback will not be registered as
586
+ * children of the current active owner (e.g. a re-runnable effect). Use this
587
+ * when a component or resource manages its own lifecycle independently of the
588
+ * reactive graph.
589
+ *
590
+ * @since 0.18.5
591
+ */
592
+ function unown<T>(fn: () => T): T {
593
+ const prev = activeOwner
594
+ activeOwner = null
595
+ try {
596
+ return fn()
597
+ } finally {
598
+ activeOwner = prev
599
+ }
600
+ }
601
+
582
602
  export {
583
603
  type Cleanup,
584
604
  type ComputedOptions,
@@ -601,6 +621,7 @@ export {
601
621
  createScope,
602
622
  DEFAULT_EQUALITY,
603
623
  SKIP_EQUALITY,
624
+ FLAG_CHECK,
604
625
  FLAG_CLEAN,
605
626
  FLAG_DIRTY,
606
627
  FLAG_RELINK,
@@ -622,5 +643,6 @@ export {
622
643
  TYPE_STORE,
623
644
  TYPE_TASK,
624
645
  unlink,
646
+ unown,
625
647
  untrack,
626
648
  }
package/src/nodes/memo.ts CHANGED
@@ -110,9 +110,7 @@ function createMemo<T extends {}>(
110
110
  if (activeSink) {
111
111
  if (!node.sinks)
112
112
  node.stop = watched(() => {
113
- node.flags |= FLAG_DIRTY
114
- for (let e = node.sinks; e; e = e.nextSink)
115
- propagate(e.sink)
113
+ propagate(node as unknown as SinkNode)
116
114
  if (batchDepth === 0) flush()
117
115
  })
118
116
  link(node, activeSink)
package/src/nodes/task.ts CHANGED
@@ -129,9 +129,7 @@ function createTask<T extends {}>(
129
129
  if (activeSink) {
130
130
  if (!node.sinks)
131
131
  node.stop = watched(() => {
132
- node.flags |= FLAG_DIRTY
133
- for (let e = node.sinks; e; e = e.nextSink)
134
- propagate(e.sink)
132
+ propagate(node as unknown as SinkNode)
135
133
  if (batchDepth === 0) flush()
136
134
  })
137
135
  link(node, activeSink)
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, mock, test } from 'bun:test'
2
2
  import {
3
+ batch,
3
4
  createEffect,
4
5
  createMemo,
5
6
  createScope,
@@ -140,6 +141,209 @@ describe('createEffect', () => {
140
141
  })
141
142
  })
142
143
 
144
+ describe('Watched memo equality', () => {
145
+ test('should skip effect re-run when watched memo recomputes to same value', () => {
146
+ let invalidate!: () => void
147
+ let effectCount = 0
148
+
149
+ // Memo whose computed value does not change on invalidation
150
+ const memo = createMemo(() => 42, {
151
+ value: 42,
152
+ watched: inv => {
153
+ invalidate = inv
154
+ return () => {}
155
+ },
156
+ })
157
+
158
+ const dispose = createScope(() => {
159
+ createEffect(() => {
160
+ void memo.get()
161
+ effectCount++
162
+ })
163
+ })
164
+
165
+ expect(effectCount).toBe(1)
166
+
167
+ // Invalidate — memo recomputes but returns same value (42)
168
+ invalidate()
169
+
170
+ // Because equals(42, 42) is true, the effect should NOT re-run
171
+ expect(effectCount).toBe(1)
172
+
173
+ dispose()
174
+ })
175
+
176
+ test('should re-run effect when watched memo recomputes to different value', () => {
177
+ let invalidate!: () => void
178
+ let effectCount = 0
179
+ let externalValue = 1
180
+
181
+ const memo = createMemo(() => externalValue, {
182
+ value: 0,
183
+ watched: inv => {
184
+ invalidate = inv
185
+ return () => {}
186
+ },
187
+ })
188
+
189
+ let observed = 0
190
+ const dispose = createScope(() => {
191
+ createEffect(() => {
192
+ observed = memo.get()
193
+ effectCount++
194
+ })
195
+ })
196
+
197
+ expect(effectCount).toBe(1)
198
+ expect(observed).toBe(1)
199
+
200
+ // Change external value and invalidate — memo returns a new value
201
+ externalValue = 99
202
+ invalidate()
203
+
204
+ expect(effectCount).toBe(2)
205
+ expect(observed).toBe(99)
206
+
207
+ dispose()
208
+ })
209
+
210
+ test('should respect custom equals to skip effect re-run', () => {
211
+ let invalidate!: () => void
212
+ let effectCount = 0
213
+ let externalValue = 3
214
+
215
+ // Custom equals: treat values as equal when they round to the same integer
216
+ const memo = createMemo(() => externalValue, {
217
+ value: 0,
218
+ equals: (a, b) => Math.floor(a) === Math.floor(b),
219
+ watched: inv => {
220
+ invalidate = inv
221
+ return () => {}
222
+ },
223
+ })
224
+
225
+ const dispose = createScope(() => {
226
+ createEffect(() => {
227
+ void memo.get()
228
+ effectCount++
229
+ })
230
+ })
231
+
232
+ expect(effectCount).toBe(1)
233
+
234
+ // External value changes slightly but rounds to same integer
235
+ externalValue = 3.7
236
+ invalidate()
237
+ expect(effectCount).toBe(1) // equals says same → effect skipped
238
+
239
+ // External value changes to a different integer
240
+ externalValue = 4.1
241
+ invalidate()
242
+ expect(effectCount).toBe(2) // equals says different → effect runs
243
+
244
+ dispose()
245
+ })
246
+
247
+ test('should skip effect re-run through memo chain when watched memo value unchanged', () => {
248
+ let invalidate!: () => void
249
+ let effectCount = 0
250
+
251
+ const watchedMemo = createMemo(() => 42, {
252
+ value: 42,
253
+ watched: inv => {
254
+ invalidate = inv
255
+ return () => {}
256
+ },
257
+ })
258
+
259
+ // Downstream memo that doubles the watched memo value
260
+ const doubled = createMemo(() => watchedMemo.get() * 2)
261
+
262
+ const dispose = createScope(() => {
263
+ createEffect(() => {
264
+ void doubled.get()
265
+ effectCount++
266
+ })
267
+ })
268
+
269
+ expect(effectCount).toBe(1)
270
+
271
+ // Invalidate — watchedMemo recomputes to same value, so doubled
272
+ // should also remain unchanged, and the effect should not re-run
273
+ invalidate()
274
+ expect(effectCount).toBe(1)
275
+
276
+ dispose()
277
+ })
278
+
279
+ test('should skip effect when invalidate is called inside batch and value unchanged', () => {
280
+ let invalidate!: () => void
281
+ let effectCount = 0
282
+
283
+ const memo = createMemo(() => 42, {
284
+ value: 42,
285
+ watched: inv => {
286
+ invalidate = inv
287
+ return () => {}
288
+ },
289
+ })
290
+
291
+ const dispose = createScope(() => {
292
+ createEffect(() => {
293
+ void memo.get()
294
+ effectCount++
295
+ })
296
+ })
297
+
298
+ expect(effectCount).toBe(1)
299
+
300
+ batch(() => {
301
+ invalidate()
302
+ })
303
+
304
+ // Value didn't change so effect should still be at 1
305
+ expect(effectCount).toBe(1)
306
+
307
+ dispose()
308
+ })
309
+
310
+ test('should still run effect for dirty state even when watched memo unchanged', () => {
311
+ let invalidate!: () => void
312
+ let effectCount = 0
313
+ const state = createState(1)
314
+
315
+ const memo = createMemo(() => 42, {
316
+ value: 42,
317
+ watched: inv => {
318
+ invalidate = inv
319
+ return () => {}
320
+ },
321
+ })
322
+
323
+ let observedState = 0
324
+ const dispose = createScope(() => {
325
+ createEffect(() => {
326
+ observedState = state.get()
327
+ void memo.get()
328
+ effectCount++
329
+ })
330
+ })
331
+
332
+ expect(effectCount).toBe(1)
333
+
334
+ // Change the state AND invalidate — effect must run because state changed
335
+ batch(() => {
336
+ state.set(2)
337
+ invalidate()
338
+ })
339
+
340
+ expect(effectCount).toBe(2)
341
+ expect(observedState).toBe(2)
342
+
343
+ dispose()
344
+ })
345
+ })
346
+
143
347
  describe('Input Validation', () => {
144
348
  test('should throw InvalidCallbackError for non-function', () => {
145
349
  // @ts-expect-error - Testing invalid input
@@ -0,0 +1,179 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import {
3
+ createEffect,
4
+ createScope,
5
+ createState,
6
+ unown,
7
+ } from '../index.ts'
8
+
9
+ describe('unown', () => {
10
+
11
+ test('should return the value of the callback', () => {
12
+ const result = unown(() => 42)
13
+ expect(result).toBe(42)
14
+ })
15
+
16
+ test('should run the callback immediately and synchronously', () => {
17
+ let ran = false
18
+ unown(() => { ran = true })
19
+ expect(ran).toBe(true)
20
+ })
21
+
22
+ test('scope created inside unown is not registered on the enclosing scope', () => {
23
+ let innerCleanupRan = false
24
+ const outerDispose = createScope(() => {
25
+ unown(() => {
26
+ createScope(() => {
27
+ return () => { innerCleanupRan = true }
28
+ })
29
+ })
30
+ })
31
+ outerDispose()
32
+ expect(innerCleanupRan).toBe(false)
33
+ })
34
+
35
+ test('scope created inside unown is not registered on the enclosing effect', () => {
36
+ const trigger = createState(0)
37
+ let innerCleanupRuns = 0
38
+
39
+ const outerDispose = createScope(() => {
40
+ createEffect((): undefined => {
41
+ trigger.get()
42
+ unown(() => {
43
+ createScope(() => {
44
+ return () => { innerCleanupRuns++ }
45
+ })
46
+ })
47
+ })
48
+ })
49
+
50
+ expect(innerCleanupRuns).toBe(0)
51
+ trigger.set(1)
52
+ expect(innerCleanupRuns).toBe(0)
53
+ trigger.set(2)
54
+ expect(innerCleanupRuns).toBe(0)
55
+
56
+ outerDispose()
57
+ })
58
+
59
+ test('effects inside an unowned scope survive effect re-runs (ownership bug regression)', () => {
60
+ const listChange = createState(0)
61
+ let componentEffectRuns = 0
62
+ let componentCleanupRuns = 0
63
+
64
+ const connectComponent = () => unown(() =>
65
+ createScope(() => {
66
+ createEffect((): undefined => {
67
+ componentEffectRuns++
68
+ })
69
+ return () => { componentCleanupRuns++ }
70
+ })
71
+ )
72
+
73
+ const outerDispose = createScope(() => {
74
+ createEffect((): undefined => {
75
+ listChange.get()
76
+ if (listChange.get() === 0) connectComponent()
77
+ })
78
+ })
79
+
80
+ expect(componentEffectRuns).toBe(1)
81
+ expect(componentCleanupRuns).toBe(0)
82
+
83
+ listChange.set(1)
84
+ expect(componentEffectRuns).toBe(1)
85
+ expect(componentCleanupRuns).toBe(0)
86
+
87
+ outerDispose()
88
+ })
89
+
90
+ test('effects inside an unowned scope still run reactively', () => {
91
+ const source = createState('a')
92
+ let effectRuns = 0
93
+
94
+ const dispose = unown(() =>
95
+ createScope(() => {
96
+ createEffect((): undefined => {
97
+ source.get()
98
+ effectRuns++
99
+ })
100
+ })
101
+ )
102
+
103
+ expect(effectRuns).toBe(1)
104
+ source.set('b')
105
+ expect(effectRuns).toBe(2)
106
+
107
+ dispose()
108
+ source.set('c')
109
+ expect(effectRuns).toBe(2)
110
+ })
111
+
112
+ test('dispose returned from an unowned scope still works', () => {
113
+ let cleanupRan = false
114
+ const dispose = unown(() =>
115
+ createScope(() => {
116
+ return () => { cleanupRan = true }
117
+ })
118
+ )
119
+ expect(cleanupRan).toBe(false)
120
+ dispose()
121
+ expect(cleanupRan).toBe(true)
122
+ })
123
+
124
+ test('nested unown calls work correctly', () => {
125
+ let innerCleanupRan = false
126
+ const outerDispose = createScope(() => {
127
+ unown(() => {
128
+ unown(() => {
129
+ createScope(() => {
130
+ return () => { innerCleanupRan = true }
131
+ })
132
+ })
133
+ })
134
+ })
135
+ outerDispose()
136
+ expect(innerCleanupRan).toBe(false)
137
+ })
138
+
139
+ test('restores the active owner after the callback completes', () => {
140
+ let postCleanupRan = false
141
+ const outerDispose = createScope(() => {
142
+ unown(() => { /* some unowned work */ })
143
+ createScope(() => {
144
+ return () => { postCleanupRan = true }
145
+ })
146
+ })
147
+ outerDispose()
148
+ expect(postCleanupRan).toBe(true)
149
+ })
150
+
151
+ test('restores the active owner even if the callback throws', () => {
152
+ let postCleanupRan = false
153
+ const outerDispose = createScope(() => {
154
+ try {
155
+ unown(() => { throw new Error('boom') })
156
+ } catch {
157
+ // swallow
158
+ }
159
+ createScope(() => {
160
+ return () => { postCleanupRan = true }
161
+ })
162
+ })
163
+ outerDispose()
164
+ expect(postCleanupRan).toBe(true)
165
+ })
166
+
167
+ test('works correctly when called outside any scope or effect', () => {
168
+ let ran = false
169
+ const dispose = unown(() => {
170
+ ran = true
171
+ return createScope(() => {
172
+ return () => {}
173
+ })
174
+ })
175
+ expect(ran).toBe(true)
176
+ expect(typeof dispose).toBe('function')
177
+ })
178
+
179
+ })