@farm.js/react 0.1.0-beta.2 → 0.1.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -42
- package/dist/compiler-runtime.cjs +2087 -134
- package/dist/compiler-runtime.cjs.map +1 -1
- package/dist/compiler-runtime.d.mts +94 -1
- package/dist/compiler-runtime.d.ts +94 -1
- package/dist/compiler-runtime.mjs +2087 -134
- package/dist/compiler-runtime.mjs.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/list.cjs +18 -1
- package/dist/list.cjs.map +1 -1
- package/dist/list.mjs +18 -1
- package/dist/list.mjs.map +1 -1
- package/dist/vite.cjs +1321 -75
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +1321 -75
- package/dist/vite.mjs.map +1 -1
- package/package.json +4 -3
|
@@ -7,6 +7,23 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
7
7
|
|
|
8
8
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
9
9
|
|
|
10
|
+
// src/compiler-runtime.tsx
|
|
11
|
+
|
|
12
|
+
// src/iterable.ts
|
|
13
|
+
var oneShotSnapshots = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
function materializeIterable(source) {
|
|
15
|
+
if (source == null) return [];
|
|
16
|
+
const iterator = source[Symbol.iterator]();
|
|
17
|
+
const oneShot = iterator === source && (typeof source === "object" || typeof source === "function");
|
|
18
|
+
if (oneShot) {
|
|
19
|
+
const cached = oneShotSnapshots.get(source);
|
|
20
|
+
if (cached) return cached;
|
|
21
|
+
}
|
|
22
|
+
const items = Array.from({ [Symbol.iterator]: () => iterator });
|
|
23
|
+
if (oneShot) oneShotSnapshots.set(source, items);
|
|
24
|
+
return items;
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
// src/compiler-runtime.tsx
|
|
11
28
|
var COMPILER_HMR_REGISTRY = /* @__PURE__ */ Symbol.for("@farm.js/react/compiler-hmr-registry");
|
|
12
29
|
function getCompilerHmrRegistry() {
|
|
@@ -22,6 +39,11 @@ function renderTextValue(value) {
|
|
|
22
39
|
if (value === null || value === void 0 || typeof value === "boolean") return "";
|
|
23
40
|
return String(value);
|
|
24
41
|
}
|
|
42
|
+
function isCompilerPrimitive(value) {
|
|
43
|
+
if (value === null) return true;
|
|
44
|
+
const kind = typeof value;
|
|
45
|
+
return kind === "string" || kind === "number" || kind === "boolean" || kind === "bigint" || kind === "undefined";
|
|
46
|
+
}
|
|
25
47
|
function findBindingTarget(root, path, blockRoots) {
|
|
26
48
|
let current = root;
|
|
27
49
|
for (const index of path) {
|
|
@@ -260,14 +282,19 @@ function createCompilerHostElement(document, descriptor) {
|
|
|
260
282
|
updateAttribute(element, attribute.name, attribute.value);
|
|
261
283
|
}
|
|
262
284
|
for (const style of descriptor.styles) updateStyle(element, style.name, style.value);
|
|
263
|
-
|
|
285
|
+
const appendChild = (child) => {
|
|
286
|
+
if (Array.isArray(child)) {
|
|
287
|
+
for (const nested of child) appendChild(nested);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
264
290
|
if (isCompilerHostElement(child)) {
|
|
265
291
|
element.append(createCompilerHostElement(document, child));
|
|
266
|
-
|
|
292
|
+
return;
|
|
267
293
|
}
|
|
268
294
|
const text = renderTextValue(child);
|
|
269
295
|
if (text) element.append(document.createTextNode(text));
|
|
270
|
-
}
|
|
296
|
+
};
|
|
297
|
+
for (const child of materializeCompilerHostChildren(descriptor)) appendChild(child);
|
|
271
298
|
for (const attribute of descriptor.attributes) {
|
|
272
299
|
if (attribute.name === "value" && (isSelectElement(element) || isTextAreaElement(element))) {
|
|
273
300
|
updateAttribute(element, attribute.name, attribute.value);
|
|
@@ -277,18 +304,110 @@ function createCompilerHostElement(document, descriptor) {
|
|
|
277
304
|
}
|
|
278
305
|
function matchesCompilerHostElement(element, descriptor, opaquePaths = /* @__PURE__ */ new Set(), path = []) {
|
|
279
306
|
if (element.tagName.toLowerCase() !== descriptor.tag.toLowerCase()) return false;
|
|
280
|
-
if (opaquePaths.has(path.join("."))) return true;
|
|
281
|
-
const expectedChildren = descriptor.children
|
|
307
|
+
if (opaquePaths.has(path.join(".")) || descriptor.block) return true;
|
|
308
|
+
const expectedChildren = flattenCompilerHostElements(descriptor.children);
|
|
282
309
|
if (element.children.length !== expectedChildren.length) return false;
|
|
283
310
|
return expectedChildren.every(
|
|
284
311
|
(child, index) => matchesCompilerHostElement(element.children[index], child, opaquePaths, [...path, index])
|
|
285
312
|
);
|
|
286
313
|
}
|
|
314
|
+
function flattenCompilerHostElements(children) {
|
|
315
|
+
const elements = [];
|
|
316
|
+
const visit = (child) => {
|
|
317
|
+
if (Array.isArray(child)) {
|
|
318
|
+
for (const nested of child) visit(nested);
|
|
319
|
+
} else if (isCompilerHostElement(child)) {
|
|
320
|
+
elements.push(child);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
for (const child of children) visit(child);
|
|
324
|
+
return elements;
|
|
325
|
+
}
|
|
326
|
+
function materializeCompilerHostChildren(descriptor) {
|
|
327
|
+
const block = descriptor.block;
|
|
328
|
+
if (block?.kind !== "keyed-ranges" || !block.staticChildrenOnly) {
|
|
329
|
+
return descriptor.children;
|
|
330
|
+
}
|
|
331
|
+
const staticChildren = flattenCompilerHostElements(descriptor.children);
|
|
332
|
+
const children = [];
|
|
333
|
+
let cursor = 0;
|
|
334
|
+
for (const range of block.ranges) {
|
|
335
|
+
children.push(...staticChildren.slice(cursor, cursor + range.before));
|
|
336
|
+
cursor += range.before;
|
|
337
|
+
const items = materializeIterable(range.items());
|
|
338
|
+
children.push(...items.map((item, index) => range.create(item, index)));
|
|
339
|
+
}
|
|
340
|
+
children.push(...staticChildren.slice(cursor, cursor + block.trailing));
|
|
341
|
+
return children;
|
|
342
|
+
}
|
|
343
|
+
function collectCompilerHostBlockIds(descriptor, ids) {
|
|
344
|
+
for (const child of flattenCompilerHostElements(descriptor.children)) {
|
|
345
|
+
collectCompilerHostBlockIds(child, ids);
|
|
346
|
+
}
|
|
347
|
+
const block = descriptor.block;
|
|
348
|
+
if (!block || ids.has(block.id)) return;
|
|
349
|
+
ids.add(block.id);
|
|
350
|
+
if (block.kind === "conditional-ranges") {
|
|
351
|
+
for (const range of block.ranges) {
|
|
352
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
353
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
354
|
+
}
|
|
355
|
+
} else if (block.kind === "keyed-ranges") {
|
|
356
|
+
for (const range of block.ranges) {
|
|
357
|
+
const first = materializeIterable(range.items())[0];
|
|
358
|
+
if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
|
|
359
|
+
}
|
|
360
|
+
} else {
|
|
361
|
+
for (const range of block.ranges) {
|
|
362
|
+
if (range.kind === "conditional") {
|
|
363
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
364
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
365
|
+
} else {
|
|
366
|
+
const first = materializeIterable(range.items())[0];
|
|
367
|
+
if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
287
372
|
function findCompilerHostTarget(root, path) {
|
|
288
373
|
let current = root;
|
|
289
374
|
for (const index of path) current = current?.children[index] || null;
|
|
290
375
|
return current;
|
|
291
376
|
}
|
|
377
|
+
var UNSET_STATIC_RANGE_BINDING = /* @__PURE__ */ Symbol("unset static range binding");
|
|
378
|
+
function normalizedStaticRangeBindingValue(binding, value) {
|
|
379
|
+
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
380
|
+
}
|
|
381
|
+
function applyStaticRangeBindings(bindings, segments, values) {
|
|
382
|
+
const activeBindings = bindings || [];
|
|
383
|
+
if (values.length === 0 && activeBindings.length > 0) {
|
|
384
|
+
values.push(...activeBindings.map(() => UNSET_STATIC_RANGE_BINDING));
|
|
385
|
+
}
|
|
386
|
+
if (values.length !== activeBindings.length) return false;
|
|
387
|
+
for (let index = 0; index < activeBindings.length; index += 1) {
|
|
388
|
+
const binding = activeBindings[index];
|
|
389
|
+
if (!Number.isSafeInteger(binding.segment) || binding.segment < 0 || !Number.isSafeInteger(binding.sibling) || binding.sibling < 0) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
const sibling = segments[binding.segment]?.[binding.sibling];
|
|
393
|
+
const target = sibling && findCompilerHostTarget(sibling, binding.path);
|
|
394
|
+
if (!target) return false;
|
|
395
|
+
const rawValue = binding.read();
|
|
396
|
+
const value = normalizedStaticRangeBindingValue(binding, rawValue);
|
|
397
|
+
if (Object.is(values[index], value)) continue;
|
|
398
|
+
values[index] = value;
|
|
399
|
+
if (binding.kind === "text") {
|
|
400
|
+
target.textContent = value;
|
|
401
|
+
} else if (binding.kind === "style" && binding.name) {
|
|
402
|
+
updateStyle(target, binding.name, rawValue);
|
|
403
|
+
} else if (binding.kind === "attribute" && binding.name) {
|
|
404
|
+
updateAttribute(target, binding.name, rawValue);
|
|
405
|
+
} else {
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
292
411
|
var UNSET_KEYED_ROW_BINDING = /* @__PURE__ */ Symbol("unset interactive keyed-row binding");
|
|
293
412
|
function keyedRowIdentity(key) {
|
|
294
413
|
return String(key);
|
|
@@ -303,20 +422,23 @@ function readKeyedRowBindingValues(props, item, index) {
|
|
|
303
422
|
}
|
|
304
423
|
function applyKeyedRowBindings(props, instance, item, index) {
|
|
305
424
|
for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
425
|
+
applyKeyedRowBinding(props, instance, item, index, bindingIndex);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function applyKeyedRowBinding(props, instance, item, index, bindingIndex) {
|
|
429
|
+
const binding = props.bindings[bindingIndex];
|
|
430
|
+
const rawValue = binding.read(item, index);
|
|
431
|
+
const value = normalizedKeyedRowBindingValue(binding, rawValue);
|
|
432
|
+
if (Object.is(instance.values[bindingIndex], value)) return;
|
|
433
|
+
instance.values[bindingIndex] = value;
|
|
434
|
+
const target = findCompilerHostTarget(instance.element, binding.path);
|
|
435
|
+
if (!target) return;
|
|
436
|
+
if (binding.kind === "text") {
|
|
437
|
+
target.textContent = value;
|
|
438
|
+
} else if (binding.kind === "style" && binding.name) {
|
|
439
|
+
updateStyle(target, binding.name, rawValue);
|
|
440
|
+
} else if (binding.kind === "attribute" && binding.name) {
|
|
441
|
+
updateAttribute(target, binding.name, rawValue);
|
|
320
442
|
}
|
|
321
443
|
}
|
|
322
444
|
function keyedRowConditionalSnapshot(conditional, item, index) {
|
|
@@ -335,13 +457,15 @@ function keyedRowConditionalSnapshot(conditional, item, index) {
|
|
|
335
457
|
];
|
|
336
458
|
}
|
|
337
459
|
function readKeyedRowConditionalValues(props, item, index) {
|
|
460
|
+
if (!props.conditionals?.length) return EMPTY_KEYED_ROW_CONDITIONAL_VALUES;
|
|
338
461
|
return new Map(
|
|
339
|
-
|
|
462
|
+
props.conditionals.map((conditional) => [
|
|
340
463
|
conditional.id,
|
|
341
464
|
keyedRowConditionalSnapshot(conditional, item, index)
|
|
342
465
|
])
|
|
343
466
|
);
|
|
344
467
|
}
|
|
468
|
+
var EMPTY_KEYED_ROW_CONDITIONAL_VALUES = /* @__PURE__ */ new Map();
|
|
345
469
|
function keyedRowConditionalChanged(previous, next) {
|
|
346
470
|
return !previous || previous.length !== next.length || next.some((value, index) => !Object.is(value, previous[index]));
|
|
347
471
|
}
|
|
@@ -358,11 +482,6 @@ function hostConditionalSelection(props) {
|
|
|
358
482
|
function normalizedHostConditionalBindingValue(binding, value) {
|
|
359
483
|
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
360
484
|
}
|
|
361
|
-
function readHostConditionalBindingValues(branch) {
|
|
362
|
-
return branch.bindings.map(
|
|
363
|
-
(binding) => normalizedHostConditionalBindingValue(binding, binding.read())
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
485
|
function applyHostConditionalBindings(branch, instance) {
|
|
367
486
|
for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
|
|
368
487
|
const binding = branch.bindings[bindingIndex];
|
|
@@ -381,6 +500,903 @@ function applyHostConditionalBindings(branch, instance) {
|
|
|
381
500
|
}
|
|
382
501
|
}
|
|
383
502
|
}
|
|
503
|
+
var UNSET_HOST_CONDITIONAL_BINDING = /* @__PURE__ */ Symbol("unset host conditional binding");
|
|
504
|
+
function mountCompilerHostTree(owner, element, descriptor, onFallback) {
|
|
505
|
+
if (!matchesCompilerHostElement(element, descriptor)) return null;
|
|
506
|
+
if (descriptor.block?.kind === "conditional-ranges") {
|
|
507
|
+
const controller = new CompilerNestedConditionalRanges(
|
|
508
|
+
owner,
|
|
509
|
+
element,
|
|
510
|
+
descriptor,
|
|
511
|
+
descriptor.block,
|
|
512
|
+
onFallback
|
|
513
|
+
);
|
|
514
|
+
try {
|
|
515
|
+
if (controller.adopt()) return controller;
|
|
516
|
+
controller.cleanup();
|
|
517
|
+
return null;
|
|
518
|
+
} catch (error) {
|
|
519
|
+
controller.cleanup();
|
|
520
|
+
throw error;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (descriptor.block?.kind === "keyed-ranges") {
|
|
524
|
+
const controller = new CompilerNestedKeyedRanges(
|
|
525
|
+
owner,
|
|
526
|
+
element,
|
|
527
|
+
descriptor,
|
|
528
|
+
descriptor.block,
|
|
529
|
+
onFallback
|
|
530
|
+
);
|
|
531
|
+
try {
|
|
532
|
+
if (controller.adopt()) return controller;
|
|
533
|
+
controller.cleanup();
|
|
534
|
+
return null;
|
|
535
|
+
} catch (error) {
|
|
536
|
+
controller.cleanup();
|
|
537
|
+
throw error;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (descriptor.block?.kind === "mixed-ranges") {
|
|
541
|
+
const controller = new CompilerNestedMixedRanges(
|
|
542
|
+
owner,
|
|
543
|
+
element,
|
|
544
|
+
descriptor,
|
|
545
|
+
descriptor.block,
|
|
546
|
+
onFallback
|
|
547
|
+
);
|
|
548
|
+
try {
|
|
549
|
+
if (controller.adopt()) return controller;
|
|
550
|
+
controller.cleanup();
|
|
551
|
+
return null;
|
|
552
|
+
} catch (error) {
|
|
553
|
+
controller.cleanup();
|
|
554
|
+
throw error;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
558
|
+
if (descriptors.length !== element.children.length) return null;
|
|
559
|
+
const scopes = [];
|
|
560
|
+
for (let index = 0; index < descriptors.length; index += 1) {
|
|
561
|
+
const scope = mountCompilerHostTree(
|
|
562
|
+
owner,
|
|
563
|
+
element.children[index],
|
|
564
|
+
descriptors[index],
|
|
565
|
+
onFallback
|
|
566
|
+
);
|
|
567
|
+
if (!scope) {
|
|
568
|
+
for (const mounted of scopes) mounted.cleanup();
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
scopes.push(scope);
|
|
572
|
+
}
|
|
573
|
+
let active = true;
|
|
574
|
+
return {
|
|
575
|
+
update(nextDescriptor) {
|
|
576
|
+
if (!active || nextDescriptor.block || !matchesCompilerHostElement(element, nextDescriptor)) {
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
const nextChildren = flattenCompilerHostElements(nextDescriptor.children);
|
|
580
|
+
if (nextChildren.length !== scopes.length) return false;
|
|
581
|
+
return scopes.every((scope, index) => scope.update(nextChildren[index]));
|
|
582
|
+
},
|
|
583
|
+
cleanup() {
|
|
584
|
+
if (!active) return;
|
|
585
|
+
active = false;
|
|
586
|
+
for (const scope of scopes) scope.cleanup();
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback) {
|
|
591
|
+
const scope = mountCompilerHostTree(owner, element, descriptor, onFallback);
|
|
592
|
+
if (!scope) return null;
|
|
593
|
+
const instance = {
|
|
594
|
+
element,
|
|
595
|
+
scope,
|
|
596
|
+
values: branch.bindings.map(() => UNSET_HOST_CONDITIONAL_BINDING)
|
|
597
|
+
};
|
|
598
|
+
try {
|
|
599
|
+
applyHostConditionalBindings(branch, instance);
|
|
600
|
+
} catch (error) {
|
|
601
|
+
scope.cleanup();
|
|
602
|
+
throw error;
|
|
603
|
+
}
|
|
604
|
+
return instance;
|
|
605
|
+
}
|
|
606
|
+
var CompilerNestedConditionalRanges = class {
|
|
607
|
+
constructor(owner, root, host, block, onFallback) {
|
|
608
|
+
this.owner = owner;
|
|
609
|
+
this.root = root;
|
|
610
|
+
this.host = host;
|
|
611
|
+
this.block = block;
|
|
612
|
+
this.onFallback = onFallback;
|
|
613
|
+
this.instances = [];
|
|
614
|
+
this.staticSegments = [];
|
|
615
|
+
this.staticScopes = [];
|
|
616
|
+
this.staticValues = [];
|
|
617
|
+
this.active = true;
|
|
618
|
+
this.refresh = (afterCommit) => {
|
|
619
|
+
if (!this.active) {
|
|
620
|
+
afterCommit?.();
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const selections = this.readSelections();
|
|
624
|
+
if (!selections || selections.length !== this.instances.length) {
|
|
625
|
+
this.onFallback();
|
|
626
|
+
afterCommit?.();
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
630
|
+
this.onFallback();
|
|
631
|
+
afterCommit?.();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
for (let index = this.instances.length - 1; index >= 0; index -= 1) {
|
|
635
|
+
if (!this.reconcileRange(index, selections[index])) {
|
|
636
|
+
this.onFallback();
|
|
637
|
+
afterCommit?.();
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
afterCommit?.();
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
readSelections() {
|
|
645
|
+
const selections = [];
|
|
646
|
+
for (const range of this.block.ranges) {
|
|
647
|
+
const selection = hostConditionalSelection(range);
|
|
648
|
+
if (selection.kind === "fallback") return null;
|
|
649
|
+
selections.push(selection);
|
|
650
|
+
}
|
|
651
|
+
return selections;
|
|
652
|
+
}
|
|
653
|
+
mountStatic(elements, descriptors) {
|
|
654
|
+
if (elements.length !== descriptors.length) return false;
|
|
655
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
656
|
+
const scope = mountCompilerHostTree(
|
|
657
|
+
this.owner,
|
|
658
|
+
elements[index],
|
|
659
|
+
descriptors[index],
|
|
660
|
+
this.onFallback
|
|
661
|
+
);
|
|
662
|
+
if (!scope) return false;
|
|
663
|
+
this.staticScopes.push(scope);
|
|
664
|
+
}
|
|
665
|
+
return true;
|
|
666
|
+
}
|
|
667
|
+
adopt() {
|
|
668
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
669
|
+
const selections = this.readSelections();
|
|
670
|
+
if (!selections) return false;
|
|
671
|
+
const elements = [...this.root.children];
|
|
672
|
+
const descriptors = flattenCompilerHostElements(this.host.children);
|
|
673
|
+
if (elements.length !== descriptors.length) return false;
|
|
674
|
+
let cursor = 0;
|
|
675
|
+
for (let index = 0; index < this.block.ranges.length; index += 1) {
|
|
676
|
+
const range = this.block.ranges[index];
|
|
677
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
678
|
+
this.cleanup();
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
const staticEnd = cursor + range.before;
|
|
682
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
683
|
+
this.cleanup();
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
686
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
687
|
+
cursor = staticEnd;
|
|
688
|
+
const selection = selections[index];
|
|
689
|
+
if (selection.kind === "empty") {
|
|
690
|
+
this.instances.push(null);
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
const element = elements[cursor];
|
|
694
|
+
if (!element) {
|
|
695
|
+
this.cleanup();
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
const descriptor = selection.branch.create();
|
|
699
|
+
const host = mountCompilerHostInstance(
|
|
700
|
+
this.owner,
|
|
701
|
+
element,
|
|
702
|
+
descriptor,
|
|
703
|
+
selection.branch,
|
|
704
|
+
this.onFallback
|
|
705
|
+
);
|
|
706
|
+
if (!host) {
|
|
707
|
+
this.cleanup();
|
|
708
|
+
return false;
|
|
709
|
+
}
|
|
710
|
+
this.instances.push({ key: selection.key, host });
|
|
711
|
+
cursor += 1;
|
|
712
|
+
}
|
|
713
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
714
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
715
|
+
this.cleanup();
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
719
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
720
|
+
this.cleanup();
|
|
721
|
+
return false;
|
|
722
|
+
}
|
|
723
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
724
|
+
return true;
|
|
725
|
+
}
|
|
726
|
+
anchorAfter(rangeIndex) {
|
|
727
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
728
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
729
|
+
if (staticAnchor) return staticAnchor;
|
|
730
|
+
const rangeAnchor = this.instances[next]?.host.element;
|
|
731
|
+
if (rangeAnchor) return rangeAnchor;
|
|
732
|
+
}
|
|
733
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
734
|
+
}
|
|
735
|
+
reconcileRange(rangeIndex, selection) {
|
|
736
|
+
const previous = this.instances[rangeIndex];
|
|
737
|
+
if (selection.kind === "empty") {
|
|
738
|
+
previous?.host.scope?.cleanup();
|
|
739
|
+
previous?.host.element.remove();
|
|
740
|
+
this.instances[rangeIndex] = null;
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
if (previous?.key === selection.key) {
|
|
744
|
+
const descriptor2 = selection.branch.create();
|
|
745
|
+
if (!previous.host.scope?.update(descriptor2)) return false;
|
|
746
|
+
applyHostConditionalBindings(selection.branch, previous.host);
|
|
747
|
+
return true;
|
|
748
|
+
}
|
|
749
|
+
const descriptor = selection.branch.create();
|
|
750
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
751
|
+
const host = mountCompilerHostInstance(
|
|
752
|
+
this.owner,
|
|
753
|
+
element,
|
|
754
|
+
descriptor,
|
|
755
|
+
selection.branch,
|
|
756
|
+
this.onFallback
|
|
757
|
+
);
|
|
758
|
+
if (!host) return false;
|
|
759
|
+
previous?.host.scope?.cleanup();
|
|
760
|
+
if (previous) previous.host.element.replaceWith(element);
|
|
761
|
+
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
762
|
+
this.instances[rangeIndex] = { key: selection.key, host };
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
updateStaticScopes(descriptor, selections) {
|
|
766
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
767
|
+
let descriptorIndex = 0;
|
|
768
|
+
let scopeIndex = 0;
|
|
769
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
770
|
+
const range = this.block.ranges[rangeIndex];
|
|
771
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
772
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
773
|
+
const child = descriptors[descriptorIndex++];
|
|
774
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
775
|
+
}
|
|
776
|
+
if (selections[rangeIndex].kind === "branch") descriptorIndex += 1;
|
|
777
|
+
}
|
|
778
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
779
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
780
|
+
const child = descriptors[descriptorIndex++];
|
|
781
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
782
|
+
}
|
|
783
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
784
|
+
}
|
|
785
|
+
update(descriptor) {
|
|
786
|
+
const block = descriptor.block;
|
|
787
|
+
if (!this.active || block?.kind !== "conditional-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
|
|
788
|
+
return false;
|
|
789
|
+
}
|
|
790
|
+
this.host = descriptor;
|
|
791
|
+
this.block = block;
|
|
792
|
+
const selections = this.readSelections();
|
|
793
|
+
if (!selections || !this.updateStaticScopes(descriptor, selections) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
for (let index = this.instances.length - 1; index >= 0; index -= 1) {
|
|
797
|
+
if (!this.reconcileRange(index, selections[index])) return false;
|
|
798
|
+
}
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
801
|
+
cleanup() {
|
|
802
|
+
if (!this.active) return;
|
|
803
|
+
this.active = false;
|
|
804
|
+
this.unsubscribe?.();
|
|
805
|
+
for (const instance of this.instances) instance?.host.scope?.cleanup();
|
|
806
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
807
|
+
this.instances.length = 0;
|
|
808
|
+
this.staticSegments.length = 0;
|
|
809
|
+
this.staticScopes.length = 0;
|
|
810
|
+
this.staticValues.length = 0;
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
var CompilerNestedKeyedRanges = class {
|
|
814
|
+
constructor(owner, root, host, block, onFallback) {
|
|
815
|
+
this.owner = owner;
|
|
816
|
+
this.root = root;
|
|
817
|
+
this.host = host;
|
|
818
|
+
this.block = block;
|
|
819
|
+
this.onFallback = onFallback;
|
|
820
|
+
this.instances = [];
|
|
821
|
+
this.staticSegments = [];
|
|
822
|
+
this.staticScopes = [];
|
|
823
|
+
this.staticValues = [];
|
|
824
|
+
this.active = true;
|
|
825
|
+
this.refresh = (afterCommit) => {
|
|
826
|
+
if (!this.active) {
|
|
827
|
+
afterCommit?.();
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const rowsByRange = this.readRanges();
|
|
831
|
+
if (!rowsByRange || rowsByRange.length !== this.instances.length) {
|
|
832
|
+
this.onFallback();
|
|
833
|
+
afterCommit?.();
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
837
|
+
this.onFallback();
|
|
838
|
+
afterCommit?.();
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const activeElement = this.root.ownerDocument.activeElement;
|
|
842
|
+
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
843
|
+
for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
|
|
844
|
+
if (!this.reconcileRange(index, rowsByRange[index])) {
|
|
845
|
+
this.onFallback();
|
|
846
|
+
afterCommit?.();
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
851
|
+
activeElement.focus({ preventScroll: true });
|
|
852
|
+
}
|
|
853
|
+
afterCommit?.();
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
readRange(range) {
|
|
857
|
+
const items = materializeIterable(range.items());
|
|
858
|
+
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
859
|
+
return new Set(keys).size === keys.length ? { items, keys } : null;
|
|
860
|
+
}
|
|
861
|
+
readRanges() {
|
|
862
|
+
const ranges = [];
|
|
863
|
+
for (const range of this.block.ranges) {
|
|
864
|
+
const rows = this.readRange(range);
|
|
865
|
+
if (!rows) return null;
|
|
866
|
+
ranges.push(rows);
|
|
867
|
+
}
|
|
868
|
+
return ranges;
|
|
869
|
+
}
|
|
870
|
+
mountStatic(elements, descriptors) {
|
|
871
|
+
if (elements.length !== descriptors.length) return false;
|
|
872
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
873
|
+
const scope = mountCompilerHostTree(
|
|
874
|
+
this.owner,
|
|
875
|
+
elements[index],
|
|
876
|
+
descriptors[index],
|
|
877
|
+
this.onFallback
|
|
878
|
+
);
|
|
879
|
+
if (!scope) return false;
|
|
880
|
+
this.staticScopes.push(scope);
|
|
881
|
+
}
|
|
882
|
+
return true;
|
|
883
|
+
}
|
|
884
|
+
adopt() {
|
|
885
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
886
|
+
const rowsByRange = this.readRanges();
|
|
887
|
+
if (!rowsByRange) return false;
|
|
888
|
+
const elements = [...this.root.children];
|
|
889
|
+
const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(this.host));
|
|
890
|
+
if (elements.length !== descriptors.length) return false;
|
|
891
|
+
let cursor = 0;
|
|
892
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
893
|
+
const range = this.block.ranges[rangeIndex];
|
|
894
|
+
const rows = rowsByRange[rangeIndex];
|
|
895
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
896
|
+
this.cleanup();
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
const staticEnd = cursor + range.before;
|
|
900
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
901
|
+
this.cleanup();
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
905
|
+
cursor = staticEnd;
|
|
906
|
+
const instances = /* @__PURE__ */ new Map();
|
|
907
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
908
|
+
const element = elements[cursor + index];
|
|
909
|
+
if (!element) {
|
|
910
|
+
this.cleanup();
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
const descriptor = range.create(rows.items[index], index);
|
|
914
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
915
|
+
if (!scope) {
|
|
916
|
+
this.cleanup();
|
|
917
|
+
return false;
|
|
918
|
+
}
|
|
919
|
+
instances.set(rows.keys[index], {
|
|
920
|
+
key: rows.keys[index],
|
|
921
|
+
element,
|
|
922
|
+
scope,
|
|
923
|
+
values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
|
|
924
|
+
item: rows.items[index],
|
|
925
|
+
index,
|
|
926
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
927
|
+
});
|
|
928
|
+
applyKeyedRowBindings(range, instances.get(rows.keys[index]), rows.items[index], index);
|
|
929
|
+
}
|
|
930
|
+
this.instances.push(instances);
|
|
931
|
+
cursor += rows.items.length;
|
|
932
|
+
}
|
|
933
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
934
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
935
|
+
this.cleanup();
|
|
936
|
+
return false;
|
|
937
|
+
}
|
|
938
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
939
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
940
|
+
this.cleanup();
|
|
941
|
+
return false;
|
|
942
|
+
}
|
|
943
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
944
|
+
return true;
|
|
945
|
+
}
|
|
946
|
+
anchorAfter(rangeIndex) {
|
|
947
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
948
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
949
|
+
if (staticAnchor) return staticAnchor;
|
|
950
|
+
const rowAnchor = this.instances[next].values().next().value?.element;
|
|
951
|
+
if (rowAnchor) return rowAnchor;
|
|
952
|
+
}
|
|
953
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
954
|
+
}
|
|
955
|
+
reconcileRange(rangeIndex, rows) {
|
|
956
|
+
const range = this.block.ranges[rangeIndex];
|
|
957
|
+
const previous = this.instances[rangeIndex];
|
|
958
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
959
|
+
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
960
|
+
const nextKeys = new Set(rows.keys);
|
|
961
|
+
for (const [key, instance] of previous) {
|
|
962
|
+
if (nextKeys.has(key)) continue;
|
|
963
|
+
instance.scope?.cleanup();
|
|
964
|
+
instance.element.remove();
|
|
965
|
+
}
|
|
966
|
+
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
967
|
+
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
968
|
+
const nextInstances = [];
|
|
969
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
970
|
+
const key = rows.keys[index];
|
|
971
|
+
const existing = previous.get(key);
|
|
972
|
+
if (existing) {
|
|
973
|
+
const descriptor2 = range.create(rows.items[index], index);
|
|
974
|
+
if (!existing.scope?.update(descriptor2)) return false;
|
|
975
|
+
applyKeyedRowBindings(range, existing, rows.items[index], index);
|
|
976
|
+
existing.item = rows.items[index];
|
|
977
|
+
existing.index = index;
|
|
978
|
+
nextInstances.push(existing);
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
const descriptor = range.create(rows.items[index], index);
|
|
982
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
983
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
984
|
+
if (!scope) return false;
|
|
985
|
+
nextInstances.push({
|
|
986
|
+
key,
|
|
987
|
+
element,
|
|
988
|
+
scope,
|
|
989
|
+
values: readKeyedRowBindingValues(range, rows.items[index], index),
|
|
990
|
+
item: rows.items[index],
|
|
991
|
+
index,
|
|
992
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
let anchor = this.anchorAfter(rangeIndex);
|
|
996
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
997
|
+
const instance = nextInstances[index];
|
|
998
|
+
if (sequence[index] < 0 || !stablePositions.has(index) && instance.element.nextSibling !== anchor) {
|
|
999
|
+
this.root.insertBefore(instance.element, anchor);
|
|
1000
|
+
}
|
|
1001
|
+
anchor = instance.element;
|
|
1002
|
+
}
|
|
1003
|
+
this.instances[rangeIndex] = new Map(nextInstances.map((instance) => [instance.key, instance]));
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
updateStaticScopes(descriptor, rowsByRange) {
|
|
1007
|
+
const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(descriptor));
|
|
1008
|
+
let descriptorIndex = 0;
|
|
1009
|
+
let scopeIndex = 0;
|
|
1010
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1011
|
+
const range = this.block.ranges[rangeIndex];
|
|
1012
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
1013
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1014
|
+
const child = descriptors[descriptorIndex++];
|
|
1015
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1016
|
+
}
|
|
1017
|
+
descriptorIndex += rowsByRange[rangeIndex].items.length;
|
|
1018
|
+
}
|
|
1019
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
1020
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1021
|
+
const child = descriptors[descriptorIndex++];
|
|
1022
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1023
|
+
}
|
|
1024
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
1025
|
+
}
|
|
1026
|
+
update(descriptor) {
|
|
1027
|
+
const block = descriptor.block;
|
|
1028
|
+
if (!this.active || block?.kind !== "keyed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
this.host = descriptor;
|
|
1032
|
+
this.block = block;
|
|
1033
|
+
const rowsByRange = this.readRanges();
|
|
1034
|
+
if (!rowsByRange || rowsByRange.length !== this.instances.length || !this.updateStaticScopes(descriptor, rowsByRange) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
|
|
1038
|
+
if (!this.reconcileRange(index, rowsByRange[index])) return false;
|
|
1039
|
+
}
|
|
1040
|
+
return true;
|
|
1041
|
+
}
|
|
1042
|
+
cleanup() {
|
|
1043
|
+
if (!this.active) return;
|
|
1044
|
+
this.active = false;
|
|
1045
|
+
this.unsubscribe?.();
|
|
1046
|
+
for (const instances of this.instances) {
|
|
1047
|
+
for (const instance of instances.values()) instance.scope?.cleanup();
|
|
1048
|
+
}
|
|
1049
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
1050
|
+
this.instances.length = 0;
|
|
1051
|
+
this.staticSegments.length = 0;
|
|
1052
|
+
this.staticScopes.length = 0;
|
|
1053
|
+
this.staticValues.length = 0;
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
var CompilerNestedMixedRanges = class {
|
|
1057
|
+
constructor(owner, root, host, block, onFallback) {
|
|
1058
|
+
this.owner = owner;
|
|
1059
|
+
this.root = root;
|
|
1060
|
+
this.host = host;
|
|
1061
|
+
this.block = block;
|
|
1062
|
+
this.onFallback = onFallback;
|
|
1063
|
+
this.instances = [];
|
|
1064
|
+
this.staticSegments = [];
|
|
1065
|
+
this.staticScopes = [];
|
|
1066
|
+
this.staticValues = [];
|
|
1067
|
+
this.active = true;
|
|
1068
|
+
this.refresh = (afterCommit) => {
|
|
1069
|
+
if (!this.active) {
|
|
1070
|
+
afterCommit?.();
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
const snapshots = this.readSnapshots();
|
|
1074
|
+
if (!snapshots || snapshots.length !== this.instances.length) {
|
|
1075
|
+
this.onFallback();
|
|
1076
|
+
afterCommit?.();
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1080
|
+
this.onFallback();
|
|
1081
|
+
afterCommit?.();
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
const activeElement = this.root.ownerDocument.activeElement;
|
|
1085
|
+
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
1086
|
+
for (let index = snapshots.length - 1; index >= 0; index -= 1) {
|
|
1087
|
+
if (!this.reconcileRange(index, snapshots[index])) {
|
|
1088
|
+
this.onFallback();
|
|
1089
|
+
afterCommit?.();
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
1094
|
+
activeElement.focus({ preventScroll: true });
|
|
1095
|
+
}
|
|
1096
|
+
afterCommit?.();
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
readSnapshots() {
|
|
1100
|
+
const snapshots = [];
|
|
1101
|
+
for (const range of this.block.ranges) {
|
|
1102
|
+
if (range.kind === "conditional") {
|
|
1103
|
+
const selection = hostConditionalSelection(range);
|
|
1104
|
+
if (selection.kind === "fallback") return null;
|
|
1105
|
+
snapshots.push({ kind: "conditional", selection });
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
const items = materializeIterable(range.items());
|
|
1109
|
+
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
1110
|
+
if (new Set(keys).size !== keys.length) return null;
|
|
1111
|
+
snapshots.push({ kind: "keyed", rows: { items, keys } });
|
|
1112
|
+
}
|
|
1113
|
+
return snapshots;
|
|
1114
|
+
}
|
|
1115
|
+
mountStatic(elements, descriptors) {
|
|
1116
|
+
if (elements.length !== descriptors.length) return false;
|
|
1117
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
1118
|
+
const scope = mountCompilerHostTree(
|
|
1119
|
+
this.owner,
|
|
1120
|
+
elements[index],
|
|
1121
|
+
descriptors[index],
|
|
1122
|
+
this.onFallback
|
|
1123
|
+
);
|
|
1124
|
+
if (!scope) return false;
|
|
1125
|
+
this.staticScopes.push(scope);
|
|
1126
|
+
}
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
adopt() {
|
|
1130
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
1131
|
+
const snapshots = this.readSnapshots();
|
|
1132
|
+
if (!snapshots) return false;
|
|
1133
|
+
const elements = [...this.root.children];
|
|
1134
|
+
const descriptors = flattenCompilerHostElements(this.host.children);
|
|
1135
|
+
if (elements.length !== descriptors.length) return false;
|
|
1136
|
+
let cursor = 0;
|
|
1137
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1138
|
+
const range = this.block.ranges[rangeIndex];
|
|
1139
|
+
const snapshot = snapshots[rangeIndex];
|
|
1140
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0 || range.kind !== snapshot.kind) {
|
|
1141
|
+
this.cleanup();
|
|
1142
|
+
return false;
|
|
1143
|
+
}
|
|
1144
|
+
const staticEnd = cursor + range.before;
|
|
1145
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
1146
|
+
this.cleanup();
|
|
1147
|
+
return false;
|
|
1148
|
+
}
|
|
1149
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
1150
|
+
cursor = staticEnd;
|
|
1151
|
+
if (range.kind === "conditional" && snapshot.kind === "conditional") {
|
|
1152
|
+
if (snapshot.selection.kind === "empty") {
|
|
1153
|
+
this.instances.push({ kind: "conditional", value: null });
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
const element = elements[cursor];
|
|
1157
|
+
if (!element) {
|
|
1158
|
+
this.cleanup();
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1161
|
+
const descriptor = snapshot.selection.branch.create();
|
|
1162
|
+
const host = mountCompilerHostInstance(
|
|
1163
|
+
this.owner,
|
|
1164
|
+
element,
|
|
1165
|
+
descriptor,
|
|
1166
|
+
snapshot.selection.branch,
|
|
1167
|
+
this.onFallback
|
|
1168
|
+
);
|
|
1169
|
+
if (!host) {
|
|
1170
|
+
this.cleanup();
|
|
1171
|
+
return false;
|
|
1172
|
+
}
|
|
1173
|
+
this.instances.push({
|
|
1174
|
+
kind: "conditional",
|
|
1175
|
+
value: { key: snapshot.selection.key, host }
|
|
1176
|
+
});
|
|
1177
|
+
cursor += 1;
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
if (range.kind !== "keyed" || snapshot.kind !== "keyed") {
|
|
1181
|
+
this.cleanup();
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1184
|
+
const keyedInstances = /* @__PURE__ */ new Map();
|
|
1185
|
+
for (let index = 0; index < snapshot.rows.items.length; index += 1) {
|
|
1186
|
+
const element = elements[cursor + index];
|
|
1187
|
+
if (!element) {
|
|
1188
|
+
this.cleanup();
|
|
1189
|
+
return false;
|
|
1190
|
+
}
|
|
1191
|
+
const descriptor = range.create(snapshot.rows.items[index], index);
|
|
1192
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
1193
|
+
if (!scope) {
|
|
1194
|
+
this.cleanup();
|
|
1195
|
+
return false;
|
|
1196
|
+
}
|
|
1197
|
+
const instance = {
|
|
1198
|
+
key: snapshot.rows.keys[index],
|
|
1199
|
+
element,
|
|
1200
|
+
scope,
|
|
1201
|
+
values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
|
|
1202
|
+
item: snapshot.rows.items[index],
|
|
1203
|
+
index,
|
|
1204
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
1205
|
+
};
|
|
1206
|
+
try {
|
|
1207
|
+
applyKeyedRowBindings(range, instance, snapshot.rows.items[index], index);
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
scope.cleanup();
|
|
1210
|
+
throw error;
|
|
1211
|
+
}
|
|
1212
|
+
keyedInstances.set(snapshot.rows.keys[index], instance);
|
|
1213
|
+
}
|
|
1214
|
+
this.instances.push({ kind: "keyed", value: keyedInstances });
|
|
1215
|
+
cursor += snapshot.rows.items.length;
|
|
1216
|
+
}
|
|
1217
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
1218
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
1219
|
+
this.cleanup();
|
|
1220
|
+
return false;
|
|
1221
|
+
}
|
|
1222
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
1223
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1224
|
+
this.cleanup();
|
|
1225
|
+
return false;
|
|
1226
|
+
}
|
|
1227
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
1228
|
+
return true;
|
|
1229
|
+
}
|
|
1230
|
+
firstInstanceElement(instance) {
|
|
1231
|
+
if (instance.kind === "conditional") return instance.value?.host.element || null;
|
|
1232
|
+
return instance.value.values().next().value?.element || null;
|
|
1233
|
+
}
|
|
1234
|
+
anchorAfter(rangeIndex) {
|
|
1235
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
1236
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
1237
|
+
if (staticAnchor) return staticAnchor;
|
|
1238
|
+
const rangeAnchor = this.firstInstanceElement(this.instances[next]);
|
|
1239
|
+
if (rangeAnchor) return rangeAnchor;
|
|
1240
|
+
}
|
|
1241
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
1242
|
+
}
|
|
1243
|
+
reconcileConditional(rangeIndex, range, selection) {
|
|
1244
|
+
const instance = this.instances[rangeIndex];
|
|
1245
|
+
if (instance.kind !== "conditional") return false;
|
|
1246
|
+
const previous = instance.value;
|
|
1247
|
+
if (selection.kind === "empty") {
|
|
1248
|
+
previous?.host.scope?.cleanup();
|
|
1249
|
+
previous?.host.element.remove();
|
|
1250
|
+
instance.value = null;
|
|
1251
|
+
return true;
|
|
1252
|
+
}
|
|
1253
|
+
if (previous?.key === selection.key) {
|
|
1254
|
+
const descriptor2 = selection.branch.create();
|
|
1255
|
+
if (!previous.host.scope?.update(descriptor2)) return false;
|
|
1256
|
+
applyHostConditionalBindings(selection.branch, previous.host);
|
|
1257
|
+
return true;
|
|
1258
|
+
}
|
|
1259
|
+
const descriptor = selection.branch.create();
|
|
1260
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1261
|
+
const host = mountCompilerHostInstance(
|
|
1262
|
+
this.owner,
|
|
1263
|
+
element,
|
|
1264
|
+
descriptor,
|
|
1265
|
+
selection.branch,
|
|
1266
|
+
this.onFallback
|
|
1267
|
+
);
|
|
1268
|
+
if (!host) return false;
|
|
1269
|
+
previous?.host.scope?.cleanup();
|
|
1270
|
+
if (previous) previous.host.element.replaceWith(element);
|
|
1271
|
+
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
1272
|
+
instance.value = { key: selection.key, host };
|
|
1273
|
+
return true;
|
|
1274
|
+
}
|
|
1275
|
+
reconcileKeyed(rangeIndex, range, rows) {
|
|
1276
|
+
const instance = this.instances[rangeIndex];
|
|
1277
|
+
if (instance.kind !== "keyed") return false;
|
|
1278
|
+
const previous = instance.value;
|
|
1279
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
1280
|
+
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
1281
|
+
const nextKeys = new Set(rows.keys);
|
|
1282
|
+
for (const [key, row] of previous) {
|
|
1283
|
+
if (nextKeys.has(key)) continue;
|
|
1284
|
+
row.scope?.cleanup();
|
|
1285
|
+
row.element.remove();
|
|
1286
|
+
}
|
|
1287
|
+
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
1288
|
+
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
1289
|
+
const nextInstances = [];
|
|
1290
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
1291
|
+
const key = rows.keys[index];
|
|
1292
|
+
const existing = previous.get(key);
|
|
1293
|
+
if (existing) {
|
|
1294
|
+
const descriptor2 = range.create(rows.items[index], index);
|
|
1295
|
+
if (!existing.scope?.update(descriptor2)) return false;
|
|
1296
|
+
applyKeyedRowBindings(range, existing, rows.items[index], index);
|
|
1297
|
+
existing.item = rows.items[index];
|
|
1298
|
+
existing.index = index;
|
|
1299
|
+
nextInstances.push(existing);
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
const descriptor = range.create(rows.items[index], index);
|
|
1303
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1304
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
1305
|
+
if (!scope) return false;
|
|
1306
|
+
let values;
|
|
1307
|
+
try {
|
|
1308
|
+
values = readKeyedRowBindingValues(range, rows.items[index], index);
|
|
1309
|
+
} catch (error) {
|
|
1310
|
+
scope.cleanup();
|
|
1311
|
+
throw error;
|
|
1312
|
+
}
|
|
1313
|
+
nextInstances.push({
|
|
1314
|
+
key,
|
|
1315
|
+
element,
|
|
1316
|
+
scope,
|
|
1317
|
+
values,
|
|
1318
|
+
item: rows.items[index],
|
|
1319
|
+
index,
|
|
1320
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1323
|
+
let anchor = this.anchorAfter(rangeIndex);
|
|
1324
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
1325
|
+
const row = nextInstances[index];
|
|
1326
|
+
if (sequence[index] < 0 || !stablePositions.has(index) && row.element.nextSibling !== anchor) {
|
|
1327
|
+
this.root.insertBefore(row.element, anchor);
|
|
1328
|
+
}
|
|
1329
|
+
anchor = row.element;
|
|
1330
|
+
}
|
|
1331
|
+
instance.value = new Map(nextInstances.map((row) => [row.key, row]));
|
|
1332
|
+
return true;
|
|
1333
|
+
}
|
|
1334
|
+
reconcileRange(rangeIndex, snapshot) {
|
|
1335
|
+
const range = this.block.ranges[rangeIndex];
|
|
1336
|
+
if (range.kind !== snapshot.kind) return false;
|
|
1337
|
+
return range.kind === "conditional" && snapshot.kind === "conditional" ? this.reconcileConditional(rangeIndex, range, snapshot.selection) : range.kind === "keyed" && snapshot.kind === "keyed" ? this.reconcileKeyed(rangeIndex, range, snapshot.rows) : false;
|
|
1338
|
+
}
|
|
1339
|
+
updateStaticScopes(descriptor, snapshots) {
|
|
1340
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
1341
|
+
let descriptorIndex = 0;
|
|
1342
|
+
let scopeIndex = 0;
|
|
1343
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1344
|
+
const range = this.block.ranges[rangeIndex];
|
|
1345
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
1346
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1347
|
+
const child = descriptors[descriptorIndex++];
|
|
1348
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1349
|
+
}
|
|
1350
|
+
const snapshot = snapshots[rangeIndex];
|
|
1351
|
+
if (snapshot.kind === "conditional") {
|
|
1352
|
+
if (snapshot.selection.kind === "branch") descriptorIndex += 1;
|
|
1353
|
+
} else {
|
|
1354
|
+
descriptorIndex += snapshot.rows.items.length;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
1358
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1359
|
+
const child = descriptors[descriptorIndex++];
|
|
1360
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1361
|
+
}
|
|
1362
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
1363
|
+
}
|
|
1364
|
+
update(descriptor) {
|
|
1365
|
+
const block = descriptor.block;
|
|
1366
|
+
if (!this.active || block?.kind !== "mixed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some(
|
|
1367
|
+
(range, index) => range.kind !== this.block.ranges[index].kind || range.before !== this.block.ranges[index].before
|
|
1368
|
+
)) {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
this.host = descriptor;
|
|
1372
|
+
this.block = block;
|
|
1373
|
+
const snapshots = this.readSnapshots();
|
|
1374
|
+
if (!snapshots || snapshots.length !== this.instances.length || !this.updateStaticScopes(descriptor, snapshots) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
for (let index = snapshots.length - 1; index >= 0; index -= 1) {
|
|
1378
|
+
if (!this.reconcileRange(index, snapshots[index])) return false;
|
|
1379
|
+
}
|
|
1380
|
+
return true;
|
|
1381
|
+
}
|
|
1382
|
+
cleanup() {
|
|
1383
|
+
if (!this.active) return;
|
|
1384
|
+
this.active = false;
|
|
1385
|
+
this.unsubscribe?.();
|
|
1386
|
+
for (const instance of this.instances) {
|
|
1387
|
+
if (instance.kind === "conditional") {
|
|
1388
|
+
instance.value?.host.scope?.cleanup();
|
|
1389
|
+
} else {
|
|
1390
|
+
for (const row of instance.value.values()) row.scope?.cleanup();
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
1394
|
+
this.instances.length = 0;
|
|
1395
|
+
this.staticSegments.length = 0;
|
|
1396
|
+
this.staticScopes.length = 0;
|
|
1397
|
+
this.staticValues.length = 0;
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
384
1400
|
function createHostConditionalBlockComponent(owner) {
|
|
385
1401
|
class FarmHostConditionalBlock extends React__default.default.Component {
|
|
386
1402
|
constructor() {
|
|
@@ -392,8 +1408,13 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
392
1408
|
this.fallbackVersion = 0;
|
|
393
1409
|
this.propSyncQueued = false;
|
|
394
1410
|
this.currentProps = this.props;
|
|
1411
|
+
this.fallbackUnsubscribers = [];
|
|
395
1412
|
this.activeBranch = null;
|
|
396
1413
|
this.instance = null;
|
|
1414
|
+
this.requestNestedFallback = () => {
|
|
1415
|
+
this.instance?.scope?.cleanup();
|
|
1416
|
+
this.activateFallback();
|
|
1417
|
+
};
|
|
397
1418
|
this.captureRoot = (root) => {
|
|
398
1419
|
this.root = root;
|
|
399
1420
|
};
|
|
@@ -401,6 +1422,26 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
401
1422
|
this.reconcile(afterCommit);
|
|
402
1423
|
};
|
|
403
1424
|
}
|
|
1425
|
+
subscribeFallbackDescendants() {
|
|
1426
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1427
|
+
this.fallbackUnsubscribers = [];
|
|
1428
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1429
|
+
if (this.currentProps.truthy) {
|
|
1430
|
+
collectCompilerHostBlockIds(this.currentProps.truthy.create(), ids);
|
|
1431
|
+
}
|
|
1432
|
+
if (this.currentProps.falsy) {
|
|
1433
|
+
collectCompilerHostBlockIds(this.currentProps.falsy.create(), ids);
|
|
1434
|
+
}
|
|
1435
|
+
ids.delete(this.currentProps.id);
|
|
1436
|
+
for (const id of ids) {
|
|
1437
|
+
this.fallbackUnsubscribers.push(
|
|
1438
|
+
owner.subscribe(id, (afterCommit) => {
|
|
1439
|
+
this.fallbackVersion += 1;
|
|
1440
|
+
this.forceUpdate(afterCommit);
|
|
1441
|
+
})
|
|
1442
|
+
);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
404
1445
|
adopt() {
|
|
405
1446
|
if (!this.root) return false;
|
|
406
1447
|
const selection = hostConditionalSelection(this.currentProps);
|
|
@@ -417,11 +1458,16 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
417
1458
|
const descriptor = selection.branch.create();
|
|
418
1459
|
const element = this.root.firstElementChild;
|
|
419
1460
|
if (!matchesCompilerHostElement(element, descriptor)) return false;
|
|
420
|
-
|
|
421
|
-
|
|
1461
|
+
const instance = mountCompilerHostInstance(
|
|
1462
|
+
owner,
|
|
422
1463
|
element,
|
|
423
|
-
|
|
424
|
-
|
|
1464
|
+
descriptor,
|
|
1465
|
+
selection.branch,
|
|
1466
|
+
this.requestNestedFallback
|
|
1467
|
+
);
|
|
1468
|
+
if (!instance) return false;
|
|
1469
|
+
this.activeBranch = selection.key;
|
|
1470
|
+
this.instance = instance;
|
|
425
1471
|
return true;
|
|
426
1472
|
}
|
|
427
1473
|
activateFallback(afterCommit) {
|
|
@@ -430,6 +1476,10 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
430
1476
|
return;
|
|
431
1477
|
}
|
|
432
1478
|
this.fallbackRequested = true;
|
|
1479
|
+
this.instance?.scope?.cleanup();
|
|
1480
|
+
this.instance = null;
|
|
1481
|
+
this.activeBranch = null;
|
|
1482
|
+
this.subscribeFallbackDescendants();
|
|
433
1483
|
this.fallbackVersion += 1;
|
|
434
1484
|
this.setState({ fallback: true }, afterCommit);
|
|
435
1485
|
}
|
|
@@ -448,6 +1498,7 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
448
1498
|
return;
|
|
449
1499
|
}
|
|
450
1500
|
if (selection.kind === "empty") {
|
|
1501
|
+
this.instance?.scope?.cleanup();
|
|
451
1502
|
if (this.instance) this.instance.element.remove();
|
|
452
1503
|
this.activeBranch = null;
|
|
453
1504
|
this.instance = null;
|
|
@@ -455,17 +1506,40 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
455
1506
|
return;
|
|
456
1507
|
}
|
|
457
1508
|
if (this.activeBranch === selection.key && this.instance) {
|
|
1509
|
+
const descriptor2 = selection.branch.create();
|
|
1510
|
+
const scope = mountCompilerHostTree(
|
|
1511
|
+
owner,
|
|
1512
|
+
this.instance.element,
|
|
1513
|
+
descriptor2,
|
|
1514
|
+
this.requestNestedFallback
|
|
1515
|
+
);
|
|
1516
|
+
if (!scope) {
|
|
1517
|
+
this.activateFallback(afterCommit);
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
this.instance.scope?.cleanup();
|
|
1521
|
+
this.instance.scope = scope;
|
|
458
1522
|
applyHostConditionalBindings(selection.branch, this.instance);
|
|
459
1523
|
afterCommit?.();
|
|
460
1524
|
return;
|
|
461
1525
|
}
|
|
462
|
-
const
|
|
1526
|
+
const descriptor = selection.branch.create();
|
|
1527
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1528
|
+
const instance = mountCompilerHostInstance(
|
|
1529
|
+
owner,
|
|
1530
|
+
element,
|
|
1531
|
+
descriptor,
|
|
1532
|
+
selection.branch,
|
|
1533
|
+
this.requestNestedFallback
|
|
1534
|
+
);
|
|
1535
|
+
if (!instance) {
|
|
1536
|
+
this.activateFallback(afterCommit);
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
this.instance?.scope?.cleanup();
|
|
463
1540
|
this.root.replaceChildren(element);
|
|
464
1541
|
this.activeBranch = selection.key;
|
|
465
|
-
this.instance =
|
|
466
|
-
element,
|
|
467
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
468
|
-
};
|
|
1542
|
+
this.instance = instance;
|
|
469
1543
|
afterCommit?.();
|
|
470
1544
|
}
|
|
471
1545
|
schedulePropSync() {
|
|
@@ -490,6 +1564,9 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
490
1564
|
componentWillUnmount() {
|
|
491
1565
|
this.mounted = false;
|
|
492
1566
|
this.unsubscribe?.();
|
|
1567
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1568
|
+
this.fallbackUnsubscribers = [];
|
|
1569
|
+
this.instance?.scope?.cleanup();
|
|
493
1570
|
this.root = null;
|
|
494
1571
|
this.activeBranch = null;
|
|
495
1572
|
this.instance = null;
|
|
@@ -510,6 +1587,279 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
510
1587
|
FarmHostConditionalBlock.displayName = "FarmCompiledHostConditional";
|
|
511
1588
|
return FarmHostConditionalBlock;
|
|
512
1589
|
}
|
|
1590
|
+
function createConditionalRangesBlockComponent(owner) {
|
|
1591
|
+
class FarmConditionalRangesBlock extends React__default.default.Component {
|
|
1592
|
+
constructor() {
|
|
1593
|
+
super(...arguments);
|
|
1594
|
+
this.state = { fallback: false };
|
|
1595
|
+
this.root = null;
|
|
1596
|
+
this.mounted = false;
|
|
1597
|
+
this.fallbackRequested = false;
|
|
1598
|
+
this.fallbackVersion = 0;
|
|
1599
|
+
this.propFallbackQueued = false;
|
|
1600
|
+
this.currentProps = this.props;
|
|
1601
|
+
this.fallbackUnsubscribers = [];
|
|
1602
|
+
this.rangeInstances = [];
|
|
1603
|
+
this.staticSegments = [];
|
|
1604
|
+
this.staticValues = [];
|
|
1605
|
+
this.requestNestedFallback = () => {
|
|
1606
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1607
|
+
this.activateFallback();
|
|
1608
|
+
};
|
|
1609
|
+
this.captureRoot = (root) => {
|
|
1610
|
+
this.root = root;
|
|
1611
|
+
this.currentProps.rootRef?.(root);
|
|
1612
|
+
};
|
|
1613
|
+
this.refresh = (afterCommit) => {
|
|
1614
|
+
this.reconcile(afterCommit);
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
subscribeFallbackDescendants() {
|
|
1618
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1619
|
+
this.fallbackUnsubscribers = [];
|
|
1620
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1621
|
+
for (const range of this.currentProps.ranges) {
|
|
1622
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
1623
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
1624
|
+
}
|
|
1625
|
+
ids.delete(this.currentProps.id);
|
|
1626
|
+
for (const id of ids) {
|
|
1627
|
+
this.fallbackUnsubscribers.push(
|
|
1628
|
+
owner.subscribe(id, (afterCommit) => {
|
|
1629
|
+
this.fallbackVersion += 1;
|
|
1630
|
+
this.forceUpdate(afterCommit);
|
|
1631
|
+
})
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
readSelections(props) {
|
|
1636
|
+
const selections = [];
|
|
1637
|
+
for (const range of props.ranges) {
|
|
1638
|
+
const selection = hostConditionalSelection(range);
|
|
1639
|
+
if (selection.kind === "fallback") return null;
|
|
1640
|
+
selections.push(selection);
|
|
1641
|
+
}
|
|
1642
|
+
return selections;
|
|
1643
|
+
}
|
|
1644
|
+
adopt(props = this.currentProps) {
|
|
1645
|
+
if (!this.root || !Number.isSafeInteger(props.trailing) || props.trailing < 0) return false;
|
|
1646
|
+
const selections = this.readSelections(props);
|
|
1647
|
+
if (!selections) return false;
|
|
1648
|
+
const elements = [...this.root.children];
|
|
1649
|
+
const staticSegments = [];
|
|
1650
|
+
const instances = [];
|
|
1651
|
+
const cleanupInstances = () => {
|
|
1652
|
+
for (const instance of instances) instance?.host.scope?.cleanup();
|
|
1653
|
+
};
|
|
1654
|
+
let cursor = 0;
|
|
1655
|
+
for (let rangeIndex = 0; rangeIndex < props.ranges.length; rangeIndex += 1) {
|
|
1656
|
+
const range = props.ranges[rangeIndex];
|
|
1657
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
1658
|
+
cleanupInstances();
|
|
1659
|
+
return false;
|
|
1660
|
+
}
|
|
1661
|
+
const staticEnd = cursor + range.before;
|
|
1662
|
+
if (staticEnd > elements.length) {
|
|
1663
|
+
cleanupInstances();
|
|
1664
|
+
return false;
|
|
1665
|
+
}
|
|
1666
|
+
staticSegments.push(elements.slice(cursor, staticEnd));
|
|
1667
|
+
cursor = staticEnd;
|
|
1668
|
+
const selection = selections[rangeIndex];
|
|
1669
|
+
if (selection.kind === "empty") {
|
|
1670
|
+
instances.push(null);
|
|
1671
|
+
continue;
|
|
1672
|
+
}
|
|
1673
|
+
const element = elements[cursor];
|
|
1674
|
+
if (!element) {
|
|
1675
|
+
cleanupInstances();
|
|
1676
|
+
return false;
|
|
1677
|
+
}
|
|
1678
|
+
const descriptor = selection.branch.create();
|
|
1679
|
+
if (!matchesCompilerHostElement(element, descriptor)) {
|
|
1680
|
+
cleanupInstances();
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
const host = mountCompilerHostInstance(
|
|
1684
|
+
owner,
|
|
1685
|
+
element,
|
|
1686
|
+
descriptor,
|
|
1687
|
+
selection.branch,
|
|
1688
|
+
this.requestNestedFallback
|
|
1689
|
+
);
|
|
1690
|
+
if (!host) {
|
|
1691
|
+
cleanupInstances();
|
|
1692
|
+
return false;
|
|
1693
|
+
}
|
|
1694
|
+
instances.push({
|
|
1695
|
+
key: selection.key,
|
|
1696
|
+
host
|
|
1697
|
+
});
|
|
1698
|
+
cursor += 1;
|
|
1699
|
+
}
|
|
1700
|
+
if (cursor + props.trailing !== elements.length) {
|
|
1701
|
+
cleanupInstances();
|
|
1702
|
+
return false;
|
|
1703
|
+
}
|
|
1704
|
+
staticSegments.push(elements.slice(cursor));
|
|
1705
|
+
this.staticSegments = staticSegments;
|
|
1706
|
+
this.rangeInstances = instances;
|
|
1707
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
1708
|
+
cleanupInstances();
|
|
1709
|
+
this.rangeInstances = [];
|
|
1710
|
+
this.staticSegments = [];
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
return true;
|
|
1714
|
+
}
|
|
1715
|
+
anchorAfter(rangeIndex) {
|
|
1716
|
+
for (let next = rangeIndex + 1; next < this.rangeInstances.length; next += 1) {
|
|
1717
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
1718
|
+
if (staticAnchor) return staticAnchor;
|
|
1719
|
+
const rangeAnchor = this.rangeInstances[next]?.host.element;
|
|
1720
|
+
if (rangeAnchor) return rangeAnchor;
|
|
1721
|
+
}
|
|
1722
|
+
return this.staticSegments[this.rangeInstances.length]?.[0] || null;
|
|
1723
|
+
}
|
|
1724
|
+
reconcileRange(rangeIndex, selection) {
|
|
1725
|
+
if (!this.root) return false;
|
|
1726
|
+
const previous = this.rangeInstances[rangeIndex];
|
|
1727
|
+
if (selection.kind === "empty") {
|
|
1728
|
+
previous?.host.scope?.cleanup();
|
|
1729
|
+
previous?.host.element.remove();
|
|
1730
|
+
this.rangeInstances[rangeIndex] = null;
|
|
1731
|
+
return true;
|
|
1732
|
+
}
|
|
1733
|
+
if (previous?.key === selection.key) {
|
|
1734
|
+
const descriptor2 = selection.branch.create();
|
|
1735
|
+
const scope = mountCompilerHostTree(
|
|
1736
|
+
owner,
|
|
1737
|
+
previous.host.element,
|
|
1738
|
+
descriptor2,
|
|
1739
|
+
this.requestNestedFallback
|
|
1740
|
+
);
|
|
1741
|
+
if (!scope) {
|
|
1742
|
+
this.requestNestedFallback();
|
|
1743
|
+
return false;
|
|
1744
|
+
}
|
|
1745
|
+
previous.host.scope?.cleanup();
|
|
1746
|
+
previous.host.scope = scope;
|
|
1747
|
+
applyHostConditionalBindings(selection.branch, previous.host);
|
|
1748
|
+
return true;
|
|
1749
|
+
}
|
|
1750
|
+
const descriptor = selection.branch.create();
|
|
1751
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1752
|
+
const host = mountCompilerHostInstance(
|
|
1753
|
+
owner,
|
|
1754
|
+
element,
|
|
1755
|
+
descriptor,
|
|
1756
|
+
selection.branch,
|
|
1757
|
+
this.requestNestedFallback
|
|
1758
|
+
);
|
|
1759
|
+
if (!host) {
|
|
1760
|
+
this.requestNestedFallback();
|
|
1761
|
+
return false;
|
|
1762
|
+
}
|
|
1763
|
+
previous?.host.scope?.cleanup();
|
|
1764
|
+
if (previous) previous.host.element.replaceWith(element);
|
|
1765
|
+
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
1766
|
+
this.rangeInstances[rangeIndex] = {
|
|
1767
|
+
key: selection.key,
|
|
1768
|
+
host
|
|
1769
|
+
};
|
|
1770
|
+
return true;
|
|
1771
|
+
}
|
|
1772
|
+
reconcile(afterCommit) {
|
|
1773
|
+
if (!this.mounted || !this.root) {
|
|
1774
|
+
afterCommit?.();
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1777
|
+
if (this.state.fallback) {
|
|
1778
|
+
this.fallbackVersion += 1;
|
|
1779
|
+
this.forceUpdate(afterCommit);
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
if (this.currentProps.ranges.length !== this.rangeInstances.length) {
|
|
1783
|
+
this.activateFallback(afterCommit);
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1786
|
+
const selections = this.readSelections(this.currentProps);
|
|
1787
|
+
if (!selections) {
|
|
1788
|
+
this.activateFallback(afterCommit);
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
if (!applyStaticRangeBindings(
|
|
1792
|
+
this.currentProps.bindings,
|
|
1793
|
+
this.staticSegments,
|
|
1794
|
+
this.staticValues
|
|
1795
|
+
)) {
|
|
1796
|
+
this.activateFallback(afterCommit);
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
for (let rangeIndex = this.rangeInstances.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
1800
|
+
if (!this.reconcileRange(rangeIndex, selections[rangeIndex])) {
|
|
1801
|
+
afterCommit?.();
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
afterCommit?.();
|
|
1806
|
+
}
|
|
1807
|
+
activateFallback(afterCommit) {
|
|
1808
|
+
if (!this.mounted || this.state.fallback || this.fallbackRequested) {
|
|
1809
|
+
afterCommit?.();
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
this.fallbackRequested = true;
|
|
1813
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1814
|
+
this.subscribeFallbackDescendants();
|
|
1815
|
+
this.setState({ fallback: true }, afterCommit);
|
|
1816
|
+
}
|
|
1817
|
+
schedulePropFallback() {
|
|
1818
|
+
if (this.propFallbackQueued) return;
|
|
1819
|
+
this.propFallbackQueued = true;
|
|
1820
|
+
queueMicrotask(() => {
|
|
1821
|
+
this.propFallbackQueued = false;
|
|
1822
|
+
if (this.mounted && !this.state.fallback) this.activateFallback();
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1825
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
1826
|
+
this.currentProps = nextProps;
|
|
1827
|
+
if (nextState.fallback || this.state.fallback) return true;
|
|
1828
|
+
this.schedulePropFallback();
|
|
1829
|
+
return false;
|
|
1830
|
+
}
|
|
1831
|
+
componentDidMount() {
|
|
1832
|
+
this.mounted = true;
|
|
1833
|
+
this.unsubscribe = owner.subscribe(this.props.id, this.refresh);
|
|
1834
|
+
if (!this.adopt()) this.activateFallback();
|
|
1835
|
+
}
|
|
1836
|
+
componentWillUnmount() {
|
|
1837
|
+
this.mounted = false;
|
|
1838
|
+
this.unsubscribe?.();
|
|
1839
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1840
|
+
this.fallbackUnsubscribers = [];
|
|
1841
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1842
|
+
this.root = null;
|
|
1843
|
+
this.rangeInstances = [];
|
|
1844
|
+
this.staticSegments = [];
|
|
1845
|
+
this.staticValues.length = 0;
|
|
1846
|
+
}
|
|
1847
|
+
render() {
|
|
1848
|
+
const container = this.currentProps.render();
|
|
1849
|
+
if (!React__default.default.isValidElement(container) || typeof container.type !== "string") {
|
|
1850
|
+
throw new TypeError(
|
|
1851
|
+
`Compiled conditional ranges ${this.currentProps.id} must own one host container.`
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
return React__default.default.cloneElement(container, {
|
|
1855
|
+
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
1856
|
+
ref: this.captureRoot
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
FarmConditionalRangesBlock.displayName = "FarmCompiledConditionalRanges";
|
|
1861
|
+
return FarmConditionalRangesBlock;
|
|
1862
|
+
}
|
|
513
1863
|
function longestIncreasingSubsequencePositions(sequence) {
|
|
514
1864
|
const tails = [];
|
|
515
1865
|
const previous = Array.from({ length: sequence.length }, () => -1);
|
|
@@ -534,6 +1884,10 @@ function longestIncreasingSubsequencePositions(sequence) {
|
|
|
534
1884
|
return positions;
|
|
535
1885
|
}
|
|
536
1886
|
function createKeyedRowsBlockComponent(owner) {
|
|
1887
|
+
const rowHostScopeOwner = {
|
|
1888
|
+
subscribe: () => () => {
|
|
1889
|
+
}
|
|
1890
|
+
};
|
|
537
1891
|
class FarmKeyedRowConditional extends React__default.default.Component {
|
|
538
1892
|
constructor() {
|
|
539
1893
|
super(...arguments);
|
|
@@ -590,16 +1944,23 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
590
1944
|
this.renderVersion = 0;
|
|
591
1945
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
592
1946
|
this.conditionalListeners = /* @__PURE__ */ new Map();
|
|
1947
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
593
1948
|
this.conditionalOwner = {
|
|
594
1949
|
subscribe: (key, id, refresh) => this.subscribeToRowConditional(key, id, refresh)
|
|
595
1950
|
};
|
|
596
1951
|
this.captureRoot = (root) => {
|
|
597
1952
|
this.root = root;
|
|
598
1953
|
};
|
|
1954
|
+
this.requestHostScopeFallback = () => {
|
|
1955
|
+
this.activateFallback();
|
|
1956
|
+
};
|
|
599
1957
|
this.rowEvent = (item, index, eventId) => {
|
|
600
1958
|
if (this.state.fallback) {
|
|
601
1959
|
return (event) => this.currentProps.events?.[eventId]?.invoke(item, index, event);
|
|
602
1960
|
}
|
|
1961
|
+
if (this.usesDelegatedEvents()) {
|
|
1962
|
+
return void 0;
|
|
1963
|
+
}
|
|
603
1964
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
604
1965
|
let handlers = this.eventHandlers.get(key);
|
|
605
1966
|
if (!handlers) {
|
|
@@ -617,6 +1978,26 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
617
1978
|
handlers.set(eventId, handler);
|
|
618
1979
|
return handler;
|
|
619
1980
|
};
|
|
1981
|
+
this.dispatchDelegatedEvent = (name, event) => {
|
|
1982
|
+
const instance = this.eventRowInstance(event);
|
|
1983
|
+
const eventTarget = event.target;
|
|
1984
|
+
if (!instance || !eventTarget) return;
|
|
1985
|
+
const capture = name.endsWith("Capture");
|
|
1986
|
+
const matches = (this.currentProps.events || []).filter((descriptor) => descriptor.name === name && descriptor.path !== void 0).map((descriptor) => ({
|
|
1987
|
+
descriptor,
|
|
1988
|
+
target: findCompilerHostTarget(instance.element, descriptor.path || [])
|
|
1989
|
+
})).filter(
|
|
1990
|
+
(match) => Boolean(
|
|
1991
|
+
match.target && (match.target === eventTarget || match.target.contains(eventTarget))
|
|
1992
|
+
)
|
|
1993
|
+
).sort(
|
|
1994
|
+
(left, right) => capture ? (left.descriptor.path?.length || 0) - (right.descriptor.path?.length || 0) : (right.descriptor.path?.length || 0) - (left.descriptor.path?.length || 0)
|
|
1995
|
+
);
|
|
1996
|
+
for (const match of matches) {
|
|
1997
|
+
this.invokeDelegatedEvent(match.descriptor, instance, event, match.target);
|
|
1998
|
+
if (event.isPropagationStopped()) break;
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
620
2001
|
this.rowConditional = (item, index, conditionalId, render) => {
|
|
621
2002
|
if (this.state.fallback) return render(item, index);
|
|
622
2003
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
@@ -631,17 +2012,65 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
631
2012
|
render
|
|
632
2013
|
});
|
|
633
2014
|
};
|
|
634
|
-
this.refresh = (afterCommit) => {
|
|
2015
|
+
this.refresh = (afterCommit, dirtyState) => {
|
|
2016
|
+
if (dirtyState && this.refreshDirtyBindings(dirtyState, afterCommit)) return;
|
|
635
2017
|
this.reconcile(afterCommit);
|
|
636
2018
|
};
|
|
637
2019
|
}
|
|
638
2020
|
readRows(props) {
|
|
639
|
-
const
|
|
640
|
-
const items = source ? Array.from(source) : [];
|
|
2021
|
+
const items = materializeIterable(props.items());
|
|
641
2022
|
const keys = items.map((item, index) => keyedRowIdentity(props.rowKey(item, index)));
|
|
642
2023
|
if (new Set(keys).size !== keys.length) return null;
|
|
643
2024
|
return { items, keys };
|
|
644
2025
|
}
|
|
2026
|
+
usesDelegatedEvents(props = this.currentProps) {
|
|
2027
|
+
return Boolean(
|
|
2028
|
+
props.delegateEvents && props.events?.length && props.events.every((event) => event.path !== void 0)
|
|
2029
|
+
);
|
|
2030
|
+
}
|
|
2031
|
+
rebuildElementIndex(instances) {
|
|
2032
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2033
|
+
for (const instance of instances.values()) {
|
|
2034
|
+
this.instancesByElement.set(instance.element, instance);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
eventRowInstance(event) {
|
|
2038
|
+
if (!this.root) return void 0;
|
|
2039
|
+
const target = event.target;
|
|
2040
|
+
if (!target) return void 0;
|
|
2041
|
+
let element = target.nodeType === 1 ? target : target.parentElement;
|
|
2042
|
+
while (element && element.parentElement !== this.root) element = element.parentElement;
|
|
2043
|
+
return element?.parentElement === this.root ? this.instancesByElement.get(element) : void 0;
|
|
2044
|
+
}
|
|
2045
|
+
invokeDelegatedEvent(descriptor, instance, event, currentTarget) {
|
|
2046
|
+
const ownCurrentTarget = Object.getOwnPropertyDescriptor(event, "currentTarget");
|
|
2047
|
+
try {
|
|
2048
|
+
Object.defineProperty(event, "currentTarget", {
|
|
2049
|
+
configurable: true,
|
|
2050
|
+
value: currentTarget
|
|
2051
|
+
});
|
|
2052
|
+
descriptor.invoke(instance.item, instance.index, event);
|
|
2053
|
+
} finally {
|
|
2054
|
+
if (ownCurrentTarget) Object.defineProperty(event, "currentTarget", ownCurrentTarget);
|
|
2055
|
+
else Reflect.deleteProperty(event, "currentTarget");
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
delegatedContainerProps(container) {
|
|
2059
|
+
if (this.state.fallback || !this.usesDelegatedEvents()) return {};
|
|
2060
|
+
const props = container.props;
|
|
2061
|
+
return Object.fromEntries(
|
|
2062
|
+
[...new Set((this.currentProps.events || []).map((event) => event.name))].map((name) => {
|
|
2063
|
+
const existing = props[name];
|
|
2064
|
+
const capture = name.endsWith("Capture");
|
|
2065
|
+
const handler = (event) => {
|
|
2066
|
+
if (capture) existing?.(event);
|
|
2067
|
+
if (!event.isPropagationStopped()) this.dispatchDelegatedEvent(name, event);
|
|
2068
|
+
if (!capture && !event.isPropagationStopped()) existing?.(event);
|
|
2069
|
+
};
|
|
2070
|
+
return [name, handler];
|
|
2071
|
+
})
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
645
2074
|
subscribeToRowConditional(key, id, refresh) {
|
|
646
2075
|
let listeners = this.conditionalListeners.get(key);
|
|
647
2076
|
if (!listeners) {
|
|
@@ -657,7 +2086,21 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
657
2086
|
};
|
|
658
2087
|
}
|
|
659
2088
|
hasReactOwnedRows(props = this.currentProps) {
|
|
660
|
-
return Boolean(
|
|
2089
|
+
return Boolean(
|
|
2090
|
+
props.conditionals?.length || props.events?.length && !this.usesDelegatedEvents(props)
|
|
2091
|
+
);
|
|
2092
|
+
}
|
|
2093
|
+
cleanupHostScopes(instances = this.instances) {
|
|
2094
|
+
for (const instance of instances.values()) instance.scope?.cleanup();
|
|
2095
|
+
}
|
|
2096
|
+
mountRowHostScope(element, descriptor, props = this.currentProps) {
|
|
2097
|
+
if (!props.hostBlocks) return void 0;
|
|
2098
|
+
return mountCompilerHostTree(
|
|
2099
|
+
rowHostScopeOwner,
|
|
2100
|
+
element,
|
|
2101
|
+
descriptor,
|
|
2102
|
+
this.requestHostScopeFallback
|
|
2103
|
+
);
|
|
661
2104
|
}
|
|
662
2105
|
pruneEventHandlers(keys) {
|
|
663
2106
|
const active = new Set(keys);
|
|
@@ -681,16 +2124,20 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
681
2124
|
);
|
|
682
2125
|
const instances = /* @__PURE__ */ new Map();
|
|
683
2126
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
this.
|
|
687
|
-
|
|
688
|
-
|
|
2127
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2128
|
+
if (this.hasReactOwnedRows() && !matchesCompilerHostElement(elements[index], descriptor, opaqueConditionalPaths)) {
|
|
2129
|
+
this.cleanupHostScopes(instances);
|
|
2130
|
+
return false;
|
|
2131
|
+
}
|
|
2132
|
+
const scope = this.mountRowHostScope(elements[index], descriptor);
|
|
2133
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2134
|
+
this.cleanupHostScopes(instances);
|
|
689
2135
|
return false;
|
|
690
2136
|
}
|
|
691
2137
|
const instance = {
|
|
692
2138
|
key: rows.keys[index],
|
|
693
2139
|
element: elements[index],
|
|
2140
|
+
scope: scope || void 0,
|
|
694
2141
|
values: this.hasReactOwnedRows() ? this.currentProps.bindings.map(() => UNSET_KEYED_ROW_BINDING) : readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
695
2142
|
item: rows.items[index],
|
|
696
2143
|
index,
|
|
@@ -705,7 +2152,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
705
2152
|
}
|
|
706
2153
|
instances.set(rows.keys[index], instance);
|
|
707
2154
|
}
|
|
2155
|
+
this.cleanupHostScopes();
|
|
708
2156
|
this.instances = instances;
|
|
2157
|
+
this.rebuildElementIndex(instances);
|
|
709
2158
|
this.pruneEventHandlers(rows.keys);
|
|
710
2159
|
this.pruneConditionalListeners(rows.keys);
|
|
711
2160
|
return true;
|
|
@@ -724,6 +2173,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
724
2173
|
}
|
|
725
2174
|
this.fallbackRequested = true;
|
|
726
2175
|
this.fallbackKeysWereUnsafe = this.hasUnsafeFallbackKeys();
|
|
2176
|
+
this.cleanupHostScopes();
|
|
727
2177
|
this.fallbackVersion += 1;
|
|
728
2178
|
this.setState({ fallback: true }, afterCommit);
|
|
729
2179
|
}
|
|
@@ -758,6 +2208,116 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
758
2208
|
}
|
|
759
2209
|
});
|
|
760
2210
|
}
|
|
2211
|
+
refreshDirtyBindings(dirtyState, afterCommit) {
|
|
2212
|
+
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)) {
|
|
2213
|
+
return false;
|
|
2214
|
+
}
|
|
2215
|
+
const affectedBindingIndices = [];
|
|
2216
|
+
for (let bindingIndex = 0; bindingIndex < this.currentProps.bindings.length; bindingIndex += 1) {
|
|
2217
|
+
const dependencies = this.currentProps.bindings[bindingIndex].dependencies || [];
|
|
2218
|
+
if (dependencies.some((dependency) => dirtyState.has(dependency))) {
|
|
2219
|
+
affectedBindingIndices.push(bindingIndex);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
for (const instance of this.instances.values()) {
|
|
2223
|
+
for (const bindingIndex of affectedBindingIndices) {
|
|
2224
|
+
applyKeyedRowBinding(
|
|
2225
|
+
this.currentProps,
|
|
2226
|
+
instance,
|
|
2227
|
+
instance.item,
|
|
2228
|
+
instance.index,
|
|
2229
|
+
bindingIndex
|
|
2230
|
+
);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
afterCommit?.();
|
|
2234
|
+
return true;
|
|
2235
|
+
}
|
|
2236
|
+
reconcileStableRows(rows, afterCommit) {
|
|
2237
|
+
if (rows.keys.length !== this.instances.size) return false;
|
|
2238
|
+
let index = 0;
|
|
2239
|
+
for (const key of this.instances.keys()) {
|
|
2240
|
+
if (rows.keys[index] !== key) return false;
|
|
2241
|
+
index += 1;
|
|
2242
|
+
}
|
|
2243
|
+
const conditionalChanges = [];
|
|
2244
|
+
for (index = 0; index < rows.items.length; index += 1) {
|
|
2245
|
+
const key = rows.keys[index];
|
|
2246
|
+
const existing = this.instances.get(key);
|
|
2247
|
+
if (!existing) return false;
|
|
2248
|
+
if (this.currentProps.hostBlocks) {
|
|
2249
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2250
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2251
|
+
this.activateFallback(afterCommit);
|
|
2252
|
+
return true;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2256
|
+
const conditionalValues = readKeyedRowConditionalValues(
|
|
2257
|
+
this.currentProps,
|
|
2258
|
+
rows.items[index],
|
|
2259
|
+
index
|
|
2260
|
+
);
|
|
2261
|
+
for (const [id, values] of conditionalValues) {
|
|
2262
|
+
if (keyedRowConditionalChanged(existing.conditionalValues.get(id), values)) {
|
|
2263
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
existing.conditionalValues = conditionalValues;
|
|
2267
|
+
existing.item = rows.items[index];
|
|
2268
|
+
existing.index = index;
|
|
2269
|
+
}
|
|
2270
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2271
|
+
return true;
|
|
2272
|
+
}
|
|
2273
|
+
reconcileSingleRemoval(rows, afterCommit) {
|
|
2274
|
+
if (this.hasReactOwnedRows() || rows.keys.length + 1 !== this.instances.size) return false;
|
|
2275
|
+
const previousKeys = [...this.instances.keys()];
|
|
2276
|
+
let removedIndex = 0;
|
|
2277
|
+
while (removedIndex < rows.keys.length && previousKeys[removedIndex] === rows.keys[removedIndex]) {
|
|
2278
|
+
removedIndex += 1;
|
|
2279
|
+
}
|
|
2280
|
+
for (let index = removedIndex; index < rows.keys.length; index += 1) {
|
|
2281
|
+
if (previousKeys[index + 1] !== rows.keys[index]) return false;
|
|
2282
|
+
}
|
|
2283
|
+
const removedKey = previousKeys[removedIndex];
|
|
2284
|
+
const removed = this.instances.get(removedKey);
|
|
2285
|
+
if (!removed) return false;
|
|
2286
|
+
const conditionalChanges = [];
|
|
2287
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
2288
|
+
const key = rows.keys[index];
|
|
2289
|
+
const existing = this.instances.get(key);
|
|
2290
|
+
if (!existing) return false;
|
|
2291
|
+
if (this.currentProps.hostBlocks) {
|
|
2292
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2293
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2294
|
+
this.activateFallback(afterCommit);
|
|
2295
|
+
return true;
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2299
|
+
const conditionalValues = readKeyedRowConditionalValues(
|
|
2300
|
+
this.currentProps,
|
|
2301
|
+
rows.items[index],
|
|
2302
|
+
index
|
|
2303
|
+
);
|
|
2304
|
+
for (const [id, values] of conditionalValues) {
|
|
2305
|
+
if (keyedRowConditionalChanged(existing.conditionalValues.get(id), values)) {
|
|
2306
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
existing.conditionalValues = conditionalValues;
|
|
2310
|
+
existing.item = rows.items[index];
|
|
2311
|
+
existing.index = index;
|
|
2312
|
+
}
|
|
2313
|
+
removed.scope?.cleanup();
|
|
2314
|
+
removed.element.remove();
|
|
2315
|
+
this.instances.delete(removedKey);
|
|
2316
|
+
this.eventHandlers.delete(removedKey);
|
|
2317
|
+
this.conditionalListeners.delete(removedKey);
|
|
2318
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2319
|
+
return true;
|
|
2320
|
+
}
|
|
761
2321
|
reconcile(afterCommit) {
|
|
762
2322
|
if (!this.mounted || !this.root) {
|
|
763
2323
|
afterCommit?.();
|
|
@@ -777,27 +2337,54 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
777
2337
|
this.activateFallback(afterCommit);
|
|
778
2338
|
return;
|
|
779
2339
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
2340
|
+
if (this.hasReactOwnedRows()) {
|
|
2341
|
+
const previousKeys = [...this.instances.keys()];
|
|
2342
|
+
if (rows.keys.length !== previousKeys.length || rows.keys.some((key, index) => key !== previousKeys[index])) {
|
|
2343
|
+
this.synchronizeReactOwnedRows(afterCommit);
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
if (rows.items.length === 0) {
|
|
2348
|
+
this.cleanupHostScopes();
|
|
2349
|
+
this.root.replaceChildren();
|
|
2350
|
+
this.instances = /* @__PURE__ */ new Map();
|
|
2351
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2352
|
+
this.eventHandlers.clear();
|
|
2353
|
+
this.conditionalListeners.clear();
|
|
2354
|
+
afterCommit?.();
|
|
783
2355
|
return;
|
|
784
2356
|
}
|
|
785
|
-
|
|
2357
|
+
if (this.reconcileStableRows(rows, afterCommit)) return;
|
|
2358
|
+
if (this.reconcileSingleRemoval(rows, afterCommit)) return;
|
|
786
2359
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
787
2360
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
788
|
-
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
789
2361
|
const nextKeys = new Set(rows.keys);
|
|
2362
|
+
const hasSurvivingRows = rows.keys.some((key) => this.instances.has(key));
|
|
2363
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
2364
|
+
if (hasSurvivingRows) {
|
|
2365
|
+
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
2366
|
+
}
|
|
790
2367
|
for (const [key, instance] of this.instances) {
|
|
791
|
-
if (!nextKeys.has(key))
|
|
2368
|
+
if (!nextKeys.has(key)) {
|
|
2369
|
+
instance.scope?.cleanup();
|
|
2370
|
+
if (hasSurvivingRows) instance.element.remove();
|
|
2371
|
+
}
|
|
792
2372
|
}
|
|
793
|
-
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
794
|
-
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
2373
|
+
const sequence = hasSurvivingRows ? rows.keys.map((key) => oldIndices.get(key) ?? -1) : rows.keys.map(() => -1);
|
|
2374
|
+
const stablePositions = hasSurvivingRows ? longestIncreasingSubsequencePositions(sequence) : /* @__PURE__ */ new Set();
|
|
795
2375
|
const nextInstances = [];
|
|
796
2376
|
const conditionalChanges = [];
|
|
797
2377
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
798
2378
|
const key = rows.keys[index];
|
|
799
2379
|
const existing = this.instances.get(key);
|
|
800
2380
|
if (existing) {
|
|
2381
|
+
if (this.currentProps.hostBlocks) {
|
|
2382
|
+
const descriptor2 = this.currentProps.create(rows.items[index], index);
|
|
2383
|
+
if (!existing.scope?.update(descriptor2)) {
|
|
2384
|
+
this.activateFallback(afterCommit);
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
801
2388
|
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
802
2389
|
const conditionalValues = readKeyedRowConditionalValues(
|
|
803
2390
|
this.currentProps,
|
|
@@ -815,13 +2402,20 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
815
2402
|
nextInstances.push(existing);
|
|
816
2403
|
continue;
|
|
817
2404
|
}
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
)
|
|
2405
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2406
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
2407
|
+
const scope = this.mountRowHostScope(element, descriptor);
|
|
2408
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2409
|
+
for (const instance of nextInstances) {
|
|
2410
|
+
if (!this.instances.has(instance.key)) instance.scope?.cleanup();
|
|
2411
|
+
}
|
|
2412
|
+
this.activateFallback(afterCommit);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
822
2415
|
nextInstances.push({
|
|
823
2416
|
key,
|
|
824
2417
|
element,
|
|
2418
|
+
scope: scope || void 0,
|
|
825
2419
|
values: readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
826
2420
|
item: rows.items[index],
|
|
827
2421
|
index,
|
|
@@ -832,17 +2426,34 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
832
2426
|
)
|
|
833
2427
|
});
|
|
834
2428
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
const instance
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
2429
|
+
if (!hasSurvivingRows) {
|
|
2430
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2431
|
+
for (const instance of nextInstances) fragment.append(instance.element);
|
|
2432
|
+
this.root.replaceChildren(fragment);
|
|
2433
|
+
} else {
|
|
2434
|
+
let anchor = null;
|
|
2435
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
2436
|
+
const instance = nextInstances[index];
|
|
2437
|
+
if (sequence[index] < 0) {
|
|
2438
|
+
let start = index;
|
|
2439
|
+
while (start > 0 && sequence[start - 1] < 0) start -= 1;
|
|
2440
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2441
|
+
for (let itemIndex = start; itemIndex <= index; itemIndex += 1) {
|
|
2442
|
+
fragment.append(nextInstances[itemIndex].element);
|
|
2443
|
+
}
|
|
2444
|
+
this.root.insertBefore(fragment, anchor);
|
|
2445
|
+
anchor = nextInstances[start].element;
|
|
2446
|
+
index = start;
|
|
2447
|
+
} else {
|
|
2448
|
+
if (!stablePositions.has(index) && instance.element.nextSibling !== anchor) {
|
|
2449
|
+
this.root.insertBefore(instance.element, anchor);
|
|
2450
|
+
}
|
|
2451
|
+
anchor = instance.element;
|
|
2452
|
+
}
|
|
842
2453
|
}
|
|
843
|
-
anchor = instance.element;
|
|
844
2454
|
}
|
|
845
2455
|
this.instances = new Map(nextInstances.map((instance) => [instance.key, instance]));
|
|
2456
|
+
this.rebuildElementIndex(this.instances);
|
|
846
2457
|
this.pruneEventHandlers(rows.keys);
|
|
847
2458
|
this.pruneConditionalListeners(rows.keys);
|
|
848
2459
|
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
@@ -885,7 +2496,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
885
2496
|
this.mounted = false;
|
|
886
2497
|
this.unsubscribe?.();
|
|
887
2498
|
this.root = null;
|
|
2499
|
+
this.cleanupHostScopes();
|
|
888
2500
|
this.instances.clear();
|
|
2501
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
889
2502
|
this.eventHandlers.clear();
|
|
890
2503
|
this.conditionalListeners.clear();
|
|
891
2504
|
}
|
|
@@ -898,6 +2511,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
898
2511
|
);
|
|
899
2512
|
}
|
|
900
2513
|
return React__default.default.cloneElement(container, {
|
|
2514
|
+
...this.delegatedContainerProps(container),
|
|
901
2515
|
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
902
2516
|
ref: this.captureRoot
|
|
903
2517
|
});
|
|
@@ -919,6 +2533,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
919
2533
|
this.currentProps = this.props;
|
|
920
2534
|
this.rangeInstances = [];
|
|
921
2535
|
this.staticSegments = [];
|
|
2536
|
+
this.staticValues = [];
|
|
922
2537
|
this.captureRoot = (root) => {
|
|
923
2538
|
this.root = root;
|
|
924
2539
|
this.currentProps.rootRef?.(root);
|
|
@@ -928,8 +2543,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
928
2543
|
};
|
|
929
2544
|
}
|
|
930
2545
|
readRange(range) {
|
|
931
|
-
const
|
|
932
|
-
const items = source ? Array.from(source) : [];
|
|
2546
|
+
const items = materializeIterable(range.items());
|
|
933
2547
|
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
934
2548
|
if (new Set(keys).size !== keys.length) return null;
|
|
935
2549
|
return { items, keys };
|
|
@@ -983,6 +2597,11 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
983
2597
|
staticSegments.push(elements.slice(cursor));
|
|
984
2598
|
this.staticSegments = staticSegments;
|
|
985
2599
|
this.rangeInstances = instancesByRange;
|
|
2600
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
2601
|
+
this.rangeInstances = [];
|
|
2602
|
+
this.staticSegments = [];
|
|
2603
|
+
return false;
|
|
2604
|
+
}
|
|
986
2605
|
return true;
|
|
987
2606
|
}
|
|
988
2607
|
anchorAfter(rangeIndex) {
|
|
@@ -1059,6 +2678,14 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1059
2678
|
this.activateFallback(afterCommit);
|
|
1060
2679
|
return;
|
|
1061
2680
|
}
|
|
2681
|
+
if (!applyStaticRangeBindings(
|
|
2682
|
+
this.currentProps.bindings,
|
|
2683
|
+
this.staticSegments,
|
|
2684
|
+
this.staticValues
|
|
2685
|
+
)) {
|
|
2686
|
+
this.activateFallback(afterCommit);
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
1062
2689
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
1063
2690
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
1064
2691
|
for (let rangeIndex = rowsByRange.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
@@ -1102,6 +2729,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1102
2729
|
this.root = null;
|
|
1103
2730
|
this.rangeInstances = [];
|
|
1104
2731
|
this.staticSegments = [];
|
|
2732
|
+
this.staticValues.length = 0;
|
|
1105
2733
|
}
|
|
1106
2734
|
render() {
|
|
1107
2735
|
const container = this.currentProps.render();
|
|
@@ -1119,6 +2747,128 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1119
2747
|
FarmKeyedRangesBlock.displayName = "FarmCompiledKeyedRanges";
|
|
1120
2748
|
return FarmKeyedRangesBlock;
|
|
1121
2749
|
}
|
|
2750
|
+
function createMixedRangesBlockComponent(owner) {
|
|
2751
|
+
class FarmMixedRangesBlock extends React__default.default.Component {
|
|
2752
|
+
constructor() {
|
|
2753
|
+
super(...arguments);
|
|
2754
|
+
this.state = { fallback: false };
|
|
2755
|
+
this.root = null;
|
|
2756
|
+
this.mounted = false;
|
|
2757
|
+
this.fallbackRequested = false;
|
|
2758
|
+
this.fallbackVersion = 0;
|
|
2759
|
+
this.propFallbackQueued = false;
|
|
2760
|
+
this.currentProps = this.props;
|
|
2761
|
+
this.controller = null;
|
|
2762
|
+
this.fallbackUnsubscribers = [];
|
|
2763
|
+
this.captureRoot = (root) => {
|
|
2764
|
+
this.root = root;
|
|
2765
|
+
this.currentProps.rootRef?.(root);
|
|
2766
|
+
};
|
|
2767
|
+
this.activateFallback = (afterCommit) => {
|
|
2768
|
+
if (!this.mounted || this.state.fallback || this.fallbackRequested) {
|
|
2769
|
+
afterCommit?.();
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
this.fallbackRequested = true;
|
|
2773
|
+
this.controller?.cleanup();
|
|
2774
|
+
this.controller = null;
|
|
2775
|
+
this.fallbackVersion += 1;
|
|
2776
|
+
this.setState({ fallback: true }, () => {
|
|
2777
|
+
this.subscribeFallbackBlocks();
|
|
2778
|
+
afterCommit?.();
|
|
2779
|
+
});
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
clearFallbackSubscriptions() {
|
|
2783
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
2784
|
+
this.fallbackUnsubscribers = [];
|
|
2785
|
+
}
|
|
2786
|
+
subscribeFallbackBlocks() {
|
|
2787
|
+
this.clearFallbackSubscriptions();
|
|
2788
|
+
const descriptor = this.currentProps.create();
|
|
2789
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2790
|
+
collectCompilerHostBlockIds(descriptor, ids);
|
|
2791
|
+
for (const id of ids) {
|
|
2792
|
+
this.fallbackUnsubscribers.push(
|
|
2793
|
+
owner.subscribe(id, (afterCommit) => {
|
|
2794
|
+
if (!this.mounted || !this.state.fallback) {
|
|
2795
|
+
afterCommit?.();
|
|
2796
|
+
return;
|
|
2797
|
+
}
|
|
2798
|
+
this.fallbackVersion += 1;
|
|
2799
|
+
this.forceUpdate(afterCommit);
|
|
2800
|
+
})
|
|
2801
|
+
);
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
adopt() {
|
|
2805
|
+
if (!this.root) return false;
|
|
2806
|
+
const descriptor = this.currentProps.create();
|
|
2807
|
+
const block = descriptor.block;
|
|
2808
|
+
if (block?.kind !== "mixed-ranges" || block.id !== this.currentProps.id) return false;
|
|
2809
|
+
const controller = new CompilerNestedMixedRanges(
|
|
2810
|
+
owner,
|
|
2811
|
+
this.root,
|
|
2812
|
+
descriptor,
|
|
2813
|
+
block,
|
|
2814
|
+
this.activateFallback
|
|
2815
|
+
);
|
|
2816
|
+
try {
|
|
2817
|
+
if (!controller.adopt()) {
|
|
2818
|
+
controller.cleanup();
|
|
2819
|
+
return false;
|
|
2820
|
+
}
|
|
2821
|
+
} catch (error) {
|
|
2822
|
+
controller.cleanup();
|
|
2823
|
+
throw error;
|
|
2824
|
+
}
|
|
2825
|
+
this.controller = controller;
|
|
2826
|
+
return true;
|
|
2827
|
+
}
|
|
2828
|
+
schedulePropFallback() {
|
|
2829
|
+
if (this.propFallbackQueued) return;
|
|
2830
|
+
this.propFallbackQueued = true;
|
|
2831
|
+
queueMicrotask(() => {
|
|
2832
|
+
this.propFallbackQueued = false;
|
|
2833
|
+
if (this.mounted && !this.state.fallback) this.activateFallback();
|
|
2834
|
+
});
|
|
2835
|
+
}
|
|
2836
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
2837
|
+
this.currentProps = nextProps;
|
|
2838
|
+
if (nextState.fallback || this.state.fallback) return true;
|
|
2839
|
+
this.schedulePropFallback();
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2842
|
+
componentDidMount() {
|
|
2843
|
+
this.mounted = true;
|
|
2844
|
+
if (!this.adopt()) this.activateFallback();
|
|
2845
|
+
}
|
|
2846
|
+
componentDidUpdate() {
|
|
2847
|
+
if (this.state.fallback) this.subscribeFallbackBlocks();
|
|
2848
|
+
}
|
|
2849
|
+
componentWillUnmount() {
|
|
2850
|
+
this.mounted = false;
|
|
2851
|
+
this.controller?.cleanup();
|
|
2852
|
+
this.controller = null;
|
|
2853
|
+
this.clearFallbackSubscriptions();
|
|
2854
|
+
this.root = null;
|
|
2855
|
+
}
|
|
2856
|
+
render() {
|
|
2857
|
+
const container = this.currentProps.render();
|
|
2858
|
+
if (!React__default.default.isValidElement(container) || typeof container.type !== "string") {
|
|
2859
|
+
throw new TypeError(
|
|
2860
|
+
`Compiled mixed ranges ${this.currentProps.id} must own one host container.`
|
|
2861
|
+
);
|
|
2862
|
+
}
|
|
2863
|
+
return React__default.default.cloneElement(container, {
|
|
2864
|
+
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
2865
|
+
ref: this.captureRoot
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
FarmMixedRangesBlock.displayName = "FarmCompiledMixedRanges";
|
|
2870
|
+
return FarmMixedRangesBlock;
|
|
2871
|
+
}
|
|
1122
2872
|
function createComponentBlockComponent(owner) {
|
|
1123
2873
|
class FarmComponentBlock extends React__default.default.Component {
|
|
1124
2874
|
constructor() {
|
|
@@ -1171,6 +2921,17 @@ function createCompiledComponent(definition) {
|
|
|
1171
2921
|
this.hasBindingError = false;
|
|
1172
2922
|
this.inputSelection = null;
|
|
1173
2923
|
this.dirtyState = /* @__PURE__ */ new Set();
|
|
2924
|
+
this.indexedDefinition = null;
|
|
2925
|
+
this.staticBindingsByDependency = [];
|
|
2926
|
+
this.blockBindingsByDependency = [];
|
|
2927
|
+
this.blockBindings = /* @__PURE__ */ new Map();
|
|
2928
|
+
this.trackedBindingsByDependency = [];
|
|
2929
|
+
this.trackedDependenciesByBinding = /* @__PURE__ */ new Map();
|
|
2930
|
+
this.bindingValues = /* @__PURE__ */ new Map();
|
|
2931
|
+
this.activeBinding = null;
|
|
2932
|
+
this.activeDependencies = null;
|
|
2933
|
+
this.renderedDefinition = null;
|
|
2934
|
+
this.renderedElement = null;
|
|
1174
2935
|
this.blockRefreshListeners = /* @__PURE__ */ new Map();
|
|
1175
2936
|
this.blockRoots = /* @__PURE__ */ new Map();
|
|
1176
2937
|
this.blockRootElements = /* @__PURE__ */ new Set();
|
|
@@ -1182,20 +2943,35 @@ function createCompiledComponent(definition) {
|
|
|
1182
2943
|
this.refreshDefinition = () => {
|
|
1183
2944
|
if (this.mounted) this.forceUpdate();
|
|
1184
2945
|
};
|
|
1185
|
-
|
|
2946
|
+
const initialState = definitionReference.current.initialize(props);
|
|
2947
|
+
const initialProps = definitionReference.current.readProps?.(props) || [];
|
|
2948
|
+
this.propCellOffset = initialState.length;
|
|
2949
|
+
this.cells = [...initialState, ...initialProps].map((initialValue, index) => {
|
|
1186
2950
|
let value = initialValue;
|
|
1187
2951
|
const pending = [];
|
|
1188
2952
|
return {
|
|
1189
|
-
get: () =>
|
|
2953
|
+
get: () => {
|
|
2954
|
+
if (this.activeBinding && this.activeDependencies) {
|
|
2955
|
+
this.activeDependencies.add(index);
|
|
2956
|
+
}
|
|
2957
|
+
return value;
|
|
2958
|
+
},
|
|
1190
2959
|
set: (next) => {
|
|
1191
|
-
pending.push(next);
|
|
2960
|
+
pending.push({ kind: "state", update: next });
|
|
1192
2961
|
this.scheduleBindingFlush(index);
|
|
1193
2962
|
},
|
|
2963
|
+
replace: (next) => {
|
|
2964
|
+
pending.push({ kind: "value", value: next });
|
|
2965
|
+
},
|
|
1194
2966
|
flush: () => {
|
|
1195
2967
|
if (pending.length === 0) return false;
|
|
1196
2968
|
const previous = value;
|
|
1197
2969
|
for (const next of pending.splice(0)) {
|
|
1198
|
-
|
|
2970
|
+
if (next.kind === "value") {
|
|
2971
|
+
value = next.value;
|
|
2972
|
+
} else {
|
|
2973
|
+
value = typeof next.update === "function" ? next.update(value) : next.update;
|
|
2974
|
+
}
|
|
1199
2975
|
}
|
|
1200
2976
|
return !Object.is(previous, value);
|
|
1201
2977
|
}
|
|
@@ -1209,6 +2985,9 @@ function createCompiledComponent(definition) {
|
|
|
1209
2985
|
HostConditional: createHostConditionalBlockComponent({
|
|
1210
2986
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1211
2987
|
}),
|
|
2988
|
+
ConditionalRanges: createConditionalRangesBlockComponent({
|
|
2989
|
+
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
2990
|
+
}),
|
|
1212
2991
|
KeyedList: createKeyedListBlockComponent({
|
|
1213
2992
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1214
2993
|
}),
|
|
@@ -1218,12 +2997,113 @@ function createCompiledComponent(definition) {
|
|
|
1218
2997
|
KeyedRanges: createKeyedRangesBlockComponent({
|
|
1219
2998
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1220
2999
|
}),
|
|
3000
|
+
MixedRanges: createMixedRangesBlockComponent({
|
|
3001
|
+
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
3002
|
+
}),
|
|
1221
3003
|
Component: createComponentBlockComponent({
|
|
1222
3004
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1223
3005
|
}),
|
|
1224
3006
|
target: (id) => this.bindingTarget(id)
|
|
1225
3007
|
};
|
|
1226
3008
|
}
|
|
3009
|
+
usesHybridReactivity() {
|
|
3010
|
+
return definitionReference.current.reactivity === "hybrid";
|
|
3011
|
+
}
|
|
3012
|
+
canReuseRenderedElement(currentDefinition, propValues) {
|
|
3013
|
+
return Boolean(
|
|
3014
|
+
this.mounted && propValues && propValues.every(isCompilerPrimitive) && this.renderedDefinition === currentDefinition && this.renderedElement
|
|
3015
|
+
);
|
|
3016
|
+
}
|
|
3017
|
+
renderCellsForProps(propValues) {
|
|
3018
|
+
if (!propValues) return { cells: this.cells, commit: () => void 0 };
|
|
3019
|
+
let committed = false;
|
|
3020
|
+
const cells = this.cells.slice(0, this.propCellOffset);
|
|
3021
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3022
|
+
const cell = this.cells[this.propCellOffset + propIndex];
|
|
3023
|
+
if (!cell) continue;
|
|
3024
|
+
cells.push({
|
|
3025
|
+
get: () => committed ? cell.get() : propValues[propIndex],
|
|
3026
|
+
set: (next) => cell.set(next)
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
return {
|
|
3030
|
+
cells,
|
|
3031
|
+
commit: () => {
|
|
3032
|
+
committed = true;
|
|
3033
|
+
}
|
|
3034
|
+
};
|
|
3035
|
+
}
|
|
3036
|
+
tracksBinding(binding) {
|
|
3037
|
+
return this.usesHybridReactivity() && binding.tracking === "dynamic";
|
|
3038
|
+
}
|
|
3039
|
+
ensureBindingIndex() {
|
|
3040
|
+
const currentDefinition = definitionReference.current;
|
|
3041
|
+
if (this.indexedDefinition === currentDefinition) return;
|
|
3042
|
+
this.indexedDefinition = currentDefinition;
|
|
3043
|
+
this.staticBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3044
|
+
this.blockBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3045
|
+
this.trackedBindingsByDependency = Array.from(
|
|
3046
|
+
{ length: this.cells.length },
|
|
3047
|
+
() => /* @__PURE__ */ new Set()
|
|
3048
|
+
);
|
|
3049
|
+
this.blockBindings.clear();
|
|
3050
|
+
this.trackedDependenciesByBinding.clear();
|
|
3051
|
+
this.bindingValues.clear();
|
|
3052
|
+
for (const binding of currentDefinition.bindings) {
|
|
3053
|
+
if (binding.kind === "block") this.blockBindings.set(binding.id, binding);
|
|
3054
|
+
for (const dependency of binding.dependencies) {
|
|
3055
|
+
if (dependency < 0 || dependency >= this.cells.length) continue;
|
|
3056
|
+
if (binding.kind === "block") {
|
|
3057
|
+
this.blockBindingsByDependency[dependency].push(binding);
|
|
3058
|
+
} else if (!this.tracksBinding(binding)) {
|
|
3059
|
+
this.staticBindingsByDependency[dependency].push(binding);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
updateTrackedDependencies(binding, nextDependencies) {
|
|
3065
|
+
const previousDependencies = this.trackedDependenciesByBinding.get(binding);
|
|
3066
|
+
if (previousDependencies) {
|
|
3067
|
+
for (const dependency of previousDependencies) {
|
|
3068
|
+
if (!nextDependencies.has(dependency)) {
|
|
3069
|
+
this.trackedBindingsByDependency[dependency]?.delete(binding);
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
for (const dependency of nextDependencies) {
|
|
3074
|
+
if (!previousDependencies?.has(dependency)) {
|
|
3075
|
+
this.trackedBindingsByDependency[dependency]?.add(binding);
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
this.trackedDependenciesByBinding.set(binding, nextDependencies);
|
|
3079
|
+
}
|
|
3080
|
+
readBinding(binding) {
|
|
3081
|
+
if (!this.tracksBinding(binding)) return binding.read(this.props, this.cells);
|
|
3082
|
+
const previousBinding = this.activeBinding;
|
|
3083
|
+
const previousDependencies = this.activeDependencies;
|
|
3084
|
+
const nextDependencies = /* @__PURE__ */ new Set();
|
|
3085
|
+
this.activeBinding = binding;
|
|
3086
|
+
this.activeDependencies = nextDependencies;
|
|
3087
|
+
try {
|
|
3088
|
+
return binding.read(this.props, this.cells);
|
|
3089
|
+
} finally {
|
|
3090
|
+
this.activeBinding = previousBinding;
|
|
3091
|
+
this.activeDependencies = previousDependencies;
|
|
3092
|
+
this.updateTrackedDependencies(binding, nextDependencies);
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
bindingValue(binding, value) {
|
|
3096
|
+
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
3097
|
+
}
|
|
3098
|
+
primeHybridBindings() {
|
|
3099
|
+
if (!this.usesHybridReactivity()) return;
|
|
3100
|
+
for (const binding of definitionReference.current.bindings) {
|
|
3101
|
+
if (binding.kind === "block") continue;
|
|
3102
|
+
if (!this.tracksBinding(binding)) continue;
|
|
3103
|
+
const value = this.readBinding(binding);
|
|
3104
|
+
this.bindingValues.set(binding, this.bindingValue(binding, value));
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
1227
3107
|
bindingTarget(id) {
|
|
1228
3108
|
const existing = this.bindingTargetRefs.get(id);
|
|
1229
3109
|
if (existing) return existing;
|
|
@@ -1280,83 +3160,118 @@ function createCompiledComponent(definition) {
|
|
|
1280
3160
|
this.flushQueued = true;
|
|
1281
3161
|
queueMicrotask(() => {
|
|
1282
3162
|
this.flushQueued = false;
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
3163
|
+
this.flushBindingUpdates();
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3166
|
+
flushBindingUpdates() {
|
|
3167
|
+
const inputSelection = this.inputSelection;
|
|
3168
|
+
this.inputSelection = null;
|
|
3169
|
+
if (!this.mounted) return;
|
|
3170
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
3171
|
+
for (const index of this.dirtyState) {
|
|
3172
|
+
if (this.cells[index]?.flush()) dirty.add(index);
|
|
3173
|
+
}
|
|
3174
|
+
this.dirtyState.clear();
|
|
3175
|
+
if (dirty.size === 0) return;
|
|
3176
|
+
try {
|
|
3177
|
+
this.ensureBindingIndex();
|
|
3178
|
+
const affectedBlockIds = /* @__PURE__ */ new Set();
|
|
3179
|
+
const affectedBindings = /* @__PURE__ */ new Set();
|
|
3180
|
+
for (const dependency of dirty) {
|
|
3181
|
+
for (const binding of this.blockBindingsByDependency[dependency] || []) {
|
|
3182
|
+
affectedBlockIds.add(binding.id);
|
|
1302
3183
|
}
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
parent = blockBindings.get(parent)?.parent;
|
|
1310
|
-
}
|
|
1311
|
-
return false;
|
|
1312
|
-
};
|
|
1313
|
-
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
1314
|
-
const binding = blockBindings.get(id);
|
|
1315
|
-
const refresh = this.blockRefreshListeners.get(id);
|
|
1316
|
-
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
1317
|
-
}).filter(
|
|
1318
|
-
(refresh) => refresh !== void 0
|
|
1319
|
-
);
|
|
1320
|
-
for (const binding of bindings) {
|
|
1321
|
-
if (binding.kind !== "block" && binding.dependencies.some((dependency) => dirty.has(dependency))) {
|
|
1322
|
-
this.applyBinding(binding);
|
|
3184
|
+
for (const binding of this.staticBindingsByDependency[dependency] || []) {
|
|
3185
|
+
affectedBindings.add(binding);
|
|
3186
|
+
}
|
|
3187
|
+
if (this.usesHybridReactivity()) {
|
|
3188
|
+
for (const binding of this.trackedBindingsByDependency[dependency] || []) {
|
|
3189
|
+
affectedBindings.add(binding);
|
|
1323
3190
|
}
|
|
1324
3191
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
3192
|
+
}
|
|
3193
|
+
const hasAffectedMountedAncestor = (binding) => {
|
|
3194
|
+
let parent = binding.parent;
|
|
3195
|
+
while (parent !== void 0) {
|
|
3196
|
+
if (affectedBlockIds.has(parent) && this.blockRefreshListeners.has(parent)) {
|
|
3197
|
+
return true;
|
|
3198
|
+
}
|
|
3199
|
+
parent = this.blockBindings.get(parent)?.parent;
|
|
1331
3200
|
}
|
|
1332
|
-
|
|
1333
|
-
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
this.
|
|
3201
|
+
return false;
|
|
3202
|
+
};
|
|
3203
|
+
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
3204
|
+
const binding = this.blockBindings.get(id);
|
|
3205
|
+
const refresh = this.blockRefreshListeners.get(id);
|
|
3206
|
+
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
3207
|
+
}).filter((refresh) => refresh !== void 0);
|
|
3208
|
+
for (const binding of affectedBindings) {
|
|
3209
|
+
if (binding.kind !== "block") this.applyBinding(binding);
|
|
1337
3210
|
}
|
|
1338
|
-
|
|
3211
|
+
let pendingBlockCommits = blockRefreshes.length;
|
|
3212
|
+
for (const refresh of blockRefreshes) {
|
|
3213
|
+
refresh(() => {
|
|
3214
|
+
pendingBlockCommits -= 1;
|
|
3215
|
+
if (pendingBlockCommits === 0) this.restoreInputSelection(inputSelection);
|
|
3216
|
+
}, dirty);
|
|
3217
|
+
}
|
|
3218
|
+
if (blockRefreshes.length === 0) this.restoreInputSelection(inputSelection);
|
|
3219
|
+
} catch (error) {
|
|
3220
|
+
this.bindingError = error;
|
|
3221
|
+
this.hasBindingError = true;
|
|
3222
|
+
this.forceUpdate();
|
|
3223
|
+
}
|
|
1339
3224
|
}
|
|
1340
|
-
applyBinding(binding) {
|
|
3225
|
+
applyBinding(binding, force = false) {
|
|
1341
3226
|
if (!this.root || binding.kind === "block") return;
|
|
1342
3227
|
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;
|
|
1343
3228
|
if (!target) return;
|
|
1344
|
-
const value =
|
|
3229
|
+
const value = this.readBinding(binding);
|
|
3230
|
+
const comparableValue = this.bindingValue(binding, value);
|
|
3231
|
+
if (!force && this.bindingValues.has(binding)) {
|
|
3232
|
+
if (Object.is(this.bindingValues.get(binding), comparableValue)) return;
|
|
3233
|
+
}
|
|
1345
3234
|
if (binding.kind === "text") {
|
|
1346
|
-
target.textContent =
|
|
3235
|
+
target.textContent = comparableValue;
|
|
1347
3236
|
} else if (binding.kind === "style") {
|
|
1348
3237
|
updateStyle(target, binding.name, value);
|
|
1349
3238
|
} else {
|
|
1350
3239
|
updateAttribute(target, binding.name, value);
|
|
1351
3240
|
}
|
|
3241
|
+
this.bindingValues.set(binding, comparableValue);
|
|
1352
3242
|
}
|
|
1353
3243
|
componentDidMount() {
|
|
1354
3244
|
this.mounted = true;
|
|
1355
3245
|
refreshListeners.add(this.refreshDefinition);
|
|
3246
|
+
this.ensureBindingIndex();
|
|
3247
|
+
this.primeHybridBindings();
|
|
1356
3248
|
}
|
|
1357
|
-
|
|
3249
|
+
getSnapshotBeforeUpdate() {
|
|
3250
|
+
const currentDefinition = definitionReference.current;
|
|
3251
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3252
|
+
return this.canReuseRenderedElement(currentDefinition, propValues);
|
|
3253
|
+
}
|
|
3254
|
+
componentDidUpdate(_previousProps, _previousState, reusedRenderedElement = false) {
|
|
3255
|
+
const propValues = definitionReference.current.readProps?.(this.props) || null;
|
|
3256
|
+
if (propValues) {
|
|
3257
|
+
if (reusedRenderedElement) this.captureInputSelection();
|
|
3258
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3259
|
+
const cellIndex = this.propCellOffset + propIndex;
|
|
3260
|
+
const cell = this.cells[cellIndex];
|
|
3261
|
+
if (!cell) continue;
|
|
3262
|
+
cell.replace(propValues[propIndex]);
|
|
3263
|
+
if (reusedRenderedElement) {
|
|
3264
|
+
this.dirtyState.add(cellIndex);
|
|
3265
|
+
} else {
|
|
3266
|
+
cell.flush();
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
this.flushBindingUpdates();
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3272
|
+
this.ensureBindingIndex();
|
|
1358
3273
|
for (const binding of definitionReference.current.bindings) {
|
|
1359
|
-
if (binding.kind !== "block") this.applyBinding(binding);
|
|
3274
|
+
if (binding.kind !== "block") this.applyBinding(binding, true);
|
|
1360
3275
|
}
|
|
1361
3276
|
}
|
|
1362
3277
|
componentWillUnmount() {
|
|
@@ -1369,30 +3284,68 @@ function createCompiledComponent(definition) {
|
|
|
1369
3284
|
this.blockRootElements.clear();
|
|
1370
3285
|
this.bindingTargets.clear();
|
|
1371
3286
|
this.bindingTargetRefs.clear();
|
|
3287
|
+
this.indexedDefinition = null;
|
|
3288
|
+
this.staticBindingsByDependency = [];
|
|
3289
|
+
this.blockBindingsByDependency = [];
|
|
3290
|
+
this.blockBindings.clear();
|
|
3291
|
+
this.trackedBindingsByDependency = [];
|
|
3292
|
+
this.trackedDependenciesByBinding.clear();
|
|
3293
|
+
this.bindingValues.clear();
|
|
3294
|
+
this.activeBinding = null;
|
|
3295
|
+
this.activeDependencies = null;
|
|
1372
3296
|
refreshListeners.delete(this.refreshDefinition);
|
|
1373
3297
|
}
|
|
1374
3298
|
render() {
|
|
1375
3299
|
if (this.hasBindingError) throw this.bindingError;
|
|
1376
3300
|
const currentDefinition = definitionReference.current;
|
|
1377
|
-
const
|
|
3301
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3302
|
+
if (this.canReuseRenderedElement(currentDefinition, propValues)) {
|
|
3303
|
+
return this.renderedElement;
|
|
3304
|
+
}
|
|
3305
|
+
const renderCells = this.renderCellsForProps(propValues);
|
|
3306
|
+
const element = currentDefinition.render(this.props, renderCells.cells, this.blockRuntime);
|
|
1378
3307
|
if (!React__default.default.isValidElement(element)) {
|
|
1379
3308
|
throw new TypeError(
|
|
1380
3309
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1381
3310
|
);
|
|
1382
3311
|
}
|
|
3312
|
+
let renderedElement;
|
|
3313
|
+
const captureCommittedRoot = (root) => {
|
|
3314
|
+
this.captureRoot(root);
|
|
3315
|
+
if (!root) return;
|
|
3316
|
+
renderCells.commit();
|
|
3317
|
+
this.renderedDefinition = currentDefinition;
|
|
3318
|
+
this.renderedElement = renderedElement;
|
|
3319
|
+
};
|
|
1383
3320
|
if (element.type === this.blockRuntime.KeyedRanges) {
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
3321
|
+
renderedElement = React__default.default.cloneElement(
|
|
3322
|
+
element,
|
|
3323
|
+
{
|
|
3324
|
+
rootRef: captureCommittedRoot
|
|
3325
|
+
}
|
|
3326
|
+
);
|
|
3327
|
+
} else if (element.type === this.blockRuntime.ConditionalRanges) {
|
|
3328
|
+
renderedElement = React__default.default.cloneElement(
|
|
3329
|
+
element,
|
|
3330
|
+
{ rootRef: captureCommittedRoot }
|
|
3331
|
+
);
|
|
3332
|
+
} else if (element.type === this.blockRuntime.MixedRanges) {
|
|
3333
|
+
renderedElement = React__default.default.cloneElement(
|
|
3334
|
+
element,
|
|
3335
|
+
{
|
|
3336
|
+
rootRef: captureCommittedRoot
|
|
3337
|
+
}
|
|
3338
|
+
);
|
|
3339
|
+
} else if (typeof element.type !== "string") {
|
|
1389
3340
|
throw new TypeError(
|
|
1390
3341
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1391
3342
|
);
|
|
3343
|
+
} else {
|
|
3344
|
+
renderedElement = React__default.default.cloneElement(element, {
|
|
3345
|
+
ref: captureCommittedRoot
|
|
3346
|
+
});
|
|
1392
3347
|
}
|
|
1393
|
-
return
|
|
1394
|
-
ref: this.captureRoot
|
|
1395
|
-
});
|
|
3348
|
+
return renderedElement;
|
|
1396
3349
|
}
|
|
1397
3350
|
}
|
|
1398
3351
|
FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
|