@trojanbox-vcp-test/site-edit-engine 0.1.0 → 0.2.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.d.ts +3 -0
- package/dist/index.js +127 -2
- package/dist/internal/protocol/operation.d.ts +2 -0
- package/dist/internal/protocol/render.d.ts +3 -30
- package/dist/internal/protocol.d.ts +1 -1
- package/dist/next-app-router.js +1 -140
- package/dist/preview-runtime.d.ts +249 -303
- package/dist/runtime-sync.d.ts +8 -8
- package/dist/runtime.d.ts +1 -127
- package/dist/site-edit-instrumentation.d.ts +1 -1
- package/dist/source-watcher.js +1 -150
- package/dist/types.d.ts +12 -14
- package/dist/webpack-loader.cjs +50 -588
- package/package.json +2 -2
- package/dist/execute-integration/execute-fixture-harness.d.ts +0 -25
- package/dist/execute-integration/execute-fixture-harness.js +0 -37
- package/dist/internal/ast/diagnostics/index.d.ts +0 -5
- package/dist/internal/ast/diagnostics/index.js +0 -25
- package/dist/internal/ast/history/index.d.ts +0 -15
- package/dist/internal/ast/history/index.js +0 -62
- package/dist/internal/ast/index.d.ts +0 -8
- package/dist/internal/ast/index.js +0 -5
- package/dist/internal/ast/locators/index.d.ts +0 -1
- package/dist/internal/ast/locators/index.js +0 -1
- package/dist/internal/ast/locators/resolve-locator.d.ts +0 -16
- package/dist/internal/ast/locators/resolve-locator.js +0 -920
- package/dist/internal/ast/parser/SourceParser.d.ts +0 -30
- package/dist/internal/ast/parser/SourceParser.js +0 -49
- package/dist/internal/ast/parser/index.d.ts +0 -21
- package/dist/internal/ast/parser/index.js +0 -64
- package/dist/internal/ast/primitives/conditional/conditional-primitives.d.ts +0 -18
- package/dist/internal/ast/primitives/conditional/conditional-primitives.js +0 -237
- package/dist/internal/ast/primitives/conditional/index.d.ts +0 -1
- package/dist/internal/ast/primitives/conditional/index.js +0 -1
- package/dist/internal/ast/primitives/imports/add-import.d.ts +0 -18
- package/dist/internal/ast/primitives/imports/add-import.js +0 -111
- package/dist/internal/ast/primitives/imports/index.d.ts +0 -2
- package/dist/internal/ast/primitives/imports/index.js +0 -2
- package/dist/internal/ast/primitives/imports/remove-import.d.ts +0 -15
- package/dist/internal/ast/primitives/imports/remove-import.js +0 -72
- package/dist/internal/ast/primitives/index.d.ts +0 -10
- package/dist/internal/ast/primitives/index.js +0 -10
- package/dist/internal/ast/primitives/jsx/index.d.ts +0 -4
- package/dist/internal/ast/primitives/jsx/index.js +0 -4
- package/dist/internal/ast/primitives/jsx/insert-child.d.ts +0 -11
- package/dist/internal/ast/primitives/jsx/insert-child.js +0 -69
- package/dist/internal/ast/primitives/jsx/move-node.d.ts +0 -9
- package/dist/internal/ast/primitives/jsx/move-node.js +0 -76
- package/dist/internal/ast/primitives/jsx/remove-node.d.ts +0 -7
- package/dist/internal/ast/primitives/jsx/remove-node.js +0 -36
- package/dist/internal/ast/primitives/jsx/update-text.d.ts +0 -8
- package/dist/internal/ast/primitives/jsx/update-text.js +0 -81
- package/dist/internal/ast/primitives/next/index.d.ts +0 -1
- package/dist/internal/ast/primitives/next/index.js +0 -1
- package/dist/internal/ast/primitives/next/next-primitives.d.ts +0 -43
- package/dist/internal/ast/primitives/next/next-primitives.js +0 -211
- package/dist/internal/ast/primitives/shared.d.ts +0 -60
- package/dist/internal/ast/primitives/shared.js +0 -176
- package/dist/internal/ast/primitives/style/class-expression.d.ts +0 -23
- package/dist/internal/ast/primitives/style/class-expression.js +0 -174
- package/dist/internal/ast/primitives/style/index.d.ts +0 -1
- package/dist/internal/ast/primitives/style/index.js +0 -1
- package/dist/internal/ast/primitives/style/style-primitives.d.ts +0 -49
- package/dist/internal/ast/primitives/style/style-primitives.js +0 -555
- package/dist/internal/ast/primitives/values/index.d.ts +0 -1
- package/dist/internal/ast/primitives/values/index.js +0 -1
- package/dist/internal/ast/primitives/values/value-primitives.d.ts +0 -42
- package/dist/internal/ast/primitives/values/value-primitives.js +0 -158
- package/dist/internal/ast/printer/SourcePrinter.d.ts +0 -21
- package/dist/internal/ast/printer/SourcePrinter.js +0 -76
- package/dist/internal/ast/printer/index.d.ts +0 -6
- package/dist/internal/ast/printer/index.js +0 -126
- package/dist/internal/ast/types.d.ts +0 -190
- package/dist/internal/ast/types.js +0 -1
- package/dist/internal/capability/capability-resolver.d.ts +0 -16
- package/dist/internal/capability/capability-resolver.js +0 -127
- package/dist/internal/classname-source.d.ts +0 -24
- package/dist/internal/classname-source.js +0 -220
- package/dist/internal/contracts/IEditEngineRuntime.d.ts +0 -18
- package/dist/internal/contracts/IEditEngineRuntime.js +0 -1
- package/dist/internal/domain/EditDiagnostic.d.ts +0 -38
- package/dist/internal/domain/EditDiagnostic.js +0 -43
- package/dist/internal/events/event-bus.d.ts +0 -14
- package/dist/internal/events/event-bus.js +0 -21
- package/dist/internal/graph/graph-builder.d.ts +0 -12
- package/dist/internal/graph/graph-builder.js +0 -1371
- package/dist/internal/graph/import-resolver.d.ts +0 -31
- package/dist/internal/graph/import-resolver.js +0 -109
- package/dist/internal/graph/project-graph-builder.d.ts +0 -32
- package/dist/internal/graph/project-graph-builder.js +0 -133
- package/dist/internal/graph/types.d.ts +0 -114
- package/dist/internal/graph/types.js +0 -6
- package/dist/internal/history/undo-redo.d.ts +0 -28
- package/dist/internal/history/undo-redo.js +0 -42
- package/dist/internal/index.d.ts +0 -2
- package/dist/internal/index.js +0 -1
- package/dist/internal/planner/planner.d.ts +0 -104
- package/dist/internal/planner/planner.js +0 -2533
- package/dist/internal/planner/types.d.ts +0 -275
- package/dist/internal/planner/types.js +0 -6
- package/dist/internal/protocol/boundary.js +0 -3
- package/dist/internal/protocol/capability.js +0 -8
- package/dist/internal/protocol/error.js +0 -38
- package/dist/internal/protocol/event.js +0 -3
- package/dist/internal/protocol/identity.js +0 -30
- package/dist/internal/protocol/operation.js +0 -8
- package/dist/internal/protocol/render.js +0 -3
- package/dist/internal/protocol.js +0 -2
- package/dist/internal/provenance/binding-graph.d.ts +0 -39
- package/dist/internal/provenance/binding-graph.js +0 -184
- package/dist/internal/provenance/capability-policy.d.ts +0 -15
- package/dist/internal/provenance/capability-policy.js +0 -96
- package/dist/internal/provenance/data-source-classifier.d.ts +0 -14
- package/dist/internal/provenance/data-source-classifier.js +0 -281
- package/dist/internal/provenance/resolve-text-provenance.d.ts +0 -45
- package/dist/internal/provenance/resolve-text-provenance.js +0 -3090
- package/dist/internal/provenance/types.d.ts +0 -89
- package/dist/internal/provenance/types.js +0 -1
- package/dist/internal/render/component-semantic.d.ts +0 -11
- package/dist/internal/render/component-semantic.js +0 -141
- package/dist/internal/render/content-model.d.ts +0 -3
- package/dist/internal/render/content-model.js +0 -89
- package/dist/internal/render/media-model.d.ts +0 -3
- package/dist/internal/render/media-model.js +0 -45
- package/dist/internal/render/provenance-types.d.ts +0 -33
- package/dist/internal/render/provenance-types.js +0 -1
- package/dist/internal/render/render-projection.d.ts +0 -24
- package/dist/internal/render/render-projection.js +0 -281
- package/dist/internal/render/tailwind-style-model.d.ts +0 -19
- package/dist/internal/render/tailwind-style-model.js +0 -1187
- package/dist/internal/runtime/EditEngineRuntime.d.ts +0 -25
- package/dist/internal/runtime/EditEngineRuntime.js +0 -89
- package/dist/internal/runtime/EditEngineRuntimeSnapshot.d.ts +0 -31
- package/dist/internal/runtime/EditEngineRuntimeSnapshot.js +0 -15
- package/dist/internal/runtime/InternalEditEngine.d.ts +0 -44
- package/dist/internal/runtime/InternalEditEngine.js +0 -1391
- package/dist/internal/runtime.d.ts +0 -3
- package/dist/internal/runtime.js +0 -1
- package/dist/internal/topology/topology.d.ts +0 -6
- package/dist/internal/topology/topology.js +0 -98
- package/dist/internal/topology/types.d.ts +0 -35
- package/dist/internal/topology/types.js +0 -5
- package/dist/internal/types.d.ts +0 -1
- package/dist/internal/types.js +0 -1
- package/dist/internal/writeback/in-memory-fs.d.ts +0 -7
- package/dist/internal/writeback/in-memory-fs.js +0 -44
- package/dist/internal/writeback/types.d.ts +0 -45
- package/dist/internal/writeback/types.js +0 -7
- package/dist/internal/writeback/writeback-service.d.ts +0 -7
- package/dist/internal/writeback/writeback-service.js +0 -568
- package/dist/internal-adapter.d.ts +0 -18
- package/dist/internal-adapter.js +0 -350
- package/dist/next-app-router-fs.js +0 -64
- package/dist/preview-runtime.js +0 -102
- package/dist/public-file-system.js +0 -1
- package/dist/runtime-sync.js +0 -321
- package/dist/runtime.js +0 -134
- package/dist/site-edit-instrumentation.js +0 -322
- package/dist/snapshot-file-system.d.ts +0 -19
- package/dist/snapshot-file-system.js +0 -49
- package/dist/source-writeback-test-harness.d.ts +0 -244
- package/dist/source-writeback-test-harness.js +0 -119
- package/dist/types.js +0 -1
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import * as t from "@babel/types";
|
|
2
|
-
/**
|
|
3
|
-
* 从源文件中提取所有本地 import 路径。
|
|
4
|
-
* 不做路径解析,只返回原始 specifier。
|
|
5
|
-
*/
|
|
6
|
-
export declare function extractLocalImports(source: string): string[];
|
|
7
|
-
export declare function extractLocalImportsFromAst(ast: t.File): string[];
|
|
8
|
-
export declare function isLocalProjectSpecifier(specifier: string): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* 将 import specifier 解析为相对于 fromFile 的完整路径(不含扩展名)。
|
|
11
|
-
* 返回已规范化但不含扩展名的路径字符串。
|
|
12
|
-
*
|
|
13
|
-
* 例:
|
|
14
|
-
* fromFile = 'src/page.tsx', specifier = '../components/Card'
|
|
15
|
-
* → 'components/Card'
|
|
16
|
-
*/
|
|
17
|
-
export declare function resolveImportBase(fromFile: string, specifier: string): string;
|
|
18
|
-
/**
|
|
19
|
-
* 给定一个无扩展路径(如 'components/Card'),通过 `exists` 探测
|
|
20
|
-
* 实际存在的文件路径,返回第一个匹配的路径,或 null。
|
|
21
|
-
*
|
|
22
|
-
* 探测顺序:
|
|
23
|
-
* 1. 直接加扩展名 (.tsx, .ts, .jsx, .js)
|
|
24
|
-
* 2. 当作目录,探测 /index.tsx 等
|
|
25
|
-
*/
|
|
26
|
-
export declare function resolveFile(basePath: string, exists: (path: string) => Promise<boolean>): Promise<string | null>;
|
|
27
|
-
/**
|
|
28
|
-
* 从 fromFile 解析并定位 specifier 对应的真实文件路径。
|
|
29
|
-
* 返回 resolved 文件路径,或 null(文件不存在)。
|
|
30
|
-
*/
|
|
31
|
-
export declare function resolveLocalImport(fromFile: string, specifier: string, exists: (path: string) => Promise<boolean>): Promise<string | null>;
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
// ─── Import Resolver ─────────────────────────────────
|
|
2
|
-
// 从源文件 AST 中提取本地 import,并将其解析为真实文件路径。
|
|
3
|
-
// 支持相对路径和 Next.js 常见 project-root alias `@/`,跳过 node_modules。
|
|
4
|
-
import * as parser from "@babel/parser";
|
|
5
|
-
import * as t from "@babel/types";
|
|
6
|
-
import * as nodePath from "node:path";
|
|
7
|
-
// ── Constants ──
|
|
8
|
-
const EXTENSIONS = [".tsx", ".ts", ".jsx", ".js"];
|
|
9
|
-
const INDEX_SUFFIXES = EXTENSIONS.map((ext) => `${nodePath.sep === "\\" ? "\\" : "/"}index${ext}`);
|
|
10
|
-
// ── Extract local import specifiers from source ──
|
|
11
|
-
/**
|
|
12
|
-
* 从源文件中提取所有本地 import 路径。
|
|
13
|
-
* 不做路径解析,只返回原始 specifier。
|
|
14
|
-
*/
|
|
15
|
-
export function extractLocalImports(source) {
|
|
16
|
-
let ast = null;
|
|
17
|
-
try {
|
|
18
|
-
ast = parser.parse(source, {
|
|
19
|
-
sourceType: "module",
|
|
20
|
-
plugins: ["jsx", "typescript"],
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
return extractLocalImportsFromAst(ast);
|
|
27
|
-
}
|
|
28
|
-
export function extractLocalImportsFromAst(ast) {
|
|
29
|
-
const specifiers = [];
|
|
30
|
-
for (const node of ast.program.body) {
|
|
31
|
-
// import ... from '...'
|
|
32
|
-
if (t.isImportDeclaration(node) &&
|
|
33
|
-
typeof node.source.value === "string" &&
|
|
34
|
-
isLocalProjectSpecifier(node.source.value)) {
|
|
35
|
-
specifiers.push(node.source.value);
|
|
36
|
-
}
|
|
37
|
-
// export { ... } from '...'
|
|
38
|
-
if (t.isExportNamedDeclaration(node) &&
|
|
39
|
-
node.source &&
|
|
40
|
-
typeof node.source.value === "string" &&
|
|
41
|
-
isLocalProjectSpecifier(node.source.value)) {
|
|
42
|
-
specifiers.push(node.source.value);
|
|
43
|
-
}
|
|
44
|
-
// export * from '...'
|
|
45
|
-
if (t.isExportAllDeclaration(node) &&
|
|
46
|
-
typeof node.source.value === "string" &&
|
|
47
|
-
isLocalProjectSpecifier(node.source.value)) {
|
|
48
|
-
specifiers.push(node.source.value);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return specifiers;
|
|
52
|
-
}
|
|
53
|
-
export function isLocalProjectSpecifier(specifier) {
|
|
54
|
-
return (specifier.startsWith("./") ||
|
|
55
|
-
specifier.startsWith("../") ||
|
|
56
|
-
specifier.startsWith("@/"));
|
|
57
|
-
}
|
|
58
|
-
// ── Resolve import specifier relative to a file ──
|
|
59
|
-
/**
|
|
60
|
-
* 将 import specifier 解析为相对于 fromFile 的完整路径(不含扩展名)。
|
|
61
|
-
* 返回已规范化但不含扩展名的路径字符串。
|
|
62
|
-
*
|
|
63
|
-
* 例:
|
|
64
|
-
* fromFile = 'src/page.tsx', specifier = '../components/Card'
|
|
65
|
-
* → 'components/Card'
|
|
66
|
-
*/
|
|
67
|
-
export function resolveImportBase(fromFile, specifier) {
|
|
68
|
-
if (specifier.startsWith("@/")) {
|
|
69
|
-
return specifier.slice(2).replace(/\\/g, "/");
|
|
70
|
-
}
|
|
71
|
-
const dir = nodePath.dirname(fromFile);
|
|
72
|
-
// Use POSIX join for consistency with forward-slash paths used in the engine
|
|
73
|
-
const joined = nodePath.join(dir, specifier);
|
|
74
|
-
// Normalize away any .. / . segments; use forward slashes for consistency
|
|
75
|
-
return joined.replace(/\\/g, "/");
|
|
76
|
-
}
|
|
77
|
-
// ── Resolve to actual file path with extension ──
|
|
78
|
-
/**
|
|
79
|
-
* 给定一个无扩展路径(如 'components/Card'),通过 `exists` 探测
|
|
80
|
-
* 实际存在的文件路径,返回第一个匹配的路径,或 null。
|
|
81
|
-
*
|
|
82
|
-
* 探测顺序:
|
|
83
|
-
* 1. 直接加扩展名 (.tsx, .ts, .jsx, .js)
|
|
84
|
-
* 2. 当作目录,探测 /index.tsx 等
|
|
85
|
-
*/
|
|
86
|
-
export async function resolveFile(basePath, exists) {
|
|
87
|
-
// 1. Try direct extensions
|
|
88
|
-
for (const ext of EXTENSIONS) {
|
|
89
|
-
const candidate = `${basePath}${ext}`;
|
|
90
|
-
if (await exists(candidate))
|
|
91
|
-
return candidate;
|
|
92
|
-
}
|
|
93
|
-
// 2. Try index variants
|
|
94
|
-
for (const suffix of INDEX_SUFFIXES) {
|
|
95
|
-
const candidate = `${basePath}${suffix}`;
|
|
96
|
-
if (await exists(candidate))
|
|
97
|
-
return candidate;
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
// ── Combined helper ──
|
|
102
|
-
/**
|
|
103
|
-
* 从 fromFile 解析并定位 specifier 对应的真实文件路径。
|
|
104
|
-
* 返回 resolved 文件路径,或 null(文件不存在)。
|
|
105
|
-
*/
|
|
106
|
-
export async function resolveLocalImport(fromFile, specifier, exists) {
|
|
107
|
-
const base = resolveImportBase(fromFile, specifier);
|
|
108
|
-
return resolveFile(base, exists);
|
|
109
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { RenderSourceGraph } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* 多文件构建结果:
|
|
4
|
-
* - graph: 合并后的 RenderSourceGraph(多文件 fileIndex)
|
|
5
|
-
* - allSources: 本次加载的所有文件源码(供 engine 更新缓存用)
|
|
6
|
-
*/
|
|
7
|
-
export interface MultiFileGraphResult {
|
|
8
|
-
graph: RenderSourceGraph;
|
|
9
|
-
/** 所有参与构建的文件源码,key = 文件路径 */
|
|
10
|
-
allSources: Map<string, string>;
|
|
11
|
-
}
|
|
12
|
-
export interface MultiFileGraphOptions {
|
|
13
|
-
/** 递归最大深度,默认 10 */
|
|
14
|
-
maxDepth?: number;
|
|
15
|
-
/** 目标 graph 版本号,默认 1 */
|
|
16
|
-
version?: number;
|
|
17
|
-
/** Additional entry files that are rendered with the primary route entry. */
|
|
18
|
-
additionalEntries?: Array<{
|
|
19
|
-
file: string;
|
|
20
|
-
source: string;
|
|
21
|
-
}>;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* 构建多文件 RenderSourceGraph。
|
|
25
|
-
*
|
|
26
|
-
* @param entryFile 入口文件路径(例如 'src/app/page.tsx')
|
|
27
|
-
* @param entrySource 入口文件源码(已预先读取,避免重复 IO)
|
|
28
|
-
* @param readFile 读取文件内容(async)
|
|
29
|
-
* @param exists 判断文件是否存在(async)
|
|
30
|
-
* @param opts 可选配置
|
|
31
|
-
*/
|
|
32
|
-
export declare function buildMultiFileRenderGraph(entryFile: string, entrySource: string, readFile: (path: string) => Promise<string>, exists: (path: string) => Promise<boolean>, opts?: MultiFileGraphOptions): Promise<MultiFileGraphResult>;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
// ─── Project Graph Builder ───────────────────────────
|
|
2
|
-
// 基于 import 递归构建多文件 ProjectSourceGraph。
|
|
3
|
-
// 核心职责:
|
|
4
|
-
// 1. 从入口文件出发,提取本地 import
|
|
5
|
-
// 2. 递归加载并解析已导入文件
|
|
6
|
-
// 3. 将所有单文件 graph 合并为完整的 RenderSourceGraph
|
|
7
|
-
// (多文件 fileIndex、全量 elements/regions)
|
|
8
|
-
//
|
|
9
|
-
// 注意:
|
|
10
|
-
// - 本阶段 isOpaque 保持 true(组件边界仍然不透明)
|
|
11
|
-
// - rootKeys 只含 entryFile 的根节点
|
|
12
|
-
// - 后续 Step 5 会补 importSource / transparent component 能力
|
|
13
|
-
import { buildGraphWithLocalImportsFromSource } from "./graph-builder.js";
|
|
14
|
-
import { isLocalProjectSpecifier, resolveLocalImport, } from "./import-resolver.js";
|
|
15
|
-
// ── Main entry ──
|
|
16
|
-
/**
|
|
17
|
-
* 构建多文件 RenderSourceGraph。
|
|
18
|
-
*
|
|
19
|
-
* @param entryFile 入口文件路径(例如 'src/app/page.tsx')
|
|
20
|
-
* @param entrySource 入口文件源码(已预先读取,避免重复 IO)
|
|
21
|
-
* @param readFile 读取文件内容(async)
|
|
22
|
-
* @param exists 判断文件是否存在(async)
|
|
23
|
-
* @param opts 可选配置
|
|
24
|
-
*/
|
|
25
|
-
export async function buildMultiFileRenderGraph(entryFile, entrySource, readFile, exists, opts = {}) {
|
|
26
|
-
const maxDepth = opts.maxDepth ?? 10;
|
|
27
|
-
const version = opts.version ?? 1;
|
|
28
|
-
// ── State ──
|
|
29
|
-
const allSources = new Map();
|
|
30
|
-
const singleFileGraphs = new Map();
|
|
31
|
-
const queue = [
|
|
32
|
-
{ file: entryFile, source: entrySource, depth: 0 },
|
|
33
|
-
...(opts.additionalEntries ?? []).map((entry) => ({
|
|
34
|
-
file: entry.file,
|
|
35
|
-
source: entry.source,
|
|
36
|
-
depth: 0,
|
|
37
|
-
})),
|
|
38
|
-
];
|
|
39
|
-
const visited = new Set();
|
|
40
|
-
while (queue.length > 0) {
|
|
41
|
-
const entry = queue.shift();
|
|
42
|
-
const { file, source, depth } = entry;
|
|
43
|
-
if (visited.has(file))
|
|
44
|
-
continue;
|
|
45
|
-
visited.add(file);
|
|
46
|
-
allSources.set(file, source);
|
|
47
|
-
// Build single-file graph
|
|
48
|
-
const { graph: fileGraph, localImports } = buildGraphWithLocalImportsFromSource(file, source);
|
|
49
|
-
// Resolve importedFrom raw specifiers to actual file paths for component nodes.
|
|
50
|
-
// At this point we have the exists callback available, so we can do it here.
|
|
51
|
-
for (const element of fileGraph.elements.values()) {
|
|
52
|
-
if (element.importedFrom &&
|
|
53
|
-
isLocalProjectSpecifier(element.importedFrom)) {
|
|
54
|
-
try {
|
|
55
|
-
const resolved = await resolveLocalImport(file, element.importedFrom, exists);
|
|
56
|
-
if (resolved) {
|
|
57
|
-
element.importedFrom = resolved;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
catch {
|
|
61
|
-
// Leave as raw specifier if resolution fails
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
singleFileGraphs.set(file, fileGraph);
|
|
66
|
-
// Stop recursing at maxDepth
|
|
67
|
-
if (depth >= maxDepth)
|
|
68
|
-
continue;
|
|
69
|
-
// Extract and resolve relative imports
|
|
70
|
-
for (const spec of localImports) {
|
|
71
|
-
try {
|
|
72
|
-
const resolvedFile = await resolveLocalImport(file, spec, exists);
|
|
73
|
-
if (!resolvedFile || visited.has(resolvedFile))
|
|
74
|
-
continue;
|
|
75
|
-
const importedSource = await readFile(resolvedFile);
|
|
76
|
-
queue.push({
|
|
77
|
-
file: resolvedFile,
|
|
78
|
-
source: importedSource,
|
|
79
|
-
depth: depth + 1,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// Silently skip files that can't be read
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// ── Merge all single-file graphs ──
|
|
88
|
-
const merged = mergeGraphs(entryFile, singleFileGraphs, version, (opts.additionalEntries ?? []).map((entry) => entry.file));
|
|
89
|
-
return { graph: merged, allSources };
|
|
90
|
-
}
|
|
91
|
-
// ── Merge helper ──
|
|
92
|
-
/**
|
|
93
|
-
* 将多个单文件 graph 合并为一个 RenderSourceGraph。
|
|
94
|
-
* - rootKeys: 来自 entryFile 的图
|
|
95
|
-
* - elements / regions / fileIndex: 所有文件合并
|
|
96
|
-
*/
|
|
97
|
-
function mergeGraphs(entryFile, graphs, version, additionalRootFiles = []) {
|
|
98
|
-
const elements = new Map();
|
|
99
|
-
const regions = [];
|
|
100
|
-
const fileIndex = new Map();
|
|
101
|
-
let rootKeys = [];
|
|
102
|
-
for (const [file, graph] of graphs) {
|
|
103
|
-
// Merge elements
|
|
104
|
-
for (const [key, node] of graph.elements) {
|
|
105
|
-
elements.set(key, node);
|
|
106
|
-
}
|
|
107
|
-
// Merge regions
|
|
108
|
-
for (const region of graph.regions) {
|
|
109
|
-
regions.push(region);
|
|
110
|
-
}
|
|
111
|
-
// Merge fileIndex
|
|
112
|
-
for (const [indexFile, keys] of graph.fileIndex) {
|
|
113
|
-
const existing = fileIndex.get(indexFile) ?? [];
|
|
114
|
-
fileIndex.set(indexFile, [...existing, ...keys]);
|
|
115
|
-
}
|
|
116
|
-
// Use entry file's rootKeys
|
|
117
|
-
if (file === entryFile) {
|
|
118
|
-
rootKeys = graph.rootKeys;
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (additionalRootFiles.includes(file)) {
|
|
122
|
-
rootKeys = [...rootKeys, ...graph.rootKeys];
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return {
|
|
126
|
-
routeId: entryFile,
|
|
127
|
-
rootKeys,
|
|
128
|
-
elements,
|
|
129
|
-
regions,
|
|
130
|
-
fileIndex,
|
|
131
|
-
version,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { SourceIdentity } from "../protocol.js";
|
|
2
|
-
import type { BoundaryKind } from "../protocol.js";
|
|
3
|
-
export interface SourceRange {
|
|
4
|
-
startLine: number;
|
|
5
|
-
startColumn: number;
|
|
6
|
-
endLine: number;
|
|
7
|
-
endColumn: number;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* 元素节点 —— 对应 JSX 元素 / 组件调用。
|
|
11
|
-
*/
|
|
12
|
-
export interface ElementNode {
|
|
13
|
-
identity: SourceIdentity;
|
|
14
|
-
tag: string;
|
|
15
|
-
componentName: string;
|
|
16
|
-
sourceFile: string;
|
|
17
|
-
sourceRange: SourceRange;
|
|
18
|
-
parentKey: string | null;
|
|
19
|
-
childKeys: string[];
|
|
20
|
-
textSegments: TextSegment[];
|
|
21
|
-
attributes?: AttributeSource[];
|
|
22
|
-
boundaryKind: BoundaryKind | null;
|
|
23
|
-
isOpaque: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* 组件来源文件(已解析路径,相对 projectRoot 或绝对路径)。
|
|
26
|
-
* 仅 isOpaque=true 的组件节点才会有值;
|
|
27
|
-
* graph-builder 阶段写入原始 specifier,
|
|
28
|
-
* project-graph-builder 解析后替换为真实文件路径。
|
|
29
|
-
*/
|
|
30
|
-
importedFrom?: string;
|
|
31
|
-
/**
|
|
32
|
-
* 组件在来源文件中的导出名。
|
|
33
|
-
* 默认导出为 'default',具名导出为实际导出标识符名称。
|
|
34
|
-
*/
|
|
35
|
-
exportName?: string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 区域节点 —— 描述 repeat / conditional / fragment 等语义区域。
|
|
39
|
-
*/
|
|
40
|
-
export interface RegionNode {
|
|
41
|
-
kind: BoundaryKind;
|
|
42
|
-
ownerKey: string;
|
|
43
|
-
childKeys: string[];
|
|
44
|
-
sourceRange: SourceRange;
|
|
45
|
-
sourceCandidates?: SourceCandidate[];
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* 文本段落 —— 对应可编辑的文本内容。
|
|
49
|
-
*/
|
|
50
|
-
export interface TextExpressionSource {
|
|
51
|
-
kind: "identifier" | "member-expression" | "index-expression";
|
|
52
|
-
expression: string;
|
|
53
|
-
base: string;
|
|
54
|
-
path: Array<{
|
|
55
|
-
kind: "property";
|
|
56
|
-
name: string;
|
|
57
|
-
} | {
|
|
58
|
-
kind: "index";
|
|
59
|
-
index: number;
|
|
60
|
-
}>;
|
|
61
|
-
}
|
|
62
|
-
export type StaticAttributeValue = string | number | boolean | null | StaticAttributeValue[] | {
|
|
63
|
-
[key: string]: StaticAttributeValue;
|
|
64
|
-
};
|
|
65
|
-
export interface AttributeSource {
|
|
66
|
-
name: string;
|
|
67
|
-
value: string;
|
|
68
|
-
sourceRange: SourceRange;
|
|
69
|
-
source: TextExpressionSource | null;
|
|
70
|
-
resolvedValue?: StaticAttributeValue;
|
|
71
|
-
}
|
|
72
|
-
export interface RepeatSourceCandidate {
|
|
73
|
-
kind: "repeat-template";
|
|
74
|
-
collectionExpression: string;
|
|
75
|
-
collectionSource: TextExpressionSource | null;
|
|
76
|
-
itemParamName?: string;
|
|
77
|
-
indexParamName?: string;
|
|
78
|
-
}
|
|
79
|
-
export interface ConditionalSourceCandidate {
|
|
80
|
-
kind: "conditional-branch";
|
|
81
|
-
conditionExpression: string;
|
|
82
|
-
conditionSource: TextExpressionSource | null;
|
|
83
|
-
}
|
|
84
|
-
export type SourceCandidate = RepeatSourceCandidate | ConditionalSourceCandidate;
|
|
85
|
-
export interface TextSegment {
|
|
86
|
-
index: number;
|
|
87
|
-
value: string;
|
|
88
|
-
sourceRange: SourceRange;
|
|
89
|
-
editable: boolean;
|
|
90
|
-
source: TextExpressionSource | null;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* 项目源图 —— 跨文件的完整 graph。
|
|
94
|
-
*/
|
|
95
|
-
export interface ProjectSourceGraph {
|
|
96
|
-
/** 所有元素节点,key → ElementNode */
|
|
97
|
-
elements: Map<string, ElementNode>;
|
|
98
|
-
/** 所有区域节点 */
|
|
99
|
-
regions: RegionNode[];
|
|
100
|
-
/** 文件 → keys 的反向索引 */
|
|
101
|
-
fileIndex: Map<string, string[]>;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* 渲染源图 —— 单路由视角的 graph。
|
|
105
|
-
*/
|
|
106
|
-
export interface RenderSourceGraph {
|
|
107
|
-
routeId: string;
|
|
108
|
-
rootKeys: string[];
|
|
109
|
-
elements: Map<string, ElementNode>;
|
|
110
|
-
regions: RegionNode[];
|
|
111
|
-
/** 文件 → keys 的反向索引 */
|
|
112
|
-
fileIndex: Map<string, string[]>;
|
|
113
|
-
version: number;
|
|
114
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export interface FileSnapshot {
|
|
2
|
-
file: string;
|
|
3
|
-
content: string;
|
|
4
|
-
version: number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* 历史条目 —— 一次操作前后的文件快照。
|
|
8
|
-
*/
|
|
9
|
-
export interface HistoryEntry {
|
|
10
|
-
requestId: string;
|
|
11
|
-
beforeSnapshots: FileSnapshot[];
|
|
12
|
-
afterSnapshots: FileSnapshot[];
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* 撤销/重做管理器。
|
|
16
|
-
*/
|
|
17
|
-
export interface UndoRedoManager {
|
|
18
|
-
push(entry: HistoryEntry): void;
|
|
19
|
-
undo(): HistoryEntry | null;
|
|
20
|
-
redo(): HistoryEntry | null;
|
|
21
|
-
canUndo(): boolean;
|
|
22
|
-
canRedo(): boolean;
|
|
23
|
-
clear(): void;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* 创建撤销/重做管理器。
|
|
27
|
-
*/
|
|
28
|
-
export declare function createUndoRedoManager(): UndoRedoManager;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// ─── Undo/Redo History ───────────────────────────────
|
|
2
|
-
// 来源: docs/06-development-checklist.md §6
|
|
3
|
-
//
|
|
4
|
-
// 基于 FileSnapshot 的撤销/重做栈。
|
|
5
|
-
/**
|
|
6
|
-
* 创建撤销/重做管理器。
|
|
7
|
-
*/
|
|
8
|
-
export function createUndoRedoManager() {
|
|
9
|
-
const undoStack = [];
|
|
10
|
-
const redoStack = [];
|
|
11
|
-
return {
|
|
12
|
-
push(entry) {
|
|
13
|
-
undoStack.push(entry);
|
|
14
|
-
// 新操作清空 redo 栈
|
|
15
|
-
redoStack.length = 0;
|
|
16
|
-
},
|
|
17
|
-
undo() {
|
|
18
|
-
const entry = undoStack.pop();
|
|
19
|
-
if (!entry)
|
|
20
|
-
return null;
|
|
21
|
-
redoStack.push(entry);
|
|
22
|
-
return entry;
|
|
23
|
-
},
|
|
24
|
-
redo() {
|
|
25
|
-
const entry = redoStack.pop();
|
|
26
|
-
if (!entry)
|
|
27
|
-
return null;
|
|
28
|
-
undoStack.push(entry);
|
|
29
|
-
return entry;
|
|
30
|
-
},
|
|
31
|
-
canUndo() {
|
|
32
|
-
return undoStack.length > 0;
|
|
33
|
-
},
|
|
34
|
-
canRedo() {
|
|
35
|
-
return redoStack.length > 0;
|
|
36
|
-
},
|
|
37
|
-
clear() {
|
|
38
|
-
undoStack.length = 0;
|
|
39
|
-
redoStack.length = 0;
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
package/dist/internal/index.d.ts
DELETED
package/dist/internal/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createEditEngineRuntime, EditEngineRuntime } from "./runtime.js";
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { NodeCapabilitySnapshot, OperationErrorCode, OperationRequest, OperationValue, ResolvedTextWriteTarget, RewritePlan } from "./types.js";
|
|
2
|
-
import { type ValuePathSegment } from "../ast/index.js";
|
|
3
|
-
import type { ComponentSemanticDescriptor, ContentModelView } from "../protocol.js";
|
|
4
|
-
import type { ProvenanceResolution } from "../provenance/types.js";
|
|
5
|
-
export interface PlannerGraphAccess {
|
|
6
|
-
getNode: (key: string) => NodeInfo | null;
|
|
7
|
-
getChildNodes?: (key: string) => NodeInfo[];
|
|
8
|
-
getCapability: (key: string) => NodeCapabilitySnapshot;
|
|
9
|
-
getFileContent: (file: string) => string;
|
|
10
|
-
getFileVersion: (file: string) => number;
|
|
11
|
-
getRouteEntryFile: (routeId: string) => string | null;
|
|
12
|
-
getComponentSemantic: (key: string) => ComponentSemanticDescriptor | null;
|
|
13
|
-
getEditableTextSegmentIndex: (key: string) => number | null;
|
|
14
|
-
getTextWriteTarget: (key: string, segmentIndex: number) => Promise<ResolvedTextWriteTarget | null>;
|
|
15
|
-
getTextProvenance?: (key: string, segmentIndex: number) => ProvenanceResolution | null;
|
|
16
|
-
}
|
|
17
|
-
export interface NodeInfo {
|
|
18
|
-
key: string;
|
|
19
|
-
file: string;
|
|
20
|
-
component: string;
|
|
21
|
-
tag?: string;
|
|
22
|
-
structuralPath: string;
|
|
23
|
-
sourceRange: {
|
|
24
|
-
startLine: number;
|
|
25
|
-
startColumn: number;
|
|
26
|
-
endLine: number;
|
|
27
|
-
endColumn: number;
|
|
28
|
-
};
|
|
29
|
-
parentKey?: string;
|
|
30
|
-
writeTarget?: string;
|
|
31
|
-
isRepeatRegion?: boolean;
|
|
32
|
-
isTemplateOwner?: boolean;
|
|
33
|
-
isBoundary?: boolean;
|
|
34
|
-
/**
|
|
35
|
-
* 组件来源文件(已解析路径),用于 cross-file move 时自动推导 add-import/remove-import 步骤。
|
|
36
|
-
* 由 graph-builder + project-graph-builder 阶段填充。
|
|
37
|
-
*/
|
|
38
|
-
importedFrom?: string;
|
|
39
|
-
/**
|
|
40
|
-
* 组件在来源文件中的导出名('default' 或具名导出名称)。
|
|
41
|
-
* 由 graph-builder 阶段填充。
|
|
42
|
-
*/
|
|
43
|
-
exportName?: string;
|
|
44
|
-
isRepeatItemRoot?: boolean;
|
|
45
|
-
repeatOwnerKey?: string;
|
|
46
|
-
contentModel?: ContentModelView;
|
|
47
|
-
richTextBlock?: {
|
|
48
|
-
field: string;
|
|
49
|
-
index: number;
|
|
50
|
-
};
|
|
51
|
-
attributes?: Array<{
|
|
52
|
-
name: string;
|
|
53
|
-
value: string;
|
|
54
|
-
source: {
|
|
55
|
-
expression: string;
|
|
56
|
-
base: string;
|
|
57
|
-
path: ValuePathSegment[];
|
|
58
|
-
} | null;
|
|
59
|
-
resolvedValue?: OperationValue;
|
|
60
|
-
}>;
|
|
61
|
-
}
|
|
62
|
-
export type PlanResult = {
|
|
63
|
-
ok: true;
|
|
64
|
-
plan: RewritePlan;
|
|
65
|
-
} | {
|
|
66
|
-
ok: false;
|
|
67
|
-
errorCode: OperationErrorCode;
|
|
68
|
-
reason: string;
|
|
69
|
-
};
|
|
70
|
-
export declare class OperationPlanner {
|
|
71
|
-
private graph;
|
|
72
|
-
constructor(graph: PlannerGraphAccess);
|
|
73
|
-
plan(request: OperationRequest): Promise<PlanResult>;
|
|
74
|
-
private planConditionalOperation;
|
|
75
|
-
private planRichTextOperation;
|
|
76
|
-
private planRichTextBlockInsert;
|
|
77
|
-
private planRichTextBlockRemoval;
|
|
78
|
-
private planRichTextBlockMove;
|
|
79
|
-
private planMediaFieldOperation;
|
|
80
|
-
private buildAttributeRewriteStep;
|
|
81
|
-
private planComponentSlotOperation;
|
|
82
|
-
private planValueCollectionOperation;
|
|
83
|
-
private resolveNodeRequest;
|
|
84
|
-
private resolveRouteRequest;
|
|
85
|
-
private planNodeAttributeOperation;
|
|
86
|
-
private planStyleClassNameOperation;
|
|
87
|
-
private planRouteOperation;
|
|
88
|
-
private buildTextRewriteSteps;
|
|
89
|
-
private checkDocumentVersion;
|
|
90
|
-
private toTextContent;
|
|
91
|
-
private planUpdateText;
|
|
92
|
-
private planRemoveNode;
|
|
93
|
-
private buildRemoveComponentImportStep;
|
|
94
|
-
private planInsertChild;
|
|
95
|
-
private planExternalBackedInsertChild;
|
|
96
|
-
private findExternalInsertContext;
|
|
97
|
-
private planRepeatBackedInsertChild;
|
|
98
|
-
private getUpstreamBackedDescendantReason;
|
|
99
|
-
private getRepeatBackedTemplateStructureReason;
|
|
100
|
-
private isInsideMapCallback;
|
|
101
|
-
private planMoveNode;
|
|
102
|
-
private planCrossFileMove;
|
|
103
|
-
private buildPlan;
|
|
104
|
-
}
|