@microsoft/fast-element 2.0.0-beta.2 → 2.0.0-beta.5

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.
Files changed (54) hide show
  1. package/CHANGELOG.json +147 -0
  2. package/CHANGELOG.md +42 -1
  3. package/dist/dts/components/fast-definitions.d.ts +9 -8
  4. package/dist/dts/components/fast-element.d.ts +12 -24
  5. package/dist/dts/context.d.ts +1 -1
  6. package/dist/dts/di/di.d.ts +858 -0
  7. package/dist/dts/hooks.d.ts +2 -2
  8. package/dist/dts/interfaces.d.ts +40 -7
  9. package/dist/dts/observation/observable.d.ts +19 -13
  10. package/dist/dts/styles/element-styles.d.ts +6 -0
  11. package/dist/dts/templating/binding-signal.d.ts +10 -27
  12. package/dist/dts/templating/binding-two-way.d.ts +16 -41
  13. package/dist/dts/templating/binding.d.ts +79 -118
  14. package/dist/dts/templating/html-directive.d.ts +31 -3
  15. package/dist/dts/templating/render.d.ts +277 -0
  16. package/dist/dts/templating/repeat.d.ts +12 -16
  17. package/dist/dts/templating/template.d.ts +3 -3
  18. package/dist/dts/templating/when.d.ts +3 -3
  19. package/dist/dts/testing/exports.d.ts +2 -0
  20. package/dist/dts/testing/fixture.d.ts +90 -0
  21. package/dist/dts/testing/timeout.d.ts +7 -0
  22. package/dist/esm/components/fast-definitions.js +25 -27
  23. package/dist/esm/components/fast-element.js +20 -11
  24. package/dist/esm/context.js +5 -1
  25. package/dist/esm/debug.js +36 -4
  26. package/dist/esm/di/di.js +1351 -0
  27. package/dist/esm/observation/arrays.js +303 -2
  28. package/dist/esm/observation/observable.js +11 -6
  29. package/dist/esm/platform.js +1 -1
  30. package/dist/esm/styles/element-styles.js +14 -0
  31. package/dist/esm/templating/binding-signal.js +56 -61
  32. package/dist/esm/templating/binding-two-way.js +56 -34
  33. package/dist/esm/templating/binding.js +137 -156
  34. package/dist/esm/templating/compiler.js +30 -7
  35. package/dist/esm/templating/html-directive.js +16 -2
  36. package/dist/esm/templating/render.js +392 -0
  37. package/dist/esm/templating/repeat.js +57 -40
  38. package/dist/esm/templating/template.js +8 -5
  39. package/dist/esm/templating/view.js +3 -1
  40. package/dist/esm/templating/when.js +5 -4
  41. package/dist/esm/testing/exports.js +2 -0
  42. package/dist/esm/testing/fixture.js +88 -0
  43. package/dist/esm/testing/timeout.js +24 -0
  44. package/dist/fast-element.api.json +2828 -2758
  45. package/dist/fast-element.d.ts +218 -230
  46. package/dist/fast-element.debug.js +656 -257
  47. package/dist/fast-element.debug.min.js +1 -1
  48. package/dist/fast-element.js +620 -253
  49. package/dist/fast-element.min.js +1 -1
  50. package/dist/fast-element.untrimmed.d.ts +226 -235
  51. package/docs/api-report.md +88 -91
  52. package/package.json +15 -6
  53. package/dist/dts/observation/splice-strategies.d.ts +0 -13
  54. package/dist/esm/observation/splice-strategies.js +0 -400
@@ -1,400 +0,0 @@
1
- import { emptyArray } from "../platform.js";
2
- import { Splice, SpliceStrategy, SpliceStrategySupport, } from "./arrays.js";
3
- // Note: This function is *based* on the computation of the Levenshtein
4
- // "edit" distance. The one change is that "updates" are treated as two
5
- // edits - not one. With Array splices, an update is really a delete
6
- // followed by an add. By retaining this, we optimize for "keeping" the
7
- // maximum array items in the original array. For example:
8
- //
9
- // 'xxxx123' to '123yyyy'
10
- //
11
- // With 1-edit updates, the shortest path would be just to update all seven
12
- // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
13
- // leaves the substring '123' intact.
14
- function calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd) {
15
- // "Deletion" columns
16
- const rowCount = oldEnd - oldStart + 1;
17
- const columnCount = currentEnd - currentStart + 1;
18
- const distances = new Array(rowCount);
19
- let north;
20
- let west;
21
- // "Addition" rows. Initialize null column.
22
- for (let i = 0; i < rowCount; ++i) {
23
- distances[i] = new Array(columnCount);
24
- distances[i][0] = i;
25
- }
26
- // Initialize null row
27
- for (let j = 0; j < columnCount; ++j) {
28
- distances[0][j] = j;
29
- }
30
- for (let i = 1; i < rowCount; ++i) {
31
- for (let j = 1; j < columnCount; ++j) {
32
- if (current[currentStart + j - 1] === old[oldStart + i - 1]) {
33
- distances[i][j] = distances[i - 1][j - 1];
34
- }
35
- else {
36
- north = distances[i - 1][j] + 1;
37
- west = distances[i][j - 1] + 1;
38
- distances[i][j] = north < west ? north : west;
39
- }
40
- }
41
- }
42
- return distances;
43
- }
44
- // This starts at the final weight, and walks "backward" by finding
45
- // the minimum previous weight recursively until the origin of the weight
46
- // matrix.
47
- function spliceOperationsFromEditDistances(distances) {
48
- let i = distances.length - 1;
49
- let j = distances[0].length - 1;
50
- let current = distances[i][j];
51
- const edits = [];
52
- while (i > 0 || j > 0) {
53
- if (i === 0) {
54
- edits.push(2 /* Edit.add */);
55
- j--;
56
- continue;
57
- }
58
- if (j === 0) {
59
- edits.push(3 /* Edit.delete */);
60
- i--;
61
- continue;
62
- }
63
- const northWest = distances[i - 1][j - 1];
64
- const west = distances[i - 1][j];
65
- const north = distances[i][j - 1];
66
- let min;
67
- if (west < north) {
68
- min = west < northWest ? west : northWest;
69
- }
70
- else {
71
- min = north < northWest ? north : northWest;
72
- }
73
- if (min === northWest) {
74
- if (northWest === current) {
75
- edits.push(0 /* Edit.leave */);
76
- }
77
- else {
78
- edits.push(1 /* Edit.update */);
79
- current = northWest;
80
- }
81
- i--;
82
- j--;
83
- }
84
- else if (min === west) {
85
- edits.push(3 /* Edit.delete */);
86
- i--;
87
- current = west;
88
- }
89
- else {
90
- edits.push(2 /* Edit.add */);
91
- j--;
92
- current = north;
93
- }
94
- }
95
- return edits.reverse();
96
- }
97
- function sharedPrefix(current, old, searchLength) {
98
- for (let i = 0; i < searchLength; ++i) {
99
- if (current[i] !== old[i]) {
100
- return i;
101
- }
102
- }
103
- return searchLength;
104
- }
105
- function sharedSuffix(current, old, searchLength) {
106
- let index1 = current.length;
107
- let index2 = old.length;
108
- let count = 0;
109
- while (count < searchLength && current[--index1] === old[--index2]) {
110
- count++;
111
- }
112
- return count;
113
- }
114
- function intersect(start1, end1, start2, end2) {
115
- // Disjoint
116
- if (end1 < start2 || end2 < start1) {
117
- return -1;
118
- }
119
- // Adjacent
120
- if (end1 === start2 || end2 === start1) {
121
- return 0;
122
- }
123
- // Non-zero intersect, span1 first
124
- if (start1 < start2) {
125
- if (end1 < end2) {
126
- return end1 - start2; // Overlap
127
- }
128
- return end2 - start2; // Contained
129
- }
130
- // Non-zero intersect, span2 first
131
- if (end2 < end1) {
132
- return end2 - start1; // Overlap
133
- }
134
- return end1 - start1; // Contained
135
- }
136
- /**
137
- * @remarks
138
- * Lacking individual splice mutation information, the minimal set of
139
- * splices can be synthesized given the previous state and final state of an
140
- * array. The basic approach is to calculate the edit distance matrix and
141
- * choose the shortest path through it.
142
- *
143
- * Complexity: O(l * p)
144
- * l: The length of the current array
145
- * p: The length of the old array
146
- */
147
- function calc(current, currentStart, currentEnd, old, oldStart, oldEnd) {
148
- let prefixCount = 0;
149
- let suffixCount = 0;
150
- const minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
151
- if (currentStart === 0 && oldStart === 0) {
152
- prefixCount = sharedPrefix(current, old, minLength);
153
- }
154
- if (currentEnd === current.length && oldEnd === old.length) {
155
- suffixCount = sharedSuffix(current, old, minLength - prefixCount);
156
- }
157
- currentStart += prefixCount;
158
- oldStart += prefixCount;
159
- currentEnd -= suffixCount;
160
- oldEnd -= suffixCount;
161
- if (currentEnd - currentStart === 0 && oldEnd - oldStart === 0) {
162
- return emptyArray;
163
- }
164
- if (currentStart === currentEnd) {
165
- const splice = new Splice(currentStart, [], 0);
166
- while (oldStart < oldEnd) {
167
- splice.removed.push(old[oldStart++]);
168
- }
169
- return [splice];
170
- }
171
- else if (oldStart === oldEnd) {
172
- return [new Splice(currentStart, [], currentEnd - currentStart)];
173
- }
174
- const ops = spliceOperationsFromEditDistances(calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
175
- const splices = [];
176
- let splice = void 0;
177
- let index = currentStart;
178
- let oldIndex = oldStart;
179
- for (let i = 0; i < ops.length; ++i) {
180
- switch (ops[i]) {
181
- case 0 /* Edit.leave */:
182
- if (splice !== void 0) {
183
- splices.push(splice);
184
- splice = void 0;
185
- }
186
- index++;
187
- oldIndex++;
188
- break;
189
- case 1 /* Edit.update */:
190
- if (splice === void 0) {
191
- splice = new Splice(index, [], 0);
192
- }
193
- splice.addedCount++;
194
- index++;
195
- splice.removed.push(old[oldIndex]);
196
- oldIndex++;
197
- break;
198
- case 2 /* Edit.add */:
199
- if (splice === void 0) {
200
- splice = new Splice(index, [], 0);
201
- }
202
- splice.addedCount++;
203
- index++;
204
- break;
205
- case 3 /* Edit.delete */:
206
- if (splice === void 0) {
207
- splice = new Splice(index, [], 0);
208
- }
209
- splice.removed.push(old[oldIndex]);
210
- oldIndex++;
211
- break;
212
- // no default
213
- }
214
- }
215
- if (splice !== void 0) {
216
- splices.push(splice);
217
- }
218
- return splices;
219
- }
220
- function merge(splice, splices) {
221
- let inserted = false;
222
- let insertionOffset = 0;
223
- for (let i = 0; i < splices.length; i++) {
224
- const current = splices[i];
225
- current.index += insertionOffset;
226
- if (inserted) {
227
- continue;
228
- }
229
- const intersectCount = intersect(splice.index, splice.index + splice.removed.length, current.index, current.index + current.addedCount);
230
- if (intersectCount >= 0) {
231
- // Merge the two splices
232
- splices.splice(i, 1);
233
- i--;
234
- insertionOffset -= current.addedCount - current.removed.length;
235
- splice.addedCount += current.addedCount - intersectCount;
236
- const deleteCount = splice.removed.length + current.removed.length - intersectCount;
237
- if (!splice.addedCount && !deleteCount) {
238
- // merged splice is a noop. discard.
239
- inserted = true;
240
- }
241
- else {
242
- let currentRemoved = current.removed;
243
- if (splice.index < current.index) {
244
- // some prefix of splice.removed is prepended to current.removed.
245
- const prepend = splice.removed.slice(0, current.index - splice.index);
246
- prepend.push(...currentRemoved);
247
- currentRemoved = prepend;
248
- }
249
- if (splice.index + splice.removed.length >
250
- current.index + current.addedCount) {
251
- // some suffix of splice.removed is appended to current.removed.
252
- const append = splice.removed.slice(current.index + current.addedCount - splice.index);
253
- currentRemoved.push(...append);
254
- }
255
- splice.removed = currentRemoved;
256
- if (current.index < splice.index) {
257
- splice.index = current.index;
258
- }
259
- }
260
- }
261
- else if (splice.index < current.index) {
262
- // Insert splice here.
263
- inserted = true;
264
- splices.splice(i, 0, splice);
265
- i++;
266
- const offset = splice.addedCount - splice.removed.length;
267
- current.index += offset;
268
- insertionOffset += offset;
269
- }
270
- }
271
- if (!inserted) {
272
- splices.push(splice);
273
- }
274
- }
275
- function project(array, changes) {
276
- let splices = [];
277
- const initialSplices = [];
278
- for (let i = 0, ii = changes.length; i < ii; i++) {
279
- merge(changes[i], initialSplices);
280
- }
281
- for (let i = 0, ii = initialSplices.length; i < ii; ++i) {
282
- const splice = initialSplices[i];
283
- if (splice.addedCount === 1 && splice.removed.length === 1) {
284
- if (splice.removed[0] !== array[splice.index]) {
285
- splices.push(splice);
286
- }
287
- continue;
288
- }
289
- splices = splices.concat(calc(array, splice.index, splice.index + splice.addedCount, splice.removed, 0, splice.removed.length));
290
- }
291
- return splices;
292
- }
293
- /**
294
- * A SpliceStrategy that attempts to merge all splices into the minimal set of
295
- * splices needed to represent the change from the old array to the new array.
296
- * @public
297
- */
298
- export const mergeSpliceStrategy = Object.freeze({
299
- support: SpliceStrategySupport.optimized,
300
- normalize(previous, current, changes) {
301
- if (previous === void 0) {
302
- if (changes === void 0) {
303
- return emptyArray;
304
- }
305
- return changes.length > 1 ? project(current, changes) : changes;
306
- }
307
- return calc(current, 0, current.length, previous, 0, previous.length);
308
- },
309
- pop(array, observer, pop, args) {
310
- const notEmpty = array.length > 0;
311
- const result = pop.apply(array, args);
312
- if (notEmpty) {
313
- observer.addSplice(new Splice(array.length, [result], 0));
314
- }
315
- return result;
316
- },
317
- push(array, observer, push, args) {
318
- const result = push.apply(array, args);
319
- observer.addSplice(new Splice(array.length - args.length, [], args.length).adjustTo(array));
320
- return result;
321
- },
322
- reverse(array, observer, reverse, args) {
323
- observer.flush();
324
- const oldArray = array.slice();
325
- const result = reverse.apply(array, args);
326
- observer.reset(oldArray);
327
- return result;
328
- },
329
- shift(array, observer, shift, args) {
330
- const notEmpty = array.length > 0;
331
- const result = shift.apply(array, args);
332
- if (notEmpty) {
333
- observer.addSplice(new Splice(0, [result], 0));
334
- }
335
- return result;
336
- },
337
- sort(array, observer, sort, args) {
338
- observer.flush();
339
- const oldArray = array.slice();
340
- const result = sort.apply(array, args);
341
- observer.reset(oldArray);
342
- return result;
343
- },
344
- splice(array, observer, splice, args) {
345
- const result = splice.apply(array, args);
346
- observer.addSplice(new Splice(+args[0], result, args.length > 2 ? args.length - 2 : 0).adjustTo(array));
347
- return result;
348
- },
349
- unshift(array, observer, unshift, args) {
350
- const result = unshift.apply(array, args);
351
- observer.addSplice(new Splice(0, [], args.length).adjustTo(array));
352
- return result;
353
- },
354
- });
355
- /**
356
- * A splice strategy that doesn't create splices, but instead
357
- * tracks every change as a full array reset.
358
- * @public
359
- */
360
- export const resetSpliceStrategy = Object.freeze({
361
- support: SpliceStrategySupport.reset,
362
- normalize(previous, current, changes) {
363
- return SpliceStrategy.reset;
364
- },
365
- pop(array, observer, pop, args) {
366
- const result = pop.apply(array, args);
367
- observer.reset(array);
368
- return result;
369
- },
370
- push(array, observer, push, args) {
371
- const result = push.apply(array, args);
372
- observer.reset(array);
373
- return result;
374
- },
375
- reverse(array, observer, reverse, args) {
376
- const result = reverse.apply(array, args);
377
- observer.reset(array);
378
- return result;
379
- },
380
- shift(array, observer, shift, args) {
381
- const result = shift.apply(array, args);
382
- observer.reset(array);
383
- return result;
384
- },
385
- sort(array, observer, sort, args) {
386
- const result = sort.apply(array, args);
387
- observer.reset(array);
388
- return result;
389
- },
390
- splice(array, observer, splice, args) {
391
- const result = splice.apply(array, args);
392
- observer.reset(array);
393
- return result;
394
- },
395
- unshift(array, observer, unshift, args) {
396
- const result = unshift.apply(array, args);
397
- observer.reset(array);
398
- return result;
399
- },
400
- });