@farm.js/react 0.1.0-beta.20 → 0.1.0-beta.21
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
CHANGED
|
@@ -925,6 +925,12 @@ components, fragments, refs, SVG, spreads, dangerous HTML, and index keys keep t
|
|
|
925
925
|
row on React's fallback. Additional keyed levels that satisfy the same host-only contract are
|
|
926
926
|
analyzed recursively instead of using a fixed nesting limit.
|
|
927
927
|
|
|
928
|
+
When every inner key stays in the same order, the nested scope reuses its row table and skips
|
|
929
|
+
position-map construction and LIS planning. It still validates all keys and updates every child
|
|
930
|
+
scope and binding. Insertions, removals, and reorders keep the existing structural reconciliation;
|
|
931
|
+
duplicate keys or an invalid child scope keep the existing React fallback. This also applies to
|
|
932
|
+
keyed ranges next to host-only conditions inside a nested mixed range.
|
|
933
|
+
|
|
928
934
|
For example, `boards → columns → cards → tags` becomes a tree of keyed scopes. Each stable parent
|
|
929
935
|
key owns its child key table and LIS pass. Moving a board carries its column, card, and tag scopes;
|
|
930
936
|
reordering cards reconciles only the selected column. Block IDs stay globally unique while runtime
|
|
@@ -2998,6 +2998,24 @@ var CompilerNestedConditionalRanges = class {
|
|
|
2998
2998
|
this.staticValues.length = 0;
|
|
2999
2999
|
}
|
|
3000
3000
|
};
|
|
3001
|
+
function reconcileStableNestedKeyedRows(range, previous, rows) {
|
|
3002
|
+
if (rows.keys.length !== previous.size) return void 0;
|
|
3003
|
+
let index = 0;
|
|
3004
|
+
for (const key of previous.keys()) {
|
|
3005
|
+
if (rows.keys[index++] !== key) return void 0;
|
|
3006
|
+
}
|
|
3007
|
+
index = 0;
|
|
3008
|
+
for (const existing of previous.values()) {
|
|
3009
|
+
const item = rows.items[index];
|
|
3010
|
+
const descriptor = range.create(item, index);
|
|
3011
|
+
if (!existing.scope?.update(descriptor)) return false;
|
|
3012
|
+
applyKeyedRowBindings(range, existing, item, index);
|
|
3013
|
+
existing.item = item;
|
|
3014
|
+
existing.index = index;
|
|
3015
|
+
index += 1;
|
|
3016
|
+
}
|
|
3017
|
+
return true;
|
|
3018
|
+
}
|
|
3001
3019
|
var CompilerNestedKeyedRanges = class {
|
|
3002
3020
|
constructor(owner, root, host, block, onFallback) {
|
|
3003
3021
|
this.owner = owner;
|
|
@@ -3171,6 +3189,8 @@ var CompilerNestedKeyedRanges = class {
|
|
|
3171
3189
|
reconcileRange(rangeIndex, rows) {
|
|
3172
3190
|
const range = this.block.ranges[rangeIndex];
|
|
3173
3191
|
const previous = this.instances[rangeIndex];
|
|
3192
|
+
const stable = reconcileStableNestedKeyedRows(range, previous, rows);
|
|
3193
|
+
if (stable !== void 0) return stable;
|
|
3174
3194
|
const oldIndices = /* @__PURE__ */ new Map();
|
|
3175
3195
|
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
3176
3196
|
const nextKeys = new Set(rows.keys);
|
|
@@ -3529,6 +3549,8 @@ var CompilerNestedMixedRanges = class {
|
|
|
3529
3549
|
const instance = this.instances[rangeIndex];
|
|
3530
3550
|
if (instance.kind !== "keyed") return false;
|
|
3531
3551
|
const previous = instance.value;
|
|
3552
|
+
const stable = reconcileStableNestedKeyedRows(range, previous, rows);
|
|
3553
|
+
if (stable !== void 0) return stable;
|
|
3532
3554
|
const oldIndices = /* @__PURE__ */ new Map();
|
|
3533
3555
|
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
3534
3556
|
const nextKeys = new Set(rows.keys);
|
|
@@ -6009,6 +6031,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6009
6031
|
this.currentProps = this.props;
|
|
6010
6032
|
this.definitionVersion = owner.getDefinitionVersion?.();
|
|
6011
6033
|
this.instances = /* @__PURE__ */ new Map();
|
|
6034
|
+
this.reactElements = [];
|
|
6012
6035
|
this.keyedTargets = options.keyedTargets?.(this.props);
|
|
6013
6036
|
this.renderVersion = 0;
|
|
6014
6037
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -6125,7 +6148,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6125
6148
|
);
|
|
6126
6149
|
if (positionedInstances) {
|
|
6127
6150
|
if (positionedInstances !== this.instances) {
|
|
6128
|
-
this.instances =
|
|
6151
|
+
this.instances = positionedInstances;
|
|
6129
6152
|
this.rebuildElementIndex(this.instances);
|
|
6130
6153
|
this.pruneEventHandlers();
|
|
6131
6154
|
this.pruneConditionalListeners();
|
|
@@ -6167,8 +6190,10 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6167
6190
|
this.instances = rollingWindowInstances instanceof Map ? rollingWindowInstances : new Map(rollingWindowInstances);
|
|
6168
6191
|
if (delta) {
|
|
6169
6192
|
COMPILER_KEYED_ROLLING_WINDOW_DELTAS.delete(rollingWindowInstances);
|
|
6170
|
-
|
|
6171
|
-
|
|
6193
|
+
if (this.usesDelegatedEvents()) {
|
|
6194
|
+
for (const instance of delta.added) {
|
|
6195
|
+
this.instancesByElement.set(instance.element, instance);
|
|
6196
|
+
}
|
|
6172
6197
|
}
|
|
6173
6198
|
for (const key of delta.removedKeys) {
|
|
6174
6199
|
this.eventHandlers.delete(key);
|
|
@@ -6208,7 +6233,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6208
6233
|
this.hasReactOwnedRows()
|
|
6209
6234
|
);
|
|
6210
6235
|
if (prependedInstances) {
|
|
6211
|
-
this.instances =
|
|
6236
|
+
this.instances = prependedInstances;
|
|
6212
6237
|
this.rebuildElementIndex(this.instances);
|
|
6213
6238
|
this.commitCurrentCollection(dirtyState);
|
|
6214
6239
|
afterCommit?.();
|
|
@@ -6232,6 +6257,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6232
6257
|
}
|
|
6233
6258
|
rebuildElementIndex(instances) {
|
|
6234
6259
|
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
6260
|
+
if (!this.usesDelegatedEvents()) return;
|
|
6235
6261
|
for (const instance of instances.values()) {
|
|
6236
6262
|
this.instancesByElement.set(instance.element, instance);
|
|
6237
6263
|
}
|
|
@@ -6366,6 +6392,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6366
6392
|
}
|
|
6367
6393
|
this.cleanupHostScopes();
|
|
6368
6394
|
this.instances = instances;
|
|
6395
|
+
this.reactElements = elements;
|
|
6369
6396
|
this.rebuildElementIndex(instances);
|
|
6370
6397
|
this.pruneEventHandlers();
|
|
6371
6398
|
this.pruneConditionalListeners();
|
|
@@ -6787,6 +6814,10 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6787
6814
|
}
|
|
6788
6815
|
if (nextState.fallback || this.state.fallback) return true;
|
|
6789
6816
|
if (definitionChanged || wasReactOwned || willBeReactOwned) {
|
|
6817
|
+
const elements = this.root?.children;
|
|
6818
|
+
if (elements && (elements.length !== this.reactElements.length || this.reactElements.some((element, index) => element !== elements[index]))) {
|
|
6819
|
+
this.fallbackVersion += 1;
|
|
6820
|
+
}
|
|
6790
6821
|
this.eventHandlers.clear();
|
|
6791
6822
|
return true;
|
|
6792
6823
|
}
|
|
@@ -6815,6 +6846,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6815
6846
|
this.id = void 0;
|
|
6816
6847
|
this.cleanupHostScopes();
|
|
6817
6848
|
this.instances.clear();
|
|
6849
|
+
this.reactElements = [];
|
|
6818
6850
|
this.keyedTargets?.clear();
|
|
6819
6851
|
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
6820
6852
|
this.eventHandlers.clear();
|
|
@@ -6830,7 +6862,7 @@ function createKeyedRowsBlockComponentCore(owner, options = {}) {
|
|
|
6830
6862
|
}
|
|
6831
6863
|
return React__default.default.cloneElement(container, {
|
|
6832
6864
|
...this.delegatedContainerProps(container),
|
|
6833
|
-
key: this.state.fallback ?
|
|
6865
|
+
key: `${this.state.fallback ? "react" : "compiled"}-${this.fallbackVersion}`,
|
|
6834
6866
|
ref: this.captureRoot
|
|
6835
6867
|
});
|
|
6836
6868
|
}
|