@oscarpalmer/mora 0.23.0 → 0.25.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 +4 -2
- package/dist/effect.js +2 -2
- package/dist/helpers/is.js +3 -3
- package/dist/helpers/proxy.js +9 -5
- package/dist/mora.full.js +496 -583
- package/dist/value/array.js +5 -7
- package/dist/value/reactive.js +2 -1
- package/dist/value/store.js +5 -2
- package/package.json +11 -13
- package/src/batch.ts +1 -1
- package/src/constants.ts +7 -8
- package/src/effect.ts +5 -7
- package/src/helpers/is.ts +8 -11
- package/src/helpers/proxy.ts +35 -21
- package/src/helpers/value.ts +1 -7
- package/src/index.ts +1 -7
- package/src/value/array.ts +22 -64
- package/src/value/computed.ts +3 -0
- package/src/value/reactive.ts +2 -1
- package/src/value/signal.ts +2 -5
- package/src/value/store.ts +24 -22
- package/types/constants.d.ts +3 -1
- package/types/helpers/proxy.d.ts +3 -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 +11 -4
package/dist/mora.full.js
CHANGED
|
@@ -3,604 +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
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
33
34
|
]);
|
|
35
|
+
const PROPERTY_LENGTH = "length";
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
effect.state.callback();
|
|
51
|
-
}
|
|
52
|
-
finally {
|
|
53
|
-
ACTIVE.effect = previousEffect;
|
|
54
|
-
}
|
|
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
|
+
}
|
|
55
52
|
}
|
|
56
53
|
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
* Create an effect
|
|
55
|
+
* @param callback Callback for handling signal effects
|
|
56
|
+
* @returns Effect
|
|
57
|
+
*/
|
|
61
58
|
function effect(callback) {
|
|
62
|
-
|
|
63
|
-
? new Effect(callback)
|
|
64
|
-
: undefined;
|
|
59
|
+
return typeof callback === "function" ? new Effect(callback) : void 0;
|
|
65
60
|
}
|
|
66
61
|
|
|
67
62
|
/**
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
* Is the value a reactive array?
|
|
64
|
+
* @param value Value to check
|
|
65
|
+
* @returns True if value is a {@link ReactiveArray}
|
|
66
|
+
*/
|
|
72
67
|
function isArray(value) {
|
|
73
|
-
|
|
68
|
+
return isMora(value, NAME_ARRAY);
|
|
74
69
|
}
|
|
75
70
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
* Is the value a computed signal?
|
|
72
|
+
* @param value Value to check
|
|
73
|
+
* @returns True if value is a {@link Computed}
|
|
74
|
+
*/
|
|
80
75
|
function isComputed(value) {
|
|
81
|
-
|
|
76
|
+
return isMora(value, NAME_COMPUTED);
|
|
82
77
|
}
|
|
83
78
|
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
* Is the value an effect?
|
|
80
|
+
* @param value Value to check
|
|
81
|
+
* @returns True if value is an {@link Effect}
|
|
82
|
+
*/
|
|
88
83
|
function isEffect(value) {
|
|
89
|
-
|
|
84
|
+
return isMora(value, NAME_EFFECT);
|
|
90
85
|
}
|
|
91
86
|
function isMora(value, name) {
|
|
92
|
-
|
|
93
|
-
value != null &&
|
|
94
|
-
'$mora' in value &&
|
|
95
|
-
(typeof name === 'string'
|
|
96
|
-
? value.$mora === name
|
|
97
|
-
: name.has(value.$mora)));
|
|
87
|
+
return typeof value === "object" && value != null && NAME_MORA in value && (typeof name === "string" ? value[NAME_MORA] === name : name.has(value[NAME_MORA]));
|
|
98
88
|
}
|
|
99
89
|
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
* Is the value reactive?
|
|
91
|
+
* @param value Value to check
|
|
92
|
+
* @returns True if value is a {@link Reactive}
|
|
93
|
+
*/
|
|
104
94
|
function isReactive(value) {
|
|
105
|
-
|
|
95
|
+
return isMora(value, NAME_ALL);
|
|
106
96
|
}
|
|
107
97
|
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
* Is the value a signal?
|
|
99
|
+
* @param value Value to check
|
|
100
|
+
* @returns True if value is a {@link Signal}
|
|
101
|
+
*/
|
|
112
102
|
function isSignal(value) {
|
|
113
|
-
|
|
103
|
+
return isMora(value, NAME_SIGNAL);
|
|
114
104
|
}
|
|
115
105
|
|
|
116
106
|
function flushHandlers() {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
handler.callback(handler.state.value);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
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
|
+
}
|
|
129
113
|
}
|
|
130
114
|
/**
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
115
|
+
* Start batching effects
|
|
116
|
+
*
|
|
117
|
+
* _(Use {@link stopBatch} to flush and run batched effects)_
|
|
118
|
+
*/
|
|
135
119
|
function startBatch() {
|
|
136
|
-
|
|
120
|
+
BATCH.depth += 1;
|
|
137
121
|
}
|
|
138
122
|
/**
|
|
139
|
-
|
|
140
|
-
|
|
123
|
+
* Stop batching effects and flush _(run)_ them
|
|
124
|
+
*/
|
|
141
125
|
function stopBatch() {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
flushHandlers();
|
|
126
|
+
if (BATCH.depth > 0) BATCH.depth -= 1;
|
|
127
|
+
flushHandlers();
|
|
146
128
|
}
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
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() {}
|
|
162
144
|
function subscribe(state, callback) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
unsubscribe(state, callback);
|
|
169
|
-
};
|
|
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
|
+
};
|
|
170
150
|
}
|
|
171
151
|
function unsubscribe(state, callback) {
|
|
172
|
-
|
|
173
|
-
|
|
152
|
+
state.subscriptions.get(callback)?.destroy();
|
|
153
|
+
state.subscriptions.delete(callback);
|
|
174
154
|
}
|
|
175
155
|
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
unsubscribe(callback) {
|
|
227
|
-
unsubscribe(this.state, callback);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
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
|
+
};
|
|
230
206
|
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
get() {
|
|
265
|
-
if (ACTIVE.computed != null && this !== ACTIVE.computed) {
|
|
266
|
-
this.state.computeds.add(ACTIVE.computed);
|
|
267
|
-
}
|
|
268
|
-
if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) {
|
|
269
|
-
this.state.effects.add(ACTIVE.effect);
|
|
270
|
-
}
|
|
271
|
-
if (this.effect.dirty && BATCH.depth === 0) {
|
|
272
|
-
runEffect(this.effect.instance);
|
|
273
|
-
}
|
|
274
|
-
return this.state.value;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
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
|
+
};
|
|
277
239
|
/**
|
|
278
|
-
|
|
279
|
-
|
|
240
|
+
* Create a computed value
|
|
241
|
+
* @param callback Callback to compute the value
|
|
242
|
+
* @param options Reactivity options
|
|
243
|
+
* @returns Computed value
|
|
244
|
+
*/
|
|
280
245
|
function computed(callback, options) {
|
|
281
|
-
|
|
246
|
+
return new Computed(callback, options);
|
|
282
247
|
}
|
|
283
248
|
|
|
284
249
|
function emitValue(state) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
BATCH.handlers.add(effect);
|
|
290
|
-
}
|
|
291
|
-
for (const [, subscription] of state.subscriptions) {
|
|
292
|
-
BATCH.handlers.add(subscription);
|
|
293
|
-
}
|
|
294
|
-
if (BATCH.depth === 0) {
|
|
295
|
-
flushHandlers();
|
|
296
|
-
}
|
|
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();
|
|
297
254
|
}
|
|
298
255
|
function equalArrays(state, first, second) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
length -= offset;
|
|
314
|
-
for (let index = offset; index < length; index += 1) {
|
|
315
|
-
if (!state.equal(first[index], second[index])) {
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
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;
|
|
320
267
|
}
|
|
321
268
|
function getValue(state) {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (ACTIVE.effect != null) {
|
|
326
|
-
state.effects.add(ACTIVE.effect);
|
|
327
|
-
}
|
|
328
|
-
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;
|
|
329
272
|
}
|
|
330
273
|
|
|
331
|
-
function
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
274
|
+
function emityProxyValues(state, mapped) {
|
|
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;
|
|
343
287
|
}
|
|
344
288
|
function setProxyValue(proxy, value) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const keyedValue = value[key];
|
|
360
|
-
proxy[key] = keyedValue;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
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();
|
|
364
303
|
}
|
|
365
304
|
function setValueInProxy(parameters) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
emitValue(state);
|
|
378
|
-
if (isArray) {
|
|
379
|
-
length?.set(target.length);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
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;
|
|
383
316
|
}
|
|
384
317
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
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
|
+
};
|
|
413
346
|
/**
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
347
|
+
* Create a reactive value
|
|
348
|
+
* @param value Initial value
|
|
349
|
+
* @param options Reactivity options
|
|
350
|
+
* @returns Reactive value
|
|
351
|
+
*/
|
|
419
352
|
function signal(value, options) {
|
|
420
|
-
|
|
353
|
+
return new Signal(value, options);
|
|
421
354
|
}
|
|
422
355
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
-
subscribe(first, second) {
|
|
551
|
-
if (typeof first === 'number' && typeof second === 'function') {
|
|
552
|
-
return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
|
|
553
|
-
}
|
|
554
|
-
return typeof first === 'function' ? subscribe(this.state, first) : noop;
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Add items to the beginning of the array
|
|
558
|
-
* @param items Items to add
|
|
559
|
-
* @returns New array length
|
|
560
|
-
*/
|
|
561
|
-
unshift(...items) {
|
|
562
|
-
return this.state.value.unshift(...items);
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Update the value _(based on the current value)_
|
|
566
|
-
* @param callback Callback to update the value
|
|
567
|
-
*/
|
|
568
|
-
update(callback) {
|
|
569
|
-
const updated = callback(this.state.value);
|
|
570
|
-
if (updated == null || Array.isArray(updated)) {
|
|
571
|
-
this.set(updated);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}
|
|
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
|
+
};
|
|
575
482
|
/**
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
483
|
+
* Create a reactive array
|
|
484
|
+
* @param value Initial array of items
|
|
485
|
+
* @param options Reactivity options
|
|
486
|
+
* @returns Reactive array
|
|
487
|
+
*/
|
|
581
488
|
function array(value, options) {
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
function updateArray(type, array, state, length) {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
const actual = index < 0 ? array.length + index : index;
|
|
601
|
-
if (actual > -1) {
|
|
602
|
-
array[actual] = value;
|
|
603
|
-
}
|
|
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;
|
|
604
507
|
}
|
|
605
508
|
|
|
606
509
|
function isKey(value) {
|
|
@@ -612,61 +515,71 @@ function isPlainObject(value) {
|
|
|
612
515
|
const prototype = Object.getPrototypeOf(value);
|
|
613
516
|
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
614
517
|
}
|
|
518
|
+
var TYPED_ARRAYS = new Set([
|
|
519
|
+
Int8Array,
|
|
520
|
+
Uint8Array,
|
|
521
|
+
Uint8ClampedArray,
|
|
522
|
+
Int16Array,
|
|
523
|
+
Uint16Array,
|
|
524
|
+
Int32Array,
|
|
525
|
+
Uint32Array,
|
|
526
|
+
Float32Array,
|
|
527
|
+
Float64Array,
|
|
528
|
+
BigInt64Array,
|
|
529
|
+
BigUint64Array
|
|
530
|
+
]);
|
|
615
531
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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
|
-
}
|
|
532
|
+
var Store = class extends Reactive {
|
|
533
|
+
#keyed = /* @__PURE__ */ new Map();
|
|
534
|
+
constructor(value, options) {
|
|
535
|
+
super(NAME_STORE, new Proxy(value, { set: (target, property, value$1) => setValueInProxy({
|
|
536
|
+
target,
|
|
537
|
+
property,
|
|
538
|
+
value: value$1,
|
|
539
|
+
isArray: false,
|
|
540
|
+
state: this.state
|
|
541
|
+
}) }), options);
|
|
542
|
+
}
|
|
543
|
+
get(key) {
|
|
544
|
+
return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue(this.state);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Notify dependents of changes
|
|
548
|
+
*
|
|
549
|
+
* _This bypasses equality checks and will immediately notify dependents.
|
|
550
|
+
* Use this only if you're modifying nested data that would be ignored by equality checks._
|
|
551
|
+
*/
|
|
552
|
+
notify() {
|
|
553
|
+
emityProxyValues(this.state, this.#keyed);
|
|
554
|
+
}
|
|
555
|
+
peek(key) {
|
|
556
|
+
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
557
|
+
}
|
|
558
|
+
set(first, second) {
|
|
559
|
+
if (isKey(first)) this.state.value[first] = second;
|
|
560
|
+
else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
|
|
561
|
+
}
|
|
562
|
+
subscribe(first, second) {
|
|
563
|
+
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
564
|
+
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Update the value _(based on the current value)_
|
|
568
|
+
* @param callback Callback to update the value
|
|
569
|
+
*/
|
|
570
|
+
update(callback) {
|
|
571
|
+
const updated = callback({ ...this.state.value });
|
|
572
|
+
if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
|
|
573
|
+
}
|
|
574
|
+
};
|
|
662
575
|
/**
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
576
|
+
* Create a reactive store
|
|
577
|
+
* @param value Initial object value
|
|
578
|
+
* @param options Reactivity options
|
|
579
|
+
* @returns Reactive store
|
|
580
|
+
*/
|
|
668
581
|
function store(value, options) {
|
|
669
|
-
|
|
582
|
+
return new Store(isPlainObject(value) ? value : {}, options);
|
|
670
583
|
}
|
|
671
584
|
|
|
672
|
-
export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|
|
585
|
+
export { array, computed, effect, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|