@zeix/cause-effect 0.17.1 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ai-context.md +7 -0
- package/.github/copilot-instructions.md +4 -0
- package/CLAUDE.md +96 -1
- package/README.md +44 -7
- package/archive/collection.ts +23 -25
- package/archive/computed.ts +3 -2
- package/archive/list.ts +21 -28
- package/archive/memo.ts +2 -1
- package/archive/state.ts +2 -1
- package/archive/store.ts +21 -32
- package/archive/task.ts +4 -7
- package/index.dev.js +356 -198
- package/index.js +1 -1
- package/index.ts +15 -6
- package/package.json +1 -1
- package/src/classes/collection.ts +69 -53
- package/src/classes/composite.ts +28 -33
- package/src/classes/computed.ts +87 -28
- package/src/classes/list.ts +31 -26
- package/src/classes/ref.ts +33 -5
- package/src/classes/state.ts +41 -8
- package/src/classes/store.ts +47 -30
- package/src/diff.ts +2 -1
- package/src/effect.ts +19 -9
- package/src/errors.ts +10 -1
- package/src/resolve.ts +1 -1
- package/src/signal.ts +0 -1
- package/src/system.ts +159 -43
- package/src/util.ts +0 -6
- package/test/collection.test.ts +279 -20
- package/test/computed.test.ts +268 -11
- package/test/effect.test.ts +2 -2
- package/test/list.test.ts +249 -21
- package/test/ref.test.ts +154 -0
- package/test/state.test.ts +13 -13
- package/test/store.test.ts +473 -28
- package/types/index.d.ts +3 -3
- package/types/src/classes/collection.d.ts +8 -7
- package/types/src/classes/composite.d.ts +4 -4
- package/types/src/classes/computed.d.ts +17 -0
- package/types/src/classes/list.d.ts +2 -2
- package/types/src/classes/ref.d.ts +10 -1
- package/types/src/classes/state.d.ts +9 -0
- package/types/src/classes/store.d.ts +4 -4
- package/types/src/effect.d.ts +1 -2
- package/types/src/errors.d.ts +4 -1
- package/types/src/system.d.ts +40 -24
- package/types/src/util.d.ts +1 -2
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var B=Symbol(),o=($)=>typeof $==="string",s=($)=>typeof $==="number",E=($)=>typeof $==="symbol",M=($)=>typeof $==="function",j=($)=>M($)&&$.constructor.name==="AsyncFunction",P$=($)=>M($)&&$.constructor.name!=="AsyncFunction",J$=($)=>$!=null&&typeof $==="object",K=($,G)=>Object.prototype.toString.call($)===`[object ${G}]`,D=($)=>K($,"Object"),c=($)=>D($)||Array.isArray($),z$=($,G=(J)=>J!=null)=>Array.isArray($)&&$.every(G);var S=($)=>$ instanceof DOMException&&$.name==="AbortError",T=($)=>o($)?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($);var L=($,G,J)=>{if(Object.is($,G))return!0;if(typeof $!==typeof G)return!1;if(!J$($)||!J$(G))return!1;if(!J)J=new WeakSet;if(J.has($)||J.has(G))throw new U("isEqual");J.add($),J.add(G);try{if(Array.isArray($)&&Array.isArray(G)){if($.length!==G.length)return!1;for(let z=0;z<$.length;z++)if(!L($[z],G[z],J))return!1;return!0}if(Array.isArray($)!==Array.isArray(G))return!1;if(D($)&&D(G)){let z=Object.keys($),X=Object.keys(G);if(z.length!==X.length)return!1;for(let Z of z){if(!(Z in G))return!1;if(!L($[Z],G[Z],J))return!1}return!0}return!1}finally{J.delete($),J.delete(G)}},w=($,G)=>{let J=c($),z=c(G);if(!J||!z){let H=!Object.is($,G);return{changed:H,add:H&&z?G:{},change:{},remove:H&&J?$:{}}}let X=new WeakSet,Z={},Q={},I={},f=Object.keys($),u=Object.keys(G),_=new Set([...f,...u]);for(let H of _){let W=H in $,m=H in G;if(!W&&m){Z[H]=G[H];continue}else if(W&&!m){I[H]=B;continue}let N$=$[H],Y$=G[H];if(!L(N$,Y$,X))Q[H]=Y$}return{add:Z,change:Q,remove:I,changed:!!(Object.keys(Z).length||Object.keys(Q).length||Object.keys(I).length)}};var O,g=new Set,i=0,Y=($)=>{let G=new Set,J=$;return J.onCleanup=(z)=>{G.add(z)},J.stop=()=>{for(let z of G)z();G.clear()},J},q=($)=>{if(O&&!$.has(O)){let G=O;G.onCleanup(()=>$.delete(G)),$.add(G)}},x=($)=>{for(let G of $)if(i)g.add(G);else G()},p=()=>{while(g.size){let $=Array.from(g);g.clear();for(let G of $)G()}},X$=($)=>{i++;try{$()}finally{p(),i--}},P=($,G)=>{let J=O;O=$||void 0;try{G()}finally{O=J}},A=($,G)=>{for(let J of $)if(i)g.add(()=>J(G));else J(G)};var t="Computed";class b{#G=new Set;#J;#z;#$;#X=!0;#Q=!1;#Z;constructor($,G=B){N("memo",$,l),F("memo",G),this.#J=$,this.#z=G,this.#Z=Y(()=>{if(this.#X=!0,this.#G.size)x(this.#G);else this.#Z.stop()})}get[Symbol.toStringTag](){return t}get(){if(q(this.#G),p(),this.#X)P(this.#Z,()=>{if(this.#Q)throw new U("memo");let $;this.#Q=!0;try{$=this.#J(this.#z)}catch(G){this.#z=B,this.#$=R(G),this.#Q=!1;return}if($==null||B===$)this.#z=B,this.#$=void 0;else this.#z=$,this.#$=void 0,this.#X=!1;this.#Q=!1});if(this.#$)throw this.#$;return this.#z}}class y{#G=new Set;#J;#z;#$;#X=!0;#Q=!1;#Z=!1;#x;#B;constructor($,G=B){N("task",$,r),F("task",G),this.#J=$,this.#z=G,this.#x=Y(()=>{if(this.#X=!0,this.#B?.abort(),this.#G.size)x(this.#G);else this.#x.stop()}),this.#x.onCleanup(()=>{this.#B?.abort()})}get[Symbol.toStringTag](){return t}get(){q(this.#G),p();let $=(Z)=>{if(!L(Z,this.#z))this.#z=Z,this.#Z=!0;this.#$=void 0,this.#X=!1},G=()=>{this.#Z=B!==this.#z,this.#z=B,this.#$=void 0},J=(Z)=>{let Q=R(Z);this.#Z=!this.#$||Q.name!==this.#$.name||Q.message!==this.#$.message,this.#z=B,this.#$=Q},z=(Z)=>(Q)=>{if(this.#Q=!1,this.#B=void 0,Z(Q),this.#Z)x(this.#G)},X=()=>P(this.#x,()=>{if(this.#Q)throw new U("task");if(this.#Z=!1,this.#B)return this.#z;this.#B=new AbortController,this.#B.signal.addEventListener("abort",()=>{this.#Q=!1,this.#B=void 0,X()},{once:!0});let Z;this.#Q=!0;try{Z=this.#J(this.#z,this.#B.signal)}catch(Q){if(S(Q))G();else J(Q);this.#Q=!1;return}if(Z instanceof Promise)Z.then(z($),z(J));else if(Z==null||B===Z)G();else $(Z);this.#Q=!1});if(this.#X)X();if(this.#$)throw this.#$;return this.#z}}var Z$=($,G=B)=>j($)?new y($,G):new b($,G),Q$=($)=>K($,t),l=($)=>P$($)&&$.length<2,r=($)=>j($)&&$.length<3;class k{signals=new Map;#G;#J;#z=new Map;#$={add:new Set,change:new Set,remove:new Set};#X=!1;constructor($,G,J){this.#G=G,this.#J=J,this.change({add:$,change:{},remove:{},changed:!0},!0)}#Q($){let G=Y(()=>{P(G,()=>{if(this.signals.get($)?.get(),!this.#X)A(this.#$.change,[$])})});this.#z.set($,G),G()}add($,G){if(!this.#G($,G))return!1;if(this.signals.set($,this.#J(G)),this.#$.change.size)this.#Q($);if(!this.#X)A(this.#$.add,[$]);return!0}remove($){if(!this.signals.delete($))return!1;let J=this.#z.get($);if(J)J.stop(),this.#z.delete($);if(!this.#X)A(this.#$.remove,[$]);return!0}change($,G){if(this.#X=!0,Object.keys($.add).length){for(let z in $.add)this.add(z,$.add[z]);let J=()=>A(this.#$.add,Object.keys($.add));if(G)setTimeout(J,0);else J()}if(Object.keys($.change).length)X$(()=>{for(let J in $.change){let z=$.change[J];if(!this.#G(J,z))continue;let X=this.signals.get(J);if(B$(`list item "${J}"`,z,X))X.set(z)}}),A(this.#$.change,Object.keys($.change));if(Object.keys($.remove).length){for(let J in $.remove)this.remove(J);A(this.#$.remove,Object.keys($.remove))}return this.#X=!1,$.changed}clear(){let $=Array.from(this.signals.keys());return this.signals.clear(),this.#z.clear(),A(this.#$.remove,$),!0}on($,G){if(this.#$[$].add(G),$==="change"&&!this.#z.size){this.#X=!0;for(let J of this.signals.keys())this.#Q(J);this.#X=!1}return()=>{if(this.#$[$].delete(G),$==="change"&&!this.#$.change.size){if(this.#z.size){for(let J of this.#z.values())J.stop();this.#z.clear()}}}}}var x$="State";class C{#G=new Set;#J;constructor($){F("state",$),this.#J=$}get[Symbol.toStringTag](){return x$}get(){return q(this.#G),this.#J}set($){if(F("state",$),L(this.#J,$))return;if(this.#J=$,x(this.#G),B===this.#J)this.#G.clear()}update($){N("state update",$),this.set($(this.#J))}}var a=($)=>K($,x$);var H$="List";class h{#G;#J=new Set;#z={sort:new Set};#$=[];#X;constructor($,G){F("list",$,Array.isArray);let J=0;this.#X=o(G)?()=>`${G}${J++}`:M(G)?(z)=>G(z):()=>String(J++),this.#G=new k(this.#Q($),(z,X)=>{return F(`list for key "${z}"`,X),!0},(z)=>new C(z))}#Q($){let G={};for(let J=0;J<$.length;J++){let z=$[J];if(z===void 0)continue;let X=this.#$[J];if(!X)X=this.#X(z),this.#$[J]=X;G[X]=z}return G}get#Z(){return this.#$.map(($)=>this.#G.signals.get($)?.get()).filter(($)=>$!==void 0)}get[Symbol.toStringTag](){return H$}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#$){let G=this.#G.signals.get($);if(G)yield G}}get length(){return q(this.#J),this.#$.length}get(){return q(this.#J),this.#Z}set($){if(B===$){this.#G.clear(),x(this.#J),this.#J.clear();return}let G=this.#Z,J=w(this.#Q(G),this.#Q($)),z=Object.keys(J.remove);if(this.#G.change(J)){for(let Z of z){let Q=this.#$.indexOf(Z);if(Q!==-1)this.#$.splice(Q,1)}this.#$=this.#$.filter(()=>!0),x(this.#J)}}update($){this.set($(this.get()))}at($){return this.#G.signals.get(this.#$[$])}keys(){return this.#$.values()}byKey($){return this.#G.signals.get($)}keyAt($){return this.#$[$]}indexOfKey($){return this.#$.indexOf($)}add($){let G=this.#X($);if(this.#G.signals.has(G))throw new V("store",G,$);if(!this.#$.includes(G))this.#$.push(G);if(this.#G.add(G,$))x(this.#J);return G}remove($){let G=s($)?this.#$[$]:$;if(this.#G.remove(G)){let z=s($)?$:this.#$.indexOf(G);if(z>=0)this.#$.splice(z,1);this.#$=this.#$.filter(()=>!0),x(this.#J)}}sort($){let J=this.#$.map((z)=>[z,this.#G.signals.get(z)?.get()]).sort(M($)?(z,X)=>$(z[1],X[1]):(z,X)=>String(z[1]).localeCompare(String(X[1]))).map(([z])=>z);if(!L(this.#$,J))this.#$=J,x(this.#J),A(this.#z.sort,this.#$)}splice($,G,...J){let z=this.#$.length,X=$<0?Math.max(0,z+$):Math.min($,z),Z=Math.max(0,Math.min(G??Math.max(0,z-Math.max(0,X)),z-X)),Q={},I={};for(let _=0;_<Z;_++){let H=X+_,W=this.#$[H];if(W){let m=this.#G.signals.get(W);if(m)I[W]=m.get()}}let f=this.#$.slice(0,X);for(let _ of J){let H=this.#X(_);f.push(H),Q[H]=_}f.push(...this.#$.slice(X+Z));let u=!!(Object.keys(Q).length||Object.keys(I).length);if(u)this.#G.change({add:Q,change:{},remove:I,changed:u}),this.#$=f.filter(()=>!0),x(this.#J);return Object.values(I)}on($,G){if($==="sort")return this.#z.sort.add(G),()=>{this.#z.sort.delete(G)};return this.#G.on($,G)}deriveCollection($){return new d(this,$)}}var v=($)=>K($,H$);var M$="Store";class q${#G;#J=new Set;constructor($){F("store",$,D),this.#G=new k($,(G,J)=>{return F(`store for key "${G}"`,J),!0},(G)=>U$(G))}get#z(){let $={};for(let[G,J]of this.#G.signals.entries())$[G]=J.get();return $}get[Symbol.toStringTag](){return M$}get[Symbol.isConcatSpreadable](){return!1}*[Symbol.iterator](){for(let[$,G]of this.#G.signals.entries())yield[$,G]}get(){return q(this.#J),this.#z}set($){if(B===$){this.#G.clear(),x(this.#J),this.#J.clear();return}let G=this.#z;if(this.#G.change(w(G,$)))x(this.#J)}keys(){return this.#G.signals.keys()}byKey($){return this.#G.signals.get($)}update($){this.set($(this.get()))}add($,G){if(this.#G.signals.has($))throw new V("store",$,G);if(this.#G.add($,G))x(this.#J);return $}remove($){if(this.#G.remove($))x(this.#J)}on($,G){return this.#G.on($,G)}}var e=($)=>{let G=new q$($);return new Proxy(G,{get(J,z){if(z in J){let X=Reflect.get(J,z);return M(X)?X.bind(J):X}if(!E(z))return J.byKey(z)},has(J,z){if(z in J)return!0;return J.byKey(String(z))!==void 0},ownKeys(J){return Array.from(J.keys())},getOwnPropertyDescriptor(J,z){if(z in J)return Reflect.getOwnPropertyDescriptor(J,z);if(E(z))return;let X=J.byKey(String(z));return X?{enumerable:!0,configurable:!0,writable:!0,value:X}:void 0}})},$$=($)=>K($,M$);var T$=($)=>a($)||Q$($)||$$($),A$=($)=>a($)||$$($)||v($);function C$($){if(l($))return new b($);if(r($))return new y($);if(z$($))return new h($);if(D($))return e($);return new C($)}function U$($){if(z$($))return new h($);if(D($))return e($);return new C($)}class U extends Error{constructor($){super(`Circular dependency detected in ${$}`);this.name="CircularDependencyError"}}class V extends Error{constructor($,G,J){super(`Could not add ${$} key "${G}"${J?` with value ${T(J)}`:""} because it already exists`);this.name="DuplicateKeyError"}}class n extends TypeError{constructor($,G){super(`Invalid ${$} callback ${T(G)}`);this.name="InvalidCallbackError"}}class G$ extends TypeError{constructor($,G){super(`Invalid ${$} source ${T(G)}`);this.name="InvalidCollectionSourceError"}}class F$ extends TypeError{constructor($,G){super(`Invalid signal value ${T(G)} in ${$}`);this.name="InvalidSignalValueError"}}class I$ extends TypeError{constructor($){super(`Nullish signal values are not allowed in ${$}`);this.name="NullishSignalValueError"}}class K$ extends Error{constructor($,G){super(`Could not set ${$} to ${T(G)} because signal is read-only`);this.name="ReadonlySignalError"}}var R=($)=>$ instanceof Error?$:Error(String($)),N=($,G,J=M)=>{if(!J(G))throw new n($,G)},F=($,G,J=()=>!(E(G)&&G!==B)||M(G))=>{if(G==null)throw new I$($);if(!J(G))throw new F$($,G)},B$=($,G,J)=>{if(!A$(J))throw new K$($,G);return!0};var D$="Collection";class d{#G=new Set;#J;#z;#$=new Map;#X=new Map;#Q={add:new Set,change:new Set,remove:new Set,sort:new Set};#Z=[];constructor($,G){if(N("collection",G),M($))$=$();if(!W$($))throw new G$("derived collection",$);this.#J=$,this.#z=G;for(let J=0;J<this.#J.length;J++){let z=this.#J.keyAt(J);if(!z)continue;this.#x(z)}this.#J.on("add",(J)=>{for(let z of J)if(!this.#$.has(z)){this.#x(z);let X=this.#$.get(z);if(X&&_$(this.#z))X.get()}x(this.#G),A(this.#Q.add,J)}),this.#J.on("remove",(J)=>{for(let z of J){if(!this.#$.has(z))continue;this.#$.delete(z);let X=this.#Z.indexOf(z);if(X>=0)this.#Z.splice(X,1);let Z=this.#X.get(z);if(Z)Z.stop(),this.#X.delete(z)}this.#Z=this.#Z.filter(()=>!0),x(this.#G),A(this.#Q.remove,J)}),this.#J.on("sort",(J)=>{this.#Z=[...J],x(this.#G),A(this.#Q.sort,J)})}#x($){let G=_$(this.#z)?async(z,X)=>{let Z=this.#J.byKey($);if(!Z)return B;let Q=Z.get();if(Q===B)return B;return this.#z(Q,X)}:()=>{let z=this.#J.byKey($);if(!z)return B;let X=z.get();if(X===B)return B;return this.#z(X)},J=Z$(G);if(this.#$.set($,J),!this.#Z.includes($))this.#Z.push($);if(this.#Q.change.size)this.#B($);return!0}#B($){let G=Y(()=>{P(G,()=>{this.#$.get($)?.get()})});this.#X.set($,G),G()}get[Symbol.toStringTag](){return D$}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#Z){let G=this.#$.get($);if(G)yield G}}get length(){return q(this.#G),this.#Z.length}get(){return q(this.#G),this.#Z.map(($)=>this.#$.get($)?.get()).filter(($)=>$!=null&&$!==B)}at($){return this.#$.get(this.#Z[$])}keys(){return this.#Z.values()}byKey($){return this.#$.get($)}keyAt($){return this.#Z[$]}indexOfKey($){return this.#Z.indexOf($)}on($,G){if(this.#Q[$].add(G),$==="change"&&!this.#X.size)for(let J of this.#$.keys())this.#B(J);return()=>{if(this.#Q[$].delete(G),$==="change"&&!this.#Q.change.size){if(this.#X.size){for(let J of this.#X.values())J.stop();this.#X.clear()}}}}deriveCollection($){return new d(this,$)}}var j$=($)=>K($,D$),W$=($)=>v($)||j$($),_$=($)=>j($);var L$="Ref";class R${#G=new Set;#J;constructor($,G){F("ref",$,G),this.#J=$}get[Symbol.toStringTag](){return L$}get(){return q(this.#G),this.#J}notify(){x(this.#G)}}var E$=($)=>K($,L$);var S$=($)=>{if(!M($)||$.length>1)throw new n("effect",$);let G=j($),J=!1,z,X=Y(()=>P(X,()=>{if(J)throw new U("effect");J=!0,z?.abort(),z=void 0;let Z;try{if(G){z=new AbortController;let Q=z;$(z.signal).then((I)=>{if(M(I)&&z===Q)X.onCleanup(I)}).catch((I)=>{if(!S(I))console.error("Async effect error:",I)})}else if(Z=$(),M(Z))X.onCleanup(Z)}catch(Q){if(!S(Q))console.error("Effect callback error:",Q)}J=!1}));return X(),()=>{z?.abort(),X.stop()}};function O$($,G){try{if($.pending)G.nil?.();else if($.errors)G.err?.($.errors);else if($.ok)G.ok($.values)}catch(J){let z=R(J);if(G.err&&(!$.errors||!$.errors.includes(z)))G.err($.errors?[...$.errors,z]:[z]);else throw z}}function V$($){let G=[],J=!1,z={};for(let[X,Z]of Object.entries($))try{let Q=Z.get();if(Q===B)J=!0;else z[X]=Q}catch(Q){G.push(R(Q))}if(J)return{ok:!1,pending:!0};if(G.length>0)return{ok:!1,errors:G};return{ok:!0,values:z}}export{T as valueString,F as validateSignalValue,N as validateCallback,P as trackSignalReads,q as subscribeActiveWatcher,V$ as resolve,x as notifyWatchers,O$ as match,r as isTaskCallback,E as isSymbol,o as isString,$$ as isStore,a as isState,T$ as isSignal,E$ as isRef,c as isRecordOrArray,D as isRecord,K as isObjectOfType,s as isNumber,A$ as isMutableSignal,l as isMemoCallback,v as isList,M as isFunction,L as isEqual,Q$ as isComputed,j$ as isCollection,j as isAsyncFunction,S as isAbortError,B$ as guardMutableSignal,p as flushPendingReactions,A as emitNotification,w as diff,Y as createWatcher,e as createStore,C$ as createSignal,R as createError,S$ as createEffect,Z$ as createComputed,X$ as batchSignalWrites,B as UNSET,y as Task,M$ as TYPE_STORE,x$ as TYPE_STATE,L$ as TYPE_REF,H$ as TYPE_LIST,t as TYPE_COMPUTED,D$ as TYPE_COLLECTION,C as State,R$ as Ref,K$ as ReadonlySignalError,I$ as NullishSignalValueError,b as Memo,h as List,F$ as InvalidSignalValueError,G$ as InvalidCollectionSourceError,n as InvalidCallbackError,V as DuplicateKeyError,d as DerivedCollection,U as CircularDependencyError,q$ as BaseStore};
|
|
1
|
+
var Z$=($)=>typeof $==="string",Q$=($)=>typeof $==="number",p=($)=>typeof $==="symbol",q=($)=>typeof $==="function",H=($)=>q($)&&$.constructor.name==="AsyncFunction",_$=($)=>q($)&&$.constructor.name!=="AsyncFunction",U$=($)=>$!=null&&typeof $==="object",L=($,J)=>Object.prototype.toString.call($)===`[object ${J}]`,P=($)=>L($,"Object"),B$=($)=>P($)||Array.isArray($),Y$=($,J=(z)=>z!=null)=>Array.isArray($)&&$.every(J);var y=($)=>$ instanceof DOMException&&$.name==="AbortError",C=($)=>Z$($)?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($);var b,o=new WeakMap,x$=new Set,L$=0,x=Symbol(),A="add",N="change",m="cleanup",K="remove",v="sort",F="watch",S=($)=>{let J=new Set,z=$;return z.on=(X,Z)=>{if(X===m)J.add(Z);else throw new M("watcher",X)},z.stop=()=>{try{for(let X of J)X()}finally{J.clear()}},z},I=($,J)=>{if(!$.size&&J?.size){let z=j(J);if(z){let X=o.get($)??new Set;if(X.add(z),!o.has($))o.set($,X)}}if(b&&!$.has(b)){let z=b;z.on(m,()=>{if($.delete(z),!$.size){let X=o.get($);if(X)try{for(let Z of X)Z()}finally{X.clear(),o.delete($)}}}),$.add(z)}},G=($)=>{if(!$.size)return!1;for(let J of $)if(L$)x$.add(J);else J();return!0},s=()=>{while(x$.size){let $=Array.from(x$);x$.clear();for(let J of $)J()}},N$=($)=>{L$++;try{$()}finally{s(),L$--}},W=($,J)=>{let z=b;b=$||void 0;try{J()}finally{b=z}},j=($,J)=>{if(!$)return;let z=[],X=[],Z=(Q)=>{if(X.length){if(X.length===1)throw X[0];throw AggregateError(X,`Errors in hook ${Q?"cleanup":"callback"}:`)}};for(let Q of $)try{let B=Q(J);if(q(B))z.push(B)}catch(B){X.push(R(B))}if(Z(),!z.length)return;if(z.length===1)return z[0];return()=>{for(let Q of z)try{Q()}catch(B){X.push(R(B))}Z(!0)}},f=($,J)=>J.includes($);var V=($,J,z)=>{if(Object.is($,J))return!0;if(typeof $!==typeof J)return!1;if(!U$($)||!U$(J))return!1;if(!z)z=new WeakSet;if(z.has($)||z.has(J))throw new _("isEqual");z.add($),z.add(J);try{if(Array.isArray($)&&Array.isArray(J)){if($.length!==J.length)return!1;for(let X=0;X<$.length;X++)if(!V($[X],J[X],z))return!1;return!0}if(Array.isArray($)!==Array.isArray(J))return!1;if(P($)&&P(J)){let X=Object.keys($),Z=Object.keys(J);if(X.length!==Z.length)return!1;for(let Q of X){if(!(Q in J))return!1;if(!V($[Q],J[Q],z))return!1}return!0}return!1}finally{z.delete($),z.delete(J)}},t=($,J)=>{let z=B$($),X=B$(J);if(!z||!X){let D=!Object.is($,J);return{changed:D,add:D&&X?J:{},change:{},remove:D&&z?$:{}}}let Z=new WeakSet,Q={},B={},Y={},k=Object.keys($),X$=Object.keys(J),T=new Set([...k,...X$]);for(let D of T){let w=D in $,i=D in J;if(!w&&i){Q[D]=J[D];continue}else if(w&&!i){Y[D]=x;continue}let g$=$[D],m$=J[D];if(!V(g$,m$,Z))B[D]=m$}return{add:Q,change:B,remove:Y,changed:!!(Object.keys(Q).length||Object.keys(B).length||Object.keys(Y).length)}};var G$="Computed";class c{#z=new Set;#X;#J;#$;#B=!0;#Q=!1;#Z;#x;constructor($,J=x){E(this.constructor.name,$,q$),U(this.constructor.name,J),this.#X=$,this.#J=J}#G(){if(!this.#Z)this.#Z=S(()=>{if(this.#B=!0,!G(this.#z))this.#Z?.stop()}),this.#Z.on(m,()=>{this.#Z=void 0});return this.#Z}get[Symbol.toStringTag](){return G$}get(){if(I(this.#z,this.#x),s(),this.#B){let $=this.#G();W($,()=>{if(this.#Q)throw new _("memo");let J;this.#Q=!0;try{J=this.#X(this.#J)}catch(z){this.#J=x,this.#$=R(z),this.#Q=!1;return}if(J==null||x===J)this.#J=x,this.#$=void 0;else this.#J=J,this.#$=void 0,this.#B=!1;this.#Q=!1})}if(this.#$)throw this.#$;return this.#J}on($,J){if($===F)return this.#x||=new Set,this.#x.add(J),()=>{this.#x?.delete(J)};throw new M(this.constructor.name,$)}}class r{#z=new Set;#X;#J;#$;#B=!0;#Q=!1;#Z=!1;#x;#G;#q;constructor($,J=x){E(this.constructor.name,$,F$),U(this.constructor.name,J),this.#X=$,this.#J=J}#F(){if(!this.#x)this.#x=S(()=>{if(this.#B=!0,this.#G?.abort(),!G(this.#z))this.#x?.stop()}),this.#x.on(m,()=>{this.#G?.abort(),this.#G=void 0,this.#x=void 0});return this.#x}get[Symbol.toStringTag](){return G$}get(){I(this.#z,this.#q),s();let $=(Q)=>{if(!V(Q,this.#J))this.#J=Q,this.#Z=!0;this.#$=void 0,this.#B=!1},J=()=>{this.#Z=x!==this.#J,this.#J=x,this.#$=void 0},z=(Q)=>{let B=R(Q);this.#Z=!this.#$||B.name!==this.#$.name||B.message!==this.#$.message,this.#J=x,this.#$=B},X=(Q)=>(B)=>{if(this.#Q=!1,this.#G=void 0,Q(B),this.#Z&&!G(this.#z))this.#x?.stop()},Z=()=>W(this.#F(),()=>{if(this.#Q)throw new _("task");if(this.#Z=!1,this.#G)return this.#J;this.#G=new AbortController,this.#G.signal.addEventListener("abort",()=>{this.#Q=!1,this.#G=void 0,Z()},{once:!0});let Q;this.#Q=!0;try{Q=this.#X(this.#J,this.#G.signal)}catch(B){if(y(B))J();else z(B);this.#Q=!1;return}if(Q instanceof Promise)Q.then(X($),X(z));else if(Q==null||x===Q)J();else $(Q);this.#Q=!1});if(this.#B)Z();if(this.#$)throw this.#$;return this.#J}on($,J){if($===F)return this.#q||=new Set,this.#q.add(J),()=>{this.#q?.delete(J)};throw new M(this.constructor.name,$)}}var R$=($,J=x)=>H($)?new r($,J):new c($,J),P$=($)=>L($,G$),q$=($)=>_$($)&&$.length<2,F$=($)=>H($)&&$.length<3;class l{signals=new Map;#z;#X;#J=new Map;#$={};#B=!1;constructor($,J,z){this.#z=J,this.#X=z,this.change({add:$,change:{},remove:{},changed:!0},!0)}#Q($){let J=S(()=>{W(J,()=>{if(this.signals.get($)?.get(),!this.#B)j(this.#$.change,[$])})});this.#J.set($,J),J()}add($,J){if(!this.#z($,J))return!1;if(this.signals.set($,this.#X(J)),this.#$.change?.size)this.#Q($);if(!this.#B)j(this.#$.add,[$]);return!0}remove($){if(!this.signals.delete($))return!1;let z=this.#J.get($);if(z)z.stop(),this.#J.delete($);if(!this.#B)j(this.#$.remove,[$]);return!0}change($,J){if(this.#B=!0,Object.keys($.add).length){for(let X in $.add)this.add(X,$.add[X]);let z=()=>j(this.#$.add,Object.keys($.add));if(J)setTimeout(z,0);else z()}if(Object.keys($.change).length)N$(()=>{for(let z in $.change){let X=$.change[z];if(!this.#z(z,X))continue;let Z=this.signals.get(z);if(A$(`list item "${z}"`,X,Z))Z.set(X)}}),j(this.#$.change,Object.keys($.change));if(Object.keys($.remove).length){for(let z in $.remove)this.remove(z);j(this.#$.remove,Object.keys($.remove))}return this.#B=!1,$.changed}clear(){let $=Array.from(this.signals.keys());return this.signals.clear(),this.#J.clear(),j(this.#$.remove,$),!0}on($,J){if(!f($,[A,N,K]))throw new M("Composite",$);if(this.#$[$]||=new Set,this.#$[$].add(J),$===N&&!this.#J.size){this.#B=!0;for(let z of this.signals.keys())this.#Q(z);this.#B=!1}return()=>{if(this.#$[$]?.delete(J),$===N&&!this.#$.change?.size){if(this.#J.size){for(let z of this.#J.values())z.stop();this.#J.clear()}}}}}var n="State";class g{#z=new Set;#X;#J;constructor($){U(n,$),this.#X=$}get[Symbol.toStringTag](){return n}get(){return I(this.#z,this.#J),this.#X}set($){if(U(n,$),V(this.#X,$))return;if(this.#X=$,this.#z.size)G(this.#z);if(x===this.#X)this.#z.clear()}update($){E(`${n} update`,$),this.set($(this.#X))}on($,J){if($===F)return this.#J||=new Set,this.#J.add(J),()=>{this.#J?.delete(J)};throw new M(this.constructor.name,$)}}var M$=($)=>L($,n);var d="List";class a{#z;#X=new Set;#J={};#$=[];#B;constructor($,J){U(d,$,Array.isArray);let z=0;this.#B=Z$(J)?()=>`${J}${z++}`:q(J)?(X)=>J(X):()=>String(z++),this.#z=new l(this.#Q($),(X,Z)=>{return U(`${d} for key "${X}"`,Z),!0},(X)=>new g(X))}#Q($){let J={};for(let z=0;z<$.length;z++){let X=$[z];if(X===void 0)continue;let Z=this.#$[z];if(!Z)Z=this.#B(X),this.#$[z]=Z;J[Z]=X}return J}get#Z(){return this.#$.map(($)=>this.#z.signals.get($)?.get()).filter(($)=>$!==void 0)}get[Symbol.toStringTag](){return d}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#$){let J=this.#z.signals.get($);if(J)yield J}}get length(){return I(this.#X,this.#J[F]),this.#$.length}get(){return I(this.#X,this.#J[F]),this.#Z}set($){if(x===$){this.#z.clear(),G(this.#X),this.#X.clear();return}let J=this.#Z,z=t(this.#Q(J),this.#Q($)),X=Object.keys(z.remove);if(this.#z.change(z)){for(let Q of X){let B=this.#$.indexOf(Q);if(B!==-1)this.#$.splice(B,1)}this.#$=this.#$.filter(()=>!0),G(this.#X)}}update($){this.set($(this.get()))}at($){return this.#z.signals.get(this.#$[$])}keys(){return this.#$.values()}byKey($){return this.#z.signals.get($)}keyAt($){return this.#$[$]}indexOfKey($){return this.#$.indexOf($)}add($){let J=this.#B($);if(this.#z.signals.has(J))throw new h("store",J,$);if(!this.#$.includes(J))this.#$.push(J);if(this.#z.add(J,$))G(this.#X);return J}remove($){let J=Q$($)?this.#$[$]:$;if(this.#z.remove(J)){let X=Q$($)?$:this.#$.indexOf(J);if(X>=0)this.#$.splice(X,1);this.#$=this.#$.filter(()=>!0),G(this.#X)}}sort($){let z=this.#$.map((X)=>[X,this.#z.signals.get(X)?.get()]).sort(q($)?(X,Z)=>$(X[1],Z[1]):(X,Z)=>String(X[1]).localeCompare(String(Z[1]))).map(([X])=>X);if(!V(this.#$,z))this.#$=z,G(this.#X),j(this.#J.sort,this.#$)}splice($,J,...z){let X=this.#$.length,Z=$<0?Math.max(0,X+$):Math.min($,X),Q=Math.max(0,Math.min(J??Math.max(0,X-Math.max(0,Z)),X-Z)),B={},Y={};for(let T=0;T<Q;T++){let D=Z+T,w=this.#$[D];if(w){let i=this.#z.signals.get(w);if(i)Y[w]=i.get()}}let k=this.#$.slice(0,Z);for(let T of z){let D=this.#B(T);k.push(D),B[D]=T}k.push(...this.#$.slice(Z+Q));let X$=!!(Object.keys(B).length||Object.keys(Y).length);if(X$)this.#z.change({add:B,change:{},remove:Y,changed:X$}),this.#$=k.filter(()=>!0),G(this.#X);return Object.values(Y)}on($,J){if(f($,[v,F]))return this.#J[$]||=new Set,this.#J[$].add(J),()=>{this.#J[$]?.delete(J)};else if(f($,[A,N,K]))return this.#z.on($,J);throw new M(d,$)}deriveCollection($){return new $$(this,$)}}var e=($)=>L($,d);var O="Store";class K${#z;#X=new Set;#J;constructor($){U(O,$,P),this.#z=new l($,(J,z)=>{return U(`${O} for key "${J}"`,z),!0},(J)=>T$(J))}get#$(){let $={};for(let[J,z]of this.#z.signals.entries())$[J]=z.get();return $}get[Symbol.toStringTag](){return O}get[Symbol.isConcatSpreadable](){return!1}*[Symbol.iterator](){for(let[$,J]of this.#z.signals.entries())yield[$,J]}keys(){return this.#z.signals.keys()}byKey($){return this.#z.signals.get($)}get(){return I(this.#X,this.#J),this.#$}set($){if(x===$){this.#z.clear(),G(this.#X),this.#X.clear();return}let J=this.#$;if(this.#z.change(t(J,$)))G(this.#X)}update($){this.set($(this.get()))}add($,J){if(this.#z.signals.has($))throw new h(O,$,J);if(this.#z.add($,J))G(this.#X);return $}remove($){if(this.#z.remove($))G(this.#X)}on($,J){if($===F)return this.#J||=new Set,this.#J.add(J),()=>{this.#J?.delete(J)};else if(f($,[A,N,K]))return this.#z.on($,J);throw new M(O,$)}}var D$=($)=>{let J=new K$($);return new Proxy(J,{get(z,X){if(X in z){let Z=Reflect.get(z,X);return q(Z)?Z.bind(z):Z}if(!p(X))return z.byKey(X)},has(z,X){if(X in z)return!0;return z.byKey(String(X))!==void 0},ownKeys(z){return Array.from(z.keys())},getOwnPropertyDescriptor(z,X){if(X in z)return Reflect.getOwnPropertyDescriptor(z,X);if(p(X))return;let Z=z.byKey(String(X));return Z?{enumerable:!0,configurable:!0,writable:!0,value:Z}:void 0}})},I$=($)=>L($,O);var O$=($)=>M$($)||P$($)||I$($),S$=($)=>M$($)||I$($)||e($);function w$($){if(q$($))return new c($);if(F$($))return new r($);if(Y$($))return new a($);if(P($))return D$($);return new g($)}function T$($){if(Y$($))return new a($);if(P($))return D$($);return new g($)}class _ extends Error{constructor($){super(`Circular dependency detected in ${$}`);this.name="CircularDependencyError"}}class h extends Error{constructor($,J,z){super(`Could not add ${$} key "${J}"${z?` with value ${C(z)}`:""} because it already exists`);this.name="DuplicateKeyError"}}class J$ extends TypeError{constructor($,J){super(`Invalid ${$} callback ${C(J)}`);this.name="InvalidCallbackError"}}class j$ extends TypeError{constructor($,J){super(`Invalid ${$} source ${C(J)}`);this.name="InvalidCollectionSourceError"}}class M extends TypeError{constructor($,J){super(`Invalid hook "${J}" in ${$}`);this.name="InvalidHookError"}}class W$ extends TypeError{constructor($,J){super(`Invalid signal value ${C(J)} in ${$}`);this.name="InvalidSignalValueError"}}class f$ extends TypeError{constructor($){super(`Nullish signal values are not allowed in ${$}`);this.name="NullishSignalValueError"}}class V$ extends Error{constructor($,J){super(`Could not set ${$} to ${C(J)} because signal is read-only`);this.name="ReadonlySignalError"}}var R=($)=>$ instanceof Error?$:Error(String($)),E=($,J,z=q)=>{if(!z(J))throw new J$($,J)},U=($,J,z=()=>!(p(J)&&J!==x)||q(J))=>{if(J==null)throw new f$($);if(!z(J))throw new W$($,J)},A$=($,J,z)=>{if(!S$(z))throw new V$($,J);return!0};var u="Collection";class $${#z=new Set;#X;#J;#$=new Map;#B=new Map;#Q={};#Z=[];constructor($,J){if(E(u,J),q($))$=$();if(!p$($))throw new j$(u,$);this.#X=$,this.#J=J;for(let z=0;z<this.#X.length;z++){let X=this.#X.keyAt(z);if(!X)continue;this.#x(X)}this.#X.on(A,(z)=>{if(!z)return;for(let X of z)if(!this.#$.has(X)){this.#x(X);let Z=this.#$.get(X);if(Z&&H$(this.#J))Z.get()}G(this.#z),j(this.#Q.add,z)}),this.#X.on(K,(z)=>{if(!z)return;for(let X of z){if(!this.#$.has(X))continue;this.#$.delete(X);let Z=this.#Z.indexOf(X);if(Z>=0)this.#Z.splice(Z,1);let Q=this.#B.get(X);if(Q)Q.stop(),this.#B.delete(X)}this.#Z=this.#Z.filter(()=>!0),G(this.#z),j(this.#Q.remove,z)}),this.#X.on(v,(z)=>{if(z)this.#Z=[...z];G(this.#z),j(this.#Q.sort,z)})}#x($){let J=H$(this.#J)?async(X,Z)=>{let Q=this.#X.byKey($)?.get();if(Q===x)return x;return this.#J(Q,Z)}:()=>{let X=this.#X.byKey($)?.get();if(X===x)return x;return this.#J(X)},z=R$(J);if(this.#$.set($,z),!this.#Z.includes($))this.#Z.push($);if(this.#Q.change?.size)this.#G($);return!0}#G($){let J=S(()=>{W(J,()=>{this.#$.get($)?.get()})});this.#B.set($,J),J()}get[Symbol.toStringTag](){return u}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#Z){let J=this.#$.get($);if(J)yield J}}keys(){return this.#Z.values()}get(){return I(this.#z,this.#Q[F]),this.#Z.map(($)=>this.#$.get($)?.get()).filter(($)=>$!=null&&$!==x)}at($){return this.#$.get(this.#Z[$])}byKey($){return this.#$.get($)}keyAt($){return this.#Z[$]}indexOfKey($){return this.#Z.indexOf($)}on($,J){if(f($,[A,N,K,v,F])){if(this.#Q[$]||=new Set,this.#Q[$].add(J),$===N&&!this.#B.size)for(let z of this.#$.keys())this.#G(z);return()=>{if(this.#Q[$]?.delete(J),$===N&&!this.#Q.change?.size){if(this.#B.size){for(let z of this.#B.values())z.stop();this.#B.clear()}}}}throw new M(u,$)}deriveCollection($){return new $$(this,$)}get length(){return I(this.#z,this.#Q[F]),this.#Z.length}}var E$=($)=>L($,u),p$=($)=>e($)||E$($),H$=($)=>H($);var z$="Ref";class C${#z=new Set;#X;#J;constructor($,J){U(z$,$,J),this.#X=$}get[Symbol.toStringTag](){return z$}get(){return I(this.#z,this.#J),this.#X}notify(){G(this.#z)}on($,J){if($===F)return this.#J||=new Set,this.#J.add(J),()=>{this.#J?.delete(J)};throw new M(z$,$)}}var y$=($)=>L($,z$);var b$=($)=>{if(!q($)||$.length>1)throw new J$("effect",$);let J=H($),z=!1,X,Z=S(()=>W(Z,()=>{if(z)throw new _("effect");z=!0,X?.abort(),X=void 0;let Q;try{if(J){X=new AbortController;let B=X;$(X.signal).then((Y)=>{if(q(Y)&&X===B)Z.on(m,Y)}).catch((Y)=>{if(!y(Y))console.error("Error in async effect callback:",Y)})}else if(Q=$(),q(Q))Z.on(m,Q)}catch(B){if(!y(B))console.error("Error in effect callback:",B)}z=!1}));return Z(),()=>{X?.abort();try{Z.stop()}catch(Q){console.error("Error in effect cleanup:",Q)}}};function v$($,J){try{if($.pending)J.nil?.();else if($.errors)J.err?.($.errors);else if($.ok)J.ok($.values)}catch(z){let X=R(z);if(J.err&&(!$.errors||!$.errors.includes(X)))J.err($.errors?[...$.errors,X]:[X]);else throw X}}function n$($){let J=[],z=!1,X={};for(let[Z,Q]of Object.entries($))try{let B=Q.get();if(B===x)z=!0;else X[Z]=B}catch(B){J.push(R(B))}if(z)return{ok:!1,pending:!0};if(J.length>0)return{ok:!1,errors:J};return{ok:!0,values:X}}export{C as valueString,U as validateSignalValue,E as validateCallback,j as triggerHook,W as trackSignalReads,I as subscribeActiveWatcher,n$ as resolve,G as notifyWatchers,v$ as match,F$ as isTaskCallback,p as isSymbol,Z$ as isString,I$ as isStore,M$ as isState,O$ as isSignal,y$ as isRef,B$ as isRecordOrArray,P as isRecord,L as isObjectOfType,Q$ as isNumber,S$ as isMutableSignal,q$ as isMemoCallback,e as isList,f as isHandledHook,q as isFunction,V as isEqual,P$ as isComputed,E$ as isCollection,H as isAsyncFunction,y as isAbortError,A$ as guardMutableSignal,s as flushPendingReactions,t as diff,S as createWatcher,D$ as createStore,w$ as createSignal,R as createError,b$ as createEffect,R$ as createComputed,N$ as batchSignalWrites,x as UNSET,r as Task,O as TYPE_STORE,n as TYPE_STATE,z$ as TYPE_REF,d as TYPE_LIST,G$ as TYPE_COMPUTED,u as TYPE_COLLECTION,g as State,C$ as Ref,V$ as ReadonlySignalError,f$ as NullishSignalValueError,c as Memo,a as List,W$ as InvalidSignalValueError,j$ as InvalidCollectionSourceError,J$ as InvalidCallbackError,F as HOOK_WATCH,v as HOOK_SORT,K as HOOK_REMOVE,m as HOOK_CLEANUP,N as HOOK_CHANGE,A as HOOK_ADD,h as DuplicateKeyError,$$ as DerivedCollection,_ as CircularDependencyError,K$ as BaseStore};
|
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name Cause & Effect
|
|
3
|
-
* @version 0.17.
|
|
3
|
+
* @version 0.17.2
|
|
4
4
|
* @author Esther Brunner
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -80,14 +80,24 @@ export {
|
|
|
80
80
|
batchSignalWrites,
|
|
81
81
|
type Cleanup,
|
|
82
82
|
createWatcher,
|
|
83
|
-
emitNotification,
|
|
84
83
|
flushPendingReactions,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
HOOK_ADD,
|
|
85
|
+
HOOK_CHANGE,
|
|
86
|
+
HOOK_CLEANUP,
|
|
87
|
+
HOOK_REMOVE,
|
|
88
|
+
HOOK_SORT,
|
|
89
|
+
HOOK_WATCH,
|
|
90
|
+
type Hook,
|
|
91
|
+
type CleanupHook,
|
|
92
|
+
type WatchHook,
|
|
93
|
+
type HookCallback,
|
|
94
|
+
type HookCallbacks,
|
|
95
|
+
isHandledHook,
|
|
88
96
|
notifyWatchers,
|
|
89
97
|
subscribeActiveWatcher,
|
|
90
98
|
trackSignalReads,
|
|
99
|
+
triggerHook,
|
|
100
|
+
UNSET,
|
|
91
101
|
type Watcher,
|
|
92
102
|
} from './src/system'
|
|
93
103
|
export {
|
|
@@ -100,6 +110,5 @@ export {
|
|
|
100
110
|
isRecordOrArray,
|
|
101
111
|
isString,
|
|
102
112
|
isSymbol,
|
|
103
|
-
UNSET,
|
|
104
113
|
valueString,
|
|
105
114
|
} from './src/util'
|
package/package.json
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
InvalidCollectionSourceError,
|
|
3
|
+
InvalidHookError,
|
|
4
|
+
validateCallback,
|
|
5
|
+
} from '../errors'
|
|
2
6
|
import type { Signal } from '../signal'
|
|
3
7
|
import {
|
|
4
8
|
type Cleanup,
|
|
5
9
|
createWatcher,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
HOOK_ADD,
|
|
11
|
+
HOOK_CHANGE,
|
|
12
|
+
HOOK_REMOVE,
|
|
13
|
+
HOOK_SORT,
|
|
14
|
+
HOOK_WATCH,
|
|
15
|
+
type Hook,
|
|
16
|
+
type HookCallback,
|
|
17
|
+
type HookCallbacks,
|
|
18
|
+
isHandledHook,
|
|
9
19
|
notifyWatchers,
|
|
10
20
|
subscribeActiveWatcher,
|
|
11
21
|
trackSignalReads,
|
|
22
|
+
triggerHook,
|
|
23
|
+
UNSET,
|
|
12
24
|
type Watcher,
|
|
13
25
|
} from '../system'
|
|
14
|
-
import { isAsyncFunction, isFunction, isObjectOfType
|
|
26
|
+
import { isAsyncFunction, isFunction, isObjectOfType } from '../util'
|
|
15
27
|
import { type Computed, createComputed } from './computed'
|
|
16
28
|
import { isList, type List } from './list'
|
|
17
29
|
|
|
@@ -27,12 +39,13 @@ type Collection<T extends {}> = {
|
|
|
27
39
|
readonly [Symbol.toStringTag]: 'Collection'
|
|
28
40
|
readonly [Symbol.isConcatSpreadable]: true
|
|
29
41
|
[Symbol.iterator](): IterableIterator<Signal<T>>
|
|
42
|
+
keys(): IterableIterator<string>
|
|
30
43
|
get: () => T[]
|
|
31
44
|
at: (index: number) => Signal<T> | undefined
|
|
32
45
|
byKey: (key: string) => Signal<T> | undefined
|
|
33
46
|
keyAt: (index: number) => string | undefined
|
|
34
47
|
indexOfKey: (key: string) => number | undefined
|
|
35
|
-
on: <K extends
|
|
48
|
+
on: <K extends Hook>(type: K, callback: HookCallback) => Cleanup
|
|
36
49
|
deriveCollection: <R extends {}>(
|
|
37
50
|
callback: CollectionCallback<R, T>,
|
|
38
51
|
) => DerivedCollection<R, T>
|
|
@@ -51,23 +64,18 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
51
64
|
#callback: CollectionCallback<T, U>
|
|
52
65
|
#signals = new Map<string, Computed<T>>()
|
|
53
66
|
#ownWatchers = new Map<string, Watcher>()
|
|
54
|
-
#
|
|
55
|
-
add: new Set<Listener<'add'>>(),
|
|
56
|
-
change: new Set<Listener<'change'>>(),
|
|
57
|
-
remove: new Set<Listener<'remove'>>(),
|
|
58
|
-
sort: new Set<Listener<'sort'>>(),
|
|
59
|
-
}
|
|
67
|
+
#hookCallbacks: HookCallbacks = {}
|
|
60
68
|
#order: string[] = []
|
|
61
69
|
|
|
62
70
|
constructor(
|
|
63
71
|
source: CollectionSource<U> | (() => CollectionSource<U>),
|
|
64
72
|
callback: CollectionCallback<T, U>,
|
|
65
73
|
) {
|
|
66
|
-
validateCallback(
|
|
74
|
+
validateCallback(TYPE_COLLECTION, callback)
|
|
67
75
|
|
|
68
76
|
if (isFunction(source)) source = source()
|
|
69
77
|
if (!isCollectionSource(source))
|
|
70
|
-
throw new InvalidCollectionSourceError(
|
|
78
|
+
throw new InvalidCollectionSourceError(TYPE_COLLECTION, source)
|
|
71
79
|
this.#source = source
|
|
72
80
|
|
|
73
81
|
this.#callback = callback
|
|
@@ -79,7 +87,8 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
79
87
|
this.#add(key)
|
|
80
88
|
}
|
|
81
89
|
|
|
82
|
-
this.#source.on(
|
|
90
|
+
this.#source.on(HOOK_ADD, additions => {
|
|
91
|
+
if (!additions) return
|
|
83
92
|
for (const key of additions) {
|
|
84
93
|
if (!this.#signals.has(key)) {
|
|
85
94
|
this.#add(key)
|
|
@@ -90,10 +99,11 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
90
99
|
}
|
|
91
100
|
}
|
|
92
101
|
notifyWatchers(this.#watchers)
|
|
93
|
-
|
|
102
|
+
triggerHook(this.#hookCallbacks.add, additions)
|
|
94
103
|
})
|
|
95
104
|
|
|
96
|
-
this.#source.on(
|
|
105
|
+
this.#source.on(HOOK_REMOVE, removals => {
|
|
106
|
+
if (!removals) return
|
|
97
107
|
for (const key of removals) {
|
|
98
108
|
if (!this.#signals.has(key)) continue
|
|
99
109
|
|
|
@@ -109,31 +119,25 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
109
119
|
}
|
|
110
120
|
this.#order = this.#order.filter(() => true) // Compact array
|
|
111
121
|
notifyWatchers(this.#watchers)
|
|
112
|
-
|
|
122
|
+
triggerHook(this.#hookCallbacks.remove, removals)
|
|
113
123
|
})
|
|
114
124
|
|
|
115
|
-
this.#source.on(
|
|
116
|
-
this.#order = [...newOrder]
|
|
125
|
+
this.#source.on(HOOK_SORT, newOrder => {
|
|
126
|
+
if (newOrder) this.#order = [...newOrder]
|
|
117
127
|
notifyWatchers(this.#watchers)
|
|
118
|
-
|
|
128
|
+
triggerHook(this.#hookCallbacks.sort, newOrder)
|
|
119
129
|
})
|
|
120
130
|
}
|
|
121
131
|
|
|
122
132
|
#add(key: string): boolean {
|
|
123
133
|
const computedCallback = isAsyncCollectionCallback<T>(this.#callback)
|
|
124
134
|
? async (_: T, abort: AbortSignal) => {
|
|
125
|
-
const
|
|
126
|
-
if (!sourceSignal) return UNSET
|
|
127
|
-
|
|
128
|
-
const sourceValue = sourceSignal.get() as U
|
|
135
|
+
const sourceValue = this.#source.byKey(key)?.get() as U
|
|
129
136
|
if (sourceValue === UNSET) return UNSET
|
|
130
137
|
return this.#callback(sourceValue, abort)
|
|
131
138
|
}
|
|
132
139
|
: () => {
|
|
133
|
-
const
|
|
134
|
-
if (!sourceSignal) return UNSET
|
|
135
|
-
|
|
136
|
-
const sourceValue = sourceSignal.get() as U
|
|
140
|
+
const sourceValue = this.#source.byKey(key)?.get() as U
|
|
137
141
|
if (sourceValue === UNSET) return UNSET
|
|
138
142
|
return (this.#callback as (sourceValue: U) => T)(
|
|
139
143
|
sourceValue,
|
|
@@ -144,7 +148,7 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
144
148
|
|
|
145
149
|
this.#signals.set(key, signal)
|
|
146
150
|
if (!this.#order.includes(key)) this.#order.push(key)
|
|
147
|
-
if (this.#
|
|
151
|
+
if (this.#hookCallbacks.change?.size) this.#addWatcher(key)
|
|
148
152
|
return true
|
|
149
153
|
}
|
|
150
154
|
|
|
@@ -173,13 +177,12 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
179
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return this.#order.length
|
|
180
|
+
keys(): IterableIterator<string> {
|
|
181
|
+
return this.#order.values()
|
|
179
182
|
}
|
|
180
183
|
|
|
181
184
|
get(): T[] {
|
|
182
|
-
subscribeActiveWatcher(this.#watchers)
|
|
185
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH])
|
|
183
186
|
return this.#order
|
|
184
187
|
.map(key => this.#signals.get(key)?.get())
|
|
185
188
|
.filter(v => v != null && v !== UNSET) as T[]
|
|
@@ -189,10 +192,6 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
189
192
|
return this.#signals.get(this.#order[index])
|
|
190
193
|
}
|
|
191
194
|
|
|
192
|
-
keys(): IterableIterator<string> {
|
|
193
|
-
return this.#order.values()
|
|
194
|
-
}
|
|
195
|
-
|
|
196
195
|
byKey(key: string): Computed<T> | undefined {
|
|
197
196
|
return this.#signals.get(key)
|
|
198
197
|
}
|
|
@@ -205,22 +204,34 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
205
204
|
return this.#order.indexOf(key)
|
|
206
205
|
}
|
|
207
206
|
|
|
208
|
-
on
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
on(type: Hook, callback: HookCallback): Cleanup {
|
|
208
|
+
if (
|
|
209
|
+
isHandledHook(type, [
|
|
210
|
+
HOOK_ADD,
|
|
211
|
+
HOOK_CHANGE,
|
|
212
|
+
HOOK_REMOVE,
|
|
213
|
+
HOOK_SORT,
|
|
214
|
+
HOOK_WATCH,
|
|
215
|
+
])
|
|
216
|
+
) {
|
|
217
|
+
this.#hookCallbacks[type] ||= new Set()
|
|
218
|
+
this.#hookCallbacks[type].add(callback)
|
|
219
|
+
if (type === HOOK_CHANGE && !this.#ownWatchers.size) {
|
|
220
|
+
for (const key of this.#signals.keys()) this.#addWatcher(key)
|
|
221
|
+
}
|
|
213
222
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
return () => {
|
|
224
|
+
this.#hookCallbacks[type]?.delete(callback)
|
|
225
|
+
if (type === HOOK_CHANGE && !this.#hookCallbacks.change?.size) {
|
|
226
|
+
if (this.#ownWatchers.size) {
|
|
227
|
+
for (const watcher of this.#ownWatchers.values())
|
|
228
|
+
watcher.stop()
|
|
229
|
+
this.#ownWatchers.clear()
|
|
230
|
+
}
|
|
221
231
|
}
|
|
222
232
|
}
|
|
223
233
|
}
|
|
234
|
+
throw new InvalidHookError(TYPE_COLLECTION, type)
|
|
224
235
|
}
|
|
225
236
|
|
|
226
237
|
deriveCollection<R extends {}>(
|
|
@@ -234,6 +245,11 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
234
245
|
): DerivedCollection<R, T> {
|
|
235
246
|
return new DerivedCollection(this, callback)
|
|
236
247
|
}
|
|
248
|
+
|
|
249
|
+
get length(): number {
|
|
250
|
+
subscribeActiveWatcher(this.#watchers, this.#hookCallbacks[HOOK_WATCH])
|
|
251
|
+
return this.#order.length
|
|
252
|
+
}
|
|
237
253
|
}
|
|
238
254
|
|
|
239
255
|
/* === Functions === */
|
|
@@ -241,13 +257,13 @@ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
|
|
|
241
257
|
/**
|
|
242
258
|
* Check if a value is a collection signal
|
|
243
259
|
*
|
|
244
|
-
* @since 0.17.
|
|
260
|
+
* @since 0.17.2
|
|
245
261
|
* @param {unknown} value - Value to check
|
|
246
262
|
* @returns {boolean} - True if value is a collection signal, false otherwise
|
|
247
263
|
*/
|
|
248
|
-
const isCollection = /*#__PURE__*/ <T extends {}
|
|
264
|
+
const isCollection = /*#__PURE__*/ <T extends {}>(
|
|
249
265
|
value: unknown,
|
|
250
|
-
): value is
|
|
266
|
+
): value is Collection<T> => isObjectOfType(value, TYPE_COLLECTION)
|
|
251
267
|
|
|
252
268
|
/**
|
|
253
269
|
* Check if a value is a collection source
|
package/src/classes/composite.ts
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import type { DiffResult, UnknownRecord } from '../diff'
|
|
2
|
-
import { guardMutableSignal } from '../errors'
|
|
2
|
+
import { guardMutableSignal, InvalidHookError } from '../errors'
|
|
3
3
|
import type { Signal } from '../signal'
|
|
4
4
|
import {
|
|
5
5
|
batchSignalWrites,
|
|
6
6
|
type Cleanup,
|
|
7
7
|
createWatcher,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
HOOK_ADD,
|
|
9
|
+
HOOK_CHANGE,
|
|
10
|
+
HOOK_REMOVE,
|
|
11
|
+
type HookCallback,
|
|
12
|
+
type HookCallbacks,
|
|
13
|
+
isHandledHook,
|
|
11
14
|
trackSignalReads,
|
|
15
|
+
triggerHook,
|
|
12
16
|
type Watcher,
|
|
13
17
|
} from '../system'
|
|
14
18
|
|
|
15
19
|
/* === Types === */
|
|
16
20
|
|
|
17
|
-
type
|
|
21
|
+
type CompositeHook = 'add' | 'change' | 'remove'
|
|
18
22
|
|
|
19
23
|
/* === Class Definitions === */
|
|
20
24
|
|
|
@@ -26,11 +30,7 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
26
30
|
) => value is T[K] & {}
|
|
27
31
|
#create: <V extends T[keyof T] & {}>(value: V) => S
|
|
28
32
|
#watchers = new Map<string, Watcher>()
|
|
29
|
-
#
|
|
30
|
-
add: new Set<Listener<'add'>>(),
|
|
31
|
-
change: new Set<Listener<'change'>>(),
|
|
32
|
-
remove: new Set<Listener<'remove'>>(),
|
|
33
|
-
}
|
|
33
|
+
#hookCallbacks: HookCallbacks = {}
|
|
34
34
|
#batching = false
|
|
35
35
|
|
|
36
36
|
constructor(
|
|
@@ -59,7 +59,7 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
59
59
|
trackSignalReads(watcher, () => {
|
|
60
60
|
this.signals.get(key)?.get() // Subscribe to the signal
|
|
61
61
|
if (!this.#batching)
|
|
62
|
-
|
|
62
|
+
triggerHook(this.#hookCallbacks.change, [key])
|
|
63
63
|
})
|
|
64
64
|
})
|
|
65
65
|
this.#watchers.set(key, watcher)
|
|
@@ -70,9 +70,9 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
70
70
|
if (!this.#validate(key, value)) return false
|
|
71
71
|
|
|
72
72
|
this.signals.set(key, this.#create(value))
|
|
73
|
-
if (this.#
|
|
73
|
+
if (this.#hookCallbacks.change?.size) this.#addWatcher(key)
|
|
74
74
|
|
|
75
|
-
if (!this.#batching)
|
|
75
|
+
if (!this.#batching) triggerHook(this.#hookCallbacks.add, [key])
|
|
76
76
|
return true
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -86,7 +86,7 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
86
86
|
this.#watchers.delete(key)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if (!this.#batching)
|
|
89
|
+
if (!this.#batching) triggerHook(this.#hookCallbacks.remove, [key])
|
|
90
90
|
return true
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -103,7 +103,7 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
103
103
|
|
|
104
104
|
// Queue initial additions event to allow listeners to be added first
|
|
105
105
|
const notify = () =>
|
|
106
|
-
|
|
106
|
+
triggerHook(this.#hookCallbacks.add, Object.keys(changes.add))
|
|
107
107
|
if (initialRun) setTimeout(notify, 0)
|
|
108
108
|
else notify()
|
|
109
109
|
}
|
|
@@ -121,20 +121,14 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
121
121
|
signal.set(value)
|
|
122
122
|
}
|
|
123
123
|
})
|
|
124
|
-
|
|
125
|
-
this.#listeners.change,
|
|
126
|
-
Object.keys(changes.change),
|
|
127
|
-
)
|
|
124
|
+
triggerHook(this.#hookCallbacks.change, Object.keys(changes.change))
|
|
128
125
|
}
|
|
129
126
|
|
|
130
127
|
// Removals
|
|
131
128
|
if (Object.keys(changes.remove).length) {
|
|
132
129
|
for (const key in changes.remove)
|
|
133
130
|
this.remove(key as keyof T & string)
|
|
134
|
-
|
|
135
|
-
this.#listeners.remove,
|
|
136
|
-
Object.keys(changes.remove),
|
|
137
|
-
)
|
|
131
|
+
triggerHook(this.#hookCallbacks.remove, Object.keys(changes.remove))
|
|
138
132
|
}
|
|
139
133
|
|
|
140
134
|
this.#batching = false
|
|
@@ -145,24 +139,25 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
145
139
|
const keys = Array.from(this.signals.keys())
|
|
146
140
|
this.signals.clear()
|
|
147
141
|
this.#watchers.clear()
|
|
148
|
-
|
|
142
|
+
triggerHook(this.#hookCallbacks.remove, keys)
|
|
149
143
|
return true
|
|
150
144
|
}
|
|
151
145
|
|
|
152
|
-
on
|
|
153
|
-
type
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this.#
|
|
157
|
-
|
|
146
|
+
on(type: CompositeHook, callback: HookCallback): Cleanup {
|
|
147
|
+
if (!isHandledHook(type, [HOOK_ADD, HOOK_CHANGE, HOOK_REMOVE]))
|
|
148
|
+
throw new InvalidHookError('Composite', type)
|
|
149
|
+
|
|
150
|
+
this.#hookCallbacks[type] ||= new Set()
|
|
151
|
+
this.#hookCallbacks[type].add(callback)
|
|
152
|
+
if (type === HOOK_CHANGE && !this.#watchers.size) {
|
|
158
153
|
this.#batching = true
|
|
159
154
|
for (const key of this.signals.keys()) this.#addWatcher(key)
|
|
160
155
|
this.#batching = false
|
|
161
156
|
}
|
|
162
157
|
|
|
163
158
|
return () => {
|
|
164
|
-
this.#
|
|
165
|
-
if (type ===
|
|
159
|
+
this.#hookCallbacks[type]?.delete(callback)
|
|
160
|
+
if (type === HOOK_CHANGE && !this.#hookCallbacks.change?.size) {
|
|
166
161
|
if (this.#watchers.size) {
|
|
167
162
|
for (const watcher of this.#watchers.values())
|
|
168
163
|
watcher.stop()
|
|
@@ -173,4 +168,4 @@ class Composite<T extends UnknownRecord, S extends Signal<T[keyof T] & {}>> {
|
|
|
173
168
|
}
|
|
174
169
|
}
|
|
175
170
|
|
|
176
|
-
export { Composite, type CompositeListeners }
|
|
171
|
+
export { Composite, type CompositeHook as CompositeListeners }
|