@tko/computed 4.0.0-alpha8.0 → 4.0.0-beta1.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/computed.js +422 -665
- package/dist/computed.js.map +7 -1
- package/dist/index.cjs +1746 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +16 -0
- package/dist/index.mjs.map +7 -0
- package/dist/proxy.js +96 -0
- package/dist/proxy.js.map +7 -0
- package/dist/throttleExtender.js +21 -0
- package/dist/throttleExtender.js.map +7 -0
- package/dist/when.js +19 -0
- package/dist/when.js.map +7 -0
- package/package.json +16 -26
- package/dist/computed.es6.js +0 -661
- package/dist/computed.es6.js.map +0 -1
package/dist/computed.js
CHANGED
|
@@ -1,668 +1,425 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// Attach a DOM node disposal callback so that the computed will be proactively disposed as soon as the node is
|
|
117
|
-
// removed using ko.removeNode. But skip if isActive is false (there will never be any dependencies to dispose).
|
|
118
|
-
if (state.disposeWhenNodeIsRemoved && computedObservable.isActive()) {
|
|
119
|
-
addDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback = function () {
|
|
120
|
-
computedObservable.dispose();
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
return computedObservable;
|
|
124
|
-
}
|
|
125
|
-
// Utility function that disposes a given dependencyTracking entry
|
|
126
|
-
function computedDisposeDependencyCallback(id, entryToDispose) {
|
|
127
|
-
if (entryToDispose !== null && entryToDispose.dispose) {
|
|
128
|
-
entryToDispose.dispose();
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
// This function gets called each time a dependency is detected while evaluating a computed.
|
|
132
|
-
// It's factored out as a shared function to avoid creating unnecessary function instances during evaluation.
|
|
133
|
-
function computedBeginDependencyDetectionCallback(subscribable$$1, id) {
|
|
134
|
-
var computedObservable = this.computedObservable, state = computedObservable[computedState];
|
|
135
|
-
if (!state.isDisposed) {
|
|
136
|
-
if (this.disposalCount && this.disposalCandidates[id]) {
|
|
137
|
-
// Don't want to dispose this subscription, as it's still being used
|
|
138
|
-
computedObservable.addDependencyTracking(id, subscribable$$1, this.disposalCandidates[id]);
|
|
139
|
-
this.disposalCandidates[id] = null; // No need to actually delete the property - disposalCandidates is a transient object anyway
|
|
140
|
-
--this.disposalCount;
|
|
141
|
-
}
|
|
142
|
-
else if (!state.dependencyTracking[id]) {
|
|
143
|
-
// Brand new subscription - add it
|
|
144
|
-
computedObservable.addDependencyTracking(id, subscribable$$1, state.isSleeping ? { _target: subscribable$$1 } : computedObservable.subscribeToDependency(subscribable$$1));
|
|
145
|
-
}
|
|
146
|
-
// If the observable we've accessed has a pending notification, ensure
|
|
147
|
-
// we get notified of the actual final value (bypass equality checks)
|
|
148
|
-
if (subscribable$$1._notificationIsPending) {
|
|
149
|
-
subscribable$$1._notifyNextChangeIfValueIsDifferent();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
computed.fn = (_a = {
|
|
154
|
-
equalityComparer: valuesArePrimitiveAndEqual,
|
|
155
|
-
getDependenciesCount: function () {
|
|
156
|
-
return this[computedState].dependenciesCount;
|
|
157
|
-
},
|
|
158
|
-
getDependencies: function () {
|
|
159
|
-
var dependencyTracking = this[computedState].dependencyTracking;
|
|
160
|
-
var dependentObservables = [];
|
|
161
|
-
objectForEach(dependencyTracking, function (id, dependency) {
|
|
162
|
-
dependentObservables[dependency._order] = dependency._target;
|
|
163
|
-
});
|
|
164
|
-
return dependentObservables;
|
|
165
|
-
},
|
|
166
|
-
addDependencyTracking: function (id, target, trackingObj) {
|
|
167
|
-
if (this[computedState].pure && target === this) {
|
|
168
|
-
throw Error("A 'pure' computed must not be called recursively");
|
|
169
|
-
}
|
|
170
|
-
this[computedState].dependencyTracking[id] = trackingObj;
|
|
171
|
-
trackingObj._order = this[computedState].dependenciesCount++;
|
|
172
|
-
trackingObj._version = target.getVersion();
|
|
173
|
-
},
|
|
174
|
-
haveDependenciesChanged: function () {
|
|
175
|
-
var id, dependency, dependencyTracking = this[computedState].dependencyTracking;
|
|
176
|
-
for (id in dependencyTracking) {
|
|
177
|
-
if (hasOwnProperty(dependencyTracking, id)) {
|
|
178
|
-
dependency = dependencyTracking[id];
|
|
179
|
-
if ((this._evalDelayed && dependency._target._notificationIsPending) || dependency._target.hasChanged(dependency._version)) {
|
|
180
|
-
return true;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
markDirty: function () {
|
|
186
|
-
// Process "dirty" events if we can handle delayed notifications
|
|
187
|
-
if (this._evalDelayed && !this[computedState].isBeingEvaluated) {
|
|
188
|
-
this._evalDelayed(false /* notifyChange */);
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
isActive: function () {
|
|
192
|
-
var state = this[computedState];
|
|
193
|
-
return state.isDirty || state.dependenciesCount > 0;
|
|
194
|
-
},
|
|
195
|
-
respondToChange: function () {
|
|
196
|
-
// Ignore "change" events if we've already scheduled a delayed notification
|
|
197
|
-
if (!this._notificationIsPending) {
|
|
198
|
-
this.evaluatePossiblyAsync();
|
|
199
|
-
}
|
|
200
|
-
else if (this[computedState].isDirty) {
|
|
201
|
-
this[computedState].isStale = true;
|
|
202
|
-
}
|
|
203
|
-
},
|
|
204
|
-
subscribeToDependency: function (target) {
|
|
205
|
-
if (target._deferUpdates) {
|
|
206
|
-
var dirtySub = target.subscribe(this.markDirty, this, 'dirty'), changeSub = target.subscribe(this.respondToChange, this);
|
|
207
|
-
return {
|
|
208
|
-
_target: target,
|
|
209
|
-
dispose: function () {
|
|
210
|
-
dirtySub.dispose();
|
|
211
|
-
changeSub.dispose();
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
return target.subscribe(this.evaluatePossiblyAsync, this);
|
|
217
|
-
}
|
|
218
|
-
},
|
|
219
|
-
evaluatePossiblyAsync: function () {
|
|
220
|
-
var computedObservable = this, throttleEvaluationTimeout = computedObservable.throttleEvaluation;
|
|
221
|
-
if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) {
|
|
222
|
-
clearTimeout(this[computedState].evaluationTimeoutInstance);
|
|
223
|
-
this[computedState].evaluationTimeoutInstance = safeSetTimeout(function () {
|
|
224
|
-
computedObservable.evaluateImmediate(true /* notifyChange */);
|
|
225
|
-
}, throttleEvaluationTimeout);
|
|
226
|
-
}
|
|
227
|
-
else if (computedObservable._evalDelayed) {
|
|
228
|
-
computedObservable._evalDelayed(true /* notifyChange */);
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
computedObservable.evaluateImmediate(true /* notifyChange */);
|
|
232
|
-
}
|
|
233
|
-
},
|
|
234
|
-
evaluateImmediate: function (notifyChange) {
|
|
235
|
-
var computedObservable = this, state = computedObservable[computedState], disposeWhen = state.disposeWhen, changed = false;
|
|
236
|
-
if (state.isBeingEvaluated) {
|
|
237
|
-
// If the evaluation of a ko.computed causes side effects, it's possible that it will trigger its own re-evaluation.
|
|
238
|
-
// This is not desirable (it's hard for a developer to realise a chain of dependencies might cause this, and they almost
|
|
239
|
-
// certainly didn't intend infinite re-evaluations). So, for predictability, we simply prevent ko.computeds from causing
|
|
240
|
-
// their own re-evaluation. Further discussion at https://github.com/SteveSanderson/knockout/pull/387
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
// Do not evaluate (and possibly capture new dependencies) if disposed
|
|
244
|
-
if (state.isDisposed) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
if (state.disposeWhenNodeIsRemoved && !domNodeIsAttachedToDocument(state.disposeWhenNodeIsRemoved) || disposeWhen && disposeWhen()) {
|
|
248
|
-
// See comment above about suppressDisposalUntilDisposeWhenReturnsFalse
|
|
249
|
-
if (!state.suppressDisposalUntilDisposeWhenReturnsFalse) {
|
|
250
|
-
computedObservable.dispose();
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
// It just did return false, so we can stop suppressing now
|
|
256
|
-
state.suppressDisposalUntilDisposeWhenReturnsFalse = false;
|
|
257
|
-
}
|
|
258
|
-
state.isBeingEvaluated = true;
|
|
259
|
-
try {
|
|
260
|
-
changed = this.evaluateImmediate_CallReadWithDependencyDetection(notifyChange);
|
|
261
|
-
}
|
|
262
|
-
finally {
|
|
263
|
-
state.isBeingEvaluated = false;
|
|
264
|
-
}
|
|
265
|
-
return changed;
|
|
266
|
-
},
|
|
267
|
-
evaluateImmediate_CallReadWithDependencyDetection: function (notifyChange) {
|
|
268
|
-
// This function is really just part of the evaluateImmediate logic. You would never call it from anywhere else.
|
|
269
|
-
// Factoring it out into a separate function means it can be independent of the try/catch block in evaluateImmediate,
|
|
270
|
-
// which contributes to saving about 40% off the CPU overhead of computed evaluation (on V8 at least).
|
|
271
|
-
var computedObservable = this, state = computedObservable[computedState], changed = false;
|
|
272
|
-
// Initially, we assume that none of the subscriptions are still being used (i.e., all are candidates for disposal).
|
|
273
|
-
// Then, during evaluation, we cross off any that are in fact still being used.
|
|
274
|
-
var isInitial = state.pure ? undefined : !state.dependenciesCount, // If we're evaluating when there are no previous dependencies, it must be the first time
|
|
275
|
-
dependencyDetectionContext = {
|
|
276
|
-
computedObservable: computedObservable,
|
|
277
|
-
disposalCandidates: state.dependencyTracking,
|
|
278
|
-
disposalCount: state.dependenciesCount
|
|
279
|
-
};
|
|
280
|
-
dependencyDetection.begin({
|
|
281
|
-
callbackTarget: dependencyDetectionContext,
|
|
282
|
-
callback: computedBeginDependencyDetectionCallback,
|
|
283
|
-
computed: computedObservable,
|
|
284
|
-
isInitial: isInitial
|
|
285
|
-
});
|
|
286
|
-
state.dependencyTracking = {};
|
|
287
|
-
state.dependenciesCount = 0;
|
|
288
|
-
var newValue = this.evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext);
|
|
289
|
-
if (!state.dependenciesCount) {
|
|
290
|
-
computedObservable.dispose();
|
|
291
|
-
changed = true; // When evaluation causes a disposal, make sure all dependent computeds get notified so they'll see the new state
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
changed = computedObservable.isDifferent(state.latestValue, newValue);
|
|
295
|
-
}
|
|
296
|
-
if (changed) {
|
|
297
|
-
if (!state.isSleeping) {
|
|
298
|
-
computedObservable.notifySubscribers(state.latestValue, 'beforeChange');
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
computedObservable.updateVersion();
|
|
302
|
-
}
|
|
303
|
-
state.latestValue = newValue;
|
|
304
|
-
if (options.debug) {
|
|
305
|
-
computedObservable._latestValue = newValue;
|
|
306
|
-
}
|
|
307
|
-
computedObservable.notifySubscribers(state.latestValue, 'spectate');
|
|
308
|
-
if (!state.isSleeping && notifyChange) {
|
|
309
|
-
computedObservable.notifySubscribers(state.latestValue);
|
|
310
|
-
}
|
|
311
|
-
if (computedObservable._recordUpdate) {
|
|
312
|
-
computedObservable._recordUpdate();
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (isInitial) {
|
|
316
|
-
computedObservable.notifySubscribers(state.latestValue, 'awake');
|
|
317
|
-
}
|
|
318
|
-
return changed;
|
|
319
|
-
},
|
|
320
|
-
evaluateImmediate_CallReadThenEndDependencyDetection: function (state, dependencyDetectionContext) {
|
|
321
|
-
// This function is really part of the evaluateImmediate_CallReadWithDependencyDetection logic.
|
|
322
|
-
// You'd never call it from anywhere else. Factoring it out means that evaluateImmediate_CallReadWithDependencyDetection
|
|
323
|
-
// can be independent of try/finally blocks, which contributes to saving about 40% off the CPU
|
|
324
|
-
// overhead of computed evaluation (on V8 at least).
|
|
325
|
-
try {
|
|
326
|
-
var readFunction = state.readFunction;
|
|
327
|
-
return state.evaluatorFunctionTarget ? readFunction.call(state.evaluatorFunctionTarget) : readFunction();
|
|
328
|
-
}
|
|
329
|
-
finally {
|
|
330
|
-
dependencyDetection.end();
|
|
331
|
-
// For each subscription no longer being used, remove it from the active subscriptions list and dispose it
|
|
332
|
-
if (dependencyDetectionContext.disposalCount && !state.isSleeping) {
|
|
333
|
-
objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback);
|
|
334
|
-
}
|
|
335
|
-
state.isStale = state.isDirty = false;
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
peek: function (forceEvaluate) {
|
|
339
|
-
// Peek won't ordinarily re-evaluate, except while the computed is sleeping
|
|
340
|
-
// or to get the initial value when "deferEvaluation" is set.
|
|
341
|
-
var state = this[computedState];
|
|
342
|
-
if ((state.isDirty && (forceEvaluate || !state.dependenciesCount)) || (state.isSleeping && this.haveDependenciesChanged())) {
|
|
343
|
-
this.evaluateImmediate();
|
|
344
|
-
}
|
|
345
|
-
return state.latestValue;
|
|
346
|
-
}
|
|
347
|
-
},
|
|
348
|
-
Object.defineProperty(_a, LATEST_VALUE, {
|
|
349
|
-
get: function () {
|
|
350
|
-
return this.peek();
|
|
351
|
-
},
|
|
352
|
-
enumerable: true,
|
|
353
|
-
configurable: true
|
|
354
|
-
}),
|
|
355
|
-
_a.limit = function (limitFunction) {
|
|
356
|
-
var state = this[computedState];
|
|
357
|
-
// Override the limit function with one that delays evaluation as well
|
|
358
|
-
subscribable.fn.limit.call(this, limitFunction);
|
|
359
|
-
Object.assign(this, {
|
|
360
|
-
_evalIfChanged: function () {
|
|
361
|
-
if (!this[computedState].isSleeping) {
|
|
362
|
-
if (this[computedState].isStale) {
|
|
363
|
-
this.evaluateImmediate();
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
this[computedState].isDirty = false;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
return state.latestValue;
|
|
370
|
-
},
|
|
371
|
-
_evalDelayed: function (isChange) {
|
|
372
|
-
this._limitBeforeChange(state.latestValue);
|
|
373
|
-
// Mark as dirty
|
|
374
|
-
state.isDirty = true;
|
|
375
|
-
if (isChange) {
|
|
376
|
-
state.isStale = true;
|
|
377
|
-
}
|
|
378
|
-
// Pass the observable to the "limit" code, which will evaluate it when
|
|
379
|
-
// it's time to do the notification.
|
|
380
|
-
this._limitChange(this, !isChange /* isDirty */);
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
},
|
|
384
|
-
_a.dispose = function () {
|
|
385
|
-
var state = this[computedState];
|
|
386
|
-
if (!state.isSleeping && state.dependencyTracking) {
|
|
387
|
-
objectForEach(state.dependencyTracking, function (id, dependency) {
|
|
388
|
-
if (dependency.dispose) {
|
|
389
|
-
dependency.dispose();
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
if (state.disposeWhenNodeIsRemoved && state.domNodeDisposalCallback) {
|
|
394
|
-
removeDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback);
|
|
395
|
-
}
|
|
396
|
-
Object.assign(state, DISPOSED_STATE);
|
|
397
|
-
},
|
|
398
|
-
_a);
|
|
399
|
-
var pureComputedOverrides = {
|
|
400
|
-
beforeSubscriptionAdd: function (event) {
|
|
401
|
-
// If asleep, wake up the computed by subscribing to any dependencies.
|
|
402
|
-
var computedObservable = this, state = computedObservable[computedState];
|
|
403
|
-
if (!state.isDisposed && state.isSleeping && event === 'change') {
|
|
404
|
-
state.isSleeping = false;
|
|
405
|
-
if (state.isStale || computedObservable.haveDependenciesChanged()) {
|
|
406
|
-
state.dependencyTracking = null;
|
|
407
|
-
state.dependenciesCount = 0;
|
|
408
|
-
if (computedObservable.evaluateImmediate()) {
|
|
409
|
-
computedObservable.updateVersion();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
// First put the dependencies in order
|
|
414
|
-
var dependenciesOrder = [];
|
|
415
|
-
objectForEach(state.dependencyTracking, function (id, dependency) {
|
|
416
|
-
dependenciesOrder[dependency._order] = id;
|
|
417
|
-
});
|
|
418
|
-
// Next, subscribe to each one
|
|
419
|
-
arrayForEach(dependenciesOrder, function (id, order) {
|
|
420
|
-
var dependency = state.dependencyTracking[id], subscription = computedObservable.subscribeToDependency(dependency._target);
|
|
421
|
-
subscription._order = order;
|
|
422
|
-
subscription._version = dependency._version;
|
|
423
|
-
state.dependencyTracking[id] = subscription;
|
|
424
|
-
});
|
|
425
|
-
// Waking dependencies may have triggered effects
|
|
426
|
-
if (computedObservable.haveDependenciesChanged()) {
|
|
427
|
-
if (computedObservable.evaluateImmediate()) {
|
|
428
|
-
computedObservable.updateVersion();
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
if (!state.isDisposed) { // test since evaluating could trigger disposal
|
|
433
|
-
computedObservable.notifySubscribers(state.latestValue, 'awake');
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
},
|
|
437
|
-
afterSubscriptionRemove: function (event) {
|
|
438
|
-
var state = this[computedState];
|
|
439
|
-
if (!state.isDisposed && event === 'change' && !this.hasSubscriptionsForEvent('change')) {
|
|
440
|
-
objectForEach(state.dependencyTracking, function (id, dependency) {
|
|
441
|
-
if (dependency.dispose) {
|
|
442
|
-
state.dependencyTracking[id] = {
|
|
443
|
-
_target: dependency._target,
|
|
444
|
-
_order: dependency._order,
|
|
445
|
-
_version: dependency._version
|
|
446
|
-
};
|
|
447
|
-
dependency.dispose();
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
state.isSleeping = true;
|
|
451
|
-
this.notifySubscribers(undefined, 'asleep');
|
|
452
|
-
}
|
|
453
|
-
},
|
|
454
|
-
getVersion: function () {
|
|
455
|
-
// Because a pure computed is not automatically updated while it is sleeping, we can't
|
|
456
|
-
// simply return the version number. Instead, we check if any of the dependencies have
|
|
457
|
-
// changed and conditionally re-evaluate the computed observable.
|
|
458
|
-
var state = this[computedState];
|
|
459
|
-
if (state.isSleeping && (state.isStale || this.haveDependenciesChanged())) {
|
|
460
|
-
this.evaluateImmediate();
|
|
461
|
-
}
|
|
462
|
-
return subscribable.fn.getVersion.call(this);
|
|
463
|
-
}
|
|
464
|
-
};
|
|
465
|
-
var deferEvaluationOverrides = {
|
|
466
|
-
beforeSubscriptionAdd: function (event) {
|
|
467
|
-
// This will force a computed with deferEvaluation to evaluate when the first subscription is registered.
|
|
468
|
-
if (event === 'change' || event === 'beforeChange') {
|
|
469
|
-
this.peek();
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
Object.setPrototypeOf(computed.fn, subscribable.fn);
|
|
474
|
-
// Set the proto values for ko.computed
|
|
475
|
-
var protoProp = observable.protoProperty; // == "__ko_proto__"
|
|
476
|
-
computed.fn[protoProp] = computed;
|
|
477
|
-
/* This is used by ko.isObservable */
|
|
478
|
-
observable.observablePrototypes.add(computed);
|
|
479
|
-
function isComputed(instance) {
|
|
480
|
-
return (typeof instance === 'function' && instance[protoProp] === computed);
|
|
481
|
-
}
|
|
482
|
-
function isPureComputed(instance) {
|
|
483
|
-
return isComputed(instance) && instance[computedState] && instance[computedState].pure;
|
|
484
|
-
}
|
|
485
|
-
function pureComputed(evaluatorFunctionOrOptions, evaluatorFunctionTarget) {
|
|
486
|
-
if (typeof evaluatorFunctionOrOptions === 'function') {
|
|
487
|
-
return computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget, { 'pure': true });
|
|
488
|
-
}
|
|
489
|
-
else {
|
|
490
|
-
evaluatorFunctionOrOptions = extend({}, evaluatorFunctionOrOptions); // make a copy of the parameter object
|
|
491
|
-
evaluatorFunctionOrOptions.pure = true;
|
|
492
|
-
return computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget);
|
|
493
|
-
}
|
|
1
|
+
// @tko/computed 🥊 4.0.0-beta1.0 ESM
|
|
2
|
+
import {
|
|
3
|
+
addDisposeCallback,
|
|
4
|
+
arrayForEach,
|
|
5
|
+
createSymbolOrString,
|
|
6
|
+
domNodeIsAttachedToDocument,
|
|
7
|
+
extend,
|
|
8
|
+
options,
|
|
9
|
+
hasOwnProperty,
|
|
10
|
+
objectForEach,
|
|
11
|
+
options as koOptions,
|
|
12
|
+
removeDisposeCallback,
|
|
13
|
+
safeSetTimeout
|
|
14
|
+
} from "@tko/utils";
|
|
15
|
+
import {
|
|
16
|
+
dependencyDetection,
|
|
17
|
+
extenders,
|
|
18
|
+
valuesArePrimitiveAndEqual,
|
|
19
|
+
observable,
|
|
20
|
+
subscribable,
|
|
21
|
+
LATEST_VALUE
|
|
22
|
+
} from "@tko/observable";
|
|
23
|
+
const computedState = createSymbolOrString("_state");
|
|
24
|
+
const DISPOSED_STATE = {
|
|
25
|
+
dependencyTracking: null,
|
|
26
|
+
dependenciesCount: 0,
|
|
27
|
+
isDisposed: true,
|
|
28
|
+
isStale: false,
|
|
29
|
+
isDirty: false,
|
|
30
|
+
isSleeping: false,
|
|
31
|
+
disposeWhenNodeIsRemoved: null,
|
|
32
|
+
readFunction: null,
|
|
33
|
+
_options: null
|
|
34
|
+
};
|
|
35
|
+
export function computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget, options2) {
|
|
36
|
+
if (typeof evaluatorFunctionOrOptions === "object") {
|
|
37
|
+
options2 = evaluatorFunctionOrOptions;
|
|
38
|
+
} else {
|
|
39
|
+
options2 = options2 || {};
|
|
40
|
+
if (evaluatorFunctionOrOptions) {
|
|
41
|
+
options2.read = evaluatorFunctionOrOptions;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (typeof options2.read !== "function") {
|
|
45
|
+
throw Error("Pass a function that returns the value of the computed");
|
|
46
|
+
}
|
|
47
|
+
var writeFunction = options2.write;
|
|
48
|
+
var state = {
|
|
49
|
+
latestValue: void 0,
|
|
50
|
+
isStale: true,
|
|
51
|
+
isDirty: true,
|
|
52
|
+
isBeingEvaluated: false,
|
|
53
|
+
suppressDisposalUntilDisposeWhenReturnsFalse: false,
|
|
54
|
+
isDisposed: false,
|
|
55
|
+
pure: false,
|
|
56
|
+
isSleeping: false,
|
|
57
|
+
readFunction: options2.read,
|
|
58
|
+
evaluatorFunctionTarget: evaluatorFunctionTarget || options2.owner,
|
|
59
|
+
disposeWhenNodeIsRemoved: options2.disposeWhenNodeIsRemoved || options2.disposeWhenNodeIsRemoved || null,
|
|
60
|
+
disposeWhen: options2.disposeWhen || options2.disposeWhen,
|
|
61
|
+
domNodeDisposalCallback: null,
|
|
62
|
+
dependencyTracking: {},
|
|
63
|
+
dependenciesCount: 0,
|
|
64
|
+
evaluationTimeoutInstance: null
|
|
65
|
+
};
|
|
66
|
+
function computedObservable() {
|
|
67
|
+
if (arguments.length > 0) {
|
|
68
|
+
if (typeof writeFunction === "function") {
|
|
69
|
+
writeFunction.apply(state.evaluatorFunctionTarget, arguments);
|
|
70
|
+
} else {
|
|
71
|
+
throw new Error("Cannot write a value to a computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
|
|
72
|
+
}
|
|
73
|
+
return this;
|
|
74
|
+
} else {
|
|
75
|
+
if (!state.isDisposed) {
|
|
76
|
+
dependencyDetection.registerDependency(computedObservable);
|
|
77
|
+
}
|
|
78
|
+
if (state.isDirty || state.isSleeping && computedObservable.haveDependenciesChanged()) {
|
|
79
|
+
computedObservable.evaluateImmediate();
|
|
80
|
+
}
|
|
81
|
+
return state.latestValue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
computedObservable[computedState] = state;
|
|
85
|
+
computedObservable.isWriteable = typeof writeFunction === "function";
|
|
86
|
+
subscribable.fn.init(computedObservable);
|
|
87
|
+
Object.setPrototypeOf(computedObservable, computed.fn);
|
|
88
|
+
if (options2.pure) {
|
|
89
|
+
state.pure = true;
|
|
90
|
+
state.isSleeping = true;
|
|
91
|
+
extend(computedObservable, pureComputedOverrides);
|
|
92
|
+
} else if (options2.deferEvaluation) {
|
|
93
|
+
extend(computedObservable, deferEvaluationOverrides);
|
|
94
|
+
}
|
|
95
|
+
if (koOptions.deferUpdates) {
|
|
96
|
+
extenders.deferred(computedObservable, true);
|
|
97
|
+
}
|
|
98
|
+
if (koOptions.debug) {
|
|
99
|
+
computedObservable._options = options2;
|
|
100
|
+
}
|
|
101
|
+
if (state.disposeWhenNodeIsRemoved) {
|
|
102
|
+
state.suppressDisposalUntilDisposeWhenReturnsFalse = true;
|
|
103
|
+
if (!state.disposeWhenNodeIsRemoved.nodeType) {
|
|
104
|
+
state.disposeWhenNodeIsRemoved = null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!state.isSleeping && !options2.deferEvaluation) {
|
|
108
|
+
computedObservable.evaluateImmediate();
|
|
109
|
+
}
|
|
110
|
+
if (state.disposeWhenNodeIsRemoved && computedObservable.isActive()) {
|
|
111
|
+
addDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback = function() {
|
|
112
|
+
computedObservable.dispose();
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return computedObservable;
|
|
494
116
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// notify updates, the target doesn't re-evaluate (and hence doesn't notify) faster than a certain rate
|
|
500
|
-
target.throttleEvaluation = timeout;
|
|
501
|
-
// (2) For writable targets (observables, or writable dependent observables), we throttle *writes*
|
|
502
|
-
// so the target cannot change value synchronously or faster than a certain rate
|
|
503
|
-
var writeTimeoutInstance = null;
|
|
504
|
-
return computed({
|
|
505
|
-
read: target,
|
|
506
|
-
write: function (value) {
|
|
507
|
-
clearTimeout(writeTimeoutInstance);
|
|
508
|
-
writeTimeoutInstance = setTimeout(function () {
|
|
509
|
-
target(value);
|
|
510
|
-
}, timeout);
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
extenders.throttle = throttleExtender;
|
|
515
|
-
|
|
516
|
-
/*! *****************************************************************************
|
|
517
|
-
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
518
|
-
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
519
|
-
this file except in compliance with the License. You may obtain a copy of the
|
|
520
|
-
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
521
|
-
|
|
522
|
-
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
523
|
-
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
524
|
-
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
525
|
-
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
526
|
-
|
|
527
|
-
See the Apache Version 2.0 License for specific language governing permissions
|
|
528
|
-
and limitations under the License.
|
|
529
|
-
***************************************************************************** */
|
|
530
|
-
|
|
531
|
-
function __values(o) {
|
|
532
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
|
533
|
-
if (m) return m.call(o);
|
|
534
|
-
return {
|
|
535
|
-
next: function () {
|
|
536
|
-
if (o && i >= o.length) o = void 0;
|
|
537
|
-
return { value: o && o[i++], done: !o };
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
function __read(o, n) {
|
|
543
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
544
|
-
if (!m) return o;
|
|
545
|
-
var i = m.call(o), r, ar = [], e;
|
|
546
|
-
try {
|
|
547
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
548
|
-
}
|
|
549
|
-
catch (error) { e = { error: error }; }
|
|
550
|
-
finally {
|
|
551
|
-
try {
|
|
552
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
553
|
-
}
|
|
554
|
-
finally { if (e) throw e.error; }
|
|
555
|
-
}
|
|
556
|
-
return ar;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function __spread() {
|
|
560
|
-
for (var ar = [], i = 0; i < arguments.length; i++)
|
|
561
|
-
ar = ar.concat(__read(arguments[i]));
|
|
562
|
-
return ar;
|
|
117
|
+
function computedDisposeDependencyCallback(id, entryToDispose) {
|
|
118
|
+
if (entryToDispose !== null && entryToDispose.dispose) {
|
|
119
|
+
entryToDispose.dispose();
|
|
120
|
+
}
|
|
563
121
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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
|
-
|
|
662
|
-
|
|
122
|
+
function computedBeginDependencyDetectionCallback(subscribable2, id) {
|
|
123
|
+
var computedObservable = this.computedObservable, state = computedObservable[computedState];
|
|
124
|
+
if (!state.isDisposed) {
|
|
125
|
+
if (this.disposalCount && this.disposalCandidates[id]) {
|
|
126
|
+
computedObservable.addDependencyTracking(id, subscribable2, this.disposalCandidates[id]);
|
|
127
|
+
this.disposalCandidates[id] = null;
|
|
128
|
+
--this.disposalCount;
|
|
129
|
+
} else if (!state.dependencyTracking[id]) {
|
|
130
|
+
computedObservable.addDependencyTracking(id, subscribable2, state.isSleeping ? { _target: subscribable2 } : computedObservable.subscribeToDependency(subscribable2));
|
|
131
|
+
}
|
|
132
|
+
if (subscribable2._notificationIsPending) {
|
|
133
|
+
subscribable2._notifyNextChangeIfValueIsDifferent();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
computed.fn = {
|
|
138
|
+
equalityComparer: valuesArePrimitiveAndEqual,
|
|
139
|
+
getDependenciesCount() {
|
|
140
|
+
return this[computedState].dependenciesCount;
|
|
141
|
+
},
|
|
142
|
+
getDependencies() {
|
|
143
|
+
const dependencyTracking = this[computedState].dependencyTracking;
|
|
144
|
+
const dependentObservables = [];
|
|
145
|
+
objectForEach(dependencyTracking, function(id, dependency) {
|
|
146
|
+
dependentObservables[dependency._order] = dependency._target;
|
|
147
|
+
});
|
|
148
|
+
return dependentObservables;
|
|
149
|
+
},
|
|
150
|
+
addDependencyTracking(id, target, trackingObj) {
|
|
151
|
+
if (this[computedState].pure && target === this) {
|
|
152
|
+
throw Error("A 'pure' computed must not be called recursively");
|
|
153
|
+
}
|
|
154
|
+
this[computedState].dependencyTracking[id] = trackingObj;
|
|
155
|
+
trackingObj._order = this[computedState].dependenciesCount++;
|
|
156
|
+
trackingObj._version = target.getVersion();
|
|
157
|
+
},
|
|
158
|
+
haveDependenciesChanged() {
|
|
159
|
+
var id, dependency, dependencyTracking = this[computedState].dependencyTracking;
|
|
160
|
+
for (id in dependencyTracking) {
|
|
161
|
+
if (hasOwnProperty(dependencyTracking, id)) {
|
|
162
|
+
dependency = dependencyTracking[id];
|
|
163
|
+
if (this._evalDelayed && dependency._target._notificationIsPending || dependency._target.hasChanged(dependency._version)) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
markDirty() {
|
|
170
|
+
if (this._evalDelayed && !this[computedState].isBeingEvaluated) {
|
|
171
|
+
this._evalDelayed(false);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
isActive() {
|
|
175
|
+
const state = this[computedState];
|
|
176
|
+
return state.isDirty || state.dependenciesCount > 0;
|
|
177
|
+
},
|
|
178
|
+
respondToChange() {
|
|
179
|
+
if (!this._notificationIsPending) {
|
|
180
|
+
this.evaluatePossiblyAsync();
|
|
181
|
+
} else if (this[computedState].isDirty) {
|
|
182
|
+
this[computedState].isStale = true;
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
subscribeToDependency(target) {
|
|
186
|
+
if (target._deferUpdates) {
|
|
187
|
+
var dirtySub = target.subscribe(this.markDirty, this, "dirty"), changeSub = target.subscribe(this.respondToChange, this);
|
|
188
|
+
return {
|
|
189
|
+
_target: target,
|
|
190
|
+
dispose() {
|
|
191
|
+
dirtySub.dispose();
|
|
192
|
+
changeSub.dispose();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
} else {
|
|
196
|
+
return target.subscribe(this.evaluatePossiblyAsync, this);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
evaluatePossiblyAsync() {
|
|
200
|
+
var computedObservable = this, throttleEvaluationTimeout = computedObservable.throttleEvaluation;
|
|
201
|
+
if (throttleEvaluationTimeout && throttleEvaluationTimeout >= 0) {
|
|
202
|
+
clearTimeout(this[computedState].evaluationTimeoutInstance);
|
|
203
|
+
this[computedState].evaluationTimeoutInstance = safeSetTimeout(function() {
|
|
204
|
+
computedObservable.evaluateImmediate(true);
|
|
205
|
+
}, throttleEvaluationTimeout);
|
|
206
|
+
} else if (computedObservable._evalDelayed) {
|
|
207
|
+
computedObservable._evalDelayed(true);
|
|
208
|
+
} else {
|
|
209
|
+
computedObservable.evaluateImmediate(true);
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
evaluateImmediate(notifyChange) {
|
|
213
|
+
var computedObservable = this, state = computedObservable[computedState], disposeWhen = state.disposeWhen, changed = false;
|
|
214
|
+
if (state.isBeingEvaluated) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (state.isDisposed) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (state.disposeWhenNodeIsRemoved && !domNodeIsAttachedToDocument(state.disposeWhenNodeIsRemoved) || disposeWhen && disposeWhen()) {
|
|
221
|
+
if (!state.suppressDisposalUntilDisposeWhenReturnsFalse) {
|
|
222
|
+
computedObservable.dispose();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
state.suppressDisposalUntilDisposeWhenReturnsFalse = false;
|
|
227
|
+
}
|
|
228
|
+
state.isBeingEvaluated = true;
|
|
229
|
+
try {
|
|
230
|
+
changed = this.evaluateImmediate_CallReadWithDependencyDetection(notifyChange);
|
|
231
|
+
} finally {
|
|
232
|
+
state.isBeingEvaluated = false;
|
|
233
|
+
}
|
|
234
|
+
return changed;
|
|
235
|
+
},
|
|
236
|
+
evaluateImmediate_CallReadWithDependencyDetection(notifyChange) {
|
|
237
|
+
var computedObservable = this, state = computedObservable[computedState], changed = false;
|
|
238
|
+
var isInitial = state.pure ? void 0 : !state.dependenciesCount, dependencyDetectionContext = {
|
|
239
|
+
computedObservable,
|
|
240
|
+
disposalCandidates: state.dependencyTracking,
|
|
241
|
+
disposalCount: state.dependenciesCount
|
|
242
|
+
};
|
|
243
|
+
dependencyDetection.begin({
|
|
244
|
+
callbackTarget: dependencyDetectionContext,
|
|
245
|
+
callback: computedBeginDependencyDetectionCallback,
|
|
246
|
+
computed: computedObservable,
|
|
247
|
+
isInitial
|
|
248
|
+
});
|
|
249
|
+
state.dependencyTracking = {};
|
|
250
|
+
state.dependenciesCount = 0;
|
|
251
|
+
var newValue = this.evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext);
|
|
252
|
+
if (!state.dependenciesCount) {
|
|
253
|
+
computedObservable.dispose();
|
|
254
|
+
changed = true;
|
|
255
|
+
} else {
|
|
256
|
+
changed = computedObservable.isDifferent(state.latestValue, newValue);
|
|
257
|
+
}
|
|
258
|
+
if (changed) {
|
|
259
|
+
if (!state.isSleeping) {
|
|
260
|
+
computedObservable.notifySubscribers(state.latestValue, "beforeChange");
|
|
261
|
+
} else {
|
|
262
|
+
computedObservable.updateVersion();
|
|
263
|
+
}
|
|
264
|
+
state.latestValue = newValue;
|
|
265
|
+
if (options.debug) {
|
|
266
|
+
computedObservable._latestValue = newValue;
|
|
267
|
+
}
|
|
268
|
+
computedObservable.notifySubscribers(state.latestValue, "spectate");
|
|
269
|
+
if (!state.isSleeping && notifyChange) {
|
|
270
|
+
computedObservable.notifySubscribers(state.latestValue);
|
|
271
|
+
}
|
|
272
|
+
if (computedObservable._recordUpdate) {
|
|
273
|
+
computedObservable._recordUpdate();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (isInitial) {
|
|
277
|
+
computedObservable.notifySubscribers(state.latestValue, "awake");
|
|
278
|
+
}
|
|
279
|
+
return changed;
|
|
280
|
+
},
|
|
281
|
+
evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext) {
|
|
282
|
+
try {
|
|
283
|
+
var readFunction = state.readFunction;
|
|
284
|
+
return state.evaluatorFunctionTarget ? readFunction.call(state.evaluatorFunctionTarget) : readFunction();
|
|
285
|
+
} finally {
|
|
286
|
+
dependencyDetection.end();
|
|
287
|
+
if (dependencyDetectionContext.disposalCount && !state.isSleeping) {
|
|
288
|
+
objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback);
|
|
289
|
+
}
|
|
290
|
+
state.isStale = state.isDirty = false;
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
peek(forceEvaluate) {
|
|
294
|
+
const state = this[computedState];
|
|
295
|
+
if (state.isDirty && (forceEvaluate || !state.dependenciesCount) || state.isSleeping && this.haveDependenciesChanged()) {
|
|
296
|
+
this.evaluateImmediate();
|
|
297
|
+
}
|
|
298
|
+
return state.latestValue;
|
|
299
|
+
},
|
|
300
|
+
get [LATEST_VALUE]() {
|
|
301
|
+
return this.peek();
|
|
302
|
+
},
|
|
303
|
+
limit(limitFunction) {
|
|
304
|
+
const state = this[computedState];
|
|
305
|
+
subscribable.fn.limit.call(this, limitFunction);
|
|
306
|
+
Object.assign(this, {
|
|
307
|
+
_evalIfChanged() {
|
|
308
|
+
if (!this[computedState].isSleeping) {
|
|
309
|
+
if (this[computedState].isStale) {
|
|
310
|
+
this.evaluateImmediate();
|
|
311
|
+
} else {
|
|
312
|
+
this[computedState].isDirty = false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return state.latestValue;
|
|
316
|
+
},
|
|
317
|
+
_evalDelayed(isChange) {
|
|
318
|
+
this._limitBeforeChange(state.latestValue);
|
|
319
|
+
state.isDirty = true;
|
|
320
|
+
if (isChange) {
|
|
321
|
+
state.isStale = true;
|
|
322
|
+
}
|
|
323
|
+
this._limitChange(this, !isChange);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
},
|
|
327
|
+
dispose() {
|
|
328
|
+
var state = this[computedState];
|
|
329
|
+
if (!state.isSleeping && state.dependencyTracking) {
|
|
330
|
+
objectForEach(state.dependencyTracking, function(id, dependency) {
|
|
331
|
+
if (dependency.dispose) {
|
|
332
|
+
dependency.dispose();
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
if (state.disposeWhenNodeIsRemoved && state.domNodeDisposalCallback) {
|
|
337
|
+
removeDisposeCallback(state.disposeWhenNodeIsRemoved, state.domNodeDisposalCallback);
|
|
338
|
+
}
|
|
339
|
+
Object.assign(state, DISPOSED_STATE);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
var pureComputedOverrides = {
|
|
343
|
+
beforeSubscriptionAdd(event) {
|
|
344
|
+
var computedObservable = this, state = computedObservable[computedState];
|
|
345
|
+
if (!state.isDisposed && state.isSleeping && event === "change") {
|
|
346
|
+
state.isSleeping = false;
|
|
347
|
+
if (state.isStale || computedObservable.haveDependenciesChanged()) {
|
|
348
|
+
state.dependencyTracking = null;
|
|
349
|
+
state.dependenciesCount = 0;
|
|
350
|
+
if (computedObservable.evaluateImmediate()) {
|
|
351
|
+
computedObservable.updateVersion();
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
var dependenciesOrder = [];
|
|
355
|
+
objectForEach(state.dependencyTracking, function(id, dependency) {
|
|
356
|
+
dependenciesOrder[dependency._order] = id;
|
|
357
|
+
});
|
|
358
|
+
arrayForEach(dependenciesOrder, function(id, order) {
|
|
359
|
+
var dependency = state.dependencyTracking[id], subscription = computedObservable.subscribeToDependency(dependency._target);
|
|
360
|
+
subscription._order = order;
|
|
361
|
+
subscription._version = dependency._version;
|
|
362
|
+
state.dependencyTracking[id] = subscription;
|
|
363
|
+
});
|
|
364
|
+
if (computedObservable.haveDependenciesChanged()) {
|
|
365
|
+
if (computedObservable.evaluateImmediate()) {
|
|
366
|
+
computedObservable.updateVersion();
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (!state.isDisposed) {
|
|
371
|
+
computedObservable.notifySubscribers(state.latestValue, "awake");
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
afterSubscriptionRemove(event) {
|
|
376
|
+
var state = this[computedState];
|
|
377
|
+
if (!state.isDisposed && event === "change" && !this.hasSubscriptionsForEvent("change")) {
|
|
378
|
+
objectForEach(state.dependencyTracking, function(id, dependency) {
|
|
379
|
+
if (dependency.dispose) {
|
|
380
|
+
state.dependencyTracking[id] = {
|
|
381
|
+
_target: dependency._target,
|
|
382
|
+
_order: dependency._order,
|
|
383
|
+
_version: dependency._version
|
|
384
|
+
};
|
|
385
|
+
dependency.dispose();
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
state.isSleeping = true;
|
|
389
|
+
this.notifySubscribers(void 0, "asleep");
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
getVersion() {
|
|
393
|
+
var state = this[computedState];
|
|
394
|
+
if (state.isSleeping && (state.isStale || this.haveDependenciesChanged())) {
|
|
395
|
+
this.evaluateImmediate();
|
|
396
|
+
}
|
|
397
|
+
return subscribable.fn.getVersion.call(this);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
var deferEvaluationOverrides = {
|
|
401
|
+
beforeSubscriptionAdd(event) {
|
|
402
|
+
if (event === "change" || event === "beforeChange") {
|
|
403
|
+
this.peek();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
Object.setPrototypeOf(computed.fn, subscribable.fn);
|
|
408
|
+
var protoProp = observable.protoProperty;
|
|
409
|
+
computed.fn[protoProp] = computed;
|
|
410
|
+
observable.observablePrototypes.add(computed);
|
|
411
|
+
export function isComputed(instance) {
|
|
412
|
+
return typeof instance === "function" && instance[protoProp] === computed;
|
|
413
|
+
}
|
|
414
|
+
export function isPureComputed(instance) {
|
|
415
|
+
return isComputed(instance) && instance[computedState] && instance[computedState].pure;
|
|
416
|
+
}
|
|
417
|
+
export function pureComputed(evaluatorFunctionOrOptions, evaluatorFunctionTarget) {
|
|
418
|
+
if (typeof evaluatorFunctionOrOptions === "function") {
|
|
419
|
+
return computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget, { "pure": true });
|
|
420
|
+
} else {
|
|
421
|
+
evaluatorFunctionOrOptions = extend({}, evaluatorFunctionOrOptions);
|
|
422
|
+
evaluatorFunctionOrOptions.pure = true;
|
|
423
|
+
return computed(evaluatorFunctionOrOptions, evaluatorFunctionTarget);
|
|
424
|
+
}
|
|
663
425
|
}
|
|
664
|
-
|
|
665
|
-
//
|
|
666
|
-
|
|
667
|
-
export { computed, isComputed, isPureComputed, pureComputed, throttleExtender, proxy, when };
|
|
668
|
-
//# sourceMappingURL=computed.js.map
|