phantom-build 0.1.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/README.md +378 -0
- package/dist/analyzer.d.ts +11 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +330 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/ast-compat.d.ts +11 -0
- package/dist/ast-compat.d.ts.map +1 -0
- package/dist/ast-compat.js +84 -0
- package/dist/ast-compat.js.map +1 -0
- package/dist/classify/boundary.d.ts +30 -0
- package/dist/classify/boundary.d.ts.map +1 -0
- package/dist/classify/boundary.js +145 -0
- package/dist/classify/boundary.js.map +1 -0
- package/dist/classify/browser-globals.d.ts +29 -0
- package/dist/classify/browser-globals.d.ts.map +1 -0
- package/dist/classify/browser-globals.js +197 -0
- package/dist/classify/browser-globals.js.map +1 -0
- package/dist/classify/index.d.ts +14 -0
- package/dist/classify/index.d.ts.map +1 -0
- package/dist/classify/index.js +294 -0
- package/dist/classify/index.js.map +1 -0
- package/dist/classify/lazy-llm.d.ts +122 -0
- package/dist/classify/lazy-llm.d.ts.map +1 -0
- package/dist/classify/lazy-llm.js +142 -0
- package/dist/classify/lazy-llm.js.map +1 -0
- package/dist/classify/lazy.d.ts +23 -0
- package/dist/classify/lazy.d.ts.map +1 -0
- package/dist/classify/lazy.js +686 -0
- package/dist/classify/lazy.js.map +1 -0
- package/dist/classify/llm-client.d.ts +59 -0
- package/dist/classify/llm-client.d.ts.map +1 -0
- package/dist/classify/llm-client.js +193 -0
- package/dist/classify/llm-client.js.map +1 -0
- package/dist/classify/purity.d.ts +21 -0
- package/dist/classify/purity.d.ts.map +1 -0
- package/dist/classify/purity.js +47 -0
- package/dist/classify/purity.js.map +1 -0
- package/dist/classify/react-patterns.d.ts +15 -0
- package/dist/classify/react-patterns.d.ts.map +1 -0
- package/dist/classify/react-patterns.js +82 -0
- package/dist/classify/react-patterns.js.map +1 -0
- package/dist/classify/taint.d.ts +32 -0
- package/dist/classify/taint.d.ts.map +1 -0
- package/dist/classify/taint.js +68 -0
- package/dist/classify/taint.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/extract/chunk-module.d.ts +20 -0
- package/dist/extract/chunk-module.d.ts.map +1 -0
- package/dist/extract/chunk-module.js +163 -0
- package/dist/extract/chunk-module.js.map +1 -0
- package/dist/extract/client-stub.d.ts +25 -0
- package/dist/extract/client-stub.d.ts.map +1 -0
- package/dist/extract/client-stub.js +233 -0
- package/dist/extract/client-stub.js.map +1 -0
- package/dist/extract/import-resolver.d.ts +20 -0
- package/dist/extract/import-resolver.d.ts.map +1 -0
- package/dist/extract/import-resolver.js +51 -0
- package/dist/extract/import-resolver.js.map +1 -0
- package/dist/extract/index.d.ts +20 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +105 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/lazy-transform.d.ts +14 -0
- package/dist/extract/lazy-transform.d.ts.map +1 -0
- package/dist/extract/lazy-transform.js +473 -0
- package/dist/extract/lazy-transform.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +7 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +535 -0
- package/dist/plugin.js.map +1 -0
- package/dist/runtime/index.d.ts +28 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +73 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +3 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpack.d.ts +3 -0
- package/dist/webpack.d.ts.map +1 -0
- package/dist/webpack.js +3 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { resolve, dirname } from 'node:path';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve what the extracted segment needs: imports vs captured variables.
|
|
4
|
+
*
|
|
5
|
+
* ClassifiedSegment.dependencies merges fn.captured + fn.imported.
|
|
6
|
+
* We recover the split by matching back to the FunctionDependency via span,
|
|
7
|
+
* then cross-reference imported names against AnalyzedModule.imports.
|
|
8
|
+
*
|
|
9
|
+
* Relative import paths (./foo, ../bar) are rewritten to absolute paths
|
|
10
|
+
* so that chunk virtual modules (which have no filesystem location) can
|
|
11
|
+
* resolve their dependencies correctly.
|
|
12
|
+
*/
|
|
13
|
+
export function resolveImports(segment, analyzed, sourceFilePath) {
|
|
14
|
+
const fnDep = analyzed.functions.find((fn) => fn.span.start === segment.span.start && fn.span.end === segment.span.end);
|
|
15
|
+
if (!fnDep) {
|
|
16
|
+
return { imports: [], capturedParams: segment.dependencies };
|
|
17
|
+
}
|
|
18
|
+
const capturedParams = fnDep.captured;
|
|
19
|
+
const importedNames = new Set(fnDep.imported);
|
|
20
|
+
// Group needed imports by source module
|
|
21
|
+
const importMap = new Map();
|
|
22
|
+
const sourceDir = dirname(sourceFilePath);
|
|
23
|
+
for (const imp of analyzed.imports) {
|
|
24
|
+
for (const spec of imp.specifiers) {
|
|
25
|
+
if (importedNames.has(spec.local)) {
|
|
26
|
+
// Rewrite relative imports to absolute paths for virtual module resolution
|
|
27
|
+
const resolvedSource = isRelativeImport(imp.source)
|
|
28
|
+
? resolve(sourceDir, imp.source)
|
|
29
|
+
: imp.source;
|
|
30
|
+
let entry = importMap.get(resolvedSource);
|
|
31
|
+
if (!entry) {
|
|
32
|
+
entry = { source: resolvedSource, specifiers: [] };
|
|
33
|
+
importMap.set(resolvedSource, entry);
|
|
34
|
+
}
|
|
35
|
+
entry.specifiers.push(spec);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
imports: Array.from(importMap.values()),
|
|
41
|
+
capturedParams,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if an import specifier is a relative path (./foo or ../bar).
|
|
46
|
+
* Bare specifiers like 'react' or '@org/pkg' are NOT relative.
|
|
47
|
+
*/
|
|
48
|
+
function isRelativeImport(source) {
|
|
49
|
+
return source.startsWith('./') || source.startsWith('../');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=import-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../src/extract/import-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAU7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA0B,EAC1B,QAAwB,EACxB,cAAsB;IAEtB,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CACnC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,CACjF,CAAC;IAEF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;IAC/D,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC;IACtC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE9C,wCAAwC;IACxC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE1C,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAClC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,2EAA2E;gBAC3E,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC;oBACjD,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC;oBAChC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;gBAEf,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;oBACnD,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;gBACvC,CAAC;gBACD,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACvC,cAAc;KACf,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AnalyzedModule, ClassifiedSegment, LazyCandidate, SourceMapLike } from '../types.js';
|
|
2
|
+
export interface ExtractionResult {
|
|
3
|
+
clientCode: string;
|
|
4
|
+
clientMap: SourceMapLike;
|
|
5
|
+
chunkModules: Array<{
|
|
6
|
+
id: string;
|
|
7
|
+
code: string;
|
|
8
|
+
map: SourceMapLike;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extract EventHandler segments from a module into lazy-loaded chunks.
|
|
13
|
+
*
|
|
14
|
+
* Returns null if no segments qualify for extraction,
|
|
15
|
+
* otherwise returns rewritten client code + chunk modules.
|
|
16
|
+
*
|
|
17
|
+
* Uses proper AST-based codegen with esrap — no source text splicing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractModule(analyzed: AnalyzedModule, segments: ClassifiedSegment[], _sourceCode: string, confidenceThreshold: number, sourceFilePath: string, lazyCandidates?: LazyCandidate[]): ExtractionResult | null;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extract/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMnG,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;CACvE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,MAAM,EAC3B,cAAc,EAAE,MAAM,EACtB,cAAc,CAAC,EAAE,aAAa,EAAE,GAC/B,gBAAgB,GAAG,IAAI,CA6EzB"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { print } from 'esrap';
|
|
2
|
+
import tsx from 'esrap/languages/tsx';
|
|
3
|
+
import { resolveImports } from './import-resolver.js';
|
|
4
|
+
import { generateChunkModule } from './chunk-module.js';
|
|
5
|
+
import { replaceWithStub } from './client-stub.js';
|
|
6
|
+
import { applyLazyTransforms } from './lazy-transform.js';
|
|
7
|
+
/**
|
|
8
|
+
* Extract EventHandler segments from a module into lazy-loaded chunks.
|
|
9
|
+
*
|
|
10
|
+
* Returns null if no segments qualify for extraction,
|
|
11
|
+
* otherwise returns rewritten client code + chunk modules.
|
|
12
|
+
*
|
|
13
|
+
* Uses proper AST-based codegen with esrap — no source text splicing.
|
|
14
|
+
*/
|
|
15
|
+
export function extractModule(analyzed, segments, _sourceCode, confidenceThreshold, sourceFilePath, lazyCandidates) {
|
|
16
|
+
const extractable = segments.filter((seg) => seg.classification === 'EventHandler' &&
|
|
17
|
+
seg.confidence >= confidenceThreshold);
|
|
18
|
+
const hasLazyTransforms = lazyCandidates && lazyCandidates.length > 0;
|
|
19
|
+
// Nothing to do if no handler extractions and no lazy transforms
|
|
20
|
+
if (extractable.length === 0 && !hasLazyTransforms)
|
|
21
|
+
return null;
|
|
22
|
+
// Deep-copy the full AST for client code mutation
|
|
23
|
+
const clientAST = structuredClone(analyzed.ast);
|
|
24
|
+
const chunkModules = [];
|
|
25
|
+
let extractedCount = 0;
|
|
26
|
+
for (const segment of extractable) {
|
|
27
|
+
// Find the AST node in the ORIGINAL tree (for chunk module generation)
|
|
28
|
+
const originalNode = findASTNode(analyzed.ast, segment.span);
|
|
29
|
+
if (!originalNode)
|
|
30
|
+
continue;
|
|
31
|
+
// Find the corresponding node in the CLONED tree (for client mutation)
|
|
32
|
+
const clientNode = findASTNode(clientAST, segment.span);
|
|
33
|
+
if (!clientNode)
|
|
34
|
+
continue;
|
|
35
|
+
// Separate captured vars from imports (rewrites relative paths to absolute)
|
|
36
|
+
const resolution = resolveImports(segment, analyzed, sourceFilePath);
|
|
37
|
+
// Generate the chunk module from the original (unmutated) AST
|
|
38
|
+
const chunkResult = generateChunkModule(segment, originalNode, resolution.imports, resolution.capturedParams, sourceFilePath, _sourceCode);
|
|
39
|
+
chunkModules.push({ id: segment.id, code: chunkResult.code, map: chunkResult.map });
|
|
40
|
+
// Mutate the client AST node — replace function body with lazy stub
|
|
41
|
+
replaceWithStub(clientNode, segment, resolution.capturedParams);
|
|
42
|
+
extractedCount++;
|
|
43
|
+
}
|
|
44
|
+
// Apply React.lazy + Suspense transforms (after handler extraction)
|
|
45
|
+
if (hasLazyTransforms) {
|
|
46
|
+
applyLazyTransforms(clientAST, lazyCandidates);
|
|
47
|
+
}
|
|
48
|
+
// Bail if neither handler extraction nor lazy transforms produced changes
|
|
49
|
+
if (extractedCount === 0 && !hasLazyTransforms)
|
|
50
|
+
return null;
|
|
51
|
+
// Prepend `import { __phantom_lazy } from 'phantom-build/runtime'` if handlers were extracted
|
|
52
|
+
if (extractedCount > 0) {
|
|
53
|
+
const lazyImport = {
|
|
54
|
+
type: 'ImportDeclaration',
|
|
55
|
+
specifiers: [{
|
|
56
|
+
type: 'ImportSpecifier',
|
|
57
|
+
imported: { type: 'Identifier', name: '__phantom_lazy' },
|
|
58
|
+
local: { type: 'Identifier', name: '__phantom_lazy' },
|
|
59
|
+
}],
|
|
60
|
+
source: { type: 'Literal', value: 'phantom-build/runtime' },
|
|
61
|
+
};
|
|
62
|
+
clientAST.body.unshift(lazyImport);
|
|
63
|
+
}
|
|
64
|
+
// Generate client code with esrap (including source map)
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- esrap tsx visitors expect TSESTree.Node, OXC produces compatible estree nodes
|
|
66
|
+
const result = print(clientAST, tsx(), {
|
|
67
|
+
sourceMapSource: sourceFilePath,
|
|
68
|
+
sourceMapContent: _sourceCode,
|
|
69
|
+
});
|
|
70
|
+
return { clientCode: result.code, clientMap: result.map, chunkModules };
|
|
71
|
+
}
|
|
72
|
+
// ── AST helpers ──────────────────────────────────────────────────────────
|
|
73
|
+
function findASTNode(root, span) {
|
|
74
|
+
let match = null;
|
|
75
|
+
walkNode(root, (node) => {
|
|
76
|
+
const n = node;
|
|
77
|
+
if (n.start !== span.start || n.end !== span.end)
|
|
78
|
+
return;
|
|
79
|
+
if (node.type === 'ArrowFunctionExpression' ||
|
|
80
|
+
node.type === 'FunctionExpression' ||
|
|
81
|
+
node.type === 'FunctionDeclaration') {
|
|
82
|
+
match = node;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return match;
|
|
86
|
+
}
|
|
87
|
+
function walkNode(node, callback) {
|
|
88
|
+
if (!node || typeof node !== 'object')
|
|
89
|
+
return;
|
|
90
|
+
if (Array.isArray(node)) {
|
|
91
|
+
for (const child of node)
|
|
92
|
+
walkNode(child, callback);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const obj = node;
|
|
96
|
+
if (typeof obj.type !== 'string')
|
|
97
|
+
return;
|
|
98
|
+
callback(obj);
|
|
99
|
+
for (const key of Object.keys(obj)) {
|
|
100
|
+
if (key === 'type')
|
|
101
|
+
continue;
|
|
102
|
+
walkNode(obj[key], callback);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extract/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Program } from 'estree';
|
|
2
|
+
import type { LazyCandidate } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Apply React.lazy + Suspense transforms to a cloned AST.
|
|
5
|
+
*
|
|
6
|
+
* Mutates the AST in place:
|
|
7
|
+
* 1. Rewrites component imports → React.lazy(() => import(...))
|
|
8
|
+
* 2. Wraps JSX usages in <Suspense fallback={null}>
|
|
9
|
+
* 3. Ensures `lazy` and `Suspense` are imported from 'react'
|
|
10
|
+
*
|
|
11
|
+
* Should be called on a structuredClone of the original AST.
|
|
12
|
+
*/
|
|
13
|
+
export declare function applyLazyTransforms(ast: Program, candidates: LazyCandidate[]): void;
|
|
14
|
+
//# sourceMappingURL=lazy-transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-transform.d.ts","sourceRoot":"","sources":["../../src/extract/lazy-transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,OAAO,EAYR,MAAM,QAAQ,CAAC;AAChB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,aAAa,EAAE,GAC1B,IAAI,CAiBN"}
|