@fictjs/vite-plugin 0.3.0 → 0.5.0

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/index.cjs CHANGED
@@ -30,7 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- default: () => fict
33
+ default: () => fict,
34
+ registerExtractedHandler: () => registerExtractedHandler
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
36
37
  var import_node_crypto = require("crypto");
@@ -38,9 +39,18 @@ var import_node_fs = require("fs");
38
39
  var import_node_path = __toESM(require("path"), 1);
39
40
  var import_node_url = require("url");
40
41
  var import_core = require("@babel/core");
42
+ var import_generator = __toESM(require("@babel/generator"), 1);
43
+ var import_parser = require("@babel/parser");
44
+ var import_traverse = __toESM(require("@babel/traverse"), 1);
45
+ var t = __toESM(require("@babel/types"), 1);
41
46
  var import_compiler = require("@fictjs/compiler");
47
+ var traverse = typeof import_traverse.default === "function" ? import_traverse.default : import_traverse.default.default;
48
+ var generate = typeof import_generator.default === "function" ? import_generator.default : import_generator.default.default;
42
49
  var CACHE_VERSION = 1;
43
50
  var MODULE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
51
+ var VIRTUAL_HANDLER_PREFIX = "\0fict-handler:";
52
+ var VIRTUAL_HANDLER_RESOLVE_PREFIX = "virtual:fict-handler:";
53
+ var extractedHandlers = /* @__PURE__ */ new Map();
44
54
  function fict(options = {}) {
45
55
  const {
46
56
  include = ["**/*.tsx", "**/*.jsx"],
@@ -96,6 +106,39 @@ function fict(options = {}) {
96
106
  config = resolvedConfig;
97
107
  isDev = config.command === "serve" || config.mode === "development";
98
108
  resetCache();
109
+ extractedHandlers.clear();
110
+ },
111
+ resolveId(id) {
112
+ if (id.startsWith(VIRTUAL_HANDLER_RESOLVE_PREFIX)) {
113
+ return VIRTUAL_HANDLER_PREFIX + id.slice(VIRTUAL_HANDLER_RESOLVE_PREFIX.length);
114
+ }
115
+ return null;
116
+ },
117
+ load(id) {
118
+ if (!id.startsWith(VIRTUAL_HANDLER_PREFIX)) {
119
+ return null;
120
+ }
121
+ const handlerId = id.slice(VIRTUAL_HANDLER_PREFIX.length);
122
+ console.log(`[fict-plugin] Loading virtual module: ${handlerId}`);
123
+ console.log(
124
+ `[fict-plugin] Registry has ${extractedHandlers.size} handlers:`,
125
+ Array.from(extractedHandlers.keys())
126
+ );
127
+ const handler = extractedHandlers.get(handlerId);
128
+ if (handler) {
129
+ const generatedCode = generateHandlerModule(handler);
130
+ console.log(`[fict-plugin] Generated code length: ${generatedCode.length}`);
131
+ console.log(`[fict-plugin] Generated code preview: ${generatedCode.slice(0, 200)}...`);
132
+ return generatedCode;
133
+ }
134
+ if (!handler) {
135
+ const [sourceModule, exportName] = parseHandlerId(handlerId);
136
+ if (sourceModule && exportName) {
137
+ return `export { ${exportName} as default } from '${sourceModule}'`;
138
+ }
139
+ return null;
140
+ }
141
+ return generateHandlerModule(handler);
99
142
  },
100
143
  config(userConfig, env) {
101
144
  const userOptimize = userConfig.optimizeDeps;
@@ -145,6 +188,12 @@ function fict(options = {}) {
145
188
  // Our plugin will handle the full transformation
146
189
  include: /\.(ts|js|mts|mjs|cjs)$/
147
190
  },
191
+ build: {
192
+ rollupOptions: {
193
+ // Preserve exports in entry chunks to prevent tree-shaking of handler exports
194
+ preserveEntrySignatures: "exports-only"
195
+ }
196
+ },
148
197
  resolve: {
149
198
  ...userConfig.resolve ?? {},
150
199
  dedupe: Array.from(dedupe)
@@ -171,6 +220,7 @@ function fict(options = {}) {
171
220
  ...compilerOptions,
172
221
  dev: compilerOptions.dev ?? isDev,
173
222
  sourcemap: compilerOptions.sourcemap ?? true,
223
+ filename,
174
224
  moduleMetadata,
175
225
  resolveModuleMetadata: (source, importer) => {
176
226
  const userResolved = compilerOptions.resolveModuleMetadata?.(source, importer);
@@ -261,9 +311,44 @@ function fict(options = {}) {
261
311
  if (!result || !result.code) {
262
312
  return null;
263
313
  }
314
+ let finalCode = result.code;
315
+ let finalMap = result.map;
316
+ const shouldSplit = options.functionSplitting ?? (config?.command === "build" && (compilerOptions.resumable || !config?.build?.ssr));
317
+ console.log(
318
+ `[fict-plugin] shouldSplit=${shouldSplit}, ssr=${config?.build?.ssr}, resumable=${compilerOptions.resumable}, file=${filename}`
319
+ );
320
+ if (shouldSplit) {
321
+ let splitResult = null;
322
+ try {
323
+ splitResult = extractAndRewriteHandlers(finalCode, filename);
324
+ } catch (e) {
325
+ console.error("[fict-plugin] extractAndRewriteHandlers error:", e);
326
+ }
327
+ console.log(
328
+ `[fict-plugin] splitResult: ${splitResult ? splitResult.handlers.length + " handlers" : "null"}`
329
+ );
330
+ if (splitResult) {
331
+ console.log(
332
+ `[fict-plugin] Function splitting: ${filename} - ${splitResult.handlers.length} handlers extracted`
333
+ );
334
+ finalCode = splitResult.code;
335
+ finalMap = null;
336
+ if (config?.command === "build" && !config?.build?.ssr) {
337
+ for (const handlerName of splitResult.handlers) {
338
+ const handlerId = createHandlerId(filename, handlerName);
339
+ const virtualModuleId = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
340
+ this.emitFile({
341
+ type: "chunk",
342
+ id: virtualModuleId,
343
+ name: `handler-${handlerName}`
344
+ });
345
+ }
346
+ }
347
+ }
348
+ }
264
349
  const transformed = {
265
- code: result.code,
266
- map: result.map
350
+ code: finalCode,
351
+ map: finalMap
267
352
  };
268
353
  if (cacheKey) {
269
354
  await cacheStore.set(cacheKey, transformed);
@@ -289,6 +374,40 @@ function fict(options = {}) {
289
374
  path: "*"
290
375
  });
291
376
  }
377
+ },
378
+ generateBundle(_options, bundle) {
379
+ if (!config || config.command !== "build") return;
380
+ if (config.build.ssr) return;
381
+ const base = config.base ?? "/";
382
+ const manifest = {};
383
+ for (const output of Object.values(bundle)) {
384
+ if (output.type !== "chunk") continue;
385
+ const fileName = output.fileName;
386
+ const url = joinBasePath(base, fileName);
387
+ for (const moduleId of Object.keys(output.modules)) {
388
+ if (!moduleId) continue;
389
+ if (moduleId.startsWith(VIRTUAL_HANDLER_PREFIX)) {
390
+ const handlerId = moduleId.slice(VIRTUAL_HANDLER_PREFIX.length);
391
+ const virtualKey = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
392
+ if (!manifest[virtualKey]) {
393
+ manifest[virtualKey] = url;
394
+ }
395
+ continue;
396
+ }
397
+ if (moduleId.startsWith("\0")) continue;
398
+ const normalized = normalizeFileName(moduleId, config.root);
399
+ if (!import_node_path.default.isAbsolute(normalized)) continue;
400
+ const key = (0, import_node_url.pathToFileURL)(normalized).href;
401
+ if (!manifest[key]) {
402
+ manifest[key] = url;
403
+ }
404
+ }
405
+ }
406
+ this.emitFile({
407
+ type: "asset",
408
+ fileName: "fict.manifest.json",
409
+ source: JSON.stringify(manifest)
410
+ });
292
411
  }
293
412
  };
294
413
  }
@@ -353,6 +472,12 @@ function normalizeFileName(id, root) {
353
472
  if (root) return import_node_path.default.normalize(import_node_path.default.resolve(root, clean));
354
473
  return import_node_path.default.normalize(import_node_path.default.resolve(clean));
355
474
  }
475
+ function joinBasePath(base, fileName) {
476
+ if (!base) return fileName;
477
+ if (base === "/") return `/${fileName}`;
478
+ const normalized = base.endsWith("/") ? base : `${base}/`;
479
+ return `${normalized}${fileName}`;
480
+ }
356
481
  function normalizeAliases(aliases) {
357
482
  if (!aliases) return [];
358
483
  if (Array.isArray(aliases)) {
@@ -537,4 +662,439 @@ async function createTypeScriptProject(ts, rootDir, configPath) {
537
662
  dispose: () => service.dispose?.()
538
663
  };
539
664
  }
665
+ function parseHandlerId(handlerId) {
666
+ const separatorIndex = handlerId.lastIndexOf("$$");
667
+ if (separatorIndex === -1) {
668
+ return [handlerId, "default"];
669
+ }
670
+ return [handlerId.slice(0, separatorIndex), handlerId.slice(separatorIndex + 2)];
671
+ }
672
+ function createHandlerId(sourceModule, exportName) {
673
+ return `${sourceModule}$$${exportName}`;
674
+ }
675
+ function generateHandlerModule(handler) {
676
+ if (!handler.code) {
677
+ return `export { ${handler.exportName} as default } from '${handler.sourceModule}';
678
+ `;
679
+ }
680
+ const importsByModule = /* @__PURE__ */ new Map();
681
+ for (const helperName of handler.helpersUsed) {
682
+ const helper = RUNTIME_HELPERS[helperName];
683
+ if (!helper) continue;
684
+ const existing = importsByModule.get(helper.from) ?? [];
685
+ if (!existing.includes(helper.import)) {
686
+ existing.push(helper.import);
687
+ }
688
+ importsByModule.set(helper.from, existing);
689
+ }
690
+ const imports = [];
691
+ for (const [module2, names] of importsByModule) {
692
+ imports.push(`import { ${names.join(", ")} } from '${module2}';`);
693
+ }
694
+ if (handler.localDeps.length > 0) {
695
+ const depImports = handler.localDeps.map((dep) => `${HANDLER_DEP_PREFIX}${dep} as ${dep}`);
696
+ imports.push(`import { ${depImports.join(", ")} } from '${handler.sourceModule}';`);
697
+ }
698
+ return `${imports.join("\n")}${imports.length > 0 ? "\n\n" : ""}export default ${handler.code};
699
+ `;
700
+ }
701
+ var HANDLER_DEP_PREFIX = "__fict_dep_";
702
+ function registerExtractedHandler(sourceModule, exportName, helpersUsed, code, localDeps = []) {
703
+ const handlerId = createHandlerId(sourceModule, exportName);
704
+ extractedHandlers.set(handlerId, {
705
+ sourceModule,
706
+ exportName,
707
+ helpersUsed,
708
+ localDeps,
709
+ code
710
+ });
711
+ return `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
712
+ }
713
+ var RUNTIME_HELPERS = {
714
+ __fictUseLexicalScope: { import: "__fictUseLexicalScope", from: "@fictjs/runtime/internal" },
715
+ __fictGetScopeProps: { import: "__fictGetScopeProps", from: "@fictjs/runtime/internal" },
716
+ __fictGetSSRScope: { import: "__fictGetSSRScope", from: "@fictjs/runtime/internal" },
717
+ __fictEnsureScope: { import: "__fictEnsureScope", from: "@fictjs/runtime/internal" },
718
+ __fictPrepareContext: { import: "__fictPrepareContext", from: "@fictjs/runtime/internal" },
719
+ __fictPushContext: { import: "__fictPushContext", from: "@fictjs/runtime/internal" },
720
+ __fictPopContext: { import: "__fictPopContext", from: "@fictjs/runtime/internal" },
721
+ hydrateComponent: { import: "hydrateComponent", from: "@fictjs/runtime/internal" },
722
+ __fictQrl: { import: "__fictQrl", from: "@fictjs/runtime/internal" }
723
+ };
724
+ var GLOBAL_IDENTIFIERS = /* @__PURE__ */ new Set([
725
+ // JavaScript globals
726
+ "undefined",
727
+ "null",
728
+ "true",
729
+ "false",
730
+ "NaN",
731
+ "Infinity",
732
+ "globalThis",
733
+ "window",
734
+ "document",
735
+ "console",
736
+ "setTimeout",
737
+ "setInterval",
738
+ "clearTimeout",
739
+ "clearInterval",
740
+ "requestAnimationFrame",
741
+ "cancelAnimationFrame",
742
+ "fetch",
743
+ "URL",
744
+ "URLSearchParams",
745
+ "FormData",
746
+ "Headers",
747
+ "Request",
748
+ "Response",
749
+ "AbortController",
750
+ "AbortSignal",
751
+ // Built-in constructors
752
+ "Object",
753
+ "Array",
754
+ "String",
755
+ "Number",
756
+ "Boolean",
757
+ "Symbol",
758
+ "BigInt",
759
+ "Date",
760
+ "RegExp",
761
+ "Error",
762
+ "TypeError",
763
+ "RangeError",
764
+ "SyntaxError",
765
+ "Map",
766
+ "Set",
767
+ "WeakMap",
768
+ "WeakSet",
769
+ "Promise",
770
+ "Proxy",
771
+ "Reflect",
772
+ "JSON",
773
+ "Math",
774
+ "Intl",
775
+ // Event and DOM
776
+ "Event",
777
+ "CustomEvent",
778
+ "Element",
779
+ "Node",
780
+ "HTMLElement"
781
+ ]);
782
+ function collectReferencedIdentifiers(node, localBindings) {
783
+ const referenced = /* @__PURE__ */ new Set();
784
+ function visitNode(current, parent, key) {
785
+ if (!current) return;
786
+ if (t.isIdentifier(current)) {
787
+ const name = current.name;
788
+ if (parent && t.isMemberExpression(parent) && parent.property === current && !parent.computed) {
789
+ return;
790
+ }
791
+ if (parent && t.isObjectProperty(parent) && parent.key === current && !parent.computed) {
792
+ return;
793
+ }
794
+ if (parent && t.isVariableDeclarator(parent) && parent.id === current) {
795
+ return;
796
+ }
797
+ if (parent && (t.isFunctionDeclaration(parent) || t.isFunctionExpression(parent)) && parent.id === current) {
798
+ return;
799
+ }
800
+ if (key === "params") {
801
+ return;
802
+ }
803
+ if (parent && t.isCatchClause(parent) && parent.param === current) {
804
+ return;
805
+ }
806
+ if (localBindings.has(name)) {
807
+ return;
808
+ }
809
+ if (GLOBAL_IDENTIFIERS.has(name)) {
810
+ return;
811
+ }
812
+ if (RUNTIME_HELPERS[name]) {
813
+ return;
814
+ }
815
+ referenced.add(name);
816
+ return;
817
+ }
818
+ for (const nodeKey of Object.keys(current)) {
819
+ if (nodeKey === "loc" || nodeKey === "start" || nodeKey === "end" || nodeKey === "extra" || nodeKey === "comments" || nodeKey === "leadingComments" || nodeKey === "trailingComments" || nodeKey === "innerComments") {
820
+ continue;
821
+ }
822
+ const child = current[nodeKey];
823
+ if (Array.isArray(child)) {
824
+ for (const item of child) {
825
+ if (item && typeof item === "object" && item !== null && "type" in item && typeof item.type === "string") {
826
+ visitNode(item, current, nodeKey);
827
+ }
828
+ }
829
+ } else if (child && typeof child === "object" && child !== null && "type" in child && typeof child.type === "string") {
830
+ visitNode(child, current, nodeKey);
831
+ }
832
+ }
833
+ }
834
+ visitNode(node, null, null);
835
+ return referenced;
836
+ }
837
+ function collectLocalBindings(node) {
838
+ const bindings = /* @__PURE__ */ new Set();
839
+ function visitNode(current) {
840
+ if (!current) return;
841
+ if (t.isVariableDeclarator(current)) {
842
+ if (t.isIdentifier(current.id)) {
843
+ bindings.add(current.id.name);
844
+ } else if (t.isObjectPattern(current.id) || t.isArrayPattern(current.id)) {
845
+ const names = collectPatternIdentifiers(current.id);
846
+ for (const name of names) {
847
+ bindings.add(name);
848
+ }
849
+ }
850
+ }
851
+ if (t.isFunctionDeclaration(current)) {
852
+ if (current.id) {
853
+ bindings.add(current.id.name);
854
+ }
855
+ for (const param of current.params) {
856
+ const names = collectPatternIdentifiers(param);
857
+ for (const name of names) {
858
+ bindings.add(name);
859
+ }
860
+ }
861
+ }
862
+ if (t.isFunctionExpression(current)) {
863
+ for (const param of current.params) {
864
+ const names = collectPatternIdentifiers(param);
865
+ for (const name of names) {
866
+ bindings.add(name);
867
+ }
868
+ }
869
+ }
870
+ if (t.isArrowFunctionExpression(current)) {
871
+ for (const param of current.params) {
872
+ const names = collectPatternIdentifiers(param);
873
+ for (const name of names) {
874
+ bindings.add(name);
875
+ }
876
+ }
877
+ }
878
+ if (t.isCatchClause(current)) {
879
+ if (current.param && t.isIdentifier(current.param)) {
880
+ bindings.add(current.param.name);
881
+ }
882
+ }
883
+ for (const nodeKey of Object.keys(current)) {
884
+ if (nodeKey === "loc" || nodeKey === "start" || nodeKey === "end" || nodeKey === "extra" || nodeKey === "comments" || nodeKey === "leadingComments" || nodeKey === "trailingComments" || nodeKey === "innerComments") {
885
+ continue;
886
+ }
887
+ const child = current[nodeKey];
888
+ if (Array.isArray(child)) {
889
+ for (const item of child) {
890
+ if (item && typeof item === "object" && item !== null && "type" in item && typeof item.type === "string") {
891
+ visitNode(item);
892
+ }
893
+ }
894
+ } else if (child && typeof child === "object" && child !== null && "type" in child && typeof child.type === "string") {
895
+ visitNode(child);
896
+ }
897
+ }
898
+ }
899
+ visitNode(node);
900
+ return bindings;
901
+ }
902
+ function collectPatternIdentifiers(pattern) {
903
+ const names = [];
904
+ if (t.isIdentifier(pattern)) {
905
+ names.push(pattern.name);
906
+ } else if (t.isObjectPattern(pattern)) {
907
+ for (const prop of pattern.properties) {
908
+ if (t.isObjectProperty(prop) && t.isLVal(prop.value)) {
909
+ names.push(...collectPatternIdentifiers(prop.value));
910
+ } else if (t.isRestElement(prop)) {
911
+ names.push(...collectPatternIdentifiers(prop.argument));
912
+ }
913
+ }
914
+ } else if (t.isArrayPattern(pattern)) {
915
+ for (const element of pattern.elements) {
916
+ if (element) {
917
+ names.push(...collectPatternIdentifiers(element));
918
+ }
919
+ }
920
+ } else if (t.isRestElement(pattern)) {
921
+ names.push(...collectPatternIdentifiers(pattern.argument));
922
+ } else if (t.isAssignmentPattern(pattern)) {
923
+ names.push(...collectPatternIdentifiers(pattern.left));
924
+ }
925
+ return names;
926
+ }
927
+ function extractAndRewriteHandlers(code, sourceModule) {
928
+ let ast;
929
+ try {
930
+ ast = (0, import_parser.parse)(code, {
931
+ sourceType: "module",
932
+ plugins: ["jsx", "typescript"]
933
+ });
934
+ } catch (e) {
935
+ console.error("[fict-plugin] Parse error in extractAndRewriteHandlers:", e);
936
+ return null;
937
+ }
938
+ const topLevelDeclarations = /* @__PURE__ */ new Set();
939
+ const importedNames = /* @__PURE__ */ new Set();
940
+ for (const node of ast.program.body) {
941
+ if (t.isImportDeclaration(node)) {
942
+ for (const specifier of node.specifiers) {
943
+ if (t.isImportSpecifier(specifier) || t.isImportDefaultSpecifier(specifier)) {
944
+ importedNames.add(specifier.local.name);
945
+ } else if (t.isImportNamespaceSpecifier(specifier)) {
946
+ importedNames.add(specifier.local.name);
947
+ }
948
+ }
949
+ continue;
950
+ }
951
+ if (t.isFunctionDeclaration(node) && node.id) {
952
+ topLevelDeclarations.add(node.id.name);
953
+ continue;
954
+ }
955
+ if (t.isVariableDeclaration(node)) {
956
+ for (const declarator of node.declarations) {
957
+ if (t.isIdentifier(declarator.id)) {
958
+ topLevelDeclarations.add(declarator.id.name);
959
+ }
960
+ }
961
+ continue;
962
+ }
963
+ if (t.isClassDeclaration(node) && node.id) {
964
+ topLevelDeclarations.add(node.id.name);
965
+ continue;
966
+ }
967
+ if (t.isExportNamedDeclaration(node) && node.declaration) {
968
+ if (t.isFunctionDeclaration(node.declaration) && node.declaration.id) {
969
+ topLevelDeclarations.add(node.declaration.id.name);
970
+ } else if (t.isVariableDeclaration(node.declaration)) {
971
+ for (const declarator of node.declaration.declarations) {
972
+ if (t.isIdentifier(declarator.id)) {
973
+ topLevelDeclarations.add(declarator.id.name);
974
+ }
975
+ }
976
+ } else if (t.isClassDeclaration(node.declaration) && node.declaration.id) {
977
+ topLevelDeclarations.add(node.declaration.id.name);
978
+ }
979
+ }
980
+ }
981
+ for (const name of importedNames) {
982
+ topLevelDeclarations.add(name);
983
+ }
984
+ const handlerNames = [];
985
+ const nodesToRemove = /* @__PURE__ */ new Set();
986
+ const allLocalDeps = /* @__PURE__ */ new Set();
987
+ traverse(ast, {
988
+ ExportNamedDeclaration(path2) {
989
+ const declaration = path2.node.declaration;
990
+ if (t.isVariableDeclaration(declaration)) {
991
+ for (const declarator of declaration.declarations) {
992
+ if (!t.isIdentifier(declarator.id)) continue;
993
+ const name = declarator.id.name;
994
+ if (!name.match(/^__fict_e\d+$/)) continue;
995
+ if (!declarator.init) continue;
996
+ handlerNames.push(name);
997
+ const handlerCode = generate(declarator.init).code;
998
+ const helpersUsed = [];
999
+ for (const helperName of Object.keys(RUNTIME_HELPERS)) {
1000
+ if (handlerCode.includes(helperName)) {
1001
+ helpersUsed.push(helperName);
1002
+ }
1003
+ }
1004
+ const localBindings = collectLocalBindings(declarator.init);
1005
+ const referencedIds = collectReferencedIdentifiers(declarator.init, localBindings);
1006
+ const localDeps = [];
1007
+ for (const ref of referencedIds) {
1008
+ if (topLevelDeclarations.has(ref) && !ref.match(/^__fict_[er]\d+$/)) {
1009
+ localDeps.push(ref);
1010
+ allLocalDeps.add(ref);
1011
+ }
1012
+ }
1013
+ const handlerId = createHandlerId(sourceModule, name);
1014
+ extractedHandlers.set(handlerId, {
1015
+ sourceModule,
1016
+ exportName: name,
1017
+ helpersUsed,
1018
+ localDeps,
1019
+ code: handlerCode
1020
+ });
1021
+ nodesToRemove.add(path2.node);
1022
+ }
1023
+ return;
1024
+ }
1025
+ if (t.isFunctionDeclaration(declaration) && declaration.id) {
1026
+ const name = declaration.id.name;
1027
+ if (!name.match(/^__fict_e\d+$/)) return;
1028
+ handlerNames.push(name);
1029
+ const params = declaration.params;
1030
+ const body = declaration.body;
1031
+ const arrowFn = t.arrowFunctionExpression(params, body, declaration.async);
1032
+ const handlerCode = generate(arrowFn).code;
1033
+ const helpersUsed = [];
1034
+ for (const helperName of Object.keys(RUNTIME_HELPERS)) {
1035
+ if (handlerCode.includes(helperName)) {
1036
+ helpersUsed.push(helperName);
1037
+ }
1038
+ }
1039
+ const localBindings = collectLocalBindings(arrowFn);
1040
+ const referencedIds = collectReferencedIdentifiers(arrowFn, localBindings);
1041
+ const localDeps = [];
1042
+ for (const ref of referencedIds) {
1043
+ if (topLevelDeclarations.has(ref) && !ref.match(/^__fict_[er]\d+$/)) {
1044
+ localDeps.push(ref);
1045
+ allLocalDeps.add(ref);
1046
+ }
1047
+ }
1048
+ const handlerId = createHandlerId(sourceModule, name);
1049
+ extractedHandlers.set(handlerId, {
1050
+ sourceModule,
1051
+ exportName: name,
1052
+ helpersUsed,
1053
+ localDeps,
1054
+ code: handlerCode
1055
+ });
1056
+ nodesToRemove.add(path2.node);
1057
+ }
1058
+ }
1059
+ });
1060
+ if (handlerNames.length === 0) {
1061
+ return null;
1062
+ }
1063
+ traverse(ast, {
1064
+ ExportNamedDeclaration(path2) {
1065
+ if (nodesToRemove.has(path2.node)) {
1066
+ path2.remove();
1067
+ }
1068
+ },
1069
+ CallExpression(path2) {
1070
+ if (!t.isIdentifier(path2.node.callee, { name: "__fictQrl" })) return;
1071
+ if (path2.node.arguments.length !== 2) return;
1072
+ const secondArg = path2.node.arguments[1];
1073
+ if (!t.isStringLiteral(secondArg)) return;
1074
+ const handlerName = secondArg.value;
1075
+ if (!handlerNames.includes(handlerName)) return;
1076
+ const handlerId = createHandlerId(sourceModule, handlerName);
1077
+ const virtualUrl = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}#default`;
1078
+ path2.replaceWith(t.stringLiteral(virtualUrl));
1079
+ }
1080
+ });
1081
+ if (allLocalDeps.size > 0) {
1082
+ const reExports = [];
1083
+ for (const dep of allLocalDeps) {
1084
+ reExports.push(
1085
+ t.exportSpecifier(t.identifier(dep), t.identifier(`${HANDLER_DEP_PREFIX}${dep}`))
1086
+ );
1087
+ }
1088
+ ast.program.body.push(t.exportNamedDeclaration(null, reExports));
1089
+ }
1090
+ const result = generate(ast, {
1091
+ retainLines: true,
1092
+ compact: false
1093
+ });
1094
+ return { code: result.code, handlers: handlerNames };
1095
+ }
1096
+ // Annotate the CommonJS export names for ESM import in node:
1097
+ 0 && (module.exports = {
1098
+ registerExtractedHandler
1099
+ });
540
1100
  //# sourceMappingURL=index.cjs.map