@fictjs/vite-plugin 0.4.0 → 0.5.1
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 +563 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +560 -4
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
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:
|
|
266
|
-
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
|