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