@zeix/cause-effect 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import { isEqual } from '../src/diff'
2
2
  import {
3
3
  CircularDependencyError,
4
+ createError,
4
5
  InvalidCallbackError,
5
6
  NullishSignalValueError,
6
7
  } from '../src/errors'
@@ -17,7 +18,6 @@ import {
17
18
  isAsyncFunction,
18
19
  isFunction,
19
20
  isObjectOfType,
20
- toError,
21
21
  UNSET,
22
22
  } from '../src/util'
23
23
 
@@ -78,7 +78,7 @@ const createComputed = <T extends {}>(
78
78
  error = undefined
79
79
  }
80
80
  const err = (e: unknown): undefined => {
81
- const newError = toError(e)
81
+ const newError = createError(e)
82
82
  changed =
83
83
  !error ||
84
84
  newError.name !== error.name ||
package/archive/memo.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  CircularDependencyError,
3
+ createError,
3
4
  InvalidCallbackError,
4
5
  NullishSignalValueError,
5
6
  } from '../src/errors'
@@ -11,7 +12,7 @@ import {
11
12
  trackSignalReads,
12
13
  type Watcher,
13
14
  } from '../src/system'
14
- import { isObjectOfType, isSyncFunction, toError, UNSET } from '../src/util'
15
+ import { isObjectOfType, isSyncFunction, UNSET } from '../src/util'
15
16
 
16
17
  /* === Types === */
17
18
 
@@ -69,7 +70,7 @@ const createMemo = <T extends {}>(
69
70
  } catch (e) {
70
71
  // Err track
71
72
  value = UNSET
72
- error = toError(e)
73
+ error = createError(e)
73
74
  computing = false
74
75
  return
75
76
  }
package/archive/task.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { isEqual } from '../src/diff'
2
2
  import {
3
3
  CircularDependencyError,
4
+ createError,
4
5
  InvalidCallbackError,
5
6
  NullishSignalValueError,
6
7
  } from '../src/errors'
@@ -16,7 +17,6 @@ import {
16
17
  isAbortError,
17
18
  isAsyncFunction,
18
19
  isObjectOfType,
19
- toError,
20
20
  UNSET,
21
21
  } from '../src/util'
22
22
 
@@ -78,7 +78,7 @@ const createTask = <T extends {}>(
78
78
  error = undefined
79
79
  }
80
80
  const err = (e: unknown): undefined => {
81
- const newError = toError(e)
81
+ const newError = createError(e)
82
82
  changed =
83
83
  !error ||
84
84
  newError.name !== error.name ||
package/index.dev.js CHANGED
@@ -12,7 +12,6 @@ var isRecord = (value) => isObjectOfType(value, "Object");
12
12
  var isRecordOrArray = (value) => isRecord(value) || Array.isArray(value);
13
13
  var isUniformArray = (value, guard = (item) => item != null) => Array.isArray(value) && value.every(guard);
14
14
  var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError";
15
- var toError = (reason) => reason instanceof Error ? reason : Error(String(reason));
16
15
  var valueString = (value) => isString(value) ? `"${value}"` : !!value && typeof value === "object" ? JSON.stringify(value) : String(value);
17
16
 
18
17
  // src/diff.ts
@@ -209,7 +208,7 @@ class Memo {
209
208
  result = this.#callback(this.#value);
210
209
  } catch (e) {
211
210
  this.#value = UNSET;
212
- this.#error = toError(e);
211
+ this.#error = createError(e);
213
212
  this.#computing = false;
214
213
  return;
215
214
  }
@@ -277,7 +276,7 @@ class Task {
277
276
  this.#error = undefined;
278
277
  };
279
278
  const err = (e) => {
280
- const newError = toError(e);
279
+ const newError = createError(e);
281
280
  this.#changed = !this.#error || newError.name !== this.#error.name || newError.message !== this.#error.message;
282
281
  this.#value = UNSET;
283
282
  this.#error = newError;
@@ -651,12 +650,14 @@ class List {
651
650
  on(type, listener) {
652
651
  if (type === "sort") {
653
652
  this.#listeners.sort.add(listener);
654
- return () => this.#listeners.sort.delete(listener);
653
+ return () => {
654
+ this.#listeners.sort.delete(listener);
655
+ };
655
656
  }
656
657
  return this.#composite.on(type, listener);
657
658
  }
658
659
  deriveCollection(callback) {
659
- return new Collection(this, callback);
660
+ return new DerivedCollection(this, callback);
660
661
  }
661
662
  }
662
663
  var isList = (value) => isObjectOfType(value, TYPE_LIST);
@@ -812,6 +813,13 @@ class InvalidCallbackError extends TypeError {
812
813
  }
813
814
  }
814
815
 
816
+ class InvalidCollectionSourceError extends TypeError {
817
+ constructor(where, value) {
818
+ super(`Invalid ${where} source ${valueString(value)}`);
819
+ this.name = "InvalidCollectionSourceError";
820
+ }
821
+ }
822
+
815
823
  class InvalidSignalValueError extends TypeError {
816
824
  constructor(where, value) {
817
825
  super(`Invalid signal value ${valueString(value)} in ${where}`);
@@ -832,6 +840,7 @@ class ReadonlySignalError extends Error {
832
840
  this.name = "ReadonlySignalError";
833
841
  }
834
842
  }
843
+ var createError = (reason) => reason instanceof Error ? reason : Error(String(reason));
835
844
  var validateCallback = (where, value, guard = isFunction) => {
836
845
  if (!guard(value))
837
846
  throw new InvalidCallbackError(where, value);
@@ -851,7 +860,7 @@ var guardMutableSignal = (what, value, signal) => {
851
860
  // src/classes/collection.ts
852
861
  var TYPE_COLLECTION = "Collection";
853
862
 
854
- class Collection {
863
+ class DerivedCollection {
855
864
  #watchers = new Set;
856
865
  #source;
857
866
  #callback;
@@ -869,7 +878,7 @@ class Collection {
869
878
  if (isFunction(source))
870
879
  source = source();
871
880
  if (!isCollectionSource(source))
872
- throw new Error("Invalid collection source");
881
+ throw new InvalidCollectionSourceError("derived collection", source);
873
882
  this.#source = source;
874
883
  this.#callback = callback;
875
884
  for (let i = 0;i < this.#source.length; i++) {
@@ -898,7 +907,11 @@ class Collection {
898
907
  const index = this.#order.indexOf(key);
899
908
  if (index >= 0)
900
909
  this.#order.splice(index, 1);
901
- this.#removeWatcher(key);
910
+ const watcher = this.#ownWatchers.get(key);
911
+ if (watcher) {
912
+ watcher.stop();
913
+ this.#ownWatchers.delete(key);
914
+ }
902
915
  }
903
916
  this.#order = this.#order.filter(() => true);
904
917
  notifyWatchers(this.#watchers);
@@ -910,9 +923,6 @@ class Collection {
910
923
  emitNotification(this.#listeners.sort, newOrder);
911
924
  });
912
925
  }
913
- get #value() {
914
- return this.#order.map((key) => this.#signals.get(key)?.get()).filter((v) => v != null && v !== UNSET);
915
- }
916
926
  #add(key) {
917
927
  const computedCallback = isAsyncCollectionCallback(this.#callback) ? async (_, abort) => {
918
928
  const sourceSignal = this.#source.byKey(key);
@@ -948,13 +958,6 @@ class Collection {
948
958
  this.#ownWatchers.set(key, watcher);
949
959
  watcher();
950
960
  }
951
- #removeWatcher(key) {
952
- const watcher = this.#ownWatchers.get(key);
953
- if (watcher) {
954
- watcher.stop();
955
- this.#ownWatchers.delete(key);
956
- }
957
- }
958
961
  get [Symbol.toStringTag]() {
959
962
  return TYPE_COLLECTION;
960
963
  }
@@ -974,7 +977,7 @@ class Collection {
974
977
  }
975
978
  get() {
976
979
  subscribeActiveWatcher(this.#watchers);
977
- return this.#value;
980
+ return this.#order.map((key) => this.#signals.get(key)?.get()).filter((v) => v != null && v !== UNSET);
978
981
  }
979
982
  at(index) {
980
983
  return this.#signals.get(this.#order[index]);
@@ -1009,12 +1012,34 @@ class Collection {
1009
1012
  };
1010
1013
  }
1011
1014
  deriveCollection(callback) {
1012
- return new Collection(this, callback);
1015
+ return new DerivedCollection(this, callback);
1013
1016
  }
1014
1017
  }
1015
1018
  var isCollection = (value) => isObjectOfType(value, TYPE_COLLECTION);
1016
1019
  var isCollectionSource = (value) => isList(value) || isCollection(value);
1017
1020
  var isAsyncCollectionCallback = (callback) => isAsyncFunction(callback);
1021
+ // src/classes/ref.ts
1022
+ var TYPE_REF = "Ref";
1023
+
1024
+ class Ref {
1025
+ #watchers = new Set;
1026
+ #value;
1027
+ constructor(value, guard) {
1028
+ validateSignalValue("ref", value, guard);
1029
+ this.#value = value;
1030
+ }
1031
+ get [Symbol.toStringTag]() {
1032
+ return TYPE_REF;
1033
+ }
1034
+ get() {
1035
+ subscribeActiveWatcher(this.#watchers);
1036
+ return this.#value;
1037
+ }
1038
+ notify() {
1039
+ notifyWatchers(this.#watchers);
1040
+ }
1041
+ }
1042
+ var isRef = (value) => isObjectOfType(value, TYPE_REF);
1018
1043
  // src/effect.ts
1019
1044
  var createEffect = (callback) => {
1020
1045
  if (!isFunction(callback) || callback.length > 1)
@@ -1066,9 +1091,10 @@ function match(result, handlers) {
1066
1091
  handlers.err?.(result.errors);
1067
1092
  else if (result.ok)
1068
1093
  handlers.ok(result.values);
1069
- } catch (error) {
1070
- if (handlers.err && (!result.errors || !result.errors.includes(toError(error))))
1071
- handlers.err(result.errors ? [...result.errors, toError(error)] : [toError(error)]);
1094
+ } catch (e) {
1095
+ const error = createError(e);
1096
+ if (handlers.err && (!result.errors || !result.errors.includes(error)))
1097
+ handlers.err(result.errors ? [...result.errors, error] : [error]);
1072
1098
  else
1073
1099
  throw error;
1074
1100
  }
@@ -1086,7 +1112,7 @@ function resolve(signals) {
1086
1112
  else
1087
1113
  values[key] = value;
1088
1114
  } catch (e) {
1089
- errors.push(toError(e));
1115
+ errors.push(createError(e));
1090
1116
  }
1091
1117
  }
1092
1118
  if (pending)
@@ -1097,8 +1123,9 @@ function resolve(signals) {
1097
1123
  }
1098
1124
  export {
1099
1125
  valueString,
1126
+ validateSignalValue,
1127
+ validateCallback,
1100
1128
  trackSignalReads,
1101
- toError,
1102
1129
  subscribeActiveWatcher,
1103
1130
  resolve,
1104
1131
  notifyWatchers,
@@ -1109,6 +1136,7 @@ export {
1109
1136
  isStore,
1110
1137
  isState,
1111
1138
  isSignal,
1139
+ isRef,
1112
1140
  isRecordOrArray,
1113
1141
  isRecord,
1114
1142
  isObjectOfType,
@@ -1122,12 +1150,14 @@ export {
1122
1150
  isCollection,
1123
1151
  isAsyncFunction,
1124
1152
  isAbortError,
1153
+ guardMutableSignal,
1125
1154
  flushPendingReactions,
1126
1155
  emitNotification,
1127
1156
  diff,
1128
1157
  createWatcher,
1129
1158
  createStore,
1130
1159
  createSignal,
1160
+ createError,
1131
1161
  createEffect,
1132
1162
  createComputed,
1133
1163
  batchSignalWrites,
@@ -1135,18 +1165,21 @@ export {
1135
1165
  Task,
1136
1166
  TYPE_STORE,
1137
1167
  TYPE_STATE,
1168
+ TYPE_REF,
1138
1169
  TYPE_LIST,
1139
1170
  TYPE_COMPUTED,
1140
1171
  TYPE_COLLECTION,
1141
1172
  State,
1173
+ Ref,
1142
1174
  ReadonlySignalError,
1143
1175
  NullishSignalValueError,
1144
1176
  Memo,
1145
1177
  List,
1146
1178
  InvalidSignalValueError,
1179
+ InvalidCollectionSourceError,
1147
1180
  InvalidCallbackError,
1148
1181
  DuplicateKeyError,
1149
- Collection,
1182
+ DerivedCollection,
1150
1183
  CircularDependencyError,
1151
1184
  BaseStore
1152
1185
  };
package/index.js CHANGED
@@ -1 +1 @@
1
- var B=Symbol(),o=($)=>typeof $==="string",s=($)=>typeof $==="number",W=($)=>typeof $==="symbol",q=($)=>typeof $==="function",j=($)=>q($)&&$.constructor.name==="AsyncFunction",Y$=($)=>q($)&&$.constructor.name!=="AsyncFunction",J$=($)=>$!=null&&typeof $==="object",F=($,J)=>Object.prototype.toString.call($)===`[object ${J}]`,Y=($)=>F($,"Object"),c=($)=>Y($)||Array.isArray($),z$=($,J=(z)=>z!=null)=>Array.isArray($)&&$.every(J);var E=($)=>$ instanceof DOMException&&$.name==="AbortError",I=($)=>$ instanceof Error?$:Error(String($)),f=($)=>o($)?`"${$}"`:!!$&&typeof $==="object"?JSON.stringify($):String($);var L=($,J,z)=>{if(Object.is($,J))return!0;if(typeof $!==typeof J)return!1;if(!J$($)||!J$(J))return!1;if(!z)z=new WeakSet;if(z.has($)||z.has(J))throw new P("isEqual");z.add($),z.add(J);try{if(Array.isArray($)&&Array.isArray(J)){if($.length!==J.length)return!1;for(let G=0;G<$.length;G++)if(!L($[G],J[G],z))return!1;return!0}if(Array.isArray($)!==Array.isArray(J))return!1;if(Y($)&&Y(J)){let G=Object.keys($),X=Object.keys(J);if(G.length!==X.length)return!1;for(let Z of G){if(!(Z in J))return!1;if(!L($[Z],J[Z],z))return!1}return!0}return!1}finally{z.delete($),z.delete(J)}},w=($,J)=>{let z=c($),G=c(J);if(!z||!G){let M=!Object.is($,J);return{changed:M,add:M&&G?J:{},change:{},remove:M&&z?$:{}}}let X=new WeakSet,Z={},Q={},A={},V=Object.keys($),u=Object.keys(J),U=new Set([...V,...u]);for(let M of U){let C=M in $,m=M in J;if(!C&&m){Z[M]=J[M];continue}else if(C&&!m){A[M]=B;continue}let P$=$[M],K$=J[M];if(!L(P$,K$,X))Q[M]=K$}return{add:Z,change:Q,remove:A,changed:!!(Object.keys(Z).length||Object.keys(Q).length||Object.keys(A).length)}};var S,g=new Set,i=0,R=($)=>{let J=new Set,z=$;return z.onCleanup=(G)=>{J.add(G)},z.stop=()=>{for(let G of J)G();J.clear()},z},D=($)=>{if(S&&!$.has(S)){let J=S;J.onCleanup(()=>$.delete(J)),$.add(J)}},H=($)=>{for(let J of $)if(i)g.add(J);else J()},p=()=>{while(g.size){let $=Array.from(g);g.clear();for(let J of $)J()}},G$=($)=>{i++;try{$()}finally{p(),i--}},_=($,J)=>{let z=S;S=$||void 0;try{J()}finally{S=z}},x=($,J)=>{for(let z of $)if(i)g.add(()=>z(J));else z(J)};var t="Computed";class b{#J=new Set;#z;#G;#$;#X=!0;#Q=!1;#Z;constructor($,J=B){N("memo",$,l),K("memo",J),this.#z=$,this.#G=J,this.#Z=R(()=>{if(this.#X=!0,this.#J.size)H(this.#J);else this.#Z.stop()})}get[Symbol.toStringTag](){return t}get(){if(D(this.#J),p(),this.#X)_(this.#Z,()=>{if(this.#Q)throw new P("memo");let $;this.#Q=!0;try{$=this.#z(this.#G)}catch(J){this.#G=B,this.#$=I(J),this.#Q=!1;return}if($==null||B===$)this.#G=B,this.#$=void 0;else this.#G=$,this.#$=void 0,this.#X=!1;this.#Q=!1});if(this.#$)throw this.#$;return this.#G}}class y{#J=new Set;#z;#G;#$;#X=!0;#Q=!1;#Z=!1;#H;#B;constructor($,J=B){N("task",$,r),K("task",J),this.#z=$,this.#G=J,this.#H=R(()=>{if(this.#X=!0,this.#B?.abort(),this.#J.size)H(this.#J);else this.#H.stop()}),this.#H.onCleanup(()=>{this.#B?.abort()})}get[Symbol.toStringTag](){return t}get(){D(this.#J),p();let $=(Z)=>{if(!L(Z,this.#G))this.#G=Z,this.#Z=!0;this.#$=void 0,this.#X=!1},J=()=>{this.#Z=B!==this.#G,this.#G=B,this.#$=void 0},z=(Z)=>{let Q=I(Z);this.#Z=!this.#$||Q.name!==this.#$.name||Q.message!==this.#$.message,this.#G=B,this.#$=Q},G=(Z)=>(Q)=>{if(this.#Q=!1,this.#B=void 0,Z(Q),this.#Z)H(this.#J)},X=()=>_(this.#H,()=>{if(this.#Q)throw new P("task");if(this.#Z=!1,this.#B)return this.#G;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.#z(this.#G,this.#B.signal)}catch(Q){if(E(Q))J();else z(Q);this.#Q=!1;return}if(Z instanceof Promise)Z.then(G($),G(z));else if(Z==null||B===Z)J();else $(Z);this.#Q=!1});if(this.#X)X();if(this.#$)throw this.#$;return this.#G}}var X$=($,J=B)=>j($)?new y($,J):new b($,J),Z$=($)=>F($,t),l=($)=>Y$($)&&$.length<2,r=($)=>j($)&&$.length<3;class k{signals=new Map;#J;#z;#G=new Map;#$={add:new Set,change:new Set,remove:new Set};#X=!1;constructor($,J,z){this.#J=J,this.#z=z,this.change({add:$,change:{},remove:{},changed:!0},!0)}#Q($){let J=R(()=>{_(J,()=>{if(this.signals.get($)?.get(),!this.#X)x(this.#$.change,[$])})});this.#G.set($,J),J()}add($,J){if(!this.#J($,J))return!1;if(this.signals.set($,this.#z(J)),this.#$.change.size)this.#Q($);if(!this.#X)x(this.#$.add,[$]);return!0}remove($){if(!this.signals.delete($))return!1;let z=this.#G.get($);if(z)z.stop(),this.#G.delete($);if(!this.#X)x(this.#$.remove,[$]);return!0}change($,J){if(this.#X=!0,Object.keys($.add).length){for(let G in $.add)this.add(G,$.add[G]);let z=()=>x(this.#$.add,Object.keys($.add));if(J)setTimeout(z,0);else z()}if(Object.keys($.change).length)G$(()=>{for(let z in $.change){let G=$.change[z];if(!this.#J(z,G))continue;let X=this.signals.get(z);if(I$(`list item "${z}"`,G,X))X.set(G)}}),x(this.#$.change,Object.keys($.change));if(Object.keys($.remove).length){for(let z in $.remove)this.remove(z);x(this.#$.remove,Object.keys($.remove))}return this.#X=!1,$.changed}clear(){let $=Array.from(this.signals.keys());return this.signals.clear(),this.#G.clear(),x(this.#$.remove,$),!0}on($,J){if(this.#$[$].add(J),$==="change"&&!this.#G.size){this.#X=!0;for(let z of this.signals.keys())this.#Q(z);this.#X=!1}return()=>{if(this.#$[$].delete(J),$==="change"&&!this.#$.change.size){if(this.#G.size){for(let z of this.#G.values())z.stop();this.#G.clear()}}}}}var Q$="State";class T{#J=new Set;#z;constructor($){K("state",$),this.#z=$}get[Symbol.toStringTag](){return Q$}get(){return D(this.#J),this.#z}set($){if(K("state",$),L(this.#z,$))return;if(this.#z=$,H(this.#J),B===this.#z)this.#J.clear()}update($){N("state update",$),this.set($(this.#z))}}var a=($)=>F($,Q$);var B$="List";class v{#J;#z=new Set;#G={sort:new Set};#$=[];#X;constructor($,J){K("list",$,Array.isArray);let z=0;this.#X=o(J)?()=>`${J}${z++}`:q(J)?(G)=>J(G):()=>String(z++),this.#J=new k(this.#Q($),(G,X)=>{return K(`list for key "${G}"`,X),!0},(G)=>new T(G))}#Q($){let J={};for(let z=0;z<$.length;z++){let G=$[z];if(G===void 0)continue;let X=this.#$[z];if(!X)X=this.#X(G),this.#$[z]=X;J[X]=G}return J}get#Z(){return this.#$.map(($)=>this.#J.signals.get($)?.get()).filter(($)=>$!==void 0)}get[Symbol.toStringTag](){return B$}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#$){let J=this.#J.signals.get($);if(J)yield J}}get length(){return D(this.#z),this.#$.length}get(){return D(this.#z),this.#Z}set($){if(B===$){this.#J.clear(),H(this.#z),this.#z.clear();return}let J=this.#Z,z=w(this.#Q(J),this.#Q($)),G=Object.keys(z.remove);if(this.#J.change(z)){for(let Z of G){let Q=this.#$.indexOf(Z);if(Q!==-1)this.#$.splice(Q,1)}this.#$=this.#$.filter(()=>!0),H(this.#z)}}update($){this.set($(this.get()))}at($){return this.#J.signals.get(this.#$[$])}keys(){return this.#$.values()}byKey($){return this.#J.signals.get($)}keyAt($){return this.#$[$]}indexOfKey($){return this.#$.indexOf($)}add($){let J=this.#X($);if(this.#J.signals.has(J))throw new O("store",J,$);if(!this.#$.includes(J))this.#$.push(J);if(this.#J.add(J,$))H(this.#z);return J}remove($){let J=s($)?this.#$[$]:$;if(this.#J.remove(J)){let G=s($)?$:this.#$.indexOf(J);if(G>=0)this.#$.splice(G,1);this.#$=this.#$.filter(()=>!0),H(this.#z)}}sort($){let z=this.#$.map((G)=>[G,this.#J.signals.get(G)?.get()]).sort(q($)?(G,X)=>$(G[1],X[1]):(G,X)=>String(G[1]).localeCompare(String(X[1]))).map(([G])=>G);if(!L(this.#$,z))this.#$=z,H(this.#z),x(this.#G.sort,this.#$)}splice($,J,...z){let G=this.#$.length,X=$<0?Math.max(0,G+$):Math.min($,G),Z=Math.max(0,Math.min(J??Math.max(0,G-Math.max(0,X)),G-X)),Q={},A={};for(let U=0;U<Z;U++){let M=X+U,C=this.#$[M];if(C){let m=this.#J.signals.get(C);if(m)A[C]=m.get()}}let V=this.#$.slice(0,X);for(let U of z){let M=this.#X(U);V.push(M),Q[M]=U}V.push(...this.#$.slice(X+Z));let u=!!(Object.keys(Q).length||Object.keys(A).length);if(u)this.#J.change({add:Q,change:{},remove:A,changed:u}),this.#$=V.filter(()=>!0),H(this.#z);return Object.values(A)}on($,J){if($==="sort")return this.#G.sort.add(J),()=>this.#G.sort.delete(J);return this.#J.on($,J)}deriveCollection($){return new d(this,$)}}var h=($)=>F($,B$);var H$="Store";class M${#J;#z=new Set;constructor($){K("store",$,Y),this.#J=new k($,(J,z)=>{return K(`store for key "${J}"`,z),!0},(J)=>L$(J))}get#G(){let $={};for(let[J,z]of this.#J.signals.entries())$[J]=z.get();return $}get[Symbol.toStringTag](){return H$}get[Symbol.isConcatSpreadable](){return!1}*[Symbol.iterator](){for(let[$,J]of this.#J.signals.entries())yield[$,J]}get(){return D(this.#z),this.#G}set($){if(B===$){this.#J.clear(),H(this.#z),this.#z.clear();return}let J=this.#G;if(this.#J.change(w(J,$)))H(this.#z)}keys(){return this.#J.signals.keys()}byKey($){return this.#J.signals.get($)}update($){this.set($(this.get()))}add($,J){if(this.#J.signals.has($))throw new O("store",$,J);if(this.#J.add($,J))H(this.#z);return $}remove($){if(this.#J.remove($))H(this.#z)}on($,J){return this.#J.on($,J)}}var e=($)=>{let J=new M$($);return new Proxy(J,{get(z,G){if(G in z){let X=Reflect.get(z,G);return q(X)?X.bind(z):X}if(!W(G))return z.byKey(G)},has(z,G){if(G in z)return!0;return z.byKey(String(G))!==void 0},ownKeys(z){return Array.from(z.keys())},getOwnPropertyDescriptor(z,G){if(G in z)return Reflect.getOwnPropertyDescriptor(z,G);if(W(G))return;let X=z.byKey(String(G));return X?{enumerable:!0,configurable:!0,writable:!0,value:X}:void 0}})},$$=($)=>F($,H$);var U$=($)=>a($)||Z$($)||$$($),q$=($)=>a($)||$$($)||h($);function j$($){if(l($))return new b($);if(r($))return new y($);if(z$($))return new v($);if(Y($))return e($);return new T($)}function L$($){if(z$($))return new v($);if(Y($))return e($);return new T($)}class P extends Error{constructor($){super(`Circular dependency detected in ${$}`);this.name="CircularDependencyError"}}class O extends Error{constructor($,J,z){super(`Could not add ${$} key "${J}"${z?` with value ${f(z)}`:""} because it already exists`);this.name="DuplicateKeyError"}}class n extends TypeError{constructor($,J){super(`Invalid ${$} callback ${f(J)}`);this.name="InvalidCallbackError"}}class x$ extends TypeError{constructor($,J){super(`Invalid signal value ${f(J)} in ${$}`);this.name="InvalidSignalValueError"}}class A$ extends TypeError{constructor($){super(`Nullish signal values are not allowed in ${$}`);this.name="NullishSignalValueError"}}class D$ extends Error{constructor($,J){super(`Could not set ${$} to ${f(J)} because signal is read-only`);this.name="ReadonlySignalError"}}var N=($,J,z=q)=>{if(!z(J))throw new n($,J)},K=($,J,z=()=>!(W(J)&&J!==B)||q(J))=>{if(J==null)throw new A$($);if(!z(J))throw new x$($,J)},I$=($,J,z)=>{if(!q$(z))throw new D$($,J);return!0};var F$="Collection";class d{#J=new Set;#z;#G;#$=new Map;#X=new Map;#Q={add:new Set,change:new Set,remove:new Set,sort:new Set};#Z=[];constructor($,J){if(N("collection",J),q($))$=$();if(!N$($))throw Error("Invalid collection source");this.#z=$,this.#G=J;for(let z=0;z<this.#z.length;z++){let G=this.#z.keyAt(z);if(!G)continue;this.#B(G)}this.#z.on("add",(z)=>{for(let G of z)if(!this.#$.has(G)){this.#B(G);let X=this.#$.get(G);if(X&&R$(this.#G))X.get()}H(this.#J),x(this.#Q.add,z)}),this.#z.on("remove",(z)=>{for(let G of z){if(!this.#$.has(G))continue;this.#$.delete(G);let X=this.#Z.indexOf(G);if(X>=0)this.#Z.splice(X,1);this.#q(G)}this.#Z=this.#Z.filter(()=>!0),H(this.#J),x(this.#Q.remove,z)}),this.#z.on("sort",(z)=>{this.#Z=[...z],H(this.#J),x(this.#Q.sort,z)})}get#H(){return this.#Z.map(($)=>this.#$.get($)?.get()).filter(($)=>$!=null&&$!==B)}#B($){let J=R$(this.#G)?async(G,X)=>{let Z=this.#z.byKey($);if(!Z)return B;let Q=Z.get();if(Q===B)return B;return this.#G(Q,X)}:()=>{let G=this.#z.byKey($);if(!G)return B;let X=G.get();if(X===B)return B;return this.#G(X)},z=X$(J);if(this.#$.set($,z),!this.#Z.includes($))this.#Z.push($);if(this.#Q.change.size)this.#M($);return!0}#M($){let J=R(()=>{_(J,()=>{this.#$.get($)?.get()})});this.#X.set($,J),J()}#q($){let J=this.#X.get($);if(J)J.stop(),this.#X.delete($)}get[Symbol.toStringTag](){return F$}get[Symbol.isConcatSpreadable](){return!0}*[Symbol.iterator](){for(let $ of this.#Z){let J=this.#$.get($);if(J)yield J}}get length(){return D(this.#J),this.#Z.length}get(){return D(this.#J),this.#H}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($,J){if(this.#Q[$].add(J),$==="change"&&!this.#X.size)for(let z of this.#$.keys())this.#M(z);return()=>{if(this.#Q[$].delete(J),$==="change"&&!this.#Q.change.size){if(this.#X.size){for(let z of this.#X.values())z.stop();this.#X.clear()}}}}deriveCollection($){return new d(this,$)}}var _$=($)=>F($,F$),N$=($)=>h($)||_$($),R$=($)=>j($);var T$=($)=>{if(!q($)||$.length>1)throw new n("effect",$);let J=j($),z=!1,G,X=R(()=>_(X,()=>{if(z)throw new P("effect");z=!0,G?.abort(),G=void 0;let Z;try{if(J){G=new AbortController;let Q=G;$(G.signal).then((A)=>{if(q(A)&&G===Q)X.onCleanup(A)}).catch((A)=>{if(!E(A))console.error("Async effect error:",A)})}else if(Z=$(),q(Z))X.onCleanup(Z)}catch(Q){if(!E(Q))console.error("Effect callback error:",Q)}z=!1}));return X(),()=>{G?.abort(),X.stop()}};function C$($,J){try{if($.pending)J.nil?.();else if($.errors)J.err?.($.errors);else if($.ok)J.ok($.values)}catch(z){if(J.err&&(!$.errors||!$.errors.includes(I(z))))J.err($.errors?[...$.errors,I(z)]:[I(z)]);else throw z}}function W$($){let J=[],z=!1,G={};for(let[X,Z]of Object.entries($))try{let Q=Z.get();if(Q===B)z=!0;else G[X]=Q}catch(Q){J.push(I(Q))}if(z)return{ok:!1,pending:!0};if(J.length>0)return{ok:!1,errors:J};return{ok:!0,values:G}}export{f as valueString,_ as trackSignalReads,I as toError,D as subscribeActiveWatcher,W$ as resolve,H as notifyWatchers,C$ as match,r as isTaskCallback,W as isSymbol,o as isString,$$ as isStore,a as isState,U$ as isSignal,c as isRecordOrArray,Y as isRecord,F as isObjectOfType,s as isNumber,q$ as isMutableSignal,l as isMemoCallback,h as isList,q as isFunction,L as isEqual,Z$ as isComputed,_$ as isCollection,j as isAsyncFunction,E as isAbortError,p as flushPendingReactions,x as emitNotification,w as diff,R as createWatcher,e as createStore,j$ as createSignal,T$ as createEffect,X$ as createComputed,G$ as batchSignalWrites,B as UNSET,y as Task,H$ as TYPE_STORE,Q$ as TYPE_STATE,B$ as TYPE_LIST,t as TYPE_COMPUTED,F$ as TYPE_COLLECTION,T as State,D$ as ReadonlySignalError,A$ as NullishSignalValueError,b as Memo,v as List,x$ as InvalidSignalValueError,n as InvalidCallbackError,O as DuplicateKeyError,d as Collection,P as CircularDependencyError,M$ as BaseStore};
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};
package/index.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * @name Cause & Effect
3
- * @version 0.17.0
3
+ * @version 0.17.1
4
4
  * @author Esther Brunner
5
5
  */
6
6
 
7
7
  export {
8
- Collection,
8
+ type Collection,
9
9
  type CollectionCallback,
10
+ type CollectionSource,
11
+ DerivedCollection,
10
12
  isCollection,
11
13
  TYPE_COLLECTION,
12
14
  } from './src/classes/collection'
@@ -29,6 +31,7 @@ export {
29
31
  List,
30
32
  TYPE_LIST,
31
33
  } from './src/classes/list'
34
+ export { isRef, Ref, TYPE_REF } from './src/classes/ref'
32
35
  export { isState, State, TYPE_STATE } from './src/classes/state'
33
36
  export {
34
37
  BaseStore,
@@ -51,11 +54,17 @@ export {
51
54
  } from './src/effect'
52
55
  export {
53
56
  CircularDependencyError,
57
+ createError,
54
58
  DuplicateKeyError,
59
+ type Guard,
60
+ guardMutableSignal,
55
61
  InvalidCallbackError,
62
+ InvalidCollectionSourceError,
56
63
  InvalidSignalValueError,
57
64
  NullishSignalValueError,
58
65
  ReadonlySignalError,
66
+ validateCallback,
67
+ validateSignalValue,
59
68
  } from './src/errors'
60
69
  export { type MatchHandlers, match } from './src/match'
61
70
  export { type ResolveResult, resolve } from './src/resolve'
@@ -91,7 +100,6 @@ export {
91
100
  isRecordOrArray,
92
101
  isString,
93
102
  isSymbol,
94
- toError,
95
103
  UNSET,
96
104
  valueString,
97
105
  } from './src/util'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeix/cause-effect",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "author": "Esther Brunner",
5
5
  "main": "index.js",
6
6
  "module": "index.ts",
@@ -1,4 +1,5 @@
1
- import { validateCallback } from '../errors'
1
+ import { InvalidCollectionSourceError, validateCallback } from '../errors'
2
+ import type { Signal } from '../signal'
2
3
  import {
3
4
  type Cleanup,
4
5
  createWatcher,
@@ -16,20 +17,35 @@ import { isList, type List } from './list'
16
17
 
17
18
  /* === Types === */
18
19
 
19
- // biome-ignore lint/suspicious/noExplicitAny: source type of current collection doesn't matter
20
- type CollectionSource<T extends {}> = List<T> | Collection<T, any>
20
+ type CollectionSource<T extends {}> = List<T> | Collection<T>
21
21
 
22
22
  type CollectionCallback<T extends {}, U extends {}> =
23
23
  | ((sourceValue: U) => T)
24
24
  | ((sourceValue: U, abort: AbortSignal) => Promise<T>)
25
25
 
26
+ type Collection<T extends {}> = {
27
+ readonly [Symbol.toStringTag]: 'Collection'
28
+ readonly [Symbol.isConcatSpreadable]: true
29
+ [Symbol.iterator](): IterableIterator<Signal<T>>
30
+ get: () => T[]
31
+ at: (index: number) => Signal<T> | undefined
32
+ byKey: (key: string) => Signal<T> | undefined
33
+ keyAt: (index: number) => string | undefined
34
+ indexOfKey: (key: string) => number | undefined
35
+ on: <K extends keyof Listeners>(type: K, listener: Listener<K>) => Cleanup
36
+ deriveCollection: <R extends {}>(
37
+ callback: CollectionCallback<R, T>,
38
+ ) => DerivedCollection<R, T>
39
+ readonly length: number
40
+ }
41
+
26
42
  /* === Constants === */
27
43
 
28
44
  const TYPE_COLLECTION = 'Collection' as const
29
45
 
30
46
  /* === Class === */
31
47
 
32
- class Collection<T extends {}, U extends {}> {
48
+ class DerivedCollection<T extends {}, U extends {}> implements Collection<T> {
33
49
  #watchers = new Set<Watcher>()
34
50
  #source: CollectionSource<U>
35
51
  #callback: CollectionCallback<T, U>
@@ -51,7 +67,7 @@ class Collection<T extends {}, U extends {}> {
51
67
 
52
68
  if (isFunction(source)) source = source()
53
69
  if (!isCollectionSource(source))
54
- throw new Error('Invalid collection source')
70
+ throw new InvalidCollectionSourceError('derived collection', source)
55
71
  this.#source = source
56
72
 
57
73
  this.#callback = callback
@@ -84,7 +100,12 @@ class Collection<T extends {}, U extends {}> {
84
100
  this.#signals.delete(key)
85
101
  const index = this.#order.indexOf(key)
86
102
  if (index >= 0) this.#order.splice(index, 1)
87
- this.#removeWatcher(key)
103
+
104
+ const watcher = this.#ownWatchers.get(key)
105
+ if (watcher) {
106
+ watcher.stop()
107
+ this.#ownWatchers.delete(key)
108
+ }
88
109
  }
89
110
  this.#order = this.#order.filter(() => true) // Compact array
90
111
  notifyWatchers(this.#watchers)
@@ -98,12 +119,6 @@ class Collection<T extends {}, U extends {}> {
98
119
  })
99
120
  }
100
121
 
101
- get #value(): T[] {
102
- return this.#order
103
- .map(key => this.#signals.get(key)?.get())
104
- .filter(v => v != null && v !== UNSET) as T[]
105
- }
106
-
107
122
  #add(key: string): boolean {
108
123
  const computedCallback = isAsyncCollectionCallback<T>(this.#callback)
109
124
  ? async (_: T, abort: AbortSignal) => {
@@ -143,19 +158,11 @@ class Collection<T extends {}, U extends {}> {
143
158
  watcher()
144
159
  }
145
160
 
146
- #removeWatcher(key: string): void {
147
- const watcher = this.#ownWatchers.get(key)
148
- if (watcher) {
149
- watcher.stop()
150
- this.#ownWatchers.delete(key)
151
- }
152
- }
153
-
154
161
  get [Symbol.toStringTag](): 'Collection' {
155
162
  return TYPE_COLLECTION
156
163
  }
157
164
 
158
- get [Symbol.isConcatSpreadable](): boolean {
165
+ get [Symbol.isConcatSpreadable](): true {
159
166
  return true
160
167
  }
161
168
 
@@ -173,7 +180,9 @@ class Collection<T extends {}, U extends {}> {
173
180
 
174
181
  get(): T[] {
175
182
  subscribeActiveWatcher(this.#watchers)
176
- return this.#value
183
+ return this.#order
184
+ .map(key => this.#signals.get(key)?.get())
185
+ .filter(v => v != null && v !== UNSET) as T[]
177
186
  }
178
187
 
179
188
  at(index: number): Computed<T> | undefined {
@@ -216,14 +225,14 @@ class Collection<T extends {}, U extends {}> {
216
225
 
217
226
  deriveCollection<R extends {}>(
218
227
  callback: (sourceValue: T) => R,
219
- ): Collection<R, T>
228
+ ): DerivedCollection<R, T>
220
229
  deriveCollection<R extends {}>(
221
230
  callback: (sourceValue: T, abort: AbortSignal) => Promise<R>,
222
- ): Collection<R, T>
231
+ ): DerivedCollection<R, T>
223
232
  deriveCollection<R extends {}>(
224
233
  callback: CollectionCallback<R, T>,
225
- ): Collection<R, T> {
226
- return new Collection(this, callback)
234
+ ): DerivedCollection<R, T> {
235
+ return new DerivedCollection(this, callback)
227
236
  }
228
237
  }
229
238
 
@@ -238,7 +247,7 @@ class Collection<T extends {}, U extends {}> {
238
247
  */
239
248
  const isCollection = /*#__PURE__*/ <T extends {}, U extends {}>(
240
249
  value: unknown,
241
- ): value is Collection<T, U> => isObjectOfType(value, TYPE_COLLECTION)
250
+ ): value is DerivedCollection<T, U> => isObjectOfType(value, TYPE_COLLECTION)
242
251
 
243
252
  /**
244
253
  * Check if a value is a collection source
@@ -264,9 +273,10 @@ const isAsyncCollectionCallback = <T extends {}>(
264
273
  isAsyncFunction(callback)
265
274
 
266
275
  export {
267
- Collection,
276
+ type Collection,
268
277
  type CollectionSource,
269
278
  type CollectionCallback,
279
+ DerivedCollection,
270
280
  isCollection,
271
281
  TYPE_COLLECTION,
272
282
  }
@@ -1,6 +1,7 @@
1
1
  import { isEqual } from '../diff'
2
2
  import {
3
3
  CircularDependencyError,
4
+ createError,
4
5
  validateCallback,
5
6
  validateSignalValue,
6
7
  } from '../errors'
@@ -17,7 +18,6 @@ import {
17
18
  isAsyncFunction,
18
19
  isObjectOfType,
19
20
  isSyncFunction,
20
- toError,
21
21
  UNSET,
22
22
  } from '../util'
23
23
 
@@ -104,7 +104,7 @@ class Memo<T extends {}> {
104
104
  } catch (e) {
105
105
  // Err track
106
106
  this.#value = UNSET
107
- this.#error = toError(e)
107
+ this.#error = createError(e)
108
108
  this.#computing = false
109
109
  return
110
110
  }
@@ -201,7 +201,7 @@ class Task<T extends {}> {
201
201
  this.#error = undefined
202
202
  }
203
203
  const err = (e: unknown): undefined => {
204
- const newError = toError(e)
204
+ const newError = createError(e)
205
205
  this.#changed =
206
206
  !this.#error ||
207
207
  newError.name !== this.#error.name ||
@@ -11,7 +11,7 @@ import {
11
11
  type Watcher,
12
12
  } from '../system'
13
13
  import { isFunction, isNumber, isObjectOfType, isString, UNSET } from '../util'
14
- import { Collection, type CollectionCallback } from './collection'
14
+ import { type CollectionCallback, DerivedCollection } from './collection'
15
15
  import { Composite } from './composite'
16
16
  import { State } from './state'
17
17
 
@@ -87,7 +87,7 @@ class List<T extends {}> {
87
87
  return TYPE_LIST
88
88
  }
89
89
 
90
- get [Symbol.isConcatSpreadable](): boolean {
90
+ get [Symbol.isConcatSpreadable](): true {
91
91
  return true
92
92
  }
93
93
 
@@ -261,8 +261,9 @@ class List<T extends {}> {
261
261
  on<K extends keyof Notifications>(type: K, listener: Listener<K>): Cleanup {
262
262
  if (type === 'sort') {
263
263
  this.#listeners.sort.add(listener as Listener<'sort'>)
264
- return () =>
264
+ return () => {
265
265
  this.#listeners.sort.delete(listener as Listener<'sort'>)
266
+ }
266
267
  }
267
268
 
268
269
  // For other types, delegate to the composite
@@ -276,14 +277,14 @@ class List<T extends {}> {
276
277
 
277
278
  deriveCollection<R extends {}>(
278
279
  callback: (sourceValue: T) => R,
279
- ): Collection<R, T>
280
+ ): DerivedCollection<R, T>
280
281
  deriveCollection<R extends {}>(
281
282
  callback: (sourceValue: T, abort: AbortSignal) => Promise<R>,
282
- ): Collection<R, T>
283
+ ): DerivedCollection<R, T>
283
284
  deriveCollection<R extends {}>(
284
285
  callback: CollectionCallback<R, T>,
285
- ): Collection<R, T> {
286
- return new Collection(this, callback)
286
+ ): DerivedCollection<R, T> {
287
+ return new DerivedCollection(this, callback)
287
288
  }
288
289
  }
289
290