@oscarpalmer/mora 0.29.0 → 0.31.0
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/dist/batch.mjs +15 -6
- package/dist/constants.d.mts +2 -2
- package/dist/constants.mjs +7 -4
- package/dist/effect.d.mts +5 -18
- package/dist/effect.mjs +23 -19
- package/dist/helpers/is.d.mts +17 -16
- package/dist/helpers/is.mjs +20 -11
- package/dist/helpers/proxy.d.mts +5 -9
- package/dist/helpers/proxy.mjs +4 -4
- package/dist/helpers/value.d.mts +3 -3
- package/dist/helpers/value.mjs +22 -5
- package/dist/index.d.mts +8 -9
- package/dist/index.mjs +2 -2
- package/dist/models.d.mts +423 -19
- package/dist/mora.full.mjs +532 -424
- package/dist/subscription.d.mts +1 -9
- package/dist/subscription.mjs +14 -15
- package/dist/value/array.d.mts +5 -133
- package/dist/value/array.mjs +108 -138
- package/dist/value/computed.d.mts +4 -12
- package/dist/value/computed.mjs +54 -50
- package/dist/value/reactive.d.mts +3 -49
- package/dist/value/reactive.mjs +10 -54
- package/dist/value/readonly.d.mts +7 -0
- package/dist/value/readonly.mjs +37 -0
- package/dist/value/signal.d.mts +5 -21
- package/dist/value/signal.mjs +33 -49
- package/dist/value/store.d.mts +9 -92
- package/dist/value/store.mjs +58 -49
- package/package.json +7 -8
- package/src/batch.ts +22 -9
- package/src/constants.ts +12 -5
- package/src/effect.ts +35 -40
- package/src/helpers/is.ts +36 -20
- package/src/helpers/proxy.ts +23 -18
- package/src/helpers/value.ts +39 -5
- package/src/index.ts +23 -8
- package/src/models.ts +520 -17
- package/src/subscription.ts +20 -20
- package/src/value/array.ts +220 -266
- package/src/value/computed.ts +80 -74
- package/src/value/reactive.ts +16 -77
- package/src/value/readonly.ts +71 -0
- package/src/value/signal.ts +43 -71
- package/src/value/store.ts +130 -177
- package/types/constants.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/value/array.d.ts +1 -1
- package/types/value/computed.d.ts +3 -0
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
package/dist/mora.full.mjs
CHANGED
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
const ACTIVE = {};
|
|
3
3
|
const BATCH = {
|
|
4
4
|
depth: 0,
|
|
5
|
+
flushing: false,
|
|
5
6
|
handlers: /* @__PURE__ */ new Set()
|
|
6
7
|
};
|
|
7
|
-
const METHODS_AFFECTING_LENGTH = new Set([
|
|
8
|
+
const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
|
|
8
9
|
"pop",
|
|
9
10
|
"push",
|
|
10
11
|
"shift",
|
|
11
12
|
"unshift"
|
|
12
13
|
]);
|
|
13
|
-
const METHODS_UPDATE = new Set([
|
|
14
|
+
const METHODS_UPDATE = /* @__PURE__ */ new Set([
|
|
14
15
|
...METHODS_AFFECTING_LENGTH,
|
|
15
16
|
"copyWithin",
|
|
16
17
|
"fill",
|
|
@@ -22,52 +23,86 @@ const NAME_ARRAY = "array";
|
|
|
22
23
|
const NAME_COMPUTED = "computed";
|
|
23
24
|
const NAME_EFFECT = "effect";
|
|
24
25
|
const NAME_MORA = "$mora";
|
|
26
|
+
const NAME_READONLY = "readonly";
|
|
25
27
|
const NAME_SIGNAL = "signal";
|
|
26
28
|
const NAME_STORE = "store";
|
|
27
|
-
const NAME_ALL = new Set([
|
|
29
|
+
const NAME_ALL = /* @__PURE__ */ new Set([
|
|
28
30
|
NAME_ARRAY,
|
|
29
31
|
NAME_COMPUTED,
|
|
32
|
+
NAME_READONLY,
|
|
30
33
|
NAME_SIGNAL,
|
|
31
34
|
NAME_STORE
|
|
32
35
|
]);
|
|
33
36
|
//#endregion
|
|
34
37
|
//#region src/effect.ts
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
function
|
|
38
|
+
/**
|
|
39
|
+
* Create an effect
|
|
40
|
+
*
|
|
41
|
+
* @param callback Callback for handling signal effects
|
|
42
|
+
* @returns Effect
|
|
43
|
+
*/
|
|
44
|
+
function effect(callback) {
|
|
45
|
+
if (typeof callback !== "function") throw new TypeError("Effect callback must be a function");
|
|
46
|
+
return getEffect(callback)[0];
|
|
47
|
+
}
|
|
48
|
+
function getEffect(callback) {
|
|
49
|
+
const state = { callback };
|
|
50
|
+
const instance = Object.freeze({ $mora: NAME_EFFECT });
|
|
51
|
+
runEffect(state);
|
|
52
|
+
return [instance, state];
|
|
53
|
+
}
|
|
54
|
+
function internalEffect(callback) {
|
|
55
|
+
return getEffect(callback)[1];
|
|
56
|
+
}
|
|
57
|
+
function runEffect(state) {
|
|
43
58
|
const previousEffect = ACTIVE.effect;
|
|
44
|
-
ACTIVE.effect =
|
|
59
|
+
ACTIVE.effect = state;
|
|
45
60
|
try {
|
|
46
|
-
|
|
61
|
+
state.callback();
|
|
47
62
|
} finally {
|
|
48
63
|
ACTIVE.effect = previousEffect;
|
|
49
64
|
}
|
|
50
65
|
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/batch.ts
|
|
68
|
+
function flushHandlers() {
|
|
69
|
+
if (BATCH.flushing) return;
|
|
70
|
+
BATCH.flushing = true;
|
|
71
|
+
try {
|
|
72
|
+
while (BATCH.depth === 0 && BATCH.handlers.size > 0) {
|
|
73
|
+
const handlers = [...BATCH.handlers];
|
|
74
|
+
const { length } = handlers;
|
|
75
|
+
BATCH.handlers.clear();
|
|
76
|
+
for (let index = 0; index < length; index += 1) {
|
|
77
|
+
const handler = handlers[index];
|
|
78
|
+
if (typeof handler.destroy === "function") handler.callback(handler.state.value);
|
|
79
|
+
else runEffect(handler);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} finally {
|
|
83
|
+
BATCH.flushing = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
51
86
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* @
|
|
87
|
+
* Start batching effects
|
|
88
|
+
*
|
|
89
|
+
* _(Use {@link stopBatch} to flush and run batched effects)_
|
|
55
90
|
*/
|
|
56
|
-
function
|
|
57
|
-
|
|
91
|
+
function startBatch() {
|
|
92
|
+
BATCH.depth += 1;
|
|
58
93
|
}
|
|
59
|
-
//#endregion
|
|
60
|
-
//#region src/helpers/is.ts
|
|
61
94
|
/**
|
|
62
|
-
*
|
|
63
|
-
* @param value Value to check
|
|
64
|
-
* @returns True if value is a {@link ReactiveArray}
|
|
95
|
+
* Stop batching effects and flush _(run)_ them
|
|
65
96
|
*/
|
|
66
|
-
function
|
|
67
|
-
|
|
97
|
+
function stopBatch() {
|
|
98
|
+
if (BATCH.depth > 0) BATCH.depth -= 1;
|
|
99
|
+
flushHandlers();
|
|
68
100
|
}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/helpers/is.ts
|
|
69
103
|
/**
|
|
70
104
|
* Is the value a computed signal?
|
|
105
|
+
*
|
|
71
106
|
* @param value Value to check
|
|
72
107
|
* @returns True if value is a {@link Computed}
|
|
73
108
|
*/
|
|
@@ -76,6 +111,7 @@ function isComputed(value) {
|
|
|
76
111
|
}
|
|
77
112
|
/**
|
|
78
113
|
* Is the value an effect?
|
|
114
|
+
*
|
|
79
115
|
* @param value Value to check
|
|
80
116
|
* @returns True if value is an {@link Effect}
|
|
81
117
|
*/
|
|
@@ -87,6 +123,7 @@ function isMora(value, name) {
|
|
|
87
123
|
}
|
|
88
124
|
/**
|
|
89
125
|
* Is the value reactive?
|
|
126
|
+
*
|
|
90
127
|
* @param value Value to check
|
|
91
128
|
* @returns True if value is a {@link Reactive}
|
|
92
129
|
*/
|
|
@@ -95,196 +132,143 @@ function isReactive(value) {
|
|
|
95
132
|
}
|
|
96
133
|
/**
|
|
97
134
|
* Is the value a signal?
|
|
135
|
+
*
|
|
98
136
|
* @param value Value to check
|
|
99
137
|
* @returns True if value is a {@link Signal}
|
|
100
138
|
*/
|
|
101
139
|
function isSignal(value) {
|
|
102
140
|
return isMora(value, NAME_SIGNAL);
|
|
103
141
|
}
|
|
104
|
-
//#endregion
|
|
105
|
-
//#region src/batch.ts
|
|
106
|
-
function flushHandlers() {
|
|
107
|
-
while (BATCH.depth === 0 && BATCH.handlers.size > 0) {
|
|
108
|
-
const handlers = [...BATCH.handlers];
|
|
109
|
-
BATCH.handlers.clear();
|
|
110
|
-
for (const handler of handlers) if (isEffect(handler)) runEffect(handler);
|
|
111
|
-
else handler.callback(handler.state.value);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
142
|
/**
|
|
115
|
-
*
|
|
143
|
+
* Is the value a reactive array?
|
|
116
144
|
*
|
|
117
|
-
*
|
|
145
|
+
* @param value Value to check
|
|
146
|
+
* @returns True if value is a {@link ReactiveArray}
|
|
118
147
|
*/
|
|
119
|
-
function
|
|
120
|
-
|
|
148
|
+
function isReactiveArray(value) {
|
|
149
|
+
return isMora(value, NAME_ARRAY);
|
|
121
150
|
}
|
|
122
151
|
/**
|
|
123
|
-
*
|
|
152
|
+
* Is the value a reactive store?
|
|
153
|
+
*
|
|
154
|
+
* @param value Value to check
|
|
155
|
+
* @returns True if value is a {@link Store}
|
|
124
156
|
*/
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
157
|
+
function isReactiveStore(value) {
|
|
158
|
+
return isMora(value, NAME_STORE);
|
|
159
|
+
}
|
|
160
|
+
function isReadonlySignal(value) {
|
|
161
|
+
return isMora(value, NAME_READONLY);
|
|
128
162
|
}
|
|
129
163
|
//#endregion
|
|
130
|
-
//#region
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
};
|
|
144
|
-
function noop() {}
|
|
145
|
-
function subscribe(state, callback) {
|
|
146
|
-
if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
|
|
147
|
-
state.subscriptions.set(callback, new Subscription(state, callback));
|
|
148
|
-
return () => {
|
|
149
|
-
unsubscribe(state, callback);
|
|
164
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
|
|
165
|
+
function getArrayCallback(value) {
|
|
166
|
+
switch (typeof value) {
|
|
167
|
+
case "function": return value;
|
|
168
|
+
case "number":
|
|
169
|
+
case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function getArrayCallbacks(bool, key, value) {
|
|
173
|
+
if (typeof bool === "function") return { bool };
|
|
174
|
+
return {
|
|
175
|
+
keyed: getArrayCallback(key),
|
|
176
|
+
value: getArrayCallback(value)
|
|
150
177
|
};
|
|
151
178
|
}
|
|
152
|
-
function unsubscribe(state, callback) {
|
|
153
|
-
state.subscriptions.get(callback)?.destroy();
|
|
154
|
-
state.subscriptions.delete(callback);
|
|
155
|
-
}
|
|
156
179
|
//#endregion
|
|
157
|
-
//#region
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
* @return Current value
|
|
179
|
-
*/
|
|
180
|
-
peek() {
|
|
181
|
-
return this.state.value;
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Subscribe to changes
|
|
185
|
-
* @param callback Callback for changes
|
|
186
|
-
* @return Unsubscribe callback
|
|
187
|
-
*/
|
|
188
|
-
subscribe(callback) {
|
|
189
|
-
return subscribe(this.state, callback);
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* JSON representation of the value
|
|
193
|
-
* @return JSON value
|
|
194
|
-
*/
|
|
195
|
-
toJSON() {
|
|
196
|
-
return this.get();
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* String representation of the value
|
|
200
|
-
* @return Value as string
|
|
201
|
-
*/
|
|
202
|
-
toString() {
|
|
203
|
-
return String(this.get());
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Unsubscribe from changes
|
|
207
|
-
* @param callback Callback to unsubscribe
|
|
208
|
-
*/
|
|
209
|
-
unsubscribe(callback) {
|
|
210
|
-
unsubscribe(this.state, callback);
|
|
180
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
|
|
181
|
+
function findValue(type, array, parameters, reversed) {
|
|
182
|
+
const findIndex = type === FIND_VALUE_INDEX;
|
|
183
|
+
if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
|
|
184
|
+
const { bool, key, value } = getFindParameters(parameters);
|
|
185
|
+
const callbacks = getArrayCallbacks(bool, key);
|
|
186
|
+
if (callbacks?.bool == null && callbacks?.keyed == null) {
|
|
187
|
+
if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
|
|
188
|
+
return reversed ? array.findLast((item) => Object.is(item, value)) : array.find((item) => Object.is(item, value));
|
|
189
|
+
}
|
|
190
|
+
if (callbacks.bool != null) {
|
|
191
|
+
const index = reversed ? array.findLastIndex(callbacks.bool) : array.findIndex(callbacks.bool);
|
|
192
|
+
return findIndex ? index : array[index];
|
|
193
|
+
}
|
|
194
|
+
return findValueInArray(array, callbacks.keyed, value, findIndex, reversed);
|
|
195
|
+
}
|
|
196
|
+
function findValueInArray(array, callback, value, findIndex, reversed) {
|
|
197
|
+
const { length } = array;
|
|
198
|
+
for (let index = 0; index < length; index += 1) {
|
|
199
|
+
const item = reversed ? array.at(-(index + 1)) : array[index];
|
|
200
|
+
if (Object.is(callback?.(item, index, array), value)) return findIndex ? index : item;
|
|
211
201
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
instance: void 0
|
|
202
|
+
return findIndex ? -1 : void 0;
|
|
203
|
+
}
|
|
204
|
+
function findValues(type, array, parameters, mapper) {
|
|
205
|
+
const result = {
|
|
206
|
+
matched: [],
|
|
207
|
+
notMatched: []
|
|
219
208
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
});
|
|
209
|
+
if (!Array.isArray(array) || array.length === 0) return result;
|
|
210
|
+
const { length } = array;
|
|
211
|
+
const { bool, key, value } = getFindParameters(parameters);
|
|
212
|
+
const callbacks = getArrayCallbacks(bool, key);
|
|
213
|
+
if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
|
|
214
|
+
result.matched = [...new Set(array)];
|
|
215
|
+
return result;
|
|
228
216
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
217
|
+
const mapCallback = getArrayCallback(mapper);
|
|
218
|
+
if (callbacks?.bool != null || type === "all" && key == null) {
|
|
219
|
+
const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
|
|
220
|
+
for (let index = 0; index < length; index += 1) {
|
|
221
|
+
const item = array[index];
|
|
222
|
+
if (callback(item, index, array)) result.matched.push(mapCallback?.(item, index, array) ?? item);
|
|
223
|
+
else result.notMatched.push(item);
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
237
226
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
227
|
+
const keys = /* @__PURE__ */ new Set();
|
|
228
|
+
for (let index = 0; index < length; index += 1) {
|
|
229
|
+
const item = array[index];
|
|
230
|
+
const keyed = callbacks?.keyed?.(item, index, array) ?? item;
|
|
231
|
+
if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
|
|
232
|
+
keys.add(keyed);
|
|
233
|
+
result.matched.push(mapCallback?.(item, index, array) ?? item);
|
|
234
|
+
} else result.notMatched.push(item);
|
|
235
|
+
}
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
function getFindParameters(original) {
|
|
239
|
+
const { length } = original;
|
|
240
|
+
return {
|
|
241
|
+
bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
|
|
242
|
+
key: length === 2 ? original[0] : void 0,
|
|
243
|
+
value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
|
|
244
|
+
};
|
|
247
245
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
246
|
+
const FIND_VALUE_INDEX = "index";
|
|
247
|
+
const FIND_VALUE_ITEM = "item";
|
|
248
|
+
const UNIQUE_THRESHOLD = 100;
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/index-of.mjs
|
|
251
|
+
function indexOf(array, ...parameters) {
|
|
252
|
+
return findValue(FIND_VALUE_INDEX, array, parameters, false);
|
|
255
253
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
try {
|
|
260
|
-
const value = callback();
|
|
261
|
-
if (value instanceof Promise) {
|
|
262
|
-
state.promise = value;
|
|
263
|
-
value.then((resolvedValue) => {
|
|
264
|
-
if (state.promise === value) {
|
|
265
|
-
state.promise = void 0;
|
|
266
|
-
setAndEmit$1(state, resolvedValue);
|
|
267
|
-
}
|
|
268
|
-
}).catch(() => {
|
|
269
|
-
if (state.promise === value) state.promise = void 0;
|
|
270
|
-
});
|
|
271
|
-
} else setAndEmit$1(state, value);
|
|
272
|
-
} finally {
|
|
273
|
-
ACTIVE.computed = previousComputed;
|
|
274
|
-
}
|
|
254
|
+
indexOf.last = lastIndexOf;
|
|
255
|
+
function lastIndexOf(array, ...parameters) {
|
|
256
|
+
return findValue(FIND_VALUE_INDEX, array, parameters, true);
|
|
275
257
|
}
|
|
276
258
|
//#endregion
|
|
277
259
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
278
260
|
/**
|
|
279
|
-
* Is the value a
|
|
261
|
+
* Is the value a _Key_?
|
|
262
|
+
*
|
|
280
263
|
* @param value Value to check
|
|
281
|
-
* @returns `true` if the value is a
|
|
264
|
+
* @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
|
|
282
265
|
*/
|
|
283
266
|
function isKey(value) {
|
|
284
267
|
return typeof value === "number" || typeof value === "string";
|
|
285
268
|
}
|
|
286
269
|
/**
|
|
287
270
|
* Is the value a plain object?
|
|
271
|
+
*
|
|
288
272
|
* @param value Value to check
|
|
289
273
|
* @returns `true` if the value is a plain object, otherwise `false`
|
|
290
274
|
*/
|
|
@@ -295,26 +279,38 @@ function isPlainObject(value) {
|
|
|
295
279
|
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
296
280
|
}
|
|
297
281
|
//#endregion
|
|
298
|
-
//#region node_modules/@oscarpalmer/atoms/dist/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
* @param value Number to round
|
|
302
|
-
* @param decimals Number of decimal places to round to _(defaults to `0`)_
|
|
303
|
-
* @returns Rounded number, or `NaN` if the value if unable to be rounded
|
|
304
|
-
*/
|
|
305
|
-
function round(value, decimals) {
|
|
306
|
-
return roundNumber(Math.round, value, decimals);
|
|
282
|
+
//#region node_modules/@oscarpalmer/atoms/dist/array/find.mjs
|
|
283
|
+
function find(array, ...parameters) {
|
|
284
|
+
return findValue(FIND_VALUE_ITEM, array, parameters, false);
|
|
307
285
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
286
|
+
find.last = findLast;
|
|
287
|
+
function findLast(array, ...parameters) {
|
|
288
|
+
return findValue(FIND_VALUE_ITEM, array, parameters, true);
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
|
|
292
|
+
function select(array, ...parameters) {
|
|
293
|
+
return findValues("all", array, parameters, parameters.pop()).matched;
|
|
313
294
|
}
|
|
314
295
|
//#endregion
|
|
296
|
+
//#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
|
|
297
|
+
function exclude(array, ...parameters) {
|
|
298
|
+
return findValues("all", array, parameters).notMatched;
|
|
299
|
+
}
|
|
300
|
+
function filter(array, ...parameters) {
|
|
301
|
+
return findValues("all", array, parameters).matched;
|
|
302
|
+
}
|
|
303
|
+
filter.remove = exclude;
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
306
|
+
/**
|
|
307
|
+
* A function that does nothing, which can be useful, I guess…
|
|
308
|
+
*/
|
|
309
|
+
function noop$1() {}
|
|
310
|
+
//#endregion
|
|
315
311
|
//#region src/helpers/value.ts
|
|
316
312
|
function emitValue(state) {
|
|
317
|
-
for (const computed of state.computeds) computed.
|
|
313
|
+
for (const computed of state.computeds) computed.dirty = true;
|
|
318
314
|
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
319
315
|
for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
|
|
320
316
|
if (BATCH.depth === 0) flushHandlers();
|
|
@@ -324,7 +320,7 @@ function equalArrays(state, first, second) {
|
|
|
324
320
|
if (length !== second.length) return false;
|
|
325
321
|
let offset = 0;
|
|
326
322
|
if (length >= 100) {
|
|
327
|
-
offset = round(length / 10);
|
|
323
|
+
offset = Math.round(length / 10);
|
|
328
324
|
offset = offset > 25 ? 25 : offset;
|
|
329
325
|
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
330
326
|
}
|
|
@@ -332,26 +328,150 @@ function equalArrays(state, first, second) {
|
|
|
332
328
|
for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
333
329
|
return true;
|
|
334
330
|
}
|
|
335
|
-
function
|
|
331
|
+
function getSimpleValue(state) {
|
|
336
332
|
if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
|
|
337
333
|
if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
|
|
338
334
|
return state.value;
|
|
339
335
|
}
|
|
336
|
+
function handleSimpleValue(state, origin, setValue, onAfter) {
|
|
337
|
+
try {
|
|
338
|
+
let actual = typeof origin === "function" ? origin() : origin;
|
|
339
|
+
if (actual instanceof Promise) {
|
|
340
|
+
state.promise = actual;
|
|
341
|
+
actual.then((value) => {
|
|
342
|
+
if (actual === state.promise) {
|
|
343
|
+
state.promise = void 0;
|
|
344
|
+
setValue(state, value);
|
|
345
|
+
}
|
|
346
|
+
}).catch(() => {
|
|
347
|
+
if (actual === state.promise) state.promise = void 0;
|
|
348
|
+
});
|
|
349
|
+
} else setValue(state, actual);
|
|
350
|
+
} catch {} finally {
|
|
351
|
+
onAfter?.();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region src/subscription.ts
|
|
356
|
+
function noop() {}
|
|
357
|
+
function subscribe(state, callback) {
|
|
358
|
+
if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
|
|
359
|
+
state.subscriptions.set(callback, subscription(state, callback));
|
|
360
|
+
return () => {
|
|
361
|
+
unsubscribe(state, callback);
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
function subscription(state, callback) {
|
|
365
|
+
const instance = {
|
|
366
|
+
callback,
|
|
367
|
+
state,
|
|
368
|
+
destroy: () => {
|
|
369
|
+
instance.callback = noop;
|
|
370
|
+
instance.state = void 0;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
callback(state.value);
|
|
374
|
+
return instance;
|
|
375
|
+
}
|
|
376
|
+
function unsubscribe(state, callback) {
|
|
377
|
+
state.subscriptions.get(callback)?.destroy();
|
|
378
|
+
state.subscriptions.delete(callback);
|
|
379
|
+
}
|
|
380
|
+
//#endregion
|
|
381
|
+
//#region src/value/reactive.ts
|
|
382
|
+
function reactive(value, options) {
|
|
383
|
+
const state = {
|
|
384
|
+
computeds: /* @__PURE__ */ new Set(),
|
|
385
|
+
effects: /* @__PURE__ */ new Set(),
|
|
386
|
+
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
|
|
387
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
388
|
+
value
|
|
389
|
+
};
|
|
390
|
+
return [{
|
|
391
|
+
toJSON: () => state.value,
|
|
392
|
+
toString: () => String(state.value)
|
|
393
|
+
}, state];
|
|
394
|
+
}
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/value/computed.ts
|
|
397
|
+
/**
|
|
398
|
+
* Create a computed value
|
|
399
|
+
*
|
|
400
|
+
* @param callback Callback to compute the value
|
|
401
|
+
* @param options Reactivity options
|
|
402
|
+
* @returns Computed value
|
|
403
|
+
*/
|
|
404
|
+
function computed(callback, options) {
|
|
405
|
+
return getComputed(callback, options)[0];
|
|
406
|
+
}
|
|
407
|
+
function getComputed(callback, options) {
|
|
408
|
+
const [rx, state] = reactive(void 0, options);
|
|
409
|
+
let fx;
|
|
410
|
+
const instance = {
|
|
411
|
+
...rx,
|
|
412
|
+
get: () => getValue(state, fx),
|
|
413
|
+
peek: () => state.value,
|
|
414
|
+
subscribe: (callback) => subscribe(state, callback),
|
|
415
|
+
unsubscribe: (callback) => {
|
|
416
|
+
state.subscriptions.delete(callback);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
Object.defineProperty(instance, NAME_MORA, {
|
|
420
|
+
enumerable: false,
|
|
421
|
+
value: NAME_COMPUTED
|
|
422
|
+
});
|
|
423
|
+
fx = getComputedEffect(state, callback);
|
|
424
|
+
return [Object.freeze(instance), fx];
|
|
425
|
+
}
|
|
426
|
+
function getComputedEffect(state, callback) {
|
|
427
|
+
const fx = {
|
|
428
|
+
dirty: true,
|
|
429
|
+
instance: void 0
|
|
430
|
+
};
|
|
431
|
+
fx.instance = internalEffect(() => {
|
|
432
|
+
if (fx.dirty) {
|
|
433
|
+
const previousComputed = ACTIVE.computed;
|
|
434
|
+
ACTIVE.computed = fx;
|
|
435
|
+
handleSimpleValue(state, callback, setAndEmit$1, () => {
|
|
436
|
+
ACTIVE.computed = previousComputed;
|
|
437
|
+
});
|
|
438
|
+
fx.dirty = false;
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
return fx;
|
|
442
|
+
}
|
|
443
|
+
function getValue(state, fx) {
|
|
444
|
+
if (ACTIVE.computed != null && fx !== ACTIVE.computed) state.computeds.add(ACTIVE.computed);
|
|
445
|
+
if (ACTIVE.effect != null && ACTIVE.effect !== fx.instance) state.effects.add(ACTIVE.effect);
|
|
446
|
+
if (fx.dirty && BATCH.depth === 0) runEffect(fx.instance);
|
|
447
|
+
return state.value;
|
|
448
|
+
}
|
|
449
|
+
function internalComputed(callback, options) {
|
|
450
|
+
return getComputed(callback, options);
|
|
451
|
+
}
|
|
452
|
+
function setAndEmit$1(state, value) {
|
|
453
|
+
if (state.equal(state.value, value)) return;
|
|
454
|
+
state.value = value;
|
|
455
|
+
for (const computed of state.computeds) computed.dirty = true;
|
|
456
|
+
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
457
|
+
for (const [, subscription] of state.subscriptions) subscription.callback(value);
|
|
458
|
+
flushHandlers();
|
|
459
|
+
}
|
|
340
460
|
//#endregion
|
|
341
461
|
//#region src/helpers/proxy.ts
|
|
342
462
|
function emityProxyValues(state, mapped) {
|
|
343
463
|
const values = [...mapped.values()];
|
|
344
464
|
const { length } = values;
|
|
345
|
-
for (let index = 0; index < length; index += 1) values[index].
|
|
465
|
+
for (let index = 0; index < length; index += 1) values[index][1].dirty = true;
|
|
346
466
|
emitValue(state);
|
|
347
467
|
}
|
|
348
468
|
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
349
469
|
let item = mapped.get(key);
|
|
350
470
|
if (item == null) {
|
|
351
|
-
item =
|
|
471
|
+
item = internalComputed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
|
|
352
472
|
mapped.set(key, item);
|
|
353
473
|
}
|
|
354
|
-
return item;
|
|
474
|
+
return item[0];
|
|
355
475
|
}
|
|
356
476
|
function setProxyValue(array, state, isObject, isProperty, setObject, setProperty, first, second) {
|
|
357
477
|
if (array && first === "length") {
|
|
@@ -406,190 +526,153 @@ function setValueInProxy(parameters) {
|
|
|
406
526
|
return true;
|
|
407
527
|
}
|
|
408
528
|
//#endregion
|
|
529
|
+
//#region src/value/readonly.ts
|
|
530
|
+
function getReadonlyInstance(state, instances, handlers, frozen) {
|
|
531
|
+
const key = frozen ? "frozen" : "original";
|
|
532
|
+
instances[key] ??= getReadonlySignal(state, handlers, frozen);
|
|
533
|
+
return instances[key];
|
|
534
|
+
}
|
|
535
|
+
function getReadonlySignal(state, handlers, frozen) {
|
|
536
|
+
const instance = {
|
|
537
|
+
...handlers,
|
|
538
|
+
get: () => getReadonlyValue(state, false, frozen),
|
|
539
|
+
peek: () => getReadonlyValue(state, true, frozen)
|
|
540
|
+
};
|
|
541
|
+
Object.defineProperties(instance, {
|
|
542
|
+
[NAME_MORA]: {
|
|
543
|
+
enumerable: false,
|
|
544
|
+
value: NAME_READONLY
|
|
545
|
+
},
|
|
546
|
+
frozen: {
|
|
547
|
+
enumerable: true,
|
|
548
|
+
value: frozen
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
return Object.freeze(instance);
|
|
552
|
+
}
|
|
553
|
+
function getReadonlyValue(state, peek, frozen) {
|
|
554
|
+
let value = peek ? state.value : getSimpleValue(state);
|
|
555
|
+
if (!frozen) return value;
|
|
556
|
+
if (Array.isArray(state.value)) value = [...state.value];
|
|
557
|
+
else if (isPlainObject(state.value)) value = { ...state.value };
|
|
558
|
+
else value = state.value;
|
|
559
|
+
return Object.freeze(value);
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
409
562
|
//#region src/value/signal.ts
|
|
410
|
-
var Signal = class extends Reactive {
|
|
411
|
-
constructor(value, options) {
|
|
412
|
-
super(NAME_SIGNAL, value, options);
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* @inheritdoc
|
|
416
|
-
*/
|
|
417
|
-
get() {
|
|
418
|
-
return getValue(this.state);
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Set the value
|
|
422
|
-
* @param value New value
|
|
423
|
-
*/
|
|
424
|
-
set(value) {
|
|
425
|
-
setValue(this.state, value);
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Update the value _(based on the current value)_
|
|
429
|
-
* @param callback Callback to update the value
|
|
430
|
-
*/
|
|
431
|
-
update(callback) {
|
|
432
|
-
this.set(callback(this.state.value));
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
563
|
function setAndEmit(state, value) {
|
|
436
564
|
if (!state.equal(state.value, value)) {
|
|
437
565
|
state.value = value;
|
|
438
566
|
emitValue(state);
|
|
439
567
|
}
|
|
440
568
|
}
|
|
441
|
-
function setValue(state, value) {
|
|
442
|
-
try {
|
|
443
|
-
let actual = value;
|
|
444
|
-
if (typeof value === "function") actual = value();
|
|
445
|
-
if (actual instanceof Promise) {
|
|
446
|
-
state.promise = actual;
|
|
447
|
-
actual.then((value) => {
|
|
448
|
-
if (actual === state.promise) {
|
|
449
|
-
state.promise = void 0;
|
|
450
|
-
setAndEmit(state, value);
|
|
451
|
-
}
|
|
452
|
-
}).catch(() => {
|
|
453
|
-
if (actual === state.promise) state.promise = void 0;
|
|
454
|
-
});
|
|
455
|
-
} else setAndEmit(state, actual);
|
|
456
|
-
} catch {}
|
|
457
|
-
}
|
|
458
569
|
function signal(value, options) {
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
570
|
+
const [rx, state] = reactive(void 0, options);
|
|
571
|
+
const readonlies = {};
|
|
572
|
+
const handlers = {
|
|
573
|
+
...rx,
|
|
574
|
+
subscribe: (callback) => subscribe(state, callback),
|
|
575
|
+
unsubscribe: (callback) => {
|
|
576
|
+
state.subscriptions.delete(callback);
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
const instance = {
|
|
580
|
+
...handlers,
|
|
581
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
|
|
582
|
+
get: () => getSimpleValue(state),
|
|
583
|
+
peek: () => state.value,
|
|
584
|
+
set: (value) => {
|
|
585
|
+
handleSimpleValue(state, value, setAndEmit);
|
|
586
|
+
},
|
|
587
|
+
update: (callback) => {
|
|
588
|
+
handleSimpleValue(state, callback(state.value), setAndEmit);
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
Object.defineProperty(instance, NAME_MORA, {
|
|
592
|
+
enumerable: false,
|
|
593
|
+
value: NAME_SIGNAL
|
|
594
|
+
});
|
|
595
|
+
handleSimpleValue(state, value, setAndEmit);
|
|
596
|
+
return Object.freeze(instance);
|
|
462
597
|
}
|
|
463
598
|
//#endregion
|
|
464
599
|
//#region src/value/array.ts
|
|
465
|
-
var ReactiveArray = class extends Reactive {
|
|
466
|
-
#indiced = /* @__PURE__ */ new Map();
|
|
467
|
-
#size = signal(0);
|
|
468
|
-
/**
|
|
469
|
-
* The length of the array
|
|
470
|
-
*/
|
|
471
|
-
get length() {
|
|
472
|
-
return this.#size.get();
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Set the length of the array
|
|
476
|
-
*/
|
|
477
|
-
set length(value) {
|
|
478
|
-
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
|
|
479
|
-
}
|
|
480
|
-
constructor(value, options) {
|
|
481
|
-
super(NAME_ARRAY, new Proxy(value, {
|
|
482
|
-
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
|
|
483
|
-
set: (target, property, value) => setValueInProxy({
|
|
484
|
-
property,
|
|
485
|
-
target,
|
|
486
|
-
value,
|
|
487
|
-
isArray: true,
|
|
488
|
-
state: this.state,
|
|
489
|
-
length: this.#size
|
|
490
|
-
})
|
|
491
|
-
}), options);
|
|
492
|
-
this.#size.set(value.length);
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Clear the array
|
|
496
|
-
*/
|
|
497
|
-
clear() {
|
|
498
|
-
this.length = 0;
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Create a computed, filtered array
|
|
502
|
-
* @param callback Callback to evaluate each item
|
|
503
|
-
* @return Computed array of filtered items
|
|
504
|
-
*/
|
|
505
|
-
filter(callback) {
|
|
506
|
-
return computed(() => this.get().filter(callback));
|
|
507
|
-
}
|
|
508
|
-
get(first) {
|
|
509
|
-
if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
510
|
-
return first === "length" ? this.length : getValue(this.state);
|
|
511
|
-
}
|
|
512
|
-
/**
|
|
513
|
-
* Create a computed, mapped array
|
|
514
|
-
* @param callback Callback to transform each item
|
|
515
|
-
* @return Computed array of mapped items
|
|
516
|
-
*/
|
|
517
|
-
map(callback) {
|
|
518
|
-
return computed(() => this.get().map(callback));
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Notify dependents of changes
|
|
522
|
-
*
|
|
523
|
-
* _This bypasses equality checks and will immediately notify dependents.
|
|
524
|
-
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
525
|
-
*/
|
|
526
|
-
notify() {
|
|
527
|
-
emityProxyValues(this.state, this.#indiced);
|
|
528
|
-
}
|
|
529
|
-
peek(value) {
|
|
530
|
-
if (value === "length") return this.#size.peek();
|
|
531
|
-
return typeof value === "number" ? this.state.value.at(value) : this.state.value.slice();
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Remove and return the last item of the array
|
|
535
|
-
* @returns Removed item, or `undefined` if the array is empty
|
|
536
|
-
*/
|
|
537
|
-
pop() {
|
|
538
|
-
return this.state.value.pop();
|
|
539
|
-
}
|
|
540
|
-
/**
|
|
541
|
-
* Add items to the end of the array
|
|
542
|
-
* @param items Items to add
|
|
543
|
-
* @returns New array length
|
|
544
|
-
*/
|
|
545
|
-
push(...items) {
|
|
546
|
-
return this.state.value.push(...items);
|
|
547
|
-
}
|
|
548
|
-
set(first, second) {
|
|
549
|
-
setProxyValue(true, this.state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Remove and return the first item of the array
|
|
553
|
-
* @returns Removed item, or `undefined` if the array is empty
|
|
554
|
-
*/
|
|
555
|
-
shift() {
|
|
556
|
-
return this.state.value.shift();
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Remove and return items from the array _(and optionally add new items)_
|
|
560
|
-
* @param from Index to start removing items from
|
|
561
|
-
* @param to Index to stop removing items at _(defaults to the end of the array)_
|
|
562
|
-
* @param items Optional items to add
|
|
563
|
-
* @returns Removed items
|
|
564
|
-
*/
|
|
565
|
-
splice(from, to, ...items) {
|
|
566
|
-
return this.state.value.splice(from, to ?? this.state.value.length, ...items);
|
|
567
|
-
}
|
|
568
|
-
subscribe(first, second) {
|
|
569
|
-
if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
|
|
570
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Add items to the beginning of the array
|
|
574
|
-
* @param items Items to add
|
|
575
|
-
* @returns New array length
|
|
576
|
-
*/
|
|
577
|
-
unshift(...items) {
|
|
578
|
-
return this.state.value.unshift(...items);
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Update the value _(based on the current value)_
|
|
582
|
-
* @param callback Callback to update the value
|
|
583
|
-
*/
|
|
584
|
-
update(callback) {
|
|
585
|
-
const updated = callback(this.state.value);
|
|
586
|
-
if (updated == null || Array.isArray(updated)) this.set(updated);
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
600
|
function array(value, options) {
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
601
|
+
const [rx, state] = reactive([], options);
|
|
602
|
+
const indiced = /* @__PURE__ */ new Map();
|
|
603
|
+
const length = signal(0);
|
|
604
|
+
const readonlies = {};
|
|
605
|
+
let instance = {};
|
|
606
|
+
state.value = new Proxy([], {
|
|
607
|
+
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, state, length) : Reflect.get(target, property),
|
|
608
|
+
set: (target, property, value) => setValueInProxy({
|
|
609
|
+
length,
|
|
610
|
+
property,
|
|
611
|
+
state,
|
|
612
|
+
target,
|
|
613
|
+
value,
|
|
614
|
+
isArray: true
|
|
615
|
+
})
|
|
616
|
+
});
|
|
617
|
+
function get(value) {
|
|
618
|
+
return getArrayValue(instance, indiced, state, length, value);
|
|
619
|
+
}
|
|
620
|
+
function set(first, second) {
|
|
621
|
+
setProxyValue(true, state, isArrayValue, isArrayIndex, setArray, setAtIndex, first, second);
|
|
622
|
+
}
|
|
623
|
+
const handlers = {
|
|
624
|
+
...rx,
|
|
625
|
+
get: (value) => get(value),
|
|
626
|
+
peek: (first, second) => peekArrayValue(state, length, first, second),
|
|
627
|
+
subscribe: (first, second) => {
|
|
628
|
+
if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(instance, indiced, first, true).subscribe(second);
|
|
629
|
+
return typeof first === "function" ? subscribe(state, first) : noop$1;
|
|
630
|
+
},
|
|
631
|
+
unsubscribe: (first, second) => {
|
|
632
|
+
if (typeof first === "number" && typeof second === "function") getReactiveValueInProxy(instance, indiced, first, true)?.unsubscribe(second);
|
|
633
|
+
else if (typeof first === "function") unsubscribe(state, first);
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
instance = {
|
|
637
|
+
...handlers,
|
|
638
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
|
|
639
|
+
at: (index) => get(index),
|
|
640
|
+
clear: () => {
|
|
641
|
+
state.value.length = 0;
|
|
642
|
+
},
|
|
643
|
+
filter: (callback) => computed(() => filter(get(), callback)),
|
|
644
|
+
map: (callback) => computed(() => get().map(callback)),
|
|
645
|
+
notify: () => {
|
|
646
|
+
emityProxyValues(state, indiced);
|
|
647
|
+
},
|
|
648
|
+
pop: () => state.value.pop(),
|
|
649
|
+
push: (...items) => state.value.push(...items),
|
|
650
|
+
select: (filter, map) => computed(() => select(get(), filter, map)),
|
|
651
|
+
set: (first, second) => {
|
|
652
|
+
set(first, second);
|
|
653
|
+
},
|
|
654
|
+
shift: () => state.value.shift(),
|
|
655
|
+
splice: (from, to, ...items) => state.value.splice(from, to ?? state.value.length, ...items),
|
|
656
|
+
unshift: (...items) => state.value.unshift(...items),
|
|
657
|
+
update: (callback) => updateArrayValue(instance, state, callback)
|
|
658
|
+
};
|
|
659
|
+
Object.defineProperties(instance, {
|
|
660
|
+
[NAME_MORA]: {
|
|
661
|
+
enumerable: false,
|
|
662
|
+
value: NAME_ARRAY
|
|
663
|
+
},
|
|
664
|
+
length: {
|
|
665
|
+
enumerable: true,
|
|
666
|
+
get: () => length.get(),
|
|
667
|
+
set: (value) => setArrayLength(state, value)
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
set(value);
|
|
671
|
+
return Object.freeze(instance);
|
|
672
|
+
}
|
|
673
|
+
function getArrayValue(instance, indiced, state, length, first) {
|
|
674
|
+
if (typeof first === "number") return getReactiveValueInProxy(instance, indiced, first, true).get();
|
|
675
|
+
return first === "length" ? length.get() : getSimpleValue(state);
|
|
593
676
|
}
|
|
594
677
|
function isArrayIndex(value) {
|
|
595
678
|
return typeof value === "number";
|
|
@@ -597,6 +680,26 @@ function isArrayIndex(value) {
|
|
|
597
680
|
function isArrayValue(value) {
|
|
598
681
|
return value == null || Array.isArray(value);
|
|
599
682
|
}
|
|
683
|
+
function peekArrayValue(state, length, first, second) {
|
|
684
|
+
if (first === "length") return length.peek();
|
|
685
|
+
let value;
|
|
686
|
+
if (typeof first === "number") value = state.value.at(first);
|
|
687
|
+
else value = state.value;
|
|
688
|
+
if (!(first === true || second === true)) return value;
|
|
689
|
+
if (Array.isArray(value)) return value.slice();
|
|
690
|
+
if (isPlainObject(value)) return { ...value };
|
|
691
|
+
return value;
|
|
692
|
+
}
|
|
693
|
+
function setArray(state, value) {
|
|
694
|
+
state.value.splice(0, state.value.length, ...value ?? []);
|
|
695
|
+
}
|
|
696
|
+
function setArrayLength(state, value) {
|
|
697
|
+
if (typeof value === "number" && value >= 0 && value !== state.value.length) state.value.length = value;
|
|
698
|
+
}
|
|
699
|
+
function setAtIndex(state, index, value) {
|
|
700
|
+
const actual = index < 0 ? state.value.length + index : index;
|
|
701
|
+
if (actual > -1) state.value[actual] = value;
|
|
702
|
+
}
|
|
600
703
|
function updateArray(type, array, state, length) {
|
|
601
704
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
602
705
|
const previousArray = affectsLength ? [] : array.slice();
|
|
@@ -610,57 +713,12 @@ function updateArray(type, array, state, length) {
|
|
|
610
713
|
return result;
|
|
611
714
|
};
|
|
612
715
|
}
|
|
613
|
-
function
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
function setAtIndex(state, index, value) {
|
|
617
|
-
const actual = index < 0 ? state.value.length + index : index;
|
|
618
|
-
if (actual > -1) state.value[actual] = value;
|
|
716
|
+
function updateArrayValue(instance, state, callback) {
|
|
717
|
+
const updated = callback(state.value);
|
|
718
|
+
if (updated == null || Array.isArray(updated)) instance.set(updated);
|
|
619
719
|
}
|
|
620
720
|
//#endregion
|
|
621
721
|
//#region src/value/store.ts
|
|
622
|
-
var Store = class extends Reactive {
|
|
623
|
-
#keyed = /* @__PURE__ */ new Map();
|
|
624
|
-
constructor(value, options) {
|
|
625
|
-
super(NAME_STORE, new Proxy(value, { set: (target, property, value) => setValueInProxy({
|
|
626
|
-
target,
|
|
627
|
-
property,
|
|
628
|
-
value,
|
|
629
|
-
isArray: false,
|
|
630
|
-
state: this.state
|
|
631
|
-
}) }), options);
|
|
632
|
-
}
|
|
633
|
-
get(key) {
|
|
634
|
-
return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue(this.state);
|
|
635
|
-
}
|
|
636
|
-
/**
|
|
637
|
-
* Notify dependents of changes
|
|
638
|
-
*
|
|
639
|
-
* _This bypasses equality checks and will immediately notify dependents.
|
|
640
|
-
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
641
|
-
*/
|
|
642
|
-
notify() {
|
|
643
|
-
emityProxyValues(this.state, this.#keyed);
|
|
644
|
-
}
|
|
645
|
-
peek(key) {
|
|
646
|
-
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
647
|
-
}
|
|
648
|
-
set(first, second) {
|
|
649
|
-
setProxyValue(false, this.state, isStoreObject, isKey, setObject, setProperty, first, second);
|
|
650
|
-
}
|
|
651
|
-
subscribe(first, second) {
|
|
652
|
-
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
653
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* Update the value _(based on the current value)_
|
|
657
|
-
* @param callback Callback to update the value
|
|
658
|
-
*/
|
|
659
|
-
update(callback) {
|
|
660
|
-
const updated = callback(this.state.value);
|
|
661
|
-
if (updated == null || isPlainObject(updated)) setObject(this.state, updated);
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
722
|
function isStoreObject(value) {
|
|
665
723
|
return value == null || isPlainObject(value);
|
|
666
724
|
}
|
|
@@ -682,13 +740,63 @@ function setObject(state, value) {
|
|
|
682
740
|
}
|
|
683
741
|
stopBatch();
|
|
684
742
|
}
|
|
743
|
+
function peekStoreValue(state, first, second) {
|
|
744
|
+
let value;
|
|
745
|
+
if (isKey(first)) value = state.value[first];
|
|
746
|
+
else value = state.value;
|
|
747
|
+
if (!(first === true || second === true)) return value;
|
|
748
|
+
if (Array.isArray(value)) return value.slice();
|
|
749
|
+
if (isPlainObject(value)) return { ...value };
|
|
750
|
+
return value;
|
|
751
|
+
}
|
|
685
752
|
function setProperty(state, key, value) {
|
|
686
753
|
state.value[key] = value;
|
|
687
754
|
}
|
|
688
755
|
function store(value, options) {
|
|
689
|
-
const
|
|
756
|
+
const [rx, state] = reactive(void 0, options);
|
|
757
|
+
const keyed = /* @__PURE__ */ new Map();
|
|
758
|
+
const readonlies = {};
|
|
759
|
+
let instance = {};
|
|
760
|
+
state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy({
|
|
761
|
+
target,
|
|
762
|
+
property,
|
|
763
|
+
state,
|
|
764
|
+
value,
|
|
765
|
+
isArray: false
|
|
766
|
+
}) });
|
|
767
|
+
const handlers = {
|
|
768
|
+
...rx,
|
|
769
|
+
get: (value) => isKey(value) ? getReactiveValueInProxy(instance, keyed, value, false).get() : getSimpleValue(state),
|
|
770
|
+
peek: (first, second) => peekStoreValue(state, first, second),
|
|
771
|
+
subscribe: (first, second) => {
|
|
772
|
+
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(instance, keyed, first, false).subscribe(second);
|
|
773
|
+
return typeof first === "function" ? subscribe(state, first) : noop;
|
|
774
|
+
},
|
|
775
|
+
unsubscribe: (first, second) => {
|
|
776
|
+
if (isKey(first) && typeof second === "function") getReactiveValueInProxy(instance, keyed, first, false)?.unsubscribe(second);
|
|
777
|
+
else if (typeof first === "function") unsubscribe(state, first);
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
instance = {
|
|
781
|
+
...handlers,
|
|
782
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, handlers, frozen === true),
|
|
783
|
+
notify() {
|
|
784
|
+
emityProxyValues(state, keyed);
|
|
785
|
+
},
|
|
786
|
+
set: (first, second) => {
|
|
787
|
+
setProxyValue(false, state, isStoreObject, isKey, setObject, setProperty, first, second);
|
|
788
|
+
},
|
|
789
|
+
update: (callback) => {
|
|
790
|
+
const updated = callback(state.value);
|
|
791
|
+
if (updated == null || isPlainObject(updated)) setObject(state, updated);
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
Object.defineProperty(instance, NAME_MORA, {
|
|
795
|
+
enumerable: false,
|
|
796
|
+
value: NAME_STORE
|
|
797
|
+
});
|
|
690
798
|
instance.set(value);
|
|
691
|
-
return instance;
|
|
799
|
+
return Object.freeze(instance);
|
|
692
800
|
}
|
|
693
801
|
//#endregion
|
|
694
|
-
export { array, computed, effect,
|
|
802
|
+
export { array, computed, effect, isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal, signal, startBatch, stopBatch, store };
|