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