ember-source 6.0.0-alpha.9 → 6.0.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/blueprints/component/index.js +8 -71
- package/blueprints/component-class/index.js +8 -47
- package/build-metadata.json +3 -3
- package/dist/ember-template-compiler.js +4200 -6302
- package/dist/ember-testing.js +1 -1
- package/dist/ember.debug.js +4040 -8666
- package/dist/ember.prod.js +3734 -8082
- package/dist/packages/@glimmer/debug/index.js +87 -1440
- package/dist/packages/@glimmer/destroyable/index.js +59 -113
- package/dist/packages/@glimmer/encoder/index.js +4 -11
- package/dist/packages/@glimmer/global-context/index.js +40 -144
- package/dist/packages/@glimmer/manager/index.js +191 -312
- package/dist/packages/@glimmer/node/index.js +34 -76
- package/dist/packages/@glimmer/opcode-compiler/index.js +794 -1422
- package/dist/packages/@glimmer/owner/index.js +2 -1
- package/dist/packages/@glimmer/program/index.js +105 -192
- package/dist/packages/@glimmer/reference/index.js +109 -237
- package/dist/packages/@glimmer/runtime/index.js +1939 -3715
- package/dist/packages/@glimmer/util/index.js +114 -241
- package/dist/packages/@glimmer/validator/index.js +203 -409
- package/dist/packages/@glimmer/vm/index.js +163 -176
- package/dist/packages/@glimmer/wire-format/index.js +70 -71
- package/dist/packages/ember/version.js +1 -1
- package/docs/data.json +1 -1
- package/lib/browsers.js +40 -68
- package/package.json +21 -24
|
@@ -2,95 +2,54 @@ import { assert, scheduleRevalidate } from '../global-context/index.js';
|
|
|
2
2
|
import { getLast, asPresentArray } from '../util/index.js';
|
|
3
3
|
import { isDevelopingApp } from '@embroider/macros';
|
|
4
4
|
|
|
5
|
-
function indexable(input) {
|
|
6
|
-
return input;
|
|
7
|
-
}
|
|
8
|
-
function getGlobal() {
|
|
9
|
-
if (typeof globalThis !== 'undefined') return indexable(globalThis);
|
|
10
|
-
if (typeof self !== 'undefined') return indexable(self);
|
|
11
|
-
if (typeof window !== 'undefined') return indexable(window);
|
|
12
|
-
if (typeof global !== 'undefined') return indexable(global);
|
|
13
|
-
throw new Error('unable to locate global object');
|
|
14
|
-
}
|
|
15
5
|
function unwrap(val) {
|
|
16
|
-
if (
|
|
6
|
+
if (null == val) throw new Error("Expected value to be present");
|
|
17
7
|
return val;
|
|
18
8
|
}
|
|
19
9
|
const debug = {};
|
|
20
10
|
if (isDevelopingApp()) {
|
|
21
11
|
let CONSUMED_TAGS = null;
|
|
22
|
-
const TRANSACTION_STACK = []
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
debugMessage(obj, keyName) {
|
|
28
|
-
let objName;
|
|
29
|
-
if (typeof obj === 'function') {
|
|
30
|
-
objName = obj.name;
|
|
31
|
-
} else if (typeof obj === 'object' && obj !== null) {
|
|
32
|
-
let className = obj.constructor && obj.constructor.name || '(unknown class)';
|
|
33
|
-
objName = `(an instance of ${className})`;
|
|
34
|
-
} else if (obj === undefined) {
|
|
35
|
-
objName = '(an unknown tag)';
|
|
36
|
-
} else {
|
|
37
|
-
objName = String(obj);
|
|
12
|
+
const TRANSACTION_STACK = [],
|
|
13
|
+
TRANSACTION_ENV = {
|
|
14
|
+
debugMessage(obj, keyName) {
|
|
15
|
+
let objName;
|
|
16
|
+
return objName = "function" == typeof obj ? obj.name : "object" == typeof obj && null !== obj ? `(an instance of ${obj.constructor && obj.constructor.name || "(unknown class)"})` : void 0 === obj ? "(an unknown tag)" : String(obj), `You attempted to update ${keyName ? `\`${keyName}\` on \`${objName}\`` : `\`${objName}\``}, but it had already been used previously in the same computation. Attempting to update a value after using it in a computation can cause logical errors, infinite revalidation bugs, and performance issues, and is not supported.`;
|
|
38
17
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
43
|
-
debug.setTrackingTransactionEnv = env => Object.assign(TRANSACTION_ENV, env);
|
|
44
|
-
debug.beginTrackingTransaction = _debugLabel => {
|
|
18
|
+
};
|
|
19
|
+
/////////
|
|
20
|
+
debug.setTrackingTransactionEnv = env => Object.assign(TRANSACTION_ENV, env), debug.beginTrackingTransaction = _debugLabel => {
|
|
45
21
|
CONSUMED_TAGS = CONSUMED_TAGS || new WeakMap();
|
|
46
|
-
let debugLabel = _debugLabel ||
|
|
47
|
-
|
|
22
|
+
let debugLabel = _debugLabel || void 0,
|
|
23
|
+
parent = TRANSACTION_STACK[TRANSACTION_STACK.length - 1] ?? null;
|
|
48
24
|
TRANSACTION_STACK.push({
|
|
49
|
-
parent,
|
|
50
|
-
debugLabel
|
|
25
|
+
parent: parent,
|
|
26
|
+
debugLabel: debugLabel
|
|
51
27
|
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
TRANSACTION_STACK.
|
|
58
|
-
|
|
59
|
-
CONSUMED_TAGS = null;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
debug.resetTrackingTransaction = () => {
|
|
63
|
-
let stack = '';
|
|
64
|
-
if (TRANSACTION_STACK.length > 0) {
|
|
65
|
-
stack = debug.logTrackingStack(TRANSACTION_STACK[TRANSACTION_STACK.length - 1]);
|
|
66
|
-
}
|
|
67
|
-
TRANSACTION_STACK.splice(0, TRANSACTION_STACK.length);
|
|
68
|
-
CONSUMED_TAGS = null;
|
|
69
|
-
return stack;
|
|
70
|
-
};
|
|
71
|
-
|
|
28
|
+
}, debug.endTrackingTransaction = () => {
|
|
29
|
+
if (0 === TRANSACTION_STACK.length) throw new Error("attempted to close a tracking transaction, but one was not open");
|
|
30
|
+
TRANSACTION_STACK.pop(), 0 === TRANSACTION_STACK.length && (CONSUMED_TAGS = null);
|
|
31
|
+
}, debug.resetTrackingTransaction = () => {
|
|
32
|
+
let stack = "";
|
|
33
|
+
return TRANSACTION_STACK.length > 0 && (stack = debug.logTrackingStack(TRANSACTION_STACK[TRANSACTION_STACK.length - 1])), TRANSACTION_STACK.splice(0, TRANSACTION_STACK.length), CONSUMED_TAGS = null, stack;
|
|
34
|
+
},
|
|
72
35
|
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
36
|
+
* Creates a global autotracking transaction. This will prevent any backflow
|
|
37
|
+
* in any `track` calls within the transaction, even if they are not
|
|
38
|
+
* externally consumed.
|
|
39
|
+
*
|
|
40
|
+
* `runInAutotrackingTransaction` can be called within itself, and it will add
|
|
41
|
+
* onto the existing transaction if one exists.
|
|
42
|
+
*
|
|
43
|
+
* TODO: Only throw an error if the `track` is consumed.
|
|
44
|
+
*/
|
|
82
45
|
debug.runInTrackingTransaction = (fn, debugLabel) => {
|
|
83
46
|
debug.beginTrackingTransaction(debugLabel);
|
|
84
|
-
let didError =
|
|
47
|
+
let didError = !0;
|
|
85
48
|
try {
|
|
86
49
|
let value = fn();
|
|
87
|
-
didError =
|
|
88
|
-
return value;
|
|
50
|
+
return didError = !1, value;
|
|
89
51
|
} finally {
|
|
90
|
-
|
|
91
|
-
debug.endTrackingTransaction();
|
|
92
|
-
}
|
|
93
|
-
|
|
52
|
+
!0 !== didError && debug.endTrackingTransaction();
|
|
94
53
|
// if (id !== TRANSACTION_STACK.length) {
|
|
95
54
|
// throw new Error(
|
|
96
55
|
// `attempted to close a tracking transaction (${id}), but it was not the last transaction (${TRANSACTION_STACK.length})`
|
|
@@ -99,97 +58,65 @@ if (isDevelopingApp()) {
|
|
|
99
58
|
}
|
|
100
59
|
};
|
|
101
60
|
let nthIndex = (str, pattern, n, startingPos = -1) => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
let message = [TRANSACTION_ENV.debugMessage(obj, keyName && String(keyName))];
|
|
111
|
-
message.push(`\`${String(keyName)}\` was first used:`);
|
|
112
|
-
message.push(debug.logTrackingStack(transaction));
|
|
113
|
-
message.push(`Stack trace for the update:`);
|
|
114
|
-
return message.join('\n\n');
|
|
115
|
-
};
|
|
61
|
+
let i = startingPos;
|
|
62
|
+
for (; n-- > 0 && i++ < str.length && (i = str.indexOf(pattern, i), !(i < 0)););
|
|
63
|
+
return i;
|
|
64
|
+
},
|
|
65
|
+
makeTrackingErrorMessage = (transaction, obj, keyName) => {
|
|
66
|
+
let message = [TRANSACTION_ENV.debugMessage(obj, keyName && String(keyName))];
|
|
67
|
+
return message.push(`\`${String(keyName)}\` was first used:`), message.push(debug.logTrackingStack(transaction)), message.push("Stack trace for the update:"), message.join("\n\n");
|
|
68
|
+
};
|
|
116
69
|
debug.logTrackingStack = transaction => {
|
|
117
|
-
let trackingStack = []
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
current = current.parent;
|
|
125
|
-
}
|
|
126
|
-
return trackingStack.map((label, index) => ' '.repeat(2 * index) + label).join('\n');
|
|
127
|
-
};
|
|
128
|
-
debug.markTagAsConsumed = _tag => {
|
|
70
|
+
let trackingStack = [],
|
|
71
|
+
current = transaction || TRANSACTION_STACK[TRANSACTION_STACK.length - 1];
|
|
72
|
+
if (void 0 === current) return "";
|
|
73
|
+
for (; current;) current.debugLabel && trackingStack.unshift(current.debugLabel), current = current.parent;
|
|
74
|
+
return trackingStack.map((label, index) => " ".repeat(2 * index) + label).join("\n");
|
|
75
|
+
}, debug.markTagAsConsumed = _tag => {
|
|
129
76
|
if (!CONSUMED_TAGS || CONSUMED_TAGS.has(_tag)) return;
|
|
130
77
|
CONSUMED_TAGS.set(_tag, getLast(asPresentArray(TRANSACTION_STACK)));
|
|
131
|
-
|
|
132
78
|
// We need to mark the tag and all of its subtags as consumed, so we need to
|
|
133
79
|
// cast it and access its internals. In the future this shouldn't be necessary,
|
|
134
80
|
// this is only for computed properties.
|
|
135
81
|
let subtag = _tag.subtag;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
} else {
|
|
140
|
-
debug.markTagAsConsumed(subtag);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
debug.assertTagNotConsumed = (tag, obj, keyName) => {
|
|
144
|
-
if (CONSUMED_TAGS === null) return;
|
|
82
|
+
subtag && debug.markTagAsConsumed && (Array.isArray(subtag) ? subtag.forEach(debug.markTagAsConsumed) : debug.markTagAsConsumed(subtag));
|
|
83
|
+
}, debug.assertTagNotConsumed = (tag, obj, keyName) => {
|
|
84
|
+
if (null === CONSUMED_TAGS) return;
|
|
145
85
|
let transaction = CONSUMED_TAGS.get(tag);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
86
|
+
var error;
|
|
87
|
+
//////////
|
|
88
|
+
if (transaction)
|
|
89
|
+
// This hack makes the assertion message nicer, we can cut off the first
|
|
90
|
+
// few lines of the stack trace and let users know where the actual error
|
|
91
|
+
// occurred.
|
|
92
|
+
try {
|
|
93
|
+
assert(!1, makeTrackingErrorMessage(transaction, obj, keyName));
|
|
94
|
+
} catch (e) {
|
|
95
|
+
if ("object" == typeof (error = e) && null !== error && "stack" in error && "string" == typeof error.stack) {
|
|
96
|
+
let updateStackBegin = e.stack.indexOf("Stack trace for the update:");
|
|
97
|
+
if (-1 !== updateStackBegin) {
|
|
98
|
+
let start = nthIndex(e.stack, "\n", 1, updateStackBegin),
|
|
99
|
+
end = nthIndex(e.stack, "\n", 4, updateStackBegin);
|
|
100
|
+
e.stack = e.stack.substr(0, start) + e.stack.substr(end);
|
|
101
|
+
}
|
|
160
102
|
}
|
|
103
|
+
throw e;
|
|
161
104
|
}
|
|
162
|
-
throw e;
|
|
163
|
-
}
|
|
164
105
|
};
|
|
165
106
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
//////////
|
|
171
|
-
|
|
172
|
-
const CONSTANT = 0;
|
|
173
|
-
const INITIAL = 1;
|
|
174
|
-
const VOLATILE = NaN;
|
|
175
|
-
let $REVISION = INITIAL;
|
|
107
|
+
const CONSTANT = 0,
|
|
108
|
+
INITIAL = 1,
|
|
109
|
+
VOLATILE = NaN;
|
|
110
|
+
let $REVISION = 1;
|
|
176
111
|
function bump() {
|
|
177
112
|
$REVISION++;
|
|
178
113
|
}
|
|
179
114
|
|
|
180
115
|
//////////
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const UPDATABLE_TAG_ID = 1;
|
|
184
|
-
const COMBINATOR_TAG_ID = 2;
|
|
185
|
-
const CONSTANT_TAG_ID = 3;
|
|
186
|
-
|
|
187
|
-
//////////
|
|
188
|
-
|
|
189
|
-
const COMPUTE = Symbol('TAG_COMPUTE');
|
|
116
|
+
const UPDATABLE_TAG_ID = 1,
|
|
117
|
+
COMPUTE = Symbol("TAG_COMPUTE");
|
|
190
118
|
|
|
191
119
|
//////////
|
|
192
|
-
|
|
193
120
|
/**
|
|
194
121
|
* `value` receives a tag and returns an opaque Revision based on that tag. This
|
|
195
122
|
* snapshot can then later be passed to `validate` with the same tag to
|
|
@@ -217,21 +144,11 @@ function validateTag(tag, snapshot) {
|
|
|
217
144
|
}
|
|
218
145
|
|
|
219
146
|
//////////
|
|
220
|
-
|
|
221
|
-
const TYPE = Symbol('TAG_TYPE');
|
|
147
|
+
const TYPE = Symbol("TAG_TYPE");
|
|
222
148
|
|
|
223
149
|
// this is basically a const
|
|
224
150
|
let ALLOW_CYCLES;
|
|
225
|
-
|
|
226
|
-
ALLOW_CYCLES = new WeakMap();
|
|
227
|
-
}
|
|
228
|
-
function allowsCycles(tag) {
|
|
229
|
-
if (ALLOW_CYCLES === undefined) {
|
|
230
|
-
return true;
|
|
231
|
-
} else {
|
|
232
|
-
return ALLOW_CYCLES.has(tag);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
151
|
+
isDevelopingApp() && (ALLOW_CYCLES = new WeakMap());
|
|
235
152
|
class MonomorphicTagImpl {
|
|
236
153
|
static combine(tags) {
|
|
237
154
|
switch (tags.length) {
|
|
@@ -241,16 +158,15 @@ class MonomorphicTagImpl {
|
|
|
241
158
|
return tags[0];
|
|
242
159
|
default:
|
|
243
160
|
{
|
|
244
|
-
let tag = new MonomorphicTagImpl(
|
|
245
|
-
tag.subtag = tags;
|
|
246
|
-
return tag;
|
|
161
|
+
let tag = new MonomorphicTagImpl(2);
|
|
162
|
+
return tag.subtag = tags, tag;
|
|
247
163
|
}
|
|
248
164
|
}
|
|
249
165
|
}
|
|
250
|
-
revision =
|
|
251
|
-
lastChecked =
|
|
252
|
-
lastValue =
|
|
253
|
-
isUpdating =
|
|
166
|
+
revision = 1;
|
|
167
|
+
lastChecked = 1;
|
|
168
|
+
lastValue = 1;
|
|
169
|
+
isUpdating = !1;
|
|
254
170
|
subtag = null;
|
|
255
171
|
subtagBufferCache = null;
|
|
256
172
|
[TYPE];
|
|
@@ -259,195 +175,128 @@ class MonomorphicTagImpl {
|
|
|
259
175
|
}
|
|
260
176
|
[COMPUTE]() {
|
|
261
177
|
let {
|
|
262
|
-
lastChecked
|
|
178
|
+
lastChecked: lastChecked
|
|
263
179
|
} = this;
|
|
264
|
-
if (this.isUpdating
|
|
265
|
-
if (isDevelopingApp() && !
|
|
266
|
-
throw new Error('Cycles in tags are not allowed');
|
|
267
|
-
}
|
|
180
|
+
if (!0 === this.isUpdating) {
|
|
181
|
+
if (isDevelopingApp() && void 0 !== ALLOW_CYCLES && !ALLOW_CYCLES.has(this)) throw new Error("Cycles in tags are not allowed");
|
|
268
182
|
this.lastChecked = ++$REVISION;
|
|
269
183
|
} else if (lastChecked !== $REVISION) {
|
|
270
|
-
this.isUpdating =
|
|
271
|
-
this.lastChecked = $REVISION;
|
|
184
|
+
this.isUpdating = !0, this.lastChecked = $REVISION;
|
|
272
185
|
try {
|
|
273
186
|
let {
|
|
274
|
-
subtag,
|
|
275
|
-
revision
|
|
187
|
+
subtag: subtag,
|
|
188
|
+
revision: revision
|
|
276
189
|
} = this;
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (subtagValue === this.subtagBufferCache) {
|
|
286
|
-
revision = Math.max(revision, this.lastValue);
|
|
287
|
-
} else {
|
|
288
|
-
// Clear the temporary buffer cache
|
|
289
|
-
this.subtagBufferCache = null;
|
|
290
|
-
revision = Math.max(revision, subtagValue);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
190
|
+
if (null !== subtag) if (Array.isArray(subtag)) for (const tag of subtag) {
|
|
191
|
+
let value = tag[COMPUTE]();
|
|
192
|
+
revision = Math.max(value, revision);
|
|
193
|
+
} else {
|
|
194
|
+
let subtagValue = subtag[COMPUTE]();
|
|
195
|
+
subtagValue === this.subtagBufferCache ? revision = Math.max(revision, this.lastValue) : (
|
|
196
|
+
// Clear the temporary buffer cache
|
|
197
|
+
this.subtagBufferCache = null, revision = Math.max(revision, subtagValue));
|
|
293
198
|
}
|
|
294
199
|
this.lastValue = revision;
|
|
295
200
|
} finally {
|
|
296
|
-
this.isUpdating =
|
|
201
|
+
this.isUpdating = !1;
|
|
297
202
|
}
|
|
298
203
|
}
|
|
299
204
|
return this.lastValue;
|
|
300
205
|
}
|
|
301
206
|
static updateTag(_tag, _subtag) {
|
|
302
|
-
if (isDevelopingApp() && _tag[TYPE] !== UPDATABLE_TAG_ID)
|
|
303
|
-
throw new Error('Attempted to update a tag that was not updatable');
|
|
304
|
-
}
|
|
305
|
-
|
|
207
|
+
if (isDevelopingApp() && _tag[TYPE] !== UPDATABLE_TAG_ID) throw new Error("Attempted to update a tag that was not updatable");
|
|
306
208
|
// TODO: TS 3.7 should allow us to do this via assertion
|
|
307
|
-
let tag = _tag
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
// its computed value, and then check against that computed value on
|
|
327
|
-
// subsequent updates. If its value hasn't changed, then we return the
|
|
328
|
-
// parent's previous value. Once the subtag changes for the first time,
|
|
329
|
-
// we clear the cache and everything is finally in sync with the parent.
|
|
330
|
-
tag.subtagBufferCache = subtag[COMPUTE]();
|
|
331
|
-
tag.subtag = subtag;
|
|
332
|
-
}
|
|
209
|
+
let tag = _tag,
|
|
210
|
+
subtag = _subtag;
|
|
211
|
+
subtag === CONSTANT_TAG ? tag.subtag = null : (
|
|
212
|
+
// There are two different possibilities when updating a subtag:
|
|
213
|
+
// 1. subtag[COMPUTE]() <= tag[COMPUTE]();
|
|
214
|
+
// 2. subtag[COMPUTE]() > tag[COMPUTE]();
|
|
215
|
+
// The first possibility is completely fine within our caching model, but
|
|
216
|
+
// the second possibility presents a problem. If the parent tag has
|
|
217
|
+
// already been read, then it's value is cached and will not update to
|
|
218
|
+
// reflect the subtag's greater value. Next time the cache is busted, the
|
|
219
|
+
// subtag's value _will_ be read, and it's value will be _greater_ than
|
|
220
|
+
// the saved snapshot of the parent, causing the resulting calculation to
|
|
221
|
+
// be rerun erroneously.
|
|
222
|
+
// In order to prevent this, when we first update to a new subtag we store
|
|
223
|
+
// its computed value, and then check against that computed value on
|
|
224
|
+
// subsequent updates. If its value hasn't changed, then we return the
|
|
225
|
+
// parent's previous value. Once the subtag changes for the first time,
|
|
226
|
+
// we clear the cache and everything is finally in sync with the parent.
|
|
227
|
+
tag.subtagBufferCache = subtag[COMPUTE](), tag.subtag = subtag);
|
|
333
228
|
}
|
|
334
229
|
static dirtyTag(tag, disableConsumptionAssertion) {
|
|
335
|
-
if (isDevelopingApp() &&
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
// but this is our last line of defense.
|
|
341
|
-
unwrap(debug.assertTagNotConsumed)(tag);
|
|
342
|
-
}
|
|
343
|
-
tag.revision = ++$REVISION;
|
|
344
|
-
scheduleRevalidate();
|
|
230
|
+
if (isDevelopingApp() && tag[TYPE] !== UPDATABLE_TAG_ID && 0 !== tag[TYPE]) throw new Error("Attempted to dirty a tag that was not dirtyable");
|
|
231
|
+
isDevelopingApp() && !0 !== disableConsumptionAssertion &&
|
|
232
|
+
// Usually by this point, we've already asserted with better error information,
|
|
233
|
+
// but this is our last line of defense.
|
|
234
|
+
unwrap(debug.assertTagNotConsumed)(tag), tag.revision = ++$REVISION, scheduleRevalidate();
|
|
345
235
|
}
|
|
346
236
|
}
|
|
347
|
-
const DIRTY_TAG = MonomorphicTagImpl.dirtyTag
|
|
348
|
-
|
|
237
|
+
const DIRTY_TAG = MonomorphicTagImpl.dirtyTag,
|
|
238
|
+
UPDATE_TAG = MonomorphicTagImpl.updateTag;
|
|
349
239
|
|
|
350
240
|
//////////
|
|
351
|
-
|
|
352
241
|
function createTag() {
|
|
353
|
-
return new MonomorphicTagImpl(
|
|
242
|
+
return new MonomorphicTagImpl(0);
|
|
354
243
|
}
|
|
355
244
|
function createUpdatableTag() {
|
|
356
245
|
return new MonomorphicTagImpl(UPDATABLE_TAG_ID);
|
|
357
246
|
}
|
|
358
247
|
|
|
359
248
|
//////////
|
|
360
|
-
|
|
361
|
-
const CONSTANT_TAG = new MonomorphicTagImpl(CONSTANT_TAG_ID);
|
|
249
|
+
const CONSTANT_TAG = new MonomorphicTagImpl(3);
|
|
362
250
|
function isConstTag(tag) {
|
|
363
251
|
return tag === CONSTANT_TAG;
|
|
364
252
|
}
|
|
365
253
|
|
|
366
254
|
//////////
|
|
367
|
-
|
|
368
|
-
const VOLATILE_TAG_ID = 100;
|
|
369
255
|
class VolatileTag {
|
|
370
|
-
[TYPE] =
|
|
256
|
+
[TYPE] = 100;
|
|
371
257
|
[COMPUTE]() {
|
|
372
|
-
return
|
|
258
|
+
return NaN;
|
|
373
259
|
}
|
|
374
260
|
}
|
|
375
261
|
const VOLATILE_TAG = new VolatileTag();
|
|
376
262
|
|
|
377
263
|
//////////
|
|
378
|
-
|
|
379
|
-
const CURRENT_TAG_ID = 101;
|
|
380
264
|
class CurrentTag {
|
|
381
|
-
[TYPE] =
|
|
265
|
+
[TYPE] = 101;
|
|
382
266
|
[COMPUTE]() {
|
|
383
267
|
return $REVISION;
|
|
384
268
|
}
|
|
385
269
|
}
|
|
386
|
-
const CURRENT_TAG = new CurrentTag()
|
|
270
|
+
const CURRENT_TAG = new CurrentTag(),
|
|
271
|
+
combine = MonomorphicTagImpl.combine;
|
|
387
272
|
|
|
388
273
|
//////////
|
|
389
|
-
|
|
390
|
-
const combine = MonomorphicTagImpl.combine;
|
|
391
|
-
|
|
392
274
|
// Warm
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
valueForTag(tag1);
|
|
398
|
-
DIRTY_TAG(tag1);
|
|
399
|
-
valueForTag(tag1);
|
|
400
|
-
UPDATE_TAG(tag1, combine([tag2, tag3]));
|
|
401
|
-
valueForTag(tag1);
|
|
402
|
-
DIRTY_TAG(tag2);
|
|
403
|
-
valueForTag(tag1);
|
|
404
|
-
DIRTY_TAG(tag3);
|
|
405
|
-
valueForTag(tag1);
|
|
406
|
-
UPDATE_TAG(tag1, tag3);
|
|
407
|
-
valueForTag(tag1);
|
|
408
|
-
DIRTY_TAG(tag3);
|
|
409
|
-
valueForTag(tag1);
|
|
410
|
-
function isObjectLike(u) {
|
|
411
|
-
return typeof u === 'object' && u !== null || typeof u === 'function';
|
|
412
|
-
}
|
|
275
|
+
let tag1 = createUpdatableTag(),
|
|
276
|
+
tag2 = createUpdatableTag(),
|
|
277
|
+
tag3 = createUpdatableTag();
|
|
278
|
+
valueForTag(tag1), DIRTY_TAG(tag1), valueForTag(tag1), UPDATE_TAG(tag1, combine([tag2, tag3])), valueForTag(tag1), DIRTY_TAG(tag2), valueForTag(tag1), DIRTY_TAG(tag3), valueForTag(tag1), UPDATE_TAG(tag1, tag3), valueForTag(tag1), DIRTY_TAG(tag3), valueForTag(tag1);
|
|
413
279
|
|
|
414
280
|
///////////
|
|
415
|
-
|
|
416
281
|
const TRACKED_TAGS = new WeakMap();
|
|
417
282
|
function dirtyTagFor(obj, key, meta) {
|
|
418
|
-
if (isDevelopingApp() &&
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
let tags = meta === undefined ? TRACKED_TAGS.get(obj) : meta;
|
|
422
|
-
|
|
283
|
+
if (isDevelopingApp() && ("object" != typeof (u = obj) || null === u) && "function" != typeof u) throw new Error("BUG: Can't update a tag for a primitive");
|
|
284
|
+
var u;
|
|
285
|
+
let tags = void 0 === meta ? TRACKED_TAGS.get(obj) : meta;
|
|
423
286
|
// No tags have been setup for this object yet, return
|
|
424
|
-
if (
|
|
425
|
-
|
|
287
|
+
if (void 0 === tags) return;
|
|
426
288
|
// Dirty the tag for the specific property if it exists
|
|
427
289
|
let propertyTag = tags.get(key);
|
|
428
|
-
|
|
429
|
-
if (isDevelopingApp()) {
|
|
430
|
-
unwrap(debug.assertTagNotConsumed)(propertyTag, obj, key);
|
|
431
|
-
}
|
|
432
|
-
DIRTY_TAG(propertyTag, true);
|
|
433
|
-
}
|
|
290
|
+
void 0 !== propertyTag && (isDevelopingApp() && unwrap(debug.assertTagNotConsumed)(propertyTag, obj, key), DIRTY_TAG(propertyTag, !0));
|
|
434
291
|
}
|
|
435
292
|
function tagMetaFor(obj) {
|
|
436
293
|
let tags = TRACKED_TAGS.get(obj);
|
|
437
|
-
|
|
438
|
-
tags = new Map();
|
|
439
|
-
TRACKED_TAGS.set(obj, tags);
|
|
440
|
-
}
|
|
441
|
-
return tags;
|
|
294
|
+
return void 0 === tags && (tags = new Map(), TRACKED_TAGS.set(obj, tags)), tags;
|
|
442
295
|
}
|
|
443
296
|
function tagFor(obj, key, meta) {
|
|
444
|
-
let tags =
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
tag = createUpdatableTag();
|
|
448
|
-
tags.set(key, tag);
|
|
449
|
-
}
|
|
450
|
-
return tag;
|
|
297
|
+
let tags = void 0 === meta ? tagMetaFor(obj) : meta,
|
|
298
|
+
tag = tags.get(key);
|
|
299
|
+
return void 0 === tag && (tag = createUpdatableTag(), tags.set(key, tag)), tag;
|
|
451
300
|
}
|
|
452
301
|
|
|
453
302
|
/**
|
|
@@ -457,24 +306,13 @@ class Tracker {
|
|
|
457
306
|
tags = new Set();
|
|
458
307
|
last = null;
|
|
459
308
|
add(tag) {
|
|
460
|
-
|
|
461
|
-
this.tags.add(tag);
|
|
462
|
-
if (isDevelopingApp()) {
|
|
463
|
-
unwrap(debug.markTagAsConsumed)(tag);
|
|
464
|
-
}
|
|
465
|
-
this.last = tag;
|
|
309
|
+
tag !== CONSTANT_TAG && (this.tags.add(tag), isDevelopingApp() && unwrap(debug.markTagAsConsumed)(tag), this.last = tag);
|
|
466
310
|
}
|
|
467
311
|
combine() {
|
|
468
312
|
let {
|
|
469
|
-
tags
|
|
313
|
+
tags: tags
|
|
470
314
|
} = this;
|
|
471
|
-
|
|
472
|
-
return CONSTANT_TAG;
|
|
473
|
-
} else if (tags.size === 1) {
|
|
474
|
-
return this.last;
|
|
475
|
-
} else {
|
|
476
|
-
return combine(Array.from(this.tags));
|
|
477
|
-
}
|
|
315
|
+
return 0 === tags.size ? CONSTANT_TAG : 1 === tags.size ? this.last : combine(Array.from(this.tags));
|
|
478
316
|
}
|
|
479
317
|
}
|
|
480
318
|
|
|
@@ -494,125 +332,88 @@ class Tracker {
|
|
|
494
332
|
let CURRENT_TRACKER = null;
|
|
495
333
|
const OPEN_TRACK_FRAMES = [];
|
|
496
334
|
function beginTrackFrame(debuggingContext) {
|
|
497
|
-
OPEN_TRACK_FRAMES.push(CURRENT_TRACKER);
|
|
498
|
-
CURRENT_TRACKER = new Tracker();
|
|
499
|
-
if (isDevelopingApp()) {
|
|
500
|
-
unwrap(debug.beginTrackingTransaction)(debuggingContext);
|
|
501
|
-
}
|
|
335
|
+
OPEN_TRACK_FRAMES.push(CURRENT_TRACKER), CURRENT_TRACKER = new Tracker(), isDevelopingApp() && unwrap(debug.beginTrackingTransaction)(debuggingContext);
|
|
502
336
|
}
|
|
503
337
|
function endTrackFrame() {
|
|
504
338
|
let current = CURRENT_TRACKER;
|
|
505
339
|
if (isDevelopingApp()) {
|
|
506
|
-
if (OPEN_TRACK_FRAMES.length
|
|
507
|
-
throw new Error('attempted to close a tracking frame, but one was not open');
|
|
508
|
-
}
|
|
340
|
+
if (0 === OPEN_TRACK_FRAMES.length) throw new Error("attempted to close a tracking frame, but one was not open");
|
|
509
341
|
unwrap(debug.endTrackingTransaction)();
|
|
510
342
|
}
|
|
511
|
-
CURRENT_TRACKER = OPEN_TRACK_FRAMES.pop() || null;
|
|
512
|
-
return unwrap(current).combine();
|
|
343
|
+
return CURRENT_TRACKER = OPEN_TRACK_FRAMES.pop() || null, unwrap(current).combine();
|
|
513
344
|
}
|
|
514
345
|
function beginUntrackFrame() {
|
|
515
|
-
OPEN_TRACK_FRAMES.push(CURRENT_TRACKER);
|
|
516
|
-
CURRENT_TRACKER = null;
|
|
346
|
+
OPEN_TRACK_FRAMES.push(CURRENT_TRACKER), CURRENT_TRACKER = null;
|
|
517
347
|
}
|
|
518
348
|
function endUntrackFrame() {
|
|
519
|
-
if (isDevelopingApp() && OPEN_TRACK_FRAMES.length
|
|
520
|
-
throw new Error('attempted to close a tracking frame, but one was not open');
|
|
521
|
-
}
|
|
349
|
+
if (isDevelopingApp() && 0 === OPEN_TRACK_FRAMES.length) throw new Error("attempted to close a tracking frame, but one was not open");
|
|
522
350
|
CURRENT_TRACKER = OPEN_TRACK_FRAMES.pop() || null;
|
|
523
351
|
}
|
|
524
352
|
|
|
525
353
|
// This function is only for handling errors and resetting to a valid state
|
|
526
354
|
function resetTracking() {
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
}
|
|
530
|
-
CURRENT_TRACKER = null;
|
|
531
|
-
if (isDevelopingApp()) {
|
|
532
|
-
return unwrap(debug.resetTrackingTransaction)();
|
|
533
|
-
}
|
|
355
|
+
for (; OPEN_TRACK_FRAMES.length > 0;) OPEN_TRACK_FRAMES.pop();
|
|
356
|
+
if (CURRENT_TRACKER = null, isDevelopingApp()) return unwrap(debug.resetTrackingTransaction)();
|
|
534
357
|
}
|
|
535
358
|
function isTracking() {
|
|
536
|
-
return
|
|
359
|
+
return null !== CURRENT_TRACKER;
|
|
537
360
|
}
|
|
538
361
|
function consumeTag(tag) {
|
|
539
|
-
|
|
540
|
-
CURRENT_TRACKER.add(tag);
|
|
541
|
-
}
|
|
362
|
+
null !== CURRENT_TRACKER && CURRENT_TRACKER.add(tag);
|
|
542
363
|
}
|
|
543
364
|
|
|
544
365
|
// public interface
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
const DEBUG_LABEL = Symbol('DEBUG_LABEL');
|
|
366
|
+
const FN = Symbol("FN"),
|
|
367
|
+
LAST_VALUE = Symbol("LAST_VALUE"),
|
|
368
|
+
TAG = Symbol("TAG"),
|
|
369
|
+
SNAPSHOT = Symbol("SNAPSHOT"),
|
|
370
|
+
DEBUG_LABEL = Symbol("DEBUG_LABEL");
|
|
551
371
|
function createCache(fn, debuggingLabel) {
|
|
552
|
-
if (isDevelopingApp() &&
|
|
553
|
-
throw new Error(`createCache() must be passed a function as its first parameter. Called with: ${String(fn)}`);
|
|
554
|
-
}
|
|
372
|
+
if (isDevelopingApp() && "function" != typeof fn) throw new Error(`createCache() must be passed a function as its first parameter. Called with: ${String(fn)}`);
|
|
555
373
|
let cache = {
|
|
556
374
|
[FN]: fn,
|
|
557
|
-
[LAST_VALUE]:
|
|
558
|
-
[TAG]:
|
|
375
|
+
[LAST_VALUE]: void 0,
|
|
376
|
+
[TAG]: void 0,
|
|
559
377
|
[SNAPSHOT]: -1
|
|
560
378
|
};
|
|
561
|
-
|
|
562
|
-
cache[DEBUG_LABEL] = debuggingLabel;
|
|
563
|
-
}
|
|
564
|
-
return cache;
|
|
379
|
+
return isDevelopingApp() && (cache[DEBUG_LABEL] = debuggingLabel), cache;
|
|
565
380
|
}
|
|
566
381
|
function getValue(cache) {
|
|
567
|
-
assertCache(cache,
|
|
568
|
-
let fn = cache[FN]
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
if (
|
|
382
|
+
assertCache(cache, "getValue");
|
|
383
|
+
let fn = cache[FN],
|
|
384
|
+
tag = cache[TAG],
|
|
385
|
+
snapshot = cache[SNAPSHOT];
|
|
386
|
+
if (void 0 !== tag && validateTag(tag, snapshot)) consumeTag(tag);else {
|
|
572
387
|
beginTrackFrame();
|
|
573
388
|
try {
|
|
574
389
|
cache[LAST_VALUE] = fn();
|
|
575
390
|
} finally {
|
|
576
|
-
tag = endTrackFrame();
|
|
577
|
-
cache[TAG] = tag;
|
|
578
|
-
cache[SNAPSHOT] = valueForTag(tag);
|
|
579
|
-
consumeTag(tag);
|
|
391
|
+
tag = endTrackFrame(), cache[TAG] = tag, cache[SNAPSHOT] = valueForTag(tag), consumeTag(tag);
|
|
580
392
|
}
|
|
581
|
-
} else {
|
|
582
|
-
consumeTag(tag);
|
|
583
393
|
}
|
|
584
394
|
return cache[LAST_VALUE];
|
|
585
395
|
}
|
|
586
396
|
function isConst(cache) {
|
|
587
|
-
assertCache(cache,
|
|
397
|
+
assertCache(cache, "isConst");
|
|
588
398
|
let tag = cache[TAG];
|
|
589
|
-
|
|
590
|
-
return
|
|
591
|
-
}
|
|
592
|
-
function assertCache(value, fnName) {
|
|
593
|
-
if (isDevelopingApp() && !(typeof value === 'object' && value !== null && FN in value)) {
|
|
594
|
-
throw new Error(`${fnName}() can only be used on an instance of a cache created with createCache(). Called with: ${String(value)}`);
|
|
399
|
+
// replace this with `expect` when we can
|
|
400
|
+
return function (tag, cache) {
|
|
401
|
+
if (isDevelopingApp() && void 0 === tag) throw new Error(`isConst() can only be used on a cache once getValue() has been called at least once. Called with cache function:\n\n${String(cache[FN])}`);
|
|
595
402
|
}
|
|
403
|
+
//////////
|
|
404
|
+
// Legacy tracking APIs
|
|
405
|
+
// track() shouldn't be necessary at all in the VM once the autotracking
|
|
406
|
+
// refactors are merged, and we should generally be moving away from it. It may
|
|
407
|
+
// be necessary in Ember for a while longer, but I think we'll be able to drop
|
|
408
|
+
// it in favor of cache sooner rather than later.
|
|
409
|
+
(tag, cache), isConstTag(tag);
|
|
596
410
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
function assertTag(tag, cache) {
|
|
600
|
-
if (isDevelopingApp() && tag === undefined) {
|
|
601
|
-
throw new Error(`isConst() can only be used on a cache once getValue() has been called at least once. Called with cache function:\n\n${String(cache[FN])}`);
|
|
602
|
-
}
|
|
411
|
+
function assertCache(value, fnName) {
|
|
412
|
+
if (isDevelopingApp() && ("object" != typeof value || null === value || !(FN in value))) throw new Error(`${fnName}() can only be used on an instance of a cache created with createCache(). Called with: ${String(value)}`);
|
|
603
413
|
}
|
|
604
|
-
|
|
605
|
-
//////////
|
|
606
|
-
|
|
607
|
-
// Legacy tracking APIs
|
|
608
|
-
|
|
609
|
-
// track() shouldn't be necessary at all in the VM once the autotracking
|
|
610
|
-
// refactors are merged, and we should generally be moving away from it. It may
|
|
611
|
-
// be necessary in Ember for a while longer, but I think we'll be able to drop
|
|
612
|
-
// it in favor of cache sooner rather than later.
|
|
613
414
|
function track(block, debugLabel) {
|
|
614
|
-
beginTrackFrame(debugLabel);
|
|
615
415
|
let tag;
|
|
416
|
+
beginTrackFrame(debugLabel);
|
|
616
417
|
try {
|
|
617
418
|
block();
|
|
618
419
|
} finally {
|
|
@@ -634,35 +435,28 @@ function untrack(callback) {
|
|
|
634
435
|
}
|
|
635
436
|
}
|
|
636
437
|
function trackedData(key, initializer) {
|
|
637
|
-
let values = new WeakMap()
|
|
638
|
-
|
|
639
|
-
function getter(self) {
|
|
640
|
-
consumeTag(tagFor(self, key));
|
|
641
|
-
let value;
|
|
642
|
-
|
|
643
|
-
// If the field has never been initialized, we should initialize it
|
|
644
|
-
if (hasInitializer && !values.has(self)) {
|
|
645
|
-
value = initializer.call(self);
|
|
646
|
-
values.set(self, value);
|
|
647
|
-
} else {
|
|
648
|
-
value = values.get(self);
|
|
649
|
-
}
|
|
650
|
-
return value;
|
|
651
|
-
}
|
|
652
|
-
function setter(self, value) {
|
|
653
|
-
dirtyTagFor(self, key);
|
|
654
|
-
values.set(self, value);
|
|
655
|
-
}
|
|
438
|
+
let values = new WeakMap(),
|
|
439
|
+
hasInitializer = "function" == typeof initializer;
|
|
656
440
|
return {
|
|
657
|
-
getter
|
|
658
|
-
|
|
441
|
+
getter: function (self) {
|
|
442
|
+
let value;
|
|
443
|
+
// If the field has never been initialized, we should initialize it
|
|
444
|
+
return consumeTag(tagFor(self, key)), hasInitializer && !values.has(self) ? (value = initializer.call(self), values.set(self, value)) : value = values.get(self), value;
|
|
445
|
+
},
|
|
446
|
+
setter: function (self, value) {
|
|
447
|
+
dirtyTagFor(self, key), values.set(self, value);
|
|
448
|
+
}
|
|
659
449
|
};
|
|
660
450
|
}
|
|
661
|
-
const GLIMMER_VALIDATOR_REGISTRATION = Symbol(
|
|
662
|
-
|
|
663
|
-
if (
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
451
|
+
const GLIMMER_VALIDATOR_REGISTRATION = Symbol("GLIMMER_VALIDATOR_REGISTRATION"),
|
|
452
|
+
globalObj = function () {
|
|
453
|
+
if ("undefined" != typeof globalThis) return globalThis;
|
|
454
|
+
if ("undefined" != typeof self) return self;
|
|
455
|
+
if ("undefined" != typeof window) return window;
|
|
456
|
+
if ("undefined" != typeof global) return global;
|
|
457
|
+
throw new Error("unable to locate global object");
|
|
458
|
+
}();
|
|
459
|
+
if (!0 === globalObj[GLIMMER_VALIDATOR_REGISTRATION]) throw new Error("The `@glimmer/validator` library has been included twice in this application. It could be different versions of the package, or the same version included twice by mistake. `@glimmer/validator` depends on having a single copy of the package in use at any time in an application, even if they are the same version. You must dedupe your build to remove the duplicate packages in order to prevent this error.");
|
|
460
|
+
globalObj[GLIMMER_VALIDATOR_REGISTRATION] = !0;
|
|
667
461
|
|
|
668
462
|
export { ALLOW_CYCLES, COMPUTE, CONSTANT, CONSTANT_TAG, CURRENT_TAG, CurrentTag, INITIAL, VOLATILE, VOLATILE_TAG, VolatileTag, beginTrackFrame, beginUntrackFrame, bump, combine, consumeTag, createCache, createTag, createUpdatableTag, debug, DIRTY_TAG as dirtyTag, dirtyTagFor, endTrackFrame, endUntrackFrame, getValue, isConst, isConstTag, isTracking, resetTracking, tagFor, tagMetaFor, track, trackedData, untrack, UPDATE_TAG as updateTag, validateTag, valueForTag };
|