@farm.js/react 0.1.0-beta.3 → 0.1.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -37
- package/dist/compiler-runtime.cjs +2052 -188
- package/dist/compiler-runtime.cjs.map +1 -1
- package/dist/compiler-runtime.d.mts +106 -4
- package/dist/compiler-runtime.d.ts +106 -4
- package/dist/compiler-runtime.mjs +2041 -189
- 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 +1224 -87
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +1224 -87
- package/dist/vite.mjs.map +1 -1
- package/package.json +6 -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;
|
|
@@ -521,8 +1598,14 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
521
1598
|
this.fallbackVersion = 0;
|
|
522
1599
|
this.propFallbackQueued = false;
|
|
523
1600
|
this.currentProps = this.props;
|
|
1601
|
+
this.fallbackUnsubscribers = [];
|
|
524
1602
|
this.rangeInstances = [];
|
|
525
1603
|
this.staticSegments = [];
|
|
1604
|
+
this.staticValues = [];
|
|
1605
|
+
this.requestNestedFallback = () => {
|
|
1606
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1607
|
+
this.activateFallback();
|
|
1608
|
+
};
|
|
526
1609
|
this.captureRoot = (root) => {
|
|
527
1610
|
this.root = root;
|
|
528
1611
|
this.currentProps.rootRef?.(root);
|
|
@@ -531,6 +1614,24 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
531
1614
|
this.reconcile(afterCommit);
|
|
532
1615
|
};
|
|
533
1616
|
}
|
|
1617
|
+
subscribeFallbackDescendants() {
|
|
1618
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1619
|
+
this.fallbackUnsubscribers = [];
|
|
1620
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1621
|
+
for (const range of this.currentProps.ranges) {
|
|
1622
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
1623
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
1624
|
+
}
|
|
1625
|
+
ids.delete(this.currentProps.id);
|
|
1626
|
+
for (const id of ids) {
|
|
1627
|
+
this.fallbackUnsubscribers.push(
|
|
1628
|
+
owner.subscribe(id, (afterCommit) => {
|
|
1629
|
+
this.fallbackVersion += 1;
|
|
1630
|
+
this.forceUpdate(afterCommit);
|
|
1631
|
+
})
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
534
1635
|
readSelections(props) {
|
|
535
1636
|
const selections = [];
|
|
536
1637
|
for (const range of props.ranges) {
|
|
@@ -547,12 +1648,21 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
547
1648
|
const elements = [...this.root.children];
|
|
548
1649
|
const staticSegments = [];
|
|
549
1650
|
const instances = [];
|
|
1651
|
+
const cleanupInstances = () => {
|
|
1652
|
+
for (const instance of instances) instance?.host.scope?.cleanup();
|
|
1653
|
+
};
|
|
550
1654
|
let cursor = 0;
|
|
551
1655
|
for (let rangeIndex = 0; rangeIndex < props.ranges.length; rangeIndex += 1) {
|
|
552
1656
|
const range = props.ranges[rangeIndex];
|
|
553
|
-
if (!Number.isSafeInteger(range.before) || range.before < 0)
|
|
1657
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
1658
|
+
cleanupInstances();
|
|
1659
|
+
return false;
|
|
1660
|
+
}
|
|
554
1661
|
const staticEnd = cursor + range.before;
|
|
555
|
-
if (staticEnd > elements.length)
|
|
1662
|
+
if (staticEnd > elements.length) {
|
|
1663
|
+
cleanupInstances();
|
|
1664
|
+
return false;
|
|
1665
|
+
}
|
|
556
1666
|
staticSegments.push(elements.slice(cursor, staticEnd));
|
|
557
1667
|
cursor = staticEnd;
|
|
558
1668
|
const selection = selections[rangeIndex];
|
|
@@ -561,22 +1671,45 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
561
1671
|
continue;
|
|
562
1672
|
}
|
|
563
1673
|
const element = elements[cursor];
|
|
564
|
-
if (!element)
|
|
1674
|
+
if (!element) {
|
|
1675
|
+
cleanupInstances();
|
|
1676
|
+
return false;
|
|
1677
|
+
}
|
|
565
1678
|
const descriptor = selection.branch.create();
|
|
566
|
-
if (!matchesCompilerHostElement(element, descriptor))
|
|
1679
|
+
if (!matchesCompilerHostElement(element, descriptor)) {
|
|
1680
|
+
cleanupInstances();
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1683
|
+
const host = mountCompilerHostInstance(
|
|
1684
|
+
owner,
|
|
1685
|
+
element,
|
|
1686
|
+
descriptor,
|
|
1687
|
+
selection.branch,
|
|
1688
|
+
this.requestNestedFallback
|
|
1689
|
+
);
|
|
1690
|
+
if (!host) {
|
|
1691
|
+
cleanupInstances();
|
|
1692
|
+
return false;
|
|
1693
|
+
}
|
|
567
1694
|
instances.push({
|
|
568
1695
|
key: selection.key,
|
|
569
|
-
host
|
|
570
|
-
element,
|
|
571
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
572
|
-
}
|
|
1696
|
+
host
|
|
573
1697
|
});
|
|
574
1698
|
cursor += 1;
|
|
575
1699
|
}
|
|
576
|
-
if (cursor + props.trailing !== elements.length)
|
|
1700
|
+
if (cursor + props.trailing !== elements.length) {
|
|
1701
|
+
cleanupInstances();
|
|
1702
|
+
return false;
|
|
1703
|
+
}
|
|
577
1704
|
staticSegments.push(elements.slice(cursor));
|
|
578
1705
|
this.staticSegments = staticSegments;
|
|
579
1706
|
this.rangeInstances = instances;
|
|
1707
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
1708
|
+
cleanupInstances();
|
|
1709
|
+
this.rangeInstances = [];
|
|
1710
|
+
this.staticSegments = [];
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
580
1713
|
return true;
|
|
581
1714
|
}
|
|
582
1715
|
anchorAfter(rangeIndex) {
|
|
@@ -589,27 +1722,52 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
589
1722
|
return this.staticSegments[this.rangeInstances.length]?.[0] || null;
|
|
590
1723
|
}
|
|
591
1724
|
reconcileRange(rangeIndex, selection) {
|
|
592
|
-
if (!this.root) return;
|
|
1725
|
+
if (!this.root) return false;
|
|
593
1726
|
const previous = this.rangeInstances[rangeIndex];
|
|
594
1727
|
if (selection.kind === "empty") {
|
|
1728
|
+
previous?.host.scope?.cleanup();
|
|
595
1729
|
previous?.host.element.remove();
|
|
596
1730
|
this.rangeInstances[rangeIndex] = null;
|
|
597
|
-
return;
|
|
1731
|
+
return true;
|
|
598
1732
|
}
|
|
599
1733
|
if (previous?.key === selection.key) {
|
|
1734
|
+
const descriptor2 = selection.branch.create();
|
|
1735
|
+
const scope = mountCompilerHostTree(
|
|
1736
|
+
owner,
|
|
1737
|
+
previous.host.element,
|
|
1738
|
+
descriptor2,
|
|
1739
|
+
this.requestNestedFallback
|
|
1740
|
+
);
|
|
1741
|
+
if (!scope) {
|
|
1742
|
+
this.requestNestedFallback();
|
|
1743
|
+
return false;
|
|
1744
|
+
}
|
|
1745
|
+
previous.host.scope?.cleanup();
|
|
1746
|
+
previous.host.scope = scope;
|
|
600
1747
|
applyHostConditionalBindings(selection.branch, previous.host);
|
|
601
|
-
return;
|
|
1748
|
+
return true;
|
|
1749
|
+
}
|
|
1750
|
+
const descriptor = selection.branch.create();
|
|
1751
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1752
|
+
const host = mountCompilerHostInstance(
|
|
1753
|
+
owner,
|
|
1754
|
+
element,
|
|
1755
|
+
descriptor,
|
|
1756
|
+
selection.branch,
|
|
1757
|
+
this.requestNestedFallback
|
|
1758
|
+
);
|
|
1759
|
+
if (!host) {
|
|
1760
|
+
this.requestNestedFallback();
|
|
1761
|
+
return false;
|
|
602
1762
|
}
|
|
603
|
-
|
|
1763
|
+
previous?.host.scope?.cleanup();
|
|
604
1764
|
if (previous) previous.host.element.replaceWith(element);
|
|
605
1765
|
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
606
1766
|
this.rangeInstances[rangeIndex] = {
|
|
607
1767
|
key: selection.key,
|
|
608
|
-
host
|
|
609
|
-
element,
|
|
610
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
611
|
-
}
|
|
1768
|
+
host
|
|
612
1769
|
};
|
|
1770
|
+
return true;
|
|
613
1771
|
}
|
|
614
1772
|
reconcile(afterCommit) {
|
|
615
1773
|
if (!this.mounted || !this.root) {
|
|
@@ -630,8 +1788,19 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
630
1788
|
this.activateFallback(afterCommit);
|
|
631
1789
|
return;
|
|
632
1790
|
}
|
|
1791
|
+
if (!applyStaticRangeBindings(
|
|
1792
|
+
this.currentProps.bindings,
|
|
1793
|
+
this.staticSegments,
|
|
1794
|
+
this.staticValues
|
|
1795
|
+
)) {
|
|
1796
|
+
this.activateFallback(afterCommit);
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
633
1799
|
for (let rangeIndex = this.rangeInstances.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
634
|
-
this.reconcileRange(rangeIndex, selections[rangeIndex])
|
|
1800
|
+
if (!this.reconcileRange(rangeIndex, selections[rangeIndex])) {
|
|
1801
|
+
afterCommit?.();
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
635
1804
|
}
|
|
636
1805
|
afterCommit?.();
|
|
637
1806
|
}
|
|
@@ -641,6 +1810,8 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
641
1810
|
return;
|
|
642
1811
|
}
|
|
643
1812
|
this.fallbackRequested = true;
|
|
1813
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1814
|
+
this.subscribeFallbackDescendants();
|
|
644
1815
|
this.setState({ fallback: true }, afterCommit);
|
|
645
1816
|
}
|
|
646
1817
|
schedulePropFallback() {
|
|
@@ -665,9 +1836,13 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
665
1836
|
componentWillUnmount() {
|
|
666
1837
|
this.mounted = false;
|
|
667
1838
|
this.unsubscribe?.();
|
|
1839
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1840
|
+
this.fallbackUnsubscribers = [];
|
|
1841
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
668
1842
|
this.root = null;
|
|
669
1843
|
this.rangeInstances = [];
|
|
670
1844
|
this.staticSegments = [];
|
|
1845
|
+
this.staticValues.length = 0;
|
|
671
1846
|
}
|
|
672
1847
|
render() {
|
|
673
1848
|
const container = this.currentProps.render();
|
|
@@ -708,7 +1883,7 @@ function longestIncreasingSubsequencePositions(sequence) {
|
|
|
708
1883
|
}
|
|
709
1884
|
return positions;
|
|
710
1885
|
}
|
|
711
|
-
function
|
|
1886
|
+
function createKeyedRowConditionalRuntime() {
|
|
712
1887
|
class FarmKeyedRowConditional extends React__default.default.Component {
|
|
713
1888
|
constructor() {
|
|
714
1889
|
super(...arguments);
|
|
@@ -750,6 +1925,22 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
750
1925
|
}
|
|
751
1926
|
}
|
|
752
1927
|
FarmKeyedRowConditional.displayName = "FarmCompiledKeyedRowConditional";
|
|
1928
|
+
return {
|
|
1929
|
+
Component: FarmKeyedRowConditional,
|
|
1930
|
+
readValues: readKeyedRowConditionalValues,
|
|
1931
|
+
changed: keyedRowConditionalChanged
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
function createKeyedRowHostRuntime() {
|
|
1935
|
+
const owner = {
|
|
1936
|
+
subscribe: () => () => {
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1939
|
+
return {
|
|
1940
|
+
mount: (element, descriptor, requestFallback) => mountCompilerHostTree(owner, element, descriptor, requestFallback)
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
function createKeyedRowsBlockComponent(owner, options = {}) {
|
|
753
1944
|
class FarmKeyedRowsBlock extends React__default.default.Component {
|
|
754
1945
|
constructor() {
|
|
755
1946
|
super(...arguments);
|
|
@@ -765,16 +1956,23 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
765
1956
|
this.renderVersion = 0;
|
|
766
1957
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
767
1958
|
this.conditionalListeners = /* @__PURE__ */ new Map();
|
|
1959
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
768
1960
|
this.conditionalOwner = {
|
|
769
1961
|
subscribe: (key, id, refresh) => this.subscribeToRowConditional(key, id, refresh)
|
|
770
1962
|
};
|
|
771
1963
|
this.captureRoot = (root) => {
|
|
772
1964
|
this.root = root;
|
|
773
1965
|
};
|
|
1966
|
+
this.requestHostScopeFallback = () => {
|
|
1967
|
+
this.activateFallback();
|
|
1968
|
+
};
|
|
774
1969
|
this.rowEvent = (item, index, eventId) => {
|
|
775
1970
|
if (this.state.fallback) {
|
|
776
1971
|
return (event) => this.currentProps.events?.[eventId]?.invoke(item, index, event);
|
|
777
1972
|
}
|
|
1973
|
+
if (this.usesDelegatedEvents()) {
|
|
1974
|
+
return void 0;
|
|
1975
|
+
}
|
|
778
1976
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
779
1977
|
let handlers = this.eventHandlers.get(key);
|
|
780
1978
|
if (!handlers) {
|
|
@@ -792,10 +1990,32 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
792
1990
|
handlers.set(eventId, handler);
|
|
793
1991
|
return handler;
|
|
794
1992
|
};
|
|
1993
|
+
this.dispatchDelegatedEvent = (name, event) => {
|
|
1994
|
+
const instance = this.eventRowInstance(event);
|
|
1995
|
+
const eventTarget = event.target;
|
|
1996
|
+
if (!instance || !eventTarget) return;
|
|
1997
|
+
const capture = name.endsWith("Capture");
|
|
1998
|
+
const matches = (this.currentProps.events || []).filter((descriptor) => descriptor.name === name && descriptor.path !== void 0).map((descriptor) => ({
|
|
1999
|
+
descriptor,
|
|
2000
|
+
target: findCompilerHostTarget(instance.element, descriptor.path || [])
|
|
2001
|
+
})).filter(
|
|
2002
|
+
(match) => Boolean(
|
|
2003
|
+
match.target && (match.target === eventTarget || match.target.contains(eventTarget))
|
|
2004
|
+
)
|
|
2005
|
+
).sort(
|
|
2006
|
+
(left, right) => capture ? (left.descriptor.path?.length || 0) - (right.descriptor.path?.length || 0) : (right.descriptor.path?.length || 0) - (left.descriptor.path?.length || 0)
|
|
2007
|
+
);
|
|
2008
|
+
for (const match of matches) {
|
|
2009
|
+
this.invokeDelegatedEvent(match.descriptor, instance, event, match.target);
|
|
2010
|
+
if (event.isPropagationStopped()) break;
|
|
2011
|
+
}
|
|
2012
|
+
};
|
|
795
2013
|
this.rowConditional = (item, index, conditionalId, render) => {
|
|
796
2014
|
if (this.state.fallback) return render(item, index);
|
|
797
2015
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
798
|
-
|
|
2016
|
+
const Conditional = options.conditionals?.Component;
|
|
2017
|
+
if (!Conditional) return render(item, index);
|
|
2018
|
+
return React__default.default.createElement(Conditional, {
|
|
799
2019
|
key: `${key}:${conditionalId}`,
|
|
800
2020
|
owner: this.conditionalOwner,
|
|
801
2021
|
rowKey: key,
|
|
@@ -806,17 +2026,65 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
806
2026
|
render
|
|
807
2027
|
});
|
|
808
2028
|
};
|
|
809
|
-
this.refresh = (afterCommit) => {
|
|
2029
|
+
this.refresh = (afterCommit, dirtyState) => {
|
|
2030
|
+
if (dirtyState && this.refreshDirtyBindings(dirtyState, afterCommit)) return;
|
|
810
2031
|
this.reconcile(afterCommit);
|
|
811
2032
|
};
|
|
812
2033
|
}
|
|
813
2034
|
readRows(props) {
|
|
814
|
-
const
|
|
815
|
-
const items = source ? Array.from(source) : [];
|
|
2035
|
+
const items = materializeIterable(props.items());
|
|
816
2036
|
const keys = items.map((item, index) => keyedRowIdentity(props.rowKey(item, index)));
|
|
817
2037
|
if (new Set(keys).size !== keys.length) return null;
|
|
818
2038
|
return { items, keys };
|
|
819
2039
|
}
|
|
2040
|
+
usesDelegatedEvents(props = this.currentProps) {
|
|
2041
|
+
return Boolean(
|
|
2042
|
+
props.delegateEvents && props.events?.length && props.events.every((event) => event.path !== void 0)
|
|
2043
|
+
);
|
|
2044
|
+
}
|
|
2045
|
+
rebuildElementIndex(instances) {
|
|
2046
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2047
|
+
for (const instance of instances.values()) {
|
|
2048
|
+
this.instancesByElement.set(instance.element, instance);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
eventRowInstance(event) {
|
|
2052
|
+
if (!this.root) return void 0;
|
|
2053
|
+
const target = event.target;
|
|
2054
|
+
if (!target) return void 0;
|
|
2055
|
+
let element = target.nodeType === 1 ? target : target.parentElement;
|
|
2056
|
+
while (element && element.parentElement !== this.root) element = element.parentElement;
|
|
2057
|
+
return element?.parentElement === this.root ? this.instancesByElement.get(element) : void 0;
|
|
2058
|
+
}
|
|
2059
|
+
invokeDelegatedEvent(descriptor, instance, event, currentTarget) {
|
|
2060
|
+
const ownCurrentTarget = Object.getOwnPropertyDescriptor(event, "currentTarget");
|
|
2061
|
+
try {
|
|
2062
|
+
Object.defineProperty(event, "currentTarget", {
|
|
2063
|
+
configurable: true,
|
|
2064
|
+
value: currentTarget
|
|
2065
|
+
});
|
|
2066
|
+
descriptor.invoke(instance.item, instance.index, event);
|
|
2067
|
+
} finally {
|
|
2068
|
+
if (ownCurrentTarget) Object.defineProperty(event, "currentTarget", ownCurrentTarget);
|
|
2069
|
+
else Reflect.deleteProperty(event, "currentTarget");
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
delegatedContainerProps(container) {
|
|
2073
|
+
if (this.state.fallback || !this.usesDelegatedEvents()) return {};
|
|
2074
|
+
const props = container.props;
|
|
2075
|
+
return Object.fromEntries(
|
|
2076
|
+
[...new Set((this.currentProps.events || []).map((event) => event.name))].map((name) => {
|
|
2077
|
+
const existing = props[name];
|
|
2078
|
+
const capture = name.endsWith("Capture");
|
|
2079
|
+
const handler = (event) => {
|
|
2080
|
+
if (capture) existing?.(event);
|
|
2081
|
+
if (!event.isPropagationStopped()) this.dispatchDelegatedEvent(name, event);
|
|
2082
|
+
if (!capture && !event.isPropagationStopped()) existing?.(event);
|
|
2083
|
+
};
|
|
2084
|
+
return [name, handler];
|
|
2085
|
+
})
|
|
2086
|
+
);
|
|
2087
|
+
}
|
|
820
2088
|
subscribeToRowConditional(key, id, refresh) {
|
|
821
2089
|
let listeners = this.conditionalListeners.get(key);
|
|
822
2090
|
if (!listeners) {
|
|
@@ -832,7 +2100,19 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
832
2100
|
};
|
|
833
2101
|
}
|
|
834
2102
|
hasReactOwnedRows(props = this.currentProps) {
|
|
835
|
-
return Boolean(
|
|
2103
|
+
return Boolean(
|
|
2104
|
+
props.conditionals?.length || props.events?.length && !this.usesDelegatedEvents(props)
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
cleanupHostScopes(instances = this.instances) {
|
|
2108
|
+
for (const instance of instances.values()) instance.scope?.cleanup();
|
|
2109
|
+
}
|
|
2110
|
+
mountRowHostScope(element, descriptor, props = this.currentProps) {
|
|
2111
|
+
if (!props.hostBlocks) return void 0;
|
|
2112
|
+
return options.hostBlocks?.mount(element, descriptor, this.requestHostScopeFallback) || null;
|
|
2113
|
+
}
|
|
2114
|
+
readConditionalValues(props, item, index) {
|
|
2115
|
+
return options.conditionals?.readValues(props, item, index) || EMPTY_KEYED_ROW_CONDITIONAL_VALUES;
|
|
836
2116
|
}
|
|
837
2117
|
pruneEventHandlers(keys) {
|
|
838
2118
|
const active = new Set(keys);
|
|
@@ -856,20 +2136,24 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
856
2136
|
);
|
|
857
2137
|
const instances = /* @__PURE__ */ new Map();
|
|
858
2138
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
this.
|
|
862
|
-
|
|
863
|
-
|
|
2139
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2140
|
+
if (this.hasReactOwnedRows() && !matchesCompilerHostElement(elements[index], descriptor, opaqueConditionalPaths)) {
|
|
2141
|
+
this.cleanupHostScopes(instances);
|
|
2142
|
+
return false;
|
|
2143
|
+
}
|
|
2144
|
+
const scope = this.mountRowHostScope(elements[index], descriptor);
|
|
2145
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2146
|
+
this.cleanupHostScopes(instances);
|
|
864
2147
|
return false;
|
|
865
2148
|
}
|
|
866
2149
|
const instance = {
|
|
867
2150
|
key: rows.keys[index],
|
|
868
2151
|
element: elements[index],
|
|
2152
|
+
scope: scope || void 0,
|
|
869
2153
|
values: this.hasReactOwnedRows() ? this.currentProps.bindings.map(() => UNSET_KEYED_ROW_BINDING) : readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
870
2154
|
item: rows.items[index],
|
|
871
2155
|
index,
|
|
872
|
-
conditionalValues:
|
|
2156
|
+
conditionalValues: this.readConditionalValues(
|
|
873
2157
|
this.currentProps,
|
|
874
2158
|
rows.items[index],
|
|
875
2159
|
index
|
|
@@ -880,7 +2164,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
880
2164
|
}
|
|
881
2165
|
instances.set(rows.keys[index], instance);
|
|
882
2166
|
}
|
|
2167
|
+
this.cleanupHostScopes();
|
|
883
2168
|
this.instances = instances;
|
|
2169
|
+
this.rebuildElementIndex(instances);
|
|
884
2170
|
this.pruneEventHandlers(rows.keys);
|
|
885
2171
|
this.pruneConditionalListeners(rows.keys);
|
|
886
2172
|
return true;
|
|
@@ -899,6 +2185,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
899
2185
|
}
|
|
900
2186
|
this.fallbackRequested = true;
|
|
901
2187
|
this.fallbackKeysWereUnsafe = this.hasUnsafeFallbackKeys();
|
|
2188
|
+
this.cleanupHostScopes();
|
|
902
2189
|
this.fallbackVersion += 1;
|
|
903
2190
|
this.setState({ fallback: true }, afterCommit);
|
|
904
2191
|
}
|
|
@@ -933,6 +2220,116 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
933
2220
|
}
|
|
934
2221
|
});
|
|
935
2222
|
}
|
|
2223
|
+
refreshDirtyBindings(dirtyState, afterCommit) {
|
|
2224
|
+
if (!this.mounted || !this.root || this.state.fallback || this.hasReactOwnedRows() || this.currentProps.hostBlocks || !this.currentProps.structureDependencies || this.currentProps.structureDependencies.some((dependency) => dirtyState.has(dependency)) || this.currentProps.bindings.some((binding) => binding.dependencies === void 0)) {
|
|
2225
|
+
return false;
|
|
2226
|
+
}
|
|
2227
|
+
const affectedBindingIndices = [];
|
|
2228
|
+
for (let bindingIndex = 0; bindingIndex < this.currentProps.bindings.length; bindingIndex += 1) {
|
|
2229
|
+
const dependencies = this.currentProps.bindings[bindingIndex].dependencies || [];
|
|
2230
|
+
if (dependencies.some((dependency) => dirtyState.has(dependency))) {
|
|
2231
|
+
affectedBindingIndices.push(bindingIndex);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
for (const instance of this.instances.values()) {
|
|
2235
|
+
for (const bindingIndex of affectedBindingIndices) {
|
|
2236
|
+
applyKeyedRowBinding(
|
|
2237
|
+
this.currentProps,
|
|
2238
|
+
instance,
|
|
2239
|
+
instance.item,
|
|
2240
|
+
instance.index,
|
|
2241
|
+
bindingIndex
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
afterCommit?.();
|
|
2246
|
+
return true;
|
|
2247
|
+
}
|
|
2248
|
+
reconcileStableRows(rows, afterCommit) {
|
|
2249
|
+
if (rows.keys.length !== this.instances.size) return false;
|
|
2250
|
+
let index = 0;
|
|
2251
|
+
for (const key of this.instances.keys()) {
|
|
2252
|
+
if (rows.keys[index] !== key) return false;
|
|
2253
|
+
index += 1;
|
|
2254
|
+
}
|
|
2255
|
+
const conditionalChanges = [];
|
|
2256
|
+
for (index = 0; index < rows.items.length; index += 1) {
|
|
2257
|
+
const key = rows.keys[index];
|
|
2258
|
+
const existing = this.instances.get(key);
|
|
2259
|
+
if (!existing) return false;
|
|
2260
|
+
if (this.currentProps.hostBlocks) {
|
|
2261
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2262
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2263
|
+
this.activateFallback(afterCommit);
|
|
2264
|
+
return true;
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2268
|
+
const conditionalValues = this.readConditionalValues(
|
|
2269
|
+
this.currentProps,
|
|
2270
|
+
rows.items[index],
|
|
2271
|
+
index
|
|
2272
|
+
);
|
|
2273
|
+
for (const [id, values] of conditionalValues) {
|
|
2274
|
+
if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
|
|
2275
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
existing.conditionalValues = conditionalValues;
|
|
2279
|
+
existing.item = rows.items[index];
|
|
2280
|
+
existing.index = index;
|
|
2281
|
+
}
|
|
2282
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2283
|
+
return true;
|
|
2284
|
+
}
|
|
2285
|
+
reconcileSingleRemoval(rows, afterCommit) {
|
|
2286
|
+
if (this.hasReactOwnedRows() || rows.keys.length + 1 !== this.instances.size) return false;
|
|
2287
|
+
const previousKeys = [...this.instances.keys()];
|
|
2288
|
+
let removedIndex = 0;
|
|
2289
|
+
while (removedIndex < rows.keys.length && previousKeys[removedIndex] === rows.keys[removedIndex]) {
|
|
2290
|
+
removedIndex += 1;
|
|
2291
|
+
}
|
|
2292
|
+
for (let index = removedIndex; index < rows.keys.length; index += 1) {
|
|
2293
|
+
if (previousKeys[index + 1] !== rows.keys[index]) return false;
|
|
2294
|
+
}
|
|
2295
|
+
const removedKey = previousKeys[removedIndex];
|
|
2296
|
+
const removed = this.instances.get(removedKey);
|
|
2297
|
+
if (!removed) return false;
|
|
2298
|
+
const conditionalChanges = [];
|
|
2299
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
2300
|
+
const key = rows.keys[index];
|
|
2301
|
+
const existing = this.instances.get(key);
|
|
2302
|
+
if (!existing) return false;
|
|
2303
|
+
if (this.currentProps.hostBlocks) {
|
|
2304
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2305
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2306
|
+
this.activateFallback(afterCommit);
|
|
2307
|
+
return true;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2311
|
+
const conditionalValues = this.readConditionalValues(
|
|
2312
|
+
this.currentProps,
|
|
2313
|
+
rows.items[index],
|
|
2314
|
+
index
|
|
2315
|
+
);
|
|
2316
|
+
for (const [id, values] of conditionalValues) {
|
|
2317
|
+
if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
|
|
2318
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
existing.conditionalValues = conditionalValues;
|
|
2322
|
+
existing.item = rows.items[index];
|
|
2323
|
+
existing.index = index;
|
|
2324
|
+
}
|
|
2325
|
+
removed.scope?.cleanup();
|
|
2326
|
+
removed.element.remove();
|
|
2327
|
+
this.instances.delete(removedKey);
|
|
2328
|
+
this.eventHandlers.delete(removedKey);
|
|
2329
|
+
this.conditionalListeners.delete(removedKey);
|
|
2330
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2331
|
+
return true;
|
|
2332
|
+
}
|
|
936
2333
|
reconcile(afterCommit) {
|
|
937
2334
|
if (!this.mounted || !this.root) {
|
|
938
2335
|
afterCommit?.();
|
|
@@ -952,35 +2349,62 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
952
2349
|
this.activateFallback(afterCommit);
|
|
953
2350
|
return;
|
|
954
2351
|
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
2352
|
+
if (this.hasReactOwnedRows()) {
|
|
2353
|
+
const previousKeys = [...this.instances.keys()];
|
|
2354
|
+
if (rows.keys.length !== previousKeys.length || rows.keys.some((key, index) => key !== previousKeys[index])) {
|
|
2355
|
+
this.synchronizeReactOwnedRows(afterCommit);
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
if (rows.items.length === 0) {
|
|
2360
|
+
this.cleanupHostScopes();
|
|
2361
|
+
this.root.replaceChildren();
|
|
2362
|
+
this.instances = /* @__PURE__ */ new Map();
|
|
2363
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2364
|
+
this.eventHandlers.clear();
|
|
2365
|
+
this.conditionalListeners.clear();
|
|
2366
|
+
afterCommit?.();
|
|
958
2367
|
return;
|
|
959
2368
|
}
|
|
960
|
-
|
|
2369
|
+
if (this.reconcileStableRows(rows, afterCommit)) return;
|
|
2370
|
+
if (this.reconcileSingleRemoval(rows, afterCommit)) return;
|
|
961
2371
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
962
2372
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
963
|
-
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
964
2373
|
const nextKeys = new Set(rows.keys);
|
|
2374
|
+
const hasSurvivingRows = rows.keys.some((key) => this.instances.has(key));
|
|
2375
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
2376
|
+
if (hasSurvivingRows) {
|
|
2377
|
+
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
2378
|
+
}
|
|
965
2379
|
for (const [key, instance] of this.instances) {
|
|
966
|
-
if (!nextKeys.has(key))
|
|
2380
|
+
if (!nextKeys.has(key)) {
|
|
2381
|
+
instance.scope?.cleanup();
|
|
2382
|
+
if (hasSurvivingRows) instance.element.remove();
|
|
2383
|
+
}
|
|
967
2384
|
}
|
|
968
|
-
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
969
|
-
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
2385
|
+
const sequence = hasSurvivingRows ? rows.keys.map((key) => oldIndices.get(key) ?? -1) : rows.keys.map(() => -1);
|
|
2386
|
+
const stablePositions = hasSurvivingRows ? longestIncreasingSubsequencePositions(sequence) : /* @__PURE__ */ new Set();
|
|
970
2387
|
const nextInstances = [];
|
|
971
2388
|
const conditionalChanges = [];
|
|
972
2389
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
973
2390
|
const key = rows.keys[index];
|
|
974
2391
|
const existing = this.instances.get(key);
|
|
975
2392
|
if (existing) {
|
|
2393
|
+
if (this.currentProps.hostBlocks) {
|
|
2394
|
+
const descriptor2 = this.currentProps.create(rows.items[index], index);
|
|
2395
|
+
if (!existing.scope?.update(descriptor2)) {
|
|
2396
|
+
this.activateFallback(afterCommit);
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
976
2400
|
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
977
|
-
const conditionalValues =
|
|
2401
|
+
const conditionalValues = this.readConditionalValues(
|
|
978
2402
|
this.currentProps,
|
|
979
2403
|
rows.items[index],
|
|
980
2404
|
index
|
|
981
2405
|
);
|
|
982
2406
|
for (const [id, values] of conditionalValues) {
|
|
983
|
-
if (
|
|
2407
|
+
if (options.conditionals?.changed(existing.conditionalValues.get(id), values)) {
|
|
984
2408
|
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
985
2409
|
}
|
|
986
2410
|
}
|
|
@@ -990,34 +2414,58 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
990
2414
|
nextInstances.push(existing);
|
|
991
2415
|
continue;
|
|
992
2416
|
}
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
)
|
|
2417
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2418
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
2419
|
+
const scope = this.mountRowHostScope(element, descriptor);
|
|
2420
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2421
|
+
for (const instance of nextInstances) {
|
|
2422
|
+
if (!this.instances.has(instance.key)) instance.scope?.cleanup();
|
|
2423
|
+
}
|
|
2424
|
+
this.activateFallback(afterCommit);
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
997
2427
|
nextInstances.push({
|
|
998
2428
|
key,
|
|
999
2429
|
element,
|
|
2430
|
+
scope: scope || void 0,
|
|
1000
2431
|
values: readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
1001
2432
|
item: rows.items[index],
|
|
1002
2433
|
index,
|
|
1003
|
-
conditionalValues:
|
|
2434
|
+
conditionalValues: this.readConditionalValues(
|
|
1004
2435
|
this.currentProps,
|
|
1005
2436
|
rows.items[index],
|
|
1006
2437
|
index
|
|
1007
2438
|
)
|
|
1008
2439
|
});
|
|
1009
2440
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
const instance
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
2441
|
+
if (!hasSurvivingRows) {
|
|
2442
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2443
|
+
for (const instance of nextInstances) fragment.append(instance.element);
|
|
2444
|
+
this.root.replaceChildren(fragment);
|
|
2445
|
+
} else {
|
|
2446
|
+
let anchor = null;
|
|
2447
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
2448
|
+
const instance = nextInstances[index];
|
|
2449
|
+
if (sequence[index] < 0) {
|
|
2450
|
+
let start = index;
|
|
2451
|
+
while (start > 0 && sequence[start - 1] < 0) start -= 1;
|
|
2452
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2453
|
+
for (let itemIndex = start; itemIndex <= index; itemIndex += 1) {
|
|
2454
|
+
fragment.append(nextInstances[itemIndex].element);
|
|
2455
|
+
}
|
|
2456
|
+
this.root.insertBefore(fragment, anchor);
|
|
2457
|
+
anchor = nextInstances[start].element;
|
|
2458
|
+
index = start;
|
|
2459
|
+
} else {
|
|
2460
|
+
if (!stablePositions.has(index) && instance.element.nextSibling !== anchor) {
|
|
2461
|
+
this.root.insertBefore(instance.element, anchor);
|
|
2462
|
+
}
|
|
2463
|
+
anchor = instance.element;
|
|
2464
|
+
}
|
|
1017
2465
|
}
|
|
1018
|
-
anchor = instance.element;
|
|
1019
2466
|
}
|
|
1020
2467
|
this.instances = new Map(nextInstances.map((instance) => [instance.key, instance]));
|
|
2468
|
+
this.rebuildElementIndex(this.instances);
|
|
1021
2469
|
this.pruneEventHandlers(rows.keys);
|
|
1022
2470
|
this.pruneConditionalListeners(rows.keys);
|
|
1023
2471
|
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
@@ -1060,7 +2508,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
1060
2508
|
this.mounted = false;
|
|
1061
2509
|
this.unsubscribe?.();
|
|
1062
2510
|
this.root = null;
|
|
2511
|
+
this.cleanupHostScopes();
|
|
1063
2512
|
this.instances.clear();
|
|
2513
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
1064
2514
|
this.eventHandlers.clear();
|
|
1065
2515
|
this.conditionalListeners.clear();
|
|
1066
2516
|
}
|
|
@@ -1073,6 +2523,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
1073
2523
|
);
|
|
1074
2524
|
}
|
|
1075
2525
|
return React__default.default.cloneElement(container, {
|
|
2526
|
+
...this.delegatedContainerProps(container),
|
|
1076
2527
|
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
1077
2528
|
ref: this.captureRoot
|
|
1078
2529
|
});
|
|
@@ -1094,6 +2545,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1094
2545
|
this.currentProps = this.props;
|
|
1095
2546
|
this.rangeInstances = [];
|
|
1096
2547
|
this.staticSegments = [];
|
|
2548
|
+
this.staticValues = [];
|
|
1097
2549
|
this.captureRoot = (root) => {
|
|
1098
2550
|
this.root = root;
|
|
1099
2551
|
this.currentProps.rootRef?.(root);
|
|
@@ -1103,8 +2555,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1103
2555
|
};
|
|
1104
2556
|
}
|
|
1105
2557
|
readRange(range) {
|
|
1106
|
-
const
|
|
1107
|
-
const items = source ? Array.from(source) : [];
|
|
2558
|
+
const items = materializeIterable(range.items());
|
|
1108
2559
|
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
1109
2560
|
if (new Set(keys).size !== keys.length) return null;
|
|
1110
2561
|
return { items, keys };
|
|
@@ -1158,6 +2609,11 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1158
2609
|
staticSegments.push(elements.slice(cursor));
|
|
1159
2610
|
this.staticSegments = staticSegments;
|
|
1160
2611
|
this.rangeInstances = instancesByRange;
|
|
2612
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
2613
|
+
this.rangeInstances = [];
|
|
2614
|
+
this.staticSegments = [];
|
|
2615
|
+
return false;
|
|
2616
|
+
}
|
|
1161
2617
|
return true;
|
|
1162
2618
|
}
|
|
1163
2619
|
anchorAfter(rangeIndex) {
|
|
@@ -1234,6 +2690,14 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1234
2690
|
this.activateFallback(afterCommit);
|
|
1235
2691
|
return;
|
|
1236
2692
|
}
|
|
2693
|
+
if (!applyStaticRangeBindings(
|
|
2694
|
+
this.currentProps.bindings,
|
|
2695
|
+
this.staticSegments,
|
|
2696
|
+
this.staticValues
|
|
2697
|
+
)) {
|
|
2698
|
+
this.activateFallback(afterCommit);
|
|
2699
|
+
return;
|
|
2700
|
+
}
|
|
1237
2701
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
1238
2702
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
1239
2703
|
for (let rangeIndex = rowsByRange.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
@@ -1277,6 +2741,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1277
2741
|
this.root = null;
|
|
1278
2742
|
this.rangeInstances = [];
|
|
1279
2743
|
this.staticSegments = [];
|
|
2744
|
+
this.staticValues.length = 0;
|
|
1280
2745
|
}
|
|
1281
2746
|
render() {
|
|
1282
2747
|
const container = this.currentProps.render();
|
|
@@ -1294,6 +2759,128 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1294
2759
|
FarmKeyedRangesBlock.displayName = "FarmCompiledKeyedRanges";
|
|
1295
2760
|
return FarmKeyedRangesBlock;
|
|
1296
2761
|
}
|
|
2762
|
+
function createMixedRangesBlockComponent(owner) {
|
|
2763
|
+
class FarmMixedRangesBlock extends React__default.default.Component {
|
|
2764
|
+
constructor() {
|
|
2765
|
+
super(...arguments);
|
|
2766
|
+
this.state = { fallback: false };
|
|
2767
|
+
this.root = null;
|
|
2768
|
+
this.mounted = false;
|
|
2769
|
+
this.fallbackRequested = false;
|
|
2770
|
+
this.fallbackVersion = 0;
|
|
2771
|
+
this.propFallbackQueued = false;
|
|
2772
|
+
this.currentProps = this.props;
|
|
2773
|
+
this.controller = null;
|
|
2774
|
+
this.fallbackUnsubscribers = [];
|
|
2775
|
+
this.captureRoot = (root) => {
|
|
2776
|
+
this.root = root;
|
|
2777
|
+
this.currentProps.rootRef?.(root);
|
|
2778
|
+
};
|
|
2779
|
+
this.activateFallback = (afterCommit) => {
|
|
2780
|
+
if (!this.mounted || this.state.fallback || this.fallbackRequested) {
|
|
2781
|
+
afterCommit?.();
|
|
2782
|
+
return;
|
|
2783
|
+
}
|
|
2784
|
+
this.fallbackRequested = true;
|
|
2785
|
+
this.controller?.cleanup();
|
|
2786
|
+
this.controller = null;
|
|
2787
|
+
this.fallbackVersion += 1;
|
|
2788
|
+
this.setState({ fallback: true }, () => {
|
|
2789
|
+
this.subscribeFallbackBlocks();
|
|
2790
|
+
afterCommit?.();
|
|
2791
|
+
});
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
clearFallbackSubscriptions() {
|
|
2795
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
2796
|
+
this.fallbackUnsubscribers = [];
|
|
2797
|
+
}
|
|
2798
|
+
subscribeFallbackBlocks() {
|
|
2799
|
+
this.clearFallbackSubscriptions();
|
|
2800
|
+
const descriptor = this.currentProps.create();
|
|
2801
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2802
|
+
collectCompilerHostBlockIds(descriptor, ids);
|
|
2803
|
+
for (const id of ids) {
|
|
2804
|
+
this.fallbackUnsubscribers.push(
|
|
2805
|
+
owner.subscribe(id, (afterCommit) => {
|
|
2806
|
+
if (!this.mounted || !this.state.fallback) {
|
|
2807
|
+
afterCommit?.();
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
this.fallbackVersion += 1;
|
|
2811
|
+
this.forceUpdate(afterCommit);
|
|
2812
|
+
})
|
|
2813
|
+
);
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
adopt() {
|
|
2817
|
+
if (!this.root) return false;
|
|
2818
|
+
const descriptor = this.currentProps.create();
|
|
2819
|
+
const block = descriptor.block;
|
|
2820
|
+
if (block?.kind !== "mixed-ranges" || block.id !== this.currentProps.id) return false;
|
|
2821
|
+
const controller = new CompilerNestedMixedRanges(
|
|
2822
|
+
owner,
|
|
2823
|
+
this.root,
|
|
2824
|
+
descriptor,
|
|
2825
|
+
block,
|
|
2826
|
+
this.activateFallback
|
|
2827
|
+
);
|
|
2828
|
+
try {
|
|
2829
|
+
if (!controller.adopt()) {
|
|
2830
|
+
controller.cleanup();
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
} catch (error) {
|
|
2834
|
+
controller.cleanup();
|
|
2835
|
+
throw error;
|
|
2836
|
+
}
|
|
2837
|
+
this.controller = controller;
|
|
2838
|
+
return true;
|
|
2839
|
+
}
|
|
2840
|
+
schedulePropFallback() {
|
|
2841
|
+
if (this.propFallbackQueued) return;
|
|
2842
|
+
this.propFallbackQueued = true;
|
|
2843
|
+
queueMicrotask(() => {
|
|
2844
|
+
this.propFallbackQueued = false;
|
|
2845
|
+
if (this.mounted && !this.state.fallback) this.activateFallback();
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2848
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
2849
|
+
this.currentProps = nextProps;
|
|
2850
|
+
if (nextState.fallback || this.state.fallback) return true;
|
|
2851
|
+
this.schedulePropFallback();
|
|
2852
|
+
return false;
|
|
2853
|
+
}
|
|
2854
|
+
componentDidMount() {
|
|
2855
|
+
this.mounted = true;
|
|
2856
|
+
if (!this.adopt()) this.activateFallback();
|
|
2857
|
+
}
|
|
2858
|
+
componentDidUpdate() {
|
|
2859
|
+
if (this.state.fallback) this.subscribeFallbackBlocks();
|
|
2860
|
+
}
|
|
2861
|
+
componentWillUnmount() {
|
|
2862
|
+
this.mounted = false;
|
|
2863
|
+
this.controller?.cleanup();
|
|
2864
|
+
this.controller = null;
|
|
2865
|
+
this.clearFallbackSubscriptions();
|
|
2866
|
+
this.root = null;
|
|
2867
|
+
}
|
|
2868
|
+
render() {
|
|
2869
|
+
const container = this.currentProps.render();
|
|
2870
|
+
if (!React__default.default.isValidElement(container) || typeof container.type !== "string") {
|
|
2871
|
+
throw new TypeError(
|
|
2872
|
+
`Compiled mixed ranges ${this.currentProps.id} must own one host container.`
|
|
2873
|
+
);
|
|
2874
|
+
}
|
|
2875
|
+
return React__default.default.cloneElement(container, {
|
|
2876
|
+
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
2877
|
+
ref: this.captureRoot
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
FarmMixedRangesBlock.displayName = "FarmCompiledMixedRanges";
|
|
2882
|
+
return FarmMixedRangesBlock;
|
|
2883
|
+
}
|
|
1297
2884
|
function createComponentBlockComponent(owner) {
|
|
1298
2885
|
class FarmComponentBlock extends React__default.default.Component {
|
|
1299
2886
|
constructor() {
|
|
@@ -1323,12 +2910,86 @@ function createComponentBlockComponent(owner) {
|
|
|
1323
2910
|
FarmComponentBlock.displayName = "FarmCompiledComponentIsland";
|
|
1324
2911
|
return FarmComponentBlock;
|
|
1325
2912
|
}
|
|
1326
|
-
|
|
2913
|
+
var conditionalRuntimeFeature = {
|
|
2914
|
+
name: "conditional",
|
|
2915
|
+
create: (owner) => ({
|
|
2916
|
+
Conditional: createConditionalBlockComponent(owner)
|
|
2917
|
+
})
|
|
2918
|
+
};
|
|
2919
|
+
var hostConditionalRuntimeFeature = {
|
|
2920
|
+
name: "host-conditional",
|
|
2921
|
+
create: (owner) => ({
|
|
2922
|
+
HostConditional: createHostConditionalBlockComponent(owner)
|
|
2923
|
+
})
|
|
2924
|
+
};
|
|
2925
|
+
var conditionalRangesRuntimeFeature = {
|
|
2926
|
+
name: "conditional-ranges",
|
|
2927
|
+
create: (owner) => ({
|
|
2928
|
+
ConditionalRanges: createConditionalRangesBlockComponent(owner)
|
|
2929
|
+
})
|
|
2930
|
+
};
|
|
2931
|
+
var keyedListRuntimeFeature = {
|
|
2932
|
+
name: "keyed-list",
|
|
2933
|
+
create: (owner) => ({
|
|
2934
|
+
KeyedList: createKeyedListBlockComponent(owner)
|
|
2935
|
+
})
|
|
2936
|
+
};
|
|
2937
|
+
var keyedRowsRuntimeFeature = {
|
|
2938
|
+
name: "keyed-rows",
|
|
2939
|
+
create: (owner) => ({
|
|
2940
|
+
KeyedRows: createKeyedRowsBlockComponent(owner)
|
|
2941
|
+
})
|
|
2942
|
+
};
|
|
2943
|
+
var keyedRowsConditionalRuntimeFeature = {
|
|
2944
|
+
name: "keyed-rows:conditional",
|
|
2945
|
+
create: (owner) => ({
|
|
2946
|
+
KeyedRows: createKeyedRowsBlockComponent(owner, {
|
|
2947
|
+
conditionals: createKeyedRowConditionalRuntime()
|
|
2948
|
+
})
|
|
2949
|
+
})
|
|
2950
|
+
};
|
|
2951
|
+
var keyedRowsHostRuntimeFeature = {
|
|
2952
|
+
name: "keyed-rows:host",
|
|
2953
|
+
create: (owner) => ({
|
|
2954
|
+
KeyedRows: createKeyedRowsBlockComponent(owner, {
|
|
2955
|
+
hostBlocks: createKeyedRowHostRuntime()
|
|
2956
|
+
})
|
|
2957
|
+
})
|
|
2958
|
+
};
|
|
2959
|
+
var keyedRowsCompleteRuntimeFeature = {
|
|
2960
|
+
name: "keyed-rows:complete",
|
|
2961
|
+
create: (owner) => ({
|
|
2962
|
+
KeyedRows: createKeyedRowsBlockComponent(owner, {
|
|
2963
|
+
conditionals: createKeyedRowConditionalRuntime(),
|
|
2964
|
+
hostBlocks: createKeyedRowHostRuntime()
|
|
2965
|
+
})
|
|
2966
|
+
})
|
|
2967
|
+
};
|
|
2968
|
+
var keyedRangesRuntimeFeature = {
|
|
2969
|
+
name: "keyed-ranges",
|
|
2970
|
+
create: (owner) => ({
|
|
2971
|
+
KeyedRanges: createKeyedRangesBlockComponent(owner)
|
|
2972
|
+
})
|
|
2973
|
+
};
|
|
2974
|
+
var mixedRangesRuntimeFeature = {
|
|
2975
|
+
name: "mixed-ranges",
|
|
2976
|
+
create: (owner) => ({
|
|
2977
|
+
MixedRanges: createMixedRangesBlockComponent(owner)
|
|
2978
|
+
})
|
|
2979
|
+
};
|
|
2980
|
+
var componentRuntimeFeature = {
|
|
2981
|
+
name: "component",
|
|
2982
|
+
create: (owner) => ({
|
|
2983
|
+
Component: createComponentBlockComponent(owner)
|
|
2984
|
+
})
|
|
2985
|
+
};
|
|
2986
|
+
function createCompiledComponentWithFeatures(definition, runtimeFeatures) {
|
|
1327
2987
|
const stateSignature = definition.stateSignature || String(definition.initialize.length);
|
|
2988
|
+
const runtimeSignature = [...new Set(runtimeFeatures.map((feature) => feature.name))].sort().join(",");
|
|
1328
2989
|
if (definition.hmrId) {
|
|
1329
2990
|
const registry = getCompilerHmrRegistry();
|
|
1330
2991
|
const existing = registry.get(definition.hmrId);
|
|
1331
|
-
if (existing?.stateSignature === stateSignature) {
|
|
2992
|
+
if (existing?.stateSignature === stateSignature && existing.runtimeSignature === runtimeSignature) {
|
|
1332
2993
|
existing.definition.current = definition;
|
|
1333
2994
|
existing.component.displayName = `FarmCompiled(${definition.displayName})`;
|
|
1334
2995
|
for (const refresh of existing.refreshListeners) refresh();
|
|
@@ -1346,6 +3007,17 @@ function createCompiledComponent(definition) {
|
|
|
1346
3007
|
this.hasBindingError = false;
|
|
1347
3008
|
this.inputSelection = null;
|
|
1348
3009
|
this.dirtyState = /* @__PURE__ */ new Set();
|
|
3010
|
+
this.indexedDefinition = null;
|
|
3011
|
+
this.staticBindingsByDependency = [];
|
|
3012
|
+
this.blockBindingsByDependency = [];
|
|
3013
|
+
this.blockBindings = /* @__PURE__ */ new Map();
|
|
3014
|
+
this.trackedBindingsByDependency = [];
|
|
3015
|
+
this.trackedDependenciesByBinding = /* @__PURE__ */ new Map();
|
|
3016
|
+
this.bindingValues = /* @__PURE__ */ new Map();
|
|
3017
|
+
this.activeBinding = null;
|
|
3018
|
+
this.activeDependencies = null;
|
|
3019
|
+
this.renderedDefinition = null;
|
|
3020
|
+
this.renderedElement = null;
|
|
1349
3021
|
this.blockRefreshListeners = /* @__PURE__ */ new Map();
|
|
1350
3022
|
this.blockRoots = /* @__PURE__ */ new Map();
|
|
1351
3023
|
this.blockRootElements = /* @__PURE__ */ new Set();
|
|
@@ -1357,50 +3029,149 @@ function createCompiledComponent(definition) {
|
|
|
1357
3029
|
this.refreshDefinition = () => {
|
|
1358
3030
|
if (this.mounted) this.forceUpdate();
|
|
1359
3031
|
};
|
|
1360
|
-
|
|
3032
|
+
const initialState = definitionReference.current.initialize(props);
|
|
3033
|
+
const initialProps = definitionReference.current.readProps?.(props) || [];
|
|
3034
|
+
this.propCellOffset = initialState.length;
|
|
3035
|
+
this.cells = [...initialState, ...initialProps].map((initialValue, index) => {
|
|
1361
3036
|
let value = initialValue;
|
|
1362
3037
|
const pending = [];
|
|
1363
3038
|
return {
|
|
1364
|
-
get: () =>
|
|
3039
|
+
get: () => {
|
|
3040
|
+
if (this.activeBinding && this.activeDependencies) {
|
|
3041
|
+
this.activeDependencies.add(index);
|
|
3042
|
+
}
|
|
3043
|
+
return value;
|
|
3044
|
+
},
|
|
1365
3045
|
set: (next) => {
|
|
1366
|
-
pending.push(next);
|
|
3046
|
+
pending.push({ kind: "state", update: next });
|
|
1367
3047
|
this.scheduleBindingFlush(index);
|
|
1368
3048
|
},
|
|
3049
|
+
replace: (next) => {
|
|
3050
|
+
pending.push({ kind: "value", value: next });
|
|
3051
|
+
},
|
|
1369
3052
|
flush: () => {
|
|
1370
3053
|
if (pending.length === 0) return false;
|
|
1371
3054
|
const previous = value;
|
|
1372
3055
|
for (const next of pending.splice(0)) {
|
|
1373
|
-
|
|
3056
|
+
if (next.kind === "value") {
|
|
3057
|
+
value = next.value;
|
|
3058
|
+
} else {
|
|
3059
|
+
value = typeof next.update === "function" ? next.update(value) : next.update;
|
|
3060
|
+
}
|
|
1374
3061
|
}
|
|
1375
3062
|
return !Object.is(previous, value);
|
|
1376
3063
|
}
|
|
1377
3064
|
};
|
|
1378
3065
|
});
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
HostConditional: createHostConditionalBlockComponent({
|
|
1385
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1386
|
-
}),
|
|
1387
|
-
ConditionalRanges: createConditionalRangesBlockComponent({
|
|
1388
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1389
|
-
}),
|
|
1390
|
-
KeyedList: createKeyedListBlockComponent({
|
|
1391
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1392
|
-
}),
|
|
1393
|
-
KeyedRows: createKeyedRowsBlockComponent({
|
|
1394
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1395
|
-
}),
|
|
1396
|
-
KeyedRanges: createKeyedRangesBlockComponent({
|
|
1397
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1398
|
-
}),
|
|
1399
|
-
Component: createComponentBlockComponent({
|
|
1400
|
-
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1401
|
-
}),
|
|
3066
|
+
const featureOwner = {
|
|
3067
|
+
setRoot: (id, root) => this.setBlockRoot(id, root),
|
|
3068
|
+
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
3069
|
+
};
|
|
3070
|
+
const blockRuntime = {
|
|
1402
3071
|
target: (id) => this.bindingTarget(id)
|
|
1403
3072
|
};
|
|
3073
|
+
for (const feature of runtimeFeatures) {
|
|
3074
|
+
Object.assign(blockRuntime, feature.create(featureOwner));
|
|
3075
|
+
}
|
|
3076
|
+
this.blockRuntime = blockRuntime;
|
|
3077
|
+
}
|
|
3078
|
+
usesHybridReactivity() {
|
|
3079
|
+
return definitionReference.current.reactivity === "hybrid";
|
|
3080
|
+
}
|
|
3081
|
+
canReuseRenderedElement(currentDefinition, propValues) {
|
|
3082
|
+
return Boolean(
|
|
3083
|
+
this.mounted && propValues && propValues.every(isCompilerPrimitive) && this.renderedDefinition === currentDefinition && this.renderedElement
|
|
3084
|
+
);
|
|
3085
|
+
}
|
|
3086
|
+
renderCellsForProps(propValues) {
|
|
3087
|
+
if (!propValues) return { cells: this.cells, commit: () => void 0 };
|
|
3088
|
+
let committed = false;
|
|
3089
|
+
const cells = this.cells.slice(0, this.propCellOffset);
|
|
3090
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3091
|
+
const cell = this.cells[this.propCellOffset + propIndex];
|
|
3092
|
+
if (!cell) continue;
|
|
3093
|
+
cells.push({
|
|
3094
|
+
get: () => committed ? cell.get() : propValues[propIndex],
|
|
3095
|
+
set: (next) => cell.set(next)
|
|
3096
|
+
});
|
|
3097
|
+
}
|
|
3098
|
+
return {
|
|
3099
|
+
cells,
|
|
3100
|
+
commit: () => {
|
|
3101
|
+
committed = true;
|
|
3102
|
+
}
|
|
3103
|
+
};
|
|
3104
|
+
}
|
|
3105
|
+
tracksBinding(binding) {
|
|
3106
|
+
return this.usesHybridReactivity() && binding.tracking === "dynamic";
|
|
3107
|
+
}
|
|
3108
|
+
ensureBindingIndex() {
|
|
3109
|
+
const currentDefinition = definitionReference.current;
|
|
3110
|
+
if (this.indexedDefinition === currentDefinition) return;
|
|
3111
|
+
this.indexedDefinition = currentDefinition;
|
|
3112
|
+
this.staticBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3113
|
+
this.blockBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3114
|
+
this.trackedBindingsByDependency = Array.from(
|
|
3115
|
+
{ length: this.cells.length },
|
|
3116
|
+
() => /* @__PURE__ */ new Set()
|
|
3117
|
+
);
|
|
3118
|
+
this.blockBindings.clear();
|
|
3119
|
+
this.trackedDependenciesByBinding.clear();
|
|
3120
|
+
this.bindingValues.clear();
|
|
3121
|
+
for (const binding of currentDefinition.bindings) {
|
|
3122
|
+
if (binding.kind === "block") this.blockBindings.set(binding.id, binding);
|
|
3123
|
+
for (const dependency of binding.dependencies) {
|
|
3124
|
+
if (dependency < 0 || dependency >= this.cells.length) continue;
|
|
3125
|
+
if (binding.kind === "block") {
|
|
3126
|
+
this.blockBindingsByDependency[dependency].push(binding);
|
|
3127
|
+
} else if (!this.tracksBinding(binding)) {
|
|
3128
|
+
this.staticBindingsByDependency[dependency].push(binding);
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
updateTrackedDependencies(binding, nextDependencies) {
|
|
3134
|
+
const previousDependencies = this.trackedDependenciesByBinding.get(binding);
|
|
3135
|
+
if (previousDependencies) {
|
|
3136
|
+
for (const dependency of previousDependencies) {
|
|
3137
|
+
if (!nextDependencies.has(dependency)) {
|
|
3138
|
+
this.trackedBindingsByDependency[dependency]?.delete(binding);
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
for (const dependency of nextDependencies) {
|
|
3143
|
+
if (!previousDependencies?.has(dependency)) {
|
|
3144
|
+
this.trackedBindingsByDependency[dependency]?.add(binding);
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
this.trackedDependenciesByBinding.set(binding, nextDependencies);
|
|
3148
|
+
}
|
|
3149
|
+
readBinding(binding) {
|
|
3150
|
+
if (!this.tracksBinding(binding)) return binding.read(this.props, this.cells);
|
|
3151
|
+
const previousBinding = this.activeBinding;
|
|
3152
|
+
const previousDependencies = this.activeDependencies;
|
|
3153
|
+
const nextDependencies = /* @__PURE__ */ new Set();
|
|
3154
|
+
this.activeBinding = binding;
|
|
3155
|
+
this.activeDependencies = nextDependencies;
|
|
3156
|
+
try {
|
|
3157
|
+
return binding.read(this.props, this.cells);
|
|
3158
|
+
} finally {
|
|
3159
|
+
this.activeBinding = previousBinding;
|
|
3160
|
+
this.activeDependencies = previousDependencies;
|
|
3161
|
+
this.updateTrackedDependencies(binding, nextDependencies);
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
bindingValue(binding, value) {
|
|
3165
|
+
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
3166
|
+
}
|
|
3167
|
+
primeHybridBindings() {
|
|
3168
|
+
if (!this.usesHybridReactivity()) return;
|
|
3169
|
+
for (const binding of definitionReference.current.bindings) {
|
|
3170
|
+
if (binding.kind === "block") continue;
|
|
3171
|
+
if (!this.tracksBinding(binding)) continue;
|
|
3172
|
+
const value = this.readBinding(binding);
|
|
3173
|
+
this.bindingValues.set(binding, this.bindingValue(binding, value));
|
|
3174
|
+
}
|
|
1404
3175
|
}
|
|
1405
3176
|
bindingTarget(id) {
|
|
1406
3177
|
const existing = this.bindingTargetRefs.get(id);
|
|
@@ -1458,83 +3229,118 @@ function createCompiledComponent(definition) {
|
|
|
1458
3229
|
this.flushQueued = true;
|
|
1459
3230
|
queueMicrotask(() => {
|
|
1460
3231
|
this.flushQueued = false;
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
3232
|
+
this.flushBindingUpdates();
|
|
3233
|
+
});
|
|
3234
|
+
}
|
|
3235
|
+
flushBindingUpdates() {
|
|
3236
|
+
const inputSelection = this.inputSelection;
|
|
3237
|
+
this.inputSelection = null;
|
|
3238
|
+
if (!this.mounted) return;
|
|
3239
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
3240
|
+
for (const index of this.dirtyState) {
|
|
3241
|
+
if (this.cells[index]?.flush()) dirty.add(index);
|
|
3242
|
+
}
|
|
3243
|
+
this.dirtyState.clear();
|
|
3244
|
+
if (dirty.size === 0) return;
|
|
3245
|
+
try {
|
|
3246
|
+
this.ensureBindingIndex();
|
|
3247
|
+
const affectedBlockIds = /* @__PURE__ */ new Set();
|
|
3248
|
+
const affectedBindings = /* @__PURE__ */ new Set();
|
|
3249
|
+
for (const dependency of dirty) {
|
|
3250
|
+
for (const binding of this.blockBindingsByDependency[dependency] || []) {
|
|
3251
|
+
affectedBlockIds.add(binding.id);
|
|
1480
3252
|
}
|
|
1481
|
-
const
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
parent = blockBindings.get(parent)?.parent;
|
|
1488
|
-
}
|
|
1489
|
-
return false;
|
|
1490
|
-
};
|
|
1491
|
-
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
1492
|
-
const binding = blockBindings.get(id);
|
|
1493
|
-
const refresh = this.blockRefreshListeners.get(id);
|
|
1494
|
-
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
1495
|
-
}).filter(
|
|
1496
|
-
(refresh) => refresh !== void 0
|
|
1497
|
-
);
|
|
1498
|
-
for (const binding of bindings) {
|
|
1499
|
-
if (binding.kind !== "block" && binding.dependencies.some((dependency) => dirty.has(dependency))) {
|
|
1500
|
-
this.applyBinding(binding);
|
|
3253
|
+
for (const binding of this.staticBindingsByDependency[dependency] || []) {
|
|
3254
|
+
affectedBindings.add(binding);
|
|
3255
|
+
}
|
|
3256
|
+
if (this.usesHybridReactivity()) {
|
|
3257
|
+
for (const binding of this.trackedBindingsByDependency[dependency] || []) {
|
|
3258
|
+
affectedBindings.add(binding);
|
|
1501
3259
|
}
|
|
1502
3260
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
3261
|
+
}
|
|
3262
|
+
const hasAffectedMountedAncestor = (binding) => {
|
|
3263
|
+
let parent = binding.parent;
|
|
3264
|
+
while (parent !== void 0) {
|
|
3265
|
+
if (affectedBlockIds.has(parent) && this.blockRefreshListeners.has(parent)) {
|
|
3266
|
+
return true;
|
|
3267
|
+
}
|
|
3268
|
+
parent = this.blockBindings.get(parent)?.parent;
|
|
1509
3269
|
}
|
|
1510
|
-
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
this.
|
|
3270
|
+
return false;
|
|
3271
|
+
};
|
|
3272
|
+
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
3273
|
+
const binding = this.blockBindings.get(id);
|
|
3274
|
+
const refresh = this.blockRefreshListeners.get(id);
|
|
3275
|
+
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
3276
|
+
}).filter((refresh) => refresh !== void 0);
|
|
3277
|
+
for (const binding of affectedBindings) {
|
|
3278
|
+
if (binding.kind !== "block") this.applyBinding(binding);
|
|
1515
3279
|
}
|
|
1516
|
-
|
|
3280
|
+
let pendingBlockCommits = blockRefreshes.length;
|
|
3281
|
+
for (const refresh of blockRefreshes) {
|
|
3282
|
+
refresh(() => {
|
|
3283
|
+
pendingBlockCommits -= 1;
|
|
3284
|
+
if (pendingBlockCommits === 0) this.restoreInputSelection(inputSelection);
|
|
3285
|
+
}, dirty);
|
|
3286
|
+
}
|
|
3287
|
+
if (blockRefreshes.length === 0) this.restoreInputSelection(inputSelection);
|
|
3288
|
+
} catch (error) {
|
|
3289
|
+
this.bindingError = error;
|
|
3290
|
+
this.hasBindingError = true;
|
|
3291
|
+
this.forceUpdate();
|
|
3292
|
+
}
|
|
1517
3293
|
}
|
|
1518
|
-
applyBinding(binding) {
|
|
3294
|
+
applyBinding(binding, force = false) {
|
|
1519
3295
|
if (!this.root || binding.kind === "block") return;
|
|
1520
3296
|
const target = binding.target === void 0 ? findBindingTarget(this.root, binding.path, this.blockRootElements) : binding.path.length === 0 ? this.root : this.bindingTargets.get(binding.target) || null;
|
|
1521
3297
|
if (!target) return;
|
|
1522
|
-
const value =
|
|
3298
|
+
const value = this.readBinding(binding);
|
|
3299
|
+
const comparableValue = this.bindingValue(binding, value);
|
|
3300
|
+
if (!force && this.bindingValues.has(binding)) {
|
|
3301
|
+
if (Object.is(this.bindingValues.get(binding), comparableValue)) return;
|
|
3302
|
+
}
|
|
1523
3303
|
if (binding.kind === "text") {
|
|
1524
|
-
target.textContent =
|
|
3304
|
+
target.textContent = comparableValue;
|
|
1525
3305
|
} else if (binding.kind === "style") {
|
|
1526
3306
|
updateStyle(target, binding.name, value);
|
|
1527
3307
|
} else {
|
|
1528
3308
|
updateAttribute(target, binding.name, value);
|
|
1529
3309
|
}
|
|
3310
|
+
this.bindingValues.set(binding, comparableValue);
|
|
1530
3311
|
}
|
|
1531
3312
|
componentDidMount() {
|
|
1532
3313
|
this.mounted = true;
|
|
1533
3314
|
refreshListeners.add(this.refreshDefinition);
|
|
3315
|
+
this.ensureBindingIndex();
|
|
3316
|
+
this.primeHybridBindings();
|
|
1534
3317
|
}
|
|
1535
|
-
|
|
3318
|
+
getSnapshotBeforeUpdate() {
|
|
3319
|
+
const currentDefinition = definitionReference.current;
|
|
3320
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3321
|
+
return this.canReuseRenderedElement(currentDefinition, propValues);
|
|
3322
|
+
}
|
|
3323
|
+
componentDidUpdate(_previousProps, _previousState, reusedRenderedElement = false) {
|
|
3324
|
+
const propValues = definitionReference.current.readProps?.(this.props) || null;
|
|
3325
|
+
if (propValues) {
|
|
3326
|
+
if (reusedRenderedElement) this.captureInputSelection();
|
|
3327
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3328
|
+
const cellIndex = this.propCellOffset + propIndex;
|
|
3329
|
+
const cell = this.cells[cellIndex];
|
|
3330
|
+
if (!cell) continue;
|
|
3331
|
+
cell.replace(propValues[propIndex]);
|
|
3332
|
+
if (reusedRenderedElement) {
|
|
3333
|
+
this.dirtyState.add(cellIndex);
|
|
3334
|
+
} else {
|
|
3335
|
+
cell.flush();
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
this.flushBindingUpdates();
|
|
3339
|
+
return;
|
|
3340
|
+
}
|
|
3341
|
+
this.ensureBindingIndex();
|
|
1536
3342
|
for (const binding of definitionReference.current.bindings) {
|
|
1537
|
-
if (binding.kind !== "block") this.applyBinding(binding);
|
|
3343
|
+
if (binding.kind !== "block") this.applyBinding(binding, true);
|
|
1538
3344
|
}
|
|
1539
3345
|
}
|
|
1540
3346
|
componentWillUnmount() {
|
|
@@ -1547,36 +3353,68 @@ function createCompiledComponent(definition) {
|
|
|
1547
3353
|
this.blockRootElements.clear();
|
|
1548
3354
|
this.bindingTargets.clear();
|
|
1549
3355
|
this.bindingTargetRefs.clear();
|
|
3356
|
+
this.indexedDefinition = null;
|
|
3357
|
+
this.staticBindingsByDependency = [];
|
|
3358
|
+
this.blockBindingsByDependency = [];
|
|
3359
|
+
this.blockBindings.clear();
|
|
3360
|
+
this.trackedBindingsByDependency = [];
|
|
3361
|
+
this.trackedDependenciesByBinding.clear();
|
|
3362
|
+
this.bindingValues.clear();
|
|
3363
|
+
this.activeBinding = null;
|
|
3364
|
+
this.activeDependencies = null;
|
|
1550
3365
|
refreshListeners.delete(this.refreshDefinition);
|
|
1551
3366
|
}
|
|
1552
3367
|
render() {
|
|
1553
3368
|
if (this.hasBindingError) throw this.bindingError;
|
|
1554
3369
|
const currentDefinition = definitionReference.current;
|
|
1555
|
-
const
|
|
3370
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3371
|
+
if (this.canReuseRenderedElement(currentDefinition, propValues)) {
|
|
3372
|
+
return this.renderedElement;
|
|
3373
|
+
}
|
|
3374
|
+
const renderCells = this.renderCellsForProps(propValues);
|
|
3375
|
+
const element = currentDefinition.render(this.props, renderCells.cells, this.blockRuntime);
|
|
1556
3376
|
if (!React__default.default.isValidElement(element)) {
|
|
1557
3377
|
throw new TypeError(
|
|
1558
3378
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1559
3379
|
);
|
|
1560
3380
|
}
|
|
3381
|
+
let renderedElement;
|
|
3382
|
+
const captureCommittedRoot = (root) => {
|
|
3383
|
+
this.captureRoot(root);
|
|
3384
|
+
if (!root) return;
|
|
3385
|
+
renderCells.commit();
|
|
3386
|
+
this.renderedDefinition = currentDefinition;
|
|
3387
|
+
this.renderedElement = renderedElement;
|
|
3388
|
+
};
|
|
1561
3389
|
if (element.type === this.blockRuntime.KeyedRanges) {
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
3390
|
+
renderedElement = React__default.default.cloneElement(
|
|
3391
|
+
element,
|
|
3392
|
+
{
|
|
3393
|
+
rootRef: captureCommittedRoot
|
|
3394
|
+
}
|
|
3395
|
+
);
|
|
3396
|
+
} else if (element.type === this.blockRuntime.ConditionalRanges) {
|
|
3397
|
+
renderedElement = React__default.default.cloneElement(
|
|
1568
3398
|
element,
|
|
1569
|
-
{ rootRef:
|
|
3399
|
+
{ rootRef: captureCommittedRoot }
|
|
1570
3400
|
);
|
|
1571
|
-
}
|
|
1572
|
-
|
|
3401
|
+
} else if (element.type === this.blockRuntime.MixedRanges) {
|
|
3402
|
+
renderedElement = React__default.default.cloneElement(
|
|
3403
|
+
element,
|
|
3404
|
+
{
|
|
3405
|
+
rootRef: captureCommittedRoot
|
|
3406
|
+
}
|
|
3407
|
+
);
|
|
3408
|
+
} else if (typeof element.type !== "string") {
|
|
1573
3409
|
throw new TypeError(
|
|
1574
3410
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1575
3411
|
);
|
|
3412
|
+
} else {
|
|
3413
|
+
renderedElement = React__default.default.cloneElement(element, {
|
|
3414
|
+
ref: captureCommittedRoot
|
|
3415
|
+
});
|
|
1576
3416
|
}
|
|
1577
|
-
return
|
|
1578
|
-
ref: this.captureRoot
|
|
1579
|
-
});
|
|
3417
|
+
return renderedElement;
|
|
1580
3418
|
}
|
|
1581
3419
|
}
|
|
1582
3420
|
FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
|
|
@@ -1586,12 +3424,38 @@ function createCompiledComponent(definition) {
|
|
|
1586
3424
|
component,
|
|
1587
3425
|
definition: definitionReference,
|
|
1588
3426
|
refreshListeners,
|
|
1589
|
-
stateSignature
|
|
3427
|
+
stateSignature,
|
|
3428
|
+
runtimeSignature
|
|
1590
3429
|
});
|
|
1591
3430
|
}
|
|
1592
3431
|
return component;
|
|
1593
3432
|
}
|
|
3433
|
+
var COMPLETE_RUNTIME_FEATURES = [
|
|
3434
|
+
conditionalRuntimeFeature,
|
|
3435
|
+
hostConditionalRuntimeFeature,
|
|
3436
|
+
conditionalRangesRuntimeFeature,
|
|
3437
|
+
keyedListRuntimeFeature,
|
|
3438
|
+
keyedRowsCompleteRuntimeFeature,
|
|
3439
|
+
keyedRangesRuntimeFeature,
|
|
3440
|
+
mixedRangesRuntimeFeature,
|
|
3441
|
+
componentRuntimeFeature
|
|
3442
|
+
];
|
|
3443
|
+
function createCompiledComponent(definition) {
|
|
3444
|
+
return createCompiledComponentWithFeatures(definition, COMPLETE_RUNTIME_FEATURES);
|
|
3445
|
+
}
|
|
1594
3446
|
|
|
3447
|
+
exports.componentRuntimeFeature = componentRuntimeFeature;
|
|
3448
|
+
exports.conditionalRangesRuntimeFeature = conditionalRangesRuntimeFeature;
|
|
3449
|
+
exports.conditionalRuntimeFeature = conditionalRuntimeFeature;
|
|
1595
3450
|
exports.createCompiledComponent = createCompiledComponent;
|
|
3451
|
+
exports.createCompiledComponentWithFeatures = createCompiledComponentWithFeatures;
|
|
3452
|
+
exports.hostConditionalRuntimeFeature = hostConditionalRuntimeFeature;
|
|
3453
|
+
exports.keyedListRuntimeFeature = keyedListRuntimeFeature;
|
|
3454
|
+
exports.keyedRangesRuntimeFeature = keyedRangesRuntimeFeature;
|
|
3455
|
+
exports.keyedRowsCompleteRuntimeFeature = keyedRowsCompleteRuntimeFeature;
|
|
3456
|
+
exports.keyedRowsConditionalRuntimeFeature = keyedRowsConditionalRuntimeFeature;
|
|
3457
|
+
exports.keyedRowsHostRuntimeFeature = keyedRowsHostRuntimeFeature;
|
|
3458
|
+
exports.keyedRowsRuntimeFeature = keyedRowsRuntimeFeature;
|
|
3459
|
+
exports.mixedRangesRuntimeFeature = mixedRangesRuntimeFeature;
|
|
1596
3460
|
//# sourceMappingURL=compiler-runtime.cjs.map
|
|
1597
3461
|
//# sourceMappingURL=compiler-runtime.cjs.map
|