@fictjs/vite-plugin 0.4.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 +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.js
CHANGED
|
@@ -2,11 +2,20 @@
|
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
3
|
import { promises as fs } from "fs";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
6
6
|
import { transformAsync } from "@babel/core";
|
|
7
|
+
import _generate from "@babel/generator";
|
|
8
|
+
import { parse } from "@babel/parser";
|
|
9
|
+
import _traverse from "@babel/traverse";
|
|
10
|
+
import * as t from "@babel/types";
|
|
7
11
|
import { createFictPlugin } from "@fictjs/compiler";
|
|
12
|
+
var traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
|
|
13
|
+
var generate = typeof _generate === "function" ? _generate : _generate.default;
|
|
8
14
|
var CACHE_VERSION = 1;
|
|
9
15
|
var MODULE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"];
|
|
16
|
+
var VIRTUAL_HANDLER_PREFIX = "\0fict-handler:";
|
|
17
|
+
var VIRTUAL_HANDLER_RESOLVE_PREFIX = "virtual:fict-handler:";
|
|
18
|
+
var extractedHandlers = /* @__PURE__ */ new Map();
|
|
10
19
|
function fict(options = {}) {
|
|
11
20
|
const {
|
|
12
21
|
include = ["**/*.tsx", "**/*.jsx"],
|
|
@@ -62,6 +71,39 @@ function fict(options = {}) {
|
|
|
62
71
|
config = resolvedConfig;
|
|
63
72
|
isDev = config.command === "serve" || config.mode === "development";
|
|
64
73
|
resetCache();
|
|
74
|
+
extractedHandlers.clear();
|
|
75
|
+
},
|
|
76
|
+
resolveId(id) {
|
|
77
|
+
if (id.startsWith(VIRTUAL_HANDLER_RESOLVE_PREFIX)) {
|
|
78
|
+
return VIRTUAL_HANDLER_PREFIX + id.slice(VIRTUAL_HANDLER_RESOLVE_PREFIX.length);
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
},
|
|
82
|
+
load(id) {
|
|
83
|
+
if (!id.startsWith(VIRTUAL_HANDLER_PREFIX)) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const handlerId = id.slice(VIRTUAL_HANDLER_PREFIX.length);
|
|
87
|
+
console.log(`[fict-plugin] Loading virtual module: ${handlerId}`);
|
|
88
|
+
console.log(
|
|
89
|
+
`[fict-plugin] Registry has ${extractedHandlers.size} handlers:`,
|
|
90
|
+
Array.from(extractedHandlers.keys())
|
|
91
|
+
);
|
|
92
|
+
const handler = extractedHandlers.get(handlerId);
|
|
93
|
+
if (handler) {
|
|
94
|
+
const generatedCode = generateHandlerModule(handler);
|
|
95
|
+
console.log(`[fict-plugin] Generated code length: ${generatedCode.length}`);
|
|
96
|
+
console.log(`[fict-plugin] Generated code preview: ${generatedCode.slice(0, 200)}...`);
|
|
97
|
+
return generatedCode;
|
|
98
|
+
}
|
|
99
|
+
if (!handler) {
|
|
100
|
+
const [sourceModule, exportName] = parseHandlerId(handlerId);
|
|
101
|
+
if (sourceModule && exportName) {
|
|
102
|
+
return `export { ${exportName} as default } from '${sourceModule}'`;
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return generateHandlerModule(handler);
|
|
65
107
|
},
|
|
66
108
|
config(userConfig, env) {
|
|
67
109
|
const userOptimize = userConfig.optimizeDeps;
|
|
@@ -111,6 +153,12 @@ function fict(options = {}) {
|
|
|
111
153
|
// Our plugin will handle the full transformation
|
|
112
154
|
include: /\.(ts|js|mts|mjs|cjs)$/
|
|
113
155
|
},
|
|
156
|
+
build: {
|
|
157
|
+
rollupOptions: {
|
|
158
|
+
// Preserve exports in entry chunks to prevent tree-shaking of handler exports
|
|
159
|
+
preserveEntrySignatures: "exports-only"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
114
162
|
resolve: {
|
|
115
163
|
...userConfig.resolve ?? {},
|
|
116
164
|
dedupe: Array.from(dedupe)
|
|
@@ -137,6 +185,7 @@ function fict(options = {}) {
|
|
|
137
185
|
...compilerOptions,
|
|
138
186
|
dev: compilerOptions.dev ?? isDev,
|
|
139
187
|
sourcemap: compilerOptions.sourcemap ?? true,
|
|
188
|
+
filename,
|
|
140
189
|
moduleMetadata,
|
|
141
190
|
resolveModuleMetadata: (source, importer) => {
|
|
142
191
|
const userResolved = compilerOptions.resolveModuleMetadata?.(source, importer);
|
|
@@ -227,9 +276,44 @@ function fict(options = {}) {
|
|
|
227
276
|
if (!result || !result.code) {
|
|
228
277
|
return null;
|
|
229
278
|
}
|
|
279
|
+
let finalCode = result.code;
|
|
280
|
+
let finalMap = result.map;
|
|
281
|
+
const shouldSplit = options.functionSplitting ?? (config?.command === "build" && (compilerOptions.resumable || !config?.build?.ssr));
|
|
282
|
+
console.log(
|
|
283
|
+
`[fict-plugin] shouldSplit=${shouldSplit}, ssr=${config?.build?.ssr}, resumable=${compilerOptions.resumable}, file=${filename}`
|
|
284
|
+
);
|
|
285
|
+
if (shouldSplit) {
|
|
286
|
+
let splitResult = null;
|
|
287
|
+
try {
|
|
288
|
+
splitResult = extractAndRewriteHandlers(finalCode, filename);
|
|
289
|
+
} catch (e) {
|
|
290
|
+
console.error("[fict-plugin] extractAndRewriteHandlers error:", e);
|
|
291
|
+
}
|
|
292
|
+
console.log(
|
|
293
|
+
`[fict-plugin] splitResult: ${splitResult ? splitResult.handlers.length + " handlers" : "null"}`
|
|
294
|
+
);
|
|
295
|
+
if (splitResult) {
|
|
296
|
+
console.log(
|
|
297
|
+
`[fict-plugin] Function splitting: ${filename} - ${splitResult.handlers.length} handlers extracted`
|
|
298
|
+
);
|
|
299
|
+
finalCode = splitResult.code;
|
|
300
|
+
finalMap = null;
|
|
301
|
+
if (config?.command === "build" && !config?.build?.ssr) {
|
|
302
|
+
for (const handlerName of splitResult.handlers) {
|
|
303
|
+
const handlerId = createHandlerId(filename, handlerName);
|
|
304
|
+
const virtualModuleId = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
|
|
305
|
+
this.emitFile({
|
|
306
|
+
type: "chunk",
|
|
307
|
+
id: virtualModuleId,
|
|
308
|
+
name: `handler-${handlerName}`
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
230
314
|
const transformed = {
|
|
231
|
-
code:
|
|
232
|
-
map:
|
|
315
|
+
code: finalCode,
|
|
316
|
+
map: finalMap
|
|
233
317
|
};
|
|
234
318
|
if (cacheKey) {
|
|
235
319
|
await cacheStore.set(cacheKey, transformed);
|
|
@@ -255,6 +339,40 @@ function fict(options = {}) {
|
|
|
255
339
|
path: "*"
|
|
256
340
|
});
|
|
257
341
|
}
|
|
342
|
+
},
|
|
343
|
+
generateBundle(_options, bundle) {
|
|
344
|
+
if (!config || config.command !== "build") return;
|
|
345
|
+
if (config.build.ssr) return;
|
|
346
|
+
const base = config.base ?? "/";
|
|
347
|
+
const manifest = {};
|
|
348
|
+
for (const output of Object.values(bundle)) {
|
|
349
|
+
if (output.type !== "chunk") continue;
|
|
350
|
+
const fileName = output.fileName;
|
|
351
|
+
const url = joinBasePath(base, fileName);
|
|
352
|
+
for (const moduleId of Object.keys(output.modules)) {
|
|
353
|
+
if (!moduleId) continue;
|
|
354
|
+
if (moduleId.startsWith(VIRTUAL_HANDLER_PREFIX)) {
|
|
355
|
+
const handlerId = moduleId.slice(VIRTUAL_HANDLER_PREFIX.length);
|
|
356
|
+
const virtualKey = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
|
|
357
|
+
if (!manifest[virtualKey]) {
|
|
358
|
+
manifest[virtualKey] = url;
|
|
359
|
+
}
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (moduleId.startsWith("\0")) continue;
|
|
363
|
+
const normalized = normalizeFileName(moduleId, config.root);
|
|
364
|
+
if (!path.isAbsolute(normalized)) continue;
|
|
365
|
+
const key = pathToFileURL(normalized).href;
|
|
366
|
+
if (!manifest[key]) {
|
|
367
|
+
manifest[key] = url;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.emitFile({
|
|
372
|
+
type: "asset",
|
|
373
|
+
fileName: "fict.manifest.json",
|
|
374
|
+
source: JSON.stringify(manifest)
|
|
375
|
+
});
|
|
258
376
|
}
|
|
259
377
|
};
|
|
260
378
|
}
|
|
@@ -319,6 +437,12 @@ function normalizeFileName(id, root) {
|
|
|
319
437
|
if (root) return path.normalize(path.resolve(root, clean));
|
|
320
438
|
return path.normalize(path.resolve(clean));
|
|
321
439
|
}
|
|
440
|
+
function joinBasePath(base, fileName) {
|
|
441
|
+
if (!base) return fileName;
|
|
442
|
+
if (base === "/") return `/${fileName}`;
|
|
443
|
+
const normalized = base.endsWith("/") ? base : `${base}/`;
|
|
444
|
+
return `${normalized}${fileName}`;
|
|
445
|
+
}
|
|
322
446
|
function normalizeAliases(aliases) {
|
|
323
447
|
if (!aliases) return [];
|
|
324
448
|
if (Array.isArray(aliases)) {
|
|
@@ -503,7 +627,439 @@ async function createTypeScriptProject(ts, rootDir, configPath) {
|
|
|
503
627
|
dispose: () => service.dispose?.()
|
|
504
628
|
};
|
|
505
629
|
}
|
|
630
|
+
function parseHandlerId(handlerId) {
|
|
631
|
+
const separatorIndex = handlerId.lastIndexOf("$$");
|
|
632
|
+
if (separatorIndex === -1) {
|
|
633
|
+
return [handlerId, "default"];
|
|
634
|
+
}
|
|
635
|
+
return [handlerId.slice(0, separatorIndex), handlerId.slice(separatorIndex + 2)];
|
|
636
|
+
}
|
|
637
|
+
function createHandlerId(sourceModule, exportName) {
|
|
638
|
+
return `${sourceModule}$$${exportName}`;
|
|
639
|
+
}
|
|
640
|
+
function generateHandlerModule(handler) {
|
|
641
|
+
if (!handler.code) {
|
|
642
|
+
return `export { ${handler.exportName} as default } from '${handler.sourceModule}';
|
|
643
|
+
`;
|
|
644
|
+
}
|
|
645
|
+
const importsByModule = /* @__PURE__ */ new Map();
|
|
646
|
+
for (const helperName of handler.helpersUsed) {
|
|
647
|
+
const helper = RUNTIME_HELPERS[helperName];
|
|
648
|
+
if (!helper) continue;
|
|
649
|
+
const existing = importsByModule.get(helper.from) ?? [];
|
|
650
|
+
if (!existing.includes(helper.import)) {
|
|
651
|
+
existing.push(helper.import);
|
|
652
|
+
}
|
|
653
|
+
importsByModule.set(helper.from, existing);
|
|
654
|
+
}
|
|
655
|
+
const imports = [];
|
|
656
|
+
for (const [module, names] of importsByModule) {
|
|
657
|
+
imports.push(`import { ${names.join(", ")} } from '${module}';`);
|
|
658
|
+
}
|
|
659
|
+
if (handler.localDeps.length > 0) {
|
|
660
|
+
const depImports = handler.localDeps.map((dep) => `${HANDLER_DEP_PREFIX}${dep} as ${dep}`);
|
|
661
|
+
imports.push(`import { ${depImports.join(", ")} } from '${handler.sourceModule}';`);
|
|
662
|
+
}
|
|
663
|
+
return `${imports.join("\n")}${imports.length > 0 ? "\n\n" : ""}export default ${handler.code};
|
|
664
|
+
`;
|
|
665
|
+
}
|
|
666
|
+
var HANDLER_DEP_PREFIX = "__fict_dep_";
|
|
667
|
+
function registerExtractedHandler(sourceModule, exportName, helpersUsed, code, localDeps = []) {
|
|
668
|
+
const handlerId = createHandlerId(sourceModule, exportName);
|
|
669
|
+
extractedHandlers.set(handlerId, {
|
|
670
|
+
sourceModule,
|
|
671
|
+
exportName,
|
|
672
|
+
helpersUsed,
|
|
673
|
+
localDeps,
|
|
674
|
+
code
|
|
675
|
+
});
|
|
676
|
+
return `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}`;
|
|
677
|
+
}
|
|
678
|
+
var RUNTIME_HELPERS = {
|
|
679
|
+
__fictUseLexicalScope: { import: "__fictUseLexicalScope", from: "@fictjs/runtime/internal" },
|
|
680
|
+
__fictGetScopeProps: { import: "__fictGetScopeProps", from: "@fictjs/runtime/internal" },
|
|
681
|
+
__fictGetSSRScope: { import: "__fictGetSSRScope", from: "@fictjs/runtime/internal" },
|
|
682
|
+
__fictEnsureScope: { import: "__fictEnsureScope", from: "@fictjs/runtime/internal" },
|
|
683
|
+
__fictPrepareContext: { import: "__fictPrepareContext", from: "@fictjs/runtime/internal" },
|
|
684
|
+
__fictPushContext: { import: "__fictPushContext", from: "@fictjs/runtime/internal" },
|
|
685
|
+
__fictPopContext: { import: "__fictPopContext", from: "@fictjs/runtime/internal" },
|
|
686
|
+
hydrateComponent: { import: "hydrateComponent", from: "@fictjs/runtime/internal" },
|
|
687
|
+
__fictQrl: { import: "__fictQrl", from: "@fictjs/runtime/internal" }
|
|
688
|
+
};
|
|
689
|
+
var GLOBAL_IDENTIFIERS = /* @__PURE__ */ new Set([
|
|
690
|
+
// JavaScript globals
|
|
691
|
+
"undefined",
|
|
692
|
+
"null",
|
|
693
|
+
"true",
|
|
694
|
+
"false",
|
|
695
|
+
"NaN",
|
|
696
|
+
"Infinity",
|
|
697
|
+
"globalThis",
|
|
698
|
+
"window",
|
|
699
|
+
"document",
|
|
700
|
+
"console",
|
|
701
|
+
"setTimeout",
|
|
702
|
+
"setInterval",
|
|
703
|
+
"clearTimeout",
|
|
704
|
+
"clearInterval",
|
|
705
|
+
"requestAnimationFrame",
|
|
706
|
+
"cancelAnimationFrame",
|
|
707
|
+
"fetch",
|
|
708
|
+
"URL",
|
|
709
|
+
"URLSearchParams",
|
|
710
|
+
"FormData",
|
|
711
|
+
"Headers",
|
|
712
|
+
"Request",
|
|
713
|
+
"Response",
|
|
714
|
+
"AbortController",
|
|
715
|
+
"AbortSignal",
|
|
716
|
+
// Built-in constructors
|
|
717
|
+
"Object",
|
|
718
|
+
"Array",
|
|
719
|
+
"String",
|
|
720
|
+
"Number",
|
|
721
|
+
"Boolean",
|
|
722
|
+
"Symbol",
|
|
723
|
+
"BigInt",
|
|
724
|
+
"Date",
|
|
725
|
+
"RegExp",
|
|
726
|
+
"Error",
|
|
727
|
+
"TypeError",
|
|
728
|
+
"RangeError",
|
|
729
|
+
"SyntaxError",
|
|
730
|
+
"Map",
|
|
731
|
+
"Set",
|
|
732
|
+
"WeakMap",
|
|
733
|
+
"WeakSet",
|
|
734
|
+
"Promise",
|
|
735
|
+
"Proxy",
|
|
736
|
+
"Reflect",
|
|
737
|
+
"JSON",
|
|
738
|
+
"Math",
|
|
739
|
+
"Intl",
|
|
740
|
+
// Event and DOM
|
|
741
|
+
"Event",
|
|
742
|
+
"CustomEvent",
|
|
743
|
+
"Element",
|
|
744
|
+
"Node",
|
|
745
|
+
"HTMLElement"
|
|
746
|
+
]);
|
|
747
|
+
function collectReferencedIdentifiers(node, localBindings) {
|
|
748
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
749
|
+
function visitNode(current, parent, key) {
|
|
750
|
+
if (!current) return;
|
|
751
|
+
if (t.isIdentifier(current)) {
|
|
752
|
+
const name = current.name;
|
|
753
|
+
if (parent && t.isMemberExpression(parent) && parent.property === current && !parent.computed) {
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
if (parent && t.isObjectProperty(parent) && parent.key === current && !parent.computed) {
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
if (parent && t.isVariableDeclarator(parent) && parent.id === current) {
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (parent && (t.isFunctionDeclaration(parent) || t.isFunctionExpression(parent)) && parent.id === current) {
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (key === "params") {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
if (parent && t.isCatchClause(parent) && parent.param === current) {
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
if (localBindings.has(name)) {
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
if (GLOBAL_IDENTIFIERS.has(name)) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (RUNTIME_HELPERS[name]) {
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
referenced.add(name);
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
for (const nodeKey of Object.keys(current)) {
|
|
784
|
+
if (nodeKey === "loc" || nodeKey === "start" || nodeKey === "end" || nodeKey === "extra" || nodeKey === "comments" || nodeKey === "leadingComments" || nodeKey === "trailingComments" || nodeKey === "innerComments") {
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
const child = current[nodeKey];
|
|
788
|
+
if (Array.isArray(child)) {
|
|
789
|
+
for (const item of child) {
|
|
790
|
+
if (item && typeof item === "object" && item !== null && "type" in item && typeof item.type === "string") {
|
|
791
|
+
visitNode(item, current, nodeKey);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
} else if (child && typeof child === "object" && child !== null && "type" in child && typeof child.type === "string") {
|
|
795
|
+
visitNode(child, current, nodeKey);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
visitNode(node, null, null);
|
|
800
|
+
return referenced;
|
|
801
|
+
}
|
|
802
|
+
function collectLocalBindings(node) {
|
|
803
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
804
|
+
function visitNode(current) {
|
|
805
|
+
if (!current) return;
|
|
806
|
+
if (t.isVariableDeclarator(current)) {
|
|
807
|
+
if (t.isIdentifier(current.id)) {
|
|
808
|
+
bindings.add(current.id.name);
|
|
809
|
+
} else if (t.isObjectPattern(current.id) || t.isArrayPattern(current.id)) {
|
|
810
|
+
const names = collectPatternIdentifiers(current.id);
|
|
811
|
+
for (const name of names) {
|
|
812
|
+
bindings.add(name);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
if (t.isFunctionDeclaration(current)) {
|
|
817
|
+
if (current.id) {
|
|
818
|
+
bindings.add(current.id.name);
|
|
819
|
+
}
|
|
820
|
+
for (const param of current.params) {
|
|
821
|
+
const names = collectPatternIdentifiers(param);
|
|
822
|
+
for (const name of names) {
|
|
823
|
+
bindings.add(name);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (t.isFunctionExpression(current)) {
|
|
828
|
+
for (const param of current.params) {
|
|
829
|
+
const names = collectPatternIdentifiers(param);
|
|
830
|
+
for (const name of names) {
|
|
831
|
+
bindings.add(name);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (t.isArrowFunctionExpression(current)) {
|
|
836
|
+
for (const param of current.params) {
|
|
837
|
+
const names = collectPatternIdentifiers(param);
|
|
838
|
+
for (const name of names) {
|
|
839
|
+
bindings.add(name);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (t.isCatchClause(current)) {
|
|
844
|
+
if (current.param && t.isIdentifier(current.param)) {
|
|
845
|
+
bindings.add(current.param.name);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
for (const nodeKey of Object.keys(current)) {
|
|
849
|
+
if (nodeKey === "loc" || nodeKey === "start" || nodeKey === "end" || nodeKey === "extra" || nodeKey === "comments" || nodeKey === "leadingComments" || nodeKey === "trailingComments" || nodeKey === "innerComments") {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
const child = current[nodeKey];
|
|
853
|
+
if (Array.isArray(child)) {
|
|
854
|
+
for (const item of child) {
|
|
855
|
+
if (item && typeof item === "object" && item !== null && "type" in item && typeof item.type === "string") {
|
|
856
|
+
visitNode(item);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
} else if (child && typeof child === "object" && child !== null && "type" in child && typeof child.type === "string") {
|
|
860
|
+
visitNode(child);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
visitNode(node);
|
|
865
|
+
return bindings;
|
|
866
|
+
}
|
|
867
|
+
function collectPatternIdentifiers(pattern) {
|
|
868
|
+
const names = [];
|
|
869
|
+
if (t.isIdentifier(pattern)) {
|
|
870
|
+
names.push(pattern.name);
|
|
871
|
+
} else if (t.isObjectPattern(pattern)) {
|
|
872
|
+
for (const prop of pattern.properties) {
|
|
873
|
+
if (t.isObjectProperty(prop) && t.isLVal(prop.value)) {
|
|
874
|
+
names.push(...collectPatternIdentifiers(prop.value));
|
|
875
|
+
} else if (t.isRestElement(prop)) {
|
|
876
|
+
names.push(...collectPatternIdentifiers(prop.argument));
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
} else if (t.isArrayPattern(pattern)) {
|
|
880
|
+
for (const element of pattern.elements) {
|
|
881
|
+
if (element) {
|
|
882
|
+
names.push(...collectPatternIdentifiers(element));
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
} else if (t.isRestElement(pattern)) {
|
|
886
|
+
names.push(...collectPatternIdentifiers(pattern.argument));
|
|
887
|
+
} else if (t.isAssignmentPattern(pattern)) {
|
|
888
|
+
names.push(...collectPatternIdentifiers(pattern.left));
|
|
889
|
+
}
|
|
890
|
+
return names;
|
|
891
|
+
}
|
|
892
|
+
function extractAndRewriteHandlers(code, sourceModule) {
|
|
893
|
+
let ast;
|
|
894
|
+
try {
|
|
895
|
+
ast = parse(code, {
|
|
896
|
+
sourceType: "module",
|
|
897
|
+
plugins: ["jsx", "typescript"]
|
|
898
|
+
});
|
|
899
|
+
} catch (e) {
|
|
900
|
+
console.error("[fict-plugin] Parse error in extractAndRewriteHandlers:", e);
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
const topLevelDeclarations = /* @__PURE__ */ new Set();
|
|
904
|
+
const importedNames = /* @__PURE__ */ new Set();
|
|
905
|
+
for (const node of ast.program.body) {
|
|
906
|
+
if (t.isImportDeclaration(node)) {
|
|
907
|
+
for (const specifier of node.specifiers) {
|
|
908
|
+
if (t.isImportSpecifier(specifier) || t.isImportDefaultSpecifier(specifier)) {
|
|
909
|
+
importedNames.add(specifier.local.name);
|
|
910
|
+
} else if (t.isImportNamespaceSpecifier(specifier)) {
|
|
911
|
+
importedNames.add(specifier.local.name);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
if (t.isFunctionDeclaration(node) && node.id) {
|
|
917
|
+
topLevelDeclarations.add(node.id.name);
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
if (t.isVariableDeclaration(node)) {
|
|
921
|
+
for (const declarator of node.declarations) {
|
|
922
|
+
if (t.isIdentifier(declarator.id)) {
|
|
923
|
+
topLevelDeclarations.add(declarator.id.name);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
if (t.isClassDeclaration(node) && node.id) {
|
|
929
|
+
topLevelDeclarations.add(node.id.name);
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
if (t.isExportNamedDeclaration(node) && node.declaration) {
|
|
933
|
+
if (t.isFunctionDeclaration(node.declaration) && node.declaration.id) {
|
|
934
|
+
topLevelDeclarations.add(node.declaration.id.name);
|
|
935
|
+
} else if (t.isVariableDeclaration(node.declaration)) {
|
|
936
|
+
for (const declarator of node.declaration.declarations) {
|
|
937
|
+
if (t.isIdentifier(declarator.id)) {
|
|
938
|
+
topLevelDeclarations.add(declarator.id.name);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
} else if (t.isClassDeclaration(node.declaration) && node.declaration.id) {
|
|
942
|
+
topLevelDeclarations.add(node.declaration.id.name);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
for (const name of importedNames) {
|
|
947
|
+
topLevelDeclarations.add(name);
|
|
948
|
+
}
|
|
949
|
+
const handlerNames = [];
|
|
950
|
+
const nodesToRemove = /* @__PURE__ */ new Set();
|
|
951
|
+
const allLocalDeps = /* @__PURE__ */ new Set();
|
|
952
|
+
traverse(ast, {
|
|
953
|
+
ExportNamedDeclaration(path2) {
|
|
954
|
+
const declaration = path2.node.declaration;
|
|
955
|
+
if (t.isVariableDeclaration(declaration)) {
|
|
956
|
+
for (const declarator of declaration.declarations) {
|
|
957
|
+
if (!t.isIdentifier(declarator.id)) continue;
|
|
958
|
+
const name = declarator.id.name;
|
|
959
|
+
if (!name.match(/^__fict_e\d+$/)) continue;
|
|
960
|
+
if (!declarator.init) continue;
|
|
961
|
+
handlerNames.push(name);
|
|
962
|
+
const handlerCode = generate(declarator.init).code;
|
|
963
|
+
const helpersUsed = [];
|
|
964
|
+
for (const helperName of Object.keys(RUNTIME_HELPERS)) {
|
|
965
|
+
if (handlerCode.includes(helperName)) {
|
|
966
|
+
helpersUsed.push(helperName);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
const localBindings = collectLocalBindings(declarator.init);
|
|
970
|
+
const referencedIds = collectReferencedIdentifiers(declarator.init, localBindings);
|
|
971
|
+
const localDeps = [];
|
|
972
|
+
for (const ref of referencedIds) {
|
|
973
|
+
if (topLevelDeclarations.has(ref) && !ref.match(/^__fict_[er]\d+$/)) {
|
|
974
|
+
localDeps.push(ref);
|
|
975
|
+
allLocalDeps.add(ref);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
const handlerId = createHandlerId(sourceModule, name);
|
|
979
|
+
extractedHandlers.set(handlerId, {
|
|
980
|
+
sourceModule,
|
|
981
|
+
exportName: name,
|
|
982
|
+
helpersUsed,
|
|
983
|
+
localDeps,
|
|
984
|
+
code: handlerCode
|
|
985
|
+
});
|
|
986
|
+
nodesToRemove.add(path2.node);
|
|
987
|
+
}
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
if (t.isFunctionDeclaration(declaration) && declaration.id) {
|
|
991
|
+
const name = declaration.id.name;
|
|
992
|
+
if (!name.match(/^__fict_e\d+$/)) return;
|
|
993
|
+
handlerNames.push(name);
|
|
994
|
+
const params = declaration.params;
|
|
995
|
+
const body = declaration.body;
|
|
996
|
+
const arrowFn = t.arrowFunctionExpression(params, body, declaration.async);
|
|
997
|
+
const handlerCode = generate(arrowFn).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(arrowFn);
|
|
1005
|
+
const referencedIds = collectReferencedIdentifiers(arrowFn, 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
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
if (handlerNames.length === 0) {
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
traverse(ast, {
|
|
1029
|
+
ExportNamedDeclaration(path2) {
|
|
1030
|
+
if (nodesToRemove.has(path2.node)) {
|
|
1031
|
+
path2.remove();
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
CallExpression(path2) {
|
|
1035
|
+
if (!t.isIdentifier(path2.node.callee, { name: "__fictQrl" })) return;
|
|
1036
|
+
if (path2.node.arguments.length !== 2) return;
|
|
1037
|
+
const secondArg = path2.node.arguments[1];
|
|
1038
|
+
if (!t.isStringLiteral(secondArg)) return;
|
|
1039
|
+
const handlerName = secondArg.value;
|
|
1040
|
+
if (!handlerNames.includes(handlerName)) return;
|
|
1041
|
+
const handlerId = createHandlerId(sourceModule, handlerName);
|
|
1042
|
+
const virtualUrl = `${VIRTUAL_HANDLER_RESOLVE_PREFIX}${handlerId}#default`;
|
|
1043
|
+
path2.replaceWith(t.stringLiteral(virtualUrl));
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
if (allLocalDeps.size > 0) {
|
|
1047
|
+
const reExports = [];
|
|
1048
|
+
for (const dep of allLocalDeps) {
|
|
1049
|
+
reExports.push(
|
|
1050
|
+
t.exportSpecifier(t.identifier(dep), t.identifier(`${HANDLER_DEP_PREFIX}${dep}`))
|
|
1051
|
+
);
|
|
1052
|
+
}
|
|
1053
|
+
ast.program.body.push(t.exportNamedDeclaration(null, reExports));
|
|
1054
|
+
}
|
|
1055
|
+
const result = generate(ast, {
|
|
1056
|
+
retainLines: true,
|
|
1057
|
+
compact: false
|
|
1058
|
+
});
|
|
1059
|
+
return { code: result.code, handlers: handlerNames };
|
|
1060
|
+
}
|
|
506
1061
|
export {
|
|
507
|
-
fict as default
|
|
1062
|
+
fict as default,
|
|
1063
|
+
registerExtractedHandler
|
|
508
1064
|
};
|
|
509
1065
|
//# sourceMappingURL=index.js.map
|