@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.
@@ -1969,10 +1969,7 @@ function normalizedStaticRangeBindingValue(binding, value) {
1969
1969
  }
1970
1970
  function applyStaticRangeBindings(bindings, segments, values) {
1971
1971
  const activeBindings = bindings || [];
1972
- if (values.length === 0 && activeBindings.length > 0) {
1973
- values.push(...activeBindings.map(() => UNSET_STATIC_RANGE_BINDING));
1974
- }
1975
- if (values.length !== activeBindings.length) return false;
1972
+ const targets = [];
1976
1973
  for (let index = 0; index < activeBindings.length; index += 1) {
1977
1974
  const binding = activeBindings[index];
1978
1975
  if (!Number.isSafeInteger(binding.segment) || binding.segment < 0 || !Number.isSafeInteger(binding.sibling) || binding.sibling < 0) {
@@ -1980,19 +1977,31 @@ function applyStaticRangeBindings(bindings, segments, values) {
1980
1977
  }
1981
1978
  const sibling = segments[binding.segment]?.[binding.sibling];
1982
1979
  const target = sibling && findCompilerHostTarget(sibling, binding.path);
1983
- if (!target) return false;
1984
- const rawValue = binding.read();
1985
- const value = normalizedStaticRangeBindingValue(binding, rawValue);
1986
- if (Object.is(values[index], value)) continue;
1980
+ if (!target || binding.kind !== "text" && (binding.kind !== "style" && binding.kind !== "attribute" || !binding.name)) {
1981
+ return false;
1982
+ }
1983
+ targets[index] = target;
1984
+ }
1985
+ const initializesValues = values.length === 0 && activeBindings.length > 0;
1986
+ if (!initializesValues && values.length !== activeBindings.length) return false;
1987
+ const nextValues = [];
1988
+ for (let index = 0; index < activeBindings.length; index += 1) {
1989
+ const binding = activeBindings[index];
1990
+ nextValues[index] = normalizedStaticRangeBindingValue(binding, binding.read());
1991
+ }
1992
+ for (let index = 0; index < activeBindings.length; index += 1) {
1993
+ const binding = activeBindings[index];
1994
+ const value = nextValues[index];
1995
+ const previous = initializesValues ? UNSET_STATIC_RANGE_BINDING : values[index];
1996
+ if (Object.is(previous, value)) continue;
1987
1997
  values[index] = value;
1998
+ const target = targets[index];
1988
1999
  if (binding.kind === "text") {
1989
2000
  target.textContent = value;
1990
- } else if (binding.kind === "style" && binding.name) {
1991
- updateStyle(target, binding.name, rawValue);
1992
- } else if (binding.kind === "attribute" && binding.name) {
1993
- updateAttribute(target, binding.name, rawValue);
2001
+ } else if (binding.kind === "style") {
2002
+ updateStyle(target, binding.name, value);
1994
2003
  } else {
1995
- return false;
2004
+ updateAttribute(target, binding.name, value);
1996
2005
  }
1997
2006
  }
1998
2007
  return true;
@@ -2248,24 +2257,49 @@ function readKeyedRowBindingValues(props, item, index) {
2248
2257
  );
2249
2258
  }
2250
2259
  function applyKeyedRowBindings(props, instance, item, index) {
2260
+ if (props.bindings.length < 2) {
2261
+ if (props.bindings.length === 1) applyKeyedRowBinding(props, instance, item, index, 0);
2262
+ return;
2263
+ }
2264
+ const nextValues = readKeyedRowBindingValues(props, item, index);
2265
+ let targets;
2251
2266
  for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
2252
- applyKeyedRowBinding(props, instance, item, index, bindingIndex);
2267
+ if (Object.is(instance.values[bindingIndex], nextValues[bindingIndex])) continue;
2268
+ targets || (targets = []);
2269
+ targets[bindingIndex] = findCompilerHostTarget(
2270
+ instance.element,
2271
+ props.bindings[bindingIndex].path
2272
+ );
2273
+ }
2274
+ if (!targets) return;
2275
+ for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
2276
+ const value = nextValues[bindingIndex];
2277
+ if (Object.is(instance.values[bindingIndex], value)) continue;
2278
+ commitKeyedRowBinding(
2279
+ props.bindings[bindingIndex],
2280
+ instance,
2281
+ bindingIndex,
2282
+ value,
2283
+ targets[bindingIndex]
2284
+ );
2253
2285
  }
2254
2286
  }
2255
2287
  function applyKeyedRowBinding(props, instance, item, index, bindingIndex) {
2256
2288
  const binding = props.bindings[bindingIndex];
2257
- const rawValue = binding.read(item, index);
2258
- const value = normalizedKeyedRowBindingValue(binding, rawValue);
2289
+ const value = normalizedKeyedRowBindingValue(binding, binding.read(item, index));
2259
2290
  if (Object.is(instance.values[bindingIndex], value)) return;
2260
- instance.values[bindingIndex] = value;
2261
2291
  const target = findCompilerHostTarget(instance.element, binding.path);
2292
+ commitKeyedRowBinding(binding, instance, bindingIndex, value, target);
2293
+ }
2294
+ function commitKeyedRowBinding(binding, instance, bindingIndex, value, target) {
2295
+ instance.values[bindingIndex] = value;
2262
2296
  if (!target) return;
2263
2297
  if (binding.kind === "text") {
2264
2298
  target.textContent = value;
2265
2299
  } else if (binding.kind === "style" && binding.name) {
2266
- updateStyle(target, binding.name, rawValue);
2300
+ updateStyle(target, binding.name, value);
2267
2301
  } else if (binding.kind === "attribute" && binding.name) {
2268
- updateAttribute(target, binding.name, rawValue);
2302
+ updateAttribute(target, binding.name, value);
2269
2303
  }
2270
2304
  }
2271
2305
  function prepareKeyedRowBindingUpdates(props, instance, item, index) {
@@ -2277,21 +2311,13 @@ function prepareKeyedRowBindingUpdates(props, instance, item, index) {
2277
2311
  if (Object.is(instance.values[bindingIndex], value)) continue;
2278
2312
  const target = findCompilerHostTarget(instance.element, binding.path);
2279
2313
  if (!target || binding.kind !== "text" && !binding.name) return void 0;
2280
- updates.push([bindingIndex, rawValue, target, value]);
2314
+ updates.push([bindingIndex, target, value]);
2281
2315
  }
2282
2316
  return updates;
2283
2317
  }
2284
2318
  function applyPreparedKeyedRowBindingUpdates(props, instance, updates) {
2285
- for (const [bindingIndex, rawValue, target, value] of updates) {
2286
- const binding = props.bindings[bindingIndex];
2287
- instance.values[bindingIndex] = value;
2288
- if (binding.kind === "text") {
2289
- target.textContent = value;
2290
- } else if (binding.kind === "style") {
2291
- updateStyle(target, binding.name, rawValue);
2292
- } else {
2293
- updateAttribute(target, binding.name, rawValue);
2294
- }
2319
+ for (const [bindingIndex, target, value] of updates) {
2320
+ commitKeyedRowBinding(props.bindings[bindingIndex], instance, bindingIndex, value, target);
2295
2321
  }
2296
2322
  }
2297
2323
  function keyedRowConditionalSnapshot(conditional, item, index) {
@@ -2353,6 +2379,35 @@ function applyHostConditionalBindings(branch, instance) {
2353
2379
  }
2354
2380
  }
2355
2381
  }
2382
+ function prepareHostConditionalBindings(branch, instance) {
2383
+ for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
2384
+ const binding = branch.bindings[bindingIndex];
2385
+ const rawValue = binding.read();
2386
+ const target = findCompilerHostTarget(instance.element, binding.path);
2387
+ if (!target || binding.kind !== "text" && (binding.kind !== "style" && binding.kind !== "attribute" || !binding.name)) {
2388
+ return false;
2389
+ }
2390
+ instance.values[bindingIndex] = [
2391
+ target,
2392
+ normalizedHostConditionalBindingValue(binding, rawValue)
2393
+ ];
2394
+ }
2395
+ return true;
2396
+ }
2397
+ function applyPreparedHostConditionalBindings(branch, instance) {
2398
+ for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
2399
+ const binding = branch.bindings[bindingIndex];
2400
+ const [target, value] = instance.values[bindingIndex];
2401
+ instance.values[bindingIndex] = value;
2402
+ if (binding.kind === "text") {
2403
+ target.textContent = value;
2404
+ } else if (binding.kind === "style") {
2405
+ updateStyle(target, binding.name, value);
2406
+ } else {
2407
+ updateAttribute(target, binding.name, value);
2408
+ }
2409
+ }
2410
+ }
2356
2411
  var UNSET_HOST_CONDITIONAL_BINDING = /* @__PURE__ */ Symbol("unset host conditional binding");
2357
2412
  function mountCompilerHostTree(owner, element, descriptor, onFallback) {
2358
2413
  if (!matchesCompilerHostElement(element, descriptor)) return null;
@@ -2440,7 +2495,7 @@ function mountCompilerHostTree(owner, element, descriptor, onFallback) {
2440
2495
  }
2441
2496
  };
2442
2497
  }
2443
- function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback) {
2498
+ function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback, applyBindingsImmediately = true) {
2444
2499
  const scope = mountCompilerHostTree(owner, element, descriptor, onFallback);
2445
2500
  if (!scope) return null;
2446
2501
  const instance = {
@@ -2448,6 +2503,7 @@ function mountCompilerHostInstance(owner, element, descriptor, branch, onFallbac
2448
2503
  scope,
2449
2504
  values: branch.bindings.map(() => UNSET_HOST_CONDITIONAL_BINDING)
2450
2505
  };
2506
+ if (!applyBindingsImmediately) return instance;
2451
2507
  try {
2452
2508
  applyHostConditionalBindings(branch, instance);
2453
2509
  } catch (error) {
@@ -2554,13 +2610,19 @@ var CompilerNestedConditionalRanges = class {
2554
2610
  element,
2555
2611
  descriptor,
2556
2612
  selection.branch,
2557
- this.onFallback
2613
+ this.onFallback,
2614
+ false
2615
+ // Commit only after every sibling range validates.
2558
2616
  );
2559
2617
  if (!host) {
2560
2618
  this.cleanup();
2561
2619
  return false;
2562
2620
  }
2563
2621
  this.instances.push({ key: selection.key, host });
2622
+ if (!prepareHostConditionalBindings(selection.branch, host)) {
2623
+ this.cleanup();
2624
+ return false;
2625
+ }
2564
2626
  cursor += 1;
2565
2627
  }
2566
2628
  const trailingEnd = cursor + this.block.trailing;
@@ -2573,6 +2635,13 @@ var CompilerNestedConditionalRanges = class {
2573
2635
  this.cleanup();
2574
2636
  return false;
2575
2637
  }
2638
+ for (let index = 0; index < selections.length; index += 1) {
2639
+ const selection = selections[index];
2640
+ const instance = this.instances[index];
2641
+ if (selection.kind === "branch" && instance) {
2642
+ applyPreparedHostConditionalBindings(selection.branch, instance.host);
2643
+ }
2644
+ }
2576
2645
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
2577
2646
  return true;
2578
2647
  }
@@ -2741,6 +2810,7 @@ var CompilerNestedKeyedRanges = class {
2741
2810
  const elements = [...this.root.children];
2742
2811
  const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(this.host));
2743
2812
  if (elements.length !== descriptors.length) return false;
2813
+ const preparedBindings = [];
2744
2814
  let cursor = 0;
2745
2815
  for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2746
2816
  const range = this.block.ranges[rangeIndex];
@@ -2757,6 +2827,8 @@ var CompilerNestedKeyedRanges = class {
2757
2827
  this.staticSegments.push(elements.slice(cursor, staticEnd));
2758
2828
  cursor = staticEnd;
2759
2829
  const instances = /* @__PURE__ */ new Map();
2830
+ this.instances.push(instances);
2831
+ const rangeBindingUpdates = [];
2760
2832
  for (let index = 0; index < rows.items.length; index += 1) {
2761
2833
  const element = elements[cursor + index];
2762
2834
  if (!element) {
@@ -2769,7 +2841,7 @@ var CompilerNestedKeyedRanges = class {
2769
2841
  this.cleanup();
2770
2842
  return false;
2771
2843
  }
2772
- instances.set(rows.keys[index], {
2844
+ const instance = {
2773
2845
  key: rows.keys[index],
2774
2846
  element,
2775
2847
  scope,
@@ -2777,10 +2849,23 @@ var CompilerNestedKeyedRanges = class {
2777
2849
  item: rows.items[index],
2778
2850
  index,
2779
2851
  conditionalValues: /* @__PURE__ */ new Map()
2780
- });
2781
- applyKeyedRowBindings(range, instances.get(rows.keys[index]), rows.items[index], index);
2852
+ };
2853
+ let bindingUpdates;
2854
+ try {
2855
+ bindingUpdates = prepareKeyedRowBindingUpdates(range, instance, rows.items[index], index);
2856
+ } catch (error) {
2857
+ scope.cleanup();
2858
+ throw error;
2859
+ }
2860
+ if (!bindingUpdates) {
2861
+ scope.cleanup();
2862
+ this.cleanup();
2863
+ return false;
2864
+ }
2865
+ instances.set(rows.keys[index], instance);
2866
+ rangeBindingUpdates.push(bindingUpdates);
2782
2867
  }
2783
- this.instances.push(instances);
2868
+ preparedBindings.push(rangeBindingUpdates);
2784
2869
  cursor += rows.items.length;
2785
2870
  }
2786
2871
  const trailingEnd = cursor + this.block.trailing;
@@ -2793,6 +2878,18 @@ var CompilerNestedKeyedRanges = class {
2793
2878
  this.cleanup();
2794
2879
  return false;
2795
2880
  }
2881
+ for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2882
+ const range = this.block.ranges[rangeIndex];
2883
+ let rowIndex = 0;
2884
+ for (const instance of this.instances[rangeIndex].values()) {
2885
+ applyPreparedKeyedRowBindingUpdates(
2886
+ range,
2887
+ instance,
2888
+ preparedBindings[rangeIndex][rowIndex]
2889
+ );
2890
+ rowIndex += 1;
2891
+ }
2892
+ }
2796
2893
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
2797
2894
  return true;
2798
2895
  }
@@ -2986,6 +3083,7 @@ var CompilerNestedMixedRanges = class {
2986
3083
  const elements = [...this.root.children];
2987
3084
  const descriptors = flattenCompilerHostElements(this.host.children);
2988
3085
  if (elements.length !== descriptors.length) return false;
3086
+ const preparedKeyedBindings = [];
2989
3087
  let cursor = 0;
2990
3088
  for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
2991
3089
  const range = this.block.ranges[rangeIndex];
@@ -3017,7 +3115,9 @@ var CompilerNestedMixedRanges = class {
3017
3115
  element,
3018
3116
  descriptor,
3019
3117
  snapshot.selection.branch,
3020
- this.onFallback
3118
+ this.onFallback,
3119
+ false
3120
+ // Commit only after every sibling range validates.
3021
3121
  );
3022
3122
  if (!host) {
3023
3123
  this.cleanup();
@@ -3027,6 +3127,10 @@ var CompilerNestedMixedRanges = class {
3027
3127
  kind: "conditional",
3028
3128
  value: { key: snapshot.selection.key, host }
3029
3129
  });
3130
+ if (!prepareHostConditionalBindings(snapshot.selection.branch, host)) {
3131
+ this.cleanup();
3132
+ return false;
3133
+ }
3030
3134
  cursor += 1;
3031
3135
  continue;
3032
3136
  }
@@ -3035,6 +3139,8 @@ var CompilerNestedMixedRanges = class {
3035
3139
  return false;
3036
3140
  }
3037
3141
  const keyedInstances = /* @__PURE__ */ new Map();
3142
+ this.instances.push({ kind: "keyed", value: keyedInstances });
3143
+ const keyedBindingUpdates = [];
3038
3144
  for (let index = 0; index < snapshot.rows.items.length; index += 1) {
3039
3145
  const element = elements[cursor + index];
3040
3146
  if (!element) {
@@ -3056,15 +3162,27 @@ var CompilerNestedMixedRanges = class {
3056
3162
  index,
3057
3163
  conditionalValues: /* @__PURE__ */ new Map()
3058
3164
  };
3165
+ let bindingUpdates;
3059
3166
  try {
3060
- applyKeyedRowBindings(range, instance, snapshot.rows.items[index], index);
3167
+ bindingUpdates = prepareKeyedRowBindingUpdates(
3168
+ range,
3169
+ instance,
3170
+ snapshot.rows.items[index],
3171
+ index
3172
+ );
3061
3173
  } catch (error) {
3062
3174
  scope.cleanup();
3063
3175
  throw error;
3064
3176
  }
3177
+ if (!bindingUpdates) {
3178
+ scope.cleanup();
3179
+ this.cleanup();
3180
+ return false;
3181
+ }
3065
3182
  keyedInstances.set(snapshot.rows.keys[index], instance);
3183
+ keyedBindingUpdates.push(bindingUpdates);
3066
3184
  }
3067
- this.instances.push({ kind: "keyed", value: keyedInstances });
3185
+ preparedKeyedBindings[rangeIndex] = keyedBindingUpdates;
3068
3186
  cursor += snapshot.rows.items.length;
3069
3187
  }
3070
3188
  const trailingEnd = cursor + this.block.trailing;
@@ -3077,6 +3195,22 @@ var CompilerNestedMixedRanges = class {
3077
3195
  this.cleanup();
3078
3196
  return false;
3079
3197
  }
3198
+ for (let index = 0; index < snapshots.length; index += 1) {
3199
+ const snapshot = snapshots[index];
3200
+ const instance = this.instances[index];
3201
+ if (snapshot.kind === "conditional" && snapshot.selection.kind === "branch" && instance?.kind === "conditional" && instance.value) {
3202
+ applyPreparedHostConditionalBindings(snapshot.selection.branch, instance.value.host);
3203
+ } else if (snapshot.kind === "keyed" && instance?.kind === "keyed") {
3204
+ const range = this.block.ranges[index];
3205
+ const bindingUpdates = preparedKeyedBindings[index];
3206
+ if (range.kind !== "keyed") continue;
3207
+ let rowIndex = 0;
3208
+ for (const row of instance.value.values()) {
3209
+ applyPreparedKeyedRowBindingUpdates(range, row, bindingUpdates[rowIndex]);
3210
+ rowIndex += 1;
3211
+ }
3212
+ }
3213
+ }
3080
3214
  this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
3081
3215
  return true;
3082
3216
  }
@@ -3607,7 +3741,9 @@ function createConditionalRangesBlockComponent(owner) {
3607
3741
  element,
3608
3742
  descriptor,
3609
3743
  selection.branch,
3610
- this.requestNestedFallback
3744
+ this.requestNestedFallback,
3745
+ false
3746
+ // Commit only after every sibling range validates.
3611
3747
  );
3612
3748
  if (!host) {
3613
3749
  cleanupInstances();
@@ -3617,6 +3753,15 @@ function createConditionalRangesBlockComponent(owner) {
3617
3753
  key: selection.key,
3618
3754
  host
3619
3755
  });
3756
+ try {
3757
+ if (!prepareHostConditionalBindings(selection.branch, host)) {
3758
+ cleanupInstances();
3759
+ return false;
3760
+ }
3761
+ } catch (error) {
3762
+ cleanupInstances();
3763
+ throw error;
3764
+ }
3620
3765
  cursor += 1;
3621
3766
  }
3622
3767
  if (cursor + props.trailing !== elements.length) {
@@ -3624,9 +3769,21 @@ function createConditionalRangesBlockComponent(owner) {
3624
3769
  return false;
3625
3770
  }
3626
3771
  staticSegments.push(elements.slice(cursor));
3627
- if (!applyStaticRangeBindings(props.bindings, staticSegments, staticValues)) {
3772
+ try {
3773
+ if (!applyStaticRangeBindings(props.bindings, staticSegments, staticValues)) {
3774
+ cleanupInstances();
3775
+ return false;
3776
+ }
3777
+ for (let index = 0; index < selections.length; index += 1) {
3778
+ const selection = selections[index];
3779
+ const instance = instances[index];
3780
+ if (selection.kind === "branch" && instance) {
3781
+ applyPreparedHostConditionalBindings(selection.branch, instance.host);
3782
+ }
3783
+ }
3784
+ } catch (error) {
3628
3785
  cleanupInstances();
3629
- return false;
3786
+ throw error;
3630
3787
  }
3631
3788
  for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
3632
3789
  this.staticSegments = staticSegments;