@legendapp/state 1.0.0-rc.31 → 1.0.0-rc.33
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/index.d.ts +1 -1
- package/index.js +242 -223
- package/index.js.map +1 -1
- package/index.mjs +242 -224
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist.js +8 -6
- package/persist.js.map +1 -1
- package/persist.mjs +9 -7
- package/persist.mjs.map +1 -1
- package/react.js +84 -53
- package/react.js.map +1 -1
- package/react.mjs +86 -55
- package/react.mjs.map +1 -1
- package/src/batching.d.ts +8 -10
- package/src/observableInterfaces.d.ts +4 -1
- package/src/observe.d.ts +1 -2
- package/src/onChange.d.ts +2 -1
- package/src/react/For.d.ts +1 -0
- package/src/react/Switch.d.ts +5 -10
- package/src/react/useObserve.d.ts +4 -4
- package/src/react/useObserveEffect.d.ts +4 -4
- package/src/when.d.ts +1 -0
- package/src/notify.d.ts +0 -3
package/index.mjs
CHANGED
|
@@ -49,155 +49,6 @@ function isChildNodeValue(node) {
|
|
|
49
49
|
return !!node.parent;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
let timeout;
|
|
53
|
-
let numInBatch = 0;
|
|
54
|
-
let isRunningBatch = false;
|
|
55
|
-
let didDelayEndBatch = false;
|
|
56
|
-
let _batch = [];
|
|
57
|
-
let _afterBatch = [];
|
|
58
|
-
// Use a Map of callbacks for fast lookups to update the BatchItem
|
|
59
|
-
let _batchMap = new Map();
|
|
60
|
-
function onActionTimeout() {
|
|
61
|
-
if (_batch.length > 0) {
|
|
62
|
-
if (process.env.NODE_ENV === 'development') {
|
|
63
|
-
console.error('Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end().');
|
|
64
|
-
}
|
|
65
|
-
endBatch(/*force*/ true);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function createPreviousHandler(value, changes) {
|
|
69
|
-
// Create a function that clones the current state and injects the previous data at the changed path
|
|
70
|
-
return function () {
|
|
71
|
-
let clone = value ? JSON.parse(JSON.stringify(value)) : {};
|
|
72
|
-
for (let i = 0; i < changes.length; i++) {
|
|
73
|
-
const { path, prevAtPath } = changes[i];
|
|
74
|
-
let o = clone;
|
|
75
|
-
if (path.length > 0) {
|
|
76
|
-
let i;
|
|
77
|
-
for (i = 0; i < path.length - 1; i++) {
|
|
78
|
-
o = o[path[i]];
|
|
79
|
-
}
|
|
80
|
-
o[path[i]] = prevAtPath;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
clone = prevAtPath;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return clone;
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function batchNotify(b, immediate) {
|
|
90
|
-
const isFunc = isFunction(b);
|
|
91
|
-
const cb = isFunc ? b : b.cb;
|
|
92
|
-
if (!immediate && numInBatch > 0) {
|
|
93
|
-
// Set a timeout to call end() in case end() is never called or there's an uncaught error
|
|
94
|
-
if (!timeout) {
|
|
95
|
-
timeout = setTimeout(onActionTimeout, 0);
|
|
96
|
-
}
|
|
97
|
-
const existing = _batchMap.get(cb);
|
|
98
|
-
// If this callback already exists, make sure it has the latest value but do not add it
|
|
99
|
-
if (existing) {
|
|
100
|
-
if (!isFunc) {
|
|
101
|
-
const params = existing.params;
|
|
102
|
-
params.value = b.params.value;
|
|
103
|
-
params.changes.push(...b.params.changes);
|
|
104
|
-
params.getPrevious = createPreviousHandler(params.value, params.changes);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
if (!isFunc) {
|
|
109
|
-
b.params.getPrevious = createPreviousHandler(b.params.value, b.params.changes);
|
|
110
|
-
}
|
|
111
|
-
_batch.push(b);
|
|
112
|
-
_batchMap.set(cb, isFunc ? true : b);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// If not batched callback immediately
|
|
117
|
-
if (isFunc) {
|
|
118
|
-
b();
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
b.params.getPrevious = createPreviousHandler(b.params.value, b.params.changes);
|
|
122
|
-
b.cb(b.params);
|
|
123
|
-
}
|
|
124
|
-
if (numInBatch === 0) {
|
|
125
|
-
// Run afterBatch callbacks if this is not batched
|
|
126
|
-
const after = _afterBatch;
|
|
127
|
-
_afterBatch = [];
|
|
128
|
-
for (let i = 0; i < after.length; i++) {
|
|
129
|
-
after[i]();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
function batch(fn, onComplete) {
|
|
135
|
-
if (onComplete) {
|
|
136
|
-
_afterBatch.push(onComplete);
|
|
137
|
-
}
|
|
138
|
-
beginBatch();
|
|
139
|
-
try {
|
|
140
|
-
fn();
|
|
141
|
-
}
|
|
142
|
-
finally {
|
|
143
|
-
endBatch();
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
function beginBatch() {
|
|
147
|
-
numInBatch++;
|
|
148
|
-
}
|
|
149
|
-
function endBatch(force) {
|
|
150
|
-
numInBatch--;
|
|
151
|
-
if (numInBatch <= 0 || force) {
|
|
152
|
-
if (isRunningBatch) {
|
|
153
|
-
// Don't want to run multiple endBatches recursively, so just note that an endBatch
|
|
154
|
-
// was delayed so that the top level endBatch will run endBatch again after it's done.
|
|
155
|
-
didDelayEndBatch = true;
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
if (timeout) {
|
|
159
|
-
clearTimeout(timeout);
|
|
160
|
-
timeout = undefined;
|
|
161
|
-
}
|
|
162
|
-
numInBatch = 0;
|
|
163
|
-
// Save batch locally and reset _batch first because a new batch could begin while looping over callbacks.
|
|
164
|
-
// This can happen with observableComputed for example.
|
|
165
|
-
const batch = _batch;
|
|
166
|
-
const after = _afterBatch;
|
|
167
|
-
_batch = [];
|
|
168
|
-
_batchMap = new Map();
|
|
169
|
-
_afterBatch = [];
|
|
170
|
-
isRunningBatch = true;
|
|
171
|
-
for (let i = 0; i < batch.length; i++) {
|
|
172
|
-
const b = batch[i];
|
|
173
|
-
if (isFunction(b)) {
|
|
174
|
-
b();
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
const { cb } = b;
|
|
178
|
-
cb(b.params);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
for (let i = 0; i < after.length; i++) {
|
|
182
|
-
after[i]();
|
|
183
|
-
}
|
|
184
|
-
isRunningBatch = false;
|
|
185
|
-
if (didDelayEndBatch) {
|
|
186
|
-
didDelayEndBatch = false;
|
|
187
|
-
endBatch(true);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
function afterBatch(fn) {
|
|
193
|
-
if (numInBatch > 0) {
|
|
194
|
-
_afterBatch.push(fn);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
fn();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
52
|
let trackCount = 0;
|
|
202
53
|
const trackingQueue = [];
|
|
203
54
|
const tracking = {
|
|
@@ -329,6 +180,206 @@ function findIDKey(obj, node) {
|
|
|
329
180
|
return idKey;
|
|
330
181
|
}
|
|
331
182
|
|
|
183
|
+
let timeout;
|
|
184
|
+
let numInBatch = 0;
|
|
185
|
+
let isRunningBatch = false;
|
|
186
|
+
let didDelayEndBatch = false;
|
|
187
|
+
let _afterBatch = [];
|
|
188
|
+
let _batchMap = new Map();
|
|
189
|
+
function onActionTimeout() {
|
|
190
|
+
if (_batchMap.size > 0) {
|
|
191
|
+
if (process.env.NODE_ENV === 'development') {
|
|
192
|
+
console.error('Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end().');
|
|
193
|
+
}
|
|
194
|
+
endBatch(/*force*/ true);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function createPreviousHandlerInner(value, changes) {
|
|
198
|
+
// Clones the current state and inject the previous data at the changed path
|
|
199
|
+
let clone = value ? JSON.parse(JSON.stringify(value)) : {};
|
|
200
|
+
for (let i = 0; i < changes.length; i++) {
|
|
201
|
+
const { path, prevAtPath } = changes[i];
|
|
202
|
+
let o = clone;
|
|
203
|
+
if (path.length > 0) {
|
|
204
|
+
let i;
|
|
205
|
+
for (i = 0; i < path.length - 1; i++) {
|
|
206
|
+
o = o[path[i]];
|
|
207
|
+
}
|
|
208
|
+
o[path[i]] = prevAtPath;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
clone = prevAtPath;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return clone;
|
|
215
|
+
}
|
|
216
|
+
function createPreviousHandler(value, changes) {
|
|
217
|
+
// Create a function that generates the previous state
|
|
218
|
+
// We don't want to always do this because cloning is expensive
|
|
219
|
+
// so it's better to run on demand.
|
|
220
|
+
return function () {
|
|
221
|
+
return createPreviousHandlerInner(value, changes);
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
225
|
+
// Run immediate listeners if there are any
|
|
226
|
+
const changesInBatch = new Map();
|
|
227
|
+
computeChangesRecursive(changesInBatch, node, value, [], [], value, prev,
|
|
228
|
+
/*immediate*/ true, level, whenOptimizedOnlyIf);
|
|
229
|
+
batchNotifyChanges(changesInBatch, /*immediate*/ true);
|
|
230
|
+
// Update the current batch
|
|
231
|
+
const existing = _batchMap.get(node);
|
|
232
|
+
if (existing) {
|
|
233
|
+
existing.value = value;
|
|
234
|
+
// TODO: level, whenOptimizedOnlyIf
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
_batchMap.set(node, { value, prev, level, whenOptimizedOnlyIf });
|
|
238
|
+
}
|
|
239
|
+
// If not in a batch run it immediately
|
|
240
|
+
if (numInBatch <= 0) {
|
|
241
|
+
runBatch();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
245
|
+
// If there are listeners at this node compute the changes that need to be run
|
|
246
|
+
if (immediate ? node.listenersImmediate : node.listeners) {
|
|
247
|
+
const change = {
|
|
248
|
+
path,
|
|
249
|
+
pathTypes,
|
|
250
|
+
valueAtPath,
|
|
251
|
+
prevAtPath,
|
|
252
|
+
};
|
|
253
|
+
const changeInBatch = changesInBatch.get(node);
|
|
254
|
+
// If the node itself has been changed then we can ignore all the child changes
|
|
255
|
+
if (changeInBatch && path.length > 0) {
|
|
256
|
+
changeInBatch.changes.push(change);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
changesInBatch.set(node, {
|
|
260
|
+
level,
|
|
261
|
+
value,
|
|
262
|
+
whenOptimizedOnlyIf,
|
|
263
|
+
changes: [change],
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function computeChangesRecursive(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf) {
|
|
269
|
+
// Do the compute at this node
|
|
270
|
+
computeChangesAtNode(changesInBatch, node, value, path, pathTypes, valueAtPath, prevAtPath, immediate, level, whenOptimizedOnlyIf);
|
|
271
|
+
// If not root notify up through parents
|
|
272
|
+
if (node.parent) {
|
|
273
|
+
const parent = node.parent;
|
|
274
|
+
if (parent) {
|
|
275
|
+
const parentValue = getNodeValue(parent);
|
|
276
|
+
computeChangesRecursive(changesInBatch, parent, parentValue, [node.key].concat(path), [(isArray(value) ? 'array' : 'object')].concat(pathTypes), valueAtPath, prevAtPath, immediate, level + 1, whenOptimizedOnlyIf);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function batchNotifyChanges(changesInBatch, immediate) {
|
|
281
|
+
// For each change in the batch, notify all of the listeners
|
|
282
|
+
changesInBatch.forEach(({ changes, level, value, whenOptimizedOnlyIf }, node) => {
|
|
283
|
+
const listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
284
|
+
if (listeners) {
|
|
285
|
+
let listenerParams;
|
|
286
|
+
// Need to convert to an array here instead of using a for...of loop because listeners can change while iterating
|
|
287
|
+
const arr = Array.from(listeners);
|
|
288
|
+
for (let i = 0; i < arr.length; i++) {
|
|
289
|
+
const listenerFn = arr[i];
|
|
290
|
+
const { track, noArgs, listener } = listenerFn;
|
|
291
|
+
const ok = track === true || track === 'shallow'
|
|
292
|
+
? level <= 0
|
|
293
|
+
: track === 'optimize'
|
|
294
|
+
? whenOptimizedOnlyIf && level <= 0
|
|
295
|
+
: true;
|
|
296
|
+
// Notify if listener is not shallow or if this is the first level
|
|
297
|
+
if (ok) {
|
|
298
|
+
// Create listenerParams if not already created
|
|
299
|
+
if (!noArgs && !listenerParams) {
|
|
300
|
+
listenerParams = {
|
|
301
|
+
value,
|
|
302
|
+
getPrevious: createPreviousHandler(value, changes),
|
|
303
|
+
changes,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
listener(listenerParams);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
function runBatch() {
|
|
313
|
+
const map = _batchMap;
|
|
314
|
+
_batchMap = new Map();
|
|
315
|
+
const changesInBatch = new Map();
|
|
316
|
+
// First compute all of the changes at each node. It's important to do this first before
|
|
317
|
+
// running all the notifications because createPreviousHandler depends on knowing
|
|
318
|
+
// all of the changes happening at the node.
|
|
319
|
+
map.forEach(({ value, prev, level, whenOptimizedOnlyIf }, node) => {
|
|
320
|
+
computeChangesRecursive(changesInBatch, node, value, [], [], value, prev, false, level, whenOptimizedOnlyIf);
|
|
321
|
+
});
|
|
322
|
+
// Once all changes are computed, notify all listeners for each node with the computed changes.
|
|
323
|
+
batchNotifyChanges(changesInBatch, false);
|
|
324
|
+
}
|
|
325
|
+
function batch(fn, onComplete) {
|
|
326
|
+
if (onComplete) {
|
|
327
|
+
_afterBatch.push(onComplete);
|
|
328
|
+
}
|
|
329
|
+
beginBatch();
|
|
330
|
+
try {
|
|
331
|
+
fn();
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
endBatch();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function beginBatch() {
|
|
338
|
+
numInBatch++;
|
|
339
|
+
if (!timeout) {
|
|
340
|
+
timeout = setTimeout(onActionTimeout, 0);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function endBatch(force) {
|
|
344
|
+
numInBatch--;
|
|
345
|
+
if (numInBatch <= 0 || force) {
|
|
346
|
+
if (isRunningBatch) {
|
|
347
|
+
// Don't want to run multiple endBatches recursively, so just note that an endBatch
|
|
348
|
+
// was delayed so that the top level endBatch will run endBatch again after it's done.
|
|
349
|
+
didDelayEndBatch = true;
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
if (timeout) {
|
|
353
|
+
clearTimeout(timeout);
|
|
354
|
+
timeout = undefined;
|
|
355
|
+
}
|
|
356
|
+
numInBatch = 0;
|
|
357
|
+
// Save batch locally and reset _batch first because a new batch could begin while looping over callbacks.
|
|
358
|
+
// This can happen with observableComputed for example.
|
|
359
|
+
const after = _afterBatch;
|
|
360
|
+
_afterBatch = [];
|
|
361
|
+
isRunningBatch = true;
|
|
362
|
+
runBatch();
|
|
363
|
+
isRunningBatch = false;
|
|
364
|
+
if (didDelayEndBatch) {
|
|
365
|
+
didDelayEndBatch = false;
|
|
366
|
+
endBatch(true);
|
|
367
|
+
}
|
|
368
|
+
for (let i = 0; i < after.length; i++) {
|
|
369
|
+
after[i]();
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function afterBatch(fn) {
|
|
375
|
+
if (numInBatch > 0) {
|
|
376
|
+
_afterBatch.push(fn);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
fn();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
332
383
|
function isObservable(obs) {
|
|
333
384
|
return obs && !!obs[symbolIsObservable];
|
|
334
385
|
}
|
|
@@ -478,69 +529,23 @@ function isObservableValueReady(value) {
|
|
|
478
529
|
return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
|
|
479
530
|
}
|
|
480
531
|
|
|
481
|
-
function
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const listenerFn = arr[i];
|
|
489
|
-
const { track, noArgs, immediate, listener } = listenerFn;
|
|
490
|
-
const ok = track === true || track === 'shallow'
|
|
491
|
-
? level <= 0
|
|
492
|
-
: track === 'optimize'
|
|
493
|
-
? whenOptimizedOnlyIf && level <= 0
|
|
494
|
-
: true;
|
|
495
|
-
// Notify if listener is not shallow or if this is the first level
|
|
496
|
-
if (ok) {
|
|
497
|
-
if (!noArgs && !listenerParams) {
|
|
498
|
-
listenerParams = {
|
|
499
|
-
value,
|
|
500
|
-
changes: [
|
|
501
|
-
{
|
|
502
|
-
path,
|
|
503
|
-
pathTypes,
|
|
504
|
-
valueAtPath,
|
|
505
|
-
prevAtPath,
|
|
506
|
-
},
|
|
507
|
-
],
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
batchNotify(noArgs ? listener : { cb: listener, params: listenerParams }, immediate);
|
|
511
|
-
}
|
|
532
|
+
function onChange(node, callback, options) {
|
|
533
|
+
const { trackingType, initial, immediate, noArgs } = options || {};
|
|
534
|
+
let listeners = immediate ? node.listenersImmediate : node.listeners;
|
|
535
|
+
if (!listeners) {
|
|
536
|
+
listeners = new Set();
|
|
537
|
+
if (immediate) {
|
|
538
|
+
node.listenersImmediate = listeners;
|
|
512
539
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
function _notifyParents(node, value, path, pathTypes, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
|
|
516
|
-
// Do the notify
|
|
517
|
-
doNotify(node, value, path, pathTypes, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf);
|
|
518
|
-
// If not root notify up through parents
|
|
519
|
-
if (node.parent) {
|
|
520
|
-
const parent = node.parent;
|
|
521
|
-
if (parent) {
|
|
522
|
-
const parentValue = getNodeValue(parent);
|
|
523
|
-
_notifyParents(parent, parentValue, [node.key].concat(path), [(isArray(value) ? 'array' : 'object')].concat(pathTypes), valueAtPath, prevAtPath, level + 1, whenOptimizedOnlyIf);
|
|
540
|
+
else {
|
|
541
|
+
node.listeners = listeners;
|
|
524
542
|
}
|
|
525
543
|
}
|
|
526
|
-
}
|
|
527
|
-
function notify(node, value, prev, level, whenOptimizedOnlyIf) {
|
|
528
|
-
// Notify self and up through parents
|
|
529
|
-
_notifyParents(node, value, [], [], value, prev, level, whenOptimizedOnlyIf);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
function onChange(node, callback, options, noArgs) {
|
|
533
|
-
let listeners = node.listeners;
|
|
534
|
-
if (!listeners) {
|
|
535
|
-
node.listeners = listeners = new Set();
|
|
536
|
-
}
|
|
537
544
|
checkActivate(node);
|
|
538
|
-
const { trackingType, initial, immediate } = options || {};
|
|
539
545
|
const listener = {
|
|
540
546
|
listener: callback,
|
|
541
547
|
track: trackingType,
|
|
542
548
|
noArgs,
|
|
543
|
-
immediate: immediate,
|
|
544
549
|
};
|
|
545
550
|
listeners.add(listener);
|
|
546
551
|
let parent = node.parent;
|
|
@@ -608,7 +613,7 @@ ObservablePrimitiveClass.prototype.set = function (value) {
|
|
|
608
613
|
const root = this._node.root;
|
|
609
614
|
const prev = root._;
|
|
610
615
|
root._ = value;
|
|
611
|
-
|
|
616
|
+
notify(this._node, value, prev, 0);
|
|
612
617
|
return this;
|
|
613
618
|
};
|
|
614
619
|
ObservablePrimitiveClass.prototype.toggle = function () {
|
|
@@ -621,9 +626,13 @@ ObservablePrimitiveClass.prototype.toggle = function () {
|
|
|
621
626
|
}
|
|
622
627
|
return !value;
|
|
623
628
|
};
|
|
629
|
+
ObservablePrimitiveClass.prototype.delete = function () {
|
|
630
|
+
this.set(undefined);
|
|
631
|
+
return this;
|
|
632
|
+
};
|
|
624
633
|
// Listener
|
|
625
|
-
ObservablePrimitiveClass.prototype.onChange = function (cb, options
|
|
626
|
-
return onChange(this._node, cb, options
|
|
634
|
+
ObservablePrimitiveClass.prototype.onChange = function (cb, options) {
|
|
635
|
+
return onChange(this._node, cb, options);
|
|
627
636
|
};
|
|
628
637
|
|
|
629
638
|
let inSet = false;
|
|
@@ -683,8 +692,8 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
683
692
|
if ((isObject(obj) && obj[symbolOpaque]) || (isObject(prevValue) && prevValue[symbolOpaque])) {
|
|
684
693
|
const isDiff = obj !== prevValue;
|
|
685
694
|
if (isDiff) {
|
|
686
|
-
if (parent.listeners) {
|
|
687
|
-
|
|
695
|
+
if (parent.listeners || parent.listenersImmediate) {
|
|
696
|
+
notify(parent, obj, prevValue, 0);
|
|
688
697
|
}
|
|
689
698
|
}
|
|
690
699
|
return isDiff;
|
|
@@ -701,7 +710,7 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
701
710
|
// Construct a map of previous indices for computing move
|
|
702
711
|
if (prevValue.length > 0) {
|
|
703
712
|
const firstPrevValue = prevValue[0];
|
|
704
|
-
if (firstPrevValue) {
|
|
713
|
+
if (firstPrevValue !== undefined) {
|
|
705
714
|
idField = findIDKey(firstPrevValue, parent);
|
|
706
715
|
if (idField) {
|
|
707
716
|
isIdFieldFunction = isFunction(idField);
|
|
@@ -745,8 +754,8 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
745
754
|
if (!isPrimitive(prev)) {
|
|
746
755
|
updateNodes(child, undefined, prev);
|
|
747
756
|
}
|
|
748
|
-
if (child.listeners) {
|
|
749
|
-
|
|
757
|
+
if (child.listeners || child.listenersImmediate) {
|
|
758
|
+
notify(child, undefined, prev, 0);
|
|
750
759
|
}
|
|
751
760
|
}
|
|
752
761
|
}
|
|
@@ -781,6 +790,7 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
781
790
|
hasADiff = true;
|
|
782
791
|
}
|
|
783
792
|
else if (prevChild !== undefined && prevChild.key !== key) {
|
|
793
|
+
const valuePrevChild = prevValue[prevChild.key];
|
|
784
794
|
// If array length changed then move the original node to the current position.
|
|
785
795
|
// That should be faster than notifying every single element that
|
|
786
796
|
// it's in a new position.
|
|
@@ -792,8 +802,7 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
792
802
|
}
|
|
793
803
|
didMove = true;
|
|
794
804
|
// And check for diff against the previous value in the previous position
|
|
795
|
-
|
|
796
|
-
isDiff = prevOfNode !== value;
|
|
805
|
+
isDiff = valuePrevChild !== value;
|
|
797
806
|
}
|
|
798
807
|
}
|
|
799
808
|
if (isDiff) {
|
|
@@ -813,8 +822,8 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
813
822
|
// Or if the position changed in an array whose length did not change
|
|
814
823
|
// But do not notify child if the parent is an array with changing length -
|
|
815
824
|
// the array's listener will cover it
|
|
816
|
-
if (child.listeners) {
|
|
817
|
-
|
|
825
|
+
if (child.listeners || child.listenersImmediate) {
|
|
826
|
+
notify(child, value, prev, 0, !isArrDiff);
|
|
818
827
|
}
|
|
819
828
|
}
|
|
820
829
|
}
|
|
@@ -1119,7 +1128,7 @@ function setupTracking(nodes, update, noArgs, immediate) {
|
|
|
1119
1128
|
// Listen to tracked nodes
|
|
1120
1129
|
nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
|
|
1121
1130
|
const { node, track } = tracked;
|
|
1122
|
-
listeners.push(onChange(node, update, { trackingType: track, immediate
|
|
1131
|
+
listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
|
|
1123
1132
|
});
|
|
1124
1133
|
return () => {
|
|
1125
1134
|
if (listeners) {
|
|
@@ -1181,10 +1190,12 @@ function observe(selectorOrRun, reactionOrOptions, options) {
|
|
|
1181
1190
|
e.onCleanupReaction();
|
|
1182
1191
|
e.onCleanupReaction = undefined;
|
|
1183
1192
|
}
|
|
1184
|
-
|
|
1193
|
+
// Call the reaction if there is one and the value changed
|
|
1194
|
+
if (reaction && (e.num > 0 || !(selectorOrRun === null || selectorOrRun === void 0 ? void 0 : selectorOrRun[symbolIsEvent])) && e.previous !== e.value) {
|
|
1185
1195
|
reaction(e);
|
|
1186
|
-
e.previous = e.value;
|
|
1187
1196
|
}
|
|
1197
|
+
// Update the previous value
|
|
1198
|
+
e.previous = e.value;
|
|
1188
1199
|
// Increment the counter
|
|
1189
1200
|
e.num++;
|
|
1190
1201
|
endBatch();
|
|
@@ -1252,12 +1263,12 @@ function event() {
|
|
|
1252
1263
|
};
|
|
1253
1264
|
}
|
|
1254
1265
|
|
|
1255
|
-
function
|
|
1266
|
+
function _when(predicate, effect, checkReady) {
|
|
1256
1267
|
let value;
|
|
1257
1268
|
// Create a wrapping fn that calls the effect if predicate returns true
|
|
1258
1269
|
function run(e) {
|
|
1259
1270
|
const ret = computeSelector(predicate);
|
|
1260
|
-
if (isObservableValueReady(ret)) {
|
|
1271
|
+
if (checkReady ? isObservableValueReady(ret) : ret) {
|
|
1261
1272
|
value = ret;
|
|
1262
1273
|
// If value is truthy then run the effect
|
|
1263
1274
|
effect === null || effect === void 0 ? void 0 : effect(ret);
|
|
@@ -1265,14 +1276,15 @@ function when(predicate, effect) {
|
|
|
1265
1276
|
e.cancel = true;
|
|
1266
1277
|
}
|
|
1267
1278
|
}
|
|
1268
|
-
//
|
|
1279
|
+
// Run in an observe
|
|
1269
1280
|
observe(run);
|
|
1270
|
-
// If first run resulted in a truthy value just return it
|
|
1281
|
+
// If first run resulted in a truthy value just return it.
|
|
1271
1282
|
// It will have set e.cancel so no need to dispose
|
|
1272
1283
|
if (value !== undefined) {
|
|
1273
1284
|
return Promise.resolve(value);
|
|
1274
1285
|
}
|
|
1275
1286
|
else {
|
|
1287
|
+
// Wrap it in a promise
|
|
1276
1288
|
const promise = new Promise((resolve) => {
|
|
1277
1289
|
if (effect) {
|
|
1278
1290
|
const originalEffect = effect;
|
|
@@ -1288,6 +1300,12 @@ function when(predicate, effect) {
|
|
|
1288
1300
|
return promise;
|
|
1289
1301
|
}
|
|
1290
1302
|
}
|
|
1303
|
+
function when(predicate, effect) {
|
|
1304
|
+
return _when(predicate, effect, false);
|
|
1305
|
+
}
|
|
1306
|
+
function whenReady(predicate, effect) {
|
|
1307
|
+
return _when(predicate, effect, true);
|
|
1308
|
+
}
|
|
1291
1309
|
|
|
1292
1310
|
const internal = {
|
|
1293
1311
|
getNode,
|
|
@@ -1296,5 +1314,5 @@ const internal = {
|
|
|
1296
1314
|
symbolDelete
|
|
1297
1315
|
};
|
|
1298
1316
|
|
|
1299
|
-
export { ObservablePrimitiveClass, afterBatch, batch, beginBatch, beginTracking, checkActivate, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, extraPrimitiveActivators, extraPrimitiveProps, findIDKey, getNode, getNodeValue, getObservableIndex, internal, isArray, isBoolean, isEmpty, isFunction, isObject, isObservable, isObservableValueReady, isPrimitive, isPromise, isString, isSymbol, lockObservable, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, setAtPath, setInObservableAtPath, setupTracking, symbolDelete, symbolIsEvent, symbolIsObservable, tracking, updateTracking, when };
|
|
1317
|
+
export { ObservablePrimitiveClass, afterBatch, batch, beginBatch, beginTracking, checkActivate, computeSelector, computed, constructObjectWithPath, deconstructObjectWithPath, endBatch, endTracking, event, extraPrimitiveActivators, extraPrimitiveProps, findIDKey, getNode, getNodeValue, getObservableIndex, internal, isArray, isBoolean, isEmpty, isFunction, isObject, isObservable, isObservableValueReady, isPrimitive, isPromise, isString, isSymbol, lockObservable, mergeIntoObservable, observable, observablePrimitive, observe, opaqueObject, setAtPath, setInObservableAtPath, setupTracking, symbolDelete, symbolIsEvent, symbolIsObservable, tracking, updateTracking, when, whenReady };
|
|
1300
1318
|
//# sourceMappingURL=index.mjs.map
|