@farm.js/react 0.1.0-beta.13 → 0.1.0-beta.14

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.
@@ -1975,10 +1975,7 @@ function normalizedStaticRangeBindingValue(binding, value) {
1975
1975
  }
1976
1976
  function applyStaticRangeBindings(bindings, segments, values) {
1977
1977
  const activeBindings = bindings || [];
1978
- if (values.length === 0 && activeBindings.length > 0) {
1979
- values.push(...activeBindings.map(() => UNSET_STATIC_RANGE_BINDING));
1980
- }
1981
- if (values.length !== activeBindings.length) return false;
1978
+ const targets = [];
1982
1979
  for (let index = 0; index < activeBindings.length; index += 1) {
1983
1980
  const binding = activeBindings[index];
1984
1981
  if (!Number.isSafeInteger(binding.segment) || binding.segment < 0 || !Number.isSafeInteger(binding.sibling) || binding.sibling < 0) {
@@ -1986,19 +1983,31 @@ function applyStaticRangeBindings(bindings, segments, values) {
1986
1983
  }
1987
1984
  const sibling = segments[binding.segment]?.[binding.sibling];
1988
1985
  const target = sibling && findCompilerHostTarget(sibling, binding.path);
1989
- if (!target) return false;
1990
- const rawValue = binding.read();
1991
- const value = normalizedStaticRangeBindingValue(binding, rawValue);
1992
- if (Object.is(values[index], value)) continue;
1986
+ if (!target || binding.kind !== "text" && (binding.kind !== "style" && binding.kind !== "attribute" || !binding.name)) {
1987
+ return false;
1988
+ }
1989
+ targets[index] = target;
1990
+ }
1991
+ const initializesValues = values.length === 0 && activeBindings.length > 0;
1992
+ if (!initializesValues && values.length !== activeBindings.length) return false;
1993
+ const nextValues = [];
1994
+ for (let index = 0; index < activeBindings.length; index += 1) {
1995
+ const binding = activeBindings[index];
1996
+ nextValues[index] = normalizedStaticRangeBindingValue(binding, binding.read());
1997
+ }
1998
+ for (let index = 0; index < activeBindings.length; index += 1) {
1999
+ const binding = activeBindings[index];
2000
+ const value = nextValues[index];
2001
+ const previous = initializesValues ? UNSET_STATIC_RANGE_BINDING : values[index];
2002
+ if (Object.is(previous, value)) continue;
1993
2003
  values[index] = value;
2004
+ const target = targets[index];
1994
2005
  if (binding.kind === "text") {
1995
2006
  target.textContent = value;
1996
- } else if (binding.kind === "style" && binding.name) {
1997
- updateStyle(target, binding.name, rawValue);
1998
- } else if (binding.kind === "attribute" && binding.name) {
1999
- updateAttribute(target, binding.name, rawValue);
2007
+ } else if (binding.kind === "style") {
2008
+ updateStyle(target, binding.name, value);
2000
2009
  } else {
2001
- return false;
2010
+ updateAttribute(target, binding.name, value);
2002
2011
  }
2003
2012
  }
2004
2013
  return true;
@@ -2254,24 +2263,49 @@ function readKeyedRowBindingValues(props, item, index) {
2254
2263
  );
2255
2264
  }
2256
2265
  function applyKeyedRowBindings(props, instance, item, index) {
2266
+ if (props.bindings.length < 2) {
2267
+ if (props.bindings.length === 1) applyKeyedRowBinding(props, instance, item, index, 0);
2268
+ return;
2269
+ }
2270
+ const nextValues = readKeyedRowBindingValues(props, item, index);
2271
+ let targets;
2257
2272
  for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
2258
- applyKeyedRowBinding(props, instance, item, index, bindingIndex);
2273
+ if (Object.is(instance.values[bindingIndex], nextValues[bindingIndex])) continue;
2274
+ targets || (targets = []);
2275
+ targets[bindingIndex] = findCompilerHostTarget(
2276
+ instance.element,
2277
+ props.bindings[bindingIndex].path
2278
+ );
2279
+ }
2280
+ if (!targets) return;
2281
+ for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
2282
+ const value = nextValues[bindingIndex];
2283
+ if (Object.is(instance.values[bindingIndex], value)) continue;
2284
+ commitKeyedRowBinding(
2285
+ props.bindings[bindingIndex],
2286
+ instance,
2287
+ bindingIndex,
2288
+ value,
2289
+ targets[bindingIndex]
2290
+ );
2259
2291
  }
2260
2292
  }
2261
2293
  function applyKeyedRowBinding(props, instance, item, index, bindingIndex) {
2262
2294
  const binding = props.bindings[bindingIndex];
2263
- const rawValue = binding.read(item, index);
2264
- const value = normalizedKeyedRowBindingValue(binding, rawValue);
2295
+ const value = normalizedKeyedRowBindingValue(binding, binding.read(item, index));
2265
2296
  if (Object.is(instance.values[bindingIndex], value)) return;
2266
- instance.values[bindingIndex] = value;
2267
2297
  const target = findCompilerHostTarget(instance.element, binding.path);
2298
+ commitKeyedRowBinding(binding, instance, bindingIndex, value, target);
2299
+ }
2300
+ function commitKeyedRowBinding(binding, instance, bindingIndex, value, target) {
2301
+ instance.values[bindingIndex] = value;
2268
2302
  if (!target) return;
2269
2303
  if (binding.kind === "text") {
2270
2304
  target.textContent = value;
2271
2305
  } else if (binding.kind === "style" && binding.name) {
2272
- updateStyle(target, binding.name, rawValue);
2306
+ updateStyle(target, binding.name, value);
2273
2307
  } else if (binding.kind === "attribute" && binding.name) {
2274
- updateAttribute(target, binding.name, rawValue);
2308
+ updateAttribute(target, binding.name, value);
2275
2309
  }
2276
2310
  }
2277
2311
  function prepareKeyedRowBindingUpdates(props, instance, item, index) {
@@ -2283,21 +2317,13 @@ function prepareKeyedRowBindingUpdates(props, instance, item, index) {
2283
2317
  if (Object.is(instance.values[bindingIndex], value)) continue;
2284
2318
  const target = findCompilerHostTarget(instance.element, binding.path);
2285
2319
  if (!target || binding.kind !== "text" && !binding.name) return void 0;
2286
- updates.push([bindingIndex, rawValue, target, value]);
2320
+ updates.push([bindingIndex, target, value]);
2287
2321
  }
2288
2322
  return updates;
2289
2323
  }
2290
2324
  function applyPreparedKeyedRowBindingUpdates(props, instance, updates) {
2291
- for (const [bindingIndex, rawValue, target, value] of updates) {
2292
- const binding = props.bindings[bindingIndex];
2293
- instance.values[bindingIndex] = value;
2294
- if (binding.kind === "text") {
2295
- target.textContent = value;
2296
- } else if (binding.kind === "style") {
2297
- updateStyle(target, binding.name, rawValue);
2298
- } else {
2299
- updateAttribute(target, binding.name, rawValue);
2300
- }
2325
+ for (const [bindingIndex, target, value] of updates) {
2326
+ commitKeyedRowBinding(props.bindings[bindingIndex], instance, bindingIndex, value, target);
2301
2327
  }
2302
2328
  }
2303
2329
  function keyedRowConditionalSnapshot(conditional, item, index) {
@@ -2359,6 +2385,35 @@ function applyHostConditionalBindings(branch, instance) {
2359
2385
  }
2360
2386
  }
2361
2387
  }
2388
+ function prepareHostConditionalBindings(branch, instance) {
2389
+ for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
2390
+ const binding = branch.bindings[bindingIndex];
2391
+ const rawValue = binding.read();
2392
+ const target = findCompilerHostTarget(instance.element, binding.path);
2393
+ if (!target || binding.kind !== "text" && (binding.kind !== "style" && binding.kind !== "attribute" || !binding.name)) {
2394
+ return false;
2395
+ }
2396
+ instance.values[bindingIndex] = [
2397
+ target,
2398
+ normalizedHostConditionalBindingValue(binding, rawValue)
2399
+ ];
2400
+ }
2401
+ return true;
2402
+ }
2403
+ function applyPreparedHostConditionalBindings(branch, instance) {
2404
+ for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
2405
+ const binding = branch.bindings[bindingIndex];
2406
+ const [target, value] = instance.values[bindingIndex];
2407
+ instance.values[bindingIndex] = value;
2408
+ if (binding.kind === "text") {
2409
+ target.textContent = value;
2410
+ } else if (binding.kind === "style") {
2411
+ updateStyle(target, binding.name, value);
2412
+ } else {
2413
+ updateAttribute(target, binding.name, value);
2414
+ }
2415
+ }
2416
+ }
2362
2417
  var UNSET_HOST_CONDITIONAL_BINDING = /* @__PURE__ */ Symbol("unset host conditional binding");
2363
2418
  function mountCompilerHostTree(owner, element, descriptor, onFallback) {
2364
2419
  if (!matchesCompilerHostElement(element, descriptor)) return null;
@@ -2446,7 +2501,7 @@ function mountCompilerHostTree(owner, element, descriptor, onFallback) {
2446
2501
  }
2447
2502
  };
2448
2503
  }
2449
- function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback) {
2504
+ function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback, applyBindingsImmediately = true) {
2450
2505
  const scope = mountCompilerHostTree(owner, element, descriptor, onFallback);
2451
2506
  if (!scope) return null;
2452
2507
  const instance = {
@@ -2454,6 +2509,7 @@ function mountCompilerHostInstance(owner, element, descriptor, branch, onFallbac
2454
2509
  scope,
2455
2510
  values: branch.bindings.map(() => UNSET_HOST_CONDITIONAL_BINDING)
2456
2511
  };
2512
+ if (!applyBindingsImmediately) return instance;
2457
2513
  try {
2458
2514
  applyHostConditionalBindings(branch, instance);
2459
2515
  } catch (error) {
@@ -2560,13 +2616,19 @@ var CompilerNestedConditionalRanges = class {
2560
2616
  element,
2561
2617
  descriptor,
2562
2618
  selection.branch,
2563
- this.onFallback
2619
+ this.onFallback,
2620
+ false
2621
+ // Commit only after every sibling range validates.
2564
2622
  );
2565
2623
  if (!host) {
2566
2624
  this.cleanup();
2567
2625
  return false;
2568
2626
  }
2569
2627
  this.instances.push({ key: selection.key, host });
2628
+ if (!prepareHostConditionalBindings(selection.branch, host)) {
2629
+ this.cleanup();
2630
+ return false;
2631
+ }
2570
2632
  cursor += 1;
2571
2633
  }
2572
2634
  const trailingEnd = cursor + this.block.trailing;
@@ -2579,6 +2641,13 @@ var CompilerNestedConditionalRanges = class {
2579
2641
  this.cleanup();
2580
2642
  return false;
2581
2643
  }
2644
+ for (let index = 0; index < selections.length; index += 1) {
2645
+ const selection = selections[index];
2646
+ const instance = this.instances[index];
2647
+ if (selection.kind === "branch" && instance) {
2648
+ applyPreparedHostConditionalBindings(selection.branch, instance.host);
2649
+ }
2650
+ }
2582
2651
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
2583
2652
  return true;
2584
2653
  }
@@ -2747,6 +2816,7 @@ var CompilerNestedKeyedRanges = class {
2747
2816
  const elements = [...this.root.children];
2748
2817
  const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(this.host));
2749
2818
  if (elements.length !== descriptors.length) return false;
2819
+ const preparedBindings = [];
2750
2820
  let cursor = 0;
2751
2821
  for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2752
2822
  const range = this.block.ranges[rangeIndex];
@@ -2763,6 +2833,8 @@ var CompilerNestedKeyedRanges = class {
2763
2833
  this.staticSegments.push(elements.slice(cursor, staticEnd));
2764
2834
  cursor = staticEnd;
2765
2835
  const instances = /* @__PURE__ */ new Map();
2836
+ this.instances.push(instances);
2837
+ const rangeBindingUpdates = [];
2766
2838
  for (let index = 0; index < rows.items.length; index += 1) {
2767
2839
  const element = elements[cursor + index];
2768
2840
  if (!element) {
@@ -2775,7 +2847,7 @@ var CompilerNestedKeyedRanges = class {
2775
2847
  this.cleanup();
2776
2848
  return false;
2777
2849
  }
2778
- instances.set(rows.keys[index], {
2850
+ const instance = {
2779
2851
  key: rows.keys[index],
2780
2852
  element,
2781
2853
  scope,
@@ -2783,10 +2855,23 @@ var CompilerNestedKeyedRanges = class {
2783
2855
  item: rows.items[index],
2784
2856
  index,
2785
2857
  conditionalValues: /* @__PURE__ */ new Map()
2786
- });
2787
- applyKeyedRowBindings(range, instances.get(rows.keys[index]), rows.items[index], index);
2858
+ };
2859
+ let bindingUpdates;
2860
+ try {
2861
+ bindingUpdates = prepareKeyedRowBindingUpdates(range, instance, rows.items[index], index);
2862
+ } catch (error) {
2863
+ scope.cleanup();
2864
+ throw error;
2865
+ }
2866
+ if (!bindingUpdates) {
2867
+ scope.cleanup();
2868
+ this.cleanup();
2869
+ return false;
2870
+ }
2871
+ instances.set(rows.keys[index], instance);
2872
+ rangeBindingUpdates.push(bindingUpdates);
2788
2873
  }
2789
- this.instances.push(instances);
2874
+ preparedBindings.push(rangeBindingUpdates);
2790
2875
  cursor += rows.items.length;
2791
2876
  }
2792
2877
  const trailingEnd = cursor + this.block.trailing;
@@ -2799,6 +2884,18 @@ var CompilerNestedKeyedRanges = class {
2799
2884
  this.cleanup();
2800
2885
  return false;
2801
2886
  }
2887
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2888
+ const range = this.block.ranges[rangeIndex];
2889
+ let rowIndex = 0;
2890
+ for (const instance of this.instances[rangeIndex].values()) {
2891
+ applyPreparedKeyedRowBindingUpdates(
2892
+ range,
2893
+ instance,
2894
+ preparedBindings[rangeIndex][rowIndex]
2895
+ );
2896
+ rowIndex += 1;
2897
+ }
2898
+ }
2802
2899
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
2803
2900
  return true;
2804
2901
  }
@@ -2992,6 +3089,7 @@ var CompilerNestedMixedRanges = class {
2992
3089
  const elements = [...this.root.children];
2993
3090
  const descriptors = flattenCompilerHostElements(this.host.children);
2994
3091
  if (elements.length !== descriptors.length) return false;
3092
+ const preparedKeyedBindings = [];
2995
3093
  let cursor = 0;
2996
3094
  for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2997
3095
  const range = this.block.ranges[rangeIndex];
@@ -3023,7 +3121,9 @@ var CompilerNestedMixedRanges = class {
3023
3121
  element,
3024
3122
  descriptor,
3025
3123
  snapshot.selection.branch,
3026
- this.onFallback
3124
+ this.onFallback,
3125
+ false
3126
+ // Commit only after every sibling range validates.
3027
3127
  );
3028
3128
  if (!host) {
3029
3129
  this.cleanup();
@@ -3033,6 +3133,10 @@ var CompilerNestedMixedRanges = class {
3033
3133
  kind: "conditional",
3034
3134
  value: { key: snapshot.selection.key, host }
3035
3135
  });
3136
+ if (!prepareHostConditionalBindings(snapshot.selection.branch, host)) {
3137
+ this.cleanup();
3138
+ return false;
3139
+ }
3036
3140
  cursor += 1;
3037
3141
  continue;
3038
3142
  }
@@ -3041,6 +3145,8 @@ var CompilerNestedMixedRanges = class {
3041
3145
  return false;
3042
3146
  }
3043
3147
  const keyedInstances = /* @__PURE__ */ new Map();
3148
+ this.instances.push({ kind: "keyed", value: keyedInstances });
3149
+ const keyedBindingUpdates = [];
3044
3150
  for (let index = 0; index < snapshot.rows.items.length; index += 1) {
3045
3151
  const element = elements[cursor + index];
3046
3152
  if (!element) {
@@ -3062,15 +3168,27 @@ var CompilerNestedMixedRanges = class {
3062
3168
  index,
3063
3169
  conditionalValues: /* @__PURE__ */ new Map()
3064
3170
  };
3171
+ let bindingUpdates;
3065
3172
  try {
3066
- applyKeyedRowBindings(range, instance, snapshot.rows.items[index], index);
3173
+ bindingUpdates = prepareKeyedRowBindingUpdates(
3174
+ range,
3175
+ instance,
3176
+ snapshot.rows.items[index],
3177
+ index
3178
+ );
3067
3179
  } catch (error) {
3068
3180
  scope.cleanup();
3069
3181
  throw error;
3070
3182
  }
3183
+ if (!bindingUpdates) {
3184
+ scope.cleanup();
3185
+ this.cleanup();
3186
+ return false;
3187
+ }
3071
3188
  keyedInstances.set(snapshot.rows.keys[index], instance);
3189
+ keyedBindingUpdates.push(bindingUpdates);
3072
3190
  }
3073
- this.instances.push({ kind: "keyed", value: keyedInstances });
3191
+ preparedKeyedBindings[rangeIndex] = keyedBindingUpdates;
3074
3192
  cursor += snapshot.rows.items.length;
3075
3193
  }
3076
3194
  const trailingEnd = cursor + this.block.trailing;
@@ -3083,6 +3201,22 @@ var CompilerNestedMixedRanges = class {
3083
3201
  this.cleanup();
3084
3202
  return false;
3085
3203
  }
3204
+ for (let index = 0; index < snapshots.length; index += 1) {
3205
+ const snapshot = snapshots[index];
3206
+ const instance = this.instances[index];
3207
+ if (snapshot.kind === "conditional" && snapshot.selection.kind === "branch" && instance?.kind === "conditional" && instance.value) {
3208
+ applyPreparedHostConditionalBindings(snapshot.selection.branch, instance.value.host);
3209
+ } else if (snapshot.kind === "keyed" && instance?.kind === "keyed") {
3210
+ const range = this.block.ranges[index];
3211
+ const bindingUpdates = preparedKeyedBindings[index];
3212
+ if (range.kind !== "keyed") continue;
3213
+ let rowIndex = 0;
3214
+ for (const row of instance.value.values()) {
3215
+ applyPreparedKeyedRowBindingUpdates(range, row, bindingUpdates[rowIndex]);
3216
+ rowIndex += 1;
3217
+ }
3218
+ }
3219
+ }
3086
3220
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
3087
3221
  return true;
3088
3222
  }
@@ -3613,7 +3747,9 @@ function createConditionalRangesBlockComponent(owner) {
3613
3747
  element,
3614
3748
  descriptor,
3615
3749
  selection.branch,
3616
- this.requestNestedFallback
3750
+ this.requestNestedFallback,
3751
+ false
3752
+ // Commit only after every sibling range validates.
3617
3753
  );
3618
3754
  if (!host) {
3619
3755
  cleanupInstances();
@@ -3623,6 +3759,15 @@ function createConditionalRangesBlockComponent(owner) {
3623
3759
  key: selection.key,
3624
3760
  host
3625
3761
  });
3762
+ try {
3763
+ if (!prepareHostConditionalBindings(selection.branch, host)) {
3764
+ cleanupInstances();
3765
+ return false;
3766
+ }
3767
+ } catch (error) {
3768
+ cleanupInstances();
3769
+ throw error;
3770
+ }
3626
3771
  cursor += 1;
3627
3772
  }
3628
3773
  if (cursor + props.trailing !== elements.length) {
@@ -3630,9 +3775,21 @@ function createConditionalRangesBlockComponent(owner) {
3630
3775
  return false;
3631
3776
  }
3632
3777
  staticSegments.push(elements.slice(cursor));
3633
- if (!applyStaticRangeBindings(props.bindings, staticSegments, staticValues)) {
3778
+ try {
3779
+ if (!applyStaticRangeBindings(props.bindings, staticSegments, staticValues)) {
3780
+ cleanupInstances();
3781
+ return false;
3782
+ }
3783
+ for (let index = 0; index < selections.length; index += 1) {
3784
+ const selection = selections[index];
3785
+ const instance = instances[index];
3786
+ if (selection.kind === "branch" && instance) {
3787
+ applyPreparedHostConditionalBindings(selection.branch, instance.host);
3788
+ }
3789
+ }
3790
+ } catch (error) {
3634
3791
  cleanupInstances();
3635
- return false;
3792
+ throw error;
3636
3793
  }
3637
3794
  for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
3638
3795
  this.staticSegments = staticSegments;