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