tutuca 0.9.2 → 0.9.3

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/tutuca.js CHANGED
@@ -1,706 +1,139 @@
1
- // deps/vdom.js
2
- function isHtmlAttribute(propName) {
3
- return propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
4
- }
5
- function getDomProp(node, propName) {
6
- return node[propName];
7
- }
8
- function setDomProp(node, propName, value) {
9
- node[propName] = value;
10
- }
11
- function applyProperties(node, props, previous) {
12
- for (const propName in props) {
13
- const propValue = props[propName];
14
- if (propValue === undefined) {
15
- removeProperty(node, propName, previous);
16
- } else if (isHtmlAttribute(propName)) {
17
- node.setAttribute(propName, propValue);
18
- } else {
19
- if (typeof propValue === "object" && propValue !== null) {
20
- patchObject(node, previous, propName, propValue);
21
- } else {
22
- setDomProp(node, propName, propValue);
23
- }
24
- }
25
- }
26
- }
27
- function removeProperty(node, propName, previous) {
28
- const previousValue = previous[propName];
29
- if (isHtmlAttribute(propName)) {
30
- node.removeAttribute(propName);
31
- } else if (typeof previousValue === "string") {
32
- setDomProp(node, propName, "");
33
- const attrName = propName === "className" ? "class" : propName === "htmlFor" ? "for" : propName;
34
- node.removeAttribute(attrName);
35
- } else {
36
- setDomProp(node, propName, null);
37
- }
38
- }
39
- function patchObject(node, previous, propName, propValue) {
40
- const previousValue = previous?.[propName];
41
- if (previousValue && typeof previousValue === "object" && Object.getPrototypeOf(previousValue) !== Object.getPrototypeOf(propValue)) {
42
- setDomProp(node, propName, propValue);
43
- return;
44
- }
45
- let current = getDomProp(node, propName);
46
- if (typeof current !== "object" || current === null) {
47
- setDomProp(node, propName, {});
48
- current = getDomProp(node, propName);
1
+ // src/path.js
2
+ class Step {
3
+ lookup(_v, dval = null) {
4
+ return dval;
49
5
  }
50
- const target = current;
51
- for (const k in propValue) {
52
- target[k] = propValue[k];
6
+ setValue(root, _v) {
7
+ return root;
53
8
  }
9
+ updateBindings(_v, _o) {}
10
+ isFrame = true;
54
11
  }
55
12
 
56
- class Warning {
57
- type;
58
- message;
59
- constructor(type, message) {
60
- this.type = type;
61
- this.message = message;
13
+ class BindStep extends Step {
14
+ constructor(binds) {
15
+ super();
16
+ this.binds = binds;
62
17
  }
63
- }
64
-
65
- class DuplicatedKeysWarning extends Warning {
66
- duplicatedKeys;
67
- parentTag;
68
- parentIndex;
69
- constructor(duplicatedKeys, parentTag, parentIndex) {
70
- const keys = [...duplicatedKeys].join(", ");
71
- super("DuplicatedKeys", `Duplicate keys found: [${keys}] in ${parentTag || "fragment"} at index ${parentIndex}. Nodes with duplicated keys are matched positionally.`);
72
- this.duplicatedKeys = duplicatedKeys;
73
- this.parentTag = parentTag;
74
- this.parentIndex = parentIndex;
18
+ lookup(v, _dval) {
19
+ return v;
75
20
  }
76
- }
77
-
78
- class VBase {
79
- isEqualTo(other) {
80
- return this === other;
21
+ setValue(_root, v) {
22
+ return v;
81
23
  }
82
- toDom(_opts) {
83
- return null;
24
+ withIndex(i) {
25
+ return new BindStep({ ...this.binds, key: i });
84
26
  }
85
- }
86
- function getKey(node) {
87
- return node instanceof VNode ? node.key : undefined;
88
- }
89
- function effectiveKey(node, duplicatedKeys) {
90
- const key = getKey(node);
91
- return key && duplicatedKeys?.has(key) ? undefined : key;
92
- }
93
- function isIterable(obj) {
94
- return obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
95
- }
96
- function addChild(normalizedChildren, child) {
97
- if (child == null) {
98
- return;
27
+ withKey(key) {
28
+ return new BindStep({ ...this.binds, key });
99
29
  }
100
- if (isIterable(child)) {
101
- for (const c of child) {
102
- addChild(normalizedChildren, c);
103
- }
104
- } else if (child instanceof VBase) {
105
- if (child instanceof VFragment) {
106
- normalizedChildren.push(...child.childs);
107
- } else {
108
- normalizedChildren.push(child);
109
- }
110
- } else {
111
- normalizedChildren.push(new VText(child));
30
+ updateBindings(_v, o) {
31
+ Object.assign(o, this.binds);
112
32
  }
33
+ isFrame = false;
113
34
  }
114
35
 
115
- class VText extends VBase {
116
- text;
117
- constructor(text) {
36
+ class FieldStep extends Step {
37
+ constructor(field) {
118
38
  super();
119
- this.text = String(text);
39
+ this.field = field;
120
40
  }
121
- get nodeType() {
122
- return 3;
41
+ lookup(v, dval = null) {
42
+ return v?.get ? v.get(this.field, dval) : dval;
123
43
  }
124
- isEqualTo(other) {
125
- return other instanceof VText && this.text === other.text;
44
+ setValue(root, v) {
45
+ return root.set(this.field, v);
126
46
  }
127
- toDom(opts) {
128
- return opts.document.createTextNode(this.text);
47
+ withIndex(i) {
48
+ return new SeqIndexStep(this.field, i);
49
+ }
50
+ withKey(k) {
51
+ return new SeqKeyStep(this.field, k);
129
52
  }
130
53
  }
131
54
 
132
- class VComment extends VBase {
133
- text;
134
- constructor(text) {
55
+ class FieldSeqStep extends Step {
56
+ constructor(field, key) {
135
57
  super();
136
- this.text = text;
58
+ this.field = field;
59
+ this.key = key;
137
60
  }
138
- get nodeType() {
139
- return 8;
61
+ lookup(v, dval = null) {
62
+ const o = v?.get(this.field, null);
63
+ return o?.get ? o.get(this.key, dval) : dval;
140
64
  }
141
- isEqualTo(other) {
142
- return other instanceof VComment && this.text === other.text;
65
+ setValue(root, v) {
66
+ return root.set(this.field, root.get(this.field).set(this.key, v));
143
67
  }
144
- toDom(opts) {
145
- return opts.document.createComment(this.text);
68
+ updateBindings(_v, o) {
69
+ o.key = this.key;
146
70
  }
147
71
  }
148
72
 
149
- class VFragment extends VBase {
150
- childs;
151
- constructor(childs) {
73
+ class SeqKeyStep extends FieldSeqStep {
74
+ }
75
+
76
+ class SeqIndexStep extends FieldSeqStep {
77
+ }
78
+ var NONE = Symbol("NONE");
79
+
80
+ class SeqAccessStep extends Step {
81
+ constructor(seqField, keyField) {
152
82
  super();
153
- const normalized = [];
154
- addChild(normalized, childs);
155
- this.childs = normalized;
83
+ this.seqField = seqField;
84
+ this.keyField = keyField;
156
85
  }
157
- get nodeType() {
158
- return 11;
86
+ lookup(v, dval = null) {
87
+ const seq = v?.get(this.seqField, NONE);
88
+ const key = v?.get(this.keyField, NONE);
89
+ return key !== NONE && seq?.get ? seq.get(key, dval) : dval;
159
90
  }
160
- isEqualTo(other) {
161
- if (!(other instanceof VFragment) || this.childs.length !== other.childs.length) {
162
- return false;
163
- }
164
- for (let i = 0;i < this.childs.length; i++) {
165
- if (!this.childs[i].isEqualTo(other.childs[i])) {
166
- return false;
167
- }
168
- }
169
- return true;
91
+ setValue(root, v) {
92
+ const seq = root?.get(this.seqField, NONE);
93
+ const key = root?.get(this.keyField, NONE);
94
+ return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
170
95
  }
171
- toDom(opts) {
172
- const fragment = opts.document.createDocumentFragment();
173
- for (const child of this.childs) {
174
- const childNode = child.toDom(opts);
175
- if (childNode) {
176
- fragment.appendChild(childNode);
177
- }
178
- }
179
- return fragment;
96
+ updateBindings(v, o) {
97
+ o.key = v?.get(this.keyField, null);
180
98
  }
181
99
  }
182
100
 
183
- class VNode extends VBase {
184
- tag;
185
- attrs;
186
- childs;
187
- key;
188
- namespace;
189
- attrCount;
190
- constructor(tag, attrs, childs, key, namespace) {
191
- super();
192
- this.tag = tag;
193
- this.attrs = attrs ?? {};
194
- this.childs = childs ?? [];
195
- this.key = key != null ? String(key) : undefined;
196
- this.namespace = typeof namespace === "string" ? namespace : null;
197
- this.attrCount = Object.keys(this.attrs).length;
101
+ class Path {
102
+ constructor(steps = []) {
103
+ this.steps = steps;
198
104
  }
199
- get nodeType() {
200
- return 1;
105
+ concat(steps) {
106
+ return new Path(this.steps.concat(steps));
201
107
  }
202
- isEqualTo(other) {
203
- if (!(other instanceof VNode) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.attrCount !== other.attrCount || this.childs.length !== other.childs.length) {
204
- return false;
205
- }
206
- for (const key in this.attrs) {
207
- if (this.attrs[key] !== other.attrs[key]) {
208
- return false;
108
+ popStep() {
109
+ return new Path(this.steps.slice(0, -1));
110
+ }
111
+ lookup(v, dval = null) {
112
+ let curVal = v;
113
+ for (const step of this.steps) {
114
+ curVal = step.lookup(curVal, NONE);
115
+ if (curVal === NONE) {
116
+ return dval;
209
117
  }
210
118
  }
211
- for (let i = 0;i < this.childs.length; i++) {
212
- if (!this.childs[i].isEqualTo(other.childs[i])) {
213
- return false;
119
+ return curVal;
120
+ }
121
+ setValue(root, v) {
122
+ const intermediates = new Array(this.steps.length);
123
+ let curVal = root;
124
+ for (let i = 0;i < this.steps.length; i++) {
125
+ intermediates[i] = curVal;
126
+ curVal = this.steps[i].lookup(curVal, NONE);
127
+ if (curVal === NONE) {
128
+ return root;
214
129
  }
215
130
  }
216
- return true;
217
- }
218
- toDom(opts) {
219
- const doc = opts.document;
220
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
221
- applyProperties(node, this.attrs, {});
222
- for (const child of this.childs) {
223
- const childNode = child.toDom(opts);
224
- if (childNode) {
225
- node.appendChild(childNode);
226
- }
227
- }
228
- return node;
229
- }
230
- }
231
- function diffProps(a, b) {
232
- let diff = null;
233
- for (const aKey in a) {
234
- if (!Object.hasOwn(b, aKey)) {
235
- diff ??= {};
236
- diff[aKey] = undefined;
237
- continue;
238
- }
239
- const aValue = a[aKey];
240
- const bValue = b[aKey];
241
- if (aValue === bValue) {} else if (typeof aValue === "object" && aValue !== null && typeof bValue === "object" && bValue !== null) {
242
- if (Object.getPrototypeOf(bValue) !== Object.getPrototypeOf(aValue)) {
243
- diff ??= {};
244
- diff[aKey] = bValue;
245
- } else {
246
- const objectDiff = diffProps(aValue, bValue);
247
- if (objectDiff) {
248
- diff ??= {};
249
- diff[aKey] = objectDiff;
250
- }
251
- }
252
- } else {
253
- diff ??= {};
254
- diff[aKey] = bValue;
255
- }
256
- }
257
- for (const bKey in b) {
258
- if (!Object.hasOwn(a, bKey)) {
259
- diff ??= {};
260
- diff[bKey] = b[bKey];
261
- }
262
- }
263
- return diff;
264
- }
265
- function reorder(oldChildren, newChildren) {
266
- const rawNew = keyIndex(newChildren);
267
- if (rawNew.free.length === newChildren.length) {
268
- return {
269
- children: newChildren,
270
- moves: null,
271
- duplicatedKeys: rawNew.duplicatedKeys
272
- };
273
- }
274
- const rawOld = keyIndex(oldChildren);
275
- const duplicatedKeys = rawNew.duplicatedKeys || rawOld.duplicatedKeys ? new Set([...rawNew.duplicatedKeys || [], ...rawOld.duplicatedKeys || []]) : null;
276
- if (rawOld.free.length === oldChildren.length) {
277
- return {
278
- children: newChildren,
279
- moves: null,
280
- duplicatedKeys
281
- };
282
- }
283
- let newKeys;
284
- let newFree;
285
- let oldKeys;
286
- if (duplicatedKeys) {
287
- const updatedNew = keyIndex(newChildren, duplicatedKeys);
288
- newKeys = updatedNew.keys;
289
- newFree = updatedNew.free;
290
- oldKeys = keyIndex(oldChildren, duplicatedKeys).keys;
291
- } else {
292
- newKeys = rawNew.keys;
293
- newFree = rawNew.free;
294
- oldKeys = rawOld.keys;
295
- }
296
- const reordered = [];
297
- let freeIndex = 0;
298
- const freeCount = newFree.length;
299
- let deletedItems = 0;
300
- for (let i = 0;i < oldChildren.length; i++) {
301
- const oldItem = oldChildren[i];
302
- const oldKey = effectiveKey(oldItem, duplicatedKeys);
303
- if (oldKey) {
304
- if (Object.hasOwn(newKeys, oldKey)) {
305
- const itemIndex = newKeys[oldKey];
306
- reordered.push(newChildren[itemIndex]);
307
- } else {
308
- deletedItems++;
309
- reordered.push(null);
310
- }
311
- } else {
312
- if (freeIndex < freeCount) {
313
- const itemIndex = newFree[freeIndex++];
314
- reordered.push(newChildren[itemIndex]);
315
- } else {
316
- deletedItems++;
317
- reordered.push(null);
318
- }
319
- }
320
- }
321
- const lastFreeIndex = freeIndex >= newFree.length ? newChildren.length : newFree[freeIndex];
322
- for (let j = 0;j < newChildren.length; j++) {
323
- const newItem = newChildren[j];
324
- const newKey = effectiveKey(newItem, duplicatedKeys);
325
- if (newKey) {
326
- if (!Object.hasOwn(oldKeys, newKey)) {
327
- reordered.push(newItem);
328
- }
329
- } else if (j >= lastFreeIndex) {
330
- reordered.push(newItem);
331
- }
332
- }
333
- const moves = computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems);
334
- return { children: reordered, moves, duplicatedKeys };
335
- }
336
- function computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems) {
337
- const simulate = reordered.slice();
338
- let simulateIndex = 0;
339
- const removes = [];
340
- const inserts = [];
341
- const wantedKeys = new Array(newChildren.length);
342
- for (let i = 0;i < newChildren.length; i++) {
343
- wantedKeys[i] = effectiveKey(newChildren[i], duplicatedKeys);
344
- }
345
- for (let k = 0;k < newChildren.length; ) {
346
- const wantedKey = wantedKeys[k];
347
- let simulateItem = simulate[simulateIndex];
348
- let simulateKey = effectiveKey(simulateItem, duplicatedKeys);
349
- while (simulateItem === null && simulate.length) {
350
- simulate.splice(simulateIndex, 1);
351
- removes.push({ from: simulateIndex, key: null });
352
- simulateItem = simulate[simulateIndex];
353
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
354
- }
355
- if (simulateItem && simulateKey === wantedKey) {
356
- simulateIndex++;
357
- k++;
358
- continue;
359
- }
360
- if (wantedKey) {
361
- if (simulateKey && newKeys[simulateKey] !== k + 1) {
362
- simulate.splice(simulateIndex, 1);
363
- removes.push({ from: simulateIndex, key: simulateKey });
364
- simulateItem = simulate[simulateIndex];
365
- simulateKey = effectiveKey(simulateItem, duplicatedKeys);
366
- if (simulateItem && simulateKey === wantedKey) {
367
- simulateIndex++;
368
- k++;
369
- continue;
370
- }
371
- }
372
- inserts.push({ key: wantedKey, to: k });
373
- k++;
374
- continue;
375
- }
376
- if (simulateKey) {
377
- simulate.splice(simulateIndex, 1);
378
- removes.push({ from: simulateIndex, key: simulateKey });
379
- continue;
380
- }
381
- k++;
382
- }
383
- while (simulateIndex < simulate.length) {
384
- const simulateItem = simulate[simulateIndex];
385
- simulate.splice(simulateIndex, 1);
386
- removes.push({
387
- from: simulateIndex,
388
- key: effectiveKey(simulateItem, duplicatedKeys)
389
- });
390
- }
391
- if (removes.length === deletedItems && !inserts.length) {
392
- return null;
393
- }
394
- return { removes, inserts };
395
- }
396
- function keyIndex(children, excludeKeys) {
397
- const keys = {};
398
- const free = [];
399
- let duplicatedKeys = null;
400
- for (let i = 0;i < children.length; i++) {
401
- const key = getKey(children[i]);
402
- if (key && !excludeKeys?.has(key)) {
403
- if (key in keys) {
404
- duplicatedKeys ??= new Set;
405
- duplicatedKeys.add(key);
406
- }
407
- keys[key] = i;
408
- } else {
409
- free.push(i);
410
- }
411
- }
412
- return { keys, free, duplicatedKeys };
413
- }
414
- function replaceNode(domNode, vnode, options) {
415
- const parentNode = domNode.parentNode;
416
- const newNode = vnode.toDom(options);
417
- if (parentNode && newNode && newNode !== domNode) {
418
- parentNode.replaceChild(newNode, domNode);
419
- }
420
- return newNode || domNode;
421
- }
422
- function morphNode(domNode, source, target, opts) {
423
- if (source === target || source.isEqualTo(target))
424
- return domNode;
425
- if (source instanceof VText && target instanceof VText || source instanceof VComment && target instanceof VComment) {
426
- domNode.data = target.text;
427
- return domNode;
428
- }
429
- if (source instanceof VNode && target instanceof VNode && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
430
- const propsDiff = diffProps(source.attrs, target.attrs);
431
- if (propsDiff) {
432
- applyProperties(domNode, propsDiff, source.attrs);
433
- }
434
- morphChildren(domNode, source.childs, target.childs, source.tag, opts);
435
- return domNode;
436
- }
437
- if (source instanceof VFragment && target instanceof VFragment) {
438
- morphChildren(domNode, source.childs, target.childs, null, opts);
439
- return domNode;
440
- }
441
- return replaceNode(domNode, target, opts);
442
- }
443
- function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
444
- if (oldChilds.length === 0) {
445
- for (const child of newChilds) {
446
- const node = child.toDom(opts);
447
- if (node)
448
- parentDom.appendChild(node);
449
- }
450
- return;
451
- }
452
- if (newChilds.length === 0) {
453
- while (parentDom.firstChild) {
454
- parentDom.removeChild(parentDom.firstChild);
455
- }
456
- return;
457
- }
458
- const orderedSet = reorder(oldChilds, newChilds);
459
- const reorderedChilds = orderedSet.children;
460
- if (orderedSet.duplicatedKeys && opts.onWarning) {
461
- opts.onWarning(new DuplicatedKeysWarning(orderedSet.duplicatedKeys, parentTag, 0));
462
- }
463
- const domChildren = Array.from(parentDom.childNodes);
464
- const oldLen = oldChilds.length;
465
- const reorderedLen = reorderedChilds.length;
466
- const len = Math.max(oldLen, reorderedLen);
467
- const toRemove = [];
468
- for (let i = 0;i < len; i++) {
469
- const leftNode = oldChilds[i];
470
- const rightNode = reorderedChilds[i];
471
- if (!leftNode && rightNode) {
472
- const newNode = rightNode.toDom(opts);
473
- if (newNode)
474
- parentDom.appendChild(newNode);
475
- } else if (leftNode && rightNode) {
476
- const domChild = domChildren[i];
477
- if (domChild) {
478
- morphNode(domChild, leftNode, rightNode, opts);
479
- }
480
- } else if (leftNode && !rightNode) {
481
- if (!orderedSet.moves && domChildren[i]) {
482
- toRemove.push(domChildren[i]);
483
- }
484
- }
485
- }
486
- for (const node of toRemove) {
487
- if (node.parentNode === parentDom) {
488
- parentDom.removeChild(node);
489
- }
490
- }
491
- if (orderedSet.moves) {
492
- applyMoves(parentDom, orderedSet.moves);
493
- }
494
- }
495
- function applyMoves(domNode, moves) {
496
- const childNodes = domNode.childNodes;
497
- const keyMap = {};
498
- for (const remove of moves.removes) {
499
- const node = childNodes[remove.from];
500
- if (remove.key)
501
- keyMap[remove.key] = node;
502
- domNode.removeChild(node);
503
- }
504
- let length = childNodes.length;
505
- for (let j = 0;j < moves.inserts.length; j++) {
506
- const insert = moves.inserts[j];
507
- const node = keyMap[insert.key];
508
- if (node) {
509
- domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]);
510
- }
511
- }
512
- }
513
- var renderCache = new WeakMap;
514
- function render(vnode, container, options) {
515
- const cached = renderCache.get(container);
516
- const isFragment = vnode instanceof VFragment;
517
- if (cached) {
518
- const wasFragment = cached.vnode instanceof VFragment;
519
- if (wasFragment === isFragment) {
520
- const rootNode = wasFragment ? container : cached.dom;
521
- const newDom = morphNode(rootNode, cached.vnode, vnode, options);
522
- renderCache.set(container, {
523
- vnode,
524
- dom: isFragment ? container : newDom
525
- });
526
- return newDom;
527
- }
528
- renderCache.delete(container);
529
- }
530
- const domNode = vnode.toDom(options);
531
- if (domNode) {
532
- container.innerHTML = "";
533
- container.appendChild(domNode);
534
- renderCache.set(container, {
535
- vnode,
536
- dom: isFragment ? container : domNode
537
- });
538
- }
539
- return domNode;
540
- }
541
- function h(tagName, properties, children) {
542
- const tag = tagName.toUpperCase();
543
- const props = {};
544
- let key;
545
- let namespace;
546
- if (properties) {
547
- for (const propName in properties) {
548
- if (propName === "key") {
549
- key = properties[propName];
550
- } else if (propName === "namespace") {
551
- namespace = properties[propName];
552
- } else if (propName === "class") {
553
- props.className = properties[propName];
554
- } else if (propName === "for") {
555
- props.htmlFor = properties[propName];
556
- } else if (isHtmlAttribute(propName)) {
557
- props[propName] = String(properties[propName]);
558
- } else {
559
- props[propName] = properties[propName];
560
- }
561
- }
562
- }
563
- const normalizedChildren = [];
564
- addChild(normalizedChildren, children);
565
- return new VNode(tag, props, normalizedChildren, key, namespace);
566
- }
567
-
568
- // src/path.js
569
- class Step {
570
- lookup(_v, dval = null) {
571
- return dval;
572
- }
573
- setValue(root, _v) {
574
- return root;
575
- }
576
- updateBindings(_v, _o) {}
577
- isFrame = true;
578
- }
579
-
580
- class BindStep extends Step {
581
- constructor(binds) {
582
- super();
583
- this.binds = binds;
584
- }
585
- lookup(v, _dval) {
586
- return v;
587
- }
588
- setValue(_root, v) {
589
- return v;
590
- }
591
- withIndex(i) {
592
- return new BindStep({ ...this.binds, key: i });
593
- }
594
- withKey(key) {
595
- return new BindStep({ ...this.binds, key });
596
- }
597
- updateBindings(_v, o) {
598
- Object.assign(o, this.binds);
599
- }
600
- isFrame = false;
601
- }
602
-
603
- class FieldStep extends Step {
604
- constructor(field) {
605
- super();
606
- this.field = field;
607
- }
608
- lookup(v, dval = null) {
609
- return v?.get ? v.get(this.field, dval) : dval;
610
- }
611
- setValue(root, v) {
612
- return root.set(this.field, v);
613
- }
614
- withIndex(i) {
615
- return new SeqIndexStep(this.field, i);
616
- }
617
- withKey(k) {
618
- return new SeqKeyStep(this.field, k);
619
- }
620
- }
621
-
622
- class FieldSeqStep extends Step {
623
- constructor(field, key) {
624
- super();
625
- this.field = field;
626
- this.key = key;
627
- }
628
- lookup(v, dval = null) {
629
- const o = v?.get(this.field, null);
630
- return o?.get ? o.get(this.key, dval) : dval;
631
- }
632
- setValue(root, v) {
633
- return root.set(this.field, root.get(this.field).set(this.key, v));
634
- }
635
- updateBindings(_v, o) {
636
- o.key = this.key;
637
- }
638
- }
639
-
640
- class SeqKeyStep extends FieldSeqStep {
641
- }
642
-
643
- class SeqIndexStep extends FieldSeqStep {
644
- }
645
- var NONE = Symbol("NONE");
646
-
647
- class SeqAccessStep extends Step {
648
- constructor(seqField, keyField) {
649
- super();
650
- this.seqField = seqField;
651
- this.keyField = keyField;
652
- }
653
- lookup(v, dval = null) {
654
- const seq = v?.get(this.seqField, NONE);
655
- const key = v?.get(this.keyField, NONE);
656
- return key !== NONE && seq?.get ? seq.get(key, dval) : dval;
657
- }
658
- setValue(root, v) {
659
- const seq = root?.get(this.seqField, NONE);
660
- const key = root?.get(this.keyField, NONE);
661
- return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
662
- }
663
- updateBindings(v, o) {
664
- o.key = v?.get(this.keyField, null);
665
- }
666
- }
667
-
668
- class Path {
669
- constructor(steps = []) {
670
- this.steps = steps;
671
- }
672
- concat(steps) {
673
- return new Path(this.steps.concat(steps));
674
- }
675
- popStep() {
676
- return new Path(this.steps.slice(0, -1));
677
- }
678
- lookup(v, dval = null) {
679
- let curVal = v;
680
- for (const step of this.steps) {
681
- curVal = step.lookup(curVal, NONE);
682
- if (curVal === NONE) {
683
- return dval;
684
- }
685
- }
686
- return curVal;
687
- }
688
- setValue(root, v) {
689
- const intermediates = new Array(this.steps.length);
690
- let curVal = root;
691
- for (let i = 0;i < this.steps.length; i++) {
692
- intermediates[i] = curVal;
693
- curVal = this.steps[i].lookup(curVal, NONE);
694
- if (curVal === NONE) {
695
- return root;
696
- }
697
- }
698
- let newVal = v;
699
- for (let i = this.steps.length - 1;i >= 0; i--) {
700
- newVal = this.steps[i].setValue(intermediates[i], newVal);
701
- intermediates[i] = newVal;
702
- }
703
- return newVal;
131
+ let newVal = v;
132
+ for (let i = this.steps.length - 1;i >= 0; i--) {
133
+ newVal = this.steps[i].setValue(intermediates[i], newVal);
134
+ intermediates[i] = newVal;
135
+ }
136
+ return newVal;
704
137
  }
705
138
  buildStack(stack) {
706
139
  const root = stack.it;
@@ -3701,28 +3134,28 @@ function hashCollection(collection) {
3701
3134
  }
3702
3135
  const ordered = isOrdered(collection);
3703
3136
  const keyed = isKeyed(collection);
3704
- let h2 = ordered ? 1 : 0;
3137
+ let h = ordered ? 1 : 0;
3705
3138
  collection.__iterate(keyed ? ordered ? (v, k) => {
3706
- h2 = 31 * h2 + hashMerge(hash(v), hash(k)) | 0;
3139
+ h = 31 * h + hashMerge(hash(v), hash(k)) | 0;
3707
3140
  } : (v, k) => {
3708
- h2 = h2 + hashMerge(hash(v), hash(k)) | 0;
3141
+ h = h + hashMerge(hash(v), hash(k)) | 0;
3709
3142
  } : ordered ? (v) => {
3710
- h2 = 31 * h2 + hash(v) | 0;
3143
+ h = 31 * h + hash(v) | 0;
3711
3144
  } : (v) => {
3712
- h2 = h2 + hash(v) | 0;
3145
+ h = h + hash(v) | 0;
3713
3146
  });
3714
- return murmurHashOfSize(collection.size, h2);
3147
+ return murmurHashOfSize(collection.size, h);
3715
3148
  }
3716
3149
  var hashMerge = (a, b) => a ^ b + 2654435769 + (a << 6) + (a >> 2) | 0;
3717
- function murmurHashOfSize(size, h2) {
3718
- h2 = Math.imul(h2, 3432918353);
3719
- h2 = Math.imul(h2 << 15 | h2 >>> -15, 461845907);
3720
- h2 = Math.imul(h2 << 13 | h2 >>> -13, 5);
3721
- h2 = (h2 + 3864292196 | 0) ^ size;
3722
- h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
3723
- h2 = Math.imul(h2 ^ h2 >>> 13, 3266489909);
3724
- h2 = smi(h2 ^ h2 >>> 16);
3725
- return h2;
3150
+ function murmurHashOfSize(size, h) {
3151
+ h = Math.imul(h, 3432918353);
3152
+ h = Math.imul(h << 15 | h >>> -15, 461845907);
3153
+ h = Math.imul(h << 13 | h >>> -13, 5);
3154
+ h = (h + 3864292196 | 0) ^ size;
3155
+ h = Math.imul(h ^ h >>> 16, 2246822507);
3156
+ h = Math.imul(h ^ h >>> 13, 3266489909);
3157
+ h = smi(h ^ h >>> 16);
3158
+ return h;
3726
3159
  }
3727
3160
  function quoteString(value) {
3728
3161
  try {
@@ -5831,7 +5264,7 @@ var List = (value) => {
5831
5264
  }
5832
5265
  assertNotInfinite(size);
5833
5266
  if (size > 0 && size < SIZE) {
5834
- return makeList(0, size, SHIFT, null, new VNode2(iter.toArray()));
5267
+ return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
5835
5268
  }
5836
5269
  return empty.withMutations((list) => {
5837
5270
  list.setSize(size);
@@ -6022,7 +5455,7 @@ class ListImpl extends IndexedCollectionImpl {
6022
5455
  }
6023
5456
  List.isList = isList;
6024
5457
 
6025
- class VNode2 {
5458
+ class VNode {
6026
5459
  constructor(array, ownerID) {
6027
5460
  this.array = array;
6028
5461
  this.ownerID = ownerID;
@@ -6033,7 +5466,7 @@ class VNode2 {
6033
5466
  }
6034
5467
  const originIndex = index >>> level & MASK;
6035
5468
  if (originIndex >= this.array.length) {
6036
- return new VNode2([], ownerID);
5469
+ return new VNode([], ownerID);
6037
5470
  }
6038
5471
  const removingFirst = originIndex === 0;
6039
5472
  let newChild;
@@ -6259,7 +5692,7 @@ function editableVNode(node, ownerID) {
6259
5692
  if (ownerID && ownerID === node?.ownerID) {
6260
5693
  return node;
6261
5694
  }
6262
- return new VNode2(node?.array.slice() ?? [], ownerID);
5695
+ return new VNode(node?.array.slice() ?? [], ownerID);
6263
5696
  }
6264
5697
  function listNodeFor(list, rawIndex) {
6265
5698
  if (rawIndex >= getTailOffset(list._capacity)) {
@@ -6297,7 +5730,7 @@ function setListBounds(list, begin, end) {
6297
5730
  let newRoot = list._root;
6298
5731
  let offsetShift = 0;
6299
5732
  while (newOrigin + offsetShift < 0) {
6300
- newRoot = new VNode2(newRoot?.array.length ? [undefined, newRoot] : [], owner);
5733
+ newRoot = new VNode(newRoot?.array.length ? [undefined, newRoot] : [], owner);
6301
5734
  newLevel += SHIFT;
6302
5735
  offsetShift += 1 << newLevel;
6303
5736
  }
@@ -6310,11 +5743,11 @@ function setListBounds(list, begin, end) {
6310
5743
  const oldTailOffset = getTailOffset(oldCapacity);
6311
5744
  const newTailOffset = getTailOffset(newCapacity);
6312
5745
  while (newTailOffset >= 1 << newLevel + SHIFT) {
6313
- newRoot = new VNode2(newRoot?.array.length ? [newRoot] : [], owner);
5746
+ newRoot = new VNode(newRoot?.array.length ? [newRoot] : [], owner);
6314
5747
  newLevel += SHIFT;
6315
5748
  }
6316
5749
  const oldTail = list._tail;
6317
- let newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode2([], owner) : oldTail;
5750
+ let newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
6318
5751
  if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
6319
5752
  newRoot = editableVNode(newRoot, owner);
6320
5753
  let node = newRoot;
@@ -6707,757 +6140,1310 @@ class StackImpl extends IndexedCollectionImpl {
6707
6140
  return result;
6708
6141
  });
6709
6142
  }
6710
- keys() {
6711
- return makeIndexKeys(this.size);
6712
- }
6713
- }
6714
- Stack2.isStack = isStack;
6715
- function returnStack(stack, newSize, head) {
6716
- if (stack.__ownerID) {
6717
- stack.size = newSize;
6718
- stack._head = head;
6719
- stack.__hash = undefined;
6720
- stack.__altered = true;
6721
- return stack;
6722
- }
6723
- return makeStack(newSize, head);
6724
- }
6725
- var makeStack = (size, head, ownerID, hash2) => new StackImpl(size, head, ownerID, hash2);
6726
- var EMPTY_STACK;
6727
- var emptyStack = () => EMPTY_STACK || (EMPTY_STACK = makeStack(0));
6728
- var Set2 = (value) => value === undefined || value === null ? emptySet() : isSet(value) && !isOrdered(value) ? value : emptySet().withMutations((set2) => {
6729
- const iter = SetCollection(value);
6730
- assertNotInfinite(iter.size);
6731
- iter.forEach((v) => set2.add(v));
6732
- });
6733
- Set2.of = (...values) => Set2(values);
6734
- Set2.fromKeys = (value) => Set2(KeyedCollection(value).keySeq());
6735
- Set2.intersect = (sets) => {
6736
- sets = Collection(sets).toArray();
6737
- return sets.length ? Set2(sets.pop()).intersect(...sets) : emptySet();
6738
- };
6739
- Set2.union = (sets) => {
6740
- const setArray = Collection(sets).toArray();
6741
- return setArray.length ? Set2(setArray.pop()).union(...setArray) : emptySet();
6143
+ keys() {
6144
+ return makeIndexKeys(this.size);
6145
+ }
6146
+ }
6147
+ Stack2.isStack = isStack;
6148
+ function returnStack(stack, newSize, head) {
6149
+ if (stack.__ownerID) {
6150
+ stack.size = newSize;
6151
+ stack._head = head;
6152
+ stack.__hash = undefined;
6153
+ stack.__altered = true;
6154
+ return stack;
6155
+ }
6156
+ return makeStack(newSize, head);
6157
+ }
6158
+ var makeStack = (size, head, ownerID, hash2) => new StackImpl(size, head, ownerID, hash2);
6159
+ var EMPTY_STACK;
6160
+ var emptyStack = () => EMPTY_STACK || (EMPTY_STACK = makeStack(0));
6161
+ var Set2 = (value) => value === undefined || value === null ? emptySet() : isSet(value) && !isOrdered(value) ? value : emptySet().withMutations((set2) => {
6162
+ const iter = SetCollection(value);
6163
+ assertNotInfinite(iter.size);
6164
+ iter.forEach((v) => set2.add(v));
6165
+ });
6166
+ Set2.of = (...values) => Set2(values);
6167
+ Set2.fromKeys = (value) => Set2(KeyedCollection(value).keySeq());
6168
+ Set2.intersect = (sets) => {
6169
+ sets = Collection(sets).toArray();
6170
+ return sets.length ? Set2(sets.pop()).intersect(...sets) : emptySet();
6171
+ };
6172
+ Set2.union = (sets) => {
6173
+ const setArray = Collection(sets).toArray();
6174
+ return setArray.length ? Set2(setArray.pop()).union(...setArray) : emptySet();
6175
+ };
6176
+
6177
+ class SetImpl extends SetCollectionImpl {
6178
+ static {
6179
+ mixin(this, {
6180
+ withMutations,
6181
+ asImmutable,
6182
+ asMutable,
6183
+ [IS_SET_SYMBOL]: true,
6184
+ [DELETE]: this.prototype.remove,
6185
+ merge: this.prototype.union,
6186
+ concat: this.prototype.union,
6187
+ [Symbol.toStringTag]: "Immutable.Set"
6188
+ });
6189
+ }
6190
+ constructor(map, ownerID) {
6191
+ super();
6192
+ this.size = map ? map.size : 0;
6193
+ this._map = map;
6194
+ this.__ownerID = ownerID;
6195
+ }
6196
+ create(value) {
6197
+ return Set2(value);
6198
+ }
6199
+ toString() {
6200
+ return this.__toString("Set {", "}");
6201
+ }
6202
+ has(value) {
6203
+ return this._map.has(value);
6204
+ }
6205
+ add(value) {
6206
+ return updateSet(this, this._map.set(value, value));
6207
+ }
6208
+ remove(value) {
6209
+ return updateSet(this, this._map.remove(value));
6210
+ }
6211
+ clear() {
6212
+ return updateSet(this, this._map.clear());
6213
+ }
6214
+ map(mapper, context) {
6215
+ let didChanges = false;
6216
+ const newMap = updateSet(this, this._map.mapEntries(([, v]) => {
6217
+ const mapped = mapper.call(context, v, v, this);
6218
+ if (mapped !== v) {
6219
+ didChanges = true;
6220
+ }
6221
+ return [mapped, mapped];
6222
+ }, context));
6223
+ return didChanges ? newMap : this;
6224
+ }
6225
+ union(...iters) {
6226
+ iters = iters.filter((x) => x.size !== 0);
6227
+ if (iters.length === 0) {
6228
+ return this;
6229
+ }
6230
+ if (this.size === 0 && !this.__ownerID && iters.length === 1) {
6231
+ return Set2(iters[0]);
6232
+ }
6233
+ return this.withMutations((set2) => {
6234
+ for (const iter of iters) {
6235
+ if (typeof iter === "string") {
6236
+ set2.add(iter);
6237
+ } else {
6238
+ SetCollection(iter).forEach((value) => set2.add(value));
6239
+ }
6240
+ }
6241
+ });
6242
+ }
6243
+ intersect(...iters) {
6244
+ return filterByIters(this, iters, (value, sets) => !sets.every((iter) => iter.includes(value)));
6245
+ }
6246
+ subtract(...iters) {
6247
+ return filterByIters(this, iters, (value, sets) => sets.some((iter) => iter.includes(value)));
6248
+ }
6249
+ wasAltered() {
6250
+ return this._map.wasAltered();
6251
+ }
6252
+ __iterator(reverse) {
6253
+ return this._map.__iterator(reverse);
6254
+ }
6255
+ __empty() {
6256
+ return emptySet();
6257
+ }
6258
+ __make(map, ownerID) {
6259
+ return makeSet(map, ownerID);
6260
+ }
6261
+ __ensureOwner(ownerID) {
6262
+ if (ownerID === this.__ownerID) {
6263
+ return this;
6264
+ }
6265
+ const newMap = this._map.__ensureOwner(ownerID);
6266
+ if (!ownerID) {
6267
+ if (this.size === 0) {
6268
+ return this.__empty();
6269
+ }
6270
+ this.__ownerID = ownerID;
6271
+ this._map = newMap;
6272
+ return this;
6273
+ }
6274
+ return this.__make(newMap, ownerID);
6275
+ }
6276
+ }
6277
+ Set2.isSet = isSet;
6278
+ var makeSet = (map, ownerID) => new SetImpl(map, ownerID);
6279
+ var EMPTY_SET;
6280
+ var emptySet = () => EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
6281
+ function filterByIters(set2, iters, shouldRemove) {
6282
+ if (iters.length === 0) {
6283
+ return set2;
6284
+ }
6285
+ iters = iters.map((iter) => SetCollection(iter));
6286
+ return set2.withMutations((s) => {
6287
+ set2.forEach((value) => {
6288
+ if (shouldRemove(value, iters)) {
6289
+ s.remove(value);
6290
+ }
6291
+ });
6292
+ });
6293
+ }
6294
+ function updateSet(set2, newMap) {
6295
+ if (set2.__ownerID) {
6296
+ set2.size = newMap.size;
6297
+ set2._map = newMap;
6298
+ return set2;
6299
+ }
6300
+ return newMap === set2._map ? set2 : newMap.size === 0 ? set2.__empty() : set2.__make(newMap);
6301
+ }
6302
+ var OrderedSet = (value) => value === undefined || value === null ? emptyOrderedSet() : isOrderedSet(value) ? value : emptyOrderedSet().withMutations((set2) => {
6303
+ const iter = SetCollection(value);
6304
+ assertNotInfinite(iter.size);
6305
+ iter.forEach((v) => set2.add(v));
6306
+ });
6307
+ OrderedSet.of = (...values) => OrderedSet(values);
6308
+ OrderedSet.fromKeys = (value) => OrderedSet(KeyedCollection(value).keySeq());
6309
+
6310
+ class OrderedSetImpl extends SetImpl {
6311
+ static {
6312
+ mixin(this, {
6313
+ [IS_ORDERED_SYMBOL]: true,
6314
+ [Symbol.toStringTag]: "Immutable.OrderedSet",
6315
+ zip: IndexedCollectionPrototype.zip,
6316
+ zipWith: IndexedCollectionPrototype.zipWith,
6317
+ zipAll: IndexedCollectionPrototype.zipAll
6318
+ });
6319
+ }
6320
+ create(value) {
6321
+ return OrderedSet(value);
6322
+ }
6323
+ toString() {
6324
+ return this.__toString("OrderedSet {", "}");
6325
+ }
6326
+ __empty() {
6327
+ return emptyOrderedSet();
6328
+ }
6329
+ __make(map, ownerID) {
6330
+ return makeOrderedSet(map, ownerID);
6331
+ }
6332
+ }
6333
+ OrderedSet.isOrderedSet = isOrderedSet;
6334
+ var makeOrderedSet = (map, ownerID) => new OrderedSetImpl(map, ownerID);
6335
+ var emptyOrderedSet = () => makeOrderedSet(emptyOrderedMap());
6336
+ function throwOnInvalidDefaultValues(defaultValues) {
6337
+ if (isRecord(defaultValues)) {
6338
+ throw new Error("Can not call `Record` with an immutable Record as default values. Use a plain javascript object instead.");
6339
+ }
6340
+ if (isImmutable(defaultValues)) {
6341
+ throw new Error("Can not call `Record` with an immutable Collection as default values. Use a plain javascript object instead.");
6342
+ }
6343
+ if (defaultValues === null || typeof defaultValues !== "object") {
6344
+ throw new Error("Can not call `Record` with a non-object as default values. Use a plain javascript object instead.");
6345
+ }
6346
+ }
6347
+ var Record = (defaultValues, name) => {
6348
+ let hasInitialized;
6349
+ throwOnInvalidDefaultValues(defaultValues);
6350
+ const RecordType = function Record2(values) {
6351
+ if (values instanceof RecordType) {
6352
+ return values;
6353
+ }
6354
+ if (!(this instanceof RecordType)) {
6355
+ return new RecordType(values);
6356
+ }
6357
+ if (!hasInitialized) {
6358
+ hasInitialized = true;
6359
+ const keys = Object.keys(defaultValues);
6360
+ const indices = RecordTypePrototype._indices = {};
6361
+ RecordTypePrototype._keys = keys;
6362
+ RecordTypePrototype._defaultValues = defaultValues;
6363
+ for (let i = 0;i < keys.length; i++) {
6364
+ const propName = keys[i];
6365
+ indices[propName] = i;
6366
+ if (RecordTypePrototype[propName]) {
6367
+ console.warn(`Cannot define ${recordName(this)} with property "${propName}" since that property name is part of the Record API.`);
6368
+ } else {
6369
+ setProp(RecordTypePrototype, propName);
6370
+ }
6371
+ }
6372
+ }
6373
+ this.__ownerID = undefined;
6374
+ this._values = List().withMutations((l) => {
6375
+ l.setSize(this._keys.length);
6376
+ KeyedCollection(values).forEach((v, k) => {
6377
+ l.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
6378
+ });
6379
+ });
6380
+ return this;
6381
+ };
6382
+ const RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
6383
+ RecordTypePrototype.constructor = RecordType;
6384
+ RecordTypePrototype.create = RecordType;
6385
+ if (name) {
6386
+ RecordType.displayName = name;
6387
+ }
6388
+ return RecordType;
6742
6389
  };
6743
6390
 
6744
- class SetImpl extends SetCollectionImpl {
6391
+ class RecordImpl {
6745
6392
  static {
6746
6393
  mixin(this, {
6747
- withMutations,
6748
6394
  asImmutable,
6749
6395
  asMutable,
6750
- [IS_SET_SYMBOL]: true,
6396
+ deleteIn,
6397
+ getIn,
6398
+ hasIn,
6399
+ merge,
6400
+ mergeWith,
6401
+ mergeDeep,
6402
+ mergeDeepWith,
6403
+ mergeDeepIn,
6404
+ mergeIn,
6405
+ setIn,
6406
+ toObject,
6407
+ update,
6408
+ updateIn,
6409
+ withMutations,
6410
+ removeIn: deleteIn,
6411
+ toJSON: toObject,
6412
+ [IS_RECORD_SYMBOL]: true,
6751
6413
  [DELETE]: this.prototype.remove,
6752
- merge: this.prototype.union,
6753
- concat: this.prototype.union,
6754
- [Symbol.toStringTag]: "Immutable.Set"
6414
+ [Symbol.iterator]: this.prototype.entries,
6415
+ [Symbol.toStringTag]: "Immutable.Record"
6755
6416
  });
6756
6417
  }
6757
- constructor(map, ownerID) {
6758
- super();
6759
- this.size = map ? map.size : 0;
6760
- this._map = map;
6761
- this.__ownerID = ownerID;
6418
+ toString() {
6419
+ const body = this._keys.map((k) => `${k}: ${quoteString(this.get(k))}`).join(", ");
6420
+ return `${recordName(this)} { ${body} }`;
6762
6421
  }
6763
- create(value) {
6764
- return Set2(value);
6422
+ equals(other) {
6423
+ return this === other || isRecord(other) && recordSeq(this).equals(recordSeq(other));
6765
6424
  }
6766
- toString() {
6767
- return this.__toString("Set {", "}");
6425
+ hashCode() {
6426
+ return recordSeq(this).hashCode();
6768
6427
  }
6769
- has(value) {
6770
- return this._map.has(value);
6428
+ has(k) {
6429
+ return Object.hasOwn(this._indices, k);
6771
6430
  }
6772
- add(value) {
6773
- return updateSet(this, this._map.set(value, value));
6431
+ get(k, notSetValue) {
6432
+ if (!this.has(k)) {
6433
+ return notSetValue;
6434
+ }
6435
+ const index = this._indices[k];
6436
+ const value = this._values.get(index);
6437
+ return value === undefined ? this._defaultValues[k] : value;
6774
6438
  }
6775
- remove(value) {
6776
- return updateSet(this, this._map.remove(value));
6439
+ set(k, v) {
6440
+ if (this.has(k)) {
6441
+ const newValues = this._values.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
6442
+ if (newValues !== this._values && !this.__ownerID) {
6443
+ return makeRecord(this, newValues);
6444
+ }
6445
+ }
6446
+ return this;
6447
+ }
6448
+ remove(k) {
6449
+ return this.set(k);
6777
6450
  }
6778
6451
  clear() {
6779
- return updateSet(this, this._map.clear());
6452
+ const newValues = this._values.clear().setSize(this._keys.length);
6453
+ return this.__ownerID ? this : makeRecord(this, newValues);
6780
6454
  }
6781
- map(mapper, context) {
6782
- let didChanges = false;
6783
- const newMap = updateSet(this, this._map.mapEntries(([, v]) => {
6784
- const mapped = mapper.call(context, v, v, this);
6785
- if (mapped !== v) {
6786
- didChanges = true;
6787
- }
6788
- return [mapped, mapped];
6789
- }, context));
6790
- return didChanges ? newMap : this;
6455
+ wasAltered() {
6456
+ return this._values.wasAltered();
6791
6457
  }
6792
- union(...iters) {
6793
- iters = iters.filter((x) => x.size !== 0);
6794
- if (iters.length === 0) {
6458
+ toSeq() {
6459
+ return recordSeq(this);
6460
+ }
6461
+ toJS() {
6462
+ return toJS(this);
6463
+ }
6464
+ entries() {
6465
+ return this.__iterator();
6466
+ }
6467
+ __iterate(fn, reverse) {
6468
+ return recordSeq(this).__iterate(fn, reverse);
6469
+ }
6470
+ __iterator(reverse) {
6471
+ return recordSeq(this).__iterator(reverse);
6472
+ }
6473
+ __ensureOwner(ownerID) {
6474
+ if (ownerID === this.__ownerID) {
6795
6475
  return this;
6796
6476
  }
6797
- if (this.size === 0 && !this.__ownerID && iters.length === 1) {
6798
- return Set2(iters[0]);
6477
+ const newValues = this._values.__ensureOwner(ownerID);
6478
+ if (!ownerID) {
6479
+ this.__ownerID = ownerID;
6480
+ this._values = newValues;
6481
+ return this;
6799
6482
  }
6800
- return this.withMutations((set2) => {
6801
- for (const iter of iters) {
6802
- if (typeof iter === "string") {
6803
- set2.add(iter);
6804
- } else {
6805
- SetCollection(iter).forEach((value) => set2.add(value));
6806
- }
6483
+ return makeRecord(this, newValues, ownerID);
6484
+ }
6485
+ }
6486
+ Record.isRecord = isRecord;
6487
+ var recordName = (record) => record.constructor.displayName || record.constructor.name || "Record";
6488
+
6489
+ class RecordSeq extends KeyedSeqImpl {
6490
+ constructor(record) {
6491
+ super();
6492
+ this._record = record;
6493
+ this.size = record._keys.length;
6494
+ }
6495
+ get(key, notSetValue) {
6496
+ return this._record.get(key, notSetValue);
6497
+ }
6498
+ has(key) {
6499
+ return this._record.has(key);
6500
+ }
6501
+ __iterateUncached(fn, reverse) {
6502
+ const record = this._record;
6503
+ const keys = record._keys;
6504
+ const size = keys.length;
6505
+ let i = 0;
6506
+ while (i !== size) {
6507
+ const ii = reverse ? size - ++i : i++;
6508
+ const k = keys[ii];
6509
+ if (fn(record.get(k), k, this) === false) {
6510
+ break;
6807
6511
  }
6808
- });
6512
+ }
6513
+ return i;
6809
6514
  }
6810
- intersect(...iters) {
6811
- return filterByIters(this, iters, (value, sets) => !sets.every((iter) => iter.includes(value)));
6515
+ __iteratorUncached(reverse) {
6516
+ const record = this._record;
6517
+ const keys = record._keys;
6518
+ const size = keys.length;
6519
+ let i = 0;
6520
+ return makeEntryIterator((entry) => {
6521
+ if (i === size) {
6522
+ return false;
6523
+ }
6524
+ const ii = reverse ? size - ++i : i++;
6525
+ const k = keys[ii];
6526
+ entry[0] = k;
6527
+ entry[1] = record.get(k);
6528
+ return true;
6529
+ });
6812
6530
  }
6813
- subtract(...iters) {
6814
- return filterByIters(this, iters, (value, sets) => sets.some((iter) => iter.includes(value)));
6531
+ }
6532
+ var recordSeq = (record) => new RecordSeq(record);
6533
+ Record.getDescriptiveName = recordName;
6534
+ var RecordPrototype = RecordImpl.prototype;
6535
+ function makeRecord(likeRecord, values, ownerID) {
6536
+ const record = Object.create(Object.getPrototypeOf(likeRecord));
6537
+ record._values = values;
6538
+ record.__ownerID = ownerID;
6539
+ return record;
6540
+ }
6541
+ function setProp(prototype, name) {
6542
+ Object.defineProperty(prototype, name, {
6543
+ get() {
6544
+ return this.get(name);
6545
+ },
6546
+ set(value) {
6547
+ invariant(this.__ownerID, "Cannot set on an immutable record.");
6548
+ this.set(name, value);
6549
+ }
6550
+ });
6551
+ }
6552
+ var Range = (start, end, step = 1) => {
6553
+ invariant(step !== 0, "Cannot step a Range by 0");
6554
+ invariant(start !== undefined, "You must define a start value when using Range");
6555
+ invariant(end !== undefined, "You must define an end value when using Range");
6556
+ step = Math.abs(step);
6557
+ if (end < start) {
6558
+ step = -step;
6815
6559
  }
6816
- wasAltered() {
6817
- return this._map.wasAltered();
6560
+ const size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
6561
+ return new RangeImpl(start, end, step, size);
6562
+ };
6563
+
6564
+ class RangeImpl extends IndexedSeqImpl {
6565
+ _start;
6566
+ _end;
6567
+ _step;
6568
+ constructor(start, end, step, size) {
6569
+ super();
6570
+ this._start = start;
6571
+ this._end = end;
6572
+ this._step = step;
6573
+ this.size = size;
6818
6574
  }
6819
- __iterator(reverse) {
6820
- return this._map.__iterator(reverse);
6575
+ toString() {
6576
+ return this.size === 0 ? "Range []" : `Range [ ${this._start}...${this._end}${this._step !== 1 ? ` by ${this._step}` : ""} ]`;
6821
6577
  }
6822
- __empty() {
6823
- return emptySet();
6578
+ get(index, notSetValue) {
6579
+ return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue;
6824
6580
  }
6825
- __make(map, ownerID) {
6826
- return makeSet(map, ownerID);
6581
+ includes(searchValue) {
6582
+ const possibleIndex = (searchValue - this._start) / this._step;
6583
+ return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex);
6827
6584
  }
6828
- __ensureOwner(ownerID) {
6829
- if (ownerID === this.__ownerID) {
6585
+ slice(begin, end) {
6586
+ if (wholeSlice(begin, end, this.size)) {
6830
6587
  return this;
6831
6588
  }
6832
- const newMap = this._map.__ensureOwner(ownerID);
6833
- if (!ownerID) {
6834
- if (this.size === 0) {
6835
- return this.__empty();
6589
+ begin = resolveBegin(begin, this.size);
6590
+ end = resolveEnd(end, this.size);
6591
+ if (end <= begin) {
6592
+ return Range(0, 0);
6593
+ }
6594
+ return Range(this.get(begin, this._end), this.get(end, this._end), this._step);
6595
+ }
6596
+ indexOf(searchValue) {
6597
+ const offsetValue = searchValue - this._start;
6598
+ if (offsetValue % this._step === 0) {
6599
+ const index = offsetValue / this._step;
6600
+ if (index >= 0 && index < this.size) {
6601
+ return index;
6836
6602
  }
6837
- this.__ownerID = ownerID;
6838
- this._map = newMap;
6839
- return this;
6840
6603
  }
6841
- return this.__make(newMap, ownerID);
6604
+ return -1;
6842
6605
  }
6843
- }
6844
- Set2.isSet = isSet;
6845
- var makeSet = (map, ownerID) => new SetImpl(map, ownerID);
6846
- var EMPTY_SET;
6847
- var emptySet = () => EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
6848
- function filterByIters(set2, iters, shouldRemove) {
6849
- if (iters.length === 0) {
6850
- return set2;
6606
+ lastIndexOf(searchValue) {
6607
+ return this.indexOf(searchValue);
6851
6608
  }
6852
- iters = iters.map((iter) => SetCollection(iter));
6853
- return set2.withMutations((s) => {
6854
- set2.forEach((value) => {
6855
- if (shouldRemove(value, iters)) {
6856
- s.remove(value);
6609
+ __iterateUncached(fn, reverse = false) {
6610
+ const size = this.size;
6611
+ const step = this._step;
6612
+ let value = reverse ? this._start + (size - 1) * step : this._start;
6613
+ let i = 0;
6614
+ while (i !== size) {
6615
+ const v = value;
6616
+ value += reverse ? -step : step;
6617
+ const ii = reverse ? size - ++i : i++;
6618
+ if (fn(v, ii, this) === false) {
6619
+ break;
6857
6620
  }
6858
- });
6859
- });
6860
- }
6861
- function updateSet(set2, newMap) {
6862
- if (set2.__ownerID) {
6863
- set2.size = newMap.size;
6864
- set2._map = newMap;
6865
- return set2;
6621
+ }
6622
+ return i;
6866
6623
  }
6867
- return newMap === set2._map ? set2 : newMap.size === 0 ? set2.__empty() : set2.__make(newMap);
6868
- }
6869
- var OrderedSet = (value) => value === undefined || value === null ? emptyOrderedSet() : isOrderedSet(value) ? value : emptyOrderedSet().withMutations((set2) => {
6870
- const iter = SetCollection(value);
6871
- assertNotInfinite(iter.size);
6872
- iter.forEach((v) => set2.add(v));
6873
- });
6874
- OrderedSet.of = (...values) => OrderedSet(values);
6875
- OrderedSet.fromKeys = (value) => OrderedSet(KeyedCollection(value).keySeq());
6876
-
6877
- class OrderedSetImpl extends SetImpl {
6878
- static {
6879
- mixin(this, {
6880
- [IS_ORDERED_SYMBOL]: true,
6881
- [Symbol.toStringTag]: "Immutable.OrderedSet",
6882
- zip: IndexedCollectionPrototype.zip,
6883
- zipWith: IndexedCollectionPrototype.zipWith,
6884
- zipAll: IndexedCollectionPrototype.zipAll
6624
+ __iteratorUncached(reverse = false) {
6625
+ const size = this.size;
6626
+ const step = this._step;
6627
+ let value = reverse ? this._start + (size - 1) * step : this._start;
6628
+ let i = 0;
6629
+ return makeEntryIterator((entry) => {
6630
+ if (i === size) {
6631
+ return false;
6632
+ }
6633
+ const v = value;
6634
+ value += reverse ? -step : step;
6635
+ entry[0] = reverse ? size - ++i : i++;
6636
+ entry[1] = v;
6637
+ return true;
6885
6638
  });
6886
6639
  }
6887
- create(value) {
6888
- return OrderedSet(value);
6640
+ values() {
6641
+ const size = this.size;
6642
+ const step = this._step;
6643
+ let value = this._start;
6644
+ let i = 0;
6645
+ const result = {
6646
+ done: false,
6647
+ value: undefined
6648
+ };
6649
+ return makeIterator(() => {
6650
+ if (i === size)
6651
+ return DONE;
6652
+ result.value = value;
6653
+ value += step;
6654
+ i++;
6655
+ return result;
6656
+ });
6889
6657
  }
6890
- toString() {
6891
- return this.__toString("OrderedSet {", "}");
6658
+ keys() {
6659
+ return makeIndexKeys(this.size);
6892
6660
  }
6893
- __empty() {
6894
- return emptyOrderedSet();
6661
+ equals(other) {
6662
+ return other instanceof RangeImpl ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other);
6895
6663
  }
6896
- __make(map, ownerID) {
6897
- return makeOrderedSet(map, ownerID);
6664
+ static {
6665
+ this.prototype[Symbol.iterator] = this.prototype.values;
6898
6666
  }
6899
6667
  }
6900
- OrderedSet.isOrderedSet = isOrderedSet;
6901
- var makeOrderedSet = (map, ownerID) => new OrderedSetImpl(map, ownerID);
6902
- var emptyOrderedSet = () => makeOrderedSet(emptyOrderedMap());
6903
- function throwOnInvalidDefaultValues(defaultValues) {
6904
- if (isRecord(defaultValues)) {
6905
- throw new Error("Can not call `Record` with an immutable Record as default values. Use a plain javascript object instead.");
6668
+ class RepeatImpl extends IndexedSeqImpl {
6669
+ constructor(value, size) {
6670
+ super();
6671
+ this._value = value;
6672
+ this.size = size;
6906
6673
  }
6907
- if (isImmutable(defaultValues)) {
6908
- throw new Error("Can not call `Record` with an immutable Collection as default values. Use a plain javascript object instead.");
6674
+ toString() {
6675
+ if (this.size === 0) {
6676
+ return "Repeat []";
6677
+ }
6678
+ return `Repeat [ ${this._value} ${this.size} times ]`;
6909
6679
  }
6910
- if (defaultValues === null || typeof defaultValues !== "object") {
6911
- throw new Error("Can not call `Record` with a non-object as default values. Use a plain javascript object instead.");
6680
+ get(index, notSetValue) {
6681
+ return this.has(index) ? this._value : notSetValue;
6912
6682
  }
6913
- }
6914
- var Record = (defaultValues, name) => {
6915
- let hasInitialized;
6916
- throwOnInvalidDefaultValues(defaultValues);
6917
- const RecordType = function Record2(values) {
6918
- if (values instanceof RecordType) {
6919
- return values;
6920
- }
6921
- if (!(this instanceof RecordType)) {
6922
- return new RecordType(values);
6683
+ includes(searchValue) {
6684
+ return is(this._value, searchValue);
6685
+ }
6686
+ slice(begin, end) {
6687
+ const size = this.size;
6688
+ return wholeSlice(begin, end, size) ? this : new RepeatImpl(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
6689
+ }
6690
+ reverse() {
6691
+ return this;
6692
+ }
6693
+ indexOf(searchValue) {
6694
+ if (is(this._value, searchValue)) {
6695
+ return 0;
6923
6696
  }
6924
- if (!hasInitialized) {
6925
- hasInitialized = true;
6926
- const keys = Object.keys(defaultValues);
6927
- const indices = RecordTypePrototype._indices = {};
6928
- RecordTypePrototype._keys = keys;
6929
- RecordTypePrototype._defaultValues = defaultValues;
6930
- for (let i = 0;i < keys.length; i++) {
6931
- const propName = keys[i];
6932
- indices[propName] = i;
6933
- if (RecordTypePrototype[propName]) {
6934
- console.warn(`Cannot define ${recordName(this)} with property "${propName}" since that property name is part of the Record API.`);
6935
- } else {
6936
- setProp(RecordTypePrototype, propName);
6937
- }
6938
- }
6697
+ return -1;
6698
+ }
6699
+ lastIndexOf(searchValue) {
6700
+ if (is(this._value, searchValue)) {
6701
+ return this.size;
6939
6702
  }
6940
- this.__ownerID = undefined;
6941
- this._values = List().withMutations((l) => {
6942
- l.setSize(this._keys.length);
6943
- KeyedCollection(values).forEach((v, k) => {
6944
- l.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
6945
- });
6946
- });
6947
- return this;
6948
- };
6949
- const RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
6950
- RecordTypePrototype.constructor = RecordType;
6951
- RecordTypePrototype.create = RecordType;
6952
- if (name) {
6953
- RecordType.displayName = name;
6703
+ return -1;
6954
6704
  }
6955
- return RecordType;
6956
- };
6957
-
6958
- class RecordImpl {
6959
- static {
6960
- mixin(this, {
6961
- asImmutable,
6962
- asMutable,
6963
- deleteIn,
6964
- getIn,
6965
- hasIn,
6966
- merge,
6967
- mergeWith,
6968
- mergeDeep,
6969
- mergeDeepWith,
6970
- mergeDeepIn,
6971
- mergeIn,
6972
- setIn,
6973
- toObject,
6974
- update,
6975
- updateIn,
6976
- withMutations,
6977
- removeIn: deleteIn,
6978
- toJSON: toObject,
6979
- [IS_RECORD_SYMBOL]: true,
6980
- [DELETE]: this.prototype.remove,
6981
- [Symbol.iterator]: this.prototype.entries,
6982
- [Symbol.toStringTag]: "Immutable.Record"
6705
+ __iterateUncached(fn, reverse) {
6706
+ const size = this.size;
6707
+ let i = 0;
6708
+ while (i !== size) {
6709
+ if (fn(this._value, reverse ? size - ++i : i++, this) === false) {
6710
+ break;
6711
+ }
6712
+ }
6713
+ return i;
6714
+ }
6715
+ __iteratorUncached(reverse) {
6716
+ const size = this.size;
6717
+ const val = this._value;
6718
+ let i = 0;
6719
+ return makeEntryIterator((entry) => {
6720
+ if (i === size) {
6721
+ return false;
6722
+ }
6723
+ entry[0] = reverse ? size - ++i : i++;
6724
+ entry[1] = val;
6725
+ return true;
6983
6726
  });
6984
6727
  }
6985
- toString() {
6986
- const body = this._keys.map((k) => `${k}: ${quoteString(this.get(k))}`).join(", ");
6987
- return `${recordName(this)} { ${body} }`;
6728
+ values() {
6729
+ const size = this.size;
6730
+ const val = this._value;
6731
+ let i = 0;
6732
+ const result = {
6733
+ done: false,
6734
+ value: undefined
6735
+ };
6736
+ return makeIterator(() => {
6737
+ if (i === size)
6738
+ return DONE;
6739
+ i++;
6740
+ result.value = val;
6741
+ return result;
6742
+ });
6743
+ }
6744
+ keys() {
6745
+ return makeIndexKeys(this.size);
6988
6746
  }
6989
6747
  equals(other) {
6990
- return this === other || isRecord(other) && recordSeq(this).equals(recordSeq(other));
6748
+ return other instanceof RepeatImpl ? this.size === other.size && is(this._value, other._value) : deepEqual(this, other);
6991
6749
  }
6992
- hashCode() {
6993
- return recordSeq(this).hashCode();
6750
+ static {
6751
+ this.prototype[Symbol.iterator] = this.prototype.values;
6994
6752
  }
6995
- has(k) {
6996
- return Object.hasOwn(this._indices, k);
6753
+ }
6754
+
6755
+ // src/renderer.js
6756
+ var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
6757
+
6758
+ class Renderer {
6759
+ constructor(comps, h, fragment, comment, renderFn, getSeqInfo, cache) {
6760
+ this.comps = comps;
6761
+ this.h = h;
6762
+ this.fragment = fragment;
6763
+ this.comment = comment;
6764
+ this.renderFn = renderFn;
6765
+ this.getSeqInfo = getSeqInfo ?? basicGetSeqInfo;
6766
+ this.cache = cache ?? new WeakMapDomCache;
6997
6767
  }
6998
- get(k, notSetValue) {
6999
- if (!this.has(k)) {
7000
- return notSetValue;
7001
- }
7002
- const index = this._indices[k];
7003
- const value = this._values.get(index);
7004
- return value === undefined ? this._defaultValues[k] : value;
6768
+ setNullCache() {
6769
+ this.cache = new NullDomCache;
7005
6770
  }
7006
- set(k, v) {
7007
- if (this.has(k)) {
7008
- const newValues = this._values.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
7009
- if (newValues !== this._values && !this.__ownerID) {
7010
- return makeRecord(this, newValues);
6771
+ renderToDOM(stack, val) {
6772
+ const rootNode = document.createElement("div");
6773
+ this.renderFn(this.h("div", null, [this.renderRoot(stack, val)]), rootNode);
6774
+ return rootNode.childNodes[0];
6775
+ }
6776
+ renderToString(stack, val, cleanAttrs = true) {
6777
+ const dom = this.renderToDOM(stack, val, this.renderFn);
6778
+ if (cleanAttrs) {
6779
+ const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
6780
+ for (const { dataset } of nodes) {
6781
+ for (const name of DATASET_ATTRS) {
6782
+ delete dataset[name];
6783
+ }
7011
6784
  }
7012
6785
  }
7013
- return this;
7014
- }
7015
- remove(k) {
7016
- return this.set(k);
6786
+ return dom.innerHTML;
7017
6787
  }
7018
- clear() {
7019
- const newValues = this._values.clear().setSize(this._keys.length);
7020
- return this.__ownerID ? this : makeRecord(this, newValues);
6788
+ renderRoot(stack, val, viewName = null) {
6789
+ const c = this.comps.getCompFor(val);
6790
+ const nid = c.getView(viewName).anode.nodeId ?? null;
6791
+ return c ? this._rValComp(stack, val, c, nid, "ROOT", viewName) : null;
7021
6792
  }
7022
- wasAltered() {
7023
- return this._values.wasAltered();
6793
+ renderIt(stack, nodeId, key, viewName) {
6794
+ const c = this.comps.getCompFor(stack.it);
6795
+ return c ? this._rValComp(stack, stack.it, c, nodeId, key, viewName) : null;
7024
6796
  }
7025
- toSeq() {
7026
- return recordSeq(this);
6797
+ _rValComp(stack, val, comp, nid, key, viewName) {
6798
+ const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
6799
+ const cachedNode = this.cache.get(val, cacheKey);
6800
+ if (cachedNode) {
6801
+ return cachedNode;
6802
+ }
6803
+ const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
6804
+ const meta = this.renderMetadata("Comp", { nid });
6805
+ const dom = this.renderFragment([meta, view.render(stack, this)]);
6806
+ this.cache.set(val, cacheKey, dom);
6807
+ return dom;
7027
6808
  }
7028
- toJS() {
7029
- return toJS(this);
6809
+ renderEach(stack, iterInfo, nodeId, viewName) {
6810
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
6811
+ const [attrName, gen] = this.getSeqInfo(seq);
6812
+ const r = [];
6813
+ const iterData = loopWith.call(stack.it, seq);
6814
+ for (const [key, value] of gen(seq)) {
6815
+ if (filter.call(stack.it, key, value, iterData)) {
6816
+ const newStack = stack.enter(value, { key }, true);
6817
+ const dom = this.renderIt(newStack, nodeId, key, viewName);
6818
+ r.push(this.renderMetadata("Each", { nid: nodeId, [attrName]: key }));
6819
+ r.push(dom);
6820
+ }
6821
+ }
6822
+ return r;
7030
6823
  }
7031
- entries() {
7032
- return this.__iterator();
6824
+ renderEachWhen(stack, iterInfo, node, nid) {
6825
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
6826
+ const [attrName, gen] = this.getSeqInfo(seq);
6827
+ const hasEnricher = !!enricher;
6828
+ const r = [];
6829
+ const iterData = loopWith.call(stack.it, seq);
6830
+ for (const [key, value] of gen(seq)) {
6831
+ if (filter.call(stack.it, key, value, iterData)) {
6832
+ const bindings = { key, value };
6833
+ const cacheKey = `${nid}-${key}`;
6834
+ let cachedNode;
6835
+ if (hasEnricher) {
6836
+ enricher.call(stack.it, bindings, key, value, iterData);
6837
+ cachedNode = this.cache.get2(stack.it, value, cacheKey);
6838
+ } else {
6839
+ cachedNode = this.cache.get(value, cacheKey);
6840
+ }
6841
+ if (cachedNode) {
6842
+ r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
6843
+ r.push(cachedNode);
6844
+ continue;
6845
+ }
6846
+ const newStack = stack.enter(value, bindings, false);
6847
+ const dom = node.render(newStack, this);
6848
+ r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
6849
+ if (hasEnricher) {
6850
+ this.cache.set2(stack.it, value, cacheKey, dom);
6851
+ } else {
6852
+ this.cache.set(value, cacheKey, dom);
6853
+ }
6854
+ r.push(dom);
6855
+ }
6856
+ }
6857
+ return r;
7033
6858
  }
7034
- __iterate(fn, reverse) {
7035
- return recordSeq(this).__iterate(fn, reverse);
6859
+ renderText(text) {
6860
+ return text;
7036
6861
  }
7037
- __iterator(reverse) {
7038
- return recordSeq(this).__iterator(reverse);
6862
+ renderMetadata(type, info) {
6863
+ info.$ = type;
6864
+ return this.renderComment(`§${JSON.stringify(info)}§`);
7039
6865
  }
7040
- __ensureOwner(ownerID) {
7041
- if (ownerID === this.__ownerID) {
7042
- return this;
7043
- }
7044
- const newValues = this._values.__ensureOwner(ownerID);
7045
- if (!ownerID) {
7046
- this.__ownerID = ownerID;
7047
- this._values = newValues;
7048
- return this;
7049
- }
7050
- return makeRecord(this, newValues, ownerID);
6866
+ renderComment(text) {
6867
+ return this.comment(text);
7051
6868
  }
7052
- }
7053
- Record.isRecord = isRecord;
7054
- var recordName = (record) => record.constructor.displayName || record.constructor.name || "Record";
7055
-
7056
- class RecordSeq extends KeyedSeqImpl {
7057
- constructor(record) {
7058
- super();
7059
- this._record = record;
7060
- this.size = record._keys.length;
6869
+ renderEmpty(_text) {
6870
+ return null;
7061
6871
  }
7062
- get(key, notSetValue) {
7063
- return this._record.get(key, notSetValue);
6872
+ renderTag(tagName, attrs, childs) {
6873
+ return this.h(tagName, attrs, childs);
7064
6874
  }
7065
- has(key) {
7066
- return this._record.has(key);
6875
+ renderFragment(childs) {
6876
+ return this.fragment(childs);
7067
6877
  }
7068
- __iterateUncached(fn, reverse) {
7069
- const record = this._record;
7070
- const keys = record._keys;
7071
- const size = keys.length;
7072
- let i = 0;
7073
- while (i !== size) {
7074
- const ii = reverse ? size - ++i : i++;
7075
- const k = keys[ii];
7076
- if (fn(record.get(k), k, this) === false) {
7077
- break;
6878
+ }
6879
+ function* imIndexedEntries(seq) {
6880
+ let i = 0;
6881
+ for (const v of seq)
6882
+ yield [i++, v];
6883
+ }
6884
+ function* imKeyedEntries(obj) {
6885
+ for (const [key, value] of obj.toSeq().entries())
6886
+ yield [key, value];
6887
+ }
6888
+ var seqInfoByClass = new Map;
6889
+ var idxInfo = ["si", imIndexedEntries];
6890
+ var keyInfo = ["sk", imKeyedEntries];
6891
+ var unkInfo = ["si", function* nullEntries(_obj) {}];
6892
+ function basicGetSeqInfo(seq) {
6893
+ return isIndexed(seq) ? idxInfo : isKeyed(seq) ? keyInfo : seqInfoByClass.get(seq?.constructor) ?? unkInfo;
6894
+ }
6895
+
6896
+ // src/vdom.js
6897
+ function isHtmlAttribute(propName) {
6898
+ return propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
6899
+ }
6900
+ function getDomProp(node, propName) {
6901
+ return node[propName];
6902
+ }
6903
+ function setDomProp(node, propName, value) {
6904
+ node[propName] = value;
6905
+ }
6906
+ function applyProperties(node, props, previous) {
6907
+ for (const propName in props) {
6908
+ const propValue = props[propName];
6909
+ if (propValue === undefined) {
6910
+ removeProperty(node, propName, previous);
6911
+ } else if (isHtmlAttribute(propName)) {
6912
+ node.setAttribute(propName, propValue);
6913
+ } else {
6914
+ if (typeof propValue === "object" && propValue !== null) {
6915
+ patchObject(node, previous, propName, propValue);
6916
+ } else {
6917
+ setDomProp(node, propName, propValue);
7078
6918
  }
7079
6919
  }
7080
- return i;
7081
- }
7082
- __iteratorUncached(reverse) {
7083
- const record = this._record;
7084
- const keys = record._keys;
7085
- const size = keys.length;
7086
- let i = 0;
7087
- return makeEntryIterator((entry) => {
7088
- if (i === size) {
7089
- return false;
7090
- }
7091
- const ii = reverse ? size - ++i : i++;
7092
- const k = keys[ii];
7093
- entry[0] = k;
7094
- entry[1] = record.get(k);
7095
- return true;
7096
- });
7097
6920
  }
7098
6921
  }
7099
- var recordSeq = (record) => new RecordSeq(record);
7100
- Record.getDescriptiveName = recordName;
7101
- var RecordPrototype = RecordImpl.prototype;
7102
- function makeRecord(likeRecord, values, ownerID) {
7103
- const record = Object.create(Object.getPrototypeOf(likeRecord));
7104
- record._values = values;
7105
- record.__ownerID = ownerID;
7106
- return record;
6922
+ function removeProperty(node, propName, previous) {
6923
+ const previousValue = previous[propName];
6924
+ if (isHtmlAttribute(propName)) {
6925
+ node.removeAttribute(propName);
6926
+ } else if (typeof previousValue === "string") {
6927
+ setDomProp(node, propName, "");
6928
+ const attrName = propName === "className" ? "class" : propName === "htmlFor" ? "for" : propName;
6929
+ node.removeAttribute(attrName);
6930
+ } else {
6931
+ setDomProp(node, propName, null);
6932
+ }
7107
6933
  }
7108
- function setProp(prototype, name) {
7109
- Object.defineProperty(prototype, name, {
7110
- get() {
7111
- return this.get(name);
7112
- },
7113
- set(value) {
7114
- invariant(this.__ownerID, "Cannot set on an immutable record.");
7115
- this.set(name, value);
7116
- }
7117
- });
6934
+ function patchObject(node, previous, propName, propValue) {
6935
+ const previousValue = previous?.[propName];
6936
+ if (previousValue && typeof previousValue === "object" && Object.getPrototypeOf(previousValue) !== Object.getPrototypeOf(propValue)) {
6937
+ setDomProp(node, propName, propValue);
6938
+ return;
6939
+ }
6940
+ let current = getDomProp(node, propName);
6941
+ if (typeof current !== "object" || current === null) {
6942
+ setDomProp(node, propName, {});
6943
+ current = getDomProp(node, propName);
6944
+ }
6945
+ const target = current;
6946
+ for (const k in propValue) {
6947
+ target[k] = propValue[k];
6948
+ }
7118
6949
  }
7119
- var Range = (start, end, step = 1) => {
7120
- invariant(step !== 0, "Cannot step a Range by 0");
7121
- invariant(start !== undefined, "You must define a start value when using Range");
7122
- invariant(end !== undefined, "You must define an end value when using Range");
7123
- step = Math.abs(step);
7124
- if (end < start) {
7125
- step = -step;
6950
+
6951
+ class Warning {
6952
+ constructor(type, message) {
6953
+ this.type = type;
6954
+ this.message = message;
7126
6955
  }
7127
- const size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
7128
- return new RangeImpl(start, end, step, size);
7129
- };
6956
+ }
7130
6957
 
7131
- class RangeImpl extends IndexedSeqImpl {
7132
- _start;
7133
- _end;
7134
- _step;
7135
- constructor(start, end, step, size) {
7136
- super();
7137
- this._start = start;
7138
- this._end = end;
7139
- this._step = step;
7140
- this.size = size;
6958
+ class DuplicatedKeysWarning extends Warning {
6959
+ constructor(duplicatedKeys, parentTag, parentIndex) {
6960
+ const keys = [...duplicatedKeys].join(", ");
6961
+ super("DuplicatedKeys", `Duplicate keys found: [${keys}] in ${parentTag || "fragment"} at index ${parentIndex}. Nodes with duplicated keys are matched positionally.`);
6962
+ this.duplicatedKeys = duplicatedKeys;
6963
+ this.parentTag = parentTag;
6964
+ this.parentIndex = parentIndex;
7141
6965
  }
7142
- toString() {
7143
- return this.size === 0 ? "Range []" : `Range [ ${this._start}...${this._end}${this._step !== 1 ? ` by ${this._step}` : ""} ]`;
6966
+ }
6967
+
6968
+ class VBase {
6969
+ isEqualTo(other) {
6970
+ return this === other;
7144
6971
  }
7145
- get(index, notSetValue) {
7146
- return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue;
6972
+ toDom(_opts) {
6973
+ return null;
7147
6974
  }
7148
- includes(searchValue) {
7149
- const possibleIndex = (searchValue - this._start) / this._step;
7150
- return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex);
6975
+ }
6976
+ function getKey(node) {
6977
+ return node instanceof VNode2 ? node.key : undefined;
6978
+ }
6979
+ function effectiveKey(node, duplicatedKeys) {
6980
+ const key = getKey(node);
6981
+ return key && duplicatedKeys?.has(key) ? undefined : key;
6982
+ }
6983
+ function isIterable(obj) {
6984
+ return obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
6985
+ }
6986
+ function addChild(normalizedChildren, child) {
6987
+ if (child == null) {
6988
+ return;
7151
6989
  }
7152
- slice(begin, end) {
7153
- if (wholeSlice(begin, end, this.size)) {
7154
- return this;
6990
+ if (isIterable(child)) {
6991
+ for (const c of child) {
6992
+ addChild(normalizedChildren, c);
7155
6993
  }
7156
- begin = resolveBegin(begin, this.size);
7157
- end = resolveEnd(end, this.size);
7158
- if (end <= begin) {
7159
- return Range(0, 0);
6994
+ } else if (child instanceof VBase) {
6995
+ if (child instanceof VFragment) {
6996
+ normalizedChildren.push(...child.childs);
6997
+ } else {
6998
+ normalizedChildren.push(child);
7160
6999
  }
7161
- return Range(this.get(begin, this._end), this.get(end, this._end), this._step);
7000
+ } else {
7001
+ normalizedChildren.push(new VText(child));
7162
7002
  }
7163
- indexOf(searchValue) {
7164
- const offsetValue = searchValue - this._start;
7165
- if (offsetValue % this._step === 0) {
7166
- const index = offsetValue / this._step;
7167
- if (index >= 0 && index < this.size) {
7168
- return index;
7169
- }
7170
- }
7171
- return -1;
7003
+ }
7004
+
7005
+ class VText extends VBase {
7006
+ constructor(text) {
7007
+ super();
7008
+ this.text = String(text);
7172
7009
  }
7173
- lastIndexOf(searchValue) {
7174
- return this.indexOf(searchValue);
7010
+ get nodeType() {
7011
+ return 3;
7175
7012
  }
7176
- __iterateUncached(fn, reverse = false) {
7177
- const size = this.size;
7178
- const step = this._step;
7179
- let value = reverse ? this._start + (size - 1) * step : this._start;
7180
- let i = 0;
7181
- while (i !== size) {
7182
- const v = value;
7183
- value += reverse ? -step : step;
7184
- const ii = reverse ? size - ++i : i++;
7185
- if (fn(v, ii, this) === false) {
7186
- break;
7187
- }
7188
- }
7189
- return i;
7013
+ isEqualTo(other) {
7014
+ return other instanceof VText && this.text === other.text;
7190
7015
  }
7191
- __iteratorUncached(reverse = false) {
7192
- const size = this.size;
7193
- const step = this._step;
7194
- let value = reverse ? this._start + (size - 1) * step : this._start;
7195
- let i = 0;
7196
- return makeEntryIterator((entry) => {
7197
- if (i === size) {
7198
- return false;
7199
- }
7200
- const v = value;
7201
- value += reverse ? -step : step;
7202
- entry[0] = reverse ? size - ++i : i++;
7203
- entry[1] = v;
7204
- return true;
7205
- });
7016
+ toDom(opts) {
7017
+ return opts.document.createTextNode(this.text);
7206
7018
  }
7207
- values() {
7208
- const size = this.size;
7209
- const step = this._step;
7210
- let value = this._start;
7211
- let i = 0;
7212
- const result = {
7213
- done: false,
7214
- value: undefined
7215
- };
7216
- return makeIterator(() => {
7217
- if (i === size)
7218
- return DONE;
7219
- result.value = value;
7220
- value += step;
7221
- i++;
7222
- return result;
7223
- });
7019
+ }
7020
+
7021
+ class VComment extends VBase {
7022
+ constructor(text) {
7023
+ super();
7024
+ this.text = text;
7224
7025
  }
7225
- keys() {
7226
- return makeIndexKeys(this.size);
7026
+ get nodeType() {
7027
+ return 8;
7227
7028
  }
7228
- equals(other) {
7229
- return other instanceof RangeImpl ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other);
7029
+ isEqualTo(other) {
7030
+ return other instanceof VComment && this.text === other.text;
7230
7031
  }
7231
- static {
7232
- this.prototype[Symbol.iterator] = this.prototype.values;
7032
+ toDom(opts) {
7033
+ return opts.document.createComment(this.text);
7233
7034
  }
7234
7035
  }
7235
- class RepeatImpl extends IndexedSeqImpl {
7236
- constructor(value, size) {
7036
+
7037
+ class VFragment extends VBase {
7038
+ constructor(childs) {
7237
7039
  super();
7238
- this._value = value;
7239
- this.size = size;
7040
+ const normalized = [];
7041
+ addChild(normalized, childs);
7042
+ this.childs = normalized;
7240
7043
  }
7241
- toString() {
7242
- if (this.size === 0) {
7243
- return "Repeat []";
7244
- }
7245
- return `Repeat [ ${this._value} ${this.size} times ]`;
7044
+ get nodeType() {
7045
+ return 11;
7246
7046
  }
7247
- get(index, notSetValue) {
7248
- return this.has(index) ? this._value : notSetValue;
7047
+ isEqualTo(other) {
7048
+ if (!(other instanceof VFragment) || this.childs.length !== other.childs.length) {
7049
+ return false;
7050
+ }
7051
+ for (let i = 0;i < this.childs.length; i++) {
7052
+ if (!this.childs[i].isEqualTo(other.childs[i])) {
7053
+ return false;
7054
+ }
7055
+ }
7056
+ return true;
7249
7057
  }
7250
- includes(searchValue) {
7251
- return is(this._value, searchValue);
7058
+ toDom(opts) {
7059
+ const fragment = opts.document.createDocumentFragment();
7060
+ for (const child of this.childs) {
7061
+ const childNode = child.toDom(opts);
7062
+ if (childNode) {
7063
+ fragment.appendChild(childNode);
7064
+ }
7065
+ }
7066
+ return fragment;
7252
7067
  }
7253
- slice(begin, end) {
7254
- const size = this.size;
7255
- return wholeSlice(begin, end, size) ? this : new RepeatImpl(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
7068
+ }
7069
+
7070
+ class VNode2 extends VBase {
7071
+ constructor(tag, attrs, childs, key, namespace) {
7072
+ super();
7073
+ this.tag = tag;
7074
+ this.attrs = attrs ?? {};
7075
+ this.childs = childs ?? [];
7076
+ this.key = key != null ? String(key) : undefined;
7077
+ this.namespace = typeof namespace === "string" ? namespace : null;
7078
+ this.attrCount = Object.keys(this.attrs).length;
7256
7079
  }
7257
- reverse() {
7258
- return this;
7080
+ get nodeType() {
7081
+ return 1;
7259
7082
  }
7260
- indexOf(searchValue) {
7261
- if (is(this._value, searchValue)) {
7262
- return 0;
7083
+ isEqualTo(other) {
7084
+ if (!(other instanceof VNode2) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.attrCount !== other.attrCount || this.childs.length !== other.childs.length) {
7085
+ return false;
7263
7086
  }
7264
- return -1;
7265
- }
7266
- lastIndexOf(searchValue) {
7267
- if (is(this._value, searchValue)) {
7268
- return this.size;
7087
+ for (const key in this.attrs) {
7088
+ if (this.attrs[key] !== other.attrs[key]) {
7089
+ return false;
7090
+ }
7269
7091
  }
7270
- return -1;
7092
+ for (let i = 0;i < this.childs.length; i++) {
7093
+ if (!this.childs[i].isEqualTo(other.childs[i])) {
7094
+ return false;
7095
+ }
7096
+ }
7097
+ return true;
7271
7098
  }
7272
- __iterateUncached(fn, reverse) {
7273
- const size = this.size;
7274
- let i = 0;
7275
- while (i !== size) {
7276
- if (fn(this._value, reverse ? size - ++i : i++, this) === false) {
7277
- break;
7099
+ toDom(opts) {
7100
+ const doc = opts.document;
7101
+ const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
7102
+ applyProperties(node, this.attrs, {});
7103
+ for (const child of this.childs) {
7104
+ const childNode = child.toDom(opts);
7105
+ if (childNode) {
7106
+ node.appendChild(childNode);
7278
7107
  }
7279
7108
  }
7280
- return i;
7109
+ return node;
7281
7110
  }
7282
- __iteratorUncached(reverse) {
7283
- const size = this.size;
7284
- const val = this._value;
7285
- let i = 0;
7286
- return makeEntryIterator((entry) => {
7287
- if (i === size) {
7288
- return false;
7111
+ }
7112
+ function diffProps(a, b) {
7113
+ let diff = null;
7114
+ for (const aKey in a) {
7115
+ if (!Object.hasOwn(b, aKey)) {
7116
+ diff ??= {};
7117
+ diff[aKey] = undefined;
7118
+ continue;
7119
+ }
7120
+ const aValue = a[aKey];
7121
+ const bValue = b[aKey];
7122
+ if (aValue === bValue) {} else if (typeof aValue === "object" && aValue !== null && typeof bValue === "object" && bValue !== null) {
7123
+ if (Object.getPrototypeOf(bValue) !== Object.getPrototypeOf(aValue)) {
7124
+ diff ??= {};
7125
+ diff[aKey] = bValue;
7126
+ } else {
7127
+ const objectDiff = diffProps(aValue, bValue);
7128
+ if (objectDiff) {
7129
+ diff ??= {};
7130
+ diff[aKey] = objectDiff;
7131
+ }
7289
7132
  }
7290
- entry[0] = reverse ? size - ++i : i++;
7291
- entry[1] = val;
7292
- return true;
7293
- });
7133
+ } else {
7134
+ diff ??= {};
7135
+ diff[aKey] = bValue;
7136
+ }
7294
7137
  }
7295
- values() {
7296
- const size = this.size;
7297
- const val = this._value;
7298
- let i = 0;
7299
- const result = {
7300
- done: false,
7301
- value: undefined
7138
+ for (const bKey in b) {
7139
+ if (!Object.hasOwn(a, bKey)) {
7140
+ diff ??= {};
7141
+ diff[bKey] = b[bKey];
7142
+ }
7143
+ }
7144
+ return diff;
7145
+ }
7146
+ function reorder(oldChildren, newChildren) {
7147
+ const rawNew = keyIndex(newChildren);
7148
+ if (rawNew.free.length === newChildren.length) {
7149
+ return {
7150
+ children: newChildren,
7151
+ moves: null,
7152
+ duplicatedKeys: rawNew.duplicatedKeys
7302
7153
  };
7303
- return makeIterator(() => {
7304
- if (i === size)
7305
- return DONE;
7306
- i++;
7307
- result.value = val;
7308
- return result;
7309
- });
7310
7154
  }
7311
- keys() {
7312
- return makeIndexKeys(this.size);
7155
+ const rawOld = keyIndex(oldChildren);
7156
+ const duplicatedKeys = rawNew.duplicatedKeys || rawOld.duplicatedKeys ? new Set([...rawNew.duplicatedKeys || [], ...rawOld.duplicatedKeys || []]) : null;
7157
+ if (rawOld.free.length === oldChildren.length) {
7158
+ return {
7159
+ children: newChildren,
7160
+ moves: null,
7161
+ duplicatedKeys
7162
+ };
7313
7163
  }
7314
- equals(other) {
7315
- return other instanceof RepeatImpl ? this.size === other.size && is(this._value, other._value) : deepEqual(this, other);
7164
+ let newKeys;
7165
+ let newFree;
7166
+ let oldKeys;
7167
+ if (duplicatedKeys) {
7168
+ const updatedNew = keyIndex(newChildren, duplicatedKeys);
7169
+ newKeys = updatedNew.keys;
7170
+ newFree = updatedNew.free;
7171
+ oldKeys = keyIndex(oldChildren, duplicatedKeys).keys;
7172
+ } else {
7173
+ newKeys = rawNew.keys;
7174
+ newFree = rawNew.free;
7175
+ oldKeys = rawOld.keys;
7316
7176
  }
7317
- static {
7318
- this.prototype[Symbol.iterator] = this.prototype.values;
7177
+ const reordered = [];
7178
+ let freeIndex = 0;
7179
+ const freeCount = newFree.length;
7180
+ let deletedItems = 0;
7181
+ for (let i = 0;i < oldChildren.length; i++) {
7182
+ const oldItem = oldChildren[i];
7183
+ const oldKey = effectiveKey(oldItem, duplicatedKeys);
7184
+ if (oldKey) {
7185
+ if (Object.hasOwn(newKeys, oldKey)) {
7186
+ const itemIndex = newKeys[oldKey];
7187
+ reordered.push(newChildren[itemIndex]);
7188
+ } else {
7189
+ deletedItems++;
7190
+ reordered.push(null);
7191
+ }
7192
+ } else {
7193
+ if (freeIndex < freeCount) {
7194
+ const itemIndex = newFree[freeIndex++];
7195
+ reordered.push(newChildren[itemIndex]);
7196
+ } else {
7197
+ deletedItems++;
7198
+ reordered.push(null);
7199
+ }
7200
+ }
7201
+ }
7202
+ const lastFreeIndex = freeIndex >= newFree.length ? newChildren.length : newFree[freeIndex];
7203
+ for (let j = 0;j < newChildren.length; j++) {
7204
+ const newItem = newChildren[j];
7205
+ const newKey = effectiveKey(newItem, duplicatedKeys);
7206
+ if (newKey) {
7207
+ if (!Object.hasOwn(oldKeys, newKey)) {
7208
+ reordered.push(newItem);
7209
+ }
7210
+ } else if (j >= lastFreeIndex) {
7211
+ reordered.push(newItem);
7212
+ }
7319
7213
  }
7214
+ const moves = computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems);
7215
+ return { children: reordered, moves, duplicatedKeys };
7320
7216
  }
7321
-
7322
- // src/renderer.js
7323
- var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
7324
-
7325
- class Renderer {
7326
- constructor(comps, h2, fragment, comment, renderFn, getSeqInfo, cache) {
7327
- this.comps = comps;
7328
- this.h = h2;
7329
- this.fragment = fragment;
7330
- this.comment = comment;
7331
- this.renderFn = renderFn;
7332
- this.getSeqInfo = getSeqInfo ?? basicGetSeqInfo;
7333
- this.cache = cache ?? new WeakMapDomCache;
7217
+ function computeMoves(reordered, newChildren, newKeys, duplicatedKeys, deletedItems) {
7218
+ const simulate = reordered.slice();
7219
+ let simulateIndex = 0;
7220
+ const removes = [];
7221
+ const inserts = [];
7222
+ const wantedKeys = new Array(newChildren.length);
7223
+ for (let i = 0;i < newChildren.length; i++) {
7224
+ wantedKeys[i] = effectiveKey(newChildren[i], duplicatedKeys);
7334
7225
  }
7335
- setNullCache() {
7336
- this.cache = new NullDomCache;
7226
+ for (let k = 0;k < newChildren.length; ) {
7227
+ const wantedKey = wantedKeys[k];
7228
+ let simulateItem = simulate[simulateIndex];
7229
+ let simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7230
+ while (simulateItem === null && simulate.length) {
7231
+ simulate.splice(simulateIndex, 1);
7232
+ removes.push({ from: simulateIndex, key: null });
7233
+ simulateItem = simulate[simulateIndex];
7234
+ simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7235
+ }
7236
+ if (simulateItem && simulateKey === wantedKey) {
7237
+ simulateIndex++;
7238
+ k++;
7239
+ continue;
7240
+ }
7241
+ if (wantedKey) {
7242
+ if (simulateKey && newKeys[simulateKey] !== k + 1) {
7243
+ simulate.splice(simulateIndex, 1);
7244
+ removes.push({ from: simulateIndex, key: simulateKey });
7245
+ simulateItem = simulate[simulateIndex];
7246
+ simulateKey = effectiveKey(simulateItem, duplicatedKeys);
7247
+ if (simulateItem && simulateKey === wantedKey) {
7248
+ simulateIndex++;
7249
+ k++;
7250
+ continue;
7251
+ }
7252
+ }
7253
+ inserts.push({ key: wantedKey, to: k });
7254
+ k++;
7255
+ continue;
7256
+ }
7257
+ if (simulateKey) {
7258
+ simulate.splice(simulateIndex, 1);
7259
+ removes.push({ from: simulateIndex, key: simulateKey });
7260
+ continue;
7261
+ }
7262
+ k++;
7263
+ }
7264
+ while (simulateIndex < simulate.length) {
7265
+ const simulateItem = simulate[simulateIndex];
7266
+ simulate.splice(simulateIndex, 1);
7267
+ removes.push({
7268
+ from: simulateIndex,
7269
+ key: effectiveKey(simulateItem, duplicatedKeys)
7270
+ });
7337
7271
  }
7338
- renderToDOM(stack, val) {
7339
- const rootNode = document.createElement("div");
7340
- this.renderFn(this.h("div", null, [this.renderRoot(stack, val)]), rootNode);
7341
- return rootNode.childNodes[0];
7272
+ if (removes.length === deletedItems && !inserts.length) {
7273
+ return null;
7342
7274
  }
7343
- renderToString(stack, val, cleanAttrs = true) {
7344
- const dom = this.renderToDOM(stack, val, this.renderFn);
7345
- if (cleanAttrs) {
7346
- const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
7347
- for (const { dataset } of nodes) {
7348
- for (const name of DATASET_ATTRS) {
7349
- delete dataset[name];
7350
- }
7275
+ return { removes, inserts };
7276
+ }
7277
+ function keyIndex(children, excludeKeys) {
7278
+ const keys = {};
7279
+ const free = [];
7280
+ let duplicatedKeys = null;
7281
+ for (let i = 0;i < children.length; i++) {
7282
+ const key = getKey(children[i]);
7283
+ if (key && !excludeKeys?.has(key)) {
7284
+ if (key in keys) {
7285
+ duplicatedKeys ??= new Set;
7286
+ duplicatedKeys.add(key);
7351
7287
  }
7288
+ keys[key] = i;
7289
+ } else {
7290
+ free.push(i);
7352
7291
  }
7353
- return dom.innerHTML;
7354
7292
  }
7355
- renderRoot(stack, val, viewName = null) {
7356
- const c = this.comps.getCompFor(val);
7357
- const nid = c.getView(viewName).anode.nodeId ?? null;
7358
- return c ? this._rValComp(stack, val, c, nid, "ROOT", viewName) : null;
7293
+ return { keys, free, duplicatedKeys };
7294
+ }
7295
+ function replaceNode(domNode, vnode, options) {
7296
+ const parentNode = domNode.parentNode;
7297
+ const newNode = vnode.toDom(options);
7298
+ if (parentNode && newNode && newNode !== domNode) {
7299
+ parentNode.replaceChild(newNode, domNode);
7359
7300
  }
7360
- renderIt(stack, nodeId, key, viewName) {
7361
- const c = this.comps.getCompFor(stack.it);
7362
- return c ? this._rValComp(stack, stack.it, c, nodeId, key, viewName) : null;
7301
+ return newNode || domNode;
7302
+ }
7303
+ function morphNode(domNode, source, target, opts) {
7304
+ if (source === target || source.isEqualTo(target))
7305
+ return domNode;
7306
+ if (source instanceof VText && target instanceof VText || source instanceof VComment && target instanceof VComment) {
7307
+ domNode.data = target.text;
7308
+ return domNode;
7363
7309
  }
7364
- _rValComp(stack, val, comp, nid, key, viewName) {
7365
- const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
7366
- const cachedNode = this.cache.get(val, cacheKey);
7367
- if (cachedNode) {
7368
- return cachedNode;
7310
+ if (source instanceof VNode2 && target instanceof VNode2 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
7311
+ const propsDiff = diffProps(source.attrs, target.attrs);
7312
+ if (propsDiff) {
7313
+ applyProperties(domNode, propsDiff, source.attrs);
7369
7314
  }
7370
- const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
7371
- const meta = this.renderMetadata("Comp", { nid });
7372
- const dom = this.renderFragment([meta, view.render(stack, this)]);
7373
- this.cache.set(val, cacheKey, dom);
7374
- return dom;
7315
+ morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7316
+ return domNode;
7375
7317
  }
7376
- renderEach(stack, iterInfo, nodeId, viewName) {
7377
- const { seq, filter, loopWith } = iterInfo.eval(stack);
7378
- const [attrName, gen] = this.getSeqInfo(seq);
7379
- const r = [];
7380
- const iterData = loopWith.call(stack.it, seq);
7381
- for (const [key, value] of gen(seq)) {
7382
- if (filter.call(stack.it, key, value, iterData)) {
7383
- const newStack = stack.enter(value, { key }, true);
7384
- const dom = this.renderIt(newStack, nodeId, key, viewName);
7385
- r.push(this.renderMetadata("Each", { nid: nodeId, [attrName]: key }));
7386
- r.push(dom);
7387
- }
7318
+ if (source instanceof VFragment && target instanceof VFragment) {
7319
+ morphChildren(domNode, source.childs, target.childs, null, opts);
7320
+ return domNode;
7321
+ }
7322
+ return replaceNode(domNode, target, opts);
7323
+ }
7324
+ function morphChildren(parentDom, oldChilds, newChilds, parentTag, opts) {
7325
+ if (oldChilds.length === 0) {
7326
+ for (const child of newChilds) {
7327
+ const node = child.toDom(opts);
7328
+ if (node)
7329
+ parentDom.appendChild(node);
7388
7330
  }
7389
- return r;
7331
+ return;
7390
7332
  }
7391
- renderEachWhen(stack, iterInfo, node, nid) {
7392
- const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
7393
- const [attrName, gen] = this.getSeqInfo(seq);
7394
- const hasEnricher = !!enricher;
7395
- const r = [];
7396
- const iterData = loopWith.call(stack.it, seq);
7397
- for (const [key, value] of gen(seq)) {
7398
- if (filter.call(stack.it, key, value, iterData)) {
7399
- const bindings = { key, value };
7400
- const cacheKey = `${nid}-${key}`;
7401
- let cachedNode;
7402
- if (hasEnricher) {
7403
- enricher.call(stack.it, bindings, key, value, iterData);
7404
- cachedNode = this.cache.get2(stack.it, value, cacheKey);
7405
- } else {
7406
- cachedNode = this.cache.get(value, cacheKey);
7407
- }
7408
- if (cachedNode) {
7409
- r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
7410
- r.push(cachedNode);
7411
- continue;
7412
- }
7413
- const newStack = stack.enter(value, bindings, false);
7414
- const dom = node.render(newStack, this);
7415
- r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
7416
- if (hasEnricher) {
7417
- this.cache.set2(stack.it, value, cacheKey, dom);
7418
- } else {
7419
- this.cache.set(value, cacheKey, dom);
7420
- }
7421
- r.push(dom);
7422
- }
7333
+ if (newChilds.length === 0) {
7334
+ while (parentDom.firstChild) {
7335
+ parentDom.removeChild(parentDom.firstChild);
7423
7336
  }
7424
- return r;
7337
+ return;
7425
7338
  }
7426
- renderText(text) {
7427
- return text;
7339
+ const orderedSet = reorder(oldChilds, newChilds);
7340
+ const reorderedChilds = orderedSet.children;
7341
+ if (orderedSet.duplicatedKeys && opts.onWarning) {
7342
+ opts.onWarning(new DuplicatedKeysWarning(orderedSet.duplicatedKeys, parentTag, 0));
7428
7343
  }
7429
- renderMetadata(type, info) {
7430
- info.$ = type;
7431
- return this.renderComment(`§${JSON.stringify(info)}§`);
7344
+ const domChildren = Array.from(parentDom.childNodes);
7345
+ const oldLen = oldChilds.length;
7346
+ const reorderedLen = reorderedChilds.length;
7347
+ const len = Math.max(oldLen, reorderedLen);
7348
+ const toRemove = [];
7349
+ for (let i = 0;i < len; i++) {
7350
+ const leftNode = oldChilds[i];
7351
+ const rightNode = reorderedChilds[i];
7352
+ if (!leftNode && rightNode) {
7353
+ const newNode = rightNode.toDom(opts);
7354
+ if (newNode)
7355
+ parentDom.appendChild(newNode);
7356
+ } else if (leftNode && rightNode) {
7357
+ const domChild = domChildren[i];
7358
+ if (domChild) {
7359
+ morphNode(domChild, leftNode, rightNode, opts);
7360
+ }
7361
+ } else if (leftNode && !rightNode) {
7362
+ if (!orderedSet.moves && domChildren[i]) {
7363
+ toRemove.push(domChildren[i]);
7364
+ }
7365
+ }
7432
7366
  }
7433
- renderComment(text) {
7434
- return this.comment(text);
7367
+ for (const node of toRemove) {
7368
+ if (node.parentNode === parentDom) {
7369
+ parentDom.removeChild(node);
7370
+ }
7435
7371
  }
7436
- renderEmpty(_text) {
7437
- return null;
7372
+ if (orderedSet.moves) {
7373
+ applyMoves(parentDom, orderedSet.moves);
7438
7374
  }
7439
- renderTag(tagName, attrs, childs) {
7440
- return this.h(tagName, attrs, childs);
7375
+ }
7376
+ function applyMoves(domNode, moves) {
7377
+ const childNodes = domNode.childNodes;
7378
+ const keyMap = {};
7379
+ for (const remove2 of moves.removes) {
7380
+ const node = childNodes[remove2.from];
7381
+ if (remove2.key)
7382
+ keyMap[remove2.key] = node;
7383
+ domNode.removeChild(node);
7441
7384
  }
7442
- renderFragment(childs) {
7443
- return this.fragment(childs);
7385
+ let length = childNodes.length;
7386
+ for (let j = 0;j < moves.inserts.length; j++) {
7387
+ const insert = moves.inserts[j];
7388
+ const node = keyMap[insert.key];
7389
+ if (node) {
7390
+ domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to]);
7391
+ }
7444
7392
  }
7445
7393
  }
7446
- function* imIndexedEntries(seq) {
7447
- let i = 0;
7448
- for (const v of seq)
7449
- yield [i++, v];
7450
- }
7451
- function* imKeyedEntries(obj) {
7452
- for (const [key, value] of obj.toSeq().entries())
7453
- yield [key, value];
7394
+ var renderCache = new WeakMap;
7395
+ function render(vnode, container, options) {
7396
+ const cached = renderCache.get(container);
7397
+ const isFragment = vnode instanceof VFragment;
7398
+ if (cached) {
7399
+ const wasFragment = cached.vnode instanceof VFragment;
7400
+ if (wasFragment === isFragment) {
7401
+ const rootNode = wasFragment ? container : cached.dom;
7402
+ const newDom = morphNode(rootNode, cached.vnode, vnode, options);
7403
+ renderCache.set(container, {
7404
+ vnode,
7405
+ dom: isFragment ? container : newDom
7406
+ });
7407
+ return newDom;
7408
+ }
7409
+ renderCache.delete(container);
7410
+ }
7411
+ const domNode = vnode.toDom(options);
7412
+ if (domNode) {
7413
+ container.innerHTML = "";
7414
+ container.appendChild(domNode);
7415
+ renderCache.set(container, {
7416
+ vnode,
7417
+ dom: isFragment ? container : domNode
7418
+ });
7419
+ }
7420
+ return domNode;
7454
7421
  }
7455
- var seqInfoByClass = new Map;
7456
- var idxInfo = ["si", imIndexedEntries];
7457
- var keyInfo = ["sk", imKeyedEntries];
7458
- var unkInfo = ["si", function* nullEntries(_obj) {}];
7459
- function basicGetSeqInfo(seq) {
7460
- return isIndexed(seq) ? idxInfo : isKeyed(seq) ? keyInfo : seqInfoByClass.get(seq?.constructor) ?? unkInfo;
7422
+ function h(tagName, properties, children) {
7423
+ const tag = tagName.toUpperCase();
7424
+ const props = {};
7425
+ let key;
7426
+ let namespace;
7427
+ if (properties) {
7428
+ for (const propName in properties) {
7429
+ if (propName === "key") {
7430
+ key = properties[propName];
7431
+ } else if (propName === "namespace") {
7432
+ namespace = properties[propName];
7433
+ } else if (propName === "class") {
7434
+ props.className = properties[propName];
7435
+ } else if (propName === "for") {
7436
+ props.htmlFor = properties[propName];
7437
+ } else if (isHtmlAttribute(propName)) {
7438
+ props[propName] = String(properties[propName]);
7439
+ } else {
7440
+ props[propName] = properties[propName];
7441
+ }
7442
+ }
7443
+ }
7444
+ const normalizedChildren = [];
7445
+ addChild(normalizedChildren, children);
7446
+ return new VNode2(tag, props, normalizedChildren, key, namespace);
7461
7447
  }
7462
7448
  // src/oo.js
7463
7449
  var BAD_VALUE = Symbol("BadValue");
@@ -7899,6 +7885,7 @@ export {
7899
7885
  isKeyed,
7900
7886
  isIndexed,
7901
7887
  isMap as isIMap,
7888
+ injectCss,
7902
7889
  html,
7903
7890
  fieldsByClass,
7904
7891
  css,