@farm.js/react 0.1.0-beta.7 → 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([
@@ -68,44 +68,77 @@ var COMPILER_RUNTIME_FEATURE_EXPORTS = {
68
68
  "keyed-rows": "keyedRowsRuntimeFeature",
69
69
  "keyed-rows-hinted": "keyedRowsHintedRuntimeFeature",
70
70
  "keyed-rows-position-hinted": "keyedRowsPositionHintedRuntimeFeature",
71
+ "keyed-rows-batch-position-hinted": "keyedRowsBatchPositionHintedRuntimeFeature",
72
+ "keyed-rows-window-position-hinted": "keyedRowsWindowPositionHintedRuntimeFeature",
71
73
  "keyed-rows-reorder-hinted": "keyedRowsReorderHintedRuntimeFeature",
74
+ "keyed-rows-map-reorder-hinted": "keyedRowsMapReorderHintedRuntimeFeature",
72
75
  "keyed-rows-all-hinted": "keyedRowsAllHintedRuntimeFeature",
73
76
  "keyed-rows-every-hinted": "keyedRowsEveryHintedRuntimeFeature",
77
+ "keyed-rows-batch-every-hinted": "keyedRowsBatchEveryHintedRuntimeFeature",
78
+ "keyed-rows-window-every-hinted": "keyedRowsWindowEveryHintedRuntimeFeature",
74
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",
75
84
  "keyed-rows-prepend-hinted": "keyedRowsPrependHintedRuntimeFeature",
76
85
  "keyed-rows-filter-prepend-hinted": "keyedRowsFilterPrependHintedRuntimeFeature",
77
86
  "keyed-rows-conditional": "keyedRowsConditionalRuntimeFeature",
78
87
  "keyed-rows-conditional-hinted": "keyedRowsConditionalHintedRuntimeFeature",
79
88
  "keyed-rows-conditional-position-hinted": "keyedRowsConditionalPositionHintedRuntimeFeature",
89
+ "keyed-rows-conditional-batch-position-hinted": "keyedRowsConditionalBatchPositionHintedRuntimeFeature",
90
+ "keyed-rows-conditional-window-position-hinted": "keyedRowsConditionalWindowPositionHintedRuntimeFeature",
80
91
  "keyed-rows-conditional-reorder-hinted": "keyedRowsConditionalReorderHintedRuntimeFeature",
81
92
  "keyed-rows-conditional-all-hinted": "keyedRowsConditionalAllHintedRuntimeFeature",
82
93
  "keyed-rows-conditional-every-hinted": "keyedRowsConditionalEveryHintedRuntimeFeature",
94
+ "keyed-rows-conditional-batch-every-hinted": "keyedRowsConditionalBatchEveryHintedRuntimeFeature",
95
+ "keyed-rows-conditional-window-every-hinted": "keyedRowsConditionalWindowEveryHintedRuntimeFeature",
83
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",
84
101
  "keyed-rows-conditional-prepend-hinted": "keyedRowsConditionalPrependHintedRuntimeFeature",
85
102
  "keyed-rows-conditional-filter-prepend-hinted": "keyedRowsConditionalFilterPrependHintedRuntimeFeature",
86
103
  "keyed-rows-host": "keyedRowsHostRuntimeFeature",
87
104
  "keyed-rows-host-hinted": "keyedRowsHostHintedRuntimeFeature",
88
105
  "keyed-rows-host-position-hinted": "keyedRowsHostPositionHintedRuntimeFeature",
106
+ "keyed-rows-host-batch-position-hinted": "keyedRowsHostBatchPositionHintedRuntimeFeature",
107
+ "keyed-rows-host-window-position-hinted": "keyedRowsHostWindowPositionHintedRuntimeFeature",
89
108
  "keyed-rows-host-reorder-hinted": "keyedRowsHostReorderHintedRuntimeFeature",
90
109
  "keyed-rows-host-all-hinted": "keyedRowsHostAllHintedRuntimeFeature",
91
110
  "keyed-rows-host-every-hinted": "keyedRowsHostEveryHintedRuntimeFeature",
111
+ "keyed-rows-host-batch-every-hinted": "keyedRowsHostBatchEveryHintedRuntimeFeature",
112
+ "keyed-rows-host-window-every-hinted": "keyedRowsHostWindowEveryHintedRuntimeFeature",
92
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",
93
118
  "keyed-rows-host-prepend-hinted": "keyedRowsHostPrependHintedRuntimeFeature",
94
119
  "keyed-rows-host-filter-prepend-hinted": "keyedRowsHostFilterPrependHintedRuntimeFeature",
95
120
  "keyed-rows-complete": "keyedRowsCompleteRuntimeFeature",
96
121
  "keyed-rows-complete-hinted": "keyedRowsCompleteHintedRuntimeFeature",
97
122
  "keyed-rows-complete-position-hinted": "keyedRowsCompletePositionHintedRuntimeFeature",
123
+ "keyed-rows-complete-batch-position-hinted": "keyedRowsCompleteBatchPositionHintedRuntimeFeature",
124
+ "keyed-rows-complete-window-position-hinted": "keyedRowsCompleteWindowPositionHintedRuntimeFeature",
98
125
  "keyed-rows-complete-reorder-hinted": "keyedRowsCompleteReorderHintedRuntimeFeature",
99
126
  "keyed-rows-complete-all-hinted": "keyedRowsCompleteAllHintedRuntimeFeature",
100
127
  "keyed-rows-complete-every-hinted": "keyedRowsCompleteEveryHintedRuntimeFeature",
128
+ "keyed-rows-complete-batch-every-hinted": "keyedRowsCompleteBatchEveryHintedRuntimeFeature",
129
+ "keyed-rows-complete-window-every-hinted": "keyedRowsCompleteWindowEveryHintedRuntimeFeature",
101
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",
102
135
  "keyed-rows-complete-prepend-hinted": "keyedRowsCompletePrependHintedRuntimeFeature",
103
136
  "keyed-rows-complete-filter-prepend-hinted": "keyedRowsCompleteFilterPrependHintedRuntimeFeature",
104
137
  "keyed-ranges": "keyedRangesRuntimeFeature",
105
138
  "mixed-ranges": "mixedRangesRuntimeFeature",
106
139
  component: "componentRuntimeFeature"
107
140
  };
108
- function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHints, keyedArrayPrependHints, keyedArrayPositionHints, keyedArrayReorderHints, keyedArrayRollingWindowHints) {
141
+ function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHints, keyedArrayStructuralAppendHints, keyedArrayStructuralAppendMapHints, keyedArrayPrependHints, keyedArrayStructuralPrependHints, keyedArrayStructuralPrependMapHints, keyedArrayPositionHints, keyedArrayBatchInsertHints, keyedArrayWindowReplaceHints, keyedArrayReorderHints, keyedArrayMapReorderHints, keyedArrayRollingWindowHints) {
109
142
  const features = /* @__PURE__ */ new Set();
110
143
  let keyedRowsHaveConditionals = false;
111
144
  let keyedRowsHaveHostBlocks = false;
@@ -122,7 +155,8 @@ function runtimeFeaturesForPlans(plans, keyedMapUpdateHints, keyedArrayFilterHin
122
155
  if (plans.some((plan) => plan.kind === "keyed-rows")) {
123
156
  const keyedRowsFeature = keyedRowsHaveConditionals && keyedRowsHaveHostBlocks ? "keyed-rows-complete" : keyedRowsHaveConditionals ? "keyed-rows-conditional" : keyedRowsHaveHostBlocks ? "keyed-rows-host" : "keyed-rows";
124
157
  const arrayRangeHints = keyedArrayRollingWindowHints || keyedArrayFilterHints || keyedArrayPrependHints;
125
- const hintSuffix = 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" : "";
126
160
  features.add(`${keyedRowsFeature}${hintSuffix}`);
127
161
  }
128
162
  return [...features].sort();
@@ -527,6 +561,22 @@ function isSafeKeyedMapResult(expression, item, safeGlobals) {
527
561
  if (validateDerivedExpression(expression.test, safeGlobals)) return false;
528
562
  return isUnchangedMapItem(expression.consequent, item) && isSafeKeyedMapReplacement(expression.alternate, item, safeGlobals) || isUnchangedMapItem(expression.alternate, item) && isSafeKeyedMapReplacement(expression.consequent, item, safeGlobals);
529
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
+ }
530
580
  function rewriteKeyedMapUpdateHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
531
581
  if (hintedStateIndices.size === 0) return { root: types.cloneNode(root, true), count: 0 };
532
582
  const file = expressionFile(types.cloneNode(root, true));
@@ -540,58 +590,50 @@ function rewriteKeyedMapUpdateHints(root, hintedStateIndices, statesBySetter, he
540
590
  return;
541
591
  }
542
592
  const updater = path.node.arguments[0];
543
- 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, {
544
- name: updater.params[0].name
545
- }) || !types.isIdentifier(updater.body.callee.property, { name: "map" })) {
546
- return;
547
- }
548
- const callback = updater.body.arguments[0];
549
- 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)) {
550
594
  return;
551
595
  }
552
- const item = callback.params[0];
553
- if (!isSafeKeyedMapResult(callback.body, item, safeGlobals)) return;
554
- const changedIndices = path.scope.generateUidIdentifier("farmChangedIndices");
555
- const mappedItem = path.scope.generateUidIdentifier("farmMappedItem");
556
- const nextValue = path.scope.generateUidIdentifier("farmNextItems");
557
- const index = types.isIdentifier(callback.params[1]) ? types.cloneNode(callback.params[1]) : path.scope.generateUidIdentifier("farmMapIndex");
558
- const wrappedCallback = types.cloneNode(callback, true);
559
- if (wrappedCallback.params.length === 1) wrappedCallback.params.push(types.cloneNode(index));
560
- wrappedCallback.body = types.blockStatement([
561
- types.variableDeclaration("const", [
562
- types.variableDeclarator(types.cloneNode(mappedItem), types.cloneNode(callback.body, true))
563
- ]),
564
- types.ifStatement(
565
- types.binaryExpression("!==", types.cloneNode(mappedItem), types.cloneNode(item)),
566
- types.expressionStatement(
567
- types.callExpression(
568
- types.memberExpression(types.cloneNode(changedIndices), types.identifier("push")),
569
- [types.cloneNode(index)]
570
- )
571
- )
572
- ),
573
- types.returnStatement(types.cloneNode(mappedItem))
574
- ]);
575
- const mapCall = types.cloneNode(updater.body, true);
576
- mapCall.arguments[0] = wrappedCallback;
596
+ const callbacks = keyedMapUpdatePipeline(updater.body, updater.params[0].name, safeGlobals);
597
+ if (!callbacks) return;
577
598
  const previous = types.cloneNode(updater.params[0]);
578
- path.node.arguments[0] = types.arrowFunctionExpression(
579
- [types.cloneNode(previous)],
580
- 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(
581
607
  types.variableDeclaration("const", [
582
- types.variableDeclarator(types.cloneNode(changedIndices), types.arrayExpression([]))
608
+ types.variableDeclarator(
609
+ types.cloneNode(method),
610
+ types.memberExpression(types.cloneNode(current), types.identifier("map"))
611
+ )
583
612
  ]),
584
- types.variableDeclaration("const", [types.variableDeclarator(types.cloneNode(nextValue), mapCall)]),
585
- types.returnStatement(
586
- types.callExpression(types.cloneNode(helperIdentifier), [
587
- types.cloneNode(previous),
613
+ types.variableDeclaration("const", [
614
+ types.variableDeclarator(
588
615
  types.cloneNode(nextValue),
589
- types.cloneNode(changedIndices)
590
- ])
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))])
591
633
  )
592
634
  ])
593
635
  );
594
- count += 1;
636
+ count += callbacks.length;
595
637
  path.skip();
596
638
  }
597
639
  });
@@ -764,8 +806,10 @@ function rewriteKeyedArrayRollingWindowHints(root, hintedStateIndices, statesByS
764
806
  }) || !types.isIdentifier(retainedSpread.argument.callee.property, { name: "slice" }) || !types.isExpression(retainedSpread.argument.arguments[0])) {
765
807
  return;
766
808
  }
767
- const retainedStart = staticSliceIndex(retainedSpread.argument.arguments[0]);
768
- 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
+ }
769
813
  const safeIncomingValue = (value) => {
770
814
  if (types.isArrayExpression(value)) {
771
815
  return value.elements.every(
@@ -808,7 +852,7 @@ function rewriteKeyedArrayRollingWindowHints(root, hintedStateIndices, statesByS
808
852
  types.callExpression(types.cloneNode(sliceHelperIdentifier), [
809
853
  types.cloneNode(previous),
810
854
  types.cloneNode(sliceMethod),
811
- types.numericLiteral(retainedStart)
855
+ types.cloneNode(retainedStart, true)
812
856
  ])
813
857
  ),
814
858
  types.variableDeclarator(types.cloneNode(nextValue), types.arrayExpression(nextElements))
@@ -850,13 +894,21 @@ function validateKeyedArrayPositionExpression(expression, safeGlobals) {
850
894
  }
851
895
  return validateDerivedExpression(expression, safeGlobals);
852
896
  }
853
- function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
897
+ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter, helperIdentifier, batchInsertHelperIdentifier, windowReplaceHelperIdentifier, safeGlobals) {
854
898
  if (hintedStateIndices.size === 0) {
855
- return { root: types.cloneNode(root, true), count: 0, stateIndices: /* @__PURE__ */ new Set() };
899
+ return {
900
+ root: types.cloneNode(root, true),
901
+ count: 0,
902
+ batchInsertCount: 0,
903
+ windowReplaceCount: 0,
904
+ stateIndices: /* @__PURE__ */ new Set()
905
+ };
856
906
  }
857
907
  const file = expressionFile(types.cloneNode(root, true));
858
908
  const stateIndices = /* @__PURE__ */ new Set();
859
909
  let count = 0;
910
+ let batchInsertCount = 0;
911
+ let windowReplaceCount = 0;
860
912
  traverse(file, {
861
913
  CallExpression(path) {
862
914
  const callee = path.get("callee");
@@ -871,11 +923,19 @@ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter
871
923
  }
872
924
  const methodName = updater.body.callee.property.name;
873
925
  const args = updater.body.arguments;
874
- const kind = methodName === "with" && args.length === 2 ? "replace" : methodName === "toSpliced" && args.length === 3 && types.isNumericLiteral(args[1], { value: 0 }) ? "insert" : methodName === "toSpliced" && args.length === 2 && types.isNumericLiteral(args[1], { value: 1 }) ? "remove" : 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;
929
+ const isBatchInsert = methodName === "toSpliced" && args.length >= 3 && types.isNumericLiteral(args[1], { value: 0 }) && (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);
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;
875
932
  if (!kind || !types.isExpression(args[0])) return;
876
933
  const position = args[0];
877
- const item = kind === "remove" ? void 0 : args.at(-1);
878
- if (validateKeyedArrayPositionExpression(position, safeGlobals) !== void 0 || item !== void 0 && (!types.isExpression(item) || validateDerivedExpression(item, safeGlobals) !== void 0)) {
934
+ const incoming = kind === "batch-insert" || kind === "window-replace" ? args.slice(2) : [args.at(-1)];
935
+ if (validateKeyedArrayPositionExpression(position, safeGlobals) !== void 0 || kind === "window-replace" && (!deleteCountExpression || validateKeyedArrayPositionExpression(deleteCountExpression, safeGlobals) !== void 0) || kind !== "remove" && incoming.some((item) => {
936
+ const expression = types.isSpreadElement(item) ? item.argument : item;
937
+ return !expression || !types.isExpression(expression) || validateDerivedExpression(expression, safeGlobals) !== void 0;
938
+ })) {
879
939
  return;
880
940
  }
881
941
  const previous = types.cloneNode(updater.params[0]);
@@ -892,7 +952,18 @@ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter
892
952
  )
893
953
  ]),
894
954
  types.returnStatement(
895
- types.callExpression(types.cloneNode(helperIdentifier), [
955
+ kind === "batch-insert" ? types.callExpression(types.cloneNode(batchInsertHelperIdentifier), [
956
+ types.cloneNode(previous),
957
+ types.cloneNode(method),
958
+ types.cloneNode(position, true),
959
+ ...args.slice(2).map((argument) => types.cloneNode(argument, true))
960
+ ]) : kind === "window-replace" ? types.callExpression(types.cloneNode(windowReplaceHelperIdentifier), [
961
+ types.cloneNode(previous),
962
+ types.cloneNode(method),
963
+ types.cloneNode(position, true),
964
+ types.cloneNode(args[1], true),
965
+ ...args.slice(2).map((argument) => types.cloneNode(argument, true))
966
+ ]) : types.callExpression(types.cloneNode(helperIdentifier), [
896
967
  types.cloneNode(previous),
897
968
  types.cloneNode(method),
898
969
  types.stringLiteral(kind),
@@ -902,6 +973,8 @@ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter
902
973
  ])
903
974
  );
904
975
  count += 1;
976
+ if (kind === "batch-insert") batchInsertCount += 1;
977
+ if (kind === "window-replace") windowReplaceCount += 1;
905
978
  stateIndices.add(state.index);
906
979
  path.skip();
907
980
  }
@@ -909,6 +982,8 @@ function rewriteKeyedArrayPositionHints(root, hintedStateIndices, statesBySetter
909
982
  return {
910
983
  root: file.program.body[0].expression,
911
984
  count,
985
+ batchInsertCount,
986
+ windowReplaceCount,
912
987
  stateIndices
913
988
  };
914
989
  }
@@ -931,34 +1006,976 @@ function rewriteKeyedArrayReorderHints(root, hintedStateIndices, statesBySetter,
931
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" })) {
932
1007
  return;
933
1008
  }
934
- const previous = types.cloneNode(updater.params[0]);
935
- const method = path.scope.generateUidIdentifier("farmToReversed");
936
- path.node.arguments[0] = types.arrowFunctionExpression(
937
- [types.cloneNode(previous)],
938
- types.blockStatement([
939
- types.variableDeclaration("const", [
940
- types.variableDeclarator(
941
- types.cloneNode(method),
942
- types.memberExpression(types.cloneNode(previous), types.identifier("toReversed"))
943
- )
944
- ]),
945
- types.returnStatement(
946
- types.callExpression(types.cloneNode(helperIdentifier), [
947
- types.cloneNode(previous),
948
- types.cloneNode(method)
949
- ])
950
- )
951
- ])
952
- );
953
- count += 1;
954
- stateIndices.add(state.index);
955
- 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
+ }
956
1972
  }
957
1973
  });
958
1974
  return {
959
1975
  root: file.program.body[0].expression,
960
- count,
961
- stateIndices
1976
+ mapCount,
1977
+ mapReorderCount,
1978
+ mapSortCount
962
1979
  };
963
1980
  }
964
1981
  function rewriteKeyedArraySortHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
@@ -1016,7 +2033,7 @@ function rewriteKeyedArraySortHints(root, hintedStateIndices, statesBySetter, he
1016
2033
  stateIndices
1017
2034
  };
1018
2035
  }
1019
- function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, helperIdentifier) {
2036
+ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, helperIdentifier, safeGlobals) {
1020
2037
  if (hintedStateIndices.size === 0) {
1021
2038
  return { root: types.cloneNode(root, true), count: 0, stateIndices: /* @__PURE__ */ new Set() };
1022
2039
  }
@@ -1035,14 +2052,13 @@ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, h
1035
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" })) {
1036
2053
  return;
1037
2054
  }
1038
- const indexes = [];
2055
+ const bounds = [];
1039
2056
  for (const argument of updater.body.arguments) {
1040
2057
  if (!types.isExpression(argument)) return;
1041
- const value = staticSliceIndex(argument);
1042
- if (value === void 0) return;
1043
- indexes.push(value);
2058
+ if (validateKeyedArrayPositionExpression(argument, safeGlobals) !== void 0) return;
2059
+ bounds.push(argument);
1044
2060
  }
1045
- if (indexes.length === 1 && indexes[0] === 0) return;
2061
+ if (bounds.length === 1 && staticSliceIndex(bounds[0]) === 0) return;
1046
2062
  const previous = types.cloneNode(updater.params[0]);
1047
2063
  const sliceMethod = path.scope.generateUidIdentifier("farmSlice");
1048
2064
  path.node.arguments[0] = types.arrowFunctionExpression(
@@ -1058,7 +2074,7 @@ function rewriteKeyedArraySliceHints(root, hintedStateIndices, statesBySetter, h
1058
2074
  types.callExpression(types.cloneNode(helperIdentifier), [
1059
2075
  types.cloneNode(previous),
1060
2076
  types.cloneNode(sliceMethod),
1061
- ...indexes.map((value) => types.numericLiteral(value))
2077
+ ...bounds.map((bound) => types.cloneNode(bound, true))
1062
2078
  ])
1063
2079
  )
1064
2080
  ])
@@ -4817,7 +5833,7 @@ function wrapperElement(definitionIdentifier, props) {
4817
5833
  const attributes = props ? [types.jsxSpreadAttribute(types.cloneNode(props))] : [];
4818
5834
  return types.jsxElement(types.jsxOpeningElement(name, attributes, true), null, [], true);
4819
5835
  }
4820
- function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateIdentifier, keyedArrayAppendIdentifier, keyedArrayFilterIdentifier, keyedArrayPrependIdentifier, keyedArrayPositionIdentifier, keyedArrayReorderIdentifier, keyedArraySortIdentifier, keyedArrayRollingWindowIdentifier, keyedArraySliceIdentifier, keyedCollectionUpdateIdentifier, keyedCollectionMutationIdentifier, runtimeFeatureIdentifiers, usedRuntimeFeatures, optimizationCounts, 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) {
4821
5837
  const { path, name, statementPath } = candidate;
4822
5838
  if (path.node.async || path.node.generator)
4823
5839
  return "async and generator components are not supported";
@@ -5189,9 +6205,13 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5189
6205
  shiftedIndexIndependentStateIndices,
5190
6206
  statesBySetter,
5191
6207
  keyedArrayPositionIdentifier,
6208
+ keyedArrayBatchInsertIdentifier,
6209
+ keyedArrayWindowReplaceIdentifier,
5192
6210
  safeGlobals
5193
6211
  );
5194
6212
  let appliedKeyedArrayPositionHints = 0;
6213
+ let appliedKeyedArrayBatchInsertHints = 0;
6214
+ let appliedKeyedArrayWindowReplaceHints = 0;
5195
6215
  let appliedPositionHintedStateIndices = /* @__PURE__ */ new Set();
5196
6216
  if (positionHintedRoot.count > 0) {
5197
6217
  const hintedBlockAnalysis = analyzeComposableBlocks(
@@ -5215,8 +6235,78 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5215
6235
  blockAnalysis = hintedBlockAnalysis;
5216
6236
  analysis = hintedAnalysis;
5217
6237
  appliedKeyedArrayPositionHints = positionHintedRoot.count;
6238
+ appliedKeyedArrayBatchInsertHints = positionHintedRoot.batchInsertCount;
6239
+ appliedKeyedArrayWindowReplaceHints = positionHintedRoot.windowReplaceCount;
5218
6240
  appliedPositionHintedStateIndices = positionHintedRoot.stateIndices;
5219
6241
  optimizationCounts.keyedArrayPositionHints += positionHintedRoot.count;
6242
+ compilerUsage.keyedArrayBatchInsertHints += positionHintedRoot.batchInsertCount;
6243
+ compilerUsage.keyedArrayWindowReplaceHints += positionHintedRoot.windowReplaceCount;
6244
+ }
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;
5220
6310
  }
5221
6311
  }
5222
6312
  const reorderHintedRoot = rewriteKeyedArrayReorderHints(
@@ -5225,8 +6315,8 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5225
6315
  statesBySetter,
5226
6316
  keyedArrayReorderIdentifier
5227
6317
  );
5228
- let appliedKeyedArrayReorderHints = 0;
5229
- let appliedReorderHintedStateIndices = /* @__PURE__ */ new Set();
6318
+ let appliedKeyedArrayReorderHints = appliedPipelineReorderHints;
6319
+ let appliedReorderHintedStateIndices = appliedPipelineHintedStateIndices;
5230
6320
  if (reorderHintedRoot.count > 0) {
5231
6321
  const hintedBlockAnalysis = analyzeComposableBlocks(
5232
6322
  reorderHintedRoot.root,
@@ -5248,8 +6338,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5248
6338
  expandedReactiveRoot = reorderHintedRoot.root;
5249
6339
  blockAnalysis = hintedBlockAnalysis;
5250
6340
  analysis = hintedAnalysis;
5251
- appliedKeyedArrayReorderHints = reorderHintedRoot.count;
5252
- appliedReorderHintedStateIndices = reorderHintedRoot.stateIndices;
6341
+ appliedKeyedArrayReorderHints += reorderHintedRoot.count;
6342
+ appliedReorderHintedStateIndices = /* @__PURE__ */ new Set([
6343
+ ...appliedReorderHintedStateIndices,
6344
+ ...reorderHintedRoot.stateIndices
6345
+ ]);
5253
6346
  optimizationCounts.keyedArrayReorderHints += reorderHintedRoot.count;
5254
6347
  }
5255
6348
  }
@@ -5260,8 +6353,8 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5260
6353
  keyedArraySortIdentifier,
5261
6354
  safeGlobals
5262
6355
  );
5263
- let appliedKeyedArraySortHints = 0;
5264
- let appliedSortHintedStateIndices = /* @__PURE__ */ new Set();
6356
+ let appliedKeyedArraySortHints = appliedPipelineSortHints;
6357
+ let appliedSortHintedStateIndices = appliedPipelineHintedStateIndices;
5265
6358
  if (sortHintedRoot.count > 0) {
5266
6359
  const hintedBlockAnalysis = analyzeComposableBlocks(
5267
6360
  sortHintedRoot.root,
@@ -5283,8 +6376,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5283
6376
  expandedReactiveRoot = sortHintedRoot.root;
5284
6377
  blockAnalysis = hintedBlockAnalysis;
5285
6378
  analysis = hintedAnalysis;
5286
- appliedKeyedArraySortHints = sortHintedRoot.count;
5287
- appliedSortHintedStateIndices = sortHintedRoot.stateIndices;
6379
+ appliedKeyedArraySortHints += sortHintedRoot.count;
6380
+ appliedSortHintedStateIndices = /* @__PURE__ */ new Set([
6381
+ ...appliedSortHintedStateIndices,
6382
+ ...sortHintedRoot.stateIndices
6383
+ ]);
5288
6384
  optimizationCounts.keyedArraySortHints += sortHintedRoot.count;
5289
6385
  }
5290
6386
  }
@@ -5292,10 +6388,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5292
6388
  expandedReactiveRoot,
5293
6389
  shiftedIndexIndependentStateIndices,
5294
6390
  statesBySetter,
5295
- keyedArraySliceIdentifier
6391
+ keyedArraySliceIdentifier,
6392
+ safeGlobals
5296
6393
  );
5297
- let appliedKeyedArraySliceHints = 0;
5298
- let appliedSliceHintedStateIndices = /* @__PURE__ */ new Set();
6394
+ let appliedKeyedArraySliceHints = appliedPipelineSliceHints;
6395
+ let appliedSliceHintedStateIndices = appliedPipelineSliceHints > 0 ? appliedPipelineHintedStateIndices : /* @__PURE__ */ new Set();
5299
6396
  if (sliceHintedRoot.count > 0) {
5300
6397
  const hintedBlockAnalysis = analyzeComposableBlocks(
5301
6398
  sliceHintedRoot.root,
@@ -5317,8 +6414,11 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5317
6414
  expandedReactiveRoot = sliceHintedRoot.root;
5318
6415
  blockAnalysis = hintedBlockAnalysis;
5319
6416
  analysis = hintedAnalysis;
5320
- appliedKeyedArraySliceHints = sliceHintedRoot.count;
5321
- appliedSliceHintedStateIndices = sliceHintedRoot.stateIndices;
6417
+ appliedKeyedArraySliceHints += sliceHintedRoot.count;
6418
+ appliedSliceHintedStateIndices = /* @__PURE__ */ new Set([
6419
+ ...appliedSliceHintedStateIndices,
6420
+ ...sliceHintedRoot.stateIndices
6421
+ ]);
5322
6422
  optimizationCounts.keyedArraySliceHints += sliceHintedRoot.count;
5323
6423
  }
5324
6424
  }
@@ -5329,8 +6429,8 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5329
6429
  keyedArrayFilterIdentifier,
5330
6430
  safeGlobals
5331
6431
  );
5332
- let appliedKeyedArrayFilterHints = 0;
5333
- let appliedFilterHintedStateIndices = /* @__PURE__ */ new Set();
6432
+ let appliedKeyedArrayFilterHints = appliedPipelineFilterHints;
6433
+ let appliedFilterHintedStateIndices = appliedPipelineFilterHints > 0 ? appliedPipelineHintedStateIndices : /* @__PURE__ */ new Set();
5334
6434
  if (filterHintedRoot.count > 0) {
5335
6435
  const hintedBlockAnalysis = analyzeComposableBlocks(
5336
6436
  filterHintedRoot.root,
@@ -5352,11 +6452,243 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5352
6452
  expandedReactiveRoot = filterHintedRoot.root;
5353
6453
  blockAnalysis = hintedBlockAnalysis;
5354
6454
  analysis = hintedAnalysis;
5355
- appliedKeyedArrayFilterHints = filterHintedRoot.count;
5356
- appliedFilterHintedStateIndices = filterHintedRoot.stateIndices;
6455
+ appliedKeyedArrayFilterHints += filterHintedRoot.count;
6456
+ appliedFilterHintedStateIndices = /* @__PURE__ */ new Set([
6457
+ ...appliedFilterHintedStateIndices,
6458
+ ...filterHintedRoot.stateIndices
6459
+ ]);
5357
6460
  optimizationCounts.keyedArrayFilterHints += filterHintedRoot.count;
5358
6461
  }
5359
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
+ }
5360
6692
  const keyedCollectionTargetKinds = /* @__PURE__ */ new Map();
5361
6693
  const conflictingKeyedCollectionTargets = /* @__PURE__ */ new Set();
5362
6694
  for (const plan of blockAnalysis.plans || []) {
@@ -5428,9 +6760,16 @@ function compileCandidate(candidate, createComponentIdentifier, keyedMapUpdateId
5428
6760
  blockPlans,
5429
6761
  hasKeyedUpdateHints,
5430
6762
  hasKeyedArrayRemovalHints,
6763
+ appliedKeyedArrayAppendHints > 0 && (appliedKeyedArrayFilterHints > 0 || appliedKeyedArraySliceHints > 0),
6764
+ appliedQueuedStructuralAppendMapHints > 0,
5431
6765
  appliedKeyedArrayPrependHints > 0,
6766
+ appliedKeyedArrayPrependHints > 0 && hasKeyedArrayRemovalHints,
6767
+ appliedQueuedStructuralPrependMapHints > 0,
5432
6768
  appliedKeyedArrayPositionHints > 0,
6769
+ appliedKeyedArrayBatchInsertHints > 0,
6770
+ appliedKeyedArrayWindowReplaceHints > 0,
5433
6771
  appliedKeyedArrayReorderHints > 0 || appliedKeyedArraySortHints > 0,
6772
+ appliedPipelineMapHints > 0 || appliedQueuedReorderMapHints > 0 || appliedQueuedMappedStructuralHints > 0 || appliedQueuedStructuralMapHints > 0,
5434
6773
  appliedKeyedArrayRollingWindowHints > 0
5435
6774
  );
5436
6775
  markShortCircuitBindings(analysis.bindings || []);
@@ -5612,6 +6951,21 @@ async function compileReactModule(code, id, options) {
5612
6951
  keyedMembershipTargets: 0,
5613
6952
  keyedMapUpdateHints: 0
5614
6953
  };
6954
+ const compilerUsage = {
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,
6967
+ keyedArrayWindowReplaceHints: 0
6968
+ };
5615
6969
  const plugin = () => ({
5616
6970
  name: "farm-react-aot",
5617
6971
  visitor: {
@@ -5650,18 +7004,54 @@ async function compileReactModule(code, id, options) {
5650
7004
  const keyedArrayFilterIdentifier = programPath.scope.generateUidIdentifier(
5651
7005
  "createCompilerKeyedArrayFilter"
5652
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
+ );
5653
7031
  const keyedArrayPrependIdentifier = programPath.scope.generateUidIdentifier(
5654
7032
  "createCompilerKeyedArrayPrepend"
5655
7033
  );
5656
7034
  const keyedArrayPositionIdentifier = programPath.scope.generateUidIdentifier(
5657
7035
  "createCompilerKeyedArrayPositionUpdate"
5658
7036
  );
7037
+ const keyedArrayBatchInsertIdentifier = programPath.scope.generateUidIdentifier(
7038
+ "createCompilerKeyedArrayBatchInsert"
7039
+ );
7040
+ const keyedArrayWindowReplaceIdentifier = programPath.scope.generateUidIdentifier(
7041
+ "createCompilerKeyedArrayWindowReplace"
7042
+ );
5659
7043
  const keyedArrayReorderIdentifier = programPath.scope.generateUidIdentifier(
5660
7044
  "createCompilerKeyedArrayReorder"
5661
7045
  );
7046
+ const keyedArrayStructuralReorderIdentifier = programPath.scope.generateUidIdentifier(
7047
+ "createCompilerKeyedArrayStructuralReorder"
7048
+ );
5662
7049
  const keyedArraySortIdentifier = programPath.scope.generateUidIdentifier(
5663
7050
  "createCompilerKeyedArraySort"
5664
7051
  );
7052
+ const keyedArrayStructuralSortIdentifier = programPath.scope.generateUidIdentifier(
7053
+ "createCompilerKeyedArrayStructuralSort"
7054
+ );
5665
7055
  const keyedArrayRollingWindowIdentifier = programPath.scope.generateUidIdentifier(
5666
7056
  "createCompilerKeyedArrayRollingWindow"
5667
7057
  );
@@ -5694,10 +7084,22 @@ async function compileReactModule(code, id, options) {
5694
7084
  keyedMapUpdateIdentifier,
5695
7085
  keyedArrayAppendIdentifier,
5696
7086
  keyedArrayFilterIdentifier,
7087
+ keyedArrayMapPipelineIdentifier,
7088
+ keyedArrayMappedStructuralAppendIdentifier,
7089
+ keyedArrayStructuralAppendMapPipelineIdentifier,
7090
+ keyedArrayMappedStructuralPrependIdentifier,
7091
+ keyedArrayStructuralPrependMapPipelineIdentifier,
7092
+ keyedArrayQueuedMapPipelineIdentifier,
7093
+ keyedArrayMapReorderIdentifier,
7094
+ keyedArrayMappedStructuralIdentifier,
5697
7095
  keyedArrayPrependIdentifier,
5698
7096
  keyedArrayPositionIdentifier,
7097
+ keyedArrayBatchInsertIdentifier,
7098
+ keyedArrayWindowReplaceIdentifier,
5699
7099
  keyedArrayReorderIdentifier,
7100
+ keyedArrayStructuralReorderIdentifier,
5700
7101
  keyedArraySortIdentifier,
7102
+ keyedArrayStructuralSortIdentifier,
5701
7103
  keyedArrayRollingWindowIdentifier,
5702
7104
  keyedArraySliceIdentifier,
5703
7105
  keyedCollectionUpdateIdentifier,
@@ -5705,6 +7107,7 @@ async function compileReactModule(code, id, options) {
5705
7107
  runtimeFeatureIdentifiers,
5706
7108
  usedRuntimeFeatures,
5707
7109
  optimizationCounts,
7110
+ compilerUsage,
5708
7111
  useStateNames,
5709
7112
  reactNames,
5710
7113
  listNames,
@@ -5721,6 +7124,12 @@ async function compileReactModule(code, id, options) {
5721
7124
  compiled.push(candidate.name);
5722
7125
  }
5723
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;
5724
7133
  if (compiled.length > 0) {
5725
7134
  programPath.unshiftContainer(
5726
7135
  "body",
@@ -5730,16 +7139,66 @@ async function compileReactModule(code, id, options) {
5730
7139
  createComponentIdentifier,
5731
7140
  types.identifier("createCompiledComponentWithFeatures")
5732
7141
  ),
5733
- ...optimizationCounts.keyedMapUpdateHints > 0 ? [
7142
+ ...optimizationCounts.keyedMapUpdateHints > compilerUsage.keyedArrayMapUpdateHints ? [
5734
7143
  types.importSpecifier(
5735
7144
  keyedMapUpdateIdentifier,
5736
7145
  types.identifier("createCompilerKeyedMapUpdate")
5737
7146
  )
5738
7147
  ] : [],
5739
- ...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 ? [
5740
7197
  types.importSpecifier(
5741
7198
  keyedArrayAppendIdentifier,
5742
- types.identifier("createCompilerKeyedArrayAppend")
7199
+ types.identifier(
7200
+ hasKeyedArrayStructuralAppendHints ? "createCompilerKeyedArrayStructuralAppend" : "createCompilerKeyedArrayAppend"
7201
+ )
5743
7202
  )
5744
7203
  ] : [],
5745
7204
  ...optimizationCounts.keyedArrayFilterHints > 0 ? [
@@ -5748,30 +7207,56 @@ async function compileReactModule(code, id, options) {
5748
7207
  types.identifier("createCompilerKeyedArrayFilter")
5749
7208
  )
5750
7209
  ] : [],
5751
- ...optimizationCounts.keyedArrayPrependHints > 0 ? [
7210
+ ...hasUnmappedKeyedArrayPrependHints ? [
5752
7211
  types.importSpecifier(
5753
7212
  keyedArrayPrependIdentifier,
5754
- types.identifier("createCompilerKeyedArrayPrepend")
7213
+ types.identifier(
7214
+ hasKeyedArrayStructuralPrependHints ? "createCompilerKeyedArrayStructuralPrepend" : "createCompilerKeyedArrayPrepend"
7215
+ )
5755
7216
  )
5756
7217
  ] : [],
5757
- ...optimizationCounts.keyedArrayPositionHints > 0 ? [
7218
+ ...optimizationCounts.keyedArrayPositionHints > compilerUsage.keyedArrayBatchInsertHints + compilerUsage.keyedArrayWindowReplaceHints ? [
5758
7219
  types.importSpecifier(
5759
7220
  keyedArrayPositionIdentifier,
5760
7221
  types.identifier("createCompilerKeyedArrayPositionUpdate")
5761
7222
  )
5762
7223
  ] : [],
5763
- ...optimizationCounts.keyedArrayReorderHints > 0 ? [
7224
+ ...compilerUsage.keyedArrayBatchInsertHints > 0 ? [
7225
+ types.importSpecifier(
7226
+ keyedArrayBatchInsertIdentifier,
7227
+ types.identifier("createCompilerKeyedArrayBatchInsert")
7228
+ )
7229
+ ] : [],
7230
+ ...compilerUsage.keyedArrayWindowReplaceHints > 0 ? [
7231
+ types.importSpecifier(
7232
+ keyedArrayWindowReplaceIdentifier,
7233
+ types.identifier("createCompilerKeyedArrayWindowReplace")
7234
+ )
7235
+ ] : [],
7236
+ ...optimizationCounts.keyedArrayReorderHints > compilerUsage.keyedArrayStructuralReorderHints + compilerUsage.keyedArrayMapReorderHints ? [
5764
7237
  types.importSpecifier(
5765
7238
  keyedArrayReorderIdentifier,
5766
7239
  types.identifier("createCompilerKeyedArrayReorder")
5767
7240
  )
5768
7241
  ] : [],
5769
- ...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 ? [
5770
7249
  types.importSpecifier(
5771
7250
  keyedArraySortIdentifier,
5772
7251
  types.identifier("createCompilerKeyedArraySort")
5773
7252
  )
5774
7253
  ] : [],
7254
+ ...compilerUsage.keyedArrayStructuralSortHints > 0 ? [
7255
+ types.importSpecifier(
7256
+ keyedArrayStructuralSortIdentifier,
7257
+ types.identifier("createCompilerKeyedArrayStructuralSort")
7258
+ )
7259
+ ] : [],
5775
7260
  ...optimizationCounts.keyedArrayRollingWindowHints > 0 ? [
5776
7261
  types.importSpecifier(
5777
7262
  keyedArrayRollingWindowIdentifier,
@@ -5912,12 +7397,46 @@ function createReactCompilerReport(projectRoot, observations) {
5912
7397
  }
5913
7398
  async function writeReactCompilerReport(projectRoot, reportFile, observations) {
5914
7399
  const outputPath = resolve(projectRoot, reportFile);
7400
+ await assertReportPathInsideProject(projectRoot, outputPath);
5915
7401
  const report = createReactCompilerReport(projectRoot, observations);
5916
7402
  await mkdir(dirname(outputPath), { recursive: true });
5917
7403
  await writeFile(outputPath, `${JSON.stringify(report, null, 2)}
5918
7404
  `, "utf8");
5919
7405
  return outputPath;
5920
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
+ }
5921
7440
 
5922
7441
  // src/index.ts
5923
7442
  var DEFAULT_COMPILER_DIRECTIVE = "use compiler";