@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 = new Map(positionedInstances);
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
- for (const instance of delta.added) {
6171
- this.instancesByElement.set(instance.element, instance);
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 = new Map(prependedInstances);
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 ? `react-${this.fallbackVersion}` : "compiled",
6865
+ key: `${this.state.fallback ? "react" : "compiled"}-${this.fallbackVersion}`,
6834
6866
  ref: this.captureRoot
6835
6867
  });
6836
6868
  }