@oscarpalmer/mora 0.32.0 → 0.34.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 +2 -2
- package/dist/constants.d.mts +2 -0
- package/dist/constants.mjs +3 -1
- package/dist/effect.d.mts +1 -0
- package/dist/effect.mjs +8 -5
- package/dist/helpers/is.d.mts +6 -6
- package/dist/helpers/misc.d.mts +4 -0
- package/dist/helpers/misc.mjs +9 -0
- package/dist/helpers/proxy.d.mts +8 -10
- package/dist/helpers/proxy.mjs +71 -33
- package/dist/helpers/subscription.d.mts +4 -4
- package/dist/helpers/subscription.mjs +16 -13
- package/dist/helpers/value.d.mts +8 -7
- package/dist/helpers/value.mjs +35 -22
- package/dist/models.d.mts +47 -24
- package/dist/models.mjs +1 -0
- package/dist/mora.full.mjs +375 -292
- package/dist/value/array.d.mts +1 -0
- package/dist/value/array.mjs +69 -61
- package/dist/value/computed.d.mts +3 -1
- package/dist/value/computed.mjs +39 -25
- package/dist/value/readonly.d.mts +3 -3
- package/dist/value/readonly.mjs +31 -24
- package/dist/value/signal.d.mts +1 -0
- package/dist/value/signal.mjs +27 -20
- package/dist/value/store.d.mts +1 -0
- package/dist/value/store.mjs +23 -41
- package/package.json +2 -2
- package/src/batch.ts +2 -2
- package/src/constants.ts +4 -0
- package/src/effect.ts +16 -11
- package/src/helpers/is.ts +6 -6
- package/src/helpers/misc.ts +15 -0
- package/src/helpers/proxy.ts +116 -89
- package/src/helpers/subscription.ts +46 -35
- package/src/helpers/value.ts +61 -35
- package/src/models.ts +54 -28
- package/src/value/array.ts +103 -124
- package/src/value/computed.ts +70 -40
- package/src/value/readonly.ts +54 -41
- package/src/value/signal.ts +46 -35
- package/src/value/store.ts +36 -83
- package/dist/value/reactive.d.mts +0 -4
- package/dist/value/reactive.mjs +0 -15
- package/src/value/reactive.ts +0 -27
package/dist/mora.full.mjs
CHANGED
|
@@ -34,6 +34,9 @@ const NAME_ALL = /* @__PURE__ */ new Set([
|
|
|
34
34
|
NAME_SIGNAL,
|
|
35
35
|
NAME_STORE
|
|
36
36
|
]);
|
|
37
|
+
const PROPERTY_LENGTH = "length";
|
|
38
|
+
const SYMBOL_EFFECT = Symbol("effect");
|
|
39
|
+
const SYMBOL_STATE = Symbol("state");
|
|
37
40
|
const SUBSCRIPTION_PROPERTY$1 = {
|
|
38
41
|
key: NAME_MORA,
|
|
39
42
|
value: NAME_SUBSCRIPTION
|
|
@@ -50,6 +53,11 @@ const SUBSCRIPTION_TYPES = /* @__PURE__ */ new Set([
|
|
|
50
53
|
]);
|
|
51
54
|
//#endregion
|
|
52
55
|
//#region src/effect.ts
|
|
56
|
+
function Effect(callback) {
|
|
57
|
+
this[SYMBOL_STATE] = { callback };
|
|
58
|
+
runEffect(this[SYMBOL_STATE]);
|
|
59
|
+
}
|
|
60
|
+
Effect.prototype[NAME_MORA] = NAME_EFFECT;
|
|
53
61
|
/**
|
|
54
62
|
* Create an effect
|
|
55
63
|
*
|
|
@@ -61,10 +69,8 @@ function effect(callback) {
|
|
|
61
69
|
return getEffect(callback)[0];
|
|
62
70
|
}
|
|
63
71
|
function getEffect(callback) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
runEffect(state);
|
|
67
|
-
return [instance, state];
|
|
72
|
+
const instance = new Effect(callback);
|
|
73
|
+
return [instance, instance[SYMBOL_STATE]];
|
|
68
74
|
}
|
|
69
75
|
function internalEffect(callback) {
|
|
70
76
|
return getEffect(callback)[1];
|
|
@@ -103,13 +109,15 @@ function isPlainObject(value) {
|
|
|
103
109
|
}
|
|
104
110
|
//#endregion
|
|
105
111
|
//#region src/helpers/value.ts
|
|
106
|
-
function emitValue(
|
|
107
|
-
|
|
108
|
-
for (const
|
|
112
|
+
function emitValue(instance) {
|
|
113
|
+
const state = instance[SYMBOL_STATE];
|
|
114
|
+
if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
|
|
115
|
+
if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) BATCH.handlers.set(effect, effect);
|
|
109
116
|
for (const type of SUBSCRIPTION_TYPES) {
|
|
110
117
|
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
111
|
-
if (subscriptions != null) for (const [subscription, callback] of subscriptions) BATCH.handlers.set(subscription, {
|
|
118
|
+
if (subscriptions != null && subscriptions.size > 0) for (const [subscription, callback] of subscriptions) BATCH.handlers.set(subscription, {
|
|
112
119
|
callback,
|
|
120
|
+
instance,
|
|
113
121
|
state,
|
|
114
122
|
frozen: type === SUBSCRIPTION_TYPE_FROZEN,
|
|
115
123
|
copy: SUBSCRIPTION_TYPES_COPY.has(type)
|
|
@@ -118,16 +126,17 @@ function emitValue(state) {
|
|
|
118
126
|
if (BATCH.depth === 0) flushHandlers();
|
|
119
127
|
}
|
|
120
128
|
function equalArrays(state, first, second) {
|
|
121
|
-
|
|
129
|
+
const { length } = first;
|
|
122
130
|
if (length !== second.length) return false;
|
|
131
|
+
const eq = state.equal ?? Object.is;
|
|
123
132
|
let offset = 0;
|
|
124
133
|
if (length >= 100) {
|
|
125
134
|
offset = Math.round(length / 10);
|
|
126
135
|
offset = offset > 25 ? 25 : offset;
|
|
127
|
-
for (let index = 0; index < offset; index += 1) if (!
|
|
136
|
+
for (let index = 0; index < offset; index += 1) if (!(eq(first[index], second[index]) && eq(first[length - index - 1], second[length - index - 1]))) return false;
|
|
128
137
|
}
|
|
129
|
-
length
|
|
130
|
-
for (let index = offset; index <
|
|
138
|
+
const end = length - offset;
|
|
139
|
+
for (let index = offset; index < end; index += 1) if (!eq(first[index], second[index])) return false;
|
|
131
140
|
return true;
|
|
132
141
|
}
|
|
133
142
|
function getFrozenValue(value) {
|
|
@@ -136,12 +145,22 @@ function getFrozenValue(value) {
|
|
|
136
145
|
else if (isPlainObject(frozen)) frozen = Object.freeze({ ...frozen });
|
|
137
146
|
return frozen;
|
|
138
147
|
}
|
|
139
|
-
function
|
|
140
|
-
if (ACTIVE.computed != null)
|
|
141
|
-
|
|
142
|
-
|
|
148
|
+
function getSignalValue() {
|
|
149
|
+
if (ACTIVE.computed != null) {
|
|
150
|
+
this[SYMBOL_STATE].computeds ??= /* @__PURE__ */ new Set();
|
|
151
|
+
this[SYMBOL_STATE].computeds.add(ACTIVE.computed);
|
|
152
|
+
}
|
|
153
|
+
if (ACTIVE.effect != null) {
|
|
154
|
+
this[SYMBOL_STATE].effects ??= /* @__PURE__ */ new Set();
|
|
155
|
+
this[SYMBOL_STATE].effects.add(ACTIVE.effect);
|
|
156
|
+
}
|
|
157
|
+
return this[SYMBOL_STATE].value;
|
|
143
158
|
}
|
|
144
|
-
function
|
|
159
|
+
function getStringValue(json) {
|
|
160
|
+
return json === true ? JSON.stringify(this[SYMBOL_STATE].value) : String(this[SYMBOL_STATE].value);
|
|
161
|
+
}
|
|
162
|
+
function handleSignalValue(instance, origin, setValue, onAfter) {
|
|
163
|
+
const state = instance[SYMBOL_STATE];
|
|
145
164
|
try {
|
|
146
165
|
let actual = typeof origin === "function" ? origin() : origin;
|
|
147
166
|
if (actual instanceof Promise) {
|
|
@@ -149,26 +168,26 @@ function handleSimpleValue(state, origin, setValue, onAfter) {
|
|
|
149
168
|
actual.then((value) => {
|
|
150
169
|
if (actual === state.promise) {
|
|
151
170
|
state.promise = void 0;
|
|
152
|
-
setValue(
|
|
171
|
+
setValue(instance, value);
|
|
153
172
|
}
|
|
154
173
|
}).catch(() => {
|
|
155
174
|
if (actual === state.promise) state.promise = void 0;
|
|
156
175
|
});
|
|
157
|
-
} else setValue(
|
|
176
|
+
} else setValue(instance, actual);
|
|
158
177
|
} catch {} finally {
|
|
159
178
|
onAfter?.();
|
|
160
179
|
}
|
|
161
180
|
}
|
|
162
|
-
function
|
|
163
|
-
let peeked = value;
|
|
164
|
-
if (
|
|
181
|
+
function peekSignalValue(copy) {
|
|
182
|
+
let peeked = Array.isArray(this) ? this[1] : this[SYMBOL_STATE].value;
|
|
183
|
+
if (copy !== true) return peeked;
|
|
165
184
|
if (Array.isArray(peeked)) peeked = peeked.slice();
|
|
166
185
|
else if (isPlainObject(peeked)) peeked = { ...peeked };
|
|
167
186
|
return peeked;
|
|
168
187
|
}
|
|
169
|
-
function
|
|
188
|
+
function updateSignalValue(instance, callback, setValue) {
|
|
170
189
|
if (typeof callback !== "function") throw new TypeError("Callback must be a function");
|
|
171
|
-
|
|
190
|
+
handleSignalValue(instance, callback(instance[SYMBOL_STATE].value), setValue);
|
|
172
191
|
}
|
|
173
192
|
//#endregion
|
|
174
193
|
//#region src/batch.ts
|
|
@@ -183,7 +202,7 @@ function flushHandlers() {
|
|
|
183
202
|
for (let index = 0; index < length; index += 1) {
|
|
184
203
|
const [, handler] = handlers[index];
|
|
185
204
|
const subscription = handler;
|
|
186
|
-
if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) :
|
|
205
|
+
if (typeof subscription.frozen === "boolean") subscription.callback(subscription.frozen ? getFrozenValue(subscription.state.value) : peekSignalValue.call(subscription.instance, subscription.copy));
|
|
187
206
|
else runEffect(handler);
|
|
188
207
|
}
|
|
189
208
|
}
|
|
@@ -423,6 +442,14 @@ function filter(array, ...parameters) {
|
|
|
423
442
|
filter.remove = exclude;
|
|
424
443
|
Object.defineProperty(filter, "remove", { value: exclude });
|
|
425
444
|
//#endregion
|
|
445
|
+
//#region src/helpers/misc.ts
|
|
446
|
+
function getState(value, options) {
|
|
447
|
+
return {
|
|
448
|
+
value,
|
|
449
|
+
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : void 0
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
//#endregion
|
|
426
453
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/abort.mjs
|
|
427
454
|
function createAborter(value, onAbort) {
|
|
428
455
|
if (!(value instanceof AbortSignal)) return;
|
|
@@ -437,13 +464,54 @@ const ABORT_EVENT = "abort";
|
|
|
437
464
|
const ABORT_OPTIONS = { once: true };
|
|
438
465
|
//#endregion
|
|
439
466
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/subscription.mjs
|
|
440
|
-
|
|
441
|
-
|
|
467
|
+
const SUBSCRIPTION_NAME = "subscription";
|
|
468
|
+
const SUBSCRIPTION_PROPERTY = "$subscription";
|
|
469
|
+
const SUBSCRIPTION_STORE = "subscriptions";
|
|
470
|
+
function Subscription(state, property, parameters) {
|
|
471
|
+
Object.defineProperty(this, SUBSCRIPTION_SYMBOL, { value: state });
|
|
472
|
+
state.aborter = createAborter(parameters.signal, () => this.unsubscribe(subscriptions, this, state));
|
|
473
|
+
Object.defineProperties(this, {
|
|
474
|
+
[property.key]: { value: property.value },
|
|
475
|
+
active: {
|
|
476
|
+
enumerable: true,
|
|
477
|
+
get: () => (state.parameters?.isActive?.() ?? true) && state.active
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
addSubscription(this);
|
|
481
|
+
}
|
|
482
|
+
Object.defineProperties(Subscription.prototype, {
|
|
483
|
+
[SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_NAME },
|
|
484
|
+
unsubscribe: { value: removeSubscription }
|
|
485
|
+
});
|
|
486
|
+
function Subscriptions(parameters) {
|
|
487
|
+
const { keys, property } = createSubscriptionsParameters(parameters);
|
|
488
|
+
Object.defineProperty(this, SUBSCRIPTION_SYMBOL, { value: createSubscriptionsState(property, keys) });
|
|
489
|
+
}
|
|
490
|
+
Object.defineProperties(Subscriptions.prototype, {
|
|
491
|
+
[SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_STORE },
|
|
492
|
+
clear: { value: clearSubscriptions },
|
|
493
|
+
create: { value: createSubscription },
|
|
494
|
+
items: {
|
|
495
|
+
enumerable: true,
|
|
496
|
+
get() {
|
|
497
|
+
return this[SUBSCRIPTION_SYMBOL].items;
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
values: {
|
|
501
|
+
enumerable: true,
|
|
502
|
+
get() {
|
|
503
|
+
return this[SUBSCRIPTION_SYMBOL].values;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
function addSubscription(instance) {
|
|
508
|
+
const state = instance[SUBSCRIPTION_SYMBOL];
|
|
442
509
|
const { key, value } = state.parameters;
|
|
510
|
+
const { items, values } = state.subscriptions;
|
|
443
511
|
if (!isKey(key)) {
|
|
444
|
-
items.any.add(
|
|
445
|
-
values.from.any.set(value,
|
|
446
|
-
values.to.any.set(
|
|
512
|
+
items.any.add(instance);
|
|
513
|
+
values.from.any.set(value, instance);
|
|
514
|
+
values.to.any.set(instance, value);
|
|
447
515
|
return;
|
|
448
516
|
}
|
|
449
517
|
/* istanbul ignore if */
|
|
@@ -455,29 +523,32 @@ function addSubscription(subscriptions, subscription, state) {
|
|
|
455
523
|
keyedItems = /* @__PURE__ */ new Set();
|
|
456
524
|
items.keyed.set(key, keyedItems);
|
|
457
525
|
}
|
|
458
|
-
keyedItems.add(
|
|
526
|
+
keyedItems.add(instance);
|
|
459
527
|
let keyedFrom = values.from.keyed.get(key);
|
|
460
528
|
if (keyedFrom == null) {
|
|
461
529
|
keyedFrom = /* @__PURE__ */ new Map();
|
|
462
530
|
values.from.keyed.set(key, keyedFrom);
|
|
463
531
|
}
|
|
464
|
-
keyedFrom.set(value,
|
|
532
|
+
keyedFrom.set(value, instance);
|
|
465
533
|
let keyedTo = values.to.keyed.get(key);
|
|
466
534
|
if (keyedTo == null) {
|
|
467
535
|
keyedTo = /* @__PURE__ */ new Map();
|
|
468
536
|
values.to.keyed.set(key, keyedTo);
|
|
469
537
|
}
|
|
470
|
-
keyedTo.set(
|
|
538
|
+
keyedTo.set(instance, value);
|
|
471
539
|
}
|
|
472
|
-
function clearSubscriptions(
|
|
473
|
-
|
|
474
|
-
|
|
540
|
+
function clearSubscriptions() {
|
|
541
|
+
const state = this[SUBSCRIPTION_SYMBOL];
|
|
542
|
+
for (const susbcription of state.values.to.any.keys()) susbcription.unsubscribe();
|
|
543
|
+
if (state.values.to.keyed != null && state.values.to.keyed.size > 0) for (const values of state.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
|
|
475
544
|
}
|
|
476
|
-
function createSubscription(
|
|
545
|
+
function createSubscription(params) {
|
|
477
546
|
const parameters = createSubscriptionParameters(params);
|
|
478
547
|
if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
|
|
548
|
+
const subscriptions = this[SUBSCRIPTION_SYMBOL];
|
|
479
549
|
const state = {
|
|
480
550
|
parameters,
|
|
551
|
+
subscriptions,
|
|
481
552
|
active: true
|
|
482
553
|
};
|
|
483
554
|
const existing = getExistingSubscription(subscriptions, state);
|
|
@@ -486,18 +557,7 @@ function createSubscription(subscriptions, property, params) {
|
|
|
486
557
|
if (subscriptions.keys === false) throw new Error(SUBSCRIPTION_DISALLOWED_KEY);
|
|
487
558
|
else if (subscriptions.keys !== true && !subscriptions.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
|
|
488
559
|
}
|
|
489
|
-
|
|
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];
|
|
560
|
+
return [new Subscription(state, subscriptions.property, parameters), false];
|
|
501
561
|
}
|
|
502
562
|
function getExistingSubscription(subscriptions, state) {
|
|
503
563
|
const { values } = subscriptions;
|
|
@@ -531,9 +591,10 @@ function createSubscriptionsProperty(input) {
|
|
|
531
591
|
value: values.value == null ? SUBSCRIPTION_NAME : values.value
|
|
532
592
|
};
|
|
533
593
|
}
|
|
534
|
-
function createSubscriptionsState(keys) {
|
|
594
|
+
function createSubscriptionsState(property, keys) {
|
|
535
595
|
return {
|
|
536
596
|
keys,
|
|
597
|
+
property,
|
|
537
598
|
items: {
|
|
538
599
|
any: /* @__PURE__ */ new Set(),
|
|
539
600
|
keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
|
|
@@ -560,16 +621,17 @@ function removeFromStore(items, values, subscription, value, key) {
|
|
|
560
621
|
values.to.keyed?.get(key)?.delete(subscription);
|
|
561
622
|
}
|
|
562
623
|
}
|
|
563
|
-
function removeSubscription(
|
|
624
|
+
function removeSubscription() {
|
|
625
|
+
const state = this[SUBSCRIPTION_SYMBOL];
|
|
564
626
|
if (!state.active) return;
|
|
565
627
|
state.aborter = void 0;
|
|
566
628
|
state.active = false;
|
|
567
|
-
|
|
568
|
-
state.parameters.signal = void 0;
|
|
569
|
-
const { items, values } = subscriptionsState;
|
|
629
|
+
const { items, values } = state.subscriptions;
|
|
570
630
|
const { key, value } = state.parameters;
|
|
631
|
+
state.parameters = void 0;
|
|
632
|
+
state.subscriptions = void 0;
|
|
571
633
|
if (!isKey(key)) {
|
|
572
|
-
removeFromStore(items.any, values,
|
|
634
|
+
removeFromStore(items.any, values, this, value);
|
|
573
635
|
return;
|
|
574
636
|
}
|
|
575
637
|
const keyed = items.keyed?.get(key);
|
|
@@ -577,7 +639,7 @@ function removeSubscription(subscriptionsState, subscription, state) {
|
|
|
577
639
|
if (items.keyed == null || keyed == null)
|
|
578
640
|
// istanbul ignore next
|
|
579
641
|
return;
|
|
580
|
-
removeFromStore(keyed, values,
|
|
642
|
+
removeFromStore(keyed, values, this, value, key);
|
|
581
643
|
if (keyed.size === 0) items.keyed.delete(key);
|
|
582
644
|
}
|
|
583
645
|
/**
|
|
@@ -587,72 +649,50 @@ function removeSubscription(subscriptionsState, subscription, state) {
|
|
|
587
649
|
* @returns Subscription store
|
|
588
650
|
*/
|
|
589
651
|
function subscriptions(parameters) {
|
|
590
|
-
|
|
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);
|
|
652
|
+
return new Subscriptions(parameters);
|
|
612
653
|
}
|
|
613
654
|
const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
|
|
614
655
|
const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
|
|
615
656
|
const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
|
|
616
|
-
const
|
|
617
|
-
const SUBSCRIPTION_PROPERTY = "$subscriptions";
|
|
618
|
-
const SUBSCRIPTION_STORE = "subscriptions";
|
|
657
|
+
const SUBSCRIPTION_SYMBOL = Symbol(SUBSCRIPTION_PROPERTY);
|
|
619
658
|
//#endregion
|
|
620
659
|
//#region src/helpers/subscription.ts
|
|
621
|
-
function subscribeToProxy(
|
|
622
|
-
if (isKey(first)) return getReactiveValueInProxy(
|
|
623
|
-
return subscribeToSignal(
|
|
660
|
+
function subscribeToProxy(first, second, third) {
|
|
661
|
+
if (isKey(first)) return getReactiveValueInProxy(this, first).subscribe(second, third);
|
|
662
|
+
return subscribeToSignal.call(this, first, second);
|
|
624
663
|
}
|
|
625
|
-
function subscribeToReactive(type,
|
|
626
|
-
|
|
664
|
+
function subscribeToReactive(type, subscriber) {
|
|
665
|
+
this[SYMBOL_STATE].subscriptions ??= subscriptions({
|
|
627
666
|
keys: SUBSCRIPTION_TYPES,
|
|
628
667
|
property: SUBSCRIPTION_PROPERTY$1
|
|
629
668
|
});
|
|
630
|
-
const [subscription, existing] =
|
|
669
|
+
const [subscription, existing] = this[SYMBOL_STATE].subscriptions.create({
|
|
631
670
|
key: type,
|
|
632
|
-
value:
|
|
671
|
+
value: subscriber
|
|
633
672
|
});
|
|
634
|
-
if (!existing)
|
|
673
|
+
if (!existing) subscriber(type === "frozen" ? getFrozenValue(this[SYMBOL_STATE].value) : peekSignalValue.call(this, SUBSCRIPTION_TYPES_COPY.has(type)), subscription);
|
|
635
674
|
return subscription;
|
|
636
675
|
}
|
|
637
|
-
function
|
|
638
|
-
return subscribeToReactive(
|
|
676
|
+
function subscribeToReadonly(subscriber) {
|
|
677
|
+
return subscribeToReactive.call(this, this.frozen ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_READONLY, subscriber);
|
|
639
678
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
function reactive(value, options) {
|
|
643
|
-
const state = {
|
|
644
|
-
computeds: /* @__PURE__ */ new Set(),
|
|
645
|
-
effects: /* @__PURE__ */ new Set(),
|
|
646
|
-
equal: typeof options === "object" && typeof options?.equal === "function" ? options.equal : Object.is,
|
|
647
|
-
value
|
|
648
|
-
};
|
|
649
|
-
return [{
|
|
650
|
-
toJSON: () => state.value,
|
|
651
|
-
toString: () => String(state.value)
|
|
652
|
-
}, state];
|
|
679
|
+
function subscribeToSignal(subscriber, copy) {
|
|
680
|
+
return subscribeToReactive.call(this, copy === true ? SUBSCRIPTION_TYPE_COPY : SUBSCRIPTION_TYPE_ORIGINAL, subscriber);
|
|
653
681
|
}
|
|
654
682
|
//#endregion
|
|
655
683
|
//#region src/value/computed.ts
|
|
684
|
+
function Computed(callback, options) {
|
|
685
|
+
this[SYMBOL_STATE] = getState(void 0, options);
|
|
686
|
+
this[SYMBOL_EFFECT] = getComputedEffect(this, callback);
|
|
687
|
+
}
|
|
688
|
+
Computed.prototype[NAME_MORA] = NAME_COMPUTED;
|
|
689
|
+
Computed.prototype.get = getComputedValue;
|
|
690
|
+
Computed.prototype.peek = peekSignalValue;
|
|
691
|
+
Computed.prototype.subscribe = subscribeToSignal;
|
|
692
|
+
Computed.prototype.toString = getStringValue;
|
|
693
|
+
Computed.prototype.toJSON = function() {
|
|
694
|
+
return this[SYMBOL_STATE].value;
|
|
695
|
+
};
|
|
656
696
|
/**
|
|
657
697
|
* Create a computed value
|
|
658
698
|
*
|
|
@@ -665,19 +705,10 @@ function computed(callback, options) {
|
|
|
665
705
|
}
|
|
666
706
|
function getComputed(callback, options) {
|
|
667
707
|
if (typeof callback !== "function") throw new TypeError("Computed callback must be a function");
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
const instance = {
|
|
671
|
-
...rx,
|
|
672
|
-
get: () => getValue(state, fx),
|
|
673
|
-
peek: (copy) => peekSimpleValue(state.value, copy === true),
|
|
674
|
-
subscribe: (callback, copy) => subscribeToSignal(state, callback, copy === true)
|
|
675
|
-
};
|
|
676
|
-
Object.defineProperty(instance, NAME_MORA, { value: NAME_COMPUTED });
|
|
677
|
-
fx = getComputedEffect(state, callback);
|
|
678
|
-
return [Object.freeze(instance), fx];
|
|
708
|
+
const instance = new Computed(callback, options);
|
|
709
|
+
return [instance, instance[SYMBOL_EFFECT]];
|
|
679
710
|
}
|
|
680
|
-
function getComputedEffect(
|
|
711
|
+
function getComputedEffect(instance, callback) {
|
|
681
712
|
const fx = {
|
|
682
713
|
dirty: true,
|
|
683
714
|
instance: void 0
|
|
@@ -686,7 +717,7 @@ function getComputedEffect(state, callback) {
|
|
|
686
717
|
if (fx.dirty) {
|
|
687
718
|
const previousComputed = ACTIVE.computed;
|
|
688
719
|
ACTIVE.computed = fx;
|
|
689
|
-
|
|
720
|
+
handleSignalValue(instance, callback, setAndEmit$1, () => {
|
|
690
721
|
ACTIVE.computed = previousComputed;
|
|
691
722
|
});
|
|
692
723
|
fx.dirty = false;
|
|
@@ -694,69 +725,116 @@ function getComputedEffect(state, callback) {
|
|
|
694
725
|
});
|
|
695
726
|
return fx;
|
|
696
727
|
}
|
|
697
|
-
function
|
|
698
|
-
|
|
699
|
-
|
|
728
|
+
function getComputedValue() {
|
|
729
|
+
const fx = this[SYMBOL_EFFECT];
|
|
730
|
+
const state = this[SYMBOL_STATE];
|
|
731
|
+
if (ACTIVE.computed != null && fx !== ACTIVE.computed) {
|
|
732
|
+
state.computeds ??= /* @__PURE__ */ new Set();
|
|
733
|
+
state.computeds.add(ACTIVE.computed);
|
|
734
|
+
}
|
|
735
|
+
if (ACTIVE.effect != null && ACTIVE.effect !== fx.instance) {
|
|
736
|
+
state.effects ??= /* @__PURE__ */ new Set();
|
|
737
|
+
state.effects.add(ACTIVE.effect);
|
|
738
|
+
}
|
|
700
739
|
if (fx.dirty && BATCH.depth === 0) runEffect(fx.instance);
|
|
701
740
|
return state.value;
|
|
702
741
|
}
|
|
703
742
|
function internalComputed(callback, options) {
|
|
704
743
|
return getComputed(callback, options);
|
|
705
744
|
}
|
|
706
|
-
function setAndEmit$1(
|
|
707
|
-
|
|
745
|
+
function setAndEmit$1(instance, value) {
|
|
746
|
+
const state = instance[SYMBOL_STATE];
|
|
747
|
+
if ((state.equal ?? Object.is)(state.value, value)) return;
|
|
708
748
|
state.value = value;
|
|
709
|
-
for (const computed of state.computeds) computed.dirty = true;
|
|
710
|
-
for (const effect of state.effects) BATCH.handlers.set(effect, effect);
|
|
749
|
+
if (state.computeds != null && state.computeds.size > 0) for (const computed of state.computeds) computed.dirty = true;
|
|
750
|
+
if (state.effects != null && state.effects.size > 0) for (const effect of state.effects) BATCH.handlers.set(effect, effect);
|
|
711
751
|
for (const type of SUBSCRIPTION_TYPES) {
|
|
712
752
|
if (type === "frozen") continue;
|
|
713
|
-
const copy = SUBSCRIPTION_TYPES_COPY.has(type);
|
|
714
753
|
const subscriptions = state.subscriptions?.values.to.keyed?.get(type);
|
|
715
|
-
if (subscriptions != null
|
|
754
|
+
if (subscriptions != null && subscriptions.size > 0) {
|
|
755
|
+
const copy = SUBSCRIPTION_TYPES_COPY.has(type);
|
|
756
|
+
for (const [, callback] of subscriptions) callback(peekSignalValue.call(instance, copy));
|
|
757
|
+
}
|
|
716
758
|
}
|
|
717
759
|
flushHandlers();
|
|
718
760
|
}
|
|
719
761
|
//#endregion
|
|
720
762
|
//#region src/helpers/proxy.ts
|
|
721
|
-
function emitProxyValues(
|
|
722
|
-
const
|
|
763
|
+
function emitProxyValues() {
|
|
764
|
+
const state = this[SYMBOL_STATE];
|
|
765
|
+
state.mapped ??= /* @__PURE__ */ new Map();
|
|
766
|
+
const values = [...state.mapped.values()];
|
|
723
767
|
const { length } = values;
|
|
724
768
|
for (let index = 0; index < length; index += 1) values[index][1].dirty = true;
|
|
725
|
-
emitValue(
|
|
769
|
+
emitValue(this);
|
|
726
770
|
}
|
|
727
|
-
function getReactiveValueInProxy(
|
|
771
|
+
function getReactiveValueInProxy(instance, key) {
|
|
772
|
+
const state = instance[SYMBOL_STATE];
|
|
773
|
+
state.mapped ??= /* @__PURE__ */ new Map();
|
|
728
774
|
const mapKey = String(key);
|
|
729
|
-
let item = mapped.get(mapKey);
|
|
775
|
+
let item = state.mapped.get(mapKey);
|
|
730
776
|
if (item == null) {
|
|
731
|
-
item = internalComputed(() => isArray ?
|
|
732
|
-
mapped.set(mapKey, item);
|
|
777
|
+
item = internalComputed(() => state.isArray ? instance.get().at(key) : instance.get()[key]);
|
|
778
|
+
state.mapped.set(mapKey, item);
|
|
733
779
|
}
|
|
734
780
|
return item[0];
|
|
735
781
|
}
|
|
736
|
-
function getValueInProxy(
|
|
737
|
-
if (isArray ? typeof first === "number" : isKey(first)) return getReactiveValueInProxy(
|
|
738
|
-
return
|
|
782
|
+
function getValueInProxy(first) {
|
|
783
|
+
if (this[SYMBOL_STATE].isArray ? typeof first === "number" : isKey(first)) return getReactiveValueInProxy(this, first).get();
|
|
784
|
+
return getSignalValue.call(this);
|
|
739
785
|
}
|
|
740
786
|
function isProxyObject(isArray, value) {
|
|
741
787
|
return value == null || (isArray ? Array.isArray(value) : isPlainObject(value));
|
|
742
788
|
}
|
|
743
|
-
function peekValueInProxy(
|
|
789
|
+
function peekValueInProxy(first, second) {
|
|
790
|
+
const state = this[SYMBOL_STATE];
|
|
744
791
|
let value;
|
|
745
|
-
if (isArray ? typeof first === "number" : isKey(first)) value = isArray ? state.value.at(first) : state.value[first];
|
|
792
|
+
if (state.isArray ? typeof first === "number" : isKey(first)) value = state.isArray ? state.value.at(first) : state.value[first];
|
|
746
793
|
else value = state.value;
|
|
747
|
-
return
|
|
794
|
+
return peekSignalValue.call([this, value], first === true || second === true);
|
|
795
|
+
}
|
|
796
|
+
function setProxyObject(state, value) {
|
|
797
|
+
if (state.isArray) {
|
|
798
|
+
state.value.splice(0, state.value.length, ...value ?? []);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
startBatch();
|
|
802
|
+
const actual = value ?? {};
|
|
803
|
+
const proxy = state.value;
|
|
804
|
+
const proxyKeys = Object.keys(proxy);
|
|
805
|
+
const actualKeys = Object.keys(actual);
|
|
806
|
+
let { length } = proxyKeys;
|
|
807
|
+
for (let index = 0; index < length; index += 1) {
|
|
808
|
+
const key = proxyKeys[index];
|
|
809
|
+
proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
|
|
810
|
+
}
|
|
811
|
+
length = actualKeys.length;
|
|
812
|
+
for (let index = 0; index < length; index += 1) {
|
|
813
|
+
const key = actualKeys[index];
|
|
814
|
+
if (!proxyKeys.includes(key)) proxy[key] = actual[key];
|
|
815
|
+
}
|
|
816
|
+
stopBatch();
|
|
817
|
+
}
|
|
818
|
+
function setProxyProperty(state, property, value) {
|
|
819
|
+
if (!state.isArray) {
|
|
820
|
+
state.value[property] = value;
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
const actual = property < 0 ? state.value.length + property : property;
|
|
824
|
+
if (actual > -1) state.value[actual] = value;
|
|
748
825
|
}
|
|
749
|
-
function setProxyValue(
|
|
750
|
-
|
|
826
|
+
function setProxyValue(first, second) {
|
|
827
|
+
const state = this[SYMBOL_STATE];
|
|
828
|
+
if (state.isArray && first === "length") {
|
|
751
829
|
state.value.length = second;
|
|
752
830
|
return;
|
|
753
831
|
}
|
|
754
|
-
if (isProxyObject(isArray, first)) {
|
|
755
|
-
|
|
832
|
+
if (isProxyObject(state.isArray, first)) {
|
|
833
|
+
setProxyObject(state, first);
|
|
756
834
|
return;
|
|
757
835
|
}
|
|
758
|
-
const property = isArray ? typeof first === "number" : isKey(first);
|
|
759
|
-
if (isArray && property && Number.isNaN(first)) return;
|
|
836
|
+
const property = state.isArray ? typeof first === "number" : isKey(first);
|
|
837
|
+
if (state.isArray && property && Number.isNaN(first)) return;
|
|
760
838
|
let actual = property ? second : first;
|
|
761
839
|
if (typeof actual === "function") try {
|
|
762
840
|
actual = actual();
|
|
@@ -771,208 +849,213 @@ function setProxyValue(isArray, state, setObject, setProperty, first, second) {
|
|
|
771
849
|
actual.then((value) => {
|
|
772
850
|
if (property && state.promises.get(first) === actual) {
|
|
773
851
|
state.promises.delete(first);
|
|
774
|
-
|
|
852
|
+
setProxyProperty(state, first, value);
|
|
775
853
|
return;
|
|
776
854
|
}
|
|
777
|
-
if (!property && isProxyObject(isArray, value) && state.promise === actual) {
|
|
855
|
+
if (!property && isProxyObject(state.isArray, value) && state.promise === actual) {
|
|
778
856
|
state.promise = void 0;
|
|
779
|
-
|
|
857
|
+
setProxyObject(state, value);
|
|
780
858
|
}
|
|
781
859
|
}).catch(() => {
|
|
782
860
|
if (property && state.promises.get(first) === actual) state.promises.delete(first);
|
|
783
861
|
else if (!property && state.promise === actual) state.promise = void 0;
|
|
784
862
|
});
|
|
785
|
-
} else if (property)
|
|
786
|
-
else if (isProxyObject(isArray, actual))
|
|
863
|
+
} else if (property) setProxyProperty(state, first, actual);
|
|
864
|
+
else if (isProxyObject(state.isArray, actual)) setProxyObject(state, actual);
|
|
787
865
|
}
|
|
788
|
-
function setValueInProxy(
|
|
789
|
-
|
|
866
|
+
function setValueInProxy(instance, target, property, value) {
|
|
867
|
+
const state = instance[SYMBOL_STATE];
|
|
868
|
+
if (state.isArray) {
|
|
790
869
|
if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
|
|
791
870
|
}
|
|
792
871
|
const previous = Reflect.get(target, property);
|
|
793
|
-
if (!state.equal(previous, value)) {
|
|
872
|
+
if (!(state.equal ?? Object.is)(previous, value)) {
|
|
794
873
|
Reflect.set(target, property, value);
|
|
795
|
-
emitValue(
|
|
796
|
-
if (isArray) length?.set(target.length);
|
|
874
|
+
emitValue(instance);
|
|
875
|
+
if (state.isArray) state.length?.set(target.length);
|
|
797
876
|
}
|
|
798
877
|
return true;
|
|
799
878
|
}
|
|
800
|
-
function updateProxyValue(
|
|
879
|
+
function updateProxyValue(callback) {
|
|
801
880
|
if (typeof callback !== "function") throw new TypeError("Callback must be a function");
|
|
802
|
-
setProxyValue(
|
|
881
|
+
setProxyValue.call(this, callback(this[SYMBOL_STATE].value));
|
|
803
882
|
}
|
|
804
883
|
//#endregion
|
|
805
884
|
//#region src/value/readonly.ts
|
|
806
|
-
function
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
885
|
+
function Readonly(state, frozen) {
|
|
886
|
+
this[SYMBOL_STATE] = state;
|
|
887
|
+
Object.defineProperty(this, SUBSCRIPTION_TYPE_FROZEN, {
|
|
888
|
+
enumerable: true,
|
|
889
|
+
value: frozen
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
Readonly.prototype[NAME_MORA] = NAME_READONLY;
|
|
893
|
+
Readonly.prototype.subscribe = subscribeToReadonly;
|
|
894
|
+
Readonly.prototype.toString = getStringValue;
|
|
895
|
+
Readonly.prototype.get = function() {
|
|
896
|
+
return getReadonlyValue(this, false, this[SUBSCRIPTION_TYPE_FROZEN]);
|
|
897
|
+
};
|
|
898
|
+
Readonly.prototype.peek = function(copy) {
|
|
899
|
+
return getReadonlyValue(this, true, this[SUBSCRIPTION_TYPE_FROZEN], copy);
|
|
900
|
+
};
|
|
901
|
+
Readonly.prototype.toJSON = function() {
|
|
902
|
+
return this[SYMBOL_STATE].value;
|
|
903
|
+
};
|
|
904
|
+
function getReadonlyInstance(frozen) {
|
|
905
|
+
const key = frozen === true ? SUBSCRIPTION_TYPE_FROZEN : SUBSCRIPTION_TYPE_ORIGINAL;
|
|
906
|
+
this[SYMBOL_STATE].readonlies ??= {};
|
|
907
|
+
this[SYMBOL_STATE].readonlies[key] ??= getReadonlySignal(this[SYMBOL_STATE], frozen === true);
|
|
908
|
+
return this[SYMBOL_STATE].readonlies[key];
|
|
810
909
|
}
|
|
811
910
|
function getReadonlySignal(state, frozen) {
|
|
812
|
-
|
|
813
|
-
const instance = {
|
|
814
|
-
get: () => getReadonlyValue(state, false, frozen),
|
|
815
|
-
peek: (copy) => getReadonlyValue(state, true, frozen, copy),
|
|
816
|
-
subscribe: (callback) => subscribeToReactive(type, state, callback)
|
|
817
|
-
};
|
|
818
|
-
Object.defineProperties(instance, {
|
|
819
|
-
[NAME_MORA]: { value: NAME_READONLY },
|
|
820
|
-
frozen: {
|
|
821
|
-
enumerable: true,
|
|
822
|
-
value: frozen
|
|
823
|
-
}
|
|
824
|
-
});
|
|
825
|
-
return Object.freeze(instance);
|
|
911
|
+
return new Readonly(state, frozen);
|
|
826
912
|
}
|
|
827
|
-
function getReadonlyValue(
|
|
913
|
+
function getReadonlyValue(instance, peek, frozen, copy) {
|
|
828
914
|
let value;
|
|
829
|
-
if (peek) value =
|
|
830
|
-
else value =
|
|
915
|
+
if (peek) value = peekSignalValue.call(instance, copy === true);
|
|
916
|
+
else value = getSignalValue.call(instance);
|
|
831
917
|
return frozen ? getFrozenValue(value) : value;
|
|
832
918
|
}
|
|
833
919
|
//#endregion
|
|
834
920
|
//#region src/value/signal.ts
|
|
835
|
-
function
|
|
836
|
-
|
|
921
|
+
function Signal(value, options) {
|
|
922
|
+
this[SYMBOL_STATE] = getState(void 0, options);
|
|
923
|
+
handleSignalValue(this, value, setAndEmit);
|
|
924
|
+
}
|
|
925
|
+
Signal.prototype[NAME_MORA] = NAME_SIGNAL;
|
|
926
|
+
Signal.prototype.asReadonly = getReadonlyInstance;
|
|
927
|
+
Signal.prototype.get = getSignalValue;
|
|
928
|
+
Signal.prototype.peek = peekSignalValue;
|
|
929
|
+
Signal.prototype.subscribe = subscribeToSignal;
|
|
930
|
+
Signal.prototype.toString = getStringValue;
|
|
931
|
+
Signal.prototype.set = function(value) {
|
|
932
|
+
return handleSignalValue(this, value, setAndEmit);
|
|
933
|
+
};
|
|
934
|
+
Signal.prototype.toJSON = function() {
|
|
935
|
+
return this[SYMBOL_STATE].value;
|
|
936
|
+
};
|
|
937
|
+
Signal.prototype.update = function(callback) {
|
|
938
|
+
return updateSignalValue(this, callback, setAndEmit);
|
|
939
|
+
};
|
|
940
|
+
function setAndEmit(instance, value) {
|
|
941
|
+
const state = instance[SYMBOL_STATE];
|
|
942
|
+
if (!(state.equal ?? Object.is)(state.value, value)) {
|
|
837
943
|
state.value = value;
|
|
838
|
-
emitValue(
|
|
944
|
+
emitValue(instance);
|
|
839
945
|
}
|
|
840
946
|
}
|
|
841
947
|
function signal(value, options) {
|
|
842
|
-
|
|
843
|
-
const readonlies = {};
|
|
844
|
-
const instance = {
|
|
845
|
-
...rx,
|
|
846
|
-
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
847
|
-
get: () => getSimpleValue(state),
|
|
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)
|
|
852
|
-
};
|
|
853
|
-
Object.defineProperty(instance, NAME_MORA, { value: NAME_SIGNAL });
|
|
854
|
-
handleSimpleValue(state, value, setAndEmit);
|
|
855
|
-
return Object.freeze(instance);
|
|
948
|
+
return new Signal(value, options);
|
|
856
949
|
}
|
|
857
950
|
//#endregion
|
|
858
951
|
//#region src/value/array.ts
|
|
859
|
-
function
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
const readonlies = {};
|
|
865
|
-
state.value = new Proxy([], {
|
|
866
|
-
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, state, length) : Reflect.get(target, property),
|
|
867
|
-
set: (target, property, value) => setValueInProxy(isArray, state, target, property, value, length)
|
|
868
|
-
});
|
|
869
|
-
function get(value) {
|
|
870
|
-
return value === "length" ? length.get() : getValueInProxy(isArray, instance, state, mapped, value);
|
|
871
|
-
}
|
|
872
|
-
function set(first, second) {
|
|
873
|
-
setProxyValue(true, state, setArrayValue, setAtIndex, first, second);
|
|
874
|
-
}
|
|
875
|
-
const instance = {
|
|
876
|
-
...rx,
|
|
877
|
-
asReadonly: (frozen) => getReadonlyInstance(state, readonlies, frozen === true),
|
|
878
|
-
at: (index) => get(index),
|
|
879
|
-
clear: () => {
|
|
880
|
-
state.value.length = 0;
|
|
881
|
-
},
|
|
882
|
-
filter: (callback) => computed(() => filter(get(), callback)),
|
|
883
|
-
get: (value) => get(value),
|
|
884
|
-
map: (callback) => computed(() => get().map(callback)),
|
|
885
|
-
notify: () => emitProxyValues(state, mapped),
|
|
886
|
-
peek: (first, second) => peekArrayValue(state, length, first, second),
|
|
887
|
-
pop: () => state.value.pop(),
|
|
888
|
-
push: (...items) => state.value.push(...items),
|
|
889
|
-
select: (filter, map) => computed(() => select(get(), filter, map)),
|
|
890
|
-
set: (first, second) => set(first, second),
|
|
891
|
-
shift: () => state.value.shift(),
|
|
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),
|
|
894
|
-
unshift: (...items) => state.value.unshift(...items),
|
|
895
|
-
update: (callback) => updateProxyValue(true, state, setArrayValue, setAtIndex, callback)
|
|
952
|
+
function ReactiveArray(value, options) {
|
|
953
|
+
this[SYMBOL_STATE] = {
|
|
954
|
+
...getState(void 0, options),
|
|
955
|
+
isArray: true,
|
|
956
|
+
length: signal(0)
|
|
896
957
|
};
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
958
|
+
this[SYMBOL_STATE].value = new Proxy([], {
|
|
959
|
+
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(this, property, target) : Reflect.get(target, property),
|
|
960
|
+
set: (target, property, value) => setValueInProxy(this, target, property, value)
|
|
961
|
+
});
|
|
962
|
+
Object.defineProperty(this, PROPERTY_LENGTH, {
|
|
963
|
+
enumerable: true,
|
|
964
|
+
get: () => this[SYMBOL_STATE].length.get(),
|
|
965
|
+
set: (value) => setArrayLength(this[SYMBOL_STATE], value)
|
|
904
966
|
});
|
|
905
|
-
|
|
906
|
-
|
|
967
|
+
setProxyValue.call(this, value);
|
|
968
|
+
}
|
|
969
|
+
ReactiveArray.prototype[NAME_MORA] = NAME_ARRAY;
|
|
970
|
+
ReactiveArray.prototype.asReadonly = getReadonlyInstance;
|
|
971
|
+
ReactiveArray.prototype.at = getArrayValues;
|
|
972
|
+
ReactiveArray.prototype.get = getArrayValues;
|
|
973
|
+
ReactiveArray.prototype.notify = emitProxyValues;
|
|
974
|
+
ReactiveArray.prototype.peek = peekArrayValue;
|
|
975
|
+
ReactiveArray.prototype.set = setProxyValue;
|
|
976
|
+
ReactiveArray.prototype.subscribe = subscribeToProxy;
|
|
977
|
+
ReactiveArray.prototype.toString = getStringValue;
|
|
978
|
+
ReactiveArray.prototype.update = updateProxyValue;
|
|
979
|
+
ReactiveArray.prototype.clear = function() {
|
|
980
|
+
this[SYMBOL_STATE].value.length = 0;
|
|
981
|
+
};
|
|
982
|
+
ReactiveArray.prototype.filter = function(callback) {
|
|
983
|
+
return computed(() => filter(getArrayValues.call(this), callback));
|
|
984
|
+
};
|
|
985
|
+
ReactiveArray.prototype.map = function(callback) {
|
|
986
|
+
return computed(() => getArrayValues.call(this).map(callback));
|
|
987
|
+
};
|
|
988
|
+
ReactiveArray.prototype.pop = function() {
|
|
989
|
+
return this[SYMBOL_STATE].value.pop();
|
|
990
|
+
};
|
|
991
|
+
ReactiveArray.prototype.push = function(...items) {
|
|
992
|
+
return this[SYMBOL_STATE].value.push(...items);
|
|
993
|
+
};
|
|
994
|
+
ReactiveArray.prototype.select = function(filter, map) {
|
|
995
|
+
return computed(() => select(getArrayValues.call(this), filter, map));
|
|
996
|
+
};
|
|
997
|
+
ReactiveArray.prototype.shift = function() {
|
|
998
|
+
return this[SYMBOL_STATE].value.shift();
|
|
999
|
+
};
|
|
1000
|
+
ReactiveArray.prototype.splice = function(from, to, ...items) {
|
|
1001
|
+
return this[SYMBOL_STATE].value.splice(from, to ?? this[SYMBOL_STATE].value.length, ...items);
|
|
1002
|
+
};
|
|
1003
|
+
ReactiveArray.prototype.toJSON = function() {
|
|
1004
|
+
return this[SYMBOL_STATE].value;
|
|
1005
|
+
};
|
|
1006
|
+
ReactiveArray.prototype.unshift = function(...items) {
|
|
1007
|
+
return this[SYMBOL_STATE].value.unshift(...items);
|
|
1008
|
+
};
|
|
1009
|
+
function array(value, options) {
|
|
1010
|
+
return new ReactiveArray(value, options);
|
|
907
1011
|
}
|
|
908
|
-
function
|
|
909
|
-
return
|
|
1012
|
+
function getArrayValues(value) {
|
|
1013
|
+
return value === "length" ? this[SYMBOL_STATE].length.get() : getValueInProxy.call(this, value);
|
|
1014
|
+
}
|
|
1015
|
+
function peekArrayValue(first, second) {
|
|
1016
|
+
return first === "length" ? this[SYMBOL_STATE].length.peek() : peekValueInProxy.call(this, first, second);
|
|
910
1017
|
}
|
|
911
1018
|
function setArrayLength(state, value) {
|
|
912
1019
|
if (typeof value === "number" && !Number.isNaN(value) && value >= 0 && value !== state.value.length) state.value.length = value;
|
|
913
1020
|
}
|
|
914
|
-
function
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
function setAtIndex(state, index, value) {
|
|
918
|
-
const actual = index < 0 ? state.value.length + index : index;
|
|
919
|
-
if (actual > -1) state.value[actual] = value;
|
|
920
|
-
}
|
|
921
|
-
function updateArray(type, array, state, length) {
|
|
1021
|
+
function updateArray(instance, type, array) {
|
|
1022
|
+
const state = instance[SYMBOL_STATE];
|
|
922
1023
|
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
923
1024
|
const previousArray = affectsLength ? [] : array.slice();
|
|
924
1025
|
const previousLength = array.length;
|
|
925
1026
|
return (...args) => {
|
|
926
1027
|
const result = array[type](...args);
|
|
927
1028
|
if (affectsLength ? array.length !== previousLength : !equalArrays(state, previousArray, array)) {
|
|
928
|
-
emitValue(
|
|
929
|
-
length.set(array.length);
|
|
1029
|
+
emitValue(instance);
|
|
1030
|
+
state.length.set(array.length);
|
|
930
1031
|
}
|
|
931
1032
|
return result;
|
|
932
1033
|
};
|
|
933
1034
|
}
|
|
934
1035
|
//#endregion
|
|
935
1036
|
//#region src/value/store.ts
|
|
936
|
-
function
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
startBatch();
|
|
941
|
-
const actual = value ?? {};
|
|
942
|
-
const proxy = state.value;
|
|
943
|
-
const proxyKeys = Object.keys(proxy);
|
|
944
|
-
const actualKeys = Object.keys(actual);
|
|
945
|
-
let { length } = proxyKeys;
|
|
946
|
-
for (let index = 0; index < length; index += 1) {
|
|
947
|
-
const key = proxyKeys[index];
|
|
948
|
-
proxy[key] = actualKeys.includes(key) ? actual[key] : void 0;
|
|
949
|
-
}
|
|
950
|
-
length = actualKeys.length;
|
|
951
|
-
for (let index = 0; index < length; index += 1) {
|
|
952
|
-
const key = actualKeys[index];
|
|
953
|
-
if (!proxyKeys.includes(key)) proxy[key] = actual[key];
|
|
954
|
-
}
|
|
955
|
-
stopBatch();
|
|
956
|
-
}
|
|
957
|
-
function store(value, options) {
|
|
958
|
-
const [rx, state] = reactive(void 0, options);
|
|
959
|
-
const isArray = false;
|
|
960
|
-
const keyed = /* @__PURE__ */ new Map();
|
|
961
|
-
const readonlies = {};
|
|
962
|
-
state.value = new Proxy({}, { set: (target, property, value) => setValueInProxy(isArray, state, target, property, value) });
|
|
963
|
-
const instance = {
|
|
964
|
-
...rx,
|
|
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)
|
|
1037
|
+
function ReactiveStore(value, options) {
|
|
1038
|
+
this[SYMBOL_STATE] = {
|
|
1039
|
+
...getState(void 0, options),
|
|
1040
|
+
isArray: false
|
|
972
1041
|
};
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
1042
|
+
this[SYMBOL_STATE].value = new Proxy({}, { set: (target, property, value) => setValueInProxy(this, target, property, value) });
|
|
1043
|
+
setProxyValue.call(this, value);
|
|
1044
|
+
}
|
|
1045
|
+
ReactiveStore.prototype[NAME_MORA] = NAME_STORE;
|
|
1046
|
+
ReactiveStore.prototype.asReadonly = getReadonlyInstance;
|
|
1047
|
+
ReactiveStore.prototype.get = getValueInProxy;
|
|
1048
|
+
ReactiveStore.prototype.notify = emitProxyValues;
|
|
1049
|
+
ReactiveStore.prototype.peek = peekValueInProxy;
|
|
1050
|
+
ReactiveStore.prototype.set = setProxyValue;
|
|
1051
|
+
ReactiveStore.prototype.subscribe = subscribeToProxy;
|
|
1052
|
+
ReactiveStore.prototype.toString = getStringValue;
|
|
1053
|
+
ReactiveStore.prototype.update = updateProxyValue;
|
|
1054
|
+
ReactiveStore.prototype.toJSON = function() {
|
|
1055
|
+
return this[SYMBOL_STATE].value;
|
|
1056
|
+
};
|
|
1057
|
+
function store(value, options) {
|
|
1058
|
+
return new ReactiveStore(value, options);
|
|
976
1059
|
}
|
|
977
1060
|
//#endregion
|
|
978
1061
|
export { array, computed, effect, isComputed, isEffect, isReactive, isReactiveArray, isReactiveStore, isReadonlySignal, isSignal, signal, startBatch, stopBatch, store };
|