@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.
- package/.ai-context.md +19 -5
- package/.cursorrules +8 -3
- package/.github/copilot-instructions.md +9 -4
- package/CLAUDE.md +96 -262
- package/README.md +232 -421
- package/archive/computed.ts +2 -2
- package/archive/memo.ts +3 -2
- package/archive/task.ts +2 -2
- package/index.dev.js +59 -26
- package/index.js +1 -1
- package/index.ts +11 -3
- package/package.json +1 -1
- package/src/classes/collection.ts +38 -28
- package/src/classes/computed.ts +3 -3
- package/src/classes/list.ts +8 -7
- package/src/classes/ref.ts +68 -0
- package/src/errors.ts +21 -0
- package/src/match.ts +5 -12
- package/src/resolve.ts +3 -2
- package/src/util.ts +0 -4
- package/test/collection.test.ts +104 -47
- package/test/ref.test.ts +227 -0
- package/types/index.d.ts +5 -4
- package/types/src/classes/collection.d.ts +21 -7
- package/types/src/classes/list.d.ts +4 -4
- package/types/src/classes/ref.d.ts +39 -0
- package/types/src/errors.d.ts +6 -1
- package/types/src/util.d.ts +1 -2
package/archive/computed.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'
|
|
@@ -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 =
|
|
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,
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 () =>
|
|
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
|
|
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
|
|
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
|
|
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.#
|
|
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.#
|
|
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
|
|
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 (
|
|
1070
|
-
|
|
1071
|
-
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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,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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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]():
|
|
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.#
|
|
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
|
-
):
|
|
228
|
+
): DerivedCollection<R, T>
|
|
220
229
|
deriveCollection<R extends {}>(
|
|
221
230
|
callback: (sourceValue: T, abort: AbortSignal) => Promise<R>,
|
|
222
|
-
):
|
|
231
|
+
): DerivedCollection<R, T>
|
|
223
232
|
deriveCollection<R extends {}>(
|
|
224
233
|
callback: CollectionCallback<R, T>,
|
|
225
|
-
):
|
|
226
|
-
return new
|
|
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
|
|
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
|
}
|
package/src/classes/computed.ts
CHANGED
|
@@ -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 =
|
|
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 =
|
|
204
|
+
const newError = createError(e)
|
|
205
205
|
this.#changed =
|
|
206
206
|
!this.#error ||
|
|
207
207
|
newError.name !== this.#error.name ||
|
package/src/classes/list.ts
CHANGED
|
@@ -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 {
|
|
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]():
|
|
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
|
-
):
|
|
280
|
+
): DerivedCollection<R, T>
|
|
280
281
|
deriveCollection<R extends {}>(
|
|
281
282
|
callback: (sourceValue: T, abort: AbortSignal) => Promise<R>,
|
|
282
|
-
):
|
|
283
|
+
): DerivedCollection<R, T>
|
|
283
284
|
deriveCollection<R extends {}>(
|
|
284
285
|
callback: CollectionCallback<R, T>,
|
|
285
|
-
):
|
|
286
|
-
return new
|
|
286
|
+
): DerivedCollection<R, T> {
|
|
287
|
+
return new DerivedCollection(this, callback)
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
|