@farm.js/react 0.1.0-beta.8 → 0.1.0-beta.9

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/dist/vite.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { normalizePath } from 'vite';
2
2
  import { transformAsync, types, traverse } from '@babel/core';
3
- import { mkdir, writeFile } from 'fs/promises';
4
- import { resolve, dirname, relative } from 'path';
3
+ import { mkdir, writeFile, realpath, lstat } from 'fs/promises';
4
+ import { resolve, dirname, relative, sep, isAbsolute } from 'path';
5
5
 
6
6
  // src/vite.ts
7
7
  var DELEGATABLE_KEYED_ROW_EVENTS = /* @__PURE__ */ new Set([
@@ -71,11 +71,16 @@ var COMPILER_RUNTIME_FEATURE_EXPORTS = {
71
71
  "keyed-rows-batch-position-hinted": "keyedRowsBatchPositionHintedRuntimeFeature",
72
72
  "keyed-rows-window-position-hinted": "keyedRowsWindowPositionHintedRuntimeFeature",
73
73
  "keyed-rows-reorder-hinted": "keyedRowsReorderHintedRuntimeFeature",
74
+ "keyed-rows-map-reorder-hinted": "keyedRowsMapReorderHintedRuntimeFeature",
74
75
  "keyed-rows-all-hinted": "keyedRowsAllHintedRuntimeFeature",
75
76
  "keyed-rows-every-hinted": "keyedRowsEveryHintedRuntimeFeature",
76
77
  "keyed-rows-batch-every-hinted": "keyedRowsBatchEveryHintedRuntimeFeature",
77
78
  "keyed-rows-window-every-hinted": "keyedRowsWindowEveryHintedRuntimeFeature",
78
79
  "keyed-rows-filter-hinted": "keyedRowsFilterHintedRuntimeFeature",
80
+ "keyed-rows-structural-append-hinted": "keyedRowsStructuralAppendHintedRuntimeFeature",
81
+ "keyed-rows-structural-append-map-hinted": "keyedRowsStructuralAppendMapHintedRuntimeFeature",
82
+ "keyed-rows-structural-prepend-hinted": "keyedRowsStructuralPrependHintedRuntimeFeature",
83
+ "keyed-rows-structural-prepend-map-hinted": "keyedRowsStructuralPrependMapHintedRuntimeFeature",
79
84
  "keyed-rows-prepend-hinted": "keyedRowsPrependHintedRuntimeFeature",
80
85
  "keyed-rows-filter-prepend-hinted": "keyedRowsFilterPrependHintedRuntimeFeature",
81
86
  "keyed-rows-conditional": "keyedRowsConditionalRuntimeFeature",
@@ -89,6 +94,10 @@ var COMPILER_RUNTIME_FEATURE_EXPORTS = {
89
94
  "keyed-rows-conditional-batch-every-hinted": "keyedRowsConditionalBatchEveryHintedRuntimeFeature",
90
95
  "keyed-rows-conditional-window-every-hinted": "keyedRowsConditionalWindowEveryHintedRuntimeFeature",
91
96
  "keyed-rows-conditional-filter-hinted": "keyedRowsConditionalFilterHintedRuntimeFeature",
97
+ "keyed-rows-conditional-structural-append-hinted": "keyedRowsConditionalStructuralAppendHintedRuntimeFeature",
98
+ "keyed-rows-conditional-structural-append-map-hinted": "keyedRowsConditionalStructuralAppendMapHintedRuntimeFeature",
99
+ "keyed-rows-conditional-structural-prepend-hinted": "keyedRowsConditionalStructuralPrependHintedRuntimeFeature",
100
+ "keyed-rows-conditional-structural-prepend-map-hinted": "keyedRowsConditionalStructuralPrependMapHintedRuntimeFeature",
92
101
  "keyed-rows-conditional-prepend-hinted": "keyedRowsConditionalPrependHintedRuntimeFeature",
93
102
  "keyed-rows-conditional-filter-prepend-hinted": "keyedRowsConditionalFilterPrependHintedRuntimeFeature",
94
103
  "keyed-rows-host": "keyedRowsHostRuntimeFeature",
@@ -102,6 +111,10 @@ var COMPILER_RUNTIME_FEATURE_EXPORTS = {
102
111
  "keyed-rows-host-batch-every-hinted": "keyedRowsHostBatchEveryHintedRuntimeFeature",
103
112
  "keyed-rows-host-window-every-hinted": "keyedRowsHostWindowEveryHintedRuntimeFeature",
104
113
  "keyed-rows-host-filter-hinted": "keyedRowsHostFilterHintedRuntimeFeature",
114
+ "keyed-rows-host-structural-append-hinted": "keyedRowsHostStructuralAppendHintedRuntimeFeature",
115
+ "keyed-rows-host-structural-append-map-hinted": "keyedRowsHostStructuralAppendMapHintedRuntimeFeature",
116
+ "keyed-rows-host-structural-prepend-hinted": "keyedRowsHostStructuralPrependHintedRuntimeFeature",
117
+ "keyed-rows-host-structural-prepend-map-hinted": "keyedRowsHostStructuralPrependMapHintedRuntimeFeature",
105
118
  "keyed-rows-host-prepend-hinted": "keyedRowsHostPrependHintedRuntimeFeature",
106
119
  "keyed-rows-host-filter-prepend-hinted": "keyedRowsHostFilterPrependHintedRuntimeFeature",
107
120
  "keyed-rows-complete": "keyedRowsCompleteRuntimeFeature",
@@ -115,13 +128,17 @@ var COMPILER_RUNTIME_FEATURE_EXPORTS = {
115
128
  "keyed-rows-complete-batch-every-hinted": "keyedRowsCompleteBatchEveryHintedRuntimeFeature",
116
129
  "keyed-rows-complete-window-every-hinted": "keyedRowsCompleteWindowEveryHintedRuntimeFeature",
117
130
  "keyed-rows-complete-filter-hinted": "keyedRowsCompleteFilterHintedRuntimeFeature",
131
+ "keyed-rows-complete-structural-append-hinted": "keyedRowsCompleteStructuralAppendHintedRuntimeFeature",
132
+ "keyed-rows-complete-structural-append-map-hinted": "keyedRowsCompleteStructuralAppendMapHintedRuntimeFeature",
133
+ "keyed-rows-complete-structural-prepend-hinted": "keyedRowsCompleteStructuralPrependHintedRuntimeFeature",
134
+ "keyed-rows-complete-structural-prepend-map-hinted": "keyedRowsCompleteStructuralPrependMapHintedRuntimeFeature",
118
135
  "keyed-rows-complete-prepend-hinted": "keyedRowsCompletePrependHintedRuntimeFeature",
119
136
  "keyed-rows-complete-filter-prepend-hinted": "keyedRowsCompleteFilterPrependHintedRuntimeFeature",
120
137
  "keyed-ranges": "keyedRangesRuntimeFeature",
121
138
  "mixed-ranges": "mixedRangesRuntimeFeature",
122
139
  component: "componentRuntimeFeature"
123
140
  };
124
- function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHints, keyedArrayPrependHints, keyedArrayPositionHints, keyedArrayBatchInsertHints, keyedArrayWindowReplaceHints, keyedArrayReorderHints, keyedArrayRollingWindowHints) {
141
+ function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHints, keyedArrayStructuralAppendHints, keyedArrayStructuralAppendMapHints, keyedArrayPrependHints, keyedArrayStructuralPrependHints, keyedArrayStructuralPrependMapHints, keyedArrayPositionHints, keyedArrayBatchInsertHints, keyedArrayWindowReplaceHints, keyedArrayReorderHints, keyedArrayMapReorderHints, keyedArrayRollingWindowHints) {
125
142
  const features = /* @__PURE__ */ new Set();
126
143
  let keyedRowsHaveConditionals = false;
127
144
  let keyedRowsHaveHostBlocks = false;
@@ -138,7 +155,8 @@ function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHin
138
155
  if (plans.some((plan) => plan.kind === "keyed-rows")) {
139
156
  const keyedRowsFeature = keyedRowsHaveConditionals && keyedRowsHaveHostBlocks ? "keyed-rows-complete" : keyedRowsHaveConditionals ? "keyed-rows-conditional" : keyedRowsHaveHostBlocks ? "keyed-rows-host" : "keyed-rows";
140
157
  const arrayRangeHints = keyedArrayRollingWindowHints || keyedArrayFilterHints || keyedArrayPrependHints;
141
- const hintSuffix = keyedArrayWindowReplaceHints ? arrayRangeHints || keyedArrayReorderHints ? "-window-every-hinted" : "-window-position-hinted" : keyedArrayBatchInsertHints ? arrayRangeHints || keyedArrayReorderHints ? "-batch-every-hinted" : "-batch-position-hinted" : keyedArrayPositionHints && (arrayRangeHints || keyedArrayReorderHints) || keyedArrayReorderHints && arrayRangeHints ? "-every-hinted" : keyedArrayRollingWindowHints ? "-all-hinted" : keyedArrayPositionHints ? "-position-hinted" : keyedArrayReorderHints ? "-reorder-hinted" : keyedArrayFilterHints && keyedArrayPrependHints ? "-filter-prepend-hinted" : keyedArrayFilterHints ? "-filter-hinted" : keyedArrayPrependHints ? "-prepend-hinted" : keyedMapUpdateHints ? "-hinted" : "";
158
+ const needsCombinedStructuralPrependRuntime = keyedArrayStructuralPrependHints && (keyedArrayStructuralAppendMapHints || keyedArrayStructuralAppendHints || keyedArrayWindowReplaceHints || keyedArrayBatchInsertHints || keyedArrayPositionHints || keyedArrayReorderHints || keyedArrayRollingWindowHints);
159
+ const hintSuffix = keyedArrayStructuralPrependMapHints ? "-structural-prepend-map-hinted" : needsCombinedStructuralPrependRuntime ? "-structural-prepend-hinted" : keyedArrayStructuralAppendMapHints ? "-structural-append-map-hinted" : keyedArrayStructuralAppendHints ? "-structural-append-hinted" : keyedArrayWindowReplaceHints ? arrayRangeHints || keyedArrayReorderHints ? "-window-every-hinted" : "-window-position-hinted" : keyedArrayBatchInsertHints ? arrayRangeHints || keyedArrayReorderHints ? "-batch-every-hinted" : "-batch-position-hinted" : keyedArrayPositionHints && (arrayRangeHints || keyedArrayReorderHints) || keyedArrayReorderHints && arrayRangeHints ? "-every-hinted" : keyedArrayRollingWindowHints ? "-all-hinted" : keyedArrayPositionHints ? "-position-hinted" : keyedArrayMapReorderHints && keyedRowsFeature === "keyed-rows" ? "-map-reorder-hinted" : keyedArrayReorderHints ? "-reorder-hinted" : keyedArrayFilterHints && keyedArrayPrependHints ? "-filter-prepend-hinted" : keyedArrayFilterHints ? "-filter-hinted" : keyedArrayPrependHints ? "-prepend-hinted" : keyedMapUpdateHints ? "-hinted" : "";
142
160
  features.add(`${keyedRowsFeature}${hintSuffix}`);
143
161
  }
144
162
  return [...features].sort();
@@ -543,6 +561,22 @@ function isSafeKeyedMapResult(expression, item, safeGlobals) {
543
561
  if (validateDerivedExpression(expression.test, safeGlobals)) return false;
544
562
  return isUnchangedMapItem(expression.consequent, item) && isSafeKeyedMapReplacement(expression.alternate, item, safeGlobals) || isUnchangedMapItem(expression.alternate, item) && isSafeKeyedMapReplacement(expression.consequent, item, safeGlobals);
545
563
  }
564
+ function keyedMapUpdatePipeline(expression, parameterName, safeGlobals) {
565
+ const outerCallbacks = [];
566
+ let current = expression;
567
+ while (types.isCallExpression(current) && current.arguments.length === 1 && types.isMemberExpression(current.callee) && !current.callee.computed && types.isIdentifier(current.callee.property, { name: "map" }) && types.isExpression(current.callee.object)) {
568
+ const callback = current.arguments[0];
569
+ if (!types.isArrowFunctionExpression(callback) || callback.async || callback.generator || callback.params.length === 0 || callback.params.length > 3 || callback.params.some((parameter) => !types.isIdentifier(parameter)) || !types.isExpression(callback.body) || !isSafeKeyedMapResult(callback.body, callback.params[0], safeGlobals)) {
570
+ return void 0;
571
+ }
572
+ outerCallbacks.push(callback);
573
+ current = current.callee.object;
574
+ }
575
+ if (!types.isIdentifier(current, { name: parameterName }) || outerCallbacks.length === 0) {
576
+ return void 0;
577
+ }
578
+ return outerCallbacks.reverse();
579
+ }
546
580
  function rewriteKeyedMapUpdateHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
547
581
  if (hintedStateIndices.size === 0) return { root: types.cloneNode(root, true), count: 0 };
548
582
  const file = expressionFile(types.cloneNode(root, true));
@@ -556,58 +590,50 @@ function rewriteKeyedMapUpdateHints(root, hintedStateIndices, statesBySetter, he
556
590
  return;
557
591
  }
558
592
  const updater = path.node.arguments[0];
559
- if (!types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0]) || !types.isCallExpression(updater.body) || !types.isMemberExpression(updater.body.callee) || updater.body.callee.computed || !types.isIdentifier(updater.body.callee.object, {
560
- name: updater.params[0].name
561
- }) || !types.isIdentifier(updater.body.callee.property, { name: "map" })) {
562
- return;
563
- }
564
- const callback = updater.body.arguments[0];
565
- if (!types.isArrowFunctionExpression(callback) || callback.async || callback.generator || callback.params.length === 0 || callback.params.length > 3 || callback.params.some((parameter) => !types.isIdentifier(parameter)) || !types.isExpression(callback.body)) {
593
+ if (!types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0]) || !types.isExpression(updater.body)) {
566
594
  return;
567
595
  }
568
- const item = callback.params[0];
569
- if (!isSafeKeyedMapResult(callback.body, item, safeGlobals)) return;
570
- const changedIndices = path.scope.generateUidIdentifier("farmChangedIndices");
571
- const mappedItem = path.scope.generateUidIdentifier("farmMappedItem");
572
- const nextValue = path.scope.generateUidIdentifier("farmNextItems");
573
- const index = types.isIdentifier(callback.params[1]) ? types.cloneNode(callback.params[1]) : path.scope.generateUidIdentifier("farmMapIndex");
574
- const wrappedCallback = types.cloneNode(callback, true);
575
- if (wrappedCallback.params.length === 1) wrappedCallback.params.push(types.cloneNode(index));
576
- wrappedCallback.body = types.blockStatement([
577
- types.variableDeclaration("const", [
578
- types.variableDeclarator(types.cloneNode(mappedItem), types.cloneNode(callback.body, true))
579
- ]),
580
- types.ifStatement(
581
- types.binaryExpression("!==", types.cloneNode(mappedItem), types.cloneNode(item)),
582
- types.expressionStatement(
583
- types.callExpression(
584
- types.memberExpression(types.cloneNode(changedIndices), types.identifier("push")),
585
- [types.cloneNode(index)]
586
- )
587
- )
588
- ),
589
- types.returnStatement(types.cloneNode(mappedItem))
590
- ]);
591
- const mapCall = types.cloneNode(updater.body, true);
592
- mapCall.arguments[0] = wrappedCallback;
596
+ const callbacks = keyedMapUpdatePipeline(updater.body, updater.params[0].name, safeGlobals);
597
+ if (!callbacks) return;
593
598
  const previous = types.cloneNode(updater.params[0]);
594
- path.node.arguments[0] = types.arrowFunctionExpression(
595
- [types.cloneNode(previous)],
596
- types.blockStatement([
599
+ const pipelineValue = path.scope.generateUidIdentifier("farmMapValue");
600
+ const applyMap = path.scope.generateUidIdentifier("farmApplyMap");
601
+ const statements = [];
602
+ let current = types.cloneNode(pipelineValue);
603
+ for (let index = 0; index < callbacks.length; index += 1) {
604
+ const method = path.scope.generateUidIdentifier(`farmMap${index + 1}`);
605
+ const nextValue = path.scope.generateUidIdentifier(`farmMappedItems${index + 1}`);
606
+ statements.push(
597
607
  types.variableDeclaration("const", [
598
- types.variableDeclarator(types.cloneNode(changedIndices), types.arrayExpression([]))
608
+ types.variableDeclarator(
609
+ types.cloneNode(method),
610
+ types.memberExpression(types.cloneNode(current), types.identifier("map"))
611
+ )
599
612
  ]),
600
- types.variableDeclaration("const", [types.variableDeclarator(types.cloneNode(nextValue), mapCall)]),
601
- types.returnStatement(
602
- types.callExpression(types.cloneNode(helperIdentifier), [
603
- types.cloneNode(previous),
613
+ types.variableDeclaration("const", [
614
+ types.variableDeclarator(
604
615
  types.cloneNode(nextValue),
605
- types.cloneNode(changedIndices)
606
- ])
616
+ types.callExpression(types.cloneNode(applyMap), [
617
+ types.cloneNode(current),
618
+ types.cloneNode(method),
619
+ types.cloneNode(callbacks[index], true)
620
+ ])
621
+ )
622
+ ])
623
+ );
624
+ current = nextValue;
625
+ }
626
+ path.node.arguments[0] = types.arrowFunctionExpression(
627
+ [types.cloneNode(previous)],
628
+ types.callExpression(types.cloneNode(helperIdentifier), [
629
+ types.cloneNode(previous),
630
+ types.arrowFunctionExpression(
631
+ [types.cloneNode(pipelineValue), types.cloneNode(applyMap)],
632
+ types.blockStatement([...statements, types.returnStatement(types.cloneNode(current))])
607
633
  )
608
634
  ])
609
635
  );
610
- count += 1;
636
+ count += callbacks.length;
611
637
  path.skip();
612
638
  }
613
639
  });
@@ -780,8 +806,10 @@ function rewriteKeyedArrayRollingWindowHints(root, hintedStateIndices, statesByS
780
806
  }) || !types.isIdentifier(retainedSpread.argument.callee.property, { name: "slice" }) || !types.isExpression(retainedSpread.argument.arguments[0])) {
781
807
  return;
782
808
  }
783
- const retainedStart = staticSliceIndex(retainedSpread.argument.arguments[0]);
784
- if (retainedStart === void 0 || retainedStart === 0) return;
809
+ const retainedStart = retainedSpread.argument.arguments[0];
810
+ if (validateKeyedArrayPositionExpression(retainedStart, safeGlobals) !== void 0 || staticSliceIndex(retainedStart) === 0) {
811
+ return;
812
+ }
785
813
  const safeIncomingValue = (value) => {
786
814
  if (types.isArrayExpression(value)) {
787
815
  return value.elements.every(
@@ -824,7 +852,7 @@ function rewriteKeyedArrayRollingWindowHints(root, hintedStateIndices, statesByS
824
852
  types.callExpression(types.cloneNode(sliceHelperIdentifier), [
825
853
  types.cloneNode(previous),
826
854
  types.cloneNode(sliceMethod),
827
- types.numericLiteral(retainedStart)
855
+ types.cloneNode(retainedStart, true)
828
856
  ])
829
857
  ),
830
858
  types.variableDeclarator(types.cloneNode(nextValue), types.arrayExpression(nextElements))
@@ -895,14 +923,16 @@ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter
895
923
  }
896
924
  const methodName = updater.body.callee.property.name;
897
925
  const args = updater.body.arguments;
898
- const toSplicedDeleteCount = methodName === "toSpliced" && args.length >= 2 && types.isNumericLiteral(args[1]) ? args[1].value : void 0;
926
+ const deleteCountExpression = methodName === "toSpliced" && args.length >= 2 && types.isExpression(args[1]) ? args[1] : void 0;
927
+ const toSplicedDeleteCount = deleteCountExpression ? staticSliceIndex(deleteCountExpression) : void 0;
928
+ const hasRuntimeDeleteCount = deleteCountExpression !== void 0 && toSplicedDeleteCount === void 0 && validateKeyedArrayPositionExpression(deleteCountExpression, safeGlobals) === void 0;
899
929
  const isBatchInsert = methodName === "toSpliced" && args.length >= 3 && types.isNumericLiteral(args[1], { value: 0 }) && (args.length > 3 || types.isSpreadElement(args[2]));
900
- const isWindowReplace = methodName === "toSpliced" && args.length >= 3 && toSplicedDeleteCount !== void 0 && Number.isSafeInteger(toSplicedDeleteCount) && toSplicedDeleteCount > 0 && (toSplicedDeleteCount !== 1 || args.length > 3 || types.isSpreadElement(args[2]));
930
+ const isWindowReplace = methodName === "toSpliced" && (args.length >= 3 && toSplicedDeleteCount !== void 0 && Number.isSafeInteger(toSplicedDeleteCount) && toSplicedDeleteCount > 0 && (toSplicedDeleteCount !== 1 || args.length > 3 || types.isSpreadElement(args[2])) || hasRuntimeDeleteCount);
901
931
  const kind = isBatchInsert ? "batch-insert" : isWindowReplace ? "window-replace" : methodName === "with" && args.length === 2 ? "replace" : methodName === "toSpliced" && args.length === 3 && types.isNumericLiteral(args[1], { value: 0 }) ? "insert" : methodName === "toSpliced" && args.length === 3 && types.isNumericLiteral(args[1], { value: 1 }) ? "replace" : args.length === 2 && toSplicedDeleteCount !== void 0 && Number.isSafeInteger(toSplicedDeleteCount) && toSplicedDeleteCount > 0 ? "remove" : void 0;
902
932
  if (!kind || !types.isExpression(args[0])) return;
903
933
  const position = args[0];
904
934
  const incoming = kind === "batch-insert" || kind === "window-replace" ? args.slice(2) : [args.at(-1)];
905
- if (validateKeyedArrayPositionExpression(position, safeGlobals) !== void 0 || kind !== "remove" && incoming.some((item) => {
935
+ if (validateKeyedArrayPositionExpression(position, safeGlobals) !== void 0 || kind === "window-replace" && (!deleteCountExpression || validateKeyedArrayPositionExpression(deleteCountExpression, safeGlobals) !== void 0) || kind !== "remove" && incoming.some((item) => {
906
936
  const expression = types.isSpreadElement(item) ? item.argument : item;
907
937
  return !expression || !types.isExpression(expression) || validateDerivedExpression(expression, safeGlobals) !== void 0;
908
938
  })) {
@@ -976,34 +1006,976 @@ function rewriteKeyedArrayReorderHints(root, hintedStateIndices, statesBySetter,
976
1006
  if (!types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0]) || !types.isCallExpression(updater.body) || updater.body.arguments.length !== 0 || !types.isMemberExpression(updater.body.callee) || updater.body.callee.computed || !types.isIdentifier(updater.body.callee.object, { name: updater.params[0].name }) || !types.isIdentifier(updater.body.callee.property, { name: "toReversed" })) {
977
1007
  return;
978
1008
  }
979
- const previous = types.cloneNode(updater.params[0]);
980
- const method = path.scope.generateUidIdentifier("farmToReversed");
981
- path.node.arguments[0] = types.arrowFunctionExpression(
982
- [types.cloneNode(previous)],
983
- types.blockStatement([
984
- types.variableDeclaration("const", [
985
- types.variableDeclarator(
986
- types.cloneNode(method),
987
- types.memberExpression(types.cloneNode(previous), types.identifier("toReversed"))
988
- )
989
- ]),
990
- types.returnStatement(
991
- types.callExpression(types.cloneNode(helperIdentifier), [
992
- types.cloneNode(previous),
993
- types.cloneNode(method)
994
- ])
995
- )
996
- ])
997
- );
998
- count += 1;
999
- stateIndices.add(state.index);
1000
- path.skip();
1009
+ const previous = types.cloneNode(updater.params[0]);
1010
+ const method = path.scope.generateUidIdentifier("farmToReversed");
1011
+ path.node.arguments[0] = types.arrowFunctionExpression(
1012
+ [types.cloneNode(previous)],
1013
+ types.blockStatement([
1014
+ types.variableDeclaration("const", [
1015
+ types.variableDeclarator(
1016
+ types.cloneNode(method),
1017
+ types.memberExpression(types.cloneNode(previous), types.identifier("toReversed"))
1018
+ )
1019
+ ]),
1020
+ types.returnStatement(
1021
+ types.callExpression(types.cloneNode(helperIdentifier), [
1022
+ types.cloneNode(previous),
1023
+ types.cloneNode(method)
1024
+ ])
1025
+ )
1026
+ ])
1027
+ );
1028
+ count += 1;
1029
+ stateIndices.add(state.index);
1030
+ path.skip();
1031
+ }
1032
+ });
1033
+ return {
1034
+ root: file.program.body[0].expression,
1035
+ count,
1036
+ stateIndices
1037
+ };
1038
+ }
1039
+ function keyedArrayReorderPipeline(expression, parameterName, safeGlobals) {
1040
+ const outerSteps = [];
1041
+ let current = expression;
1042
+ while (types.isCallExpression(current) && types.isMemberExpression(current.callee) && !current.callee.computed && types.isIdentifier(current.callee.property) && types.isExpression(current.callee.object)) {
1043
+ const methodName = current.callee.property.name;
1044
+ if (methodName === "map") {
1045
+ if (current.arguments.length !== 1) return void 0;
1046
+ const callback = current.arguments[0];
1047
+ if (!types.isArrowFunctionExpression(callback) || callback.async || callback.generator || callback.params.length === 0 || callback.params.length > 3 || callback.params.some((parameter) => !types.isIdentifier(parameter)) || !types.isExpression(callback.body) || !isSafeKeyedMapResult(callback.body, callback.params[0], safeGlobals)) {
1048
+ return void 0;
1049
+ }
1050
+ outerSteps.push({ callback, kind: "map" });
1051
+ } else if (methodName === "filter") {
1052
+ if (current.arguments.length !== 1) return void 0;
1053
+ const predicate = current.arguments[0];
1054
+ if (!types.isArrowFunctionExpression(predicate) || predicate.async || predicate.generator || predicate.params.length !== 1 || !types.isIdentifier(predicate.params[0]) || !types.isExpression(predicate.body) || validateDerivedExpression(predicate.body, safeGlobals)) {
1055
+ return void 0;
1056
+ }
1057
+ outerSteps.push({ kind: "filter", predicate });
1058
+ } else if (methodName === "slice") {
1059
+ if (current.arguments.length < 1 || current.arguments.length > 2) return void 0;
1060
+ const bounds = [];
1061
+ for (const argument of current.arguments) {
1062
+ if (!types.isExpression(argument)) return void 0;
1063
+ if (validateKeyedArrayPositionExpression(argument, safeGlobals) !== void 0) {
1064
+ return void 0;
1065
+ }
1066
+ bounds.push(argument);
1067
+ }
1068
+ if (bounds.length === 1 && staticSliceIndex(bounds[0]) === 0) return void 0;
1069
+ outerSteps.push({ bounds, kind: "slice" });
1070
+ } else if (methodName === "toReversed") {
1071
+ if (current.arguments.length !== 0) return void 0;
1072
+ outerSteps.push({ kind: "reverse" });
1073
+ } else if (methodName === "toSorted") {
1074
+ if (current.arguments.length > 1) return void 0;
1075
+ const comparator = current.arguments[0];
1076
+ if (comparator && !types.isArrowFunctionExpression(comparator) && !types.isFunctionExpression(comparator)) {
1077
+ return void 0;
1078
+ }
1079
+ if (comparator && validateCollectionCallback(comparator, "toSorted", safeGlobals)) {
1080
+ return void 0;
1081
+ }
1082
+ outerSteps.push({ kind: "sort", ...comparator ? { comparator } : {} });
1083
+ } else {
1084
+ return void 0;
1085
+ }
1086
+ current = current.callee.object;
1087
+ }
1088
+ if (!types.isIdentifier(current, { name: parameterName }) || outerSteps.length < 2) {
1089
+ return void 0;
1090
+ }
1091
+ const steps = outerSteps.reverse();
1092
+ let mapSteps = 0;
1093
+ let structuralSteps = 0;
1094
+ let reorderSteps = 0;
1095
+ let reachedReorder = false;
1096
+ for (const step of steps) {
1097
+ if (step.kind === "map") {
1098
+ if (reachedReorder && structuralSteps > 0) return void 0;
1099
+ mapSteps += 1;
1100
+ } else if (step.kind === "filter" || step.kind === "slice") {
1101
+ if (reachedReorder) return void 0;
1102
+ structuralSteps += 1;
1103
+ } else {
1104
+ reachedReorder = true;
1105
+ reorderSteps += 1;
1106
+ }
1107
+ }
1108
+ if (reorderSteps < 1) {
1109
+ return structuralSteps > 0 && mapSteps > 0 ? steps : void 0;
1110
+ }
1111
+ if (mapSteps > 0 && reorderSteps >= 1) return steps;
1112
+ if (structuralSteps < 1 && reorderSteps < 2) return void 0;
1113
+ return steps;
1114
+ }
1115
+ function rewriteKeyedArrayReorderPipelineHints(root, hintedStateIndices, statesBySetter, filterHelperIdentifier, mapHelperIdentifier, mapReorderHelperIdentifier, mappedStructuralHelperIdentifier, reorderHelperIdentifier, structuralReorderHelperIdentifier, sliceHelperIdentifier, sortHelperIdentifier, structuralSortHelperIdentifier, safeGlobals, allowMapPipelines) {
1116
+ if (hintedStateIndices.size === 0) {
1117
+ return {
1118
+ root: types.cloneNode(root, true),
1119
+ filterCount: 0,
1120
+ mapCount: 0,
1121
+ mapReorderCount: 0,
1122
+ mapSortCount: 0,
1123
+ reorderCount: 0,
1124
+ sliceCount: 0,
1125
+ sortCount: 0,
1126
+ structuralReorderCount: 0,
1127
+ terminalStructuralPipelineCount: 0,
1128
+ structuralSortCount: 0,
1129
+ stateIndices: /* @__PURE__ */ new Set()
1130
+ };
1131
+ }
1132
+ const file = expressionFile(types.cloneNode(root, true));
1133
+ const stateIndices = /* @__PURE__ */ new Set();
1134
+ let filterCount = 0;
1135
+ let mapCount = 0;
1136
+ let mapReorderCount = 0;
1137
+ let mapSortCount = 0;
1138
+ let reorderCount = 0;
1139
+ let sliceCount = 0;
1140
+ let sortCount = 0;
1141
+ let structuralReorderCount = 0;
1142
+ let terminalStructuralPipelineCount = 0;
1143
+ let structuralSortCount = 0;
1144
+ traverse(file, {
1145
+ CallExpression(path) {
1146
+ const callee = path.get("callee");
1147
+ if (!callee.isIdentifier() || callee.scope.hasBinding(callee.node.name)) return;
1148
+ const state = statesBySetter.get(callee.node.name);
1149
+ if (!state || !hintedStateIndices.has(state.index) || path.node.arguments.length !== 1) {
1150
+ return;
1151
+ }
1152
+ const updater = path.node.arguments[0];
1153
+ if (!types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0]) || !types.isExpression(updater.body)) {
1154
+ return;
1155
+ }
1156
+ const steps = keyedArrayReorderPipeline(updater.body, updater.params[0].name, safeGlobals);
1157
+ if (!steps) return;
1158
+ const structuralPipeline = steps.some(
1159
+ (step) => step.kind === "filter" || step.kind === "slice"
1160
+ );
1161
+ const mapPipeline = steps.some((step) => step.kind === "map");
1162
+ if (mapPipeline && !allowMapPipelines) return;
1163
+ const terminalStructuralPipeline = mapPipeline && structuralPipeline && steps.every((step) => step.kind !== "reverse" && step.kind !== "sort");
1164
+ const previous = types.cloneNode(updater.params[0]);
1165
+ const statements = [];
1166
+ let value = types.cloneNode(previous);
1167
+ let hasMappedLineage = false;
1168
+ for (let stepIndex = 0; stepIndex < steps.length; stepIndex += 1) {
1169
+ const step = steps[stepIndex];
1170
+ if (step.kind === "map") {
1171
+ let mapEnd = stepIndex + 1;
1172
+ while (steps[mapEnd]?.kind === "map") mapEnd += 1;
1173
+ if (mapEnd - stepIndex > 1) {
1174
+ const pipelineValue = path.scope.generateUidIdentifier("farmMapValue");
1175
+ const applyMap = path.scope.generateUidIdentifier("farmApplyMap");
1176
+ const pipelineStatements = [];
1177
+ let current = types.cloneNode(pipelineValue);
1178
+ for (let mapIndex = stepIndex; mapIndex < mapEnd; mapIndex += 1) {
1179
+ const mapStep = steps[mapIndex];
1180
+ if (mapStep.kind !== "map") break;
1181
+ const method2 = path.scope.generateUidIdentifier(`farmMap${mapIndex + 1}`);
1182
+ const result3 = path.scope.generateUidIdentifier(`farmMappedItems${mapIndex + 1}`);
1183
+ pipelineStatements.push(
1184
+ types.variableDeclaration("const", [
1185
+ types.variableDeclarator(
1186
+ types.cloneNode(method2),
1187
+ types.memberExpression(types.cloneNode(current), types.identifier("map"))
1188
+ )
1189
+ ]),
1190
+ types.variableDeclaration("const", [
1191
+ types.variableDeclarator(
1192
+ types.cloneNode(result3),
1193
+ types.callExpression(types.cloneNode(applyMap), [
1194
+ types.cloneNode(current),
1195
+ types.cloneNode(method2),
1196
+ types.cloneNode(mapStep.callback, true)
1197
+ ])
1198
+ )
1199
+ ])
1200
+ );
1201
+ current = types.cloneNode(result3);
1202
+ }
1203
+ const result2 = path.scope.generateUidIdentifier("farmPipelineValue");
1204
+ statements.push(
1205
+ types.variableDeclaration("const", [
1206
+ types.variableDeclarator(
1207
+ types.cloneNode(result2),
1208
+ types.callExpression(types.cloneNode(mapHelperIdentifier), [
1209
+ types.cloneNode(value),
1210
+ types.arrowFunctionExpression(
1211
+ [types.cloneNode(pipelineValue), types.cloneNode(applyMap)],
1212
+ types.blockStatement([
1213
+ ...pipelineStatements,
1214
+ types.returnStatement(types.cloneNode(current))
1215
+ ])
1216
+ )
1217
+ ])
1218
+ )
1219
+ ])
1220
+ );
1221
+ value = types.cloneNode(result2);
1222
+ mapCount += mapEnd - stepIndex;
1223
+ hasMappedLineage = true;
1224
+ stepIndex = mapEnd - 1;
1225
+ continue;
1226
+ }
1227
+ }
1228
+ const methodName = step.kind === "map" ? "map" : step.kind === "filter" ? "filter" : step.kind === "slice" ? "slice" : step.kind === "reverse" ? "toReversed" : "toSorted";
1229
+ const method = path.scope.generateUidIdentifier(
1230
+ step.kind === "filter" ? "farmFilter" : step.kind === "map" ? "farmMap" : step.kind === "slice" ? "farmSlice" : step.kind === "reverse" ? "farmToReversed" : "farmToSorted"
1231
+ );
1232
+ const result = path.scope.generateUidIdentifier("farmPipelineValue");
1233
+ const helper = step.kind === "map" ? mapHelperIdentifier : step.kind === "filter" ? filterHelperIdentifier : step.kind === "slice" ? sliceHelperIdentifier : step.kind === "reverse" ? structuralPipeline ? structuralReorderHelperIdentifier : hasMappedLineage ? mapReorderHelperIdentifier : reorderHelperIdentifier : structuralPipeline ? structuralSortHelperIdentifier : hasMappedLineage ? mapReorderHelperIdentifier : sortHelperIdentifier;
1234
+ const args = step.kind === "map" ? [types.cloneNode(step.callback, true)] : step.kind === "filter" ? [types.cloneNode(step.predicate, true)] : step.kind === "slice" ? step.bounds.map((bound) => types.cloneNode(bound, true)) : step.kind === "sort" && step.comparator ? [types.cloneNode(step.comparator, true)] : [];
1235
+ statements.push(
1236
+ types.variableDeclaration("const", [
1237
+ types.variableDeclarator(
1238
+ types.cloneNode(method),
1239
+ types.memberExpression(types.cloneNode(value), types.identifier(methodName))
1240
+ )
1241
+ ]),
1242
+ types.variableDeclaration("const", [
1243
+ types.variableDeclarator(
1244
+ types.cloneNode(result),
1245
+ types.callExpression(types.cloneNode(helper), [
1246
+ types.cloneNode(value),
1247
+ types.cloneNode(method),
1248
+ ...args
1249
+ ])
1250
+ )
1251
+ ])
1252
+ );
1253
+ value = types.cloneNode(result);
1254
+ if (step.kind === "map") {
1255
+ mapCount += 1;
1256
+ hasMappedLineage = true;
1257
+ } else if (step.kind === "filter") filterCount += 1;
1258
+ else if (step.kind === "slice") sliceCount += 1;
1259
+ else if (step.kind === "reverse") {
1260
+ reorderCount += 1;
1261
+ if (hasMappedLineage && !structuralPipeline) mapReorderCount += 1;
1262
+ if (structuralPipeline) structuralReorderCount += 1;
1263
+ } else {
1264
+ sortCount += 1;
1265
+ if (hasMappedLineage && !structuralPipeline) mapSortCount += 1;
1266
+ if (structuralPipeline) structuralSortCount += 1;
1267
+ }
1268
+ }
1269
+ statements.push(
1270
+ types.returnStatement(
1271
+ terminalStructuralPipeline ? types.callExpression(types.cloneNode(mappedStructuralHelperIdentifier), [types.cloneNode(value)]) : types.cloneNode(value)
1272
+ )
1273
+ );
1274
+ if (terminalStructuralPipeline) terminalStructuralPipelineCount += 1;
1275
+ path.node.arguments[0] = types.arrowFunctionExpression(
1276
+ [types.cloneNode(previous)],
1277
+ types.blockStatement(statements)
1278
+ );
1279
+ stateIndices.add(state.index);
1280
+ path.skip();
1281
+ }
1282
+ });
1283
+ return {
1284
+ root: file.program.body[0].expression,
1285
+ filterCount,
1286
+ mapCount,
1287
+ mapReorderCount,
1288
+ mapSortCount,
1289
+ reorderCount,
1290
+ sliceCount,
1291
+ sortCount,
1292
+ structuralReorderCount,
1293
+ terminalStructuralPipelineCount,
1294
+ structuralSortCount,
1295
+ stateIndices
1296
+ };
1297
+ }
1298
+ function rewriteQueuedKeyedArrayReorderMapHints(root, statesBySetter, mapUpdateIdentifier, queuedMapPipelineIdentifier, mapReorderIdentifier, reorderIdentifier, sortIdentifier, structuralReorderIdentifier, structuralSortIdentifier, allowed) {
1299
+ if (!allowed) return { root: types.cloneNode(root, true), mapCount: 0 };
1300
+ const file = expressionFile(types.cloneNode(root, true));
1301
+ let mapCount = 0;
1302
+ const containsHelperCall = (updater, helperNames) => {
1303
+ let found = false;
1304
+ types.traverseFast(updater.body, (node) => {
1305
+ if (!found && types.isCallExpression(node) && types.isIdentifier(node.callee) && helperNames.has(node.callee.name)) {
1306
+ found = true;
1307
+ }
1308
+ });
1309
+ return found;
1310
+ };
1311
+ const reorderHelperNames = /* @__PURE__ */ new Set([
1312
+ mapReorderIdentifier.name,
1313
+ reorderIdentifier.name,
1314
+ sortIdentifier.name
1315
+ ]);
1316
+ const structuralHelperNames = /* @__PURE__ */ new Set([
1317
+ structuralReorderIdentifier.name,
1318
+ structuralSortIdentifier.name
1319
+ ]);
1320
+ traverse(file, {
1321
+ BlockStatement(path) {
1322
+ let queuedReorderState;
1323
+ const statements = path.get("body");
1324
+ for (const statementPath of statements) {
1325
+ const statement = statementPath.node;
1326
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1327
+ queuedReorderState = void 0;
1328
+ continue;
1329
+ }
1330
+ const setterCall = statement.expression;
1331
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1332
+ queuedReorderState = void 0;
1333
+ continue;
1334
+ }
1335
+ const state = statesBySetter.get(setterCall.callee.name);
1336
+ const updater = setterCall.arguments[0];
1337
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1338
+ queuedReorderState = void 0;
1339
+ continue;
1340
+ }
1341
+ if (containsHelperCall(updater, reorderHelperNames) && !containsHelperCall(updater, structuralHelperNames)) {
1342
+ queuedReorderState = state.index;
1343
+ continue;
1344
+ }
1345
+ if (queuedReorderState !== state.index || !types.isCallExpression(updater.body) || !types.isIdentifier(updater.body.callee, { name: mapUpdateIdentifier.name }) || updater.body.arguments.length !== 2) {
1346
+ queuedReorderState = void 0;
1347
+ continue;
1348
+ }
1349
+ const pipeline = updater.body.arguments[1];
1350
+ if (!types.isArrowFunctionExpression(pipeline) || pipeline.params.length !== 2 || !types.isIdentifier(pipeline.params[1])) {
1351
+ queuedReorderState = void 0;
1352
+ continue;
1353
+ }
1354
+ let pipelineMapCount = 0;
1355
+ const applyMapName = pipeline.params[1].name;
1356
+ types.traverseFast(pipeline.body, (node) => {
1357
+ if (types.isCallExpression(node) && types.isIdentifier(node.callee, { name: applyMapName })) {
1358
+ pipelineMapCount += 1;
1359
+ }
1360
+ });
1361
+ if (pipelineMapCount === 0) {
1362
+ queuedReorderState = void 0;
1363
+ continue;
1364
+ }
1365
+ updater.body.callee = types.cloneNode(queuedMapPipelineIdentifier);
1366
+ mapCount += pipelineMapCount;
1367
+ }
1368
+ }
1369
+ });
1370
+ return {
1371
+ root: file.program.body[0].expression,
1372
+ mapCount
1373
+ };
1374
+ }
1375
+ function countKeyedArrayMapPipeline(updater, mapUpdateIdentifier) {
1376
+ if (!types.isCallExpression(updater.body) || !types.isIdentifier(updater.body.callee, { name: mapUpdateIdentifier.name }) || updater.body.arguments.length !== 2) {
1377
+ return 0;
1378
+ }
1379
+ const pipeline = updater.body.arguments[1];
1380
+ if (!types.isArrowFunctionExpression(pipeline) || pipeline.params.length !== 2 || !types.isIdentifier(pipeline.params[1])) {
1381
+ return 0;
1382
+ }
1383
+ const applyMapName = pipeline.params[1].name;
1384
+ let count = 0;
1385
+ types.traverseFast(pipeline.body, (node) => {
1386
+ if (types.isCallExpression(node) && types.isIdentifier(node.callee, { name: applyMapName })) {
1387
+ count += 1;
1388
+ }
1389
+ });
1390
+ return count;
1391
+ }
1392
+ function rewriteQueuedKeyedArrayMappedStructuralHints(root, statesBySetter, mapUpdateIdentifier, queuedMapPipelineIdentifier, mappedStructuralIdentifier, filterIdentifier, sliceIdentifier, allowed) {
1393
+ if (!allowed) {
1394
+ return {
1395
+ root: types.cloneNode(root, true),
1396
+ mapCount: 0,
1397
+ structuralCount: 0,
1398
+ stateIndices: /* @__PURE__ */ new Set()
1399
+ };
1400
+ }
1401
+ const file = expressionFile(types.cloneNode(root, true));
1402
+ let mapCount = 0;
1403
+ let structuralCount = 0;
1404
+ const stateIndices = /* @__PURE__ */ new Set();
1405
+ const terminalStructuralReturn = (updater) => {
1406
+ if (!types.isBlockStatement(updater.body)) return void 0;
1407
+ const statement = updater.body.body.at(-1);
1408
+ if (!types.isReturnStatement(statement) || !statement.argument || !types.isCallExpression(statement.argument) || !types.isIdentifier(statement.argument.callee) || statement.argument.callee.name !== filterIdentifier.name && statement.argument.callee.name !== sliceIdentifier.name) {
1409
+ return void 0;
1410
+ }
1411
+ return statement;
1412
+ };
1413
+ traverse(file, {
1414
+ BlockStatement(path) {
1415
+ let mappedStructuralState;
1416
+ let pendingMaps = [];
1417
+ const statements = path.get("body");
1418
+ for (const statementPath of statements) {
1419
+ const statement = statementPath.node;
1420
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1421
+ mappedStructuralState = void 0;
1422
+ pendingMaps = [];
1423
+ continue;
1424
+ }
1425
+ const setterCall = statement.expression;
1426
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1427
+ mappedStructuralState = void 0;
1428
+ pendingMaps = [];
1429
+ continue;
1430
+ }
1431
+ const state = statesBySetter.get(setterCall.callee.name);
1432
+ const updater = setterCall.arguments[0];
1433
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1434
+ mappedStructuralState = void 0;
1435
+ pendingMaps = [];
1436
+ continue;
1437
+ }
1438
+ const pipelineMapCount = countKeyedArrayMapPipeline(updater, mapUpdateIdentifier);
1439
+ if (pipelineMapCount > 0) {
1440
+ if (mappedStructuralState !== void 0) {
1441
+ mappedStructuralState = void 0;
1442
+ pendingMaps = [];
1443
+ continue;
1444
+ }
1445
+ const candidate = {
1446
+ count: pipelineMapCount,
1447
+ stateIndex: state.index,
1448
+ updater
1449
+ };
1450
+ pendingMaps = pendingMaps[0]?.stateIndex === state.index ? [...pendingMaps, candidate] : [candidate];
1451
+ continue;
1452
+ }
1453
+ const structuralReturn = terminalStructuralReturn(updater);
1454
+ const hasPendingMaps = pendingMaps.length > 0 && pendingMaps[0].stateIndex === state.index;
1455
+ if (!structuralReturn || !hasPendingMaps && mappedStructuralState !== state.index) {
1456
+ mappedStructuralState = void 0;
1457
+ pendingMaps = [];
1458
+ continue;
1459
+ }
1460
+ if (hasPendingMaps) {
1461
+ for (const candidate of pendingMaps) {
1462
+ candidate.updater.body.callee = types.cloneNode(queuedMapPipelineIdentifier);
1463
+ mapCount += candidate.count;
1464
+ }
1465
+ }
1466
+ const structuralValue = structuralReturn.argument;
1467
+ if (!types.isExpression(structuralValue)) {
1468
+ mappedStructuralState = void 0;
1469
+ pendingMaps = [];
1470
+ continue;
1471
+ }
1472
+ structuralReturn.argument = types.callExpression(types.cloneNode(mappedStructuralIdentifier), [
1473
+ types.cloneNode(structuralValue)
1474
+ ]);
1475
+ structuralCount += 1;
1476
+ stateIndices.add(state.index);
1477
+ mappedStructuralState = state.index;
1478
+ pendingMaps = [];
1479
+ }
1480
+ }
1481
+ });
1482
+ return {
1483
+ root: file.program.body[0].expression,
1484
+ mapCount,
1485
+ structuralCount,
1486
+ stateIndices
1487
+ };
1488
+ }
1489
+ function rewriteQueuedKeyedArrayStructuralMapHints(root, statesBySetter, mapUpdateIdentifier, mapPipelineIdentifier, appendIdentifier, mappedStructuralAppendIdentifier, structuralAppendMapPipelineIdentifier, filterIdentifier, sliceIdentifier, mappedStructuralIdentifier, allowed) {
1490
+ if (!allowed) {
1491
+ return {
1492
+ root: types.cloneNode(root, true),
1493
+ mapCount: 0,
1494
+ mappedStructuralAppendCount: 0,
1495
+ structuralAppendMapCount: 0,
1496
+ stateIndices: /* @__PURE__ */ new Set()
1497
+ };
1498
+ }
1499
+ const file = expressionFile(types.cloneNode(root, true));
1500
+ let mapCount = 0;
1501
+ let mappedStructuralAppendCount = 0;
1502
+ let structuralAppendMapCount = 0;
1503
+ const stateIndices = /* @__PURE__ */ new Set();
1504
+ const structuralUpdateKind = (updater) => {
1505
+ if (!types.isBlockStatement(updater.body)) return void 0;
1506
+ const statement = updater.body.body.at(-1);
1507
+ if (!types.isReturnStatement(statement) || !statement.argument) return void 0;
1508
+ let found;
1509
+ let mapped = false;
1510
+ types.traverseFast(statement.argument, (node) => {
1511
+ if (!found && types.isCallExpression(node) && types.isIdentifier(node.callee)) {
1512
+ if (node.callee.name === filterIdentifier.name) found = "filter";
1513
+ if (node.callee.name === sliceIdentifier.name) found = "slice";
1514
+ }
1515
+ if (!mapped && types.isCallExpression(node) && types.isIdentifier(node.callee, { name: mappedStructuralIdentifier.name })) {
1516
+ mapped = true;
1517
+ }
1518
+ });
1519
+ return found ? { kind: found, mapped } : void 0;
1520
+ };
1521
+ traverse(file, {
1522
+ BlockStatement(path) {
1523
+ let structuralState;
1524
+ let structuralAppendState;
1525
+ let structuralMapState;
1526
+ let structuralKind;
1527
+ const statements = path.get("body");
1528
+ for (const statementPath of statements) {
1529
+ const statement = statementPath.node;
1530
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1531
+ structuralState = void 0;
1532
+ structuralAppendState = void 0;
1533
+ structuralMapState = void 0;
1534
+ structuralKind = void 0;
1535
+ continue;
1536
+ }
1537
+ const setterCall = statement.expression;
1538
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1539
+ structuralState = void 0;
1540
+ structuralAppendState = void 0;
1541
+ structuralMapState = void 0;
1542
+ structuralKind = void 0;
1543
+ continue;
1544
+ }
1545
+ const state = statesBySetter.get(setterCall.callee.name);
1546
+ const updater = setterCall.arguments[0];
1547
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1548
+ structuralState = void 0;
1549
+ structuralAppendState = void 0;
1550
+ structuralMapState = void 0;
1551
+ structuralKind = void 0;
1552
+ continue;
1553
+ }
1554
+ const nextStructuralKind = structuralUpdateKind(updater);
1555
+ if (nextStructuralKind) {
1556
+ structuralState = state.index;
1557
+ structuralAppendState = void 0;
1558
+ structuralMapState = nextStructuralKind.mapped ? state.index : void 0;
1559
+ structuralKind = nextStructuralKind.kind;
1560
+ continue;
1561
+ }
1562
+ const appendCalls = [];
1563
+ types.traverseFast(updater.body, (node) => {
1564
+ if (types.isCallExpression(node) && types.isIdentifier(node.callee, { name: appendIdentifier.name })) {
1565
+ appendCalls.push(node);
1566
+ }
1567
+ });
1568
+ if (appendCalls.length > 0) {
1569
+ if (structuralState === state.index && structuralKind !== void 0) {
1570
+ structuralAppendState = state.index;
1571
+ if (structuralMapState === state.index) {
1572
+ for (const call of appendCalls) {
1573
+ call.callee = types.cloneNode(mappedStructuralAppendIdentifier);
1574
+ }
1575
+ mappedStructuralAppendCount += appendCalls.length;
1576
+ }
1577
+ } else {
1578
+ structuralState = void 0;
1579
+ structuralAppendState = void 0;
1580
+ structuralMapState = void 0;
1581
+ structuralKind = void 0;
1582
+ }
1583
+ continue;
1584
+ }
1585
+ const pipelineMapCount = countKeyedArrayMapPipeline(updater, mapUpdateIdentifier);
1586
+ if (structuralState !== state.index || pipelineMapCount === 0) {
1587
+ structuralState = void 0;
1588
+ structuralAppendState = void 0;
1589
+ structuralMapState = void 0;
1590
+ structuralKind = void 0;
1591
+ continue;
1592
+ }
1593
+ updater.body.callee = types.cloneNode(
1594
+ structuralAppendState === state.index ? structuralAppendMapPipelineIdentifier : mapPipelineIdentifier
1595
+ );
1596
+ mapCount += pipelineMapCount;
1597
+ if (structuralAppendState === state.index) {
1598
+ structuralAppendMapCount += pipelineMapCount;
1599
+ }
1600
+ structuralMapState = state.index;
1601
+ stateIndices.add(state.index);
1602
+ }
1603
+ }
1604
+ });
1605
+ return {
1606
+ root: file.program.body[0].expression,
1607
+ mapCount,
1608
+ mappedStructuralAppendCount,
1609
+ structuralAppendMapCount,
1610
+ stateIndices
1611
+ };
1612
+ }
1613
+ function rewriteQueuedKeyedArrayStructuralPrependMapHints(root, statesBySetter, mapUpdateIdentifier, mapPipelineIdentifier, prependIdentifier, mappedStructuralPrependIdentifier, structuralPrependMapPipelineIdentifier, filterIdentifier, sliceIdentifier, mappedStructuralIdentifier, allowed) {
1614
+ if (!allowed) {
1615
+ return {
1616
+ root: types.cloneNode(root, true),
1617
+ mapCount: 0,
1618
+ mappedStructuralPrependCount: 0,
1619
+ structuralPrependMapCount: 0,
1620
+ stateIndices: /* @__PURE__ */ new Set()
1621
+ };
1622
+ }
1623
+ const file = expressionFile(types.cloneNode(root, true));
1624
+ let mapCount = 0;
1625
+ let mappedStructuralPrependCount = 0;
1626
+ let structuralPrependMapCount = 0;
1627
+ const stateIndices = /* @__PURE__ */ new Set();
1628
+ const structuralUpdateKind = (updater) => {
1629
+ if (!types.isBlockStatement(updater.body)) return void 0;
1630
+ const statement = updater.body.body.at(-1);
1631
+ if (!types.isReturnStatement(statement) || !statement.argument) return void 0;
1632
+ let found;
1633
+ let mapped = false;
1634
+ types.traverseFast(statement.argument, (node) => {
1635
+ if (!found && types.isCallExpression(node) && types.isIdentifier(node.callee)) {
1636
+ if (node.callee.name === filterIdentifier.name) found = "filter";
1637
+ if (node.callee.name === sliceIdentifier.name) found = "slice";
1638
+ }
1639
+ if (!mapped && types.isCallExpression(node) && types.isIdentifier(node.callee, { name: mappedStructuralIdentifier.name })) {
1640
+ mapped = true;
1641
+ }
1642
+ });
1643
+ return found ? { kind: found, mapped } : void 0;
1644
+ };
1645
+ traverse(file, {
1646
+ BlockStatement(path) {
1647
+ let structuralState;
1648
+ let structuralPrependState;
1649
+ let structuralMapState;
1650
+ let structuralKind;
1651
+ const statements = path.get("body");
1652
+ for (const statementPath of statements) {
1653
+ const statement = statementPath.node;
1654
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1655
+ structuralState = void 0;
1656
+ structuralPrependState = void 0;
1657
+ structuralMapState = void 0;
1658
+ structuralKind = void 0;
1659
+ continue;
1660
+ }
1661
+ const setterCall = statement.expression;
1662
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1663
+ structuralState = void 0;
1664
+ structuralPrependState = void 0;
1665
+ structuralMapState = void 0;
1666
+ structuralKind = void 0;
1667
+ continue;
1668
+ }
1669
+ const state = statesBySetter.get(setterCall.callee.name);
1670
+ const updater = setterCall.arguments[0];
1671
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1672
+ structuralState = void 0;
1673
+ structuralPrependState = void 0;
1674
+ structuralMapState = void 0;
1675
+ structuralKind = void 0;
1676
+ continue;
1677
+ }
1678
+ const nextStructuralKind = structuralUpdateKind(updater);
1679
+ if (nextStructuralKind) {
1680
+ structuralState = state.index;
1681
+ structuralPrependState = void 0;
1682
+ structuralMapState = nextStructuralKind.mapped ? state.index : void 0;
1683
+ structuralKind = nextStructuralKind.kind;
1684
+ continue;
1685
+ }
1686
+ const prependCalls = [];
1687
+ types.traverseFast(updater.body, (node) => {
1688
+ if (types.isCallExpression(node) && types.isIdentifier(node.callee, { name: prependIdentifier.name })) {
1689
+ prependCalls.push(node);
1690
+ }
1691
+ });
1692
+ if (prependCalls.length > 0) {
1693
+ if (structuralState === state.index && structuralKind !== void 0) {
1694
+ structuralPrependState = state.index;
1695
+ if (structuralMapState === state.index) {
1696
+ for (const call of prependCalls) {
1697
+ call.callee = types.cloneNode(mappedStructuralPrependIdentifier);
1698
+ }
1699
+ mappedStructuralPrependCount += prependCalls.length;
1700
+ }
1701
+ } else {
1702
+ structuralState = void 0;
1703
+ structuralPrependState = void 0;
1704
+ structuralMapState = void 0;
1705
+ structuralKind = void 0;
1706
+ }
1707
+ continue;
1708
+ }
1709
+ const pipelineMapCount = countKeyedArrayMapPipeline(updater, mapUpdateIdentifier) || countKeyedArrayMapPipeline(updater, mapPipelineIdentifier);
1710
+ if (structuralState !== state.index || pipelineMapCount === 0) {
1711
+ structuralState = void 0;
1712
+ structuralPrependState = void 0;
1713
+ structuralMapState = void 0;
1714
+ structuralKind = void 0;
1715
+ continue;
1716
+ }
1717
+ updater.body.callee = types.cloneNode(
1718
+ structuralPrependState === state.index ? structuralPrependMapPipelineIdentifier : mapPipelineIdentifier
1719
+ );
1720
+ mapCount += pipelineMapCount;
1721
+ if (structuralPrependState === state.index) {
1722
+ structuralPrependMapCount += pipelineMapCount;
1723
+ }
1724
+ structuralMapState = state.index;
1725
+ stateIndices.add(state.index);
1726
+ }
1727
+ }
1728
+ });
1729
+ return {
1730
+ root: file.program.body[0].expression,
1731
+ mapCount,
1732
+ mappedStructuralPrependCount,
1733
+ structuralPrependMapCount,
1734
+ stateIndices
1735
+ };
1736
+ }
1737
+ function rewriteQueuedKeyedArrayStructuralReorderHints(root, statesBySetter, filterIdentifier, sliceIdentifier, mapPipelineIdentifier, queuedMapPipelineIdentifier, mappedStructuralIdentifier, mapReorderIdentifier, reorderIdentifier, sortIdentifier, structuralReorderIdentifier, structuralSortIdentifier, allowed) {
1738
+ if (!allowed) {
1739
+ return {
1740
+ root: types.cloneNode(root, true),
1741
+ reorderCount: 0,
1742
+ sortCount: 0,
1743
+ replacedMapReorderCount: 0,
1744
+ replacedMapSortCount: 0,
1745
+ replacedQueuedMapCount: 0
1746
+ };
1747
+ }
1748
+ const file = expressionFile(types.cloneNode(root, true));
1749
+ let reorderCount = 0;
1750
+ let sortCount = 0;
1751
+ let replacedMapReorderCount = 0;
1752
+ let replacedMapSortCount = 0;
1753
+ let replacedQueuedMapCount = 0;
1754
+ traverse(file, {
1755
+ BlockStatement(path) {
1756
+ let structuralState;
1757
+ const statements = path.get("body");
1758
+ for (const statementPath of statements) {
1759
+ const statement = statementPath.node;
1760
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1761
+ structuralState = void 0;
1762
+ continue;
1763
+ }
1764
+ const setterCall = statement.expression;
1765
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1766
+ structuralState = void 0;
1767
+ continue;
1768
+ }
1769
+ const state = statesBySetter.get(setterCall.callee.name);
1770
+ const updater = setterCall.arguments[0];
1771
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1772
+ structuralState = void 0;
1773
+ continue;
1774
+ }
1775
+ const methodKinds = /* @__PURE__ */ new Map();
1776
+ types.traverseFast(updater.body, (node) => {
1777
+ if (!types.isVariableDeclarator(node) || !types.isIdentifier(node.id) || !types.isMemberExpression(node.init) || node.init.computed || !types.isIdentifier(node.init.property)) {
1778
+ return;
1779
+ }
1780
+ if (node.init.property.name === "toReversed") methodKinds.set(node.id.name, "reverse");
1781
+ if (node.init.property.name === "toSorted") methodKinds.set(node.id.name, "sort");
1782
+ });
1783
+ let startsStructuralLineage = false;
1784
+ let continuesStructuralLineage = false;
1785
+ let unsupported = false;
1786
+ const queuedMaps = [];
1787
+ const reorderCalls = [];
1788
+ types.traverseFast(updater.body, (node) => {
1789
+ if (!types.isCallExpression(node) || !types.isIdentifier(node.callee)) return;
1790
+ const helperName = node.callee.name;
1791
+ if (helperName === filterIdentifier.name || helperName === sliceIdentifier.name || helperName === mappedStructuralIdentifier.name) {
1792
+ startsStructuralLineage = true;
1793
+ return;
1794
+ }
1795
+ if (helperName === structuralReorderIdentifier.name || helperName === structuralSortIdentifier.name) {
1796
+ startsStructuralLineage = true;
1797
+ return;
1798
+ }
1799
+ if (helperName === mapPipelineIdentifier.name) {
1800
+ continuesStructuralLineage = true;
1801
+ return;
1802
+ }
1803
+ if (helperName === queuedMapPipelineIdentifier.name) {
1804
+ continuesStructuralLineage = true;
1805
+ queuedMaps.push(node);
1806
+ return;
1807
+ }
1808
+ if (helperName === reorderIdentifier.name) {
1809
+ continuesStructuralLineage = true;
1810
+ reorderCalls.push({ call: node, kind: "reverse", mapped: false });
1811
+ return;
1812
+ }
1813
+ if (helperName === sortIdentifier.name) {
1814
+ continuesStructuralLineage = true;
1815
+ reorderCalls.push({ call: node, kind: "sort", mapped: false });
1816
+ return;
1817
+ }
1818
+ if (helperName === mapReorderIdentifier.name) {
1819
+ const method = node.arguments[1];
1820
+ const kind = types.isIdentifier(method) ? methodKinds.get(method.name) : void 0;
1821
+ if (!kind) {
1822
+ unsupported = true;
1823
+ return;
1824
+ }
1825
+ continuesStructuralLineage = true;
1826
+ reorderCalls.push({ call: node, kind, mapped: true });
1827
+ }
1828
+ });
1829
+ const hasStructuralLineage = startsStructuralLineage || structuralState === state.index;
1830
+ if (unsupported || !startsStructuralLineage && !continuesStructuralLineage) {
1831
+ structuralState = void 0;
1832
+ continue;
1833
+ }
1834
+ if (!hasStructuralLineage) {
1835
+ structuralState = void 0;
1836
+ continue;
1837
+ }
1838
+ for (const call of queuedMaps) {
1839
+ call.callee = types.cloneNode(mapPipelineIdentifier);
1840
+ replacedQueuedMapCount += 1;
1841
+ }
1842
+ for (const { call, kind, mapped } of reorderCalls) {
1843
+ call.callee = types.cloneNode(
1844
+ kind === "reverse" ? structuralReorderIdentifier : structuralSortIdentifier
1845
+ );
1846
+ if (kind === "reverse") {
1847
+ reorderCount += 1;
1848
+ if (mapped) replacedMapReorderCount += 1;
1849
+ } else {
1850
+ sortCount += 1;
1851
+ if (mapped) replacedMapSortCount += 1;
1852
+ }
1853
+ }
1854
+ structuralState = state.index;
1855
+ }
1856
+ }
1857
+ });
1858
+ return {
1859
+ root: file.program.body[0].expression,
1860
+ reorderCount,
1861
+ sortCount,
1862
+ replacedMapReorderCount,
1863
+ replacedMapSortCount,
1864
+ replacedQueuedMapCount
1865
+ };
1866
+ }
1867
+ function rewriteQueuedKeyedArrayMapReorderHints(root, statesBySetter, mapUpdateIdentifier, queuedMapPipelineIdentifier, mapReorderIdentifier, reorderIdentifier, sortIdentifier, structuralReorderIdentifier, structuralSortIdentifier, allowed) {
1868
+ if (!allowed) {
1869
+ return {
1870
+ root: types.cloneNode(root, true),
1871
+ mapCount: 0,
1872
+ mapReorderCount: 0,
1873
+ mapSortCount: 0
1874
+ };
1875
+ }
1876
+ const file = expressionFile(types.cloneNode(root, true));
1877
+ let mapCount = 0;
1878
+ let mapReorderCount = 0;
1879
+ let mapSortCount = 0;
1880
+ traverse(file, {
1881
+ BlockStatement(path) {
1882
+ let mappedReorderState;
1883
+ let pendingMaps = [];
1884
+ const statements = path.get("body");
1885
+ for (const statementPath of statements) {
1886
+ const statement = statementPath.node;
1887
+ if (!types.isExpressionStatement(statement) || !types.isCallExpression(statement.expression)) {
1888
+ mappedReorderState = void 0;
1889
+ pendingMaps = [];
1890
+ continue;
1891
+ }
1892
+ const setterCall = statement.expression;
1893
+ if (!types.isIdentifier(setterCall.callee) || statementPath.scope.hasBinding(setterCall.callee.name) || setterCall.arguments.length !== 1) {
1894
+ mappedReorderState = void 0;
1895
+ pendingMaps = [];
1896
+ continue;
1897
+ }
1898
+ const state = statesBySetter.get(setterCall.callee.name);
1899
+ const updater = setterCall.arguments[0];
1900
+ if (!state || !types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0])) {
1901
+ mappedReorderState = void 0;
1902
+ pendingMaps = [];
1903
+ continue;
1904
+ }
1905
+ if (types.isCallExpression(updater.body) && types.isIdentifier(updater.body.callee, { name: mapUpdateIdentifier.name }) && updater.body.arguments.length === 2) {
1906
+ const pipeline = updater.body.arguments[1];
1907
+ let pipelineMapCount = 0;
1908
+ if (types.isArrowFunctionExpression(pipeline) && pipeline.params.length === 2 && types.isIdentifier(pipeline.params[1])) {
1909
+ const applyMapName = pipeline.params[1].name;
1910
+ types.traverseFast(pipeline.body, (node) => {
1911
+ if (types.isCallExpression(node) && types.isIdentifier(node.callee, { name: applyMapName })) {
1912
+ pipelineMapCount += 1;
1913
+ }
1914
+ });
1915
+ }
1916
+ if (pipelineMapCount > 0) {
1917
+ const candidate = {
1918
+ count: pipelineMapCount,
1919
+ stateIndex: state.index,
1920
+ updater
1921
+ };
1922
+ pendingMaps = pendingMaps[0]?.stateIndex === state.index ? [...pendingMaps, candidate] : [candidate];
1923
+ if (mappedReorderState !== state.index) mappedReorderState = void 0;
1924
+ continue;
1925
+ }
1926
+ }
1927
+ let containsMappedReorder = false;
1928
+ const reorderCalls = [];
1929
+ let structural = false;
1930
+ types.traverseFast(updater.body, (node) => {
1931
+ if (!types.isCallExpression(node) || !types.isIdentifier(node.callee)) return;
1932
+ if (node.callee.name === structuralReorderIdentifier.name || node.callee.name === structuralSortIdentifier.name) {
1933
+ structural = true;
1934
+ } else if (node.callee.name === mapReorderIdentifier.name) {
1935
+ containsMappedReorder = true;
1936
+ } else if (node.callee.name === reorderIdentifier.name) {
1937
+ reorderCalls.push({ call: node, kind: "reverse" });
1938
+ } else if (node.callee.name === sortIdentifier.name) {
1939
+ reorderCalls.push({ call: node, kind: "sort" });
1940
+ }
1941
+ });
1942
+ if (structural) {
1943
+ mappedReorderState = void 0;
1944
+ pendingMaps = [];
1945
+ continue;
1946
+ }
1947
+ const hasPendingMaps = pendingMaps.length > 0 && pendingMaps[0].stateIndex === state.index;
1948
+ if (containsMappedReorder && reorderCalls.length === 0) {
1949
+ mappedReorderState = pendingMaps.length === 0 ? state.index : void 0;
1950
+ pendingMaps = [];
1951
+ continue;
1952
+ }
1953
+ if (containsMappedReorder || reorderCalls.length === 0 || !hasPendingMaps && mappedReorderState !== state.index) {
1954
+ mappedReorderState = void 0;
1955
+ pendingMaps = [];
1956
+ continue;
1957
+ }
1958
+ if (hasPendingMaps) {
1959
+ for (const candidate of pendingMaps) {
1960
+ candidate.updater.body.callee = types.cloneNode(queuedMapPipelineIdentifier);
1961
+ mapCount += candidate.count;
1962
+ }
1963
+ }
1964
+ for (const { call, kind } of reorderCalls) {
1965
+ call.callee = types.cloneNode(mapReorderIdentifier);
1966
+ if (kind === "reverse") mapReorderCount += 1;
1967
+ else mapSortCount += 1;
1968
+ }
1969
+ mappedReorderState = state.index;
1970
+ pendingMaps = [];
1971
+ }
1001
1972
  }
1002
1973
  });
1003
1974
  return {
1004
1975
  root: file.program.body[0].expression,
1005
- count,
1006
- stateIndices
1976
+ mapCount,
1977
+ mapReorderCount,
1978
+ mapSortCount
1007
1979
  };
1008
1980
  }
1009
1981
  function rewriteKeyedArraySortHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
@@ -1061,7 +2033,7 @@ function rewriteKeyedArraySortHints(root, hintedStateIndices, statesBySetter, he
1061
2033
  stateIndices
1062
2034
  };
1063
2035
  }
1064
- function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, helperIdentifier) {
2036
+ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
1065
2037
  if (hintedStateIndices.size === 0) {
1066
2038
  return { root: types.cloneNode(root, true), count: 0, stateIndices: /* @__PURE__ */ new Set() };
1067
2039
  }
@@ -1080,14 +2052,13 @@ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, h
1080
2052
  if (!types.isArrowFunctionExpression(updater) || updater.async || updater.generator || updater.params.length !== 1 || !types.isIdentifier(updater.params[0]) || !types.isCallExpression(updater.body) || updater.body.arguments.length < 1 || updater.body.arguments.length > 2 || !types.isMemberExpression(updater.body.callee) || updater.body.callee.computed || !types.isIdentifier(updater.body.callee.object, { name: updater.params[0].name }) || !types.isIdentifier(updater.body.callee.property, { name: "slice" })) {
1081
2053
  return;
1082
2054
  }
1083
- const indexes = [];
2055
+ const bounds = [];
1084
2056
  for (const argument of updater.body.arguments) {
1085
2057
  if (!types.isExpression(argument)) return;
1086
- const value = staticSliceIndex(argument);
1087
- if (value === void 0) return;
1088
- indexes.push(value);
2058
+ if (validateKeyedArrayPositionExpression(argument, safeGlobals) !== void 0) return;
2059
+ bounds.push(argument);
1089
2060
  }
1090
- if (indexes.length === 1 && indexes[0] === 0) return;
2061
+ if (bounds.length === 1 && staticSliceIndex(bounds[0]) === 0) return;
1091
2062
  const previous = types.cloneNode(updater.params[0]);
1092
2063
  const sliceMethod = path.scope.generateUidIdentifier("farmSlice");
1093
2064
  path.node.arguments[0] = types.arrowFunctionExpression(
@@ -1103,7 +2074,7 @@ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, h
1103
2074
  types.callExpression(types.cloneNode(helperIdentifier), [
1104
2075
  types.cloneNode(previous),
1105
2076
  types.cloneNode(sliceMethod),
1106
- ...indexes.map((value) => types.numericLiteral(value))
2077
+ ...bounds.map((bound) => types.cloneNode(bound, true))
1107
2078
  ])
1108
2079
  )
1109
2080
  ])
@@ -4862,7 +5833,7 @@ function wrapperElement(definitionIdentifier, props) {
4862
5833
  const attributes = props ? [types.jsxSpreadAttribute(types.cloneNode(props))] : [];
4863
5834
  return types.jsxElement(types.jsxOpeningElement(name, attributes, true), null, [], true);
4864
5835
  }
4865
- function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateIdentifier, keyedArrayAppendIdentifier, keyedArrayFilterIdentifier, keyedArrayPrependIdentifier, keyedArrayPositionIdentifier, keyedArrayBatchInsertIdentifier, keyedArrayWindowReplaceIdentifier, keyedArrayReorderIdentifier, keyedArraySortIdentifier, keyedArrayRollingWindowIdentifier, keyedArraySliceIdentifier, keyedCollectionUpdateIdentifier, keyedCollectionMutationIdentifier, runtimeFeatureIdentifiers, usedRuntimeFeatures, optimizationCounts, compilerUsage, useStateNames, reactNames, listNames, moduleId, reactivity) {
5836
+ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateIdentifier, keyedArrayAppendIdentifier, keyedArrayFilterIdentifier, keyedArrayMapPipelineIdentifier, keyedArrayMappedStructuralAppendIdentifier, keyedArrayStructuralAppendMapPipelineIdentifier, keyedArrayMappedStructuralPrependIdentifier, keyedArrayStructuralPrependMapPipelineIdentifier, keyedArrayQueuedMapPipelineIdentifier, keyedArrayMapReorderIdentifier, keyedArrayMappedStructuralIdentifier, keyedArrayPrependIdentifier, keyedArrayPositionIdentifier, keyedArrayBatchInsertIdentifier, keyedArrayWindowReplaceIdentifier, keyedArrayReorderIdentifier, keyedArrayStructuralReorderIdentifier, keyedArraySortIdentifier, keyedArrayStructuralSortIdentifier, keyedArrayRollingWindowIdentifier, keyedArraySliceIdentifier, keyedCollectionUpdateIdentifier, keyedCollectionMutationIdentifier, runtimeFeatureIdentifiers, usedRuntimeFeatures, optimizationCounts, compilerUsage, useStateNames, reactNames, listNames, moduleId, reactivity) {
4866
5837
  const { path, name, statementPath } = candidate;
4867
5838
  if (path.node.async || path.node.generator)
4868
5839
  return "async and generator components are not supported";
@@ -5272,14 +6243,80 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5272
6243
  compilerUsage.keyedArrayWindowReplaceHints += positionHintedRoot.windowReplaceCount;
5273
6244
  }
5274
6245
  }
6246
+ const allowKeyedArrayMapPipelines = (blockAnalysis.plans || []).every(
6247
+ (plan) => plan.kind !== "keyed-rows" || plan.conditionals.length === 0 && !plan.descriptorBlocks?.size
6248
+ );
6249
+ const reorderPipelineHintedRoot = rewriteKeyedArrayReorderPipelineHints(
6250
+ expandedReactiveRoot,
6251
+ shiftedIndexIndependentStateIndices,
6252
+ statesBySetter,
6253
+ keyedArrayFilterIdentifier,
6254
+ keyedArrayMapPipelineIdentifier,
6255
+ keyedArrayMapReorderIdentifier,
6256
+ keyedArrayMappedStructuralIdentifier,
6257
+ keyedArrayReorderIdentifier,
6258
+ keyedArrayStructuralReorderIdentifier,
6259
+ keyedArraySliceIdentifier,
6260
+ keyedArraySortIdentifier,
6261
+ keyedArrayStructuralSortIdentifier,
6262
+ safeGlobals,
6263
+ allowKeyedArrayMapPipelines
6264
+ );
6265
+ let appliedPipelineFilterHints = 0;
6266
+ let appliedPipelineMapHints = 0;
6267
+ let appliedPipelineReorderHints = 0;
6268
+ let appliedPipelineSliceHints = 0;
6269
+ let appliedPipelineSortHints = 0;
6270
+ let appliedPipelineHintedStateIndices = /* @__PURE__ */ new Set();
6271
+ if (reorderPipelineHintedRoot.filterCount > 0 || reorderPipelineHintedRoot.reorderCount > 0 || reorderPipelineHintedRoot.sliceCount > 0 || reorderPipelineHintedRoot.sortCount > 0) {
6272
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6273
+ reorderPipelineHintedRoot.root,
6274
+ reactiveByValue,
6275
+ safeGlobals,
6276
+ listNames,
6277
+ allowedComponentNames
6278
+ );
6279
+ const hintedAnalysis = analyzeHostTree(
6280
+ reorderPipelineHintedRoot.root,
6281
+ reactiveByValue,
6282
+ safeGlobals,
6283
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6284
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6285
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6286
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6287
+ );
6288
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6289
+ expandedReactiveRoot = reorderPipelineHintedRoot.root;
6290
+ blockAnalysis = hintedBlockAnalysis;
6291
+ analysis = hintedAnalysis;
6292
+ appliedPipelineFilterHints = reorderPipelineHintedRoot.filterCount;
6293
+ appliedPipelineMapHints = reorderPipelineHintedRoot.mapCount;
6294
+ appliedKeyedMapUpdateHints += reorderPipelineHintedRoot.mapCount;
6295
+ appliedPipelineReorderHints = reorderPipelineHintedRoot.reorderCount + reorderPipelineHintedRoot.terminalStructuralPipelineCount;
6296
+ appliedPipelineSliceHints = reorderPipelineHintedRoot.sliceCount;
6297
+ appliedPipelineSortHints = reorderPipelineHintedRoot.sortCount;
6298
+ appliedPipelineHintedStateIndices = reorderPipelineHintedRoot.stateIndices;
6299
+ optimizationCounts.keyedArrayFilterHints += reorderPipelineHintedRoot.filterCount;
6300
+ optimizationCounts.keyedMapUpdateHints += reorderPipelineHintedRoot.mapCount;
6301
+ optimizationCounts.keyedArrayReorderHints += reorderPipelineHintedRoot.reorderCount;
6302
+ optimizationCounts.keyedArraySliceHints += reorderPipelineHintedRoot.sliceCount;
6303
+ optimizationCounts.keyedArraySortHints += reorderPipelineHintedRoot.sortCount;
6304
+ compilerUsage.keyedArrayStructuralReorderHints += reorderPipelineHintedRoot.structuralReorderCount;
6305
+ compilerUsage.keyedArrayStructuralSortHints += reorderPipelineHintedRoot.structuralSortCount;
6306
+ compilerUsage.keyedArrayMapUpdateHints += reorderPipelineHintedRoot.mapCount;
6307
+ compilerUsage.keyedArrayMapReorderHints += reorderPipelineHintedRoot.mapReorderCount;
6308
+ compilerUsage.keyedArrayMapSortHints += reorderPipelineHintedRoot.mapSortCount;
6309
+ compilerUsage.keyedArrayMappedStructuralHints += reorderPipelineHintedRoot.terminalStructuralPipelineCount;
6310
+ }
6311
+ }
5275
6312
  const reorderHintedRoot = rewriteKeyedArrayReorderHints(
5276
6313
  expandedReactiveRoot,
5277
6314
  shiftedIndexIndependentStateIndices,
5278
6315
  statesBySetter,
5279
6316
  keyedArrayReorderIdentifier
5280
6317
  );
5281
- let appliedKeyedArrayReorderHints = 0;
5282
- let appliedReorderHintedStateIndices = /* @__PURE__ */ new Set();
6318
+ let appliedKeyedArrayReorderHints = appliedPipelineReorderHints;
6319
+ let appliedReorderHintedStateIndices = appliedPipelineHintedStateIndices;
5283
6320
  if (reorderHintedRoot.count > 0) {
5284
6321
  const hintedBlockAnalysis = analyzeComposableBlocks(
5285
6322
  reorderHintedRoot.root,
@@ -5301,8 +6338,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5301
6338
  expandedReactiveRoot = reorderHintedRoot.root;
5302
6339
  blockAnalysis = hintedBlockAnalysis;
5303
6340
  analysis = hintedAnalysis;
5304
- appliedKeyedArrayReorderHints = reorderHintedRoot.count;
5305
- appliedReorderHintedStateIndices = reorderHintedRoot.stateIndices;
6341
+ appliedKeyedArrayReorderHints += reorderHintedRoot.count;
6342
+ appliedReorderHintedStateIndices = /* @__PURE__ */ new Set([
6343
+ ...appliedReorderHintedStateIndices,
6344
+ ...reorderHintedRoot.stateIndices
6345
+ ]);
5306
6346
  optimizationCounts.keyedArrayReorderHints += reorderHintedRoot.count;
5307
6347
  }
5308
6348
  }
@@ -5313,8 +6353,8 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5313
6353
  keyedArraySortIdentifier,
5314
6354
  safeGlobals
5315
6355
  );
5316
- let appliedKeyedArraySortHints = 0;
5317
- let appliedSortHintedStateIndices = /* @__PURE__ */ new Set();
6356
+ let appliedKeyedArraySortHints = appliedPipelineSortHints;
6357
+ let appliedSortHintedStateIndices = appliedPipelineHintedStateIndices;
5318
6358
  if (sortHintedRoot.count > 0) {
5319
6359
  const hintedBlockAnalysis = analyzeComposableBlocks(
5320
6360
  sortHintedRoot.root,
@@ -5336,8 +6376,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5336
6376
  expandedReactiveRoot = sortHintedRoot.root;
5337
6377
  blockAnalysis = hintedBlockAnalysis;
5338
6378
  analysis = hintedAnalysis;
5339
- appliedKeyedArraySortHints = sortHintedRoot.count;
5340
- appliedSortHintedStateIndices = sortHintedRoot.stateIndices;
6379
+ appliedKeyedArraySortHints += sortHintedRoot.count;
6380
+ appliedSortHintedStateIndices = /* @__PURE__ */ new Set([
6381
+ ...appliedSortHintedStateIndices,
6382
+ ...sortHintedRoot.stateIndices
6383
+ ]);
5341
6384
  optimizationCounts.keyedArraySortHints += sortHintedRoot.count;
5342
6385
  }
5343
6386
  }
@@ -5345,10 +6388,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5345
6388
  expandedReactiveRoot,
5346
6389
  shiftedIndexIndependentStateIndices,
5347
6390
  statesBySetter,
5348
- keyedArraySliceIdentifier
6391
+ keyedArraySliceIdentifier,
6392
+ safeGlobals
5349
6393
  );
5350
- let appliedKeyedArraySliceHints = 0;
5351
- let appliedSliceHintedStateIndices = /* @__PURE__ */ new Set();
6394
+ let appliedKeyedArraySliceHints = appliedPipelineSliceHints;
6395
+ let appliedSliceHintedStateIndices = appliedPipelineSliceHints > 0 ? appliedPipelineHintedStateIndices : /* @__PURE__ */ new Set();
5352
6396
  if (sliceHintedRoot.count > 0) {
5353
6397
  const hintedBlockAnalysis = analyzeComposableBlocks(
5354
6398
  sliceHintedRoot.root,
@@ -5370,8 +6414,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5370
6414
  expandedReactiveRoot = sliceHintedRoot.root;
5371
6415
  blockAnalysis = hintedBlockAnalysis;
5372
6416
  analysis = hintedAnalysis;
5373
- appliedKeyedArraySliceHints = sliceHintedRoot.count;
5374
- appliedSliceHintedStateIndices = sliceHintedRoot.stateIndices;
6417
+ appliedKeyedArraySliceHints += sliceHintedRoot.count;
6418
+ appliedSliceHintedStateIndices = /* @__PURE__ */ new Set([
6419
+ ...appliedSliceHintedStateIndices,
6420
+ ...sliceHintedRoot.stateIndices
6421
+ ]);
5375
6422
  optimizationCounts.keyedArraySliceHints += sliceHintedRoot.count;
5376
6423
  }
5377
6424
  }
@@ -5382,8 +6429,8 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5382
6429
  keyedArrayFilterIdentifier,
5383
6430
  safeGlobals
5384
6431
  );
5385
- let appliedKeyedArrayFilterHints = 0;
5386
- let appliedFilterHintedStateIndices = /* @__PURE__ */ new Set();
6432
+ let appliedKeyedArrayFilterHints = appliedPipelineFilterHints;
6433
+ let appliedFilterHintedStateIndices = appliedPipelineFilterHints > 0 ? appliedPipelineHintedStateIndices : /* @__PURE__ */ new Set();
5387
6434
  if (filterHintedRoot.count > 0) {
5388
6435
  const hintedBlockAnalysis = analyzeComposableBlocks(
5389
6436
  filterHintedRoot.root,
@@ -5405,11 +6452,243 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5405
6452
  expandedReactiveRoot = filterHintedRoot.root;
5406
6453
  blockAnalysis = hintedBlockAnalysis;
5407
6454
  analysis = hintedAnalysis;
5408
- appliedKeyedArrayFilterHints = filterHintedRoot.count;
5409
- appliedFilterHintedStateIndices = filterHintedRoot.stateIndices;
6455
+ appliedKeyedArrayFilterHints += filterHintedRoot.count;
6456
+ appliedFilterHintedStateIndices = /* @__PURE__ */ new Set([
6457
+ ...appliedFilterHintedStateIndices,
6458
+ ...filterHintedRoot.stateIndices
6459
+ ]);
5410
6460
  optimizationCounts.keyedArrayFilterHints += filterHintedRoot.count;
5411
6461
  }
5412
6462
  }
6463
+ const queuedMappedStructuralHintedRoot = rewriteQueuedKeyedArrayMappedStructuralHints(
6464
+ expandedReactiveRoot,
6465
+ statesBySetter,
6466
+ keyedMapUpdateIdentifier,
6467
+ keyedArrayQueuedMapPipelineIdentifier,
6468
+ keyedArrayMappedStructuralIdentifier,
6469
+ keyedArrayFilterIdentifier,
6470
+ keyedArraySliceIdentifier,
6471
+ allowKeyedArrayMapPipelines
6472
+ );
6473
+ let appliedQueuedMappedStructuralHints = 0;
6474
+ if (queuedMappedStructuralHintedRoot.mapCount > 0 && queuedMappedStructuralHintedRoot.structuralCount > 0) {
6475
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6476
+ queuedMappedStructuralHintedRoot.root,
6477
+ reactiveByValue,
6478
+ safeGlobals,
6479
+ listNames,
6480
+ allowedComponentNames
6481
+ );
6482
+ const hintedAnalysis = analyzeHostTree(
6483
+ queuedMappedStructuralHintedRoot.root,
6484
+ reactiveByValue,
6485
+ safeGlobals,
6486
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6487
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6488
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6489
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6490
+ );
6491
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6492
+ expandedReactiveRoot = queuedMappedStructuralHintedRoot.root;
6493
+ blockAnalysis = hintedBlockAnalysis;
6494
+ analysis = hintedAnalysis;
6495
+ appliedQueuedMappedStructuralHints = queuedMappedStructuralHintedRoot.mapCount + queuedMappedStructuralHintedRoot.structuralCount;
6496
+ appliedKeyedArrayReorderHints += queuedMappedStructuralHintedRoot.structuralCount;
6497
+ appliedReorderHintedStateIndices = /* @__PURE__ */ new Set([
6498
+ ...appliedReorderHintedStateIndices,
6499
+ ...queuedMappedStructuralHintedRoot.stateIndices
6500
+ ]);
6501
+ compilerUsage.keyedArrayMapUpdateHints += queuedMappedStructuralHintedRoot.mapCount;
6502
+ compilerUsage.keyedArrayQueuedMapUpdateHints += queuedMappedStructuralHintedRoot.mapCount;
6503
+ compilerUsage.keyedArrayMappedStructuralHints += queuedMappedStructuralHintedRoot.structuralCount;
6504
+ }
6505
+ }
6506
+ const queuedStructuralMapHintedRoot = rewriteQueuedKeyedArrayStructuralMapHints(
6507
+ expandedReactiveRoot,
6508
+ statesBySetter,
6509
+ keyedMapUpdateIdentifier,
6510
+ keyedArrayMapPipelineIdentifier,
6511
+ keyedArrayAppendIdentifier,
6512
+ keyedArrayMappedStructuralAppendIdentifier,
6513
+ keyedArrayStructuralAppendMapPipelineIdentifier,
6514
+ keyedArrayFilterIdentifier,
6515
+ keyedArraySliceIdentifier,
6516
+ keyedArrayMappedStructuralIdentifier,
6517
+ allowKeyedArrayMapPipelines
6518
+ );
6519
+ let appliedQueuedStructuralMapHints = 0;
6520
+ let appliedQueuedStructuralAppendMapHints = 0;
6521
+ if (queuedStructuralMapHintedRoot.mapCount > 0 || queuedStructuralMapHintedRoot.mappedStructuralAppendCount > 0) {
6522
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6523
+ queuedStructuralMapHintedRoot.root,
6524
+ reactiveByValue,
6525
+ safeGlobals,
6526
+ listNames,
6527
+ allowedComponentNames
6528
+ );
6529
+ const hintedAnalysis = analyzeHostTree(
6530
+ queuedStructuralMapHintedRoot.root,
6531
+ reactiveByValue,
6532
+ safeGlobals,
6533
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6534
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6535
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6536
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6537
+ );
6538
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6539
+ expandedReactiveRoot = queuedStructuralMapHintedRoot.root;
6540
+ blockAnalysis = hintedBlockAnalysis;
6541
+ analysis = hintedAnalysis;
6542
+ appliedQueuedStructuralMapHints = queuedStructuralMapHintedRoot.mapCount;
6543
+ appliedQueuedStructuralAppendMapHints = queuedStructuralMapHintedRoot.structuralAppendMapCount + queuedStructuralMapHintedRoot.mappedStructuralAppendCount;
6544
+ appliedKeyedArrayReorderHints += queuedStructuralMapHintedRoot.mapCount;
6545
+ appliedReorderHintedStateIndices = /* @__PURE__ */ new Set([
6546
+ ...appliedReorderHintedStateIndices,
6547
+ ...queuedStructuralMapHintedRoot.stateIndices
6548
+ ]);
6549
+ compilerUsage.keyedArrayMapUpdateHints += queuedStructuralMapHintedRoot.mapCount;
6550
+ compilerUsage.keyedArrayMappedStructuralAppendHints += queuedStructuralMapHintedRoot.mappedStructuralAppendCount;
6551
+ compilerUsage.keyedArrayStructuralAppendMapHints += queuedStructuralMapHintedRoot.structuralAppendMapCount;
6552
+ }
6553
+ }
6554
+ const queuedStructuralPrependMapHintedRoot = rewriteQueuedKeyedArrayStructuralPrependMapHints(
6555
+ expandedReactiveRoot,
6556
+ statesBySetter,
6557
+ keyedMapUpdateIdentifier,
6558
+ keyedArrayMapPipelineIdentifier,
6559
+ keyedArrayPrependIdentifier,
6560
+ keyedArrayMappedStructuralPrependIdentifier,
6561
+ keyedArrayStructuralPrependMapPipelineIdentifier,
6562
+ keyedArrayFilterIdentifier,
6563
+ keyedArraySliceIdentifier,
6564
+ keyedArrayMappedStructuralIdentifier,
6565
+ allowKeyedArrayMapPipelines
6566
+ );
6567
+ let appliedQueuedStructuralPrependMapHints = 0;
6568
+ if (queuedStructuralPrependMapHintedRoot.structuralPrependMapCount > 0 || queuedStructuralPrependMapHintedRoot.mappedStructuralPrependCount > 0) {
6569
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6570
+ queuedStructuralPrependMapHintedRoot.root,
6571
+ reactiveByValue,
6572
+ safeGlobals,
6573
+ listNames,
6574
+ allowedComponentNames
6575
+ );
6576
+ const hintedAnalysis = analyzeHostTree(
6577
+ queuedStructuralPrependMapHintedRoot.root,
6578
+ reactiveByValue,
6579
+ safeGlobals,
6580
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6581
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6582
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6583
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6584
+ );
6585
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6586
+ expandedReactiveRoot = queuedStructuralPrependMapHintedRoot.root;
6587
+ blockAnalysis = hintedBlockAnalysis;
6588
+ analysis = hintedAnalysis;
6589
+ appliedQueuedStructuralPrependMapHints = queuedStructuralPrependMapHintedRoot.structuralPrependMapCount + queuedStructuralPrependMapHintedRoot.mappedStructuralPrependCount;
6590
+ compilerUsage.keyedArrayMappedStructuralPrependHints += queuedStructuralPrependMapHintedRoot.mappedStructuralPrependCount;
6591
+ compilerUsage.keyedArrayStructuralPrependMapHints += queuedStructuralPrependMapHintedRoot.structuralPrependMapCount;
6592
+ }
6593
+ }
6594
+ const queuedMapReorderHintedRoot = rewriteQueuedKeyedArrayMapReorderHints(
6595
+ expandedReactiveRoot,
6596
+ statesBySetter,
6597
+ keyedMapUpdateIdentifier,
6598
+ keyedArrayQueuedMapPipelineIdentifier,
6599
+ keyedArrayMapReorderIdentifier,
6600
+ keyedArrayReorderIdentifier,
6601
+ keyedArraySortIdentifier,
6602
+ keyedArrayStructuralReorderIdentifier,
6603
+ keyedArrayStructuralSortIdentifier,
6604
+ allowKeyedArrayMapPipelines
6605
+ );
6606
+ const queuedReorderMapHintedRoot = rewriteQueuedKeyedArrayReorderMapHints(
6607
+ queuedMapReorderHintedRoot.root,
6608
+ statesBySetter,
6609
+ keyedMapUpdateIdentifier,
6610
+ keyedArrayQueuedMapPipelineIdentifier,
6611
+ keyedArrayMapReorderIdentifier,
6612
+ keyedArrayReorderIdentifier,
6613
+ keyedArraySortIdentifier,
6614
+ keyedArrayStructuralReorderIdentifier,
6615
+ keyedArrayStructuralSortIdentifier,
6616
+ allowKeyedArrayMapPipelines
6617
+ );
6618
+ let appliedQueuedReorderMapHints = 0;
6619
+ const queuedMapCount = queuedMapReorderHintedRoot.mapCount + queuedReorderMapHintedRoot.mapCount;
6620
+ const queuedMapReorderCount = queuedMapReorderHintedRoot.mapReorderCount + queuedMapReorderHintedRoot.mapSortCount;
6621
+ if (queuedMapCount > 0 || queuedMapReorderCount > 0) {
6622
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6623
+ queuedReorderMapHintedRoot.root,
6624
+ reactiveByValue,
6625
+ safeGlobals,
6626
+ listNames,
6627
+ allowedComponentNames
6628
+ );
6629
+ const hintedAnalysis = analyzeHostTree(
6630
+ queuedReorderMapHintedRoot.root,
6631
+ reactiveByValue,
6632
+ safeGlobals,
6633
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6634
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6635
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6636
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6637
+ );
6638
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6639
+ expandedReactiveRoot = queuedReorderMapHintedRoot.root;
6640
+ blockAnalysis = hintedBlockAnalysis;
6641
+ analysis = hintedAnalysis;
6642
+ appliedQueuedReorderMapHints = queuedMapCount + queuedMapReorderCount;
6643
+ compilerUsage.keyedArrayMapUpdateHints += queuedMapCount;
6644
+ compilerUsage.keyedArrayQueuedMapUpdateHints += queuedMapCount;
6645
+ compilerUsage.keyedArrayMapReorderHints += queuedMapReorderHintedRoot.mapReorderCount;
6646
+ compilerUsage.keyedArrayMapSortHints += queuedMapReorderHintedRoot.mapSortCount;
6647
+ }
6648
+ }
6649
+ const queuedStructuralReorderHintedRoot = rewriteQueuedKeyedArrayStructuralReorderHints(
6650
+ expandedReactiveRoot,
6651
+ statesBySetter,
6652
+ keyedArrayFilterIdentifier,
6653
+ keyedArraySliceIdentifier,
6654
+ keyedArrayMapPipelineIdentifier,
6655
+ keyedArrayQueuedMapPipelineIdentifier,
6656
+ keyedArrayMappedStructuralIdentifier,
6657
+ keyedArrayMapReorderIdentifier,
6658
+ keyedArrayReorderIdentifier,
6659
+ keyedArraySortIdentifier,
6660
+ keyedArrayStructuralReorderIdentifier,
6661
+ keyedArrayStructuralSortIdentifier,
6662
+ allowKeyedArrayMapPipelines
6663
+ );
6664
+ if (queuedStructuralReorderHintedRoot.reorderCount > 0 || queuedStructuralReorderHintedRoot.sortCount > 0 || queuedStructuralReorderHintedRoot.replacedQueuedMapCount > 0) {
6665
+ const hintedBlockAnalysis = analyzeComposableBlocks(
6666
+ queuedStructuralReorderHintedRoot.root,
6667
+ reactiveByValue,
6668
+ safeGlobals,
6669
+ listNames,
6670
+ allowedComponentNames
6671
+ );
6672
+ const hintedAnalysis = analyzeHostTree(
6673
+ queuedStructuralReorderHintedRoot.root,
6674
+ reactiveByValue,
6675
+ safeGlobals,
6676
+ hintedBlockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
6677
+ hintedBlockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
6678
+ hintedBlockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
6679
+ hintedBlockAnalysis.componentElements || /* @__PURE__ */ new Set()
6680
+ );
6681
+ if (!hintedBlockAnalysis.reason && !hintedAnalysis.reason) {
6682
+ expandedReactiveRoot = queuedStructuralReorderHintedRoot.root;
6683
+ blockAnalysis = hintedBlockAnalysis;
6684
+ analysis = hintedAnalysis;
6685
+ compilerUsage.keyedArrayQueuedMapUpdateHints -= queuedStructuralReorderHintedRoot.replacedQueuedMapCount;
6686
+ compilerUsage.keyedArrayMapReorderHints -= queuedStructuralReorderHintedRoot.replacedMapReorderCount;
6687
+ compilerUsage.keyedArrayMapSortHints -= queuedStructuralReorderHintedRoot.replacedMapSortCount;
6688
+ compilerUsage.keyedArrayStructuralReorderHints += queuedStructuralReorderHintedRoot.reorderCount;
6689
+ compilerUsage.keyedArrayStructuralSortHints += queuedStructuralReorderHintedRoot.sortCount;
6690
+ }
6691
+ }
5413
6692
  const keyedCollectionTargetKinds = /* @__PURE__ */ new Map();
5414
6693
  const conflictingKeyedCollectionTargets = /* @__PURE__ */ new Set();
5415
6694
  for (const plan of blockAnalysis.plans || []) {
@@ -5481,11 +6760,16 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5481
6760
  blockPlans,
5482
6761
  hasKeyedUpdateHints,
5483
6762
  hasKeyedArrayRemovalHints,
6763
+ appliedKeyedArrayAppendHints > 0 && (appliedKeyedArrayFilterHints > 0 || appliedKeyedArraySliceHints > 0),
6764
+ appliedQueuedStructuralAppendMapHints > 0,
5484
6765
  appliedKeyedArrayPrependHints > 0,
6766
+ appliedKeyedArrayPrependHints > 0 && hasKeyedArrayRemovalHints,
6767
+ appliedQueuedStructuralPrependMapHints > 0,
5485
6768
  appliedKeyedArrayPositionHints > 0,
5486
6769
  appliedKeyedArrayBatchInsertHints > 0,
5487
6770
  appliedKeyedArrayWindowReplaceHints > 0,
5488
6771
  appliedKeyedArrayReorderHints > 0 || appliedKeyedArraySortHints > 0,
6772
+ appliedPipelineMapHints > 0 || appliedQueuedReorderMapHints > 0 || appliedQueuedMappedStructuralHints > 0 || appliedQueuedStructuralMapHints > 0,
5489
6773
  appliedKeyedArrayRollingWindowHints > 0
5490
6774
  );
5491
6775
  markShortCircuitBindings(analysis.bindings || []);
@@ -5669,6 +6953,17 @@ async function compileReactModule(code, id, options) {
5669
6953
  };
5670
6954
  const compilerUsage = {
5671
6955
  keyedArrayBatchInsertHints: 0,
6956
+ keyedArrayMapReorderHints: 0,
6957
+ keyedArrayMapSortHints: 0,
6958
+ keyedArrayMapUpdateHints: 0,
6959
+ keyedArrayMappedStructuralHints: 0,
6960
+ keyedArrayMappedStructuralAppendHints: 0,
6961
+ keyedArrayMappedStructuralPrependHints: 0,
6962
+ keyedArrayQueuedMapUpdateHints: 0,
6963
+ keyedArrayStructuralAppendMapHints: 0,
6964
+ keyedArrayStructuralPrependMapHints: 0,
6965
+ keyedArrayStructuralReorderHints: 0,
6966
+ keyedArrayStructuralSortHints: 0,
5672
6967
  keyedArrayWindowReplaceHints: 0
5673
6968
  };
5674
6969
  const plugin = () => ({
@@ -5709,6 +7004,30 @@ async function compileReactModule(code, id, options) {
5709
7004
  const keyedArrayFilterIdentifier = programPath.scope.generateUidIdentifier(
5710
7005
  "createCompilerKeyedArrayFilter"
5711
7006
  );
7007
+ const keyedArrayMapPipelineIdentifier = programPath.scope.generateUidIdentifier(
7008
+ "createCompilerKeyedArrayMapPipeline"
7009
+ );
7010
+ const keyedArrayMappedStructuralAppendIdentifier = programPath.scope.generateUidIdentifier(
7011
+ "createCompilerKeyedArrayMappedStructuralAppend"
7012
+ );
7013
+ const keyedArrayStructuralAppendMapPipelineIdentifier = programPath.scope.generateUidIdentifier(
7014
+ "createCompilerKeyedArrayStructuralAppendMapPipeline"
7015
+ );
7016
+ const keyedArrayMappedStructuralPrependIdentifier = programPath.scope.generateUidIdentifier(
7017
+ "createCompilerKeyedArrayMappedStructuralPrepend"
7018
+ );
7019
+ const keyedArrayStructuralPrependMapPipelineIdentifier = programPath.scope.generateUidIdentifier(
7020
+ "createCompilerKeyedArrayStructuralPrependMapPipeline"
7021
+ );
7022
+ const keyedArrayQueuedMapPipelineIdentifier = programPath.scope.generateUidIdentifier(
7023
+ "createCompilerKeyedArrayQueuedMapPipeline"
7024
+ );
7025
+ const keyedArrayMapReorderIdentifier = programPath.scope.generateUidIdentifier(
7026
+ "createCompilerKeyedArrayMapReorder"
7027
+ );
7028
+ const keyedArrayMappedStructuralIdentifier = programPath.scope.generateUidIdentifier(
7029
+ "finalizeCompilerKeyedArrayMappedStructuralUpdate"
7030
+ );
5712
7031
  const keyedArrayPrependIdentifier = programPath.scope.generateUidIdentifier(
5713
7032
  "createCompilerKeyedArrayPrepend"
5714
7033
  );
@@ -5724,9 +7043,15 @@ async function compileReactModule(code, id, options) {
5724
7043
  const keyedArrayReorderIdentifier = programPath.scope.generateUidIdentifier(
5725
7044
  "createCompilerKeyedArrayReorder"
5726
7045
  );
7046
+ const keyedArrayStructuralReorderIdentifier = programPath.scope.generateUidIdentifier(
7047
+ "createCompilerKeyedArrayStructuralReorder"
7048
+ );
5727
7049
  const keyedArraySortIdentifier = programPath.scope.generateUidIdentifier(
5728
7050
  "createCompilerKeyedArraySort"
5729
7051
  );
7052
+ const keyedArrayStructuralSortIdentifier = programPath.scope.generateUidIdentifier(
7053
+ "createCompilerKeyedArrayStructuralSort"
7054
+ );
5730
7055
  const keyedArrayRollingWindowIdentifier = programPath.scope.generateUidIdentifier(
5731
7056
  "createCompilerKeyedArrayRollingWindow"
5732
7057
  );
@@ -5759,12 +7084,22 @@ async function compileReactModule(code, id, options) {
5759
7084
  keyedMapUpdateIdentifier,
5760
7085
  keyedArrayAppendIdentifier,
5761
7086
  keyedArrayFilterIdentifier,
7087
+ keyedArrayMapPipelineIdentifier,
7088
+ keyedArrayMappedStructuralAppendIdentifier,
7089
+ keyedArrayStructuralAppendMapPipelineIdentifier,
7090
+ keyedArrayMappedStructuralPrependIdentifier,
7091
+ keyedArrayStructuralPrependMapPipelineIdentifier,
7092
+ keyedArrayQueuedMapPipelineIdentifier,
7093
+ keyedArrayMapReorderIdentifier,
7094
+ keyedArrayMappedStructuralIdentifier,
5762
7095
  keyedArrayPrependIdentifier,
5763
7096
  keyedArrayPositionIdentifier,
5764
7097
  keyedArrayBatchInsertIdentifier,
5765
7098
  keyedArrayWindowReplaceIdentifier,
5766
7099
  keyedArrayReorderIdentifier,
7100
+ keyedArrayStructuralReorderIdentifier,
5767
7101
  keyedArraySortIdentifier,
7102
+ keyedArrayStructuralSortIdentifier,
5768
7103
  keyedArrayRollingWindowIdentifier,
5769
7104
  keyedArraySliceIdentifier,
5770
7105
  keyedCollectionUpdateIdentifier,
@@ -5789,6 +7124,12 @@ async function compileReactModule(code, id, options) {
5789
7124
  compiled.push(candidate.name);
5790
7125
  }
5791
7126
  }
7127
+ const hasEagerKeyedArrayMapUpdateHints = compilerUsage.keyedArrayMapUpdateHints > compilerUsage.keyedArrayQueuedMapUpdateHints + compilerUsage.keyedArrayStructuralAppendMapHints + compilerUsage.keyedArrayStructuralPrependMapHints;
7128
+ const hasKeyedArrayMapReorderHints = compilerUsage.keyedArrayMapReorderHints + compilerUsage.keyedArrayMapSortHints > 0;
7129
+ const hasKeyedArrayStructuralAppendHints = optimizationCounts.keyedArrayAppendHints > 0 && (optimizationCounts.keyedArrayFilterHints > 0 || optimizationCounts.keyedArraySliceHints > 0);
7130
+ const hasUnmappedKeyedArrayAppendHints = optimizationCounts.keyedArrayAppendHints > compilerUsage.keyedArrayMappedStructuralAppendHints;
7131
+ const hasKeyedArrayStructuralPrependHints = optimizationCounts.keyedArrayPrependHints > 0 && (optimizationCounts.keyedArrayFilterHints > 0 || optimizationCounts.keyedArraySliceHints > 0);
7132
+ const hasUnmappedKeyedArrayPrependHints = optimizationCounts.keyedArrayPrependHints > compilerUsage.keyedArrayMappedStructuralPrependHints;
5792
7133
  if (compiled.length > 0) {
5793
7134
  programPath.unshiftContainer(
5794
7135
  "body",
@@ -5798,16 +7139,66 @@ async function compileReactModule(code, id, options) {
5798
7139
  createComponentIdentifier,
5799
7140
  types.identifier("createCompiledComponentWithFeatures")
5800
7141
  ),
5801
- ...optimizationCounts.keyedMapUpdateHints > 0 ? [
7142
+ ...optimizationCounts.keyedMapUpdateHints > compilerUsage.keyedArrayMapUpdateHints ? [
5802
7143
  types.importSpecifier(
5803
7144
  keyedMapUpdateIdentifier,
5804
7145
  types.identifier("createCompilerKeyedMapUpdate")
5805
7146
  )
5806
7147
  ] : [],
5807
- ...optimizationCounts.keyedArrayAppendHints > 0 ? [
7148
+ ...hasEagerKeyedArrayMapUpdateHints ? [
7149
+ types.importSpecifier(
7150
+ keyedArrayMapPipelineIdentifier,
7151
+ types.identifier("createCompilerKeyedArrayMapPipeline")
7152
+ )
7153
+ ] : [],
7154
+ ...compilerUsage.keyedArrayStructuralAppendMapHints > 0 ? [
7155
+ types.importSpecifier(
7156
+ keyedArrayStructuralAppendMapPipelineIdentifier,
7157
+ types.identifier("createCompilerKeyedArrayStructuralAppendMapPipeline")
7158
+ )
7159
+ ] : [],
7160
+ ...compilerUsage.keyedArrayStructuralPrependMapHints > 0 ? [
7161
+ types.importSpecifier(
7162
+ keyedArrayStructuralPrependMapPipelineIdentifier,
7163
+ types.identifier("createCompilerKeyedArrayStructuralPrependMapPipeline")
7164
+ )
7165
+ ] : [],
7166
+ ...hasKeyedArrayMapReorderHints ? [
7167
+ types.importSpecifier(
7168
+ keyedArrayMapReorderIdentifier,
7169
+ types.identifier("createCompilerKeyedArrayMapReorder")
7170
+ )
7171
+ ] : [],
7172
+ ...compilerUsage.keyedArrayMappedStructuralHints > 0 ? [
7173
+ types.importSpecifier(
7174
+ keyedArrayMappedStructuralIdentifier,
7175
+ types.identifier("finalizeCompilerKeyedArrayMappedStructuralUpdate")
7176
+ )
7177
+ ] : [],
7178
+ ...compilerUsage.keyedArrayMappedStructuralAppendHints > 0 ? [
7179
+ types.importSpecifier(
7180
+ keyedArrayMappedStructuralAppendIdentifier,
7181
+ types.identifier("createCompilerKeyedArrayMappedStructuralAppend")
7182
+ )
7183
+ ] : [],
7184
+ ...compilerUsage.keyedArrayMappedStructuralPrependHints > 0 ? [
7185
+ types.importSpecifier(
7186
+ keyedArrayMappedStructuralPrependIdentifier,
7187
+ types.identifier("createCompilerKeyedArrayMappedStructuralPrepend")
7188
+ )
7189
+ ] : [],
7190
+ ...compilerUsage.keyedArrayQueuedMapUpdateHints > 0 ? [
7191
+ types.importSpecifier(
7192
+ keyedArrayQueuedMapPipelineIdentifier,
7193
+ types.identifier("createCompilerKeyedArrayQueuedMapPipeline")
7194
+ )
7195
+ ] : [],
7196
+ ...hasUnmappedKeyedArrayAppendHints ? [
5808
7197
  types.importSpecifier(
5809
7198
  keyedArrayAppendIdentifier,
5810
- types.identifier("createCompilerKeyedArrayAppend")
7199
+ types.identifier(
7200
+ hasKeyedArrayStructuralAppendHints ? "createCompilerKeyedArrayStructuralAppend" : "createCompilerKeyedArrayAppend"
7201
+ )
5811
7202
  )
5812
7203
  ] : [],
5813
7204
  ...optimizationCounts.keyedArrayFilterHints > 0 ? [
@@ -5816,10 +7207,12 @@ async function compileReactModule(code, id, options) {
5816
7207
  types.identifier("createCompilerKeyedArrayFilter")
5817
7208
  )
5818
7209
  ] : [],
5819
- ...optimizationCounts.keyedArrayPrependHints > 0 ? [
7210
+ ...hasUnmappedKeyedArrayPrependHints ? [
5820
7211
  types.importSpecifier(
5821
7212
  keyedArrayPrependIdentifier,
5822
- types.identifier("createCompilerKeyedArrayPrepend")
7213
+ types.identifier(
7214
+ hasKeyedArrayStructuralPrependHints ? "createCompilerKeyedArrayStructuralPrepend" : "createCompilerKeyedArrayPrepend"
7215
+ )
5823
7216
  )
5824
7217
  ] : [],
5825
7218
  ...optimizationCounts.keyedArrayPositionHints > compilerUsage.keyedArrayBatchInsertHints + compilerUsage.keyedArrayWindowReplaceHints ? [
@@ -5840,18 +7233,30 @@ async function compileReactModule(code, id, options) {
5840
7233
  types.identifier("createCompilerKeyedArrayWindowReplace")
5841
7234
  )
5842
7235
  ] : [],
5843
- ...optimizationCounts.keyedArrayReorderHints > 0 ? [
7236
+ ...optimizationCounts.keyedArrayReorderHints > compilerUsage.keyedArrayStructuralReorderHints + compilerUsage.keyedArrayMapReorderHints ? [
5844
7237
  types.importSpecifier(
5845
7238
  keyedArrayReorderIdentifier,
5846
7239
  types.identifier("createCompilerKeyedArrayReorder")
5847
7240
  )
5848
7241
  ] : [],
5849
- ...optimizationCounts.keyedArraySortHints > 0 ? [
7242
+ ...compilerUsage.keyedArrayStructuralReorderHints > 0 ? [
7243
+ types.importSpecifier(
7244
+ keyedArrayStructuralReorderIdentifier,
7245
+ types.identifier("createCompilerKeyedArrayStructuralReorder")
7246
+ )
7247
+ ] : [],
7248
+ ...optimizationCounts.keyedArraySortHints > compilerUsage.keyedArrayStructuralSortHints + compilerUsage.keyedArrayMapSortHints ? [
5850
7249
  types.importSpecifier(
5851
7250
  keyedArraySortIdentifier,
5852
7251
  types.identifier("createCompilerKeyedArraySort")
5853
7252
  )
5854
7253
  ] : [],
7254
+ ...compilerUsage.keyedArrayStructuralSortHints > 0 ? [
7255
+ types.importSpecifier(
7256
+ keyedArrayStructuralSortIdentifier,
7257
+ types.identifier("createCompilerKeyedArrayStructuralSort")
7258
+ )
7259
+ ] : [],
5855
7260
  ...optimizationCounts.keyedArrayRollingWindowHints > 0 ? [
5856
7261
  types.importSpecifier(
5857
7262
  keyedArrayRollingWindowIdentifier,
@@ -5992,12 +7397,46 @@ function createReactCompilerReport(projectRoot, observations) {
5992
7397
  }
5993
7398
  async function writeReactCompilerReport(projectRoot, reportFile, observations) {
5994
7399
  const outputPath = resolve(projectRoot, reportFile);
7400
+ await assertReportPathInsideProject(projectRoot, outputPath);
5995
7401
  const report = createReactCompilerReport(projectRoot, observations);
5996
7402
  await mkdir(dirname(outputPath), { recursive: true });
5997
7403
  await writeFile(outputPath, `${JSON.stringify(report, null, 2)}
5998
7404
  `, "utf8");
5999
7405
  return outputPath;
6000
7406
  }
7407
+ async function assertReportPathInsideProject(projectRoot, outputPath) {
7408
+ const realProjectRoot = await realpath(projectRoot);
7409
+ let existingAncestor = outputPath;
7410
+ while (true) {
7411
+ try {
7412
+ existingAncestor = await realpath(existingAncestor);
7413
+ break;
7414
+ } catch (error) {
7415
+ if (error.code !== "ENOENT") throw error;
7416
+ let existingEntry = false;
7417
+ try {
7418
+ await lstat(existingAncestor);
7419
+ existingEntry = true;
7420
+ } catch (statError) {
7421
+ if (statError.code !== "ENOENT") throw statError;
7422
+ }
7423
+ if (existingEntry) {
7424
+ throw new Error(
7425
+ "The React compiler report file must stay inside the project root, including through symlinks."
7426
+ );
7427
+ }
7428
+ const parent = dirname(existingAncestor);
7429
+ if (parent === existingAncestor) throw error;
7430
+ existingAncestor = parent;
7431
+ }
7432
+ }
7433
+ const relativePath = relative(realProjectRoot, existingAncestor);
7434
+ if (relativePath === ".." || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)) {
7435
+ throw new Error(
7436
+ "The React compiler report file must stay inside the project root, including through symlinks."
7437
+ );
7438
+ }
7439
+ }
6001
7440
 
6002
7441
  // src/index.ts
6003
7442
  var DEFAULT_COMPILER_DIRECTIVE = "use compiler";