tutuca 0.9.13 → 0.9.15

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
@@ -924,8 +924,8 @@ class RequestHandler {
924
924
 
925
925
  // src/anode.js
926
926
  class BaseNode {
927
- render(_stack, rx) {
928
- return rx.renderEmpty();
927
+ render(_stack, _rx) {
928
+ return null;
929
929
  }
930
930
  setDataAttr(key, val) {
931
931
  console.warn("setDataAttr not implemented for", this, { key, val });
@@ -941,8 +941,8 @@ class TextNode extends BaseNode {
941
941
  super();
942
942
  this.val = val;
943
943
  }
944
- render(_stack, rx) {
945
- return rx.renderText(this.val);
944
+ render(_stack, _rx) {
945
+ return this.val;
946
946
  }
947
947
  isWhiteSpace() {
948
948
  for (let i = 0;i < this.val.length; i++) {
@@ -1233,8 +1233,8 @@ class RenderEachNode extends RenderViewId {
1233
1233
  }
1234
1234
 
1235
1235
  class RenderTextNode extends ANode {
1236
- render(stack, rx) {
1237
- return rx.renderText(this.val.eval(stack));
1236
+ render(stack, _rx) {
1237
+ return this.val.eval(stack);
1238
1238
  }
1239
1239
  }
1240
1240
 
@@ -1272,13 +1272,13 @@ class WrapperNode extends ANode {
1272
1272
 
1273
1273
  class ShowNode extends WrapperNode {
1274
1274
  render(stack, rx) {
1275
- return this.val.eval(stack) ? this.node.render(stack, rx) : rx.renderEmpty();
1275
+ return this.val.eval(stack) ? this.node.render(stack, rx) : null;
1276
1276
  }
1277
1277
  }
1278
1278
 
1279
1279
  class HideNode extends WrapperNode {
1280
1280
  render(stack, rx) {
1281
- return this.val.eval(stack) ? rx.renderEmpty() : this.node.render(stack, rx);
1281
+ return this.val.eval(stack) ? null : this.node.render(stack, rx);
1282
1282
  }
1283
1283
  }
1284
1284
 
@@ -2296,184 +2296,520 @@ class PathChanges extends PathBuilder {
2296
2296
  }
2297
2297
  }
2298
2298
 
2299
- // src/app.js
2300
- class App {
2301
- constructor(rootNode, renderFn, comps, renderer, ParseContext2) {
2302
- this.rootNode = rootNode;
2303
- this.comps = comps;
2304
- this.compStack = new ComponentStack(comps);
2305
- this.transactor = new Transactor(comps, null);
2306
- this.ParseContext = ParseContext2;
2307
- this.renderer = renderer;
2308
- this.renderFn = renderFn;
2309
- this.maxEventNodeDepth = Infinity;
2310
- this._transactNextBatchId = this._evictCacheId = null;
2311
- this._eventNames = new Set(["dragstart", "dragover", "dragend"]);
2312
- this.dragInfo = this.curDragOver = null;
2313
- this.transactor.onTransactionPushed = (_transaction) => {
2314
- if (this._transactNextBatchId === null) {
2315
- this._scheduleNextTransactionBatchExecution();
2316
- }
2317
- };
2318
- this._compiled = false;
2319
- }
2320
- get state() {
2321
- return this.transactor.state;
2322
- }
2323
- handleEvent(e) {
2324
- const isDragStart = e.type === "dragstart";
2325
- const isDragOver = e.type === "dragover";
2326
- const isDragEnd = e.type === "dragend";
2327
- const { rootNode: root, maxEventNodeDepth: maxDepth, comps } = this;
2328
- const stopOnNoEvent = !(isDragOver || isDragStart || isDragEnd);
2329
- const [path, handlers] = Path.fromEvent(e, root, maxDepth, comps, stopOnNoEvent);
2330
- if (isDragOver) {
2331
- const dropTarget = getClosestDropTarget(e.target, this.rootNode, 50);
2332
- if (dropTarget !== null) {
2333
- e.preventDefault();
2334
- this._cleanDragOverAttrs();
2335
- this.curDragOver = dropTarget;
2336
- dropTarget.dataset.draggingover = this.dragInfo.type;
2337
- }
2338
- } else if (isDragStart) {
2339
- e.target.dataset.dragging = 1;
2340
- const rootValue = this.state.val;
2341
- const value = path.lookup(rootValue);
2342
- const type = e.target.dataset.dragtype ?? "?";
2343
- const stack = path.buildStack(this.makeStack(rootValue));
2344
- this.dragInfo = new DragInfo(path, stack, e, value, type, e.target);
2345
- } else if (isDragEnd) {
2346
- delete this.dragInfo.node.dataset.dragging;
2347
- this.dragInfo = null;
2348
- this._cleanDragOverAttrs();
2349
- }
2350
- if (path !== null && handlers !== null) {
2351
- for (const handler of handlers) {
2352
- this.transactor.transactInputNow(path, e, handler, this.dragInfo);
2353
- }
2299
+ // src/vdom.js
2300
+ var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
2301
+ var isObject = (v) => v !== null && typeof v === "object";
2302
+ var prototypesDiffer = (a, b) => Object.getPrototypeOf(a) !== Object.getPrototypeOf(b);
2303
+ function applyProperties(node, props, previous) {
2304
+ for (const propName in props) {
2305
+ const propValue = props[propName];
2306
+ if (propValue === undefined) {
2307
+ removeProperty(node, propName, previous);
2308
+ } else if (isHtmlAttribute(propName)) {
2309
+ node.setAttribute(propName, propValue);
2310
+ } else if (propName === "dangerouslySetInnerHTML") {
2311
+ node.innerHTML = propValue.__html ?? "";
2312
+ } else if (isObject(propValue)) {
2313
+ patchObject(node, previous, propName, propValue);
2314
+ } else if (propName === "className") {
2315
+ node.setAttribute("class", propValue);
2316
+ } else {
2317
+ node[propName] = propValue;
2354
2318
  }
2355
2319
  }
2356
- makeStack(rootValue) {
2357
- return Stack.root(this.comps, rootValue);
2320
+ }
2321
+ function removeProperty(node, propName, previous) {
2322
+ const previousValue = previous[propName];
2323
+ if (propName === "dangerouslySetInnerHTML") {
2324
+ node.replaceChildren();
2325
+ } else if (propName === "className") {
2326
+ node.removeAttribute("class");
2327
+ } else if (propName === "htmlFor") {
2328
+ node.removeAttribute("for");
2329
+ } else if (typeof previousValue === "string" || isHtmlAttribute(propName)) {
2330
+ node.removeAttribute(propName);
2331
+ } else {
2332
+ node[propName] = null;
2358
2333
  }
2359
- _cleanDragOverAttrs() {
2360
- if (this.curDragOver !== null) {
2361
- delete this.curDragOver.dataset.draggingover;
2362
- this.curDragOver = null;
2363
- }
2334
+ }
2335
+ function patchObject(node, previous, propName, propValue) {
2336
+ const previousValue = previous?.[propName];
2337
+ if (isObject(previousValue) && prototypesDiffer(previousValue, propValue)) {
2338
+ node[propName] = propValue;
2339
+ return;
2364
2340
  }
2365
- render() {
2366
- const root = this.state.val;
2367
- const stack = this.makeStack(root);
2368
- return this.renderFn(this.renderer.renderRoot(stack, root), this.rootNode);
2341
+ if (!isObject(node[propName])) {
2342
+ node[propName] = {};
2369
2343
  }
2370
- onChange(callback) {
2371
- this.transactor.state.onChange(callback);
2344
+ const target = node[propName];
2345
+ for (const k in propValue) {
2346
+ target[k] = propValue[k];
2372
2347
  }
2373
- compile() {
2374
- for (const Comp of this.comps.byId.values()) {
2375
- Comp.compile(this.ParseContext);
2376
- for (const key in Comp.views) {
2377
- for (const name of Comp.views[key].ctx.genEventNames()) {
2378
- this._eventNames.add(name);
2379
- }
2380
- }
2381
- }
2382
- this._compiled = true;
2348
+ }
2349
+
2350
+ class VBase {
2351
+ }
2352
+ var getKey = (child) => child instanceof VNode ? child.key : undefined;
2353
+ var isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
2354
+ function childsEqual(a, b) {
2355
+ for (let i = 0;i < a.length; i++) {
2356
+ if (!a[i].isEqualTo(b[i]))
2357
+ return false;
2383
2358
  }
2384
- start(opts) {
2385
- if (!this._compiled) {
2386
- this.compile();
2387
- }
2388
- for (const name of this._eventNames) {
2389
- this.rootNode.addEventListener(name, this);
2359
+ return true;
2360
+ }
2361
+ function appendChildNodes(parent, childs, opts) {
2362
+ for (const child of childs) {
2363
+ parent.appendChild(child.toDom(opts));
2364
+ }
2365
+ }
2366
+ function addChild(normalizedChildren, child) {
2367
+ if (child == null)
2368
+ return;
2369
+ if (isIterable(child)) {
2370
+ for (const c of child) {
2371
+ addChild(normalizedChildren, c);
2390
2372
  }
2391
- this.onChange((info) => {
2392
- if (info.val !== info.old) {
2393
- this.render();
2394
- }
2395
- });
2396
- injectCss("tutuca-app", this.comps.compileStyles(), opts?.head ?? document.head);
2397
- if (opts?.noCache) {
2398
- this.renderer.setNullCache();
2399
- this.comps.setNullComputedCache();
2373
+ } else if (child instanceof VBase) {
2374
+ if (child instanceof VFragment) {
2375
+ normalizedChildren.push(...child.childs);
2400
2376
  } else {
2401
- this.startCacheEvictionInterval();
2402
- }
2403
- this.render();
2404
- }
2405
- stop() {
2406
- this.stopCacheEvictionInterval();
2407
- for (const name of this._eventNames) {
2408
- this.rootNode.removeEventListener(name, this);
2377
+ normalizedChildren.push(child);
2409
2378
  }
2379
+ } else {
2380
+ normalizedChildren.push(new VText(child));
2410
2381
  }
2411
- dispatchLogicAtRoot(name, args, opts) {
2412
- return this.transactor.pushLogic(new Path([]), name, args, opts);
2413
- }
2414
- registerComponents(comps, aliases) {
2415
- const scope = this.compStack.enter();
2416
- scope.registerComponents(comps, aliases);
2417
- return scope;
2418
- }
2419
- _transactNextBatch(maxRunTimeMs = 10) {
2420
- this._transactNextBatchId = null;
2421
- const startTs = Date.now();
2422
- const t = this.transactor;
2423
- while (t.hasPendingTransactions && Date.now() - startTs < maxRunTimeMs) {
2424
- t.transactNext();
2425
- }
2426
- if (t.hasPendingTransactions) {
2427
- this._scheduleNextTransactionBatchExecution();
2428
- }
2382
+ }
2383
+
2384
+ class VText extends VBase {
2385
+ constructor(text) {
2386
+ super();
2387
+ this.text = String(text);
2429
2388
  }
2430
- _scheduleNextTransactionBatchExecution() {
2431
- this._transactNextBatchId = setTimeout(() => this._transactNextBatch(), 0);
2389
+ get nodeType() {
2390
+ return 3;
2432
2391
  }
2433
- startCacheEvictionInterval(intervalMs = 30000) {
2434
- this._evictCacheId = setInterval(() => this.renderer.cache.evict(), intervalMs);
2392
+ isEqualTo(other) {
2393
+ return other instanceof VText && this.text === other.text;
2435
2394
  }
2436
- stopCacheEvictionInterval() {
2437
- clearInterval(this._evictCacheId);
2438
- this._evictCacheId = null;
2395
+ toDom(opts) {
2396
+ return opts.document.createTextNode(this.text);
2439
2397
  }
2440
2398
  }
2441
- function injectCss(nodeId, style, styleTarget = document.head) {
2442
- const styleNode = document.createElement("style");
2443
- const currentNodeWithId = styleTarget.querySelector(`#${nodeId}`);
2444
- if (currentNodeWithId) {
2445
- styleTarget.removeChild(currentNodeWithId);
2399
+
2400
+ class VComment extends VBase {
2401
+ constructor(text) {
2402
+ super();
2403
+ this.text = text;
2446
2404
  }
2447
- styleNode.id = nodeId;
2448
- styleNode.innerHTML = style;
2449
- styleTarget.appendChild(styleNode);
2450
- }
2451
- function getClosestDropTarget(target, rootNode, count) {
2452
- let node = target;
2453
- while (count-- > 0 && node !== rootNode) {
2454
- if (node.dataset?.droptarget !== undefined) {
2455
- return node;
2456
- }
2457
- node = node.parentNode;
2405
+ get nodeType() {
2406
+ return 8;
2458
2407
  }
2459
- return null;
2460
- }
2461
-
2462
- class DragInfo {
2463
- constructor(path, stack, e, val, type, node) {
2464
- this.path = path;
2465
- this.stack = stack;
2466
- this.e = e;
2467
- this.val = val;
2468
- this.type = type;
2469
- this.node = node;
2408
+ isEqualTo(other) {
2409
+ return other instanceof VComment && this.text === other.text;
2470
2410
  }
2471
- lookupBind(name) {
2472
- return this.stack.lookupBind(name);
2411
+ toDom(opts) {
2412
+ return opts.document.createComment(this.text);
2473
2413
  }
2474
2414
  }
2475
2415
 
2476
- // deps/immutable.js
2416
+ class VFragment extends VBase {
2417
+ constructor(childs) {
2418
+ super();
2419
+ this.childs = [];
2420
+ addChild(this.childs, childs);
2421
+ }
2422
+ get nodeType() {
2423
+ return 11;
2424
+ }
2425
+ isEqualTo(other) {
2426
+ if (!(other instanceof VFragment) || this.childs.length !== other.childs.length) {
2427
+ return false;
2428
+ }
2429
+ return childsEqual(this.childs, other.childs);
2430
+ }
2431
+ toDom(opts) {
2432
+ const fragment = opts.document.createDocumentFragment();
2433
+ appendChildNodes(fragment, this.childs, opts);
2434
+ return fragment;
2435
+ }
2436
+ }
2437
+
2438
+ class VNode extends VBase {
2439
+ constructor(tag, attrs, childs, key, namespace) {
2440
+ super();
2441
+ this.tag = tag;
2442
+ this.attrs = attrs ?? {};
2443
+ this.childs = childs ?? [];
2444
+ this.key = key != null ? String(key) : undefined;
2445
+ this.namespace = typeof namespace === "string" ? namespace : null;
2446
+ }
2447
+ get nodeType() {
2448
+ return 1;
2449
+ }
2450
+ isEqualTo(other) {
2451
+ if (!(other instanceof VNode) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
2452
+ return false;
2453
+ }
2454
+ for (const key in this.attrs) {
2455
+ if (this.attrs[key] !== other.attrs[key]) {
2456
+ return false;
2457
+ }
2458
+ }
2459
+ for (const key in other.attrs) {
2460
+ if (!Object.hasOwn(this.attrs, key)) {
2461
+ return false;
2462
+ }
2463
+ }
2464
+ return childsEqual(this.childs, other.childs);
2465
+ }
2466
+ toDom(opts) {
2467
+ const doc = opts.document;
2468
+ const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
2469
+ applyProperties(node, this.attrs, {});
2470
+ appendChildNodes(node, this.childs, opts);
2471
+ return node;
2472
+ }
2473
+ }
2474
+ function diffProps(a, b) {
2475
+ let diff = null;
2476
+ for (const aKey in a) {
2477
+ if (!Object.hasOwn(b, aKey)) {
2478
+ diff ??= {};
2479
+ diff[aKey] = undefined;
2480
+ continue;
2481
+ }
2482
+ const aValue = a[aKey];
2483
+ const bValue = b[aKey];
2484
+ if (aValue === bValue)
2485
+ continue;
2486
+ if (isObject(aValue) && isObject(bValue)) {
2487
+ if (prototypesDiffer(bValue, aValue)) {
2488
+ diff ??= {};
2489
+ diff[aKey] = bValue;
2490
+ } else {
2491
+ const objectDiff = diffProps(aValue, bValue);
2492
+ if (objectDiff) {
2493
+ diff ??= {};
2494
+ diff[aKey] = objectDiff;
2495
+ }
2496
+ }
2497
+ } else {
2498
+ diff ??= {};
2499
+ diff[aKey] = bValue;
2500
+ }
2501
+ }
2502
+ for (const bKey in b) {
2503
+ if (!Object.hasOwn(a, bKey)) {
2504
+ diff ??= {};
2505
+ diff[bKey] = b[bKey];
2506
+ }
2507
+ }
2508
+ return diff;
2509
+ }
2510
+ function morphNode(domNode, source, target, opts) {
2511
+ if (source === target || source.isEqualTo(target))
2512
+ return domNode;
2513
+ const type = source.nodeType;
2514
+ if (type === target.nodeType) {
2515
+ if (type === 3 || type === 8) {
2516
+ domNode.data = target.text;
2517
+ return domNode;
2518
+ }
2519
+ if (type === 1 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
2520
+ const propsDiff = diffProps(source.attrs, target.attrs);
2521
+ if (propsDiff)
2522
+ applyProperties(domNode, propsDiff, source.attrs);
2523
+ if (!target.attrs.dangerouslySetInnerHTML) {
2524
+ morphChildren(domNode, source.childs, target.childs, opts);
2525
+ }
2526
+ return domNode;
2527
+ }
2528
+ if (type === 11) {
2529
+ morphChildren(domNode, source.childs, target.childs, opts);
2530
+ return domNode;
2531
+ }
2532
+ }
2533
+ const newNode = target.toDom(opts);
2534
+ domNode.parentNode?.replaceChild(newNode, domNode);
2535
+ return newNode;
2536
+ }
2537
+ function morphChildren(parentDom, oldChilds, newChilds, opts) {
2538
+ if (oldChilds.length === 0) {
2539
+ appendChildNodes(parentDom, newChilds, opts);
2540
+ return;
2541
+ }
2542
+ if (newChilds.length === 0) {
2543
+ parentDom.replaceChildren();
2544
+ return;
2545
+ }
2546
+ const domNodes = Array.from(parentDom.childNodes);
2547
+ const oldKeyMap = Object.create(null);
2548
+ for (let i = 0;i < oldChilds.length; i++) {
2549
+ const key = getKey(oldChilds[i]);
2550
+ if (key != null)
2551
+ oldKeyMap[key] = i;
2552
+ }
2553
+ const used = new Uint8Array(oldChilds.length);
2554
+ let unkeyedCursor = 0;
2555
+ for (let j = 0;j < newChilds.length; j++) {
2556
+ const newChild = newChilds[j];
2557
+ const newKey = getKey(newChild);
2558
+ let oldIdx = -1;
2559
+ if (newKey != null) {
2560
+ if (newKey in oldKeyMap && !used[oldKeyMap[newKey]]) {
2561
+ oldIdx = oldKeyMap[newKey];
2562
+ }
2563
+ } else {
2564
+ while (unkeyedCursor < oldChilds.length) {
2565
+ if (!used[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
2566
+ oldIdx = unkeyedCursor++;
2567
+ break;
2568
+ }
2569
+ unkeyedCursor++;
2570
+ }
2571
+ }
2572
+ if (oldIdx >= 0) {
2573
+ used[oldIdx] = 1;
2574
+ const newDom = morphNode(domNodes[oldIdx], oldChilds[oldIdx], newChild, opts);
2575
+ const ref = parentDom.childNodes[j] ?? null;
2576
+ if (newDom !== ref)
2577
+ parentDom.insertBefore(newDom, ref);
2578
+ } else {
2579
+ const ref = parentDom.childNodes[j] ?? null;
2580
+ parentDom.insertBefore(newChild.toDom(opts), ref);
2581
+ }
2582
+ }
2583
+ for (let i = oldChilds.length - 1;i >= 0; i--) {
2584
+ if (!used[i] && domNodes[i].parentNode === parentDom) {
2585
+ parentDom.removeChild(domNodes[i]);
2586
+ }
2587
+ }
2588
+ }
2589
+ var renderCache = new WeakMap;
2590
+ function render(vnode, container, options) {
2591
+ const cached = renderCache.get(container);
2592
+ const isFragment = vnode instanceof VFragment;
2593
+ if (cached && cached.vnode instanceof VFragment === isFragment) {
2594
+ const oldDom = isFragment ? container : cached.dom;
2595
+ const newDom = morphNode(oldDom, cached.vnode, vnode, options);
2596
+ renderCache.set(container, { vnode, dom: isFragment ? container : newDom });
2597
+ return newDom;
2598
+ }
2599
+ renderCache.delete(container);
2600
+ const domNode = vnode.toDom(options);
2601
+ container.replaceChildren(domNode);
2602
+ renderCache.set(container, { vnode, dom: isFragment ? container : domNode });
2603
+ return domNode;
2604
+ }
2605
+ function h(tagName, properties, children) {
2606
+ const tag = tagName.toUpperCase();
2607
+ const props = {};
2608
+ let key, namespace;
2609
+ if (properties) {
2610
+ for (const propName in properties) {
2611
+ const propVal = properties[propName];
2612
+ switch (propName) {
2613
+ case "key":
2614
+ key = propVal;
2615
+ break;
2616
+ case "namespace":
2617
+ namespace = propVal;
2618
+ break;
2619
+ case "class":
2620
+ props.className = propVal;
2621
+ break;
2622
+ case "for":
2623
+ props.htmlFor = propVal;
2624
+ break;
2625
+ default:
2626
+ props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
2627
+ }
2628
+ }
2629
+ }
2630
+ const normalizedChildren = [];
2631
+ addChild(normalizedChildren, children);
2632
+ return new VNode(tag, props, normalizedChildren, key, namespace);
2633
+ }
2634
+
2635
+ // src/app.js
2636
+ class App {
2637
+ constructor(rootNode, comps, renderer, ParseContext2) {
2638
+ this.rootNode = rootNode;
2639
+ this.comps = comps;
2640
+ this.compStack = new ComponentStack(comps);
2641
+ this.transactor = new Transactor(comps, null);
2642
+ this.ParseContext = ParseContext2;
2643
+ this.renderer = renderer;
2644
+ this.maxEventNodeDepth = Infinity;
2645
+ this._transactNextBatchId = this._evictCacheId = null;
2646
+ this._eventNames = new Set(["dragstart", "dragover", "dragend"]);
2647
+ this.dragInfo = this.curDragOver = null;
2648
+ this.transactor.onTransactionPushed = (_transaction) => {
2649
+ if (this._transactNextBatchId === null) {
2650
+ this._scheduleNextTransactionBatchExecution();
2651
+ }
2652
+ };
2653
+ this._compiled = false;
2654
+ this._renderOpts = { document: rootNode.ownerDocument };
2655
+ }
2656
+ get state() {
2657
+ return this.transactor.state;
2658
+ }
2659
+ handleEvent(e) {
2660
+ const isDragStart = e.type === "dragstart";
2661
+ const isDragOver = e.type === "dragover";
2662
+ const isDragEnd = e.type === "dragend";
2663
+ const { rootNode: root, maxEventNodeDepth: maxDepth, comps } = this;
2664
+ const stopOnNoEvent = !(isDragOver || isDragStart || isDragEnd);
2665
+ const [path, handlers] = Path.fromEvent(e, root, maxDepth, comps, stopOnNoEvent);
2666
+ if (isDragOver) {
2667
+ const dropTarget = getClosestDropTarget(e.target, this.rootNode, 50);
2668
+ if (dropTarget !== null) {
2669
+ e.preventDefault();
2670
+ this._cleanDragOverAttrs();
2671
+ this.curDragOver = dropTarget;
2672
+ dropTarget.dataset.draggingover = this.dragInfo.type;
2673
+ }
2674
+ } else if (isDragStart) {
2675
+ e.target.dataset.dragging = 1;
2676
+ const rootValue = this.state.val;
2677
+ const value = path.lookup(rootValue);
2678
+ const type = e.target.dataset.dragtype ?? "?";
2679
+ const stack = path.buildStack(this.makeStack(rootValue));
2680
+ this.dragInfo = new DragInfo(path, stack, e, value, type, e.target);
2681
+ } else if (isDragEnd) {
2682
+ delete this.dragInfo.node.dataset.dragging;
2683
+ this.dragInfo = null;
2684
+ this._cleanDragOverAttrs();
2685
+ }
2686
+ if (path !== null && handlers !== null) {
2687
+ for (const handler of handlers) {
2688
+ this.transactor.transactInputNow(path, e, handler, this.dragInfo);
2689
+ }
2690
+ }
2691
+ }
2692
+ makeStack(rootValue) {
2693
+ return Stack.root(this.comps, rootValue);
2694
+ }
2695
+ _cleanDragOverAttrs() {
2696
+ if (this.curDragOver !== null) {
2697
+ delete this.curDragOver.dataset.draggingover;
2698
+ this.curDragOver = null;
2699
+ }
2700
+ }
2701
+ render() {
2702
+ const root = this.state.val;
2703
+ const stack = this.makeStack(root);
2704
+ return render(this.renderer.renderRoot(stack, root), this.rootNode, this._renderOpts);
2705
+ }
2706
+ onChange(callback) {
2707
+ this.transactor.state.onChange(callback);
2708
+ }
2709
+ compile() {
2710
+ for (const Comp of this.comps.byId.values()) {
2711
+ Comp.compile(this.ParseContext);
2712
+ for (const key in Comp.views) {
2713
+ for (const name of Comp.views[key].ctx.genEventNames()) {
2714
+ this._eventNames.add(name);
2715
+ }
2716
+ }
2717
+ }
2718
+ this._compiled = true;
2719
+ }
2720
+ start(opts) {
2721
+ if (!this._compiled) {
2722
+ this.compile();
2723
+ }
2724
+ for (const name of this._eventNames) {
2725
+ this.rootNode.addEventListener(name, this);
2726
+ }
2727
+ this.onChange((info) => {
2728
+ if (info.val !== info.old) {
2729
+ this.render();
2730
+ }
2731
+ });
2732
+ injectCss("tutuca-app", this.comps.compileStyles(), opts?.head ?? document.head);
2733
+ if (opts?.noCache) {
2734
+ this.renderer.setNullCache();
2735
+ this.comps.setNullComputedCache();
2736
+ } else {
2737
+ this.startCacheEvictionInterval();
2738
+ }
2739
+ this.render();
2740
+ }
2741
+ stop() {
2742
+ this.stopCacheEvictionInterval();
2743
+ for (const name of this._eventNames) {
2744
+ this.rootNode.removeEventListener(name, this);
2745
+ }
2746
+ }
2747
+ dispatchLogicAtRoot(name, args, opts) {
2748
+ return this.transactor.pushLogic(new Path([]), name, args, opts);
2749
+ }
2750
+ registerComponents(comps, aliases) {
2751
+ const scope = this.compStack.enter();
2752
+ scope.registerComponents(comps, aliases);
2753
+ return scope;
2754
+ }
2755
+ _transactNextBatch(maxRunTimeMs = 10) {
2756
+ this._transactNextBatchId = null;
2757
+ const startTs = Date.now();
2758
+ const t = this.transactor;
2759
+ while (t.hasPendingTransactions && Date.now() - startTs < maxRunTimeMs) {
2760
+ t.transactNext();
2761
+ }
2762
+ if (t.hasPendingTransactions) {
2763
+ this._scheduleNextTransactionBatchExecution();
2764
+ }
2765
+ }
2766
+ _scheduleNextTransactionBatchExecution() {
2767
+ this._transactNextBatchId = setTimeout(() => this._transactNextBatch(), 0);
2768
+ }
2769
+ startCacheEvictionInterval(intervalMs = 30000) {
2770
+ this._evictCacheId = setInterval(() => this.renderer.cache.evict(), intervalMs);
2771
+ }
2772
+ stopCacheEvictionInterval() {
2773
+ clearInterval(this._evictCacheId);
2774
+ this._evictCacheId = null;
2775
+ }
2776
+ }
2777
+ function injectCss(nodeId, style, styleTarget = document.head) {
2778
+ const styleNode = document.createElement("style");
2779
+ const currentNodeWithId = styleTarget.querySelector(`#${nodeId}`);
2780
+ if (currentNodeWithId) {
2781
+ styleTarget.removeChild(currentNodeWithId);
2782
+ }
2783
+ styleNode.id = nodeId;
2784
+ styleNode.innerHTML = style;
2785
+ styleTarget.appendChild(styleNode);
2786
+ }
2787
+ function getClosestDropTarget(target, rootNode, count) {
2788
+ let node = target;
2789
+ while (count-- > 0 && node !== rootNode) {
2790
+ if (node.dataset?.droptarget !== undefined) {
2791
+ return node;
2792
+ }
2793
+ node = node.parentNode;
2794
+ }
2795
+ return null;
2796
+ }
2797
+
2798
+ class DragInfo {
2799
+ constructor(path, stack, e, val, type, node) {
2800
+ this.path = path;
2801
+ this.stack = stack;
2802
+ this.e = e;
2803
+ this.val = val;
2804
+ this.type = type;
2805
+ this.node = node;
2806
+ }
2807
+ lookupBind(name) {
2808
+ return this.stack.lookupBind(name);
2809
+ }
2810
+ }
2811
+
2812
+ // deps/immutable.js
2477
2813
  function invariant(condition, error) {
2478
2814
  if (!condition)
2479
2815
  throw new Error(error);
@@ -3134,28 +3470,28 @@ function hashCollection(collection) {
3134
3470
  }
3135
3471
  const ordered = isOrdered(collection);
3136
3472
  const keyed = isKeyed(collection);
3137
- let h = ordered ? 1 : 0;
3473
+ let h2 = ordered ? 1 : 0;
3138
3474
  collection.__iterate(keyed ? ordered ? (v, k) => {
3139
- h = 31 * h + hashMerge(hash(v), hash(k)) | 0;
3475
+ h2 = 31 * h2 + hashMerge(hash(v), hash(k)) | 0;
3140
3476
  } : (v, k) => {
3141
- h = h + hashMerge(hash(v), hash(k)) | 0;
3477
+ h2 = h2 + hashMerge(hash(v), hash(k)) | 0;
3142
3478
  } : ordered ? (v) => {
3143
- h = 31 * h + hash(v) | 0;
3479
+ h2 = 31 * h2 + hash(v) | 0;
3144
3480
  } : (v) => {
3145
- h = h + hash(v) | 0;
3481
+ h2 = h2 + hash(v) | 0;
3146
3482
  });
3147
- return murmurHashOfSize(collection.size, h);
3483
+ return murmurHashOfSize(collection.size, h2);
3148
3484
  }
3149
3485
  var hashMerge = (a, b) => a ^ b + 2654435769 + (a << 6) + (a >> 2) | 0;
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;
3486
+ function murmurHashOfSize(size, h2) {
3487
+ h2 = Math.imul(h2, 3432918353);
3488
+ h2 = Math.imul(h2 << 15 | h2 >>> -15, 461845907);
3489
+ h2 = Math.imul(h2 << 13 | h2 >>> -13, 5);
3490
+ h2 = (h2 + 3864292196 | 0) ^ size;
3491
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507);
3492
+ h2 = Math.imul(h2 ^ h2 >>> 13, 3266489909);
3493
+ h2 = smi(h2 ^ h2 >>> 16);
3494
+ return h2;
3159
3495
  }
3160
3496
  function quoteString(value) {
3161
3497
  try {
@@ -5268,7 +5604,7 @@ var List = (value) => {
5268
5604
  }
5269
5605
  assertNotInfinite(size);
5270
5606
  if (size > 0 && size < SIZE) {
5271
- return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
5607
+ return makeList(0, size, SHIFT, null, new VNode2(iter.toArray()));
5272
5608
  }
5273
5609
  return empty.withMutations((list) => {
5274
5610
  list.setSize(size);
@@ -5459,7 +5795,7 @@ class ListImpl extends IndexedCollectionImpl {
5459
5795
  }
5460
5796
  List.isList = isList;
5461
5797
 
5462
- class VNode {
5798
+ class VNode2 {
5463
5799
  constructor(array, ownerID) {
5464
5800
  this.array = array;
5465
5801
  this.ownerID = ownerID;
@@ -5470,7 +5806,7 @@ class VNode {
5470
5806
  }
5471
5807
  const originIndex = index >>> level & MASK;
5472
5808
  if (originIndex >= this.array.length) {
5473
- return new VNode([], ownerID);
5809
+ return new VNode2([], ownerID);
5474
5810
  }
5475
5811
  const removingFirst = originIndex === 0;
5476
5812
  let newChild;
@@ -5696,7 +6032,7 @@ function editableVNode(node, ownerID) {
5696
6032
  if (ownerID && ownerID === node?.ownerID) {
5697
6033
  return node;
5698
6034
  }
5699
- return new VNode(node?.array.slice() ?? [], ownerID);
6035
+ return new VNode2(node?.array.slice() ?? [], ownerID);
5700
6036
  }
5701
6037
  function listNodeFor(list, rawIndex) {
5702
6038
  if (rawIndex >= getTailOffset(list._capacity)) {
@@ -5734,7 +6070,7 @@ function setListBounds(list, begin, end) {
5734
6070
  let newRoot = list._root;
5735
6071
  let offsetShift = 0;
5736
6072
  while (newOrigin + offsetShift < 0) {
5737
- newRoot = new VNode(newRoot?.array.length ? [undefined, newRoot] : [], owner);
6073
+ newRoot = new VNode2(newRoot?.array.length ? [undefined, newRoot] : [], owner);
5738
6074
  newLevel += SHIFT;
5739
6075
  offsetShift += 1 << newLevel;
5740
6076
  }
@@ -5747,11 +6083,11 @@ function setListBounds(list, begin, end) {
5747
6083
  const oldTailOffset = getTailOffset(oldCapacity);
5748
6084
  const newTailOffset = getTailOffset(newCapacity);
5749
6085
  while (newTailOffset >= 1 << newLevel + SHIFT) {
5750
- newRoot = new VNode(newRoot?.array.length ? [newRoot] : [], owner);
6086
+ newRoot = new VNode2(newRoot?.array.length ? [newRoot] : [], owner);
5751
6087
  newLevel += SHIFT;
5752
6088
  }
5753
6089
  const oldTail = list._tail;
5754
- let newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
6090
+ let newTail = newTailOffset < oldTailOffset ? listNodeFor(list, newCapacity - 1) : newTailOffset > oldTailOffset ? new VNode2([], owner) : oldTail;
5755
6091
  if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
5756
6092
  newRoot = editableVNode(newRoot, owner);
5757
6093
  let node = newRoot;
@@ -6414,915 +6750,581 @@ class RecordImpl {
6414
6750
  setIn,
6415
6751
  toObject,
6416
6752
  update,
6417
- updateIn,
6418
- withMutations,
6419
- removeIn: deleteIn,
6420
- toJSON: toObject,
6421
- [IS_RECORD_SYMBOL]: true,
6422
- [DELETE]: this.prototype.remove,
6423
- [Symbol.iterator]: this.prototype.entries,
6424
- [Symbol.toStringTag]: "Immutable.Record"
6425
- });
6426
- }
6427
- toString() {
6428
- const body = this._keys.map((k) => `${k}: ${quoteString(this.get(k))}`).join(", ");
6429
- return `${recordName(this)} { ${body} }`;
6430
- }
6431
- equals(other) {
6432
- return this === other || isRecord(other) && recordSeq(this).equals(recordSeq(other));
6433
- }
6434
- hashCode() {
6435
- return recordSeq(this).hashCode();
6436
- }
6437
- has(k) {
6438
- return Object.hasOwn(this._indices, k);
6439
- }
6440
- get(k, notSetValue) {
6441
- if (!this.has(k)) {
6442
- return notSetValue;
6443
- }
6444
- const index = this._indices[k];
6445
- const value = this._values.get(index);
6446
- return value === undefined ? this._defaultValues[k] : value;
6447
- }
6448
- set(k, v) {
6449
- if (this.has(k)) {
6450
- const newValues = this._values.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
6451
- if (newValues !== this._values && !this.__ownerID) {
6452
- return makeRecord(this, newValues);
6453
- }
6454
- }
6455
- return this;
6456
- }
6457
- remove(k) {
6458
- return this.set(k);
6459
- }
6460
- clear() {
6461
- const newValues = this._values.clear().setSize(this._keys.length);
6462
- return this.__ownerID ? this : makeRecord(this, newValues);
6463
- }
6464
- wasAltered() {
6465
- return this._values.wasAltered();
6466
- }
6467
- toSeq() {
6468
- return recordSeq(this);
6469
- }
6470
- toJS() {
6471
- return toJS(this);
6472
- }
6473
- entries() {
6474
- return this.__iterator();
6475
- }
6476
- __iterate(fn, reverse) {
6477
- return recordSeq(this).__iterate(fn, reverse);
6478
- }
6479
- __iterator(reverse) {
6480
- return recordSeq(this).__iterator(reverse);
6481
- }
6482
- __ensureOwner(ownerID) {
6483
- if (ownerID === this.__ownerID) {
6484
- return this;
6485
- }
6486
- const newValues = this._values.__ensureOwner(ownerID);
6487
- if (!ownerID) {
6488
- this.__ownerID = ownerID;
6489
- this._values = newValues;
6490
- return this;
6491
- }
6492
- return makeRecord(this, newValues, ownerID);
6493
- }
6494
- }
6495
- Record.isRecord = isRecord;
6496
- var recordName = (record) => record.constructor.displayName || record.constructor.name || "Record";
6497
-
6498
- class RecordSeq extends KeyedSeqImpl {
6499
- constructor(record) {
6500
- super();
6501
- this._record = record;
6502
- this.size = record._keys.length;
6503
- }
6504
- get(key, notSetValue) {
6505
- return this._record.get(key, notSetValue);
6506
- }
6507
- has(key) {
6508
- return this._record.has(key);
6509
- }
6510
- __iterateUncached(fn, reverse) {
6511
- const record = this._record;
6512
- const keys = record._keys;
6513
- const size = keys.length;
6514
- let i = 0;
6515
- while (i !== size) {
6516
- const ii = reverse ? size - ++i : i++;
6517
- const k = keys[ii];
6518
- if (fn(record.get(k), k, this) === false) {
6519
- break;
6520
- }
6521
- }
6522
- return i;
6523
- }
6524
- __iteratorUncached(reverse) {
6525
- const record = this._record;
6526
- const keys = record._keys;
6527
- const size = keys.length;
6528
- let i = 0;
6529
- return makeEntryIterator((entry) => {
6530
- if (i === size) {
6531
- return false;
6532
- }
6533
- const ii = reverse ? size - ++i : i++;
6534
- const k = keys[ii];
6535
- entry[0] = k;
6536
- entry[1] = record.get(k);
6537
- return true;
6538
- });
6539
- }
6540
- }
6541
- var recordSeq = (record) => new RecordSeq(record);
6542
- Record.getDescriptiveName = recordName;
6543
- var RecordPrototype = RecordImpl.prototype;
6544
- function makeRecord(likeRecord, values, ownerID) {
6545
- const record = Object.create(Object.getPrototypeOf(likeRecord));
6546
- record._values = values;
6547
- record.__ownerID = ownerID;
6548
- return record;
6549
- }
6550
- function setProp(prototype, name) {
6551
- Object.defineProperty(prototype, name, {
6552
- get() {
6553
- return this.get(name);
6554
- },
6555
- set(value) {
6556
- invariant(this.__ownerID, "Cannot set on an immutable record.");
6557
- this.set(name, value);
6558
- }
6559
- });
6560
- }
6561
- var Range = (start, end, step = 1) => {
6562
- invariant(step !== 0, "Cannot step a Range by 0");
6563
- invariant(start !== undefined, "You must define a start value when using Range");
6564
- invariant(end !== undefined, "You must define an end value when using Range");
6565
- step = Math.abs(step);
6566
- if (end < start) {
6567
- step = -step;
6568
- }
6569
- const size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
6570
- return new RangeImpl(start, end, step, size);
6571
- };
6572
-
6573
- class RangeImpl extends IndexedSeqImpl {
6574
- _start;
6575
- _end;
6576
- _step;
6577
- constructor(start, end, step, size) {
6578
- super();
6579
- this._start = start;
6580
- this._end = end;
6581
- this._step = step;
6582
- this.size = size;
6583
- }
6584
- toString() {
6585
- return this.size === 0 ? "Range []" : `Range [ ${this._start}...${this._end}${this._step !== 1 ? ` by ${this._step}` : ""} ]`;
6586
- }
6587
- get(index, notSetValue) {
6588
- return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue;
6589
- }
6590
- includes(searchValue) {
6591
- const possibleIndex = (searchValue - this._start) / this._step;
6592
- return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex);
6593
- }
6594
- slice(begin, end) {
6595
- if (wholeSlice(begin, end, this.size)) {
6596
- return this;
6597
- }
6598
- begin = resolveBegin(begin, this.size);
6599
- end = resolveEnd(end, this.size);
6600
- if (end <= begin) {
6601
- return Range(0, 0);
6602
- }
6603
- return Range(this.get(begin, this._end), this.get(end, this._end), this._step);
6604
- }
6605
- indexOf(searchValue) {
6606
- const offsetValue = searchValue - this._start;
6607
- if (offsetValue % this._step === 0) {
6608
- const index = offsetValue / this._step;
6609
- if (index >= 0 && index < this.size) {
6610
- return index;
6611
- }
6612
- }
6613
- return -1;
6614
- }
6615
- lastIndexOf(searchValue) {
6616
- return this.indexOf(searchValue);
6617
- }
6618
- __iterateUncached(fn, reverse = false) {
6619
- const size = this.size;
6620
- const step = this._step;
6621
- let value = reverse ? this._start + (size - 1) * step : this._start;
6622
- let i = 0;
6623
- while (i !== size) {
6624
- const v = value;
6625
- value += reverse ? -step : step;
6626
- const ii = reverse ? size - ++i : i++;
6627
- if (fn(v, ii, this) === false) {
6628
- break;
6629
- }
6630
- }
6631
- return i;
6632
- }
6633
- __iteratorUncached(reverse = false) {
6634
- const size = this.size;
6635
- const step = this._step;
6636
- let value = reverse ? this._start + (size - 1) * step : this._start;
6637
- let i = 0;
6638
- return makeEntryIterator((entry) => {
6639
- if (i === size) {
6640
- return false;
6641
- }
6642
- const v = value;
6643
- value += reverse ? -step : step;
6644
- entry[0] = reverse ? size - ++i : i++;
6645
- entry[1] = v;
6646
- return true;
6647
- });
6648
- }
6649
- values() {
6650
- const size = this.size;
6651
- const step = this._step;
6652
- let value = this._start;
6653
- let i = 0;
6654
- const result = {
6655
- done: false,
6656
- value: undefined
6657
- };
6658
- return makeIterator(() => {
6659
- if (i === size)
6660
- return DONE;
6661
- result.value = value;
6662
- value += step;
6663
- i++;
6664
- return result;
6753
+ updateIn,
6754
+ withMutations,
6755
+ removeIn: deleteIn,
6756
+ toJSON: toObject,
6757
+ [IS_RECORD_SYMBOL]: true,
6758
+ [DELETE]: this.prototype.remove,
6759
+ [Symbol.iterator]: this.prototype.entries,
6760
+ [Symbol.toStringTag]: "Immutable.Record"
6665
6761
  });
6666
6762
  }
6667
- keys() {
6668
- return makeIndexKeys(this.size);
6763
+ toString() {
6764
+ const body = this._keys.map((k) => `${k}: ${quoteString(this.get(k))}`).join(", ");
6765
+ return `${recordName(this)} { ${body} }`;
6669
6766
  }
6670
6767
  equals(other) {
6671
- return other instanceof RangeImpl ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other);
6768
+ return this === other || isRecord(other) && recordSeq(this).equals(recordSeq(other));
6672
6769
  }
6673
- static {
6674
- this.prototype[Symbol.iterator] = this.prototype.values;
6770
+ hashCode() {
6771
+ return recordSeq(this).hashCode();
6675
6772
  }
6676
- }
6677
- var Repeat = (value, times) => {
6678
- const size = times === undefined ? Infinity : Math.max(0, times);
6679
- return new RepeatImpl(value, size);
6680
- };
6681
-
6682
- class RepeatImpl extends IndexedSeqImpl {
6683
- constructor(value, size) {
6684
- super();
6685
- this._value = value;
6686
- this.size = size;
6773
+ has(k) {
6774
+ return Object.hasOwn(this._indices, k);
6687
6775
  }
6688
- toString() {
6689
- if (this.size === 0) {
6690
- return "Repeat []";
6776
+ get(k, notSetValue) {
6777
+ if (!this.has(k)) {
6778
+ return notSetValue;
6691
6779
  }
6692
- return `Repeat [ ${this._value} ${this.size} times ]`;
6693
- }
6694
- get(index, notSetValue) {
6695
- return this.has(index) ? this._value : notSetValue;
6696
- }
6697
- includes(searchValue) {
6698
- return is(this._value, searchValue);
6699
- }
6700
- slice(begin, end) {
6701
- const size = this.size;
6702
- return wholeSlice(begin, end, size) ? this : new RepeatImpl(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
6780
+ const index = this._indices[k];
6781
+ const value = this._values.get(index);
6782
+ return value === undefined ? this._defaultValues[k] : value;
6703
6783
  }
6704
- reverse() {
6784
+ set(k, v) {
6785
+ if (this.has(k)) {
6786
+ const newValues = this._values.set(this._indices[k], v === this._defaultValues[k] ? undefined : v);
6787
+ if (newValues !== this._values && !this.__ownerID) {
6788
+ return makeRecord(this, newValues);
6789
+ }
6790
+ }
6705
6791
  return this;
6706
6792
  }
6707
- indexOf(searchValue) {
6708
- if (is(this._value, searchValue)) {
6709
- return 0;
6710
- }
6711
- return -1;
6793
+ remove(k) {
6794
+ return this.set(k);
6712
6795
  }
6713
- lastIndexOf(searchValue) {
6714
- if (is(this._value, searchValue)) {
6715
- return this.size;
6716
- }
6717
- return -1;
6796
+ clear() {
6797
+ const newValues = this._values.clear().setSize(this._keys.length);
6798
+ return this.__ownerID ? this : makeRecord(this, newValues);
6718
6799
  }
6719
- __iterateUncached(fn, reverse) {
6720
- const size = this.size;
6721
- let i = 0;
6722
- while (i !== size) {
6723
- if (fn(this._value, reverse ? size - ++i : i++, this) === false) {
6724
- break;
6725
- }
6726
- }
6727
- return i;
6800
+ wasAltered() {
6801
+ return this._values.wasAltered();
6728
6802
  }
6729
- __iteratorUncached(reverse) {
6730
- const size = this.size;
6731
- const val = this._value;
6732
- let i = 0;
6733
- return makeEntryIterator((entry) => {
6734
- if (i === size) {
6735
- return false;
6736
- }
6737
- entry[0] = reverse ? size - ++i : i++;
6738
- entry[1] = val;
6739
- return true;
6740
- });
6803
+ toSeq() {
6804
+ return recordSeq(this);
6741
6805
  }
6742
- values() {
6743
- const size = this.size;
6744
- const val = this._value;
6745
- let i = 0;
6746
- const result = {
6747
- done: false,
6748
- value: undefined
6749
- };
6750
- return makeIterator(() => {
6751
- if (i === size)
6752
- return DONE;
6753
- i++;
6754
- result.value = val;
6755
- return result;
6756
- });
6806
+ toJS() {
6807
+ return toJS(this);
6757
6808
  }
6758
- keys() {
6759
- return makeIndexKeys(this.size);
6809
+ entries() {
6810
+ return this.__iterator();
6760
6811
  }
6761
- equals(other) {
6762
- return other instanceof RepeatImpl ? this.size === other.size && is(this._value, other._value) : deepEqual(this, other);
6812
+ __iterate(fn, reverse) {
6813
+ return recordSeq(this).__iterate(fn, reverse);
6763
6814
  }
6764
- static {
6765
- this.prototype[Symbol.iterator] = this.prototype.values;
6815
+ __iterator(reverse) {
6816
+ return recordSeq(this).__iterator(reverse);
6766
6817
  }
6767
- }
6768
- var fromJS = (value, converter) => fromJSWith([], converter ?? defaultConverter, value, "", converter?.length > 2 ? [] : undefined, {
6769
- "": value
6770
- });
6771
- function fromJSWith(stack, converter, value, key, keyPath, parentValue) {
6772
- if (typeof value !== "string" && !isImmutable(value) && (isArrayLike(value) || hasIterator(value) || isPlainObject(value))) {
6773
- if (stack.includes(value)) {
6774
- throw new TypeError("Cannot convert circular structure to Immutable");
6775
- }
6776
- stack.push(value);
6777
- if (keyPath && key !== "") {
6778
- keyPath.push(key);
6818
+ __ensureOwner(ownerID) {
6819
+ if (ownerID === this.__ownerID) {
6820
+ return this;
6779
6821
  }
6780
- const converted = converter.call(parentValue, key, Seq(value).map((v, k) => fromJSWith(stack, converter, v, k, keyPath, value)), keyPath?.slice());
6781
- stack.pop();
6782
- if (keyPath) {
6783
- keyPath.pop();
6822
+ const newValues = this._values.__ensureOwner(ownerID);
6823
+ if (!ownerID) {
6824
+ this.__ownerID = ownerID;
6825
+ this._values = newValues;
6826
+ return this;
6784
6827
  }
6785
- return converted;
6828
+ return makeRecord(this, newValues, ownerID);
6786
6829
  }
6787
- return value;
6788
- }
6789
- var defaultConverter = (k, v) => isIndexed(v) ? v.toList() : isKeyed(v) ? v.toMap() : v.toSet();
6790
- var asValues = (collection) => isKeyed(collection) ? collection.valueSeq() : collection;
6791
- function initCollectionConversions() {
6792
- CollectionImpl.prototype.toMap = function toMap() {
6793
- return Map2(this.toKeyedSeq());
6794
- };
6795
- CollectionImpl.prototype.toOrderedMap = function toOrderedMap() {
6796
- return OrderedMap(this.toKeyedSeq());
6797
- };
6798
- CollectionImpl.prototype.toOrderedSet = function toOrderedSet() {
6799
- return OrderedSet(asValues(this));
6800
- };
6801
- CollectionImpl.prototype.toSet = function toSet() {
6802
- return Set2(asValues(this));
6803
- };
6804
- CollectionImpl.prototype.toStack = function toStack() {
6805
- return Stack2(asValues(this));
6806
- };
6807
- CollectionImpl.prototype.toList = function toList() {
6808
- return List(asValues(this));
6809
- };
6810
- CollectionImpl.prototype.countBy = function countBy(grouper, context) {
6811
- const groups = Map2().asMutable();
6812
- this.__iterate((v, k) => {
6813
- groups.update(grouper.call(context, v, k, this), 0, (a) => a + 1);
6814
- });
6815
- return groups.asImmutable();
6816
- };
6817
- CollectionImpl.prototype.groupBy = function groupBy(grouper, context) {
6818
- const isKeyedIter = isKeyed(this);
6819
- const groups = (isOrdered(this) ? OrderedMap() : Map2()).asMutable();
6820
- this.__iterate((v, k) => {
6821
- groups.update(grouper.call(context, v, k, this), (a) => {
6822
- a ??= [];
6823
- a.push(isKeyedIter ? [k, v] : v);
6824
- return a;
6825
- });
6826
- });
6827
- return groups.map((arr) => reifyValues(this, arr)).asImmutable();
6828
- };
6829
- IndexedCollectionImpl.prototype.keySeq = function keySeq() {
6830
- return Range(0, this.size);
6831
- };
6832
- MapImpl.prototype.sort = function sort(comparator) {
6833
- return OrderedMap(sortFactory(this, comparator));
6834
- };
6835
- MapImpl.prototype.sortBy = function sortBy(mapper, comparator) {
6836
- return OrderedMap(sortFactory(this, comparator, mapper));
6837
- };
6838
- SetImpl.prototype.sort = function sort(comparator) {
6839
- return OrderedSet(sortFactory(this, comparator));
6840
- };
6841
- SetImpl.prototype.sortBy = function sortBy(mapper, comparator) {
6842
- return OrderedSet(sortFactory(this, comparator, mapper));
6843
- };
6844
6830
  }
6845
- var version$1 = "7.0.0";
6846
- var pkg = {
6847
- version: version$1
6848
- };
6849
- initCollectionConversions();
6850
- var { version } = pkg;
6851
-
6852
- // src/renderer.js
6853
- var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
6831
+ Record.isRecord = isRecord;
6832
+ var recordName = (record) => record.constructor.displayName || record.constructor.name || "Record";
6854
6833
 
6855
- class Renderer {
6856
- constructor(comps, h, fragment, comment, renderFn, getSeqInfo, cache) {
6857
- this.comps = comps;
6858
- this.h = h;
6859
- this.fragment = fragment;
6860
- this.renderComment = comment;
6861
- this.renderFn = renderFn;
6862
- this.getSeqInfo = getSeqInfo ?? basicGetSeqInfo;
6863
- this.cache = cache ?? new WeakMapDomCache;
6864
- }
6865
- setNullCache() {
6866
- this.cache = new NullDomCache;
6867
- }
6868
- renderToDOM(stack, val) {
6869
- const rootNode = document.createElement("div");
6870
- this.renderFn(this.h("div", null, [this.renderRoot(stack, val)]), rootNode);
6871
- return rootNode.childNodes[0];
6872
- }
6873
- renderToString(stack, val, cleanAttrs = true) {
6874
- const dom = this.renderToDOM(stack, val, this.renderFn);
6875
- if (cleanAttrs) {
6876
- const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
6877
- for (const { dataset } of nodes) {
6878
- for (const name of DATASET_ATTRS) {
6879
- delete dataset[name];
6880
- }
6881
- }
6882
- }
6883
- return dom.innerHTML;
6884
- }
6885
- renderRoot(stack, val, viewName = null) {
6886
- const comp = this.comps.getCompFor(val);
6887
- const nid = comp.getView(viewName).anode.nodeId ?? null;
6888
- return comp ? this._rValComp(stack, val, comp, nid, "ROOT", viewName) : null;
6889
- }
6890
- renderIt(stack, nodeId, key, viewName) {
6891
- const comp = this.comps.getCompFor(stack.it);
6892
- return comp ? this._rValComp(stack, stack.it, comp, nodeId, key, viewName) : null;
6834
+ class RecordSeq extends KeyedSeqImpl {
6835
+ constructor(record) {
6836
+ super();
6837
+ this._record = record;
6838
+ this.size = record._keys.length;
6893
6839
  }
6894
- _rValComp(stack, val, comp, nid, key, viewName) {
6895
- const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
6896
- const cachedNode = this.cache.get(val, cacheKey);
6897
- if (cachedNode) {
6898
- return cachedNode;
6899
- }
6900
- const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
6901
- const meta = this.renderMetadata("Comp", { nid });
6902
- const dom = this.renderFragment([meta, this.renderView(view, stack)]);
6903
- this.cache.set(val, cacheKey, dom);
6904
- return dom;
6840
+ get(key, notSetValue) {
6841
+ return this._record.get(key, notSetValue);
6905
6842
  }
6906
- pushEachEntry(r, nid, attrName, key, dom) {
6907
- r.push(this.renderMetadata("Each", { nid, [attrName]: key }), dom);
6843
+ has(key) {
6844
+ return this._record.has(key);
6908
6845
  }
6909
- renderEach(stack, iterInfo, nodeId, viewName) {
6910
- const { seq, filter, loopWith } = iterInfo.eval(stack);
6911
- const [attrName, gen] = this.getSeqInfo(seq);
6912
- const r = [];
6913
- const iterData = loopWith.call(stack.it, seq);
6914
- for (const [key, value] of gen(seq)) {
6915
- if (filter.call(stack.it, key, value, iterData)) {
6916
- const newStack = stack.enter(value, { key }, true);
6917
- const dom = this.renderIt(newStack, nodeId, key, viewName);
6918
- this.pushEachEntry(r, nodeId, attrName, key, dom);
6846
+ __iterateUncached(fn, reverse) {
6847
+ const record = this._record;
6848
+ const keys = record._keys;
6849
+ const size = keys.length;
6850
+ let i = 0;
6851
+ while (i !== size) {
6852
+ const ii = reverse ? size - ++i : i++;
6853
+ const k = keys[ii];
6854
+ if (fn(record.get(k), k, this) === false) {
6855
+ break;
6919
6856
  }
6920
6857
  }
6921
- return r;
6858
+ return i;
6922
6859
  }
6923
- renderEachWhen(stack, iterInfo, view, nid) {
6924
- const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
6925
- const [attrName, gen] = this.getSeqInfo(seq);
6926
- const r = [];
6927
- const iterData = loopWith.call(stack.it, seq);
6928
- for (const [key, value] of gen(seq)) {
6929
- if (filter.call(stack.it, key, value, iterData)) {
6930
- const bindings = { key, value };
6931
- const cacheKey = `${nid}-${key}`;
6932
- let cachedNode;
6933
- if (enricher) {
6934
- enricher.call(stack.it, bindings, key, value, iterData);
6935
- cachedNode = this.cache.get2(stack.it, value, cacheKey);
6936
- } else {
6937
- cachedNode = this.cache.get(value, cacheKey);
6938
- }
6939
- if (cachedNode) {
6940
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
6941
- continue;
6942
- }
6943
- const newStack = stack.enter(value, bindings, false);
6944
- const dom = this.renderView(view, newStack);
6945
- this.pushEachEntry(r, nid, attrName, key, dom);
6946
- if (enricher) {
6947
- this.cache.set2(stack.it, value, cacheKey, dom);
6948
- } else {
6949
- this.cache.set(value, cacheKey, dom);
6950
- }
6860
+ __iteratorUncached(reverse) {
6861
+ const record = this._record;
6862
+ const keys = record._keys;
6863
+ const size = keys.length;
6864
+ let i = 0;
6865
+ return makeEntryIterator((entry) => {
6866
+ if (i === size) {
6867
+ return false;
6951
6868
  }
6869
+ const ii = reverse ? size - ++i : i++;
6870
+ const k = keys[ii];
6871
+ entry[0] = k;
6872
+ entry[1] = record.get(k);
6873
+ return true;
6874
+ });
6875
+ }
6876
+ }
6877
+ var recordSeq = (record) => new RecordSeq(record);
6878
+ Record.getDescriptiveName = recordName;
6879
+ var RecordPrototype = RecordImpl.prototype;
6880
+ function makeRecord(likeRecord, values, ownerID) {
6881
+ const record = Object.create(Object.getPrototypeOf(likeRecord));
6882
+ record._values = values;
6883
+ record.__ownerID = ownerID;
6884
+ return record;
6885
+ }
6886
+ function setProp(prototype, name) {
6887
+ Object.defineProperty(prototype, name, {
6888
+ get() {
6889
+ return this.get(name);
6890
+ },
6891
+ set(value) {
6892
+ invariant(this.__ownerID, "Cannot set on an immutable record.");
6893
+ this.set(name, value);
6952
6894
  }
6953
- return r;
6895
+ });
6896
+ }
6897
+ var Range = (start, end, step = 1) => {
6898
+ invariant(step !== 0, "Cannot step a Range by 0");
6899
+ invariant(start !== undefined, "You must define a start value when using Range");
6900
+ invariant(end !== undefined, "You must define an end value when using Range");
6901
+ step = Math.abs(step);
6902
+ if (end < start) {
6903
+ step = -step;
6954
6904
  }
6955
- renderView(view, stack) {
6956
- return view.render(stack, this);
6905
+ const size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
6906
+ return new RangeImpl(start, end, step, size);
6907
+ };
6908
+
6909
+ class RangeImpl extends IndexedSeqImpl {
6910
+ _start;
6911
+ _end;
6912
+ _step;
6913
+ constructor(start, end, step, size) {
6914
+ super();
6915
+ this._start = start;
6916
+ this._end = end;
6917
+ this._step = step;
6918
+ this.size = size;
6919
+ }
6920
+ toString() {
6921
+ return this.size === 0 ? "Range []" : `Range [ ${this._start}...${this._end}${this._step !== 1 ? ` by ${this._step}` : ""} ]`;
6957
6922
  }
6958
- renderText(text) {
6959
- return text;
6923
+ get(index, notSetValue) {
6924
+ return this.has(index) ? this._start + wrapIndex(this, index) * this._step : notSetValue;
6960
6925
  }
6961
- renderMetadata(type, info) {
6962
- info.$ = type;
6963
- return this.renderComment(`§${JSON.stringify(info)}§`);
6926
+ includes(searchValue) {
6927
+ const possibleIndex = (searchValue - this._start) / this._step;
6928
+ return possibleIndex >= 0 && possibleIndex < this.size && possibleIndex === Math.floor(possibleIndex);
6964
6929
  }
6965
- renderEmpty() {
6966
- return null;
6930
+ slice(begin, end) {
6931
+ if (wholeSlice(begin, end, this.size)) {
6932
+ return this;
6933
+ }
6934
+ begin = resolveBegin(begin, this.size);
6935
+ end = resolveEnd(end, this.size);
6936
+ if (end <= begin) {
6937
+ return Range(0, 0);
6938
+ }
6939
+ return Range(this.get(begin, this._end), this.get(end, this._end), this._step);
6967
6940
  }
6968
- renderTag(tagName, attrs, childs) {
6969
- return this.h(tagName, attrs, childs);
6941
+ indexOf(searchValue) {
6942
+ const offsetValue = searchValue - this._start;
6943
+ if (offsetValue % this._step === 0) {
6944
+ const index = offsetValue / this._step;
6945
+ if (index >= 0 && index < this.size) {
6946
+ return index;
6947
+ }
6948
+ }
6949
+ return -1;
6970
6950
  }
6971
- renderFragment(childs) {
6972
- return this.fragment(childs);
6951
+ lastIndexOf(searchValue) {
6952
+ return this.indexOf(searchValue);
6973
6953
  }
6974
- }
6975
- function* imIndexedEntries(seq) {
6976
- let i = 0;
6977
- for (const v of seq)
6978
- yield [i++, v];
6979
- }
6980
- function* imKeyedEntries(obj) {
6981
- for (const [key, value] of obj.toSeq().entries())
6982
- yield [key, value];
6983
- }
6984
- var seqInfoByClass = new Map;
6985
- var idxInfo = ["si", imIndexedEntries];
6986
- var keyInfo = ["sk", imKeyedEntries];
6987
- var unkInfo = ["si", function* nullEntries(_obj) {}];
6988
- function basicGetSeqInfo(seq) {
6989
- return isIndexed(seq) ? idxInfo : isKeyed(seq) ? keyInfo : seqInfoByClass.get(seq?.constructor) ?? unkInfo;
6990
- }
6991
-
6992
- // src/vdom.js
6993
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
6994
- var isObject = (v) => v !== null && typeof v === "object";
6995
- var prototypesDiffer = (a, b) => Object.getPrototypeOf(a) !== Object.getPrototypeOf(b);
6996
- function applyProperties(node, props, previous) {
6997
- for (const propName in props) {
6998
- const propValue = props[propName];
6999
- if (propValue === undefined) {
7000
- removeProperty(node, propName, previous);
7001
- } else if (isHtmlAttribute(propName)) {
7002
- node.setAttribute(propName, propValue);
7003
- } else if (propName === "dangerouslySetInnerHTML") {
7004
- node.innerHTML = propValue.__html ?? "";
7005
- } else if (isObject(propValue)) {
7006
- patchObject(node, previous, propName, propValue);
7007
- } else if (propName === "className") {
7008
- node.setAttribute("class", propValue);
7009
- } else {
7010
- node[propName] = propValue;
6954
+ __iterateUncached(fn, reverse = false) {
6955
+ const size = this.size;
6956
+ const step = this._step;
6957
+ let value = reverse ? this._start + (size - 1) * step : this._start;
6958
+ let i = 0;
6959
+ while (i !== size) {
6960
+ const v = value;
6961
+ value += reverse ? -step : step;
6962
+ const ii = reverse ? size - ++i : i++;
6963
+ if (fn(v, ii, this) === false) {
6964
+ break;
6965
+ }
7011
6966
  }
6967
+ return i;
7012
6968
  }
7013
- }
7014
- function removeProperty(node, propName, previous) {
7015
- const previousValue = previous[propName];
7016
- if (propName === "dangerouslySetInnerHTML") {
7017
- node.replaceChildren();
7018
- } else if (propName === "className") {
7019
- node.removeAttribute("class");
7020
- } else if (propName === "htmlFor") {
7021
- node.removeAttribute("for");
7022
- } else if (typeof previousValue === "string" || isHtmlAttribute(propName)) {
7023
- node.removeAttribute(propName);
7024
- } else {
7025
- node[propName] = null;
6969
+ __iteratorUncached(reverse = false) {
6970
+ const size = this.size;
6971
+ const step = this._step;
6972
+ let value = reverse ? this._start + (size - 1) * step : this._start;
6973
+ let i = 0;
6974
+ return makeEntryIterator((entry) => {
6975
+ if (i === size) {
6976
+ return false;
6977
+ }
6978
+ const v = value;
6979
+ value += reverse ? -step : step;
6980
+ entry[0] = reverse ? size - ++i : i++;
6981
+ entry[1] = v;
6982
+ return true;
6983
+ });
7026
6984
  }
7027
- }
7028
- function patchObject(node, previous, propName, propValue) {
7029
- const previousValue = previous?.[propName];
7030
- if (isObject(previousValue) && prototypesDiffer(previousValue, propValue)) {
7031
- node[propName] = propValue;
7032
- return;
6985
+ values() {
6986
+ const size = this.size;
6987
+ const step = this._step;
6988
+ let value = this._start;
6989
+ let i = 0;
6990
+ const result = {
6991
+ done: false,
6992
+ value: undefined
6993
+ };
6994
+ return makeIterator(() => {
6995
+ if (i === size)
6996
+ return DONE;
6997
+ result.value = value;
6998
+ value += step;
6999
+ i++;
7000
+ return result;
7001
+ });
7033
7002
  }
7034
- if (!isObject(node[propName])) {
7035
- node[propName] = {};
7003
+ keys() {
7004
+ return makeIndexKeys(this.size);
7036
7005
  }
7037
- const target = node[propName];
7038
- for (const k in propValue) {
7039
- target[k] = propValue[k];
7006
+ equals(other) {
7007
+ return other instanceof RangeImpl ? this._start === other._start && this._end === other._end && this._step === other._step : deepEqual(this, other);
7040
7008
  }
7041
- }
7042
-
7043
- class VBase {
7044
- }
7045
- var getKey = (child) => child instanceof VNode2 ? child.key : undefined;
7046
- var isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
7047
- function childsEqual(a, b) {
7048
- for (let i = 0;i < a.length; i++) {
7049
- if (!a[i].isEqualTo(b[i]))
7050
- return false;
7009
+ static {
7010
+ this.prototype[Symbol.iterator] = this.prototype.values;
7051
7011
  }
7052
- return true;
7053
7012
  }
7054
- function appendChildNodes(parent, childs, opts) {
7055
- for (const child of childs) {
7056
- parent.appendChild(child.toDom(opts));
7013
+ var Repeat = (value, times) => {
7014
+ const size = times === undefined ? Infinity : Math.max(0, times);
7015
+ return new RepeatImpl(value, size);
7016
+ };
7017
+
7018
+ class RepeatImpl extends IndexedSeqImpl {
7019
+ constructor(value, size) {
7020
+ super();
7021
+ this._value = value;
7022
+ this.size = size;
7057
7023
  }
7058
- }
7059
- function addChild(normalizedChildren, child) {
7060
- if (child == null)
7061
- return;
7062
- if (isIterable(child)) {
7063
- for (const c of child) {
7064
- addChild(normalizedChildren, c);
7065
- }
7066
- } else if (child instanceof VBase) {
7067
- if (child instanceof VFragment) {
7068
- normalizedChildren.push(...child.childs);
7069
- } else {
7070
- normalizedChildren.push(child);
7024
+ toString() {
7025
+ if (this.size === 0) {
7026
+ return "Repeat []";
7071
7027
  }
7072
- } else {
7073
- normalizedChildren.push(new VText(child));
7028
+ return `Repeat [ ${this._value} ${this.size} times ]`;
7074
7029
  }
7075
- }
7076
-
7077
- class VText extends VBase {
7078
- constructor(text) {
7079
- super();
7080
- this.text = String(text);
7030
+ get(index, notSetValue) {
7031
+ return this.has(index) ? this._value : notSetValue;
7081
7032
  }
7082
- get nodeType() {
7083
- return 3;
7033
+ includes(searchValue) {
7034
+ return is(this._value, searchValue);
7084
7035
  }
7085
- isEqualTo(other) {
7086
- return other instanceof VText && this.text === other.text;
7036
+ slice(begin, end) {
7037
+ const size = this.size;
7038
+ return wholeSlice(begin, end, size) ? this : new RepeatImpl(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
7087
7039
  }
7088
- toDom(opts) {
7089
- return opts.document.createTextNode(this.text);
7040
+ reverse() {
7041
+ return this;
7090
7042
  }
7091
- }
7092
-
7093
- class VComment extends VBase {
7094
- constructor(text) {
7095
- super();
7096
- this.text = text;
7043
+ indexOf(searchValue) {
7044
+ if (is(this._value, searchValue)) {
7045
+ return 0;
7046
+ }
7047
+ return -1;
7097
7048
  }
7098
- get nodeType() {
7099
- return 8;
7049
+ lastIndexOf(searchValue) {
7050
+ if (is(this._value, searchValue)) {
7051
+ return this.size;
7052
+ }
7053
+ return -1;
7100
7054
  }
7101
- isEqualTo(other) {
7102
- return other instanceof VComment && this.text === other.text;
7055
+ __iterateUncached(fn, reverse) {
7056
+ const size = this.size;
7057
+ let i = 0;
7058
+ while (i !== size) {
7059
+ if (fn(this._value, reverse ? size - ++i : i++, this) === false) {
7060
+ break;
7061
+ }
7062
+ }
7063
+ return i;
7103
7064
  }
7104
- toDom(opts) {
7105
- return opts.document.createComment(this.text);
7065
+ __iteratorUncached(reverse) {
7066
+ const size = this.size;
7067
+ const val = this._value;
7068
+ let i = 0;
7069
+ return makeEntryIterator((entry) => {
7070
+ if (i === size) {
7071
+ return false;
7072
+ }
7073
+ entry[0] = reverse ? size - ++i : i++;
7074
+ entry[1] = val;
7075
+ return true;
7076
+ });
7106
7077
  }
7107
- }
7108
-
7109
- class VFragment extends VBase {
7110
- constructor(childs) {
7111
- super();
7112
- this.childs = [];
7113
- addChild(this.childs, childs);
7078
+ values() {
7079
+ const size = this.size;
7080
+ const val = this._value;
7081
+ let i = 0;
7082
+ const result = {
7083
+ done: false,
7084
+ value: undefined
7085
+ };
7086
+ return makeIterator(() => {
7087
+ if (i === size)
7088
+ return DONE;
7089
+ i++;
7090
+ result.value = val;
7091
+ return result;
7092
+ });
7114
7093
  }
7115
- get nodeType() {
7116
- return 11;
7094
+ keys() {
7095
+ return makeIndexKeys(this.size);
7117
7096
  }
7118
- isEqualTo(other) {
7119
- if (!(other instanceof VFragment) || this.childs.length !== other.childs.length) {
7120
- return false;
7121
- }
7122
- return childsEqual(this.childs, other.childs);
7097
+ equals(other) {
7098
+ return other instanceof RepeatImpl ? this.size === other.size && is(this._value, other._value) : deepEqual(this, other);
7123
7099
  }
7124
- toDom(opts) {
7125
- const fragment = opts.document.createDocumentFragment();
7126
- appendChildNodes(fragment, this.childs, opts);
7127
- return fragment;
7100
+ static {
7101
+ this.prototype[Symbol.iterator] = this.prototype.values;
7102
+ }
7103
+ }
7104
+ var fromJS = (value, converter) => fromJSWith([], converter ?? defaultConverter, value, "", converter?.length > 2 ? [] : undefined, {
7105
+ "": value
7106
+ });
7107
+ function fromJSWith(stack, converter, value, key, keyPath, parentValue) {
7108
+ if (typeof value !== "string" && !isImmutable(value) && (isArrayLike(value) || hasIterator(value) || isPlainObject(value))) {
7109
+ if (stack.includes(value)) {
7110
+ throw new TypeError("Cannot convert circular structure to Immutable");
7111
+ }
7112
+ stack.push(value);
7113
+ if (keyPath && key !== "") {
7114
+ keyPath.push(key);
7115
+ }
7116
+ const converted = converter.call(parentValue, key, Seq(value).map((v, k) => fromJSWith(stack, converter, v, k, keyPath, value)), keyPath?.slice());
7117
+ stack.pop();
7118
+ if (keyPath) {
7119
+ keyPath.pop();
7120
+ }
7121
+ return converted;
7128
7122
  }
7123
+ return value;
7124
+ }
7125
+ var defaultConverter = (k, v) => isIndexed(v) ? v.toList() : isKeyed(v) ? v.toMap() : v.toSet();
7126
+ var asValues = (collection) => isKeyed(collection) ? collection.valueSeq() : collection;
7127
+ function initCollectionConversions() {
7128
+ CollectionImpl.prototype.toMap = function toMap() {
7129
+ return Map2(this.toKeyedSeq());
7130
+ };
7131
+ CollectionImpl.prototype.toOrderedMap = function toOrderedMap() {
7132
+ return OrderedMap(this.toKeyedSeq());
7133
+ };
7134
+ CollectionImpl.prototype.toOrderedSet = function toOrderedSet() {
7135
+ return OrderedSet(asValues(this));
7136
+ };
7137
+ CollectionImpl.prototype.toSet = function toSet() {
7138
+ return Set2(asValues(this));
7139
+ };
7140
+ CollectionImpl.prototype.toStack = function toStack() {
7141
+ return Stack2(asValues(this));
7142
+ };
7143
+ CollectionImpl.prototype.toList = function toList() {
7144
+ return List(asValues(this));
7145
+ };
7146
+ CollectionImpl.prototype.countBy = function countBy(grouper, context) {
7147
+ const groups = Map2().asMutable();
7148
+ this.__iterate((v, k) => {
7149
+ groups.update(grouper.call(context, v, k, this), 0, (a) => a + 1);
7150
+ });
7151
+ return groups.asImmutable();
7152
+ };
7153
+ CollectionImpl.prototype.groupBy = function groupBy(grouper, context) {
7154
+ const isKeyedIter = isKeyed(this);
7155
+ const groups = (isOrdered(this) ? OrderedMap() : Map2()).asMutable();
7156
+ this.__iterate((v, k) => {
7157
+ groups.update(grouper.call(context, v, k, this), (a) => {
7158
+ a ??= [];
7159
+ a.push(isKeyedIter ? [k, v] : v);
7160
+ return a;
7161
+ });
7162
+ });
7163
+ return groups.map((arr) => reifyValues(this, arr)).asImmutable();
7164
+ };
7165
+ IndexedCollectionImpl.prototype.keySeq = function keySeq() {
7166
+ return Range(0, this.size);
7167
+ };
7168
+ MapImpl.prototype.sort = function sort(comparator) {
7169
+ return OrderedMap(sortFactory(this, comparator));
7170
+ };
7171
+ MapImpl.prototype.sortBy = function sortBy(mapper, comparator) {
7172
+ return OrderedMap(sortFactory(this, comparator, mapper));
7173
+ };
7174
+ SetImpl.prototype.sort = function sort(comparator) {
7175
+ return OrderedSet(sortFactory(this, comparator));
7176
+ };
7177
+ SetImpl.prototype.sortBy = function sortBy(mapper, comparator) {
7178
+ return OrderedSet(sortFactory(this, comparator, mapper));
7179
+ };
7129
7180
  }
7181
+ var version$1 = "7.0.0";
7182
+ var pkg = {
7183
+ version: version$1
7184
+ };
7185
+ initCollectionConversions();
7186
+ var { version } = pkg;
7130
7187
 
7131
- class VNode2 extends VBase {
7132
- constructor(tag, attrs, childs, key, namespace) {
7133
- super();
7134
- this.tag = tag;
7135
- this.attrs = attrs ?? {};
7136
- this.childs = childs ?? [];
7137
- this.key = key != null ? String(key) : undefined;
7138
- this.namespace = typeof namespace === "string" ? namespace : null;
7188
+ // src/renderer.js
7189
+ var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
7190
+
7191
+ class Renderer {
7192
+ constructor(comps, getSeqInfo, cache) {
7193
+ this.comps = comps;
7194
+ this.getSeqInfo = getSeqInfo ?? basicGetSeqInfo;
7195
+ this.cache = cache ?? new WeakMapDomCache;
7196
+ }
7197
+ renderTag(tag, attrs, childs) {
7198
+ return h(tag, attrs, childs);
7139
7199
  }
7140
- get nodeType() {
7141
- return 1;
7200
+ renderFragment(childs) {
7201
+ return new VFragment(childs);
7142
7202
  }
7143
- isEqualTo(other) {
7144
- if (!(other instanceof VNode2) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
7145
- return false;
7146
- }
7147
- for (const key in this.attrs) {
7148
- if (this.attrs[key] !== other.attrs[key]) {
7149
- return false;
7150
- }
7151
- }
7152
- for (const key in other.attrs) {
7153
- if (!Object.hasOwn(this.attrs, key)) {
7154
- return false;
7155
- }
7156
- }
7157
- return childsEqual(this.childs, other.childs);
7203
+ renderComment(text) {
7204
+ return new VComment(text);
7158
7205
  }
7159
- toDom(opts) {
7160
- const doc = opts.document;
7161
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
7162
- applyProperties(node, this.attrs, {});
7163
- appendChildNodes(node, this.childs, opts);
7164
- return node;
7206
+ setNullCache() {
7207
+ this.cache = new NullDomCache;
7165
7208
  }
7166
- }
7167
- function diffProps(a, b) {
7168
- let diff = null;
7169
- for (const aKey in a) {
7170
- if (!Object.hasOwn(b, aKey)) {
7171
- diff ??= {};
7172
- diff[aKey] = undefined;
7173
- continue;
7174
- }
7175
- const aValue = a[aKey];
7176
- const bValue = b[aKey];
7177
- if (aValue === bValue)
7178
- continue;
7179
- if (isObject(aValue) && isObject(bValue)) {
7180
- if (prototypesDiffer(bValue, aValue)) {
7181
- diff ??= {};
7182
- diff[aKey] = bValue;
7183
- } else {
7184
- const objectDiff = diffProps(aValue, bValue);
7185
- if (objectDiff) {
7186
- diff ??= {};
7187
- diff[aKey] = objectDiff;
7209
+ renderToDOM(stack, val) {
7210
+ const rootNode = document.createElement("div");
7211
+ render(h("div", null, [this.renderRoot(stack, val)]), rootNode, { document });
7212
+ return rootNode.childNodes[0];
7213
+ }
7214
+ renderToString(stack, val, cleanAttrs = true) {
7215
+ const dom = this.renderToDOM(stack, val);
7216
+ if (cleanAttrs) {
7217
+ const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
7218
+ for (const { dataset } of nodes) {
7219
+ for (const name of DATASET_ATTRS) {
7220
+ delete dataset[name];
7188
7221
  }
7189
7222
  }
7190
- } else {
7191
- diff ??= {};
7192
- diff[aKey] = bValue;
7193
- }
7194
- }
7195
- for (const bKey in b) {
7196
- if (!Object.hasOwn(a, bKey)) {
7197
- diff ??= {};
7198
- diff[bKey] = b[bKey];
7199
7223
  }
7224
+ return dom.innerHTML;
7200
7225
  }
7201
- return diff;
7202
- }
7203
- function morphNode(domNode, source, target, opts) {
7204
- if (source === target || source.isEqualTo(target))
7205
- return domNode;
7206
- const type = source.nodeType;
7207
- if (type === target.nodeType) {
7208
- if (type === 3 || type === 8) {
7209
- domNode.data = target.text;
7210
- return domNode;
7211
- }
7212
- if (type === 1 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
7213
- const propsDiff = diffProps(source.attrs, target.attrs);
7214
- if (propsDiff)
7215
- applyProperties(domNode, propsDiff, source.attrs);
7216
- if (!target.attrs.dangerouslySetInnerHTML) {
7217
- morphChildren(domNode, source.childs, target.childs, opts);
7218
- }
7219
- return domNode;
7220
- }
7221
- if (type === 11) {
7222
- morphChildren(domNode, source.childs, target.childs, opts);
7223
- return domNode;
7224
- }
7226
+ renderRoot(stack, val, viewName = null) {
7227
+ const comp = this.comps.getCompFor(val);
7228
+ const nid = comp.getView(viewName).anode.nodeId ?? null;
7229
+ return comp ? this._rValComp(stack, val, comp, nid, "ROOT", viewName) : null;
7225
7230
  }
7226
- const newNode = target.toDom(opts);
7227
- domNode.parentNode?.replaceChild(newNode, domNode);
7228
- return newNode;
7229
- }
7230
- function morphChildren(parentDom, oldChilds, newChilds, opts) {
7231
- if (oldChilds.length === 0) {
7232
- appendChildNodes(parentDom, newChilds, opts);
7233
- return;
7231
+ renderIt(stack, nodeId, key, viewName) {
7232
+ const comp = this.comps.getCompFor(stack.it);
7233
+ return comp ? this._rValComp(stack, stack.it, comp, nodeId, key, viewName) : null;
7234
7234
  }
7235
- if (newChilds.length === 0) {
7236
- parentDom.replaceChildren();
7237
- return;
7235
+ _rValComp(stack, val, comp, nid, key, viewName) {
7236
+ const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
7237
+ const cachedNode = this.cache.get(val, cacheKey);
7238
+ if (cachedNode) {
7239
+ return cachedNode;
7240
+ }
7241
+ const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
7242
+ const meta = this._renderMetadata({ $: "Comp", nid });
7243
+ const dom = new VFragment([meta, this.renderView(view, stack)]);
7244
+ this.cache.set(val, cacheKey, dom);
7245
+ return dom;
7238
7246
  }
7239
- const domNodes = Array.from(parentDom.childNodes);
7240
- const oldKeyMap = Object.create(null);
7241
- for (let i = 0;i < oldChilds.length; i++) {
7242
- const key = getKey(oldChilds[i]);
7243
- if (key != null)
7244
- oldKeyMap[key] = i;
7247
+ pushEachEntry(r, nid, attrName, key, dom) {
7248
+ r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
7245
7249
  }
7246
- const used = new Uint8Array(oldChilds.length);
7247
- let unkeyedCursor = 0;
7248
- for (let j = 0;j < newChilds.length; j++) {
7249
- const newChild = newChilds[j];
7250
- const newKey = getKey(newChild);
7251
- let oldIdx = -1;
7252
- if (newKey != null) {
7253
- if (newKey in oldKeyMap && !used[oldKeyMap[newKey]]) {
7254
- oldIdx = oldKeyMap[newKey];
7255
- }
7256
- } else {
7257
- while (unkeyedCursor < oldChilds.length) {
7258
- if (!used[unkeyedCursor] && getKey(oldChilds[unkeyedCursor]) == null) {
7259
- oldIdx = unkeyedCursor++;
7260
- break;
7261
- }
7262
- unkeyedCursor++;
7250
+ renderEach(stack, iterInfo, nodeId, viewName) {
7251
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
7252
+ const [attrName, gen] = this.getSeqInfo(seq);
7253
+ const r = [];
7254
+ const iterData = loopWith.call(stack.it, seq);
7255
+ for (const [key, value] of gen(seq)) {
7256
+ if (filter.call(stack.it, key, value, iterData)) {
7257
+ const newStack = stack.enter(value, { key }, true);
7258
+ const dom = this.renderIt(newStack, nodeId, key, viewName);
7259
+ this.pushEachEntry(r, nodeId, attrName, key, dom);
7263
7260
  }
7264
7261
  }
7265
- if (oldIdx >= 0) {
7266
- used[oldIdx] = 1;
7267
- const newDom = morphNode(domNodes[oldIdx], oldChilds[oldIdx], newChild, opts);
7268
- const ref = parentDom.childNodes[j] ?? null;
7269
- if (newDom !== ref)
7270
- parentDom.insertBefore(newDom, ref);
7271
- } else {
7272
- const ref = parentDom.childNodes[j] ?? null;
7273
- parentDom.insertBefore(newChild.toDom(opts), ref);
7274
- }
7262
+ return r;
7275
7263
  }
7276
- for (let i = oldChilds.length - 1;i >= 0; i--) {
7277
- if (!used[i] && domNodes[i].parentNode === parentDom) {
7278
- parentDom.removeChild(domNodes[i]);
7264
+ renderEachWhen(stack, iterInfo, view, nid) {
7265
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
7266
+ const [attrName, gen] = this.getSeqInfo(seq);
7267
+ const r = [];
7268
+ const iterData = loopWith.call(stack.it, seq);
7269
+ for (const [key, value] of gen(seq)) {
7270
+ if (filter.call(stack.it, key, value, iterData)) {
7271
+ const bindings = { key, value };
7272
+ const cacheKey = `${nid}-${key}`;
7273
+ let cachedNode;
7274
+ if (enricher) {
7275
+ enricher.call(stack.it, bindings, key, value, iterData);
7276
+ cachedNode = this.cache.get2(stack.it, value, cacheKey);
7277
+ } else {
7278
+ cachedNode = this.cache.get(value, cacheKey);
7279
+ }
7280
+ if (cachedNode) {
7281
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
7282
+ continue;
7283
+ }
7284
+ const newStack = stack.enter(value, bindings, false);
7285
+ const dom = this.renderView(view, newStack);
7286
+ this.pushEachEntry(r, nid, attrName, key, dom);
7287
+ if (enricher) {
7288
+ this.cache.set2(stack.it, value, cacheKey, dom);
7289
+ } else {
7290
+ this.cache.set(value, cacheKey, dom);
7291
+ }
7292
+ }
7279
7293
  }
7294
+ return r;
7280
7295
  }
7281
- }
7282
- var renderCache = new WeakMap;
7283
- function render(vnode, container, options) {
7284
- const cached = renderCache.get(container);
7285
- const isFragment = vnode instanceof VFragment;
7286
- if (cached && cached.vnode instanceof VFragment === isFragment) {
7287
- const oldDom = isFragment ? container : cached.dom;
7288
- const newDom = morphNode(oldDom, cached.vnode, vnode, options);
7289
- renderCache.set(container, { vnode, dom: isFragment ? container : newDom });
7290
- return newDom;
7291
- }
7292
- renderCache.delete(container);
7293
- const domNode = vnode.toDom(options);
7294
- container.replaceChildren(domNode);
7295
- renderCache.set(container, { vnode, dom: isFragment ? container : domNode });
7296
- return domNode;
7297
- }
7298
- function h(tagName, properties, children) {
7299
- const tag = tagName.toUpperCase();
7300
- const props = {};
7301
- let key, namespace;
7302
- if (properties) {
7303
- for (const propName in properties) {
7304
- const propVal = properties[propName];
7305
- switch (propName) {
7306
- case "key":
7307
- key = propVal;
7308
- break;
7309
- case "namespace":
7310
- namespace = propVal;
7311
- break;
7312
- case "class":
7313
- props.className = propVal;
7314
- break;
7315
- case "for":
7316
- props.htmlFor = propVal;
7296
+ renderView(view, stack) {
7297
+ if (stack.binds.tail !== null) {
7298
+ for (const binds of stack.binds.tail) {
7299
+ if (!binds.isFrame)
7300
+ continue;
7301
+ if (stack.it !== binds.it)
7317
7302
  break;
7318
- default:
7319
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
7303
+ console.error("recursion detected", stack.it, binds.it);
7304
+ return new VComment("RECURSION AVOIDED");
7320
7305
  }
7321
7306
  }
7307
+ return view.render(stack, this);
7322
7308
  }
7323
- const normalizedChildren = [];
7324
- addChild(normalizedChildren, children);
7325
- return new VNode2(tag, props, normalizedChildren, key, namespace);
7309
+ _renderMetadata(info) {
7310
+ return new VComment(`§${JSON.stringify(info)}§`);
7311
+ }
7312
+ }
7313
+ function* imIndexedEntries(seq) {
7314
+ let i = 0;
7315
+ for (const v of seq)
7316
+ yield [i++, v];
7317
+ }
7318
+ function* imKeyedEntries(obj) {
7319
+ for (const [key, value] of obj.toSeq().entries())
7320
+ yield [key, value];
7321
+ }
7322
+ var seqInfoByClass = new Map;
7323
+ var idxInfo = ["si", imIndexedEntries];
7324
+ var keyInfo = ["sk", imKeyedEntries];
7325
+ var unkInfo = ["si", function* nullEntries(_obj) {}];
7326
+ function basicGetSeqInfo(seq) {
7327
+ return isIndexed(seq) ? idxInfo : isKeyed(seq) ? keyInfo : seqInfoByClass.get(seq?.constructor) ?? unkInfo;
7326
7328
  }
7327
7329
  // src/oo.js
7328
7330
  var BAD_VALUE = Symbol("BadValue");
@@ -7739,12 +7741,8 @@ var toNode = (nodeOrSelector) => typeof nodeOrSelector === "string" ? document.q
7739
7741
  function tutuca(nodeOrSelector) {
7740
7742
  const rootNode = toNode(nodeOrSelector);
7741
7743
  const comps = new Components;
7742
- const fragment = (childs) => new VFragment(childs);
7743
- const comment = (text) => new VComment(text);
7744
- const ropts = { document };
7745
- const render1 = (vnode, cont) => render(vnode, cont, ropts);
7746
- const renderer = new Renderer(comps, h, fragment, comment, render1);
7747
- return new App(rootNode, render1, comps, renderer, ParseContext);
7744
+ const renderer = new Renderer(comps);
7745
+ return new App(rootNode, comps, renderer, ParseContext);
7748
7746
  }
7749
7747
  export {
7750
7748
  version,