@farm.js/react 0.1.0-beta.3 → 0.1.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,23 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
8
  var React__default = /*#__PURE__*/_interopDefault(React);
9
9
 
10
+ // src/compiler-runtime.tsx
11
+
12
+ // src/iterable.ts
13
+ var oneShotSnapshots = /* @__PURE__ */ new WeakMap();
14
+ function materializeIterable(source) {
15
+ if (source == null) return [];
16
+ const iterator = source[Symbol.iterator]();
17
+ const oneShot = iterator === source && (typeof source === "object" || typeof source === "function");
18
+ if (oneShot) {
19
+ const cached = oneShotSnapshots.get(source);
20
+ if (cached) return cached;
21
+ }
22
+ const items = Array.from({ [Symbol.iterator]: () => iterator });
23
+ if (oneShot) oneShotSnapshots.set(source, items);
24
+ return items;
25
+ }
26
+
10
27
  // src/compiler-runtime.tsx
11
28
  var COMPILER_HMR_REGISTRY = /* @__PURE__ */ Symbol.for("@farm.js/react/compiler-hmr-registry");
12
29
  function getCompilerHmrRegistry() {
@@ -22,6 +39,11 @@ function renderTextValue(value) {
22
39
  if (value === null || value === void 0 || typeof value === "boolean") return "";
23
40
  return String(value);
24
41
  }
42
+ function isCompilerPrimitive(value) {
43
+ if (value === null) return true;
44
+ const kind = typeof value;
45
+ return kind === "string" || kind === "number" || kind === "boolean" || kind === "bigint" || kind === "undefined";
46
+ }
25
47
  function findBindingTarget(root, path, blockRoots) {
26
48
  let current = root;
27
49
  for (const index of path) {
@@ -260,14 +282,19 @@ function createCompilerHostElement(document, descriptor) {
260
282
  updateAttribute(element, attribute.name, attribute.value);
261
283
  }
262
284
  for (const style of descriptor.styles) updateStyle(element, style.name, style.value);
263
- for (const child of descriptor.children) {
285
+ const appendChild = (child) => {
286
+ if (Array.isArray(child)) {
287
+ for (const nested of child) appendChild(nested);
288
+ return;
289
+ }
264
290
  if (isCompilerHostElement(child)) {
265
291
  element.append(createCompilerHostElement(document, child));
266
- continue;
292
+ return;
267
293
  }
268
294
  const text = renderTextValue(child);
269
295
  if (text) element.append(document.createTextNode(text));
270
- }
296
+ };
297
+ for (const child of materializeCompilerHostChildren(descriptor)) appendChild(child);
271
298
  for (const attribute of descriptor.attributes) {
272
299
  if (attribute.name === "value" && (isSelectElement(element) || isTextAreaElement(element))) {
273
300
  updateAttribute(element, attribute.name, attribute.value);
@@ -277,18 +304,110 @@ function createCompilerHostElement(document, descriptor) {
277
304
  }
278
305
  function matchesCompilerHostElement(element, descriptor, opaquePaths = /* @__PURE__ */ new Set(), path = []) {
279
306
  if (element.tagName.toLowerCase() !== descriptor.tag.toLowerCase()) return false;
280
- if (opaquePaths.has(path.join("."))) return true;
281
- const expectedChildren = descriptor.children.filter(isCompilerHostElement);
307
+ if (opaquePaths.has(path.join(".")) || descriptor.block) return true;
308
+ const expectedChildren = flattenCompilerHostElements(descriptor.children);
282
309
  if (element.children.length !== expectedChildren.length) return false;
283
310
  return expectedChildren.every(
284
311
  (child, index) => matchesCompilerHostElement(element.children[index], child, opaquePaths, [...path, index])
285
312
  );
286
313
  }
314
+ function flattenCompilerHostElements(children) {
315
+ const elements = [];
316
+ const visit = (child) => {
317
+ if (Array.isArray(child)) {
318
+ for (const nested of child) visit(nested);
319
+ } else if (isCompilerHostElement(child)) {
320
+ elements.push(child);
321
+ }
322
+ };
323
+ for (const child of children) visit(child);
324
+ return elements;
325
+ }
326
+ function materializeCompilerHostChildren(descriptor) {
327
+ const block = descriptor.block;
328
+ if (block?.kind !== "keyed-ranges" || !block.staticChildrenOnly) {
329
+ return descriptor.children;
330
+ }
331
+ const staticChildren = flattenCompilerHostElements(descriptor.children);
332
+ const children = [];
333
+ let cursor = 0;
334
+ for (const range of block.ranges) {
335
+ children.push(...staticChildren.slice(cursor, cursor + range.before));
336
+ cursor += range.before;
337
+ const items = materializeIterable(range.items());
338
+ children.push(...items.map((item, index) => range.create(item, index)));
339
+ }
340
+ children.push(...staticChildren.slice(cursor, cursor + block.trailing));
341
+ return children;
342
+ }
343
+ function collectCompilerHostBlockIds(descriptor, ids) {
344
+ for (const child of flattenCompilerHostElements(descriptor.children)) {
345
+ collectCompilerHostBlockIds(child, ids);
346
+ }
347
+ const block = descriptor.block;
348
+ if (!block || ids.has(block.id)) return;
349
+ ids.add(block.id);
350
+ if (block.kind === "conditional-ranges") {
351
+ for (const range of block.ranges) {
352
+ if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
353
+ if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
354
+ }
355
+ } else if (block.kind === "keyed-ranges") {
356
+ for (const range of block.ranges) {
357
+ const first = materializeIterable(range.items())[0];
358
+ if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
359
+ }
360
+ } else {
361
+ for (const range of block.ranges) {
362
+ if (range.kind === "conditional") {
363
+ if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
364
+ if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
365
+ } else {
366
+ const first = materializeIterable(range.items())[0];
367
+ if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
368
+ }
369
+ }
370
+ }
371
+ }
287
372
  function findCompilerHostTarget(root, path) {
288
373
  let current = root;
289
374
  for (const index of path) current = current?.children[index] || null;
290
375
  return current;
291
376
  }
377
+ var UNSET_STATIC_RANGE_BINDING = /* @__PURE__ */ Symbol("unset static range binding");
378
+ function normalizedStaticRangeBindingValue(binding, value) {
379
+ return binding.kind === "text" ? renderTextValue(value) : value;
380
+ }
381
+ function applyStaticRangeBindings(bindings, segments, values) {
382
+ const activeBindings = bindings || [];
383
+ if (values.length === 0 && activeBindings.length > 0) {
384
+ values.push(...activeBindings.map(() => UNSET_STATIC_RANGE_BINDING));
385
+ }
386
+ if (values.length !== activeBindings.length) return false;
387
+ for (let index = 0; index < activeBindings.length; index += 1) {
388
+ const binding = activeBindings[index];
389
+ if (!Number.isSafeInteger(binding.segment) || binding.segment < 0 || !Number.isSafeInteger(binding.sibling) || binding.sibling < 0) {
390
+ return false;
391
+ }
392
+ const sibling = segments[binding.segment]?.[binding.sibling];
393
+ const target = sibling && findCompilerHostTarget(sibling, binding.path);
394
+ if (!target) return false;
395
+ const rawValue = binding.read();
396
+ const value = normalizedStaticRangeBindingValue(binding, rawValue);
397
+ if (Object.is(values[index], value)) continue;
398
+ values[index] = value;
399
+ if (binding.kind === "text") {
400
+ target.textContent = value;
401
+ } else if (binding.kind === "style" && binding.name) {
402
+ updateStyle(target, binding.name, rawValue);
403
+ } else if (binding.kind === "attribute" && binding.name) {
404
+ updateAttribute(target, binding.name, rawValue);
405
+ } else {
406
+ return false;
407
+ }
408
+ }
409
+ return true;
410
+ }
292
411
  var UNSET_KEYED_ROW_BINDING = /* @__PURE__ */ Symbol("unset interactive keyed-row binding");
293
412
  function keyedRowIdentity(key) {
294
413
  return String(key);
@@ -303,20 +422,23 @@ function readKeyedRowBindingValues(props, item, index) {
303
422
  }
304
423
  function applyKeyedRowBindings(props, instance, item, index) {
305
424
  for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
306
- const binding = props.bindings[bindingIndex];
307
- const rawValue = binding.read(item, index);
308
- const value = normalizedKeyedRowBindingValue(binding, rawValue);
309
- if (Object.is(instance.values[bindingIndex], value)) continue;
310
- instance.values[bindingIndex] = value;
311
- const target = findCompilerHostTarget(instance.element, binding.path);
312
- if (!target) continue;
313
- if (binding.kind === "text") {
314
- target.textContent = value;
315
- } else if (binding.kind === "style" && binding.name) {
316
- updateStyle(target, binding.name, rawValue);
317
- } else if (binding.kind === "attribute" && binding.name) {
318
- updateAttribute(target, binding.name, rawValue);
319
- }
425
+ applyKeyedRowBinding(props, instance, item, index, bindingIndex);
426
+ }
427
+ }
428
+ function applyKeyedRowBinding(props, instance, item, index, bindingIndex) {
429
+ const binding = props.bindings[bindingIndex];
430
+ const rawValue = binding.read(item, index);
431
+ const value = normalizedKeyedRowBindingValue(binding, rawValue);
432
+ if (Object.is(instance.values[bindingIndex], value)) return;
433
+ instance.values[bindingIndex] = value;
434
+ const target = findCompilerHostTarget(instance.element, binding.path);
435
+ if (!target) return;
436
+ if (binding.kind === "text") {
437
+ target.textContent = value;
438
+ } else if (binding.kind === "style" && binding.name) {
439
+ updateStyle(target, binding.name, rawValue);
440
+ } else if (binding.kind === "attribute" && binding.name) {
441
+ updateAttribute(target, binding.name, rawValue);
320
442
  }
321
443
  }
322
444
  function keyedRowConditionalSnapshot(conditional, item, index) {
@@ -335,13 +457,15 @@ function keyedRowConditionalSnapshot(conditional, item, index) {
335
457
  ];
336
458
  }
337
459
  function readKeyedRowConditionalValues(props, item, index) {
460
+ if (!props.conditionals?.length) return EMPTY_KEYED_ROW_CONDITIONAL_VALUES;
338
461
  return new Map(
339
- (props.conditionals || []).map((conditional) => [
462
+ props.conditionals.map((conditional) => [
340
463
  conditional.id,
341
464
  keyedRowConditionalSnapshot(conditional, item, index)
342
465
  ])
343
466
  );
344
467
  }
468
+ var EMPTY_KEYED_ROW_CONDITIONAL_VALUES = /* @__PURE__ */ new Map();
345
469
  function keyedRowConditionalChanged(previous, next) {
346
470
  return !previous || previous.length !== next.length || next.some((value, index) => !Object.is(value, previous[index]));
347
471
  }
@@ -358,11 +482,6 @@ function hostConditionalSelection(props) {
358
482
  function normalizedHostConditionalBindingValue(binding, value) {
359
483
  return binding.kind === "text" ? renderTextValue(value) : value;
360
484
  }
361
- function readHostConditionalBindingValues(branch) {
362
- return branch.bindings.map(
363
- (binding) => normalizedHostConditionalBindingValue(binding, binding.read())
364
- );
365
- }
366
485
  function applyHostConditionalBindings(branch, instance) {
367
486
  for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
368
487
  const binding = branch.bindings[bindingIndex];
@@ -381,6 +500,903 @@ function applyHostConditionalBindings(branch, instance) {
381
500
  }
382
501
  }
383
502
  }
503
+ var UNSET_HOST_CONDITIONAL_BINDING = /* @__PURE__ */ Symbol("unset host conditional binding");
504
+ function mountCompilerHostTree(owner, element, descriptor, onFallback) {
505
+ if (!matchesCompilerHostElement(element, descriptor)) return null;
506
+ if (descriptor.block?.kind === "conditional-ranges") {
507
+ const controller = new CompilerNestedConditionalRanges(
508
+ owner,
509
+ element,
510
+ descriptor,
511
+ descriptor.block,
512
+ onFallback
513
+ );
514
+ try {
515
+ if (controller.adopt()) return controller;
516
+ controller.cleanup();
517
+ return null;
518
+ } catch (error) {
519
+ controller.cleanup();
520
+ throw error;
521
+ }
522
+ }
523
+ if (descriptor.block?.kind === "keyed-ranges") {
524
+ const controller = new CompilerNestedKeyedRanges(
525
+ owner,
526
+ element,
527
+ descriptor,
528
+ descriptor.block,
529
+ onFallback
530
+ );
531
+ try {
532
+ if (controller.adopt()) return controller;
533
+ controller.cleanup();
534
+ return null;
535
+ } catch (error) {
536
+ controller.cleanup();
537
+ throw error;
538
+ }
539
+ }
540
+ if (descriptor.block?.kind === "mixed-ranges") {
541
+ const controller = new CompilerNestedMixedRanges(
542
+ owner,
543
+ element,
544
+ descriptor,
545
+ descriptor.block,
546
+ onFallback
547
+ );
548
+ try {
549
+ if (controller.adopt()) return controller;
550
+ controller.cleanup();
551
+ return null;
552
+ } catch (error) {
553
+ controller.cleanup();
554
+ throw error;
555
+ }
556
+ }
557
+ const descriptors = flattenCompilerHostElements(descriptor.children);
558
+ if (descriptors.length !== element.children.length) return null;
559
+ const scopes = [];
560
+ for (let index = 0; index < descriptors.length; index += 1) {
561
+ const scope = mountCompilerHostTree(
562
+ owner,
563
+ element.children[index],
564
+ descriptors[index],
565
+ onFallback
566
+ );
567
+ if (!scope) {
568
+ for (const mounted of scopes) mounted.cleanup();
569
+ return null;
570
+ }
571
+ scopes.push(scope);
572
+ }
573
+ let active = true;
574
+ return {
575
+ update(nextDescriptor) {
576
+ if (!active || nextDescriptor.block || !matchesCompilerHostElement(element, nextDescriptor)) {
577
+ return false;
578
+ }
579
+ const nextChildren = flattenCompilerHostElements(nextDescriptor.children);
580
+ if (nextChildren.length !== scopes.length) return false;
581
+ return scopes.every((scope, index) => scope.update(nextChildren[index]));
582
+ },
583
+ cleanup() {
584
+ if (!active) return;
585
+ active = false;
586
+ for (const scope of scopes) scope.cleanup();
587
+ }
588
+ };
589
+ }
590
+ function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback) {
591
+ const scope = mountCompilerHostTree(owner, element, descriptor, onFallback);
592
+ if (!scope) return null;
593
+ const instance = {
594
+ element,
595
+ scope,
596
+ values: branch.bindings.map(() => UNSET_HOST_CONDITIONAL_BINDING)
597
+ };
598
+ try {
599
+ applyHostConditionalBindings(branch, instance);
600
+ } catch (error) {
601
+ scope.cleanup();
602
+ throw error;
603
+ }
604
+ return instance;
605
+ }
606
+ var CompilerNestedConditionalRanges = class {
607
+ constructor(owner, root, host, block, onFallback) {
608
+ this.owner = owner;
609
+ this.root = root;
610
+ this.host = host;
611
+ this.block = block;
612
+ this.onFallback = onFallback;
613
+ this.instances = [];
614
+ this.staticSegments = [];
615
+ this.staticScopes = [];
616
+ this.staticValues = [];
617
+ this.active = true;
618
+ this.refresh = (afterCommit) => {
619
+ if (!this.active) {
620
+ afterCommit?.();
621
+ return;
622
+ }
623
+ const selections = this.readSelections();
624
+ if (!selections || selections.length !== this.instances.length) {
625
+ this.onFallback();
626
+ afterCommit?.();
627
+ return;
628
+ }
629
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
630
+ this.onFallback();
631
+ afterCommit?.();
632
+ return;
633
+ }
634
+ for (let index = this.instances.length - 1; index >= 0; index -= 1) {
635
+ if (!this.reconcileRange(index, selections[index])) {
636
+ this.onFallback();
637
+ afterCommit?.();
638
+ return;
639
+ }
640
+ }
641
+ afterCommit?.();
642
+ };
643
+ }
644
+ readSelections() {
645
+ const selections = [];
646
+ for (const range of this.block.ranges) {
647
+ const selection = hostConditionalSelection(range);
648
+ if (selection.kind === "fallback") return null;
649
+ selections.push(selection);
650
+ }
651
+ return selections;
652
+ }
653
+ mountStatic(elements, descriptors) {
654
+ if (elements.length !== descriptors.length) return false;
655
+ for (let index = 0; index < elements.length; index += 1) {
656
+ const scope = mountCompilerHostTree(
657
+ this.owner,
658
+ elements[index],
659
+ descriptors[index],
660
+ this.onFallback
661
+ );
662
+ if (!scope) return false;
663
+ this.staticScopes.push(scope);
664
+ }
665
+ return true;
666
+ }
667
+ adopt() {
668
+ if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
669
+ const selections = this.readSelections();
670
+ if (!selections) return false;
671
+ const elements = [...this.root.children];
672
+ const descriptors = flattenCompilerHostElements(this.host.children);
673
+ if (elements.length !== descriptors.length) return false;
674
+ let cursor = 0;
675
+ for (let index = 0; index < this.block.ranges.length; index += 1) {
676
+ const range = this.block.ranges[index];
677
+ if (!Number.isSafeInteger(range.before) || range.before < 0) {
678
+ this.cleanup();
679
+ return false;
680
+ }
681
+ const staticEnd = cursor + range.before;
682
+ if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
683
+ this.cleanup();
684
+ return false;
685
+ }
686
+ this.staticSegments.push(elements.slice(cursor, staticEnd));
687
+ cursor = staticEnd;
688
+ const selection = selections[index];
689
+ if (selection.kind === "empty") {
690
+ this.instances.push(null);
691
+ continue;
692
+ }
693
+ const element = elements[cursor];
694
+ if (!element) {
695
+ this.cleanup();
696
+ return false;
697
+ }
698
+ const descriptor = selection.branch.create();
699
+ const host = mountCompilerHostInstance(
700
+ this.owner,
701
+ element,
702
+ descriptor,
703
+ selection.branch,
704
+ this.onFallback
705
+ );
706
+ if (!host) {
707
+ this.cleanup();
708
+ return false;
709
+ }
710
+ this.instances.push({ key: selection.key, host });
711
+ cursor += 1;
712
+ }
713
+ const trailingEnd = cursor + this.block.trailing;
714
+ if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
715
+ this.cleanup();
716
+ return false;
717
+ }
718
+ this.staticSegments.push(elements.slice(cursor));
719
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
720
+ this.cleanup();
721
+ return false;
722
+ }
723
+ this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
724
+ return true;
725
+ }
726
+ anchorAfter(rangeIndex) {
727
+ for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
728
+ const staticAnchor = this.staticSegments[next]?.[0];
729
+ if (staticAnchor) return staticAnchor;
730
+ const rangeAnchor = this.instances[next]?.host.element;
731
+ if (rangeAnchor) return rangeAnchor;
732
+ }
733
+ return this.staticSegments[this.instances.length]?.[0] || null;
734
+ }
735
+ reconcileRange(rangeIndex, selection) {
736
+ const previous = this.instances[rangeIndex];
737
+ if (selection.kind === "empty") {
738
+ previous?.host.scope?.cleanup();
739
+ previous?.host.element.remove();
740
+ this.instances[rangeIndex] = null;
741
+ return true;
742
+ }
743
+ if (previous?.key === selection.key) {
744
+ const descriptor2 = selection.branch.create();
745
+ if (!previous.host.scope?.update(descriptor2)) return false;
746
+ applyHostConditionalBindings(selection.branch, previous.host);
747
+ return true;
748
+ }
749
+ const descriptor = selection.branch.create();
750
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
751
+ const host = mountCompilerHostInstance(
752
+ this.owner,
753
+ element,
754
+ descriptor,
755
+ selection.branch,
756
+ this.onFallback
757
+ );
758
+ if (!host) return false;
759
+ previous?.host.scope?.cleanup();
760
+ if (previous) previous.host.element.replaceWith(element);
761
+ else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
762
+ this.instances[rangeIndex] = { key: selection.key, host };
763
+ return true;
764
+ }
765
+ updateStaticScopes(descriptor, selections) {
766
+ const descriptors = flattenCompilerHostElements(descriptor.children);
767
+ let descriptorIndex = 0;
768
+ let scopeIndex = 0;
769
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
770
+ const range = this.block.ranges[rangeIndex];
771
+ for (let index = 0; index < range.before; index += 1) {
772
+ const scope = this.staticScopes[scopeIndex++];
773
+ const child = descriptors[descriptorIndex++];
774
+ if (!scope || !child || !scope.update(child)) return false;
775
+ }
776
+ if (selections[rangeIndex].kind === "branch") descriptorIndex += 1;
777
+ }
778
+ for (let index = 0; index < this.block.trailing; index += 1) {
779
+ const scope = this.staticScopes[scopeIndex++];
780
+ const child = descriptors[descriptorIndex++];
781
+ if (!scope || !child || !scope.update(child)) return false;
782
+ }
783
+ return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
784
+ }
785
+ update(descriptor) {
786
+ const block = descriptor.block;
787
+ if (!this.active || block?.kind !== "conditional-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
788
+ return false;
789
+ }
790
+ this.host = descriptor;
791
+ this.block = block;
792
+ const selections = this.readSelections();
793
+ if (!selections || !this.updateStaticScopes(descriptor, selections) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
794
+ return false;
795
+ }
796
+ for (let index = this.instances.length - 1; index >= 0; index -= 1) {
797
+ if (!this.reconcileRange(index, selections[index])) return false;
798
+ }
799
+ return true;
800
+ }
801
+ cleanup() {
802
+ if (!this.active) return;
803
+ this.active = false;
804
+ this.unsubscribe?.();
805
+ for (const instance of this.instances) instance?.host.scope?.cleanup();
806
+ for (const scope of this.staticScopes) scope.cleanup();
807
+ this.instances.length = 0;
808
+ this.staticSegments.length = 0;
809
+ this.staticScopes.length = 0;
810
+ this.staticValues.length = 0;
811
+ }
812
+ };
813
+ var CompilerNestedKeyedRanges = class {
814
+ constructor(owner, root, host, block, onFallback) {
815
+ this.owner = owner;
816
+ this.root = root;
817
+ this.host = host;
818
+ this.block = block;
819
+ this.onFallback = onFallback;
820
+ this.instances = [];
821
+ this.staticSegments = [];
822
+ this.staticScopes = [];
823
+ this.staticValues = [];
824
+ this.active = true;
825
+ this.refresh = (afterCommit) => {
826
+ if (!this.active) {
827
+ afterCommit?.();
828
+ return;
829
+ }
830
+ const rowsByRange = this.readRanges();
831
+ if (!rowsByRange || rowsByRange.length !== this.instances.length) {
832
+ this.onFallback();
833
+ afterCommit?.();
834
+ return;
835
+ }
836
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
837
+ this.onFallback();
838
+ afterCommit?.();
839
+ return;
840
+ }
841
+ const activeElement = this.root.ownerDocument.activeElement;
842
+ const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
843
+ for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
844
+ if (!this.reconcileRange(index, rowsByRange[index])) {
845
+ this.onFallback();
846
+ afterCommit?.();
847
+ return;
848
+ }
849
+ }
850
+ if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
851
+ activeElement.focus({ preventScroll: true });
852
+ }
853
+ afterCommit?.();
854
+ };
855
+ }
856
+ readRange(range) {
857
+ const items = materializeIterable(range.items());
858
+ const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
859
+ return new Set(keys).size === keys.length ? { items, keys } : null;
860
+ }
861
+ readRanges() {
862
+ const ranges = [];
863
+ for (const range of this.block.ranges) {
864
+ const rows = this.readRange(range);
865
+ if (!rows) return null;
866
+ ranges.push(rows);
867
+ }
868
+ return ranges;
869
+ }
870
+ mountStatic(elements, descriptors) {
871
+ if (elements.length !== descriptors.length) return false;
872
+ for (let index = 0; index < elements.length; index += 1) {
873
+ const scope = mountCompilerHostTree(
874
+ this.owner,
875
+ elements[index],
876
+ descriptors[index],
877
+ this.onFallback
878
+ );
879
+ if (!scope) return false;
880
+ this.staticScopes.push(scope);
881
+ }
882
+ return true;
883
+ }
884
+ adopt() {
885
+ if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
886
+ const rowsByRange = this.readRanges();
887
+ if (!rowsByRange) return false;
888
+ const elements = [...this.root.children];
889
+ const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(this.host));
890
+ if (elements.length !== descriptors.length) return false;
891
+ let cursor = 0;
892
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
893
+ const range = this.block.ranges[rangeIndex];
894
+ const rows = rowsByRange[rangeIndex];
895
+ if (!Number.isSafeInteger(range.before) || range.before < 0) {
896
+ this.cleanup();
897
+ return false;
898
+ }
899
+ const staticEnd = cursor + range.before;
900
+ if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
901
+ this.cleanup();
902
+ return false;
903
+ }
904
+ this.staticSegments.push(elements.slice(cursor, staticEnd));
905
+ cursor = staticEnd;
906
+ const instances = /* @__PURE__ */ new Map();
907
+ for (let index = 0; index < rows.items.length; index += 1) {
908
+ const element = elements[cursor + index];
909
+ if (!element) {
910
+ this.cleanup();
911
+ return false;
912
+ }
913
+ const descriptor = range.create(rows.items[index], index);
914
+ const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
915
+ if (!scope) {
916
+ this.cleanup();
917
+ return false;
918
+ }
919
+ instances.set(rows.keys[index], {
920
+ key: rows.keys[index],
921
+ element,
922
+ scope,
923
+ values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
924
+ item: rows.items[index],
925
+ index,
926
+ conditionalValues: /* @__PURE__ */ new Map()
927
+ });
928
+ applyKeyedRowBindings(range, instances.get(rows.keys[index]), rows.items[index], index);
929
+ }
930
+ this.instances.push(instances);
931
+ cursor += rows.items.length;
932
+ }
933
+ const trailingEnd = cursor + this.block.trailing;
934
+ if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
935
+ this.cleanup();
936
+ return false;
937
+ }
938
+ this.staticSegments.push(elements.slice(cursor));
939
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
940
+ this.cleanup();
941
+ return false;
942
+ }
943
+ this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
944
+ return true;
945
+ }
946
+ anchorAfter(rangeIndex) {
947
+ for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
948
+ const staticAnchor = this.staticSegments[next]?.[0];
949
+ if (staticAnchor) return staticAnchor;
950
+ const rowAnchor = this.instances[next].values().next().value?.element;
951
+ if (rowAnchor) return rowAnchor;
952
+ }
953
+ return this.staticSegments[this.instances.length]?.[0] || null;
954
+ }
955
+ reconcileRange(rangeIndex, rows) {
956
+ const range = this.block.ranges[rangeIndex];
957
+ const previous = this.instances[rangeIndex];
958
+ const oldIndices = /* @__PURE__ */ new Map();
959
+ [...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
960
+ const nextKeys = new Set(rows.keys);
961
+ for (const [key, instance] of previous) {
962
+ if (nextKeys.has(key)) continue;
963
+ instance.scope?.cleanup();
964
+ instance.element.remove();
965
+ }
966
+ const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
967
+ const stablePositions = longestIncreasingSubsequencePositions(sequence);
968
+ const nextInstances = [];
969
+ for (let index = 0; index < rows.items.length; index += 1) {
970
+ const key = rows.keys[index];
971
+ const existing = previous.get(key);
972
+ if (existing) {
973
+ const descriptor2 = range.create(rows.items[index], index);
974
+ if (!existing.scope?.update(descriptor2)) return false;
975
+ applyKeyedRowBindings(range, existing, rows.items[index], index);
976
+ existing.item = rows.items[index];
977
+ existing.index = index;
978
+ nextInstances.push(existing);
979
+ continue;
980
+ }
981
+ const descriptor = range.create(rows.items[index], index);
982
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
983
+ const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
984
+ if (!scope) return false;
985
+ nextInstances.push({
986
+ key,
987
+ element,
988
+ scope,
989
+ values: readKeyedRowBindingValues(range, rows.items[index], index),
990
+ item: rows.items[index],
991
+ index,
992
+ conditionalValues: /* @__PURE__ */ new Map()
993
+ });
994
+ }
995
+ let anchor = this.anchorAfter(rangeIndex);
996
+ for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
997
+ const instance = nextInstances[index];
998
+ if (sequence[index] < 0 || !stablePositions.has(index) && instance.element.nextSibling !== anchor) {
999
+ this.root.insertBefore(instance.element, anchor);
1000
+ }
1001
+ anchor = instance.element;
1002
+ }
1003
+ this.instances[rangeIndex] = new Map(nextInstances.map((instance) => [instance.key, instance]));
1004
+ return true;
1005
+ }
1006
+ updateStaticScopes(descriptor, rowsByRange) {
1007
+ const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(descriptor));
1008
+ let descriptorIndex = 0;
1009
+ let scopeIndex = 0;
1010
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
1011
+ const range = this.block.ranges[rangeIndex];
1012
+ for (let index = 0; index < range.before; index += 1) {
1013
+ const scope = this.staticScopes[scopeIndex++];
1014
+ const child = descriptors[descriptorIndex++];
1015
+ if (!scope || !child || !scope.update(child)) return false;
1016
+ }
1017
+ descriptorIndex += rowsByRange[rangeIndex].items.length;
1018
+ }
1019
+ for (let index = 0; index < this.block.trailing; index += 1) {
1020
+ const scope = this.staticScopes[scopeIndex++];
1021
+ const child = descriptors[descriptorIndex++];
1022
+ if (!scope || !child || !scope.update(child)) return false;
1023
+ }
1024
+ return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
1025
+ }
1026
+ update(descriptor) {
1027
+ const block = descriptor.block;
1028
+ if (!this.active || block?.kind !== "keyed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
1029
+ return false;
1030
+ }
1031
+ this.host = descriptor;
1032
+ this.block = block;
1033
+ const rowsByRange = this.readRanges();
1034
+ if (!rowsByRange || rowsByRange.length !== this.instances.length || !this.updateStaticScopes(descriptor, rowsByRange) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
1035
+ return false;
1036
+ }
1037
+ for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
1038
+ if (!this.reconcileRange(index, rowsByRange[index])) return false;
1039
+ }
1040
+ return true;
1041
+ }
1042
+ cleanup() {
1043
+ if (!this.active) return;
1044
+ this.active = false;
1045
+ this.unsubscribe?.();
1046
+ for (const instances of this.instances) {
1047
+ for (const instance of instances.values()) instance.scope?.cleanup();
1048
+ }
1049
+ for (const scope of this.staticScopes) scope.cleanup();
1050
+ this.instances.length = 0;
1051
+ this.staticSegments.length = 0;
1052
+ this.staticScopes.length = 0;
1053
+ this.staticValues.length = 0;
1054
+ }
1055
+ };
1056
+ var CompilerNestedMixedRanges = class {
1057
+ constructor(owner, root, host, block, onFallback) {
1058
+ this.owner = owner;
1059
+ this.root = root;
1060
+ this.host = host;
1061
+ this.block = block;
1062
+ this.onFallback = onFallback;
1063
+ this.instances = [];
1064
+ this.staticSegments = [];
1065
+ this.staticScopes = [];
1066
+ this.staticValues = [];
1067
+ this.active = true;
1068
+ this.refresh = (afterCommit) => {
1069
+ if (!this.active) {
1070
+ afterCommit?.();
1071
+ return;
1072
+ }
1073
+ const snapshots = this.readSnapshots();
1074
+ if (!snapshots || snapshots.length !== this.instances.length) {
1075
+ this.onFallback();
1076
+ afterCommit?.();
1077
+ return;
1078
+ }
1079
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
1080
+ this.onFallback();
1081
+ afterCommit?.();
1082
+ return;
1083
+ }
1084
+ const activeElement = this.root.ownerDocument.activeElement;
1085
+ const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
1086
+ for (let index = snapshots.length - 1; index >= 0; index -= 1) {
1087
+ if (!this.reconcileRange(index, snapshots[index])) {
1088
+ this.onFallback();
1089
+ afterCommit?.();
1090
+ return;
1091
+ }
1092
+ }
1093
+ if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
1094
+ activeElement.focus({ preventScroll: true });
1095
+ }
1096
+ afterCommit?.();
1097
+ };
1098
+ }
1099
+ readSnapshots() {
1100
+ const snapshots = [];
1101
+ for (const range of this.block.ranges) {
1102
+ if (range.kind === "conditional") {
1103
+ const selection = hostConditionalSelection(range);
1104
+ if (selection.kind === "fallback") return null;
1105
+ snapshots.push({ kind: "conditional", selection });
1106
+ continue;
1107
+ }
1108
+ const items = materializeIterable(range.items());
1109
+ const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
1110
+ if (new Set(keys).size !== keys.length) return null;
1111
+ snapshots.push({ kind: "keyed", rows: { items, keys } });
1112
+ }
1113
+ return snapshots;
1114
+ }
1115
+ mountStatic(elements, descriptors) {
1116
+ if (elements.length !== descriptors.length) return false;
1117
+ for (let index = 0; index < elements.length; index += 1) {
1118
+ const scope = mountCompilerHostTree(
1119
+ this.owner,
1120
+ elements[index],
1121
+ descriptors[index],
1122
+ this.onFallback
1123
+ );
1124
+ if (!scope) return false;
1125
+ this.staticScopes.push(scope);
1126
+ }
1127
+ return true;
1128
+ }
1129
+ adopt() {
1130
+ if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
1131
+ const snapshots = this.readSnapshots();
1132
+ if (!snapshots) return false;
1133
+ const elements = [...this.root.children];
1134
+ const descriptors = flattenCompilerHostElements(this.host.children);
1135
+ if (elements.length !== descriptors.length) return false;
1136
+ let cursor = 0;
1137
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
1138
+ const range = this.block.ranges[rangeIndex];
1139
+ const snapshot = snapshots[rangeIndex];
1140
+ if (!Number.isSafeInteger(range.before) || range.before < 0 || range.kind !== snapshot.kind) {
1141
+ this.cleanup();
1142
+ return false;
1143
+ }
1144
+ const staticEnd = cursor + range.before;
1145
+ if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
1146
+ this.cleanup();
1147
+ return false;
1148
+ }
1149
+ this.staticSegments.push(elements.slice(cursor, staticEnd));
1150
+ cursor = staticEnd;
1151
+ if (range.kind === "conditional" && snapshot.kind === "conditional") {
1152
+ if (snapshot.selection.kind === "empty") {
1153
+ this.instances.push({ kind: "conditional", value: null });
1154
+ continue;
1155
+ }
1156
+ const element = elements[cursor];
1157
+ if (!element) {
1158
+ this.cleanup();
1159
+ return false;
1160
+ }
1161
+ const descriptor = snapshot.selection.branch.create();
1162
+ const host = mountCompilerHostInstance(
1163
+ this.owner,
1164
+ element,
1165
+ descriptor,
1166
+ snapshot.selection.branch,
1167
+ this.onFallback
1168
+ );
1169
+ if (!host) {
1170
+ this.cleanup();
1171
+ return false;
1172
+ }
1173
+ this.instances.push({
1174
+ kind: "conditional",
1175
+ value: { key: snapshot.selection.key, host }
1176
+ });
1177
+ cursor += 1;
1178
+ continue;
1179
+ }
1180
+ if (range.kind !== "keyed" || snapshot.kind !== "keyed") {
1181
+ this.cleanup();
1182
+ return false;
1183
+ }
1184
+ const keyedInstances = /* @__PURE__ */ new Map();
1185
+ for (let index = 0; index < snapshot.rows.items.length; index += 1) {
1186
+ const element = elements[cursor + index];
1187
+ if (!element) {
1188
+ this.cleanup();
1189
+ return false;
1190
+ }
1191
+ const descriptor = range.create(snapshot.rows.items[index], index);
1192
+ const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
1193
+ if (!scope) {
1194
+ this.cleanup();
1195
+ return false;
1196
+ }
1197
+ const instance = {
1198
+ key: snapshot.rows.keys[index],
1199
+ element,
1200
+ scope,
1201
+ values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
1202
+ item: snapshot.rows.items[index],
1203
+ index,
1204
+ conditionalValues: /* @__PURE__ */ new Map()
1205
+ };
1206
+ try {
1207
+ applyKeyedRowBindings(range, instance, snapshot.rows.items[index], index);
1208
+ } catch (error) {
1209
+ scope.cleanup();
1210
+ throw error;
1211
+ }
1212
+ keyedInstances.set(snapshot.rows.keys[index], instance);
1213
+ }
1214
+ this.instances.push({ kind: "keyed", value: keyedInstances });
1215
+ cursor += snapshot.rows.items.length;
1216
+ }
1217
+ const trailingEnd = cursor + this.block.trailing;
1218
+ if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
1219
+ this.cleanup();
1220
+ return false;
1221
+ }
1222
+ this.staticSegments.push(elements.slice(cursor));
1223
+ if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
1224
+ this.cleanup();
1225
+ return false;
1226
+ }
1227
+ this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
1228
+ return true;
1229
+ }
1230
+ firstInstanceElement(instance) {
1231
+ if (instance.kind === "conditional") return instance.value?.host.element || null;
1232
+ return instance.value.values().next().value?.element || null;
1233
+ }
1234
+ anchorAfter(rangeIndex) {
1235
+ for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
1236
+ const staticAnchor = this.staticSegments[next]?.[0];
1237
+ if (staticAnchor) return staticAnchor;
1238
+ const rangeAnchor = this.firstInstanceElement(this.instances[next]);
1239
+ if (rangeAnchor) return rangeAnchor;
1240
+ }
1241
+ return this.staticSegments[this.instances.length]?.[0] || null;
1242
+ }
1243
+ reconcileConditional(rangeIndex, range, selection) {
1244
+ const instance = this.instances[rangeIndex];
1245
+ if (instance.kind !== "conditional") return false;
1246
+ const previous = instance.value;
1247
+ if (selection.kind === "empty") {
1248
+ previous?.host.scope?.cleanup();
1249
+ previous?.host.element.remove();
1250
+ instance.value = null;
1251
+ return true;
1252
+ }
1253
+ if (previous?.key === selection.key) {
1254
+ const descriptor2 = selection.branch.create();
1255
+ if (!previous.host.scope?.update(descriptor2)) return false;
1256
+ applyHostConditionalBindings(selection.branch, previous.host);
1257
+ return true;
1258
+ }
1259
+ const descriptor = selection.branch.create();
1260
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
1261
+ const host = mountCompilerHostInstance(
1262
+ this.owner,
1263
+ element,
1264
+ descriptor,
1265
+ selection.branch,
1266
+ this.onFallback
1267
+ );
1268
+ if (!host) return false;
1269
+ previous?.host.scope?.cleanup();
1270
+ if (previous) previous.host.element.replaceWith(element);
1271
+ else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
1272
+ instance.value = { key: selection.key, host };
1273
+ return true;
1274
+ }
1275
+ reconcileKeyed(rangeIndex, range, rows) {
1276
+ const instance = this.instances[rangeIndex];
1277
+ if (instance.kind !== "keyed") return false;
1278
+ const previous = instance.value;
1279
+ const oldIndices = /* @__PURE__ */ new Map();
1280
+ [...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
1281
+ const nextKeys = new Set(rows.keys);
1282
+ for (const [key, row] of previous) {
1283
+ if (nextKeys.has(key)) continue;
1284
+ row.scope?.cleanup();
1285
+ row.element.remove();
1286
+ }
1287
+ const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
1288
+ const stablePositions = longestIncreasingSubsequencePositions(sequence);
1289
+ const nextInstances = [];
1290
+ for (let index = 0; index < rows.items.length; index += 1) {
1291
+ const key = rows.keys[index];
1292
+ const existing = previous.get(key);
1293
+ if (existing) {
1294
+ const descriptor2 = range.create(rows.items[index], index);
1295
+ if (!existing.scope?.update(descriptor2)) return false;
1296
+ applyKeyedRowBindings(range, existing, rows.items[index], index);
1297
+ existing.item = rows.items[index];
1298
+ existing.index = index;
1299
+ nextInstances.push(existing);
1300
+ continue;
1301
+ }
1302
+ const descriptor = range.create(rows.items[index], index);
1303
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
1304
+ const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
1305
+ if (!scope) return false;
1306
+ let values;
1307
+ try {
1308
+ values = readKeyedRowBindingValues(range, rows.items[index], index);
1309
+ } catch (error) {
1310
+ scope.cleanup();
1311
+ throw error;
1312
+ }
1313
+ nextInstances.push({
1314
+ key,
1315
+ element,
1316
+ scope,
1317
+ values,
1318
+ item: rows.items[index],
1319
+ index,
1320
+ conditionalValues: /* @__PURE__ */ new Map()
1321
+ });
1322
+ }
1323
+ let anchor = this.anchorAfter(rangeIndex);
1324
+ for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
1325
+ const row = nextInstances[index];
1326
+ if (sequence[index] < 0 || !stablePositions.has(index) && row.element.nextSibling !== anchor) {
1327
+ this.root.insertBefore(row.element, anchor);
1328
+ }
1329
+ anchor = row.element;
1330
+ }
1331
+ instance.value = new Map(nextInstances.map((row) => [row.key, row]));
1332
+ return true;
1333
+ }
1334
+ reconcileRange(rangeIndex, snapshot) {
1335
+ const range = this.block.ranges[rangeIndex];
1336
+ if (range.kind !== snapshot.kind) return false;
1337
+ return range.kind === "conditional" && snapshot.kind === "conditional" ? this.reconcileConditional(rangeIndex, range, snapshot.selection) : range.kind === "keyed" && snapshot.kind === "keyed" ? this.reconcileKeyed(rangeIndex, range, snapshot.rows) : false;
1338
+ }
1339
+ updateStaticScopes(descriptor, snapshots) {
1340
+ const descriptors = flattenCompilerHostElements(descriptor.children);
1341
+ let descriptorIndex = 0;
1342
+ let scopeIndex = 0;
1343
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
1344
+ const range = this.block.ranges[rangeIndex];
1345
+ for (let index = 0; index < range.before; index += 1) {
1346
+ const scope = this.staticScopes[scopeIndex++];
1347
+ const child = descriptors[descriptorIndex++];
1348
+ if (!scope || !child || !scope.update(child)) return false;
1349
+ }
1350
+ const snapshot = snapshots[rangeIndex];
1351
+ if (snapshot.kind === "conditional") {
1352
+ if (snapshot.selection.kind === "branch") descriptorIndex += 1;
1353
+ } else {
1354
+ descriptorIndex += snapshot.rows.items.length;
1355
+ }
1356
+ }
1357
+ for (let index = 0; index < this.block.trailing; index += 1) {
1358
+ const scope = this.staticScopes[scopeIndex++];
1359
+ const child = descriptors[descriptorIndex++];
1360
+ if (!scope || !child || !scope.update(child)) return false;
1361
+ }
1362
+ return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
1363
+ }
1364
+ update(descriptor) {
1365
+ const block = descriptor.block;
1366
+ if (!this.active || block?.kind !== "mixed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some(
1367
+ (range, index) => range.kind !== this.block.ranges[index].kind || range.before !== this.block.ranges[index].before
1368
+ )) {
1369
+ return false;
1370
+ }
1371
+ this.host = descriptor;
1372
+ this.block = block;
1373
+ const snapshots = this.readSnapshots();
1374
+ if (!snapshots || snapshots.length !== this.instances.length || !this.updateStaticScopes(descriptor, snapshots) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
1375
+ return false;
1376
+ }
1377
+ for (let index = snapshots.length - 1; index >= 0; index -= 1) {
1378
+ if (!this.reconcileRange(index, snapshots[index])) return false;
1379
+ }
1380
+ return true;
1381
+ }
1382
+ cleanup() {
1383
+ if (!this.active) return;
1384
+ this.active = false;
1385
+ this.unsubscribe?.();
1386
+ for (const instance of this.instances) {
1387
+ if (instance.kind === "conditional") {
1388
+ instance.value?.host.scope?.cleanup();
1389
+ } else {
1390
+ for (const row of instance.value.values()) row.scope?.cleanup();
1391
+ }
1392
+ }
1393
+ for (const scope of this.staticScopes) scope.cleanup();
1394
+ this.instances.length = 0;
1395
+ this.staticSegments.length = 0;
1396
+ this.staticScopes.length = 0;
1397
+ this.staticValues.length = 0;
1398
+ }
1399
+ };
384
1400
  function createHostConditionalBlockComponent(owner) {
385
1401
  class FarmHostConditionalBlock extends React__default.default.Component {
386
1402
  constructor() {
@@ -392,8 +1408,13 @@ function createHostConditionalBlockComponent(owner) {
392
1408
  this.fallbackVersion = 0;
393
1409
  this.propSyncQueued = false;
394
1410
  this.currentProps = this.props;
1411
+ this.fallbackUnsubscribers = [];
395
1412
  this.activeBranch = null;
396
1413
  this.instance = null;
1414
+ this.requestNestedFallback = () => {
1415
+ this.instance?.scope?.cleanup();
1416
+ this.activateFallback();
1417
+ };
397
1418
  this.captureRoot = (root) => {
398
1419
  this.root = root;
399
1420
  };
@@ -401,6 +1422,26 @@ function createHostConditionalBlockComponent(owner) {
401
1422
  this.reconcile(afterCommit);
402
1423
  };
403
1424
  }
1425
+ subscribeFallbackDescendants() {
1426
+ for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
1427
+ this.fallbackUnsubscribers = [];
1428
+ const ids = /* @__PURE__ */ new Set();
1429
+ if (this.currentProps.truthy) {
1430
+ collectCompilerHostBlockIds(this.currentProps.truthy.create(), ids);
1431
+ }
1432
+ if (this.currentProps.falsy) {
1433
+ collectCompilerHostBlockIds(this.currentProps.falsy.create(), ids);
1434
+ }
1435
+ ids.delete(this.currentProps.id);
1436
+ for (const id of ids) {
1437
+ this.fallbackUnsubscribers.push(
1438
+ owner.subscribe(id, (afterCommit) => {
1439
+ this.fallbackVersion += 1;
1440
+ this.forceUpdate(afterCommit);
1441
+ })
1442
+ );
1443
+ }
1444
+ }
404
1445
  adopt() {
405
1446
  if (!this.root) return false;
406
1447
  const selection = hostConditionalSelection(this.currentProps);
@@ -417,11 +1458,16 @@ function createHostConditionalBlockComponent(owner) {
417
1458
  const descriptor = selection.branch.create();
418
1459
  const element = this.root.firstElementChild;
419
1460
  if (!matchesCompilerHostElement(element, descriptor)) return false;
420
- this.activeBranch = selection.key;
421
- this.instance = {
1461
+ const instance = mountCompilerHostInstance(
1462
+ owner,
422
1463
  element,
423
- values: readHostConditionalBindingValues(selection.branch)
424
- };
1464
+ descriptor,
1465
+ selection.branch,
1466
+ this.requestNestedFallback
1467
+ );
1468
+ if (!instance) return false;
1469
+ this.activeBranch = selection.key;
1470
+ this.instance = instance;
425
1471
  return true;
426
1472
  }
427
1473
  activateFallback(afterCommit) {
@@ -430,6 +1476,10 @@ function createHostConditionalBlockComponent(owner) {
430
1476
  return;
431
1477
  }
432
1478
  this.fallbackRequested = true;
1479
+ this.instance?.scope?.cleanup();
1480
+ this.instance = null;
1481
+ this.activeBranch = null;
1482
+ this.subscribeFallbackDescendants();
433
1483
  this.fallbackVersion += 1;
434
1484
  this.setState({ fallback: true }, afterCommit);
435
1485
  }
@@ -448,6 +1498,7 @@ function createHostConditionalBlockComponent(owner) {
448
1498
  return;
449
1499
  }
450
1500
  if (selection.kind === "empty") {
1501
+ this.instance?.scope?.cleanup();
451
1502
  if (this.instance) this.instance.element.remove();
452
1503
  this.activeBranch = null;
453
1504
  this.instance = null;
@@ -455,17 +1506,40 @@ function createHostConditionalBlockComponent(owner) {
455
1506
  return;
456
1507
  }
457
1508
  if (this.activeBranch === selection.key && this.instance) {
1509
+ const descriptor2 = selection.branch.create();
1510
+ const scope = mountCompilerHostTree(
1511
+ owner,
1512
+ this.instance.element,
1513
+ descriptor2,
1514
+ this.requestNestedFallback
1515
+ );
1516
+ if (!scope) {
1517
+ this.activateFallback(afterCommit);
1518
+ return;
1519
+ }
1520
+ this.instance.scope?.cleanup();
1521
+ this.instance.scope = scope;
458
1522
  applyHostConditionalBindings(selection.branch, this.instance);
459
1523
  afterCommit?.();
460
1524
  return;
461
1525
  }
462
- const element = createCompilerHostElement(this.root.ownerDocument, selection.branch.create());
1526
+ const descriptor = selection.branch.create();
1527
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
1528
+ const instance = mountCompilerHostInstance(
1529
+ owner,
1530
+ element,
1531
+ descriptor,
1532
+ selection.branch,
1533
+ this.requestNestedFallback
1534
+ );
1535
+ if (!instance) {
1536
+ this.activateFallback(afterCommit);
1537
+ return;
1538
+ }
1539
+ this.instance?.scope?.cleanup();
463
1540
  this.root.replaceChildren(element);
464
1541
  this.activeBranch = selection.key;
465
- this.instance = {
466
- element,
467
- values: readHostConditionalBindingValues(selection.branch)
468
- };
1542
+ this.instance = instance;
469
1543
  afterCommit?.();
470
1544
  }
471
1545
  schedulePropSync() {
@@ -490,6 +1564,9 @@ function createHostConditionalBlockComponent(owner) {
490
1564
  componentWillUnmount() {
491
1565
  this.mounted = false;
492
1566
  this.unsubscribe?.();
1567
+ for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
1568
+ this.fallbackUnsubscribers = [];
1569
+ this.instance?.scope?.cleanup();
493
1570
  this.root = null;
494
1571
  this.activeBranch = null;
495
1572
  this.instance = null;
@@ -521,8 +1598,14 @@ function createConditionalRangesBlockComponent(owner) {
521
1598
  this.fallbackVersion = 0;
522
1599
  this.propFallbackQueued = false;
523
1600
  this.currentProps = this.props;
1601
+ this.fallbackUnsubscribers = [];
524
1602
  this.rangeInstances = [];
525
1603
  this.staticSegments = [];
1604
+ this.staticValues = [];
1605
+ this.requestNestedFallback = () => {
1606
+ for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
1607
+ this.activateFallback();
1608
+ };
526
1609
  this.captureRoot = (root) => {
527
1610
  this.root = root;
528
1611
  this.currentProps.rootRef?.(root);
@@ -531,6 +1614,24 @@ function createConditionalRangesBlockComponent(owner) {
531
1614
  this.reconcile(afterCommit);
532
1615
  };
533
1616
  }
1617
+ subscribeFallbackDescendants() {
1618
+ for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
1619
+ this.fallbackUnsubscribers = [];
1620
+ const ids = /* @__PURE__ */ new Set();
1621
+ for (const range of this.currentProps.ranges) {
1622
+ if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
1623
+ if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
1624
+ }
1625
+ ids.delete(this.currentProps.id);
1626
+ for (const id of ids) {
1627
+ this.fallbackUnsubscribers.push(
1628
+ owner.subscribe(id, (afterCommit) => {
1629
+ this.fallbackVersion += 1;
1630
+ this.forceUpdate(afterCommit);
1631
+ })
1632
+ );
1633
+ }
1634
+ }
534
1635
  readSelections(props) {
535
1636
  const selections = [];
536
1637
  for (const range of props.ranges) {
@@ -547,12 +1648,21 @@ function createConditionalRangesBlockComponent(owner) {
547
1648
  const elements = [...this.root.children];
548
1649
  const staticSegments = [];
549
1650
  const instances = [];
1651
+ const cleanupInstances = () => {
1652
+ for (const instance of instances) instance?.host.scope?.cleanup();
1653
+ };
550
1654
  let cursor = 0;
551
1655
  for (let rangeIndex = 0; rangeIndex < props.ranges.length; rangeIndex += 1) {
552
1656
  const range = props.ranges[rangeIndex];
553
- if (!Number.isSafeInteger(range.before) || range.before < 0) return false;
1657
+ if (!Number.isSafeInteger(range.before) || range.before < 0) {
1658
+ cleanupInstances();
1659
+ return false;
1660
+ }
554
1661
  const staticEnd = cursor + range.before;
555
- if (staticEnd > elements.length) return false;
1662
+ if (staticEnd > elements.length) {
1663
+ cleanupInstances();
1664
+ return false;
1665
+ }
556
1666
  staticSegments.push(elements.slice(cursor, staticEnd));
557
1667
  cursor = staticEnd;
558
1668
  const selection = selections[rangeIndex];
@@ -561,22 +1671,45 @@ function createConditionalRangesBlockComponent(owner) {
561
1671
  continue;
562
1672
  }
563
1673
  const element = elements[cursor];
564
- if (!element) return false;
1674
+ if (!element) {
1675
+ cleanupInstances();
1676
+ return false;
1677
+ }
565
1678
  const descriptor = selection.branch.create();
566
- if (!matchesCompilerHostElement(element, descriptor)) return false;
1679
+ if (!matchesCompilerHostElement(element, descriptor)) {
1680
+ cleanupInstances();
1681
+ return false;
1682
+ }
1683
+ const host = mountCompilerHostInstance(
1684
+ owner,
1685
+ element,
1686
+ descriptor,
1687
+ selection.branch,
1688
+ this.requestNestedFallback
1689
+ );
1690
+ if (!host) {
1691
+ cleanupInstances();
1692
+ return false;
1693
+ }
567
1694
  instances.push({
568
1695
  key: selection.key,
569
- host: {
570
- element,
571
- values: readHostConditionalBindingValues(selection.branch)
572
- }
1696
+ host
573
1697
  });
574
1698
  cursor += 1;
575
1699
  }
576
- if (cursor + props.trailing !== elements.length) return false;
1700
+ if (cursor + props.trailing !== elements.length) {
1701
+ cleanupInstances();
1702
+ return false;
1703
+ }
577
1704
  staticSegments.push(elements.slice(cursor));
578
1705
  this.staticSegments = staticSegments;
579
1706
  this.rangeInstances = instances;
1707
+ if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
1708
+ cleanupInstances();
1709
+ this.rangeInstances = [];
1710
+ this.staticSegments = [];
1711
+ return false;
1712
+ }
580
1713
  return true;
581
1714
  }
582
1715
  anchorAfter(rangeIndex) {
@@ -589,27 +1722,52 @@ function createConditionalRangesBlockComponent(owner) {
589
1722
  return this.staticSegments[this.rangeInstances.length]?.[0] || null;
590
1723
  }
591
1724
  reconcileRange(rangeIndex, selection) {
592
- if (!this.root) return;
1725
+ if (!this.root) return false;
593
1726
  const previous = this.rangeInstances[rangeIndex];
594
1727
  if (selection.kind === "empty") {
1728
+ previous?.host.scope?.cleanup();
595
1729
  previous?.host.element.remove();
596
1730
  this.rangeInstances[rangeIndex] = null;
597
- return;
1731
+ return true;
598
1732
  }
599
1733
  if (previous?.key === selection.key) {
1734
+ const descriptor2 = selection.branch.create();
1735
+ const scope = mountCompilerHostTree(
1736
+ owner,
1737
+ previous.host.element,
1738
+ descriptor2,
1739
+ this.requestNestedFallback
1740
+ );
1741
+ if (!scope) {
1742
+ this.requestNestedFallback();
1743
+ return false;
1744
+ }
1745
+ previous.host.scope?.cleanup();
1746
+ previous.host.scope = scope;
600
1747
  applyHostConditionalBindings(selection.branch, previous.host);
601
- return;
1748
+ return true;
1749
+ }
1750
+ const descriptor = selection.branch.create();
1751
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
1752
+ const host = mountCompilerHostInstance(
1753
+ owner,
1754
+ element,
1755
+ descriptor,
1756
+ selection.branch,
1757
+ this.requestNestedFallback
1758
+ );
1759
+ if (!host) {
1760
+ this.requestNestedFallback();
1761
+ return false;
602
1762
  }
603
- const element = createCompilerHostElement(this.root.ownerDocument, selection.branch.create());
1763
+ previous?.host.scope?.cleanup();
604
1764
  if (previous) previous.host.element.replaceWith(element);
605
1765
  else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
606
1766
  this.rangeInstances[rangeIndex] = {
607
1767
  key: selection.key,
608
- host: {
609
- element,
610
- values: readHostConditionalBindingValues(selection.branch)
611
- }
1768
+ host
612
1769
  };
1770
+ return true;
613
1771
  }
614
1772
  reconcile(afterCommit) {
615
1773
  if (!this.mounted || !this.root) {
@@ -630,8 +1788,19 @@ function createConditionalRangesBlockComponent(owner) {
630
1788
  this.activateFallback(afterCommit);
631
1789
  return;
632
1790
  }
1791
+ if (!applyStaticRangeBindings(
1792
+ this.currentProps.bindings,
1793
+ this.staticSegments,
1794
+ this.staticValues
1795
+ )) {
1796
+ this.activateFallback(afterCommit);
1797
+ return;
1798
+ }
633
1799
  for (let rangeIndex = this.rangeInstances.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
634
- this.reconcileRange(rangeIndex, selections[rangeIndex]);
1800
+ if (!this.reconcileRange(rangeIndex, selections[rangeIndex])) {
1801
+ afterCommit?.();
1802
+ return;
1803
+ }
635
1804
  }
636
1805
  afterCommit?.();
637
1806
  }
@@ -641,6 +1810,8 @@ function createConditionalRangesBlockComponent(owner) {
641
1810
  return;
642
1811
  }
643
1812
  this.fallbackRequested = true;
1813
+ for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
1814
+ this.subscribeFallbackDescendants();
644
1815
  this.setState({ fallback: true }, afterCommit);
645
1816
  }
646
1817
  schedulePropFallback() {
@@ -665,9 +1836,13 @@ function createConditionalRangesBlockComponent(owner) {
665
1836
  componentWillUnmount() {
666
1837
  this.mounted = false;
667
1838
  this.unsubscribe?.();
1839
+ for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
1840
+ this.fallbackUnsubscribers = [];
1841
+ for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
668
1842
  this.root = null;
669
1843
  this.rangeInstances = [];
670
1844
  this.staticSegments = [];
1845
+ this.staticValues.length = 0;
671
1846
  }
672
1847
  render() {
673
1848
  const container = this.currentProps.render();
@@ -708,7 +1883,7 @@ function longestIncreasingSubsequencePositions(sequence) {
708
1883
  }
709
1884
  return positions;
710
1885
  }
711
- function createKeyedRowsBlockComponent(owner) {
1886
+ function createKeyedRowConditionalRuntime() {
712
1887
  class FarmKeyedRowConditional extends React__default.default.Component {
713
1888
  constructor() {
714
1889
  super(...arguments);
@@ -750,6 +1925,22 @@ function createKeyedRowsBlockComponent(owner) {
750
1925
  }
751
1926
  }
752
1927
  FarmKeyedRowConditional.displayName = "FarmCompiledKeyedRowConditional";
1928
+ return {
1929
+ Component: FarmKeyedRowConditional,
1930
+ readValues: readKeyedRowConditionalValues,
1931
+ changed: keyedRowConditionalChanged
1932
+ };
1933
+ }
1934
+ function createKeyedRowHostRuntime() {
1935
+ const owner = {
1936
+ subscribe: () => () => {
1937
+ }
1938
+ };
1939
+ return {
1940
+ mount: (element, descriptor, requestFallback) => mountCompilerHostTree(owner, element, descriptor, requestFallback)
1941
+ };
1942
+ }
1943
+ function createKeyedRowsBlockComponent(owner, options = {}) {
753
1944
  class FarmKeyedRowsBlock extends React__default.default.Component {
754
1945
  constructor() {
755
1946
  super(...arguments);
@@ -765,16 +1956,23 @@ function createKeyedRowsBlockComponent(owner) {
765
1956
  this.renderVersion = 0;
766
1957
  this.eventHandlers = /* @__PURE__ */ new Map();
767
1958
  this.conditionalListeners = /* @__PURE__ */ new Map();
1959
+ this.instancesByElement = /* @__PURE__ */ new WeakMap();
768
1960
  this.conditionalOwner = {
769
1961
  subscribe: (key, id, refresh) => this.subscribeToRowConditional(key, id, refresh)
770
1962
  };
771
1963
  this.captureRoot = (root) => {
772
1964
  this.root = root;
773
1965
  };
1966
+ this.requestHostScopeFallback = () => {
1967
+ this.activateFallback();
1968
+ };
774
1969
  this.rowEvent = (item, index, eventId) => {
775
1970
  if (this.state.fallback) {
776
1971
  return (event) => this.currentProps.events?.[eventId]?.invoke(item, index, event);
777
1972
  }
1973
+ if (this.usesDelegatedEvents()) {
1974
+ return void 0;
1975
+ }
778
1976
  const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
779
1977
  let handlers = this.eventHandlers.get(key);
780
1978
  if (!handlers) {
@@ -792,10 +1990,32 @@ function createKeyedRowsBlockComponent(owner) {
792
1990
  handlers.set(eventId, handler);
793
1991
  return handler;
794
1992
  };
1993
+ this.dispatchDelegatedEvent = (name, event) => {
1994
+ const instance = this.eventRowInstance(event);
1995
+ const eventTarget = event.target;
1996
+ if (!instance || !eventTarget) return;
1997
+ const capture = name.endsWith("Capture");
1998
+ const matches = (this.currentProps.events || []).filter((descriptor) => descriptor.name === name && descriptor.path !== void 0).map((descriptor) => ({
1999
+ descriptor,
2000
+ target: findCompilerHostTarget(instance.element, descriptor.path || [])
2001
+ })).filter(
2002
+ (match) => Boolean(
2003
+ match.target && (match.target === eventTarget || match.target.contains(eventTarget))
2004
+ )
2005
+ ).sort(
2006
+ (left, right) => capture ? (left.descriptor.path?.length || 0) - (right.descriptor.path?.length || 0) : (right.descriptor.path?.length || 0) - (left.descriptor.path?.length || 0)
2007
+ );
2008
+ for (const match of matches) {
2009
+ this.invokeDelegatedEvent(match.descriptor, instance, event, match.target);
2010
+ if (event.isPropagationStopped()) break;
2011
+ }
2012
+ };
795
2013
  this.rowConditional = (item, index, conditionalId, render) => {
796
2014
  if (this.state.fallback) return render(item, index);
797
2015
  const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
798
- return React__default.default.createElement(FarmKeyedRowConditional, {
2016
+ const Conditional = options.conditionals?.Component;
2017
+ if (!Conditional) return render(item, index);
2018
+ return React__default.default.createElement(Conditional, {
799
2019
  key: `${key}:${conditionalId}`,
800
2020
  owner: this.conditionalOwner,
801
2021
  rowKey: key,
@@ -806,17 +2026,65 @@ function createKeyedRowsBlockComponent(owner) {
806
2026
  render
807
2027
  });
808
2028
  };
809
- this.refresh = (afterCommit) => {
2029
+ this.refresh = (afterCommit, dirtyState) => {
2030
+ if (dirtyState && this.refreshDirtyBindings(dirtyState, afterCommit)) return;
810
2031
  this.reconcile(afterCommit);
811
2032
  };
812
2033
  }
813
2034
  readRows(props) {
814
- const source = props.items();
815
- const items = source ? Array.from(source) : [];
2035
+ const items = materializeIterable(props.items());
816
2036
  const keys = items.map((item, index) => keyedRowIdentity(props.rowKey(item, index)));
817
2037
  if (new Set(keys).size !== keys.length) return null;
818
2038
  return { items, keys };
819
2039
  }
2040
+ usesDelegatedEvents(props = this.currentProps) {
2041
+ return Boolean(
2042
+ props.delegateEvents && props.events?.length && props.events.every((event) => event.path !== void 0)
2043
+ );
2044
+ }
2045
+ rebuildElementIndex(instances) {
2046
+ this.instancesByElement = /* @__PURE__ */ new WeakMap();
2047
+ for (const instance of instances.values()) {
2048
+ this.instancesByElement.set(instance.element, instance);
2049
+ }
2050
+ }
2051
+ eventRowInstance(event) {
2052
+ if (!this.root) return void 0;
2053
+ const target = event.target;
2054
+ if (!target) return void 0;
2055
+ let element = target.nodeType === 1 ? target : target.parentElement;
2056
+ while (element && element.parentElement !== this.root) element = element.parentElement;
2057
+ return element?.parentElement === this.root ? this.instancesByElement.get(element) : void 0;
2058
+ }
2059
+ invokeDelegatedEvent(descriptor, instance, event, currentTarget) {
2060
+ const ownCurrentTarget = Object.getOwnPropertyDescriptor(event, "currentTarget");
2061
+ try {
2062
+ Object.defineProperty(event, "currentTarget", {
2063
+ configurable: true,
2064
+ value: currentTarget
2065
+ });
2066
+ descriptor.invoke(instance.item, instance.index, event);
2067
+ } finally {
2068
+ if (ownCurrentTarget) Object.defineProperty(event, "currentTarget", ownCurrentTarget);
2069
+ else Reflect.deleteProperty(event, "currentTarget");
2070
+ }
2071
+ }
2072
+ delegatedContainerProps(container) {
2073
+ if (this.state.fallback || !this.usesDelegatedEvents()) return {};
2074
+ const props = container.props;
2075
+ return Object.fromEntries(
2076
+ [...new Set((this.currentProps.events || []).map((event) => event.name))].map((name) => {
2077
+ const existing = props[name];
2078
+ const capture = name.endsWith("Capture");
2079
+ const handler = (event) => {
2080
+ if (capture) existing?.(event);
2081
+ if (!event.isPropagationStopped()) this.dispatchDelegatedEvent(name, event);
2082
+ if (!capture && !event.isPropagationStopped()) existing?.(event);
2083
+ };
2084
+ return [name, handler];
2085
+ })
2086
+ );
2087
+ }
820
2088
  subscribeToRowConditional(key, id, refresh) {
821
2089
  let listeners = this.conditionalListeners.get(key);
822
2090
  if (!listeners) {
@@ -832,7 +2100,19 @@ function createKeyedRowsBlockComponent(owner) {
832
2100
  };
833
2101
  }
834
2102
  hasReactOwnedRows(props = this.currentProps) {
835
- return Boolean(props.events?.length || props.conditionals?.length);
2103
+ return Boolean(
2104
+ props.conditionals?.length || props.events?.length && !this.usesDelegatedEvents(props)
2105
+ );
2106
+ }
2107
+ cleanupHostScopes(instances = this.instances) {
2108
+ for (const instance of instances.values()) instance.scope?.cleanup();
2109
+ }
2110
+ mountRowHostScope(element, descriptor, props = this.currentProps) {
2111
+ if (!props.hostBlocks) return void 0;
2112
+ return options.hostBlocks?.mount(element, descriptor, this.requestHostScopeFallback) || null;
2113
+ }
2114
+ readConditionalValues(props, item, index) {
2115
+ return options.conditionals?.readValues(props, item, index) || EMPTY_KEYED_ROW_CONDITIONAL_VALUES;
836
2116
  }
837
2117
  pruneEventHandlers(keys) {
838
2118
  const active = new Set(keys);
@@ -856,20 +2136,24 @@ function createKeyedRowsBlockComponent(owner) {
856
2136
  );
857
2137
  const instances = /* @__PURE__ */ new Map();
858
2138
  for (let index = 0; index < rows.items.length; index += 1) {
859
- if (this.hasReactOwnedRows() && !matchesCompilerHostElement(
860
- elements[index],
861
- this.currentProps.create(rows.items[index], index),
862
- opaqueConditionalPaths
863
- )) {
2139
+ const descriptor = this.currentProps.create(rows.items[index], index);
2140
+ if (this.hasReactOwnedRows() && !matchesCompilerHostElement(elements[index], descriptor, opaqueConditionalPaths)) {
2141
+ this.cleanupHostScopes(instances);
2142
+ return false;
2143
+ }
2144
+ const scope = this.mountRowHostScope(elements[index], descriptor);
2145
+ if (this.currentProps.hostBlocks && !scope) {
2146
+ this.cleanupHostScopes(instances);
864
2147
  return false;
865
2148
  }
866
2149
  const instance = {
867
2150
  key: rows.keys[index],
868
2151
  element: elements[index],
2152
+ scope: scope || void 0,
869
2153
  values: this.hasReactOwnedRows() ? this.currentProps.bindings.map(() => UNSET_KEYED_ROW_BINDING) : readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
870
2154
  item: rows.items[index],
871
2155
  index,
872
- conditionalValues: readKeyedRowConditionalValues(
2156
+ conditionalValues: this.readConditionalValues(
873
2157
  this.currentProps,
874
2158
  rows.items[index],
875
2159
  index
@@ -880,7 +2164,9 @@ function createKeyedRowsBlockComponent(owner) {
880
2164
  }
881
2165
  instances.set(rows.keys[index], instance);
882
2166
  }
2167
+ this.cleanupHostScopes();
883
2168
  this.instances = instances;
2169
+ this.rebuildElementIndex(instances);
884
2170
  this.pruneEventHandlers(rows.keys);
885
2171
  this.pruneConditionalListeners(rows.keys);
886
2172
  return true;
@@ -899,6 +2185,7 @@ function createKeyedRowsBlockComponent(owner) {
899
2185
  }
900
2186
  this.fallbackRequested = true;
901
2187
  this.fallbackKeysWereUnsafe = this.hasUnsafeFallbackKeys();
2188
+ this.cleanupHostScopes();
902
2189
  this.fallbackVersion += 1;
903
2190
  this.setState({ fallback: true }, afterCommit);
904
2191
  }
@@ -933,6 +2220,116 @@ function createKeyedRowsBlockComponent(owner) {
933
2220
  }
934
2221
  });
935
2222
  }
2223
+ refreshDirtyBindings(dirtyState, afterCommit) {
2224
+ if (!this.mounted || !this.root || this.state.fallback || this.hasReactOwnedRows() || this.currentProps.hostBlocks || !this.currentProps.structureDependencies || this.currentProps.structureDependencies.some((dependency) => dirtyState.has(dependency)) || this.currentProps.bindings.some((binding) => binding.dependencies === void 0)) {
2225
+ return false;
2226
+ }
2227
+ const affectedBindingIndices = [];
2228
+ for (let bindingIndex = 0; bindingIndex < this.currentProps.bindings.length; bindingIndex += 1) {
2229
+ const dependencies = this.currentProps.bindings[bindingIndex].dependencies || [];
2230
+ if (dependencies.some((dependency) => dirtyState.has(dependency))) {
2231
+ affectedBindingIndices.push(bindingIndex);
2232
+ }
2233
+ }
2234
+ for (const instance of this.instances.values()) {
2235
+ for (const bindingIndex of affectedBindingIndices) {
2236
+ applyKeyedRowBinding(
2237
+ this.currentProps,
2238
+ instance,
2239
+ instance.item,
2240
+ instance.index,
2241
+ bindingIndex
2242
+ );
2243
+ }
2244
+ }
2245
+ afterCommit?.();
2246
+ return true;
2247
+ }
2248
+ reconcileStableRows(rows, afterCommit) {
2249
+ if (rows.keys.length !== this.instances.size) return false;
2250
+ let index = 0;
2251
+ for (const key of this.instances.keys()) {
2252
+ if (rows.keys[index] !== key) return false;
2253
+ index += 1;
2254
+ }
2255
+ const conditionalChanges = [];
2256
+ for (index = 0; index < rows.items.length; index += 1) {
2257
+ const key = rows.keys[index];
2258
+ const existing = this.instances.get(key);
2259
+ if (!existing) return false;
2260
+ if (this.currentProps.hostBlocks) {
2261
+ const descriptor = this.currentProps.create(rows.items[index], index);
2262
+ if (!existing.scope?.update(descriptor)) {
2263
+ this.activateFallback(afterCommit);
2264
+ return true;
2265
+ }
2266
+ }
2267
+ applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
2268
+ const conditionalValues = this.readConditionalValues(
2269
+ this.currentProps,
2270
+ rows.items[index],
2271
+ index
2272
+ );
2273
+ for (const [id, values] of conditionalValues) {
2274
+ if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
2275
+ conditionalChanges.push({ key, id, item: rows.items[index], index });
2276
+ }
2277
+ }
2278
+ existing.conditionalValues = conditionalValues;
2279
+ existing.item = rows.items[index];
2280
+ existing.index = index;
2281
+ }
2282
+ this.notifyConditionalChanges(conditionalChanges, afterCommit);
2283
+ return true;
2284
+ }
2285
+ reconcileSingleRemoval(rows, afterCommit) {
2286
+ if (this.hasReactOwnedRows() || rows.keys.length + 1 !== this.instances.size) return false;
2287
+ const previousKeys = [...this.instances.keys()];
2288
+ let removedIndex = 0;
2289
+ while (removedIndex < rows.keys.length && previousKeys[removedIndex] === rows.keys[removedIndex]) {
2290
+ removedIndex += 1;
2291
+ }
2292
+ for (let index = removedIndex; index < rows.keys.length; index += 1) {
2293
+ if (previousKeys[index + 1] !== rows.keys[index]) return false;
2294
+ }
2295
+ const removedKey = previousKeys[removedIndex];
2296
+ const removed = this.instances.get(removedKey);
2297
+ if (!removed) return false;
2298
+ const conditionalChanges = [];
2299
+ for (let index = 0; index < rows.items.length; index += 1) {
2300
+ const key = rows.keys[index];
2301
+ const existing = this.instances.get(key);
2302
+ if (!existing) return false;
2303
+ if (this.currentProps.hostBlocks) {
2304
+ const descriptor = this.currentProps.create(rows.items[index], index);
2305
+ if (!existing.scope?.update(descriptor)) {
2306
+ this.activateFallback(afterCommit);
2307
+ return true;
2308
+ }
2309
+ }
2310
+ applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
2311
+ const conditionalValues = this.readConditionalValues(
2312
+ this.currentProps,
2313
+ rows.items[index],
2314
+ index
2315
+ );
2316
+ for (const [id, values] of conditionalValues) {
2317
+ if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
2318
+ conditionalChanges.push({ key, id, item: rows.items[index], index });
2319
+ }
2320
+ }
2321
+ existing.conditionalValues = conditionalValues;
2322
+ existing.item = rows.items[index];
2323
+ existing.index = index;
2324
+ }
2325
+ removed.scope?.cleanup();
2326
+ removed.element.remove();
2327
+ this.instances.delete(removedKey);
2328
+ this.eventHandlers.delete(removedKey);
2329
+ this.conditionalListeners.delete(removedKey);
2330
+ this.notifyConditionalChanges(conditionalChanges, afterCommit);
2331
+ return true;
2332
+ }
936
2333
  reconcile(afterCommit) {
937
2334
  if (!this.mounted || !this.root) {
938
2335
  afterCommit?.();
@@ -952,35 +2349,62 @@ function createKeyedRowsBlockComponent(owner) {
952
2349
  this.activateFallback(afterCommit);
953
2350
  return;
954
2351
  }
955
- const previousKeys = [...this.instances.keys()];
956
- if (this.hasReactOwnedRows() && (rows.keys.length !== previousKeys.length || rows.keys.some((key, index) => key !== previousKeys[index]))) {
957
- this.synchronizeReactOwnedRows(afterCommit);
2352
+ if (this.hasReactOwnedRows()) {
2353
+ const previousKeys = [...this.instances.keys()];
2354
+ if (rows.keys.length !== previousKeys.length || rows.keys.some((key, index) => key !== previousKeys[index])) {
2355
+ this.synchronizeReactOwnedRows(afterCommit);
2356
+ return;
2357
+ }
2358
+ }
2359
+ if (rows.items.length === 0) {
2360
+ this.cleanupHostScopes();
2361
+ this.root.replaceChildren();
2362
+ this.instances = /* @__PURE__ */ new Map();
2363
+ this.instancesByElement = /* @__PURE__ */ new WeakMap();
2364
+ this.eventHandlers.clear();
2365
+ this.conditionalListeners.clear();
2366
+ afterCommit?.();
958
2367
  return;
959
2368
  }
960
- const oldIndices = /* @__PURE__ */ new Map();
2369
+ if (this.reconcileStableRows(rows, afterCommit)) return;
2370
+ if (this.reconcileSingleRemoval(rows, afterCommit)) return;
961
2371
  const activeElement = this.root.ownerDocument.activeElement;
962
2372
  const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
963
- [...this.instances].forEach(([key], index) => oldIndices.set(key, index));
964
2373
  const nextKeys = new Set(rows.keys);
2374
+ const hasSurvivingRows = rows.keys.some((key) => this.instances.has(key));
2375
+ const oldIndices = /* @__PURE__ */ new Map();
2376
+ if (hasSurvivingRows) {
2377
+ [...this.instances].forEach(([key], index) => oldIndices.set(key, index));
2378
+ }
965
2379
  for (const [key, instance] of this.instances) {
966
- if (!nextKeys.has(key)) instance.element.remove();
2380
+ if (!nextKeys.has(key)) {
2381
+ instance.scope?.cleanup();
2382
+ if (hasSurvivingRows) instance.element.remove();
2383
+ }
967
2384
  }
968
- const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
969
- const stablePositions = longestIncreasingSubsequencePositions(sequence);
2385
+ const sequence = hasSurvivingRows ? rows.keys.map((key) => oldIndices.get(key) ?? -1) : rows.keys.map(() => -1);
2386
+ const stablePositions = hasSurvivingRows ? longestIncreasingSubsequencePositions(sequence) : /* @__PURE__ */ new Set();
970
2387
  const nextInstances = [];
971
2388
  const conditionalChanges = [];
972
2389
  for (let index = 0; index < rows.items.length; index += 1) {
973
2390
  const key = rows.keys[index];
974
2391
  const existing = this.instances.get(key);
975
2392
  if (existing) {
2393
+ if (this.currentProps.hostBlocks) {
2394
+ const descriptor2 = this.currentProps.create(rows.items[index], index);
2395
+ if (!existing.scope?.update(descriptor2)) {
2396
+ this.activateFallback(afterCommit);
2397
+ return;
2398
+ }
2399
+ }
976
2400
  applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
977
- const conditionalValues = readKeyedRowConditionalValues(
2401
+ const conditionalValues = this.readConditionalValues(
978
2402
  this.currentProps,
979
2403
  rows.items[index],
980
2404
  index
981
2405
  );
982
2406
  for (const [id, values] of conditionalValues) {
983
- if (keyedRowConditionalChanged(existing.conditionalValues.get(id), values)) {
2407
+ if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
984
2408
  conditionalChanges.push({ key, id, item: rows.items[index], index });
985
2409
  }
986
2410
  }
@@ -990,34 +2414,58 @@ function createKeyedRowsBlockComponent(owner) {
990
2414
  nextInstances.push(existing);
991
2415
  continue;
992
2416
  }
993
- const element = createCompilerHostElement(
994
- this.root.ownerDocument,
995
- this.currentProps.create(rows.items[index], index)
996
- );
2417
+ const descriptor = this.currentProps.create(rows.items[index], index);
2418
+ const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
2419
+ const scope = this.mountRowHostScope(element, descriptor);
2420
+ if (this.currentProps.hostBlocks && !scope) {
2421
+ for (const instance of nextInstances) {
2422
+ if (!this.instances.has(instance.key)) instance.scope?.cleanup();
2423
+ }
2424
+ this.activateFallback(afterCommit);
2425
+ return;
2426
+ }
997
2427
  nextInstances.push({
998
2428
  key,
999
2429
  element,
2430
+ scope: scope || void 0,
1000
2431
  values: readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
1001
2432
  item: rows.items[index],
1002
2433
  index,
1003
- conditionalValues: readKeyedRowConditionalValues(
2434
+ conditionalValues: this.readConditionalValues(
1004
2435
  this.currentProps,
1005
2436
  rows.items[index],
1006
2437
  index
1007
2438
  )
1008
2439
  });
1009
2440
  }
1010
- let anchor = null;
1011
- for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
1012
- const instance = nextInstances[index];
1013
- if (sequence[index] < 0) {
1014
- this.root.insertBefore(instance.element, anchor);
1015
- } else if (!stablePositions.has(index) && instance.element.nextSibling !== anchor) {
1016
- this.root.insertBefore(instance.element, anchor);
2441
+ if (!hasSurvivingRows) {
2442
+ const fragment = this.root.ownerDocument.createDocumentFragment();
2443
+ for (const instance of nextInstances) fragment.append(instance.element);
2444
+ this.root.replaceChildren(fragment);
2445
+ } else {
2446
+ let anchor = null;
2447
+ for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
2448
+ const instance = nextInstances[index];
2449
+ if (sequence[index] < 0) {
2450
+ let start = index;
2451
+ while (start > 0 && sequence[start - 1] < 0) start -= 1;
2452
+ const fragment = this.root.ownerDocument.createDocumentFragment();
2453
+ for (let itemIndex = start; itemIndex <= index; itemIndex += 1) {
2454
+ fragment.append(nextInstances[itemIndex].element);
2455
+ }
2456
+ this.root.insertBefore(fragment, anchor);
2457
+ anchor = nextInstances[start].element;
2458
+ index = start;
2459
+ } else {
2460
+ if (!stablePositions.has(index) && instance.element.nextSibling !== anchor) {
2461
+ this.root.insertBefore(instance.element, anchor);
2462
+ }
2463
+ anchor = instance.element;
2464
+ }
1017
2465
  }
1018
- anchor = instance.element;
1019
2466
  }
1020
2467
  this.instances = new Map(nextInstances.map((instance) => [instance.key, instance]));
2468
+ this.rebuildElementIndex(this.instances);
1021
2469
  this.pruneEventHandlers(rows.keys);
1022
2470
  this.pruneConditionalListeners(rows.keys);
1023
2471
  if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
@@ -1060,7 +2508,9 @@ function createKeyedRowsBlockComponent(owner) {
1060
2508
  this.mounted = false;
1061
2509
  this.unsubscribe?.();
1062
2510
  this.root = null;
2511
+ this.cleanupHostScopes();
1063
2512
  this.instances.clear();
2513
+ this.instancesByElement = /* @__PURE__ */ new WeakMap();
1064
2514
  this.eventHandlers.clear();
1065
2515
  this.conditionalListeners.clear();
1066
2516
  }
@@ -1073,6 +2523,7 @@ function createKeyedRowsBlockComponent(owner) {
1073
2523
  );
1074
2524
  }
1075
2525
  return React__default.default.cloneElement(container, {
2526
+ ...this.delegatedContainerProps(container),
1076
2527
  key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
1077
2528
  ref: this.captureRoot
1078
2529
  });
@@ -1094,6 +2545,7 @@ function createKeyedRangesBlockComponent(owner) {
1094
2545
  this.currentProps = this.props;
1095
2546
  this.rangeInstances = [];
1096
2547
  this.staticSegments = [];
2548
+ this.staticValues = [];
1097
2549
  this.captureRoot = (root) => {
1098
2550
  this.root = root;
1099
2551
  this.currentProps.rootRef?.(root);
@@ -1103,8 +2555,7 @@ function createKeyedRangesBlockComponent(owner) {
1103
2555
  };
1104
2556
  }
1105
2557
  readRange(range) {
1106
- const source = range.items();
1107
- const items = source ? Array.from(source) : [];
2558
+ const items = materializeIterable(range.items());
1108
2559
  const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
1109
2560
  if (new Set(keys).size !== keys.length) return null;
1110
2561
  return { items, keys };
@@ -1158,6 +2609,11 @@ function createKeyedRangesBlockComponent(owner) {
1158
2609
  staticSegments.push(elements.slice(cursor));
1159
2610
  this.staticSegments = staticSegments;
1160
2611
  this.rangeInstances = instancesByRange;
2612
+ if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
2613
+ this.rangeInstances = [];
2614
+ this.staticSegments = [];
2615
+ return false;
2616
+ }
1161
2617
  return true;
1162
2618
  }
1163
2619
  anchorAfter(rangeIndex) {
@@ -1234,6 +2690,14 @@ function createKeyedRangesBlockComponent(owner) {
1234
2690
  this.activateFallback(afterCommit);
1235
2691
  return;
1236
2692
  }
2693
+ if (!applyStaticRangeBindings(
2694
+ this.currentProps.bindings,
2695
+ this.staticSegments,
2696
+ this.staticValues
2697
+ )) {
2698
+ this.activateFallback(afterCommit);
2699
+ return;
2700
+ }
1237
2701
  const activeElement = this.root.ownerDocument.activeElement;
1238
2702
  const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
1239
2703
  for (let rangeIndex = rowsByRange.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
@@ -1277,6 +2741,7 @@ function createKeyedRangesBlockComponent(owner) {
1277
2741
  this.root = null;
1278
2742
  this.rangeInstances = [];
1279
2743
  this.staticSegments = [];
2744
+ this.staticValues.length = 0;
1280
2745
  }
1281
2746
  render() {
1282
2747
  const container = this.currentProps.render();
@@ -1294,6 +2759,128 @@ function createKeyedRangesBlockComponent(owner) {
1294
2759
  FarmKeyedRangesBlock.displayName = "FarmCompiledKeyedRanges";
1295
2760
  return FarmKeyedRangesBlock;
1296
2761
  }
2762
+ function createMixedRangesBlockComponent(owner) {
2763
+ class FarmMixedRangesBlock extends React__default.default.Component {
2764
+ constructor() {
2765
+ super(...arguments);
2766
+ this.state = { fallback: false };
2767
+ this.root = null;
2768
+ this.mounted = false;
2769
+ this.fallbackRequested = false;
2770
+ this.fallbackVersion = 0;
2771
+ this.propFallbackQueued = false;
2772
+ this.currentProps = this.props;
2773
+ this.controller = null;
2774
+ this.fallbackUnsubscribers = [];
2775
+ this.captureRoot = (root) => {
2776
+ this.root = root;
2777
+ this.currentProps.rootRef?.(root);
2778
+ };
2779
+ this.activateFallback = (afterCommit) => {
2780
+ if (!this.mounted || this.state.fallback || this.fallbackRequested) {
2781
+ afterCommit?.();
2782
+ return;
2783
+ }
2784
+ this.fallbackRequested = true;
2785
+ this.controller?.cleanup();
2786
+ this.controller = null;
2787
+ this.fallbackVersion += 1;
2788
+ this.setState({ fallback: true }, () => {
2789
+ this.subscribeFallbackBlocks();
2790
+ afterCommit?.();
2791
+ });
2792
+ };
2793
+ }
2794
+ clearFallbackSubscriptions() {
2795
+ for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
2796
+ this.fallbackUnsubscribers = [];
2797
+ }
2798
+ subscribeFallbackBlocks() {
2799
+ this.clearFallbackSubscriptions();
2800
+ const descriptor = this.currentProps.create();
2801
+ const ids = /* @__PURE__ */ new Set();
2802
+ collectCompilerHostBlockIds(descriptor, ids);
2803
+ for (const id of ids) {
2804
+ this.fallbackUnsubscribers.push(
2805
+ owner.subscribe(id, (afterCommit) => {
2806
+ if (!this.mounted || !this.state.fallback) {
2807
+ afterCommit?.();
2808
+ return;
2809
+ }
2810
+ this.fallbackVersion += 1;
2811
+ this.forceUpdate(afterCommit);
2812
+ })
2813
+ );
2814
+ }
2815
+ }
2816
+ adopt() {
2817
+ if (!this.root) return false;
2818
+ const descriptor = this.currentProps.create();
2819
+ const block = descriptor.block;
2820
+ if (block?.kind !== "mixed-ranges" || block.id !== this.currentProps.id) return false;
2821
+ const controller = new CompilerNestedMixedRanges(
2822
+ owner,
2823
+ this.root,
2824
+ descriptor,
2825
+ block,
2826
+ this.activateFallback
2827
+ );
2828
+ try {
2829
+ if (!controller.adopt()) {
2830
+ controller.cleanup();
2831
+ return false;
2832
+ }
2833
+ } catch (error) {
2834
+ controller.cleanup();
2835
+ throw error;
2836
+ }
2837
+ this.controller = controller;
2838
+ return true;
2839
+ }
2840
+ schedulePropFallback() {
2841
+ if (this.propFallbackQueued) return;
2842
+ this.propFallbackQueued = true;
2843
+ queueMicrotask(() => {
2844
+ this.propFallbackQueued = false;
2845
+ if (this.mounted && !this.state.fallback) this.activateFallback();
2846
+ });
2847
+ }
2848
+ shouldComponentUpdate(nextProps, nextState) {
2849
+ this.currentProps = nextProps;
2850
+ if (nextState.fallback || this.state.fallback) return true;
2851
+ this.schedulePropFallback();
2852
+ return false;
2853
+ }
2854
+ componentDidMount() {
2855
+ this.mounted = true;
2856
+ if (!this.adopt()) this.activateFallback();
2857
+ }
2858
+ componentDidUpdate() {
2859
+ if (this.state.fallback) this.subscribeFallbackBlocks();
2860
+ }
2861
+ componentWillUnmount() {
2862
+ this.mounted = false;
2863
+ this.controller?.cleanup();
2864
+ this.controller = null;
2865
+ this.clearFallbackSubscriptions();
2866
+ this.root = null;
2867
+ }
2868
+ render() {
2869
+ const container = this.currentProps.render();
2870
+ if (!React__default.default.isValidElement(container) || typeof container.type !== "string") {
2871
+ throw new TypeError(
2872
+ `Compiled mixed ranges ${this.currentProps.id} must own one host container.`
2873
+ );
2874
+ }
2875
+ return React__default.default.cloneElement(container, {
2876
+ key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
2877
+ ref: this.captureRoot
2878
+ });
2879
+ }
2880
+ }
2881
+ FarmMixedRangesBlock.displayName = "FarmCompiledMixedRanges";
2882
+ return FarmMixedRangesBlock;
2883
+ }
1297
2884
  function createComponentBlockComponent(owner) {
1298
2885
  class FarmComponentBlock extends React__default.default.Component {
1299
2886
  constructor() {
@@ -1323,12 +2910,86 @@ function createComponentBlockComponent(owner) {
1323
2910
  FarmComponentBlock.displayName = "FarmCompiledComponentIsland";
1324
2911
  return FarmComponentBlock;
1325
2912
  }
1326
- function createCompiledComponent(definition) {
2913
+ var conditionalRuntimeFeature = {
2914
+ name: "conditional",
2915
+ create: (owner) => ({
2916
+ Conditional: createConditionalBlockComponent(owner)
2917
+ })
2918
+ };
2919
+ var hostConditionalRuntimeFeature = {
2920
+ name: "host-conditional",
2921
+ create: (owner) => ({
2922
+ HostConditional: createHostConditionalBlockComponent(owner)
2923
+ })
2924
+ };
2925
+ var conditionalRangesRuntimeFeature = {
2926
+ name: "conditional-ranges",
2927
+ create: (owner) => ({
2928
+ ConditionalRanges: createConditionalRangesBlockComponent(owner)
2929
+ })
2930
+ };
2931
+ var keyedListRuntimeFeature = {
2932
+ name: "keyed-list",
2933
+ create: (owner) => ({
2934
+ KeyedList: createKeyedListBlockComponent(owner)
2935
+ })
2936
+ };
2937
+ var keyedRowsRuntimeFeature = {
2938
+ name: "keyed-rows",
2939
+ create: (owner) => ({
2940
+ KeyedRows: createKeyedRowsBlockComponent(owner)
2941
+ })
2942
+ };
2943
+ var keyedRowsConditionalRuntimeFeature = {
2944
+ name: "keyed-rows:conditional",
2945
+ create: (owner) => ({
2946
+ KeyedRows: createKeyedRowsBlockComponent(owner, {
2947
+ conditionals: createKeyedRowConditionalRuntime()
2948
+ })
2949
+ })
2950
+ };
2951
+ var keyedRowsHostRuntimeFeature = {
2952
+ name: "keyed-rows:host",
2953
+ create: (owner) => ({
2954
+ KeyedRows: createKeyedRowsBlockComponent(owner, {
2955
+ hostBlocks: createKeyedRowHostRuntime()
2956
+ })
2957
+ })
2958
+ };
2959
+ var keyedRowsCompleteRuntimeFeature = {
2960
+ name: "keyed-rows:complete",
2961
+ create: (owner) => ({
2962
+ KeyedRows: createKeyedRowsBlockComponent(owner, {
2963
+ conditionals: createKeyedRowConditionalRuntime(),
2964
+ hostBlocks: createKeyedRowHostRuntime()
2965
+ })
2966
+ })
2967
+ };
2968
+ var keyedRangesRuntimeFeature = {
2969
+ name: "keyed-ranges",
2970
+ create: (owner) => ({
2971
+ KeyedRanges: createKeyedRangesBlockComponent(owner)
2972
+ })
2973
+ };
2974
+ var mixedRangesRuntimeFeature = {
2975
+ name: "mixed-ranges",
2976
+ create: (owner) => ({
2977
+ MixedRanges: createMixedRangesBlockComponent(owner)
2978
+ })
2979
+ };
2980
+ var componentRuntimeFeature = {
2981
+ name: "component",
2982
+ create: (owner) => ({
2983
+ Component: createComponentBlockComponent(owner)
2984
+ })
2985
+ };
2986
+ function createCompiledComponentWithFeatures(definition, runtimeFeatures) {
1327
2987
  const stateSignature = definition.stateSignature || String(definition.initialize.length);
2988
+ const runtimeSignature = [...new Set(runtimeFeatures.map((feature) => feature.name))].sort().join(",");
1328
2989
  if (definition.hmrId) {
1329
2990
  const registry = getCompilerHmrRegistry();
1330
2991
  const existing = registry.get(definition.hmrId);
1331
- if (existing?.stateSignature === stateSignature) {
2992
+ if (existing?.stateSignature === stateSignature && existing.runtimeSignature === runtimeSignature) {
1332
2993
  existing.definition.current = definition;
1333
2994
  existing.component.displayName = `FarmCompiled(${definition.displayName})`;
1334
2995
  for (const refresh of existing.refreshListeners) refresh();
@@ -1346,6 +3007,17 @@ function createCompiledComponent(definition) {
1346
3007
  this.hasBindingError = false;
1347
3008
  this.inputSelection = null;
1348
3009
  this.dirtyState = /* @__PURE__ */ new Set();
3010
+ this.indexedDefinition = null;
3011
+ this.staticBindingsByDependency = [];
3012
+ this.blockBindingsByDependency = [];
3013
+ this.blockBindings = /* @__PURE__ */ new Map();
3014
+ this.trackedBindingsByDependency = [];
3015
+ this.trackedDependenciesByBinding = /* @__PURE__ */ new Map();
3016
+ this.bindingValues = /* @__PURE__ */ new Map();
3017
+ this.activeBinding = null;
3018
+ this.activeDependencies = null;
3019
+ this.renderedDefinition = null;
3020
+ this.renderedElement = null;
1349
3021
  this.blockRefreshListeners = /* @__PURE__ */ new Map();
1350
3022
  this.blockRoots = /* @__PURE__ */ new Map();
1351
3023
  this.blockRootElements = /* @__PURE__ */ new Set();
@@ -1357,50 +3029,149 @@ function createCompiledComponent(definition) {
1357
3029
  this.refreshDefinition = () => {
1358
3030
  if (this.mounted) this.forceUpdate();
1359
3031
  };
1360
- this.cells = definitionReference.current.initialize(props).map((initialValue, index) => {
3032
+ const initialState = definitionReference.current.initialize(props);
3033
+ const initialProps = definitionReference.current.readProps?.(props) || [];
3034
+ this.propCellOffset = initialState.length;
3035
+ this.cells = [...initialState, ...initialProps].map((initialValue, index) => {
1361
3036
  let value = initialValue;
1362
3037
  const pending = [];
1363
3038
  return {
1364
- get: () => value,
3039
+ get: () => {
3040
+ if (this.activeBinding && this.activeDependencies) {
3041
+ this.activeDependencies.add(index);
3042
+ }
3043
+ return value;
3044
+ },
1365
3045
  set: (next) => {
1366
- pending.push(next);
3046
+ pending.push({ kind: "state", update: next });
1367
3047
  this.scheduleBindingFlush(index);
1368
3048
  },
3049
+ replace: (next) => {
3050
+ pending.push({ kind: "value", value: next });
3051
+ },
1369
3052
  flush: () => {
1370
3053
  if (pending.length === 0) return false;
1371
3054
  const previous = value;
1372
3055
  for (const next of pending.splice(0)) {
1373
- value = typeof next === "function" ? next(value) : next;
3056
+ if (next.kind === "value") {
3057
+ value = next.value;
3058
+ } else {
3059
+ value = typeof next.update === "function" ? next.update(value) : next.update;
3060
+ }
1374
3061
  }
1375
3062
  return !Object.is(previous, value);
1376
3063
  }
1377
3064
  };
1378
3065
  });
1379
- this.blockRuntime = {
1380
- Conditional: createConditionalBlockComponent({
1381
- setRoot: (id, root) => this.setBlockRoot(id, root),
1382
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1383
- }),
1384
- HostConditional: createHostConditionalBlockComponent({
1385
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1386
- }),
1387
- ConditionalRanges: createConditionalRangesBlockComponent({
1388
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1389
- }),
1390
- KeyedList: createKeyedListBlockComponent({
1391
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1392
- }),
1393
- KeyedRows: createKeyedRowsBlockComponent({
1394
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1395
- }),
1396
- KeyedRanges: createKeyedRangesBlockComponent({
1397
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1398
- }),
1399
- Component: createComponentBlockComponent({
1400
- subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
1401
- }),
3066
+ const featureOwner = {
3067
+ setRoot: (id, root) => this.setBlockRoot(id, root),
3068
+ subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
3069
+ };
3070
+ const blockRuntime = {
1402
3071
  target: (id) => this.bindingTarget(id)
1403
3072
  };
3073
+ for (const feature of runtimeFeatures) {
3074
+ Object.assign(blockRuntime, feature.create(featureOwner));
3075
+ }
3076
+ this.blockRuntime = blockRuntime;
3077
+ }
3078
+ usesHybridReactivity() {
3079
+ return definitionReference.current.reactivity === "hybrid";
3080
+ }
3081
+ canReuseRenderedElement(currentDefinition, propValues) {
3082
+ return Boolean(
3083
+ this.mounted && propValues && propValues.every(isCompilerPrimitive) && this.renderedDefinition === currentDefinition && this.renderedElement
3084
+ );
3085
+ }
3086
+ renderCellsForProps(propValues) {
3087
+ if (!propValues) return { cells: this.cells, commit: () => void 0 };
3088
+ let committed = false;
3089
+ const cells = this.cells.slice(0, this.propCellOffset);
3090
+ for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
3091
+ const cell = this.cells[this.propCellOffset + propIndex];
3092
+ if (!cell) continue;
3093
+ cells.push({
3094
+ get: () => committed ? cell.get() : propValues[propIndex],
3095
+ set: (next) => cell.set(next)
3096
+ });
3097
+ }
3098
+ return {
3099
+ cells,
3100
+ commit: () => {
3101
+ committed = true;
3102
+ }
3103
+ };
3104
+ }
3105
+ tracksBinding(binding) {
3106
+ return this.usesHybridReactivity() && binding.tracking === "dynamic";
3107
+ }
3108
+ ensureBindingIndex() {
3109
+ const currentDefinition = definitionReference.current;
3110
+ if (this.indexedDefinition === currentDefinition) return;
3111
+ this.indexedDefinition = currentDefinition;
3112
+ this.staticBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
3113
+ this.blockBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
3114
+ this.trackedBindingsByDependency = Array.from(
3115
+ { length: this.cells.length },
3116
+ () => /* @__PURE__ */ new Set()
3117
+ );
3118
+ this.blockBindings.clear();
3119
+ this.trackedDependenciesByBinding.clear();
3120
+ this.bindingValues.clear();
3121
+ for (const binding of currentDefinition.bindings) {
3122
+ if (binding.kind === "block") this.blockBindings.set(binding.id, binding);
3123
+ for (const dependency of binding.dependencies) {
3124
+ if (dependency < 0 || dependency >= this.cells.length) continue;
3125
+ if (binding.kind === "block") {
3126
+ this.blockBindingsByDependency[dependency].push(binding);
3127
+ } else if (!this.tracksBinding(binding)) {
3128
+ this.staticBindingsByDependency[dependency].push(binding);
3129
+ }
3130
+ }
3131
+ }
3132
+ }
3133
+ updateTrackedDependencies(binding, nextDependencies) {
3134
+ const previousDependencies = this.trackedDependenciesByBinding.get(binding);
3135
+ if (previousDependencies) {
3136
+ for (const dependency of previousDependencies) {
3137
+ if (!nextDependencies.has(dependency)) {
3138
+ this.trackedBindingsByDependency[dependency]?.delete(binding);
3139
+ }
3140
+ }
3141
+ }
3142
+ for (const dependency of nextDependencies) {
3143
+ if (!previousDependencies?.has(dependency)) {
3144
+ this.trackedBindingsByDependency[dependency]?.add(binding);
3145
+ }
3146
+ }
3147
+ this.trackedDependenciesByBinding.set(binding, nextDependencies);
3148
+ }
3149
+ readBinding(binding) {
3150
+ if (!this.tracksBinding(binding)) return binding.read(this.props, this.cells);
3151
+ const previousBinding = this.activeBinding;
3152
+ const previousDependencies = this.activeDependencies;
3153
+ const nextDependencies = /* @__PURE__ */ new Set();
3154
+ this.activeBinding = binding;
3155
+ this.activeDependencies = nextDependencies;
3156
+ try {
3157
+ return binding.read(this.props, this.cells);
3158
+ } finally {
3159
+ this.activeBinding = previousBinding;
3160
+ this.activeDependencies = previousDependencies;
3161
+ this.updateTrackedDependencies(binding, nextDependencies);
3162
+ }
3163
+ }
3164
+ bindingValue(binding, value) {
3165
+ return binding.kind === "text" ? renderTextValue(value) : value;
3166
+ }
3167
+ primeHybridBindings() {
3168
+ if (!this.usesHybridReactivity()) return;
3169
+ for (const binding of definitionReference.current.bindings) {
3170
+ if (binding.kind === "block") continue;
3171
+ if (!this.tracksBinding(binding)) continue;
3172
+ const value = this.readBinding(binding);
3173
+ this.bindingValues.set(binding, this.bindingValue(binding, value));
3174
+ }
1404
3175
  }
1405
3176
  bindingTarget(id) {
1406
3177
  const existing = this.bindingTargetRefs.get(id);
@@ -1458,83 +3229,118 @@ function createCompiledComponent(definition) {
1458
3229
  this.flushQueued = true;
1459
3230
  queueMicrotask(() => {
1460
3231
  this.flushQueued = false;
1461
- const inputSelection = this.inputSelection;
1462
- this.inputSelection = null;
1463
- if (!this.mounted) return;
1464
- const dirty = /* @__PURE__ */ new Set();
1465
- for (const index2 of this.dirtyState) {
1466
- if (this.cells[index2]?.flush()) dirty.add(index2);
1467
- }
1468
- this.dirtyState.clear();
1469
- if (dirty.size === 0) return;
1470
- try {
1471
- const bindings = definitionReference.current.bindings;
1472
- const blockBindings = /* @__PURE__ */ new Map();
1473
- const affectedBlockIds = /* @__PURE__ */ new Set();
1474
- for (const binding of bindings) {
1475
- if (binding.kind !== "block") continue;
1476
- blockBindings.set(binding.id, binding);
1477
- if (binding.dependencies.some((dependency) => dirty.has(dependency))) {
1478
- affectedBlockIds.add(binding.id);
1479
- }
3232
+ this.flushBindingUpdates();
3233
+ });
3234
+ }
3235
+ flushBindingUpdates() {
3236
+ const inputSelection = this.inputSelection;
3237
+ this.inputSelection = null;
3238
+ if (!this.mounted) return;
3239
+ const dirty = /* @__PURE__ */ new Set();
3240
+ for (const index of this.dirtyState) {
3241
+ if (this.cells[index]?.flush()) dirty.add(index);
3242
+ }
3243
+ this.dirtyState.clear();
3244
+ if (dirty.size === 0) return;
3245
+ try {
3246
+ this.ensureBindingIndex();
3247
+ const affectedBlockIds = /* @__PURE__ */ new Set();
3248
+ const affectedBindings = /* @__PURE__ */ new Set();
3249
+ for (const dependency of dirty) {
3250
+ for (const binding of this.blockBindingsByDependency[dependency] || []) {
3251
+ affectedBlockIds.add(binding.id);
1480
3252
  }
1481
- const hasAffectedMountedAncestor = (binding) => {
1482
- let parent = binding.parent;
1483
- while (parent !== void 0) {
1484
- if (affectedBlockIds.has(parent) && this.blockRefreshListeners.has(parent)) {
1485
- return true;
1486
- }
1487
- parent = blockBindings.get(parent)?.parent;
1488
- }
1489
- return false;
1490
- };
1491
- const blockRefreshes = [...affectedBlockIds].map((id) => {
1492
- const binding = blockBindings.get(id);
1493
- const refresh = this.blockRefreshListeners.get(id);
1494
- return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
1495
- }).filter(
1496
- (refresh) => refresh !== void 0
1497
- );
1498
- for (const binding of bindings) {
1499
- if (binding.kind !== "block" && binding.dependencies.some((dependency) => dirty.has(dependency))) {
1500
- this.applyBinding(binding);
3253
+ for (const binding of this.staticBindingsByDependency[dependency] || []) {
3254
+ affectedBindings.add(binding);
3255
+ }
3256
+ if (this.usesHybridReactivity()) {
3257
+ for (const binding of this.trackedBindingsByDependency[dependency] || []) {
3258
+ affectedBindings.add(binding);
1501
3259
  }
1502
3260
  }
1503
- let pendingBlockCommits = blockRefreshes.length;
1504
- for (const refresh of blockRefreshes) {
1505
- refresh(() => {
1506
- pendingBlockCommits -= 1;
1507
- if (pendingBlockCommits === 0) this.restoreInputSelection(inputSelection);
1508
- });
3261
+ }
3262
+ const hasAffectedMountedAncestor = (binding) => {
3263
+ let parent = binding.parent;
3264
+ while (parent !== void 0) {
3265
+ if (affectedBlockIds.has(parent) && this.blockRefreshListeners.has(parent)) {
3266
+ return true;
3267
+ }
3268
+ parent = this.blockBindings.get(parent)?.parent;
1509
3269
  }
1510
- if (blockRefreshes.length === 0) this.restoreInputSelection(inputSelection);
1511
- } catch (error) {
1512
- this.bindingError = error;
1513
- this.hasBindingError = true;
1514
- this.forceUpdate();
3270
+ return false;
3271
+ };
3272
+ const blockRefreshes = [...affectedBlockIds].map((id) => {
3273
+ const binding = this.blockBindings.get(id);
3274
+ const refresh = this.blockRefreshListeners.get(id);
3275
+ return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
3276
+ }).filter((refresh) => refresh !== void 0);
3277
+ for (const binding of affectedBindings) {
3278
+ if (binding.kind !== "block") this.applyBinding(binding);
1515
3279
  }
1516
- });
3280
+ let pendingBlockCommits = blockRefreshes.length;
3281
+ for (const refresh of blockRefreshes) {
3282
+ refresh(() => {
3283
+ pendingBlockCommits -= 1;
3284
+ if (pendingBlockCommits === 0) this.restoreInputSelection(inputSelection);
3285
+ }, dirty);
3286
+ }
3287
+ if (blockRefreshes.length === 0) this.restoreInputSelection(inputSelection);
3288
+ } catch (error) {
3289
+ this.bindingError = error;
3290
+ this.hasBindingError = true;
3291
+ this.forceUpdate();
3292
+ }
1517
3293
  }
1518
- applyBinding(binding) {
3294
+ applyBinding(binding, force = false) {
1519
3295
  if (!this.root || binding.kind === "block") return;
1520
3296
  const target = binding.target === void 0 ? findBindingTarget(this.root, binding.path, this.blockRootElements) : binding.path.length === 0 ? this.root : this.bindingTargets.get(binding.target) || null;
1521
3297
  if (!target) return;
1522
- const value = binding.read(this.props, this.cells);
3298
+ const value = this.readBinding(binding);
3299
+ const comparableValue = this.bindingValue(binding, value);
3300
+ if (!force && this.bindingValues.has(binding)) {
3301
+ if (Object.is(this.bindingValues.get(binding), comparableValue)) return;
3302
+ }
1523
3303
  if (binding.kind === "text") {
1524
- target.textContent = renderTextValue(value);
3304
+ target.textContent = comparableValue;
1525
3305
  } else if (binding.kind === "style") {
1526
3306
  updateStyle(target, binding.name, value);
1527
3307
  } else {
1528
3308
  updateAttribute(target, binding.name, value);
1529
3309
  }
3310
+ this.bindingValues.set(binding, comparableValue);
1530
3311
  }
1531
3312
  componentDidMount() {
1532
3313
  this.mounted = true;
1533
3314
  refreshListeners.add(this.refreshDefinition);
3315
+ this.ensureBindingIndex();
3316
+ this.primeHybridBindings();
1534
3317
  }
1535
- componentDidUpdate() {
3318
+ getSnapshotBeforeUpdate() {
3319
+ const currentDefinition = definitionReference.current;
3320
+ const propValues = currentDefinition.readProps?.(this.props) || null;
3321
+ return this.canReuseRenderedElement(currentDefinition, propValues);
3322
+ }
3323
+ componentDidUpdate(_previousProps, _previousState, reusedRenderedElement = false) {
3324
+ const propValues = definitionReference.current.readProps?.(this.props) || null;
3325
+ if (propValues) {
3326
+ if (reusedRenderedElement) this.captureInputSelection();
3327
+ for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
3328
+ const cellIndex = this.propCellOffset + propIndex;
3329
+ const cell = this.cells[cellIndex];
3330
+ if (!cell) continue;
3331
+ cell.replace(propValues[propIndex]);
3332
+ if (reusedRenderedElement) {
3333
+ this.dirtyState.add(cellIndex);
3334
+ } else {
3335
+ cell.flush();
3336
+ }
3337
+ }
3338
+ this.flushBindingUpdates();
3339
+ return;
3340
+ }
3341
+ this.ensureBindingIndex();
1536
3342
  for (const binding of definitionReference.current.bindings) {
1537
- if (binding.kind !== "block") this.applyBinding(binding);
3343
+ if (binding.kind !== "block") this.applyBinding(binding, true);
1538
3344
  }
1539
3345
  }
1540
3346
  componentWillUnmount() {
@@ -1547,36 +3353,68 @@ function createCompiledComponent(definition) {
1547
3353
  this.blockRootElements.clear();
1548
3354
  this.bindingTargets.clear();
1549
3355
  this.bindingTargetRefs.clear();
3356
+ this.indexedDefinition = null;
3357
+ this.staticBindingsByDependency = [];
3358
+ this.blockBindingsByDependency = [];
3359
+ this.blockBindings.clear();
3360
+ this.trackedBindingsByDependency = [];
3361
+ this.trackedDependenciesByBinding.clear();
3362
+ this.bindingValues.clear();
3363
+ this.activeBinding = null;
3364
+ this.activeDependencies = null;
1550
3365
  refreshListeners.delete(this.refreshDefinition);
1551
3366
  }
1552
3367
  render() {
1553
3368
  if (this.hasBindingError) throw this.bindingError;
1554
3369
  const currentDefinition = definitionReference.current;
1555
- const element = currentDefinition.render(this.props, this.cells, this.blockRuntime);
3370
+ const propValues = currentDefinition.readProps?.(this.props) || null;
3371
+ if (this.canReuseRenderedElement(currentDefinition, propValues)) {
3372
+ return this.renderedElement;
3373
+ }
3374
+ const renderCells = this.renderCellsForProps(propValues);
3375
+ const element = currentDefinition.render(this.props, renderCells.cells, this.blockRuntime);
1556
3376
  if (!React__default.default.isValidElement(element)) {
1557
3377
  throw new TypeError(
1558
3378
  `Compiled component ${currentDefinition.displayName} must return one host element.`
1559
3379
  );
1560
3380
  }
3381
+ let renderedElement;
3382
+ const captureCommittedRoot = (root) => {
3383
+ this.captureRoot(root);
3384
+ if (!root) return;
3385
+ renderCells.commit();
3386
+ this.renderedDefinition = currentDefinition;
3387
+ this.renderedElement = renderedElement;
3388
+ };
1561
3389
  if (element.type === this.blockRuntime.KeyedRanges) {
1562
- return React__default.default.cloneElement(element, {
1563
- rootRef: this.captureRoot
1564
- });
1565
- }
1566
- if (element.type === this.blockRuntime.ConditionalRanges) {
1567
- return React__default.default.cloneElement(
3390
+ renderedElement = React__default.default.cloneElement(
3391
+ element,
3392
+ {
3393
+ rootRef: captureCommittedRoot
3394
+ }
3395
+ );
3396
+ } else if (element.type === this.blockRuntime.ConditionalRanges) {
3397
+ renderedElement = React__default.default.cloneElement(
1568
3398
  element,
1569
- { rootRef: this.captureRoot }
3399
+ { rootRef: captureCommittedRoot }
1570
3400
  );
1571
- }
1572
- if (typeof element.type !== "string") {
3401
+ } else if (element.type === this.blockRuntime.MixedRanges) {
3402
+ renderedElement = React__default.default.cloneElement(
3403
+ element,
3404
+ {
3405
+ rootRef: captureCommittedRoot
3406
+ }
3407
+ );
3408
+ } else if (typeof element.type !== "string") {
1573
3409
  throw new TypeError(
1574
3410
  `Compiled component ${currentDefinition.displayName} must return one host element.`
1575
3411
  );
3412
+ } else {
3413
+ renderedElement = React__default.default.cloneElement(element, {
3414
+ ref: captureCommittedRoot
3415
+ });
1576
3416
  }
1577
- return React__default.default.cloneElement(element, {
1578
- ref: this.captureRoot
1579
- });
3417
+ return renderedElement;
1580
3418
  }
1581
3419
  }
1582
3420
  FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
@@ -1586,12 +3424,38 @@ function createCompiledComponent(definition) {
1586
3424
  component,
1587
3425
  definition: definitionReference,
1588
3426
  refreshListeners,
1589
- stateSignature
3427
+ stateSignature,
3428
+ runtimeSignature
1590
3429
  });
1591
3430
  }
1592
3431
  return component;
1593
3432
  }
3433
+ var COMPLETE_RUNTIME_FEATURES = [
3434
+ conditionalRuntimeFeature,
3435
+ hostConditionalRuntimeFeature,
3436
+ conditionalRangesRuntimeFeature,
3437
+ keyedListRuntimeFeature,
3438
+ keyedRowsCompleteRuntimeFeature,
3439
+ keyedRangesRuntimeFeature,
3440
+ mixedRangesRuntimeFeature,
3441
+ componentRuntimeFeature
3442
+ ];
3443
+ function createCompiledComponent(definition) {
3444
+ return createCompiledComponentWithFeatures(definition, COMPLETE_RUNTIME_FEATURES);
3445
+ }
1594
3446
 
3447
+ exports.componentRuntimeFeature = componentRuntimeFeature;
3448
+ exports.conditionalRangesRuntimeFeature = conditionalRangesRuntimeFeature;
3449
+ exports.conditionalRuntimeFeature = conditionalRuntimeFeature;
1595
3450
  exports.createCompiledComponent = createCompiledComponent;
3451
+ exports.createCompiledComponentWithFeatures = createCompiledComponentWithFeatures;
3452
+ exports.hostConditionalRuntimeFeature = hostConditionalRuntimeFeature;
3453
+ exports.keyedListRuntimeFeature = keyedListRuntimeFeature;
3454
+ exports.keyedRangesRuntimeFeature = keyedRangesRuntimeFeature;
3455
+ exports.keyedRowsCompleteRuntimeFeature = keyedRowsCompleteRuntimeFeature;
3456
+ exports.keyedRowsConditionalRuntimeFeature = keyedRowsConditionalRuntimeFeature;
3457
+ exports.keyedRowsHostRuntimeFeature = keyedRowsHostRuntimeFeature;
3458
+ exports.keyedRowsRuntimeFeature = keyedRowsRuntimeFeature;
3459
+ exports.mixedRangesRuntimeFeature = mixedRangesRuntimeFeature;
1596
3460
  //# sourceMappingURL=compiler-runtime.cjs.map
1597
3461
  //# sourceMappingURL=compiler-runtime.cjs.map