@oscarpalmer/mora 0.31.0 → 0.32.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.d.mts +4 -5
- package/dist/batch.mjs +4 -2
- package/dist/constants.d.mts +29 -19
- package/dist/constants.mjs +17 -2
- package/dist/effect.d.mts +4 -5
- package/dist/effect.mjs +2 -2
- package/dist/helpers/is.d.mts +14 -9
- package/dist/helpers/is.mjs +6 -0
- package/dist/helpers/proxy.d.mts +12 -10
- package/dist/helpers/proxy.mjs +32 -14
- package/dist/helpers/subscription.d.mts +8 -0
- package/dist/helpers/subscription.mjs +27 -0
- package/dist/helpers/value.d.mts +8 -6
- package/dist/helpers/value.mjs +30 -4
- package/dist/index.d.mts +3 -2
- package/dist/models.d.mts +45 -87
- package/dist/mora.full.mjs +461 -285
- package/dist/value/array.d.mts +4 -5
- package/dist/value/array.mjs +22 -69
- package/dist/value/computed.d.mts +3 -4
- package/dist/value/computed.mjs +14 -14
- package/dist/value/reactive.d.mts +2 -3
- package/dist/value/reactive.mjs +0 -1
- package/dist/value/readonly.d.mts +3 -5
- package/dist/value/readonly.mjs +15 -19
- package/dist/value/signal.d.mts +4 -5
- package/dist/value/signal.mjs +9 -22
- package/dist/value/store.d.mts +4 -5
- package/dist/value/store.mjs +16 -56
- package/package.json +6 -6
- package/src/batch.ts +15 -5
- package/src/constants.ts +32 -2
- package/src/effect.ts +6 -2
- package/src/helpers/is.ts +10 -0
- package/src/helpers/proxy.ts +99 -49
- package/src/helpers/subscription.ts +78 -0
- package/src/helpers/value.ts +69 -4
- package/src/index.ts +1 -1
- package/src/models.ts +38 -81
- package/src/value/array.ts +61 -150
- package/src/value/computed.ts +36 -13
- package/src/value/reactive.ts +8 -5
- package/src/value/readonly.ts +26 -25
- package/src/value/signal.ts +19 -22
- package/src/value/store.ts +35 -114
- 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 +0 -3
- package/types/value/signal.d.ts +1 -1
- package/types/value/store.d.ts +1 -1
- package/dist/subscription.d.mts +0 -7
- package/dist/subscription.mjs +0 -27
- package/src/subscription.ts +0 -45
package/dist/mora.full.mjs
CHANGED
|
@@ -3,7 +3,7 @@ const ACTIVE = {};
|
|
|
3
3
|
const BATCH = {
|
|
4
4
|
depth: 0,
|
|
5
5
|
flushing: false,
|
|
6
|
-
handlers: /* @__PURE__ */ new
|
|
6
|
+
handlers: /* @__PURE__ */ new Map()
|
|
7
7
|
};
|
|
8
8
|
const METHODS_AFFECTING_LENGTH = /* @__PURE__ */ new Set([
|
|
9
9
|
"pop",
|
|
@@ -26,6 +26,7 @@ const NAME_MORA = "$mora";
|
|
|
26
26
|
const NAME_READONLY = "readonly";
|
|
27
27
|
const NAME_SIGNAL = "signal";
|
|
28
28
|
const NAME_STORE = "store";
|
|
29
|
+
const NAME_SUBSCRIPTION = "subscription";
|
|
29
30
|
const NAME_ALL = /* @__PURE__ */ new Set([
|
|
30
31
|
NAME_ARRAY,
|
|
31
32
|
NAME_COMPUTED,
|
|
@@ -33,6 +34,20 @@ const NAME_ALL = /* @__PURE__ */ new Set([
|
|
|
33
34
|
NAME_SIGNAL,
|
|
34
35
|
NAME_STORE
|
|
35
36
|
]);
|
|
37
|
+
const SUBSCRIPTION_PROPERTY$1 = {
|
|
38
|
+
key: NAME_MORA,
|
|
39
|
+
value: NAME_SUBSCRIPTION
|
|
40
|
+
};
|
|
41
|
+
const SUBSCRIPTION_TYPE_COPY = "copy";
|
|
42
|
+
const SUBSCRIPTION_TYPE_FROZEN = "frozen";
|
|
43
|
+
const SUBSCRIPTION_TYPE_ORIGINAL = "original";
|
|
44
|
+
const SUBSCRIPTION_TYPE_READONLY = "readonly";
|
|
45
|
+
const SUBSCRIPTION_TYPES_COPY = /* @__PURE__ */ new Set([SUBSCRIPTION_TYPE_COPY, SUBSCRIPTION_TYPE_READONLY]);
|
|
46
|
+
const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
|
|
47
|
+
...SUBSCRIPTION_TYPES_COPY,
|
|
48
|
+
SUBSCRIPTION_TYPE_FROZEN,
|
|
49
|
+
SUBSCRIPTION_TYPE_ORIGINAL
|
|
50
|
+
]);
|
|
36
51
|
//#endregion
|
|
37
52
|
//#region src/effect.ts
|
|
38
53
|
/**
|
|
@@ -47,7 +62,7 @@ function effect(callback) {
|
|
|
47
62
|
}
|
|
48
63
|
function getEffect(callback) {
|
|
49
64
|
const state = { callback };
|
|
50
|
-
const instance = Object.freeze({
|
|
65
|
+
const instance = Object.freeze({ [NAME_MORA]: NAME_EFFECT });
|
|
51
66
|
runEffect(state);
|
|
52
67
|
return [instance, state];
|
|
53
68
|
}
|
|
@@ -64,6 +79,98 @@ function runEffect(state) {
|
|
|
64
79
|
}
|
|
65
80
|
}
|
|
66
81
|
//#endregion
|
|
82
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
|
|
83
|
+
/**
|
|
84
|
+
* Is the value a _Key_?
|
|
85
|
+
*
|
|
86
|
+
* @param value Value to check
|
|
87
|
+
* @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
|
|
88
|
+
*/
|
|
89
|
+
function isKey(value) {
|
|
90
|
+
return typeof value === "number" || typeof value === "string";
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Is the value a plain object?
|
|
94
|
+
*
|
|
95
|
+
* @param value Value to check
|
|
96
|
+
* @returns `true` if the value is a plain object, otherwise `false`
|
|
97
|
+
*/
|
|
98
|
+
function isPlainObject(value) {
|
|
99
|
+
if (value === null || typeof value !== "object") return false;
|
|
100
|
+
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
101
|
+
const prototype = Object.getPrototypeOf(value);
|
|
102
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/helpers/value.ts
|
|
106
|
+
function emitValue(state) {
|
|
107
|
+
for (const computed of state.computeds) computed.dirty = true;
|
|
108
|
+
for (const effect of state.effects) BATCH.handlers.set(effect, effect);
|
|
109
|
+
for (const type of SUBSCRIPTION_TYPES) {
|
|
110
|
+
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
111
|
+
if (subscriptions != null) for (const [subscription, callback] of subscriptions) BATCH.handlers.set(subscription, {
|
|
112
|
+
callback,
|
|
113
|
+
state,
|
|
114
|
+
frozen: type === SUBSCRIPTION_TYPE_FROZEN,
|
|
115
|
+
copy: SUBSCRIPTION_TYPES_COPY.has(type)
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (BATCH.depth === 0) flushHandlers();
|
|
119
|
+
}
|
|
120
|
+
function equalArrays(state, first, second) {
|
|
121
|
+
let { length } = first;
|
|
122
|
+
if (length !== second.length) return false;
|
|
123
|
+
let offset = 0;
|
|
124
|
+
if (length >= 100) {
|
|
125
|
+
offset = Math.round(length / 10);
|
|
126
|
+
offset = offset > 25 ? 25 : offset;
|
|
127
|
+
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
128
|
+
}
|
|
129
|
+
length -= offset;
|
|
130
|
+
for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
function getFrozenValue(value) {
|
|
134
|
+
let frozen = value;
|
|
135
|
+
if (Array.isArray(frozen)) frozen = Object.freeze(frozen.slice());
|
|
136
|
+
else if (isPlainObject(frozen)) frozen = Object.freeze({ ...frozen });
|
|
137
|
+
return frozen;
|
|
138
|
+
}
|
|
139
|
+
function getSimpleValue(state) {
|
|
140
|
+
if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
|
|
141
|
+
if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
|
|
142
|
+
return state.value;
|
|
143
|
+
}
|
|
144
|
+
function handleSimpleValue(state, origin, setValue, onAfter) {
|
|
145
|
+
try {
|
|
146
|
+
let actual = typeof origin === "function" ? origin() : origin;
|
|
147
|
+
if (actual instanceof Promise) {
|
|
148
|
+
state.promise = actual;
|
|
149
|
+
actual.then((value) => {
|
|
150
|
+
if (actual === state.promise) {
|
|
151
|
+
state.promise = void 0;
|
|
152
|
+
setValue(state, value);
|
|
153
|
+
}
|
|
154
|
+
}).catch(() => {
|
|
155
|
+
if (actual === state.promise) state.promise = void 0;
|
|
156
|
+
});
|
|
157
|
+
} else setValue(state, actual);
|
|
158
|
+
} catch {} finally {
|
|
159
|
+
onAfter?.();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function peekSimpleValue(value, copy) {
|
|
163
|
+
let peeked = value;
|
|
164
|
+
if (!copy) return peeked;
|
|
165
|
+
if (Array.isArray(peeked)) peeked = peeked.slice();
|
|
166
|
+
else if (isPlainObject(peeked)) peeked = { ...peeked };
|
|
167
|
+
return peeked;
|
|
168
|
+
}
|
|
169
|
+
function updateSimpleValue(state, callback, setValue) {
|
|
170
|
+
if (typeof callback !== "function") throw new TypeError("Callback must be a function");
|
|
171
|
+
handleSimpleValue(state, callback(state.value), setValue);
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
67
174
|
//#region src/batch.ts
|
|
68
175
|
function flushHandlers() {
|
|
69
176
|
if (BATCH.flushing) return;
|
|
@@ -74,8 +181,9 @@ function flushHandlers() {
|
|
|
74
181
|
const { length } = handlers;
|
|
75
182
|
BATCH.handlers.clear();
|
|
76
183
|
for (let index = 0; index < length; index += 1) {
|
|
77
|
-
const handler = handlers[index];
|
|
78
|
-
|
|
184
|
+
const [, handler] = handlers[index];
|
|
185
|
+
const subscription = handler;
|
|
186
|
+
if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSimpleValue(subscription.state.value, subscription.copy));
|
|
79
187
|
else runEffect(handler);
|
|
80
188
|
}
|
|
81
189
|
}
|
|
@@ -157,6 +265,12 @@ function isReactiveArray(value) {
|
|
|
157
265
|
function isReactiveStore(value) {
|
|
158
266
|
return isMora(value, NAME_STORE);
|
|
159
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Is the value a readonly signal?
|
|
270
|
+
*
|
|
271
|
+
* @param value Value to check
|
|
272
|
+
* @returns True if value is a {@link ReadonlySignal}
|
|
273
|
+
*/
|
|
160
274
|
function isReadonlySignal(value) {
|
|
161
275
|
return isMora(value, NAME_READONLY);
|
|
162
276
|
}
|
|
@@ -167,6 +281,7 @@ function getArrayCallback(value) {
|
|
|
167
281
|
case "function": return value;
|
|
168
282
|
case "number":
|
|
169
283
|
case "string": return typeof value === "string" && value.includes(".") ? void 0 : (obj) => obj[value];
|
|
284
|
+
default: return;
|
|
170
285
|
}
|
|
171
286
|
}
|
|
172
287
|
function getArrayCallbacks(bool, key, value) {
|
|
@@ -178,10 +293,18 @@ function getArrayCallbacks(bool, key, value) {
|
|
|
178
293
|
}
|
|
179
294
|
//#endregion
|
|
180
295
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
|
|
296
|
+
function createFindParameters(original) {
|
|
297
|
+
const { length } = original;
|
|
298
|
+
return {
|
|
299
|
+
bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
|
|
300
|
+
key: length === 2 ? original[0] : void 0,
|
|
301
|
+
value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
|
|
302
|
+
};
|
|
303
|
+
}
|
|
181
304
|
function findValue(type, array, parameters, reversed) {
|
|
182
305
|
const findIndex = type === FIND_VALUE_INDEX;
|
|
183
306
|
if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
|
|
184
|
-
const { bool, key, value } =
|
|
307
|
+
const { bool, key, value } = createFindParameters(parameters);
|
|
185
308
|
const callbacks = getArrayCallbacks(bool, key);
|
|
186
309
|
if (callbacks?.bool == null && callbacks?.keyed == null) {
|
|
187
310
|
if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
|
|
@@ -208,18 +331,22 @@ function findValues(type, array, parameters, mapper) {
|
|
|
208
331
|
};
|
|
209
332
|
if (!Array.isArray(array) || array.length === 0) return result;
|
|
210
333
|
const { length } = array;
|
|
211
|
-
const { bool, key, value } =
|
|
334
|
+
const { bool, key, value } = createFindParameters(parameters);
|
|
212
335
|
const callbacks = getArrayCallbacks(bool, key);
|
|
213
|
-
if (type === "unique" && callbacks?.keyed == null && length >=
|
|
336
|
+
if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
|
|
214
337
|
result.matched = [...new Set(array)];
|
|
215
338
|
return result;
|
|
216
339
|
}
|
|
217
|
-
const mapCallback = getArrayCallback(mapper);
|
|
340
|
+
const mapCallback = getArrayCallback(mapper?.callback);
|
|
341
|
+
const mapReverse = mapper?.reverse ?? false;
|
|
342
|
+
const mapAfter = mapCallback == null ? void 0 : mapReverse ? void 0 : mapCallback;
|
|
343
|
+
const mapBefore = mapCallback == null ? void 0 : mapReverse ? mapCallback : void 0;
|
|
218
344
|
if (callbacks?.bool != null || type === "all" && key == null) {
|
|
219
345
|
const callback = callbacks?.bool ?? ((item) => Object.is(item, value));
|
|
220
346
|
for (let index = 0; index < length; index += 1) {
|
|
221
347
|
const item = array[index];
|
|
222
|
-
|
|
348
|
+
const transformed = mapBefore?.(item, index, array) ?? item;
|
|
349
|
+
if (callback(transformed, index, array)) result.matched.push(mapAfter?.(item, index, array) ?? transformed);
|
|
223
350
|
else result.notMatched.push(item);
|
|
224
351
|
}
|
|
225
352
|
return result;
|
|
@@ -227,71 +354,64 @@ function findValues(type, array, parameters, mapper) {
|
|
|
227
354
|
const keys = /* @__PURE__ */ new Set();
|
|
228
355
|
for (let index = 0; index < length; index += 1) {
|
|
229
356
|
const item = array[index];
|
|
230
|
-
|
|
357
|
+
let keyed;
|
|
358
|
+
let transformed;
|
|
359
|
+
if (mapBefore == null) {
|
|
360
|
+
keyed = callbacks?.keyed?.(item, index, array) ?? item;
|
|
361
|
+
transformed = item;
|
|
362
|
+
} else {
|
|
363
|
+
transformed = mapBefore(item, index, array);
|
|
364
|
+
keyed = callbacks?.keyed?.(transformed, index, array) ?? transformed;
|
|
365
|
+
}
|
|
231
366
|
if (type === "all" && Object.is(keyed, value) || type === "unique" && !keys.has(keyed)) {
|
|
232
367
|
keys.add(keyed);
|
|
233
|
-
result.matched.push(
|
|
368
|
+
result.matched.push(mapAfter?.(item, index, array) ?? transformed);
|
|
234
369
|
} else result.notMatched.push(item);
|
|
235
370
|
}
|
|
236
371
|
return result;
|
|
237
372
|
}
|
|
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
|
-
};
|
|
245
|
-
}
|
|
246
373
|
const FIND_VALUE_INDEX = "index";
|
|
247
374
|
const FIND_VALUE_ITEM = "item";
|
|
248
|
-
const
|
|
375
|
+
const FIND_UNIQUE_THRESHOLD = 100;
|
|
249
376
|
//#endregion
|
|
250
377
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/index-of.mjs
|
|
251
378
|
function indexOf(array, ...parameters) {
|
|
252
379
|
return findValue(FIND_VALUE_INDEX, array, parameters, false);
|
|
253
380
|
}
|
|
254
|
-
indexOf.last = lastIndexOf;
|
|
255
381
|
function lastIndexOf(array, ...parameters) {
|
|
256
382
|
return findValue(FIND_VALUE_INDEX, array, parameters, true);
|
|
257
383
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Is the value a _Key_?
|
|
262
|
-
*
|
|
263
|
-
* @param value Value to check
|
|
264
|
-
* @returns `true` if the value is a _Key_ _(`number` or `string`)_, otherwise `false`
|
|
265
|
-
*/
|
|
266
|
-
function isKey(value) {
|
|
267
|
-
return typeof value === "number" || typeof value === "string";
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* Is the value a plain object?
|
|
271
|
-
*
|
|
272
|
-
* @param value Value to check
|
|
273
|
-
* @returns `true` if the value is a plain object, otherwise `false`
|
|
274
|
-
*/
|
|
275
|
-
function isPlainObject(value) {
|
|
276
|
-
if (value === null || typeof value !== "object") return false;
|
|
277
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
278
|
-
const prototype = Object.getPrototypeOf(value);
|
|
279
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
280
|
-
}
|
|
384
|
+
indexOf.last = lastIndexOf;
|
|
385
|
+
Object.defineProperty(indexOf, "last", { value: lastIndexOf });
|
|
281
386
|
//#endregion
|
|
282
387
|
//#region node_modules/@oscarpalmer/atoms/dist/array/find.mjs
|
|
283
388
|
function find(array, ...parameters) {
|
|
284
389
|
return findValue(FIND_VALUE_ITEM, array, parameters, false);
|
|
285
390
|
}
|
|
286
|
-
find.last = findLast;
|
|
287
391
|
function findLast(array, ...parameters) {
|
|
288
392
|
return findValue(FIND_VALUE_ITEM, array, parameters, true);
|
|
289
393
|
}
|
|
394
|
+
find.last = findLast;
|
|
395
|
+
Object.defineProperty(find, "last", { value: findLast });
|
|
290
396
|
//#endregion
|
|
291
397
|
//#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
|
|
398
|
+
function reverseSelect(array, ...parameters) {
|
|
399
|
+
return findValues("all", array, parameters, {
|
|
400
|
+
callback: parameters.shift(),
|
|
401
|
+
reverse: true
|
|
402
|
+
}).matched;
|
|
403
|
+
}
|
|
292
404
|
function select(array, ...parameters) {
|
|
293
|
-
return
|
|
405
|
+
return selectValues(array, parameters);
|
|
294
406
|
}
|
|
407
|
+
function selectValues(array, parameters) {
|
|
408
|
+
return findValues("all", array, parameters, {
|
|
409
|
+
callback: parameters.pop(),
|
|
410
|
+
reverse: false
|
|
411
|
+
}).matched;
|
|
412
|
+
}
|
|
413
|
+
select.reverse = reverseSelect;
|
|
414
|
+
Object.defineProperty(select, "reverse", { value: reverseSelect });
|
|
295
415
|
//#endregion
|
|
296
416
|
//#region node_modules/@oscarpalmer/atoms/dist/array/filter.mjs
|
|
297
417
|
function exclude(array, ...parameters) {
|
|
@@ -301,81 +421,221 @@ function filter(array, ...parameters) {
|
|
|
301
421
|
return findValues("all", array, parameters).matched;
|
|
302
422
|
}
|
|
303
423
|
filter.remove = exclude;
|
|
424
|
+
Object.defineProperty(filter, "remove", { value: exclude });
|
|
304
425
|
//#endregion
|
|
305
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
315
|
-
for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
|
|
316
|
-
if (BATCH.depth === 0) flushHandlers();
|
|
426
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/abort.mjs
|
|
427
|
+
function createAborter(value, onAbort) {
|
|
428
|
+
if (!(value instanceof AbortSignal)) return;
|
|
429
|
+
value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
|
|
430
|
+
return {
|
|
431
|
+
callback: onAbort,
|
|
432
|
+
signal: value,
|
|
433
|
+
cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
|
|
434
|
+
};
|
|
317
435
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
436
|
+
const ABORT_EVENT = "abort";
|
|
437
|
+
const ABORT_OPTIONS = { once: true };
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
|
|
440
|
+
function addSubscription(subscriptions, subscription, state) {
|
|
441
|
+
const { items, values } = subscriptions;
|
|
442
|
+
const { key, value } = state.parameters;
|
|
443
|
+
if (!isKey(key)) {
|
|
444
|
+
items.any.add(subscription);
|
|
445
|
+
values.from.any.set(value, subscription);
|
|
446
|
+
values.to.any.set(subscription, value);
|
|
447
|
+
return;
|
|
326
448
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
449
|
+
/* istanbul ignore if */
|
|
450
|
+
if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
|
|
451
|
+
// istanbul ignore next
|
|
452
|
+
return;
|
|
453
|
+
let keyedItems = items.keyed.get(key);
|
|
454
|
+
if (keyedItems == null) {
|
|
455
|
+
keyedItems = /* @__PURE__ */ new Set();
|
|
456
|
+
items.keyed.set(key, keyedItems);
|
|
457
|
+
}
|
|
458
|
+
keyedItems.add(subscription);
|
|
459
|
+
let keyedFrom = values.from.keyed.get(key);
|
|
460
|
+
if (keyedFrom == null) {
|
|
461
|
+
keyedFrom = /* @__PURE__ */ new Map();
|
|
462
|
+
values.from.keyed.set(key, keyedFrom);
|
|
463
|
+
}
|
|
464
|
+
keyedFrom.set(value, subscription);
|
|
465
|
+
let keyedTo = values.to.keyed.get(key);
|
|
466
|
+
if (keyedTo == null) {
|
|
467
|
+
keyedTo = /* @__PURE__ */ new Map();
|
|
468
|
+
values.to.keyed.set(key, keyedTo);
|
|
469
|
+
}
|
|
470
|
+
keyedTo.set(subscription, value);
|
|
330
471
|
}
|
|
331
|
-
function
|
|
332
|
-
|
|
333
|
-
if (
|
|
334
|
-
return state.value;
|
|
472
|
+
function clearSubscriptions(store) {
|
|
473
|
+
for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
|
|
474
|
+
if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
335
475
|
}
|
|
336
|
-
function
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
});
|
|
349
|
-
} else setValue(state, actual);
|
|
350
|
-
} catch {} finally {
|
|
351
|
-
onAfter?.();
|
|
476
|
+
function createSubscription(subscriptions, property, params) {
|
|
477
|
+
const parameters = createSubscriptionParameters(params);
|
|
478
|
+
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
479
|
+
const state = {
|
|
480
|
+
parameters,
|
|
481
|
+
active: true
|
|
482
|
+
};
|
|
483
|
+
const existing = getExistingSubscription(subscriptions, state);
|
|
484
|
+
if (existing != null) return [existing, true];
|
|
485
|
+
if (subscriptions.keys != null && isKey(parameters.key)) {
|
|
486
|
+
if (subscriptions.keys === false) throw new Error(SUBSCRIPTION_DISALLOWED_KEY);
|
|
487
|
+
else if (subscriptions.keys !== true && !subscriptions.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
352
488
|
}
|
|
489
|
+
state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
|
|
490
|
+
const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
|
|
491
|
+
Object.defineProperties(instance, {
|
|
492
|
+
[SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_NAME },
|
|
493
|
+
[property.key]: { value: property.value },
|
|
494
|
+
active: {
|
|
495
|
+
enumerable: true,
|
|
496
|
+
get: () => (parameters.isActive?.() ?? true) && state.active
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
addSubscription(subscriptions, instance, state);
|
|
500
|
+
return [Object.freeze(instance), false];
|
|
353
501
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
502
|
+
function getExistingSubscription(subscriptions, state) {
|
|
503
|
+
const { values } = subscriptions;
|
|
504
|
+
const { parameters } = state;
|
|
505
|
+
return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
|
|
506
|
+
}
|
|
507
|
+
function createSubscriptionParameters(input) {
|
|
508
|
+
const values = isPlainObject(input) ? input : {};
|
|
509
|
+
if (values.value == null) throw new Error(SUBSCRIPTION_INVALID_VALUE);
|
|
510
|
+
return {
|
|
511
|
+
isActive: typeof values.isActive === "function" ? values.isActive : void 0,
|
|
512
|
+
key: isKey(values.key) ? values.key : void 0,
|
|
513
|
+
signal: values.signal instanceof AbortSignal ? values.signal : void 0,
|
|
514
|
+
value: values.value
|
|
362
515
|
};
|
|
363
516
|
}
|
|
364
|
-
function
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
517
|
+
function createSubscriptionsParameters(input) {
|
|
518
|
+
const values = isPlainObject(input) ? input : {};
|
|
519
|
+
let keys;
|
|
520
|
+
if (values.keys instanceof Set) keys = values.keys;
|
|
521
|
+
else keys = typeof values.keys === "boolean" ? values.keys : false;
|
|
522
|
+
return {
|
|
523
|
+
keys,
|
|
524
|
+
property: createSubscriptionsProperty(values.property)
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function createSubscriptionsProperty(input) {
|
|
528
|
+
const values = isPlainObject(input) ? input : {};
|
|
529
|
+
return {
|
|
530
|
+
key: typeof values.key === "string" ? values.key : SUBSCRIPTION_PROPERTY,
|
|
531
|
+
value: values.value == null ? SUBSCRIPTION_NAME : values.value
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function createSubscriptionsState(keys) {
|
|
535
|
+
return {
|
|
536
|
+
keys,
|
|
537
|
+
items: {
|
|
538
|
+
any: /* @__PURE__ */ new Set(),
|
|
539
|
+
keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
|
|
540
|
+
},
|
|
541
|
+
values: {
|
|
542
|
+
from: {
|
|
543
|
+
any: /* @__PURE__ */ new Map(),
|
|
544
|
+
keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
|
|
545
|
+
},
|
|
546
|
+
to: {
|
|
547
|
+
any: /* @__PURE__ */ new Map(),
|
|
548
|
+
keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
|
|
549
|
+
}
|
|
371
550
|
}
|
|
372
551
|
};
|
|
373
|
-
callback(state.value);
|
|
374
|
-
return instance;
|
|
375
552
|
}
|
|
376
|
-
function
|
|
377
|
-
|
|
378
|
-
|
|
553
|
+
function removeFromStore(items, values, subscription, value, key) {
|
|
554
|
+
items.delete(subscription);
|
|
555
|
+
if (key == null) {
|
|
556
|
+
values.from.any.delete(value);
|
|
557
|
+
values.to.any.delete(subscription);
|
|
558
|
+
} else {
|
|
559
|
+
values.from.keyed?.get(key)?.delete(value);
|
|
560
|
+
values.to.keyed?.get(key)?.delete(subscription);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function removeSubscription(subscriptionsState, subscription, state) {
|
|
564
|
+
if (!state.active) return;
|
|
565
|
+
state.aborter = void 0;
|
|
566
|
+
state.active = false;
|
|
567
|
+
state.parameters.isActive = void 0;
|
|
568
|
+
state.parameters.signal = void 0;
|
|
569
|
+
const { items, values } = subscriptionsState;
|
|
570
|
+
const { key, value } = state.parameters;
|
|
571
|
+
if (!isKey(key)) {
|
|
572
|
+
removeFromStore(items.any, values, subscription, value);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const keyed = items.keyed?.get(key);
|
|
576
|
+
/* istanbul ignore if */
|
|
577
|
+
if (items.keyed == null || keyed == null)
|
|
578
|
+
// istanbul ignore next
|
|
579
|
+
return;
|
|
580
|
+
removeFromStore(keyed, values, subscription, value, key);
|
|
581
|
+
if (keyed.size === 0) items.keyed.delete(key);
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Create a subscription store
|
|
585
|
+
*
|
|
586
|
+
* @param parameters Store parameters
|
|
587
|
+
* @returns Subscription store
|
|
588
|
+
*/
|
|
589
|
+
function subscriptions(parameters) {
|
|
590
|
+
const { keys, property } = createSubscriptionsParameters(parameters);
|
|
591
|
+
const state = createSubscriptionsState(keys);
|
|
592
|
+
const instance = {
|
|
593
|
+
clear: () => clearSubscriptions(state),
|
|
594
|
+
create: (parameters) => createSubscription(state, property, parameters)
|
|
595
|
+
};
|
|
596
|
+
Object.defineProperties(instance, {
|
|
597
|
+
[SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_STORE },
|
|
598
|
+
items: {
|
|
599
|
+
enumerable: true,
|
|
600
|
+
value: state.items
|
|
601
|
+
},
|
|
602
|
+
values: {
|
|
603
|
+
enumerable: true,
|
|
604
|
+
value: state.values
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
return Object.freeze(instance);
|
|
608
|
+
}
|
|
609
|
+
function unsubscribe(subscriptionsState, subscription, state) {
|
|
610
|
+
state.aborter?.cancel();
|
|
611
|
+
removeSubscription(subscriptionsState, subscription, state);
|
|
612
|
+
}
|
|
613
|
+
const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
|
|
614
|
+
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
615
|
+
const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
|
|
616
|
+
const SUBSCRIPTION_NAME = "subscription";
|
|
617
|
+
const SUBSCRIPTION_PROPERTY = "$subscriptions";
|
|
618
|
+
const SUBSCRIPTION_STORE = "subscriptions";
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region src/helpers/subscription.ts
|
|
621
|
+
function subscribeToProxy(isArray, instance, state, mapped, first, second, third) {
|
|
622
|
+
if (isKey(first)) return getReactiveValueInProxy(instance, mapped, first, isArray).subscribe(second, third);
|
|
623
|
+
return subscribeToSignal(state, first, second === true);
|
|
624
|
+
}
|
|
625
|
+
function subscribeToReactive(type, state, callback) {
|
|
626
|
+
state.subscriptions ??= subscriptions({
|
|
627
|
+
keys: SUBSCRIPTION_TYPES,
|
|
628
|
+
property: SUBSCRIPTION_PROPERTY$1
|
|
629
|
+
});
|
|
630
|
+
const [subscription, existing] = state.subscriptions.create({
|
|
631
|
+
key: type,
|
|
632
|
+
value: callback
|
|
633
|
+
});
|
|
634
|
+
if (!existing) callback(type === "frozen" ? getFrozenValue(state.value) : peekSimpleValue(state.value, SUBSCRIPTION_TYPES_COPY.has(type)));
|
|
635
|
+
return subscription;
|
|
636
|
+
}
|
|
637
|
+
function subscribeToSignal(state, callback, copy) {
|
|
638
|
+
return subscribeToReactive(copy ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, state, callback);
|
|
379
639
|
}
|
|
380
640
|
//#endregion
|
|
381
641
|
//#region src/value/reactive.ts
|
|
@@ -384,7 +644,6 @@ function reactive(value, options) {
|
|
|
384
644
|
computeds: /* @__PURE__ */ new Set(),
|
|
385
645
|
effects: /* @__PURE__ */ new Set(),
|
|
386
646
|
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
|
|
387
|
-
subscriptions: /* @__PURE__ */ new Map(),
|
|
388
647
|
value
|
|
389
648
|
};
|
|
390
649
|
return [{
|
|
@@ -405,21 +664,16 @@ function computed(callback, options) {
|
|
|
405
664
|
return getComputed(callback, options)[0];
|
|
406
665
|
}
|
|
407
666
|
function getComputed(callback, options) {
|
|
667
|
+
if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
|
|
408
668
|
const [rx, state] = reactive(void 0, options);
|
|
409
669
|
let fx;
|
|
410
670
|
const instance = {
|
|
411
671
|
...rx,
|
|
412
672
|
get: () => getValue(state, fx),
|
|
413
|
-
peek: () => state.value,
|
|
414
|
-
subscribe: (callback) =>
|
|
415
|
-
unsubscribe: (callback) => {
|
|
416
|
-
state.subscriptions.delete(callback);
|
|
417
|
-
}
|
|
673
|
+
peek: (copy) => peekSimpleValue(state.value, copy === true),
|
|
674
|
+
subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true)
|
|
418
675
|
};
|
|
419
|
-
Object.defineProperty(instance, NAME_MORA, {
|
|
420
|
-
enumerable: false,
|
|
421
|
-
value: NAME_COMPUTED
|
|
422
|
-
});
|
|
676
|
+
Object.defineProperty(instance, NAME_MORA, { value: NAME_COMPUTED });
|
|
423
677
|
fx = getComputedEffect(state, callback);
|
|
424
678
|
return [Object.freeze(instance), fx];
|
|
425
679
|
}
|
|
@@ -453,37 +707,56 @@ function setAndEmit$1(state, value) {
|
|
|
453
707
|
if (state.equal(state.value, value)) return;
|
|
454
708
|
state.value = value;
|
|
455
709
|
for (const computed of state.computeds) computed.dirty = true;
|
|
456
|
-
for (const effect of state.effects) BATCH.handlers.
|
|
457
|
-
for (const
|
|
710
|
+
for (const effect of state.effects) BATCH.handlers.set(effect, effect);
|
|
711
|
+
for (const type of SUBSCRIPTION_TYPES) {
|
|
712
|
+
if (type === "frozen") continue;
|
|
713
|
+
const copy = SUBSCRIPTION_TYPES_COPY.has(type);
|
|
714
|
+
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
715
|
+
if (subscriptions != null) for (const [, callback] of subscriptions) callback(peekSimpleValue(state.value, copy));
|
|
716
|
+
}
|
|
458
717
|
flushHandlers();
|
|
459
718
|
}
|
|
460
719
|
//#endregion
|
|
461
720
|
//#region src/helpers/proxy.ts
|
|
462
|
-
function
|
|
721
|
+
function emitProxyValues(state, mapped) {
|
|
463
722
|
const values = [...mapped.values()];
|
|
464
723
|
const { length } = values;
|
|
465
724
|
for (let index = 0; index < length; index += 1) values[index][1].dirty = true;
|
|
466
725
|
emitValue(state);
|
|
467
726
|
}
|
|
468
727
|
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
469
|
-
|
|
728
|
+
const mapKey = String(key);
|
|
729
|
+
let item = mapped.get(mapKey);
|
|
470
730
|
if (item == null) {
|
|
471
731
|
item = internalComputed(() => isArray ? reactive.get().at(key) : reactive.get()[key]);
|
|
472
|
-
mapped.set(
|
|
732
|
+
mapped.set(mapKey, item);
|
|
473
733
|
}
|
|
474
734
|
return item[0];
|
|
475
735
|
}
|
|
476
|
-
function
|
|
477
|
-
if (
|
|
736
|
+
function getValueInProxy(isArray, instance, state, mapped, first) {
|
|
737
|
+
if (isArray ? typeof first === "number" : isKey(first)) return getReactiveValueInProxy(instance, mapped, first, isArray).get();
|
|
738
|
+
return getSimpleValue(state);
|
|
739
|
+
}
|
|
740
|
+
function isProxyObject(isArray, value) {
|
|
741
|
+
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
742
|
+
}
|
|
743
|
+
function peekValueInProxy(isArray, state, first, second) {
|
|
744
|
+
let value;
|
|
745
|
+
if (isArray ? typeof first === "number" : isKey(first)) value = isArray ? state.value.at(first) : state.value[first];
|
|
746
|
+
else value = state.value;
|
|
747
|
+
return peekSimpleValue(value, first === true || second === true);
|
|
748
|
+
}
|
|
749
|
+
function setProxyValue(isArray, state, setObject, setProperty, first, second) {
|
|
750
|
+
if (isArray && first === "length") {
|
|
478
751
|
state.value.length = second;
|
|
479
752
|
return;
|
|
480
753
|
}
|
|
481
|
-
if (
|
|
754
|
+
if (isProxyObject(isArray, first)) {
|
|
482
755
|
setObject(state, first);
|
|
483
756
|
return;
|
|
484
757
|
}
|
|
485
|
-
const property =
|
|
486
|
-
if (
|
|
758
|
+
const property = isArray ? typeof first === "number" : isKey(first);
|
|
759
|
+
if (isArray && property && Number.isNaN(first)) return;
|
|
487
760
|
let actual = property ? second : first;
|
|
488
761
|
if (typeof actual === "function") try {
|
|
489
762
|
actual = actual();
|
|
@@ -501,7 +774,7 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
|
|
|
501
774
|
setProperty(state, first, value);
|
|
502
775
|
return;
|
|
503
776
|
}
|
|
504
|
-
if (!property &&
|
|
777
|
+
if (!property && isProxyObject(isArray, value) && state.promise === actual) {
|
|
505
778
|
state.promise = void 0;
|
|
506
779
|
setObject(state, value);
|
|
507
780
|
}
|
|
@@ -510,10 +783,9 @@ function setProxyValue(array, state, isObject, isProperty, setObject, setPropert
|
|
|
510
783
|
else if (!property && state.promise === actual) state.promise = void 0;
|
|
511
784
|
});
|
|
512
785
|
} else if (property) setProperty(state, first, actual);
|
|
513
|
-
else if (
|
|
786
|
+
else if (isProxyObject(isArray, actual)) setObject(state, actual);
|
|
514
787
|
}
|
|
515
|
-
function setValueInProxy(
|
|
516
|
-
const { isArray, length, property, state, target, value } = parameters;
|
|
788
|
+
function setValueInProxy(isArray, state, target, property, value, length) {
|
|
517
789
|
if (isArray) {
|
|
518
790
|
if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
|
|
519
791
|
}
|
|
@@ -525,24 +797,26 @@ function setValueInProxy(parameters) {
|
|
|
525
797
|
}
|
|
526
798
|
return true;
|
|
527
799
|
}
|
|
800
|
+
function updateProxyValue(isArray, state, setObject, setProperty, callback) {
|
|
801
|
+
if (typeof callback !== "function") throw new TypeError("Callback must be a function");
|
|
802
|
+
setProxyValue(isArray, state, setObject, setProperty, callback(state.value));
|
|
803
|
+
}
|
|
528
804
|
//#endregion
|
|
529
805
|
//#region src/value/readonly.ts
|
|
530
|
-
function getReadonlyInstance(state, instances,
|
|
806
|
+
function getReadonlyInstance(state, instances, frozen) {
|
|
531
807
|
const key = frozen ? "frozen" : "original";
|
|
532
|
-
instances[key] ??= getReadonlySignal(state,
|
|
808
|
+
instances[key] ??= getReadonlySignal(state, frozen);
|
|
533
809
|
return instances[key];
|
|
534
810
|
}
|
|
535
|
-
function getReadonlySignal(state,
|
|
811
|
+
function getReadonlySignal(state, frozen) {
|
|
812
|
+
const type = frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY;
|
|
536
813
|
const instance = {
|
|
537
|
-
...handlers,
|
|
538
814
|
get: () => getReadonlyValue(state, false, frozen),
|
|
539
|
-
peek: () => getReadonlyValue(state, true, frozen)
|
|
815
|
+
peek: (copy) => getReadonlyValue(state, true, frozen, copy),
|
|
816
|
+
subscribe: (callback) => subscribeToReactive(type, state, callback)
|
|
540
817
|
};
|
|
541
818
|
Object.defineProperties(instance, {
|
|
542
|
-
[NAME_MORA]: {
|
|
543
|
-
enumerable: false,
|
|
544
|
-
value: NAME_READONLY
|
|
545
|
-
},
|
|
819
|
+
[NAME_MORA]: { value: NAME_READONLY },
|
|
546
820
|
frozen: {
|
|
547
821
|
enumerable: true,
|
|
548
822
|
value: frozen
|
|
@@ -550,13 +824,11 @@ function getReadonlySignal(state, handlers, frozen) {
|
|
|
550
824
|
});
|
|
551
825
|
return Object.freeze(instance);
|
|
552
826
|
}
|
|
553
|
-
function getReadonlyValue(state, peek, frozen) {
|
|
554
|
-
let value
|
|
555
|
-
if (
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
else value = state.value;
|
|
559
|
-
return Object.freeze(value);
|
|
827
|
+
function getReadonlyValue(state, peek, frozen, copy) {
|
|
828
|
+
let value;
|
|
829
|
+
if (peek) value = peekSimpleValue(state.value, copy === true);
|
|
830
|
+
else value = getSimpleValue(state);
|
|
831
|
+
return frozen ? getFrozenValue(value) : value;
|
|
560
832
|
}
|
|
561
833
|
//#endregion
|
|
562
834
|
//#region src/value/signal.ts
|
|
@@ -569,29 +841,16 @@ function setAndEmit(state, value) {
|
|
|
569
841
|
function signal(value, options) {
|
|
570
842
|
const [rx, state] = reactive(void 0, options);
|
|
571
843
|
const readonlies = {};
|
|
572
|
-
const handlers = {
|
|
573
|
-
...rx,
|
|
574
|
-
subscribe: (callback) => subscribe(state, callback),
|
|
575
|
-
unsubscribe: (callback) => {
|
|
576
|
-
state.subscriptions.delete(callback);
|
|
577
|
-
}
|
|
578
|
-
};
|
|
579
844
|
const instance = {
|
|
580
|
-
...
|
|
581
|
-
asReadonly: (frozen) => getReadonlyInstance(state, readonlies,
|
|
845
|
+
...rx,
|
|
846
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
582
847
|
get: () => getSimpleValue(state),
|
|
583
|
-
peek: () => state.value,
|
|
584
|
-
set: (value) =>
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
update: (callback) => {
|
|
588
|
-
handleSimpleValue(state, callback(state.value), setAndEmit);
|
|
589
|
-
}
|
|
848
|
+
peek: (copy) => peekSimpleValue(state.value, copy === true),
|
|
849
|
+
set: (value) => handleSimpleValue(state, value, setAndEmit),
|
|
850
|
+
subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true),
|
|
851
|
+
update: (callback) => updateSimpleValue(state, callback, setAndEmit)
|
|
590
852
|
};
|
|
591
|
-
Object.defineProperty(instance, NAME_MORA, {
|
|
592
|
-
enumerable: false,
|
|
593
|
-
value: NAME_SIGNAL
|
|
594
|
-
});
|
|
853
|
+
Object.defineProperty(instance, NAME_MORA, { value: NAME_SIGNAL });
|
|
595
854
|
handleSimpleValue(state, value, setAndEmit);
|
|
596
855
|
return Object.freeze(instance);
|
|
597
856
|
}
|
|
@@ -599,68 +858,44 @@ function signal(value, options) {
|
|
|
599
858
|
//#region src/value/array.ts
|
|
600
859
|
function array(value, options) {
|
|
601
860
|
const [rx, state] = reactive([], options);
|
|
602
|
-
const
|
|
861
|
+
const isArray = true;
|
|
603
862
|
const length = signal(0);
|
|
863
|
+
const mapped = /* @__PURE__ */ new Map();
|
|
604
864
|
const readonlies = {};
|
|
605
|
-
let instance = {};
|
|
606
865
|
state.value = new Proxy([], {
|
|
607
866
|
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
|
-
})
|
|
867
|
+
set: (target, property, value) => setValueInProxy(isArray, state, target, property, value, length)
|
|
616
868
|
});
|
|
617
869
|
function get(value) {
|
|
618
|
-
return
|
|
870
|
+
return value === "length" ? length.get() : getValueInProxy(isArray, instance, state, mapped, value);
|
|
619
871
|
}
|
|
620
872
|
function set(first, second) {
|
|
621
|
-
setProxyValue(true, state,
|
|
873
|
+
setProxyValue(true, state, setArrayValue, setAtIndex, first, second);
|
|
622
874
|
}
|
|
623
|
-
const
|
|
875
|
+
const instance = {
|
|
624
876
|
...rx,
|
|
625
|
-
|
|
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),
|
|
877
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
639
878
|
at: (index) => get(index),
|
|
640
879
|
clear: () => {
|
|
641
880
|
state.value.length = 0;
|
|
642
881
|
},
|
|
643
882
|
filter: (callback) => computed(() => filter(get(), callback)),
|
|
883
|
+
get: (value) => get(value),
|
|
644
884
|
map: (callback) => computed(() => get().map(callback)),
|
|
645
|
-
notify: () =>
|
|
646
|
-
|
|
647
|
-
},
|
|
885
|
+
notify: () => emitProxyValues(state, mapped),
|
|
886
|
+
peek: (first, second) => peekArrayValue(state, length, first, second),
|
|
648
887
|
pop: () => state.value.pop(),
|
|
649
888
|
push: (...items) => state.value.push(...items),
|
|
650
889
|
select: (filter, map) => computed(() => select(get(), filter, map)),
|
|
651
|
-
set: (first, second) =>
|
|
652
|
-
set(first, second);
|
|
653
|
-
},
|
|
890
|
+
set: (first, second) => set(first, second),
|
|
654
891
|
shift: () => state.value.shift(),
|
|
655
892
|
splice: (from, to, ...items) => state.value.splice(from, to ?? state.value.length, ...items),
|
|
893
|
+
subscribe: (first, second, third) => subscribeToProxy(isArray, instance, state, mapped, first, second, third),
|
|
656
894
|
unshift: (...items) => state.value.unshift(...items),
|
|
657
|
-
update: (callback) =>
|
|
895
|
+
update: (callback) => updateProxyValue(true, state, setArrayValue, setAtIndex, callback)
|
|
658
896
|
};
|
|
659
897
|
Object.defineProperties(instance, {
|
|
660
|
-
[NAME_MORA]: {
|
|
661
|
-
enumerable: false,
|
|
662
|
-
value: NAME_ARRAY
|
|
663
|
-
},
|
|
898
|
+
[NAME_MORA]: { value: NAME_ARRAY },
|
|
664
899
|
length: {
|
|
665
900
|
enumerable: true,
|
|
666
901
|
get: () => length.get(),
|
|
@@ -670,31 +905,14 @@ function array(value, options) {
|
|
|
670
905
|
set(value);
|
|
671
906
|
return Object.freeze(instance);
|
|
672
907
|
}
|
|
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);
|
|
676
|
-
}
|
|
677
|
-
function isArrayIndex(value) {
|
|
678
|
-
return typeof value === "number";
|
|
679
|
-
}
|
|
680
|
-
function isArrayValue(value) {
|
|
681
|
-
return value == null || Array.isArray(value);
|
|
682
|
-
}
|
|
683
908
|
function peekArrayValue(state, length, first, second) {
|
|
684
|
-
|
|
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 ?? []);
|
|
909
|
+
return first === "length" ? length.peek() : peekValueInProxy(true, state, first, second);
|
|
695
910
|
}
|
|
696
911
|
function setArrayLength(state, value) {
|
|
697
|
-
if (typeof value === "number" && value >= 0 && value !== state.value.length) state.value.length = value;
|
|
912
|
+
if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== state.value.length) state.value.length = value;
|
|
913
|
+
}
|
|
914
|
+
function setArrayValue(state, value) {
|
|
915
|
+
state.value.splice(0, state.value.length, ...value ?? []);
|
|
698
916
|
}
|
|
699
917
|
function setAtIndex(state, index, value) {
|
|
700
918
|
const actual = index < 0 ? state.value.length + index : index;
|
|
@@ -713,16 +931,12 @@ function updateArray(type, array, state, length) {
|
|
|
713
931
|
return result;
|
|
714
932
|
};
|
|
715
933
|
}
|
|
716
|
-
function updateArrayValue(instance, state, callback) {
|
|
717
|
-
const updated = callback(state.value);
|
|
718
|
-
if (updated == null || Array.isArray(updated)) instance.set(updated);
|
|
719
|
-
}
|
|
720
934
|
//#endregion
|
|
721
935
|
//#region src/value/store.ts
|
|
722
|
-
function
|
|
723
|
-
|
|
936
|
+
function setPropertyValue(state, key, value) {
|
|
937
|
+
state.value[key] = value;
|
|
724
938
|
}
|
|
725
|
-
function
|
|
939
|
+
function setStoreValue(state, value) {
|
|
726
940
|
startBatch();
|
|
727
941
|
const actual = value ?? {};
|
|
728
942
|
const proxy = state.value;
|
|
@@ -740,61 +954,23 @@ function setObject(state, value) {
|
|
|
740
954
|
}
|
|
741
955
|
stopBatch();
|
|
742
956
|
}
|
|
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
|
-
}
|
|
752
|
-
function setProperty(state, key, value) {
|
|
753
|
-
state.value[key] = value;
|
|
754
|
-
}
|
|
755
957
|
function store(value, options) {
|
|
756
958
|
const [rx, state] = reactive(void 0, options);
|
|
959
|
+
const isArray = false;
|
|
757
960
|
const keyed = /* @__PURE__ */ new Map();
|
|
758
961
|
const readonlies = {};
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
target,
|
|
762
|
-
property,
|
|
763
|
-
state,
|
|
764
|
-
value,
|
|
765
|
-
isArray: false
|
|
766
|
-
}) });
|
|
767
|
-
const handlers = {
|
|
962
|
+
state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy(isArray, state, target, property, value) });
|
|
963
|
+
const instance = {
|
|
768
964
|
...rx,
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
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
|
-
}
|
|
965
|
+
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
966
|
+
get: (value) => getValueInProxy(isArray, instance, state, keyed, value),
|
|
967
|
+
notify: () => emitProxyValues(state, keyed),
|
|
968
|
+
peek: (first, second) => peekValueInProxy(isArray, state, first, second),
|
|
969
|
+
set: (first, second) => setProxyValue(isArray, state, setStoreValue, setPropertyValue, first, second),
|
|
970
|
+
subscribe: (first, second, third) => subscribeToProxy(isArray, instance, state, keyed, first, second, third),
|
|
971
|
+
update: (callback) => updateProxyValue(isArray, state, setStoreValue, setPropertyValue, callback)
|
|
793
972
|
};
|
|
794
|
-
Object.defineProperty(instance, NAME_MORA, {
|
|
795
|
-
enumerable: false,
|
|
796
|
-
value: NAME_STORE
|
|
797
|
-
});
|
|
973
|
+
Object.defineProperty(instance, NAME_MORA, { value: NAME_STORE });
|
|
798
974
|
instance.set(value);
|
|
799
975
|
return Object.freeze(instance);
|
|
800
976
|
}
|