@trojanbox-vcp-test/site-edit-engine 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.
Files changed (174) hide show
  1. package/README.md +85 -0
  2. package/dist/execute-integration/execute-fixture-harness.d.ts +25 -0
  3. package/dist/execute-integration/execute-fixture-harness.js +37 -0
  4. package/dist/index.d.ts +3 -0
  5. package/dist/index.js +2 -0
  6. package/dist/internal/ast/diagnostics/index.d.ts +5 -0
  7. package/dist/internal/ast/diagnostics/index.js +25 -0
  8. package/dist/internal/ast/history/index.d.ts +15 -0
  9. package/dist/internal/ast/history/index.js +62 -0
  10. package/dist/internal/ast/index.d.ts +8 -0
  11. package/dist/internal/ast/index.js +5 -0
  12. package/dist/internal/ast/locators/index.d.ts +1 -0
  13. package/dist/internal/ast/locators/index.js +1 -0
  14. package/dist/internal/ast/locators/resolve-locator.d.ts +16 -0
  15. package/dist/internal/ast/locators/resolve-locator.js +920 -0
  16. package/dist/internal/ast/parser/SourceParser.d.ts +30 -0
  17. package/dist/internal/ast/parser/SourceParser.js +49 -0
  18. package/dist/internal/ast/parser/index.d.ts +21 -0
  19. package/dist/internal/ast/parser/index.js +64 -0
  20. package/dist/internal/ast/primitives/conditional/conditional-primitives.d.ts +18 -0
  21. package/dist/internal/ast/primitives/conditional/conditional-primitives.js +237 -0
  22. package/dist/internal/ast/primitives/conditional/index.d.ts +1 -0
  23. package/dist/internal/ast/primitives/conditional/index.js +1 -0
  24. package/dist/internal/ast/primitives/imports/add-import.d.ts +18 -0
  25. package/dist/internal/ast/primitives/imports/add-import.js +111 -0
  26. package/dist/internal/ast/primitives/imports/index.d.ts +2 -0
  27. package/dist/internal/ast/primitives/imports/index.js +2 -0
  28. package/dist/internal/ast/primitives/imports/remove-import.d.ts +15 -0
  29. package/dist/internal/ast/primitives/imports/remove-import.js +72 -0
  30. package/dist/internal/ast/primitives/index.d.ts +10 -0
  31. package/dist/internal/ast/primitives/index.js +10 -0
  32. package/dist/internal/ast/primitives/jsx/index.d.ts +4 -0
  33. package/dist/internal/ast/primitives/jsx/index.js +4 -0
  34. package/dist/internal/ast/primitives/jsx/insert-child.d.ts +11 -0
  35. package/dist/internal/ast/primitives/jsx/insert-child.js +69 -0
  36. package/dist/internal/ast/primitives/jsx/move-node.d.ts +9 -0
  37. package/dist/internal/ast/primitives/jsx/move-node.js +76 -0
  38. package/dist/internal/ast/primitives/jsx/remove-node.d.ts +7 -0
  39. package/dist/internal/ast/primitives/jsx/remove-node.js +36 -0
  40. package/dist/internal/ast/primitives/jsx/update-text.d.ts +8 -0
  41. package/dist/internal/ast/primitives/jsx/update-text.js +81 -0
  42. package/dist/internal/ast/primitives/next/index.d.ts +1 -0
  43. package/dist/internal/ast/primitives/next/index.js +1 -0
  44. package/dist/internal/ast/primitives/next/next-primitives.d.ts +43 -0
  45. package/dist/internal/ast/primitives/next/next-primitives.js +211 -0
  46. package/dist/internal/ast/primitives/shared.d.ts +60 -0
  47. package/dist/internal/ast/primitives/shared.js +176 -0
  48. package/dist/internal/ast/primitives/style/class-expression.d.ts +23 -0
  49. package/dist/internal/ast/primitives/style/class-expression.js +174 -0
  50. package/dist/internal/ast/primitives/style/index.d.ts +1 -0
  51. package/dist/internal/ast/primitives/style/index.js +1 -0
  52. package/dist/internal/ast/primitives/style/style-primitives.d.ts +49 -0
  53. package/dist/internal/ast/primitives/style/style-primitives.js +555 -0
  54. package/dist/internal/ast/primitives/values/index.d.ts +1 -0
  55. package/dist/internal/ast/primitives/values/index.js +1 -0
  56. package/dist/internal/ast/primitives/values/value-primitives.d.ts +42 -0
  57. package/dist/internal/ast/primitives/values/value-primitives.js +158 -0
  58. package/dist/internal/ast/printer/SourcePrinter.d.ts +21 -0
  59. package/dist/internal/ast/printer/SourcePrinter.js +76 -0
  60. package/dist/internal/ast/printer/index.d.ts +6 -0
  61. package/dist/internal/ast/printer/index.js +126 -0
  62. package/dist/internal/ast/types.d.ts +190 -0
  63. package/dist/internal/ast/types.js +1 -0
  64. package/dist/internal/capability/capability-resolver.d.ts +16 -0
  65. package/dist/internal/capability/capability-resolver.js +127 -0
  66. package/dist/internal/classname-source.d.ts +24 -0
  67. package/dist/internal/classname-source.js +220 -0
  68. package/dist/internal/contracts/IEditEngineRuntime.d.ts +18 -0
  69. package/dist/internal/contracts/IEditEngineRuntime.js +1 -0
  70. package/dist/internal/domain/EditDiagnostic.d.ts +38 -0
  71. package/dist/internal/domain/EditDiagnostic.js +43 -0
  72. package/dist/internal/events/event-bus.d.ts +14 -0
  73. package/dist/internal/events/event-bus.js +21 -0
  74. package/dist/internal/graph/graph-builder.d.ts +12 -0
  75. package/dist/internal/graph/graph-builder.js +1371 -0
  76. package/dist/internal/graph/import-resolver.d.ts +31 -0
  77. package/dist/internal/graph/import-resolver.js +109 -0
  78. package/dist/internal/graph/project-graph-builder.d.ts +32 -0
  79. package/dist/internal/graph/project-graph-builder.js +133 -0
  80. package/dist/internal/graph/types.d.ts +114 -0
  81. package/dist/internal/graph/types.js +6 -0
  82. package/dist/internal/history/undo-redo.d.ts +28 -0
  83. package/dist/internal/history/undo-redo.js +42 -0
  84. package/dist/internal/index.d.ts +2 -0
  85. package/dist/internal/index.js +1 -0
  86. package/dist/internal/planner/planner.d.ts +104 -0
  87. package/dist/internal/planner/planner.js +2533 -0
  88. package/dist/internal/planner/types.d.ts +275 -0
  89. package/dist/internal/planner/types.js +6 -0
  90. package/dist/internal/protocol/boundary.d.ts +10 -0
  91. package/dist/internal/protocol/boundary.js +3 -0
  92. package/dist/internal/protocol/capability.d.ts +47 -0
  93. package/dist/internal/protocol/capability.js +8 -0
  94. package/dist/internal/protocol/error.d.ts +43 -0
  95. package/dist/internal/protocol/error.js +38 -0
  96. package/dist/internal/protocol/event.d.ts +39 -0
  97. package/dist/internal/protocol/event.js +3 -0
  98. package/dist/internal/protocol/identity.d.ts +26 -0
  99. package/dist/internal/protocol/identity.js +30 -0
  100. package/dist/internal/protocol/operation.d.ts +224 -0
  101. package/dist/internal/protocol/operation.js +8 -0
  102. package/dist/internal/protocol/render.d.ts +212 -0
  103. package/dist/internal/protocol/render.js +3 -0
  104. package/dist/internal/protocol.d.ts +9 -0
  105. package/dist/internal/protocol.js +2 -0
  106. package/dist/internal/provenance/binding-graph.d.ts +39 -0
  107. package/dist/internal/provenance/binding-graph.js +184 -0
  108. package/dist/internal/provenance/capability-policy.d.ts +15 -0
  109. package/dist/internal/provenance/capability-policy.js +96 -0
  110. package/dist/internal/provenance/data-source-classifier.d.ts +14 -0
  111. package/dist/internal/provenance/data-source-classifier.js +281 -0
  112. package/dist/internal/provenance/resolve-text-provenance.d.ts +45 -0
  113. package/dist/internal/provenance/resolve-text-provenance.js +3090 -0
  114. package/dist/internal/provenance/types.d.ts +89 -0
  115. package/dist/internal/provenance/types.js +1 -0
  116. package/dist/internal/render/component-semantic.d.ts +11 -0
  117. package/dist/internal/render/component-semantic.js +141 -0
  118. package/dist/internal/render/content-model.d.ts +3 -0
  119. package/dist/internal/render/content-model.js +89 -0
  120. package/dist/internal/render/media-model.d.ts +3 -0
  121. package/dist/internal/render/media-model.js +45 -0
  122. package/dist/internal/render/provenance-types.d.ts +33 -0
  123. package/dist/internal/render/provenance-types.js +1 -0
  124. package/dist/internal/render/render-projection.d.ts +24 -0
  125. package/dist/internal/render/render-projection.js +281 -0
  126. package/dist/internal/render/tailwind-style-model.d.ts +19 -0
  127. package/dist/internal/render/tailwind-style-model.js +1187 -0
  128. package/dist/internal/runtime/EditEngineRuntime.d.ts +25 -0
  129. package/dist/internal/runtime/EditEngineRuntime.js +89 -0
  130. package/dist/internal/runtime/EditEngineRuntimeSnapshot.d.ts +31 -0
  131. package/dist/internal/runtime/EditEngineRuntimeSnapshot.js +15 -0
  132. package/dist/internal/runtime/InternalEditEngine.d.ts +44 -0
  133. package/dist/internal/runtime/InternalEditEngine.js +1391 -0
  134. package/dist/internal/runtime.d.ts +3 -0
  135. package/dist/internal/runtime.js +1 -0
  136. package/dist/internal/topology/topology.d.ts +6 -0
  137. package/dist/internal/topology/topology.js +98 -0
  138. package/dist/internal/topology/types.d.ts +35 -0
  139. package/dist/internal/topology/types.js +5 -0
  140. package/dist/internal/types.d.ts +1 -0
  141. package/dist/internal/types.js +1 -0
  142. package/dist/internal/writeback/in-memory-fs.d.ts +7 -0
  143. package/dist/internal/writeback/in-memory-fs.js +44 -0
  144. package/dist/internal/writeback/types.d.ts +45 -0
  145. package/dist/internal/writeback/types.js +7 -0
  146. package/dist/internal/writeback/writeback-service.d.ts +7 -0
  147. package/dist/internal/writeback/writeback-service.js +568 -0
  148. package/dist/internal-adapter.d.ts +18 -0
  149. package/dist/internal-adapter.js +350 -0
  150. package/dist/next-app-router-fs.d.ts +2 -0
  151. package/dist/next-app-router-fs.js +64 -0
  152. package/dist/next-app-router.d.ts +11 -0
  153. package/dist/next-app-router.js +140 -0
  154. package/dist/preview-runtime.d.ts +394 -0
  155. package/dist/preview-runtime.js +102 -0
  156. package/dist/public-file-system.d.ts +7 -0
  157. package/dist/public-file-system.js +1 -0
  158. package/dist/runtime-sync.d.ts +95 -0
  159. package/dist/runtime-sync.js +321 -0
  160. package/dist/runtime.d.ts +340 -0
  161. package/dist/runtime.js +134 -0
  162. package/dist/site-edit-instrumentation.d.ts +19 -0
  163. package/dist/site-edit-instrumentation.js +322 -0
  164. package/dist/snapshot-file-system.d.ts +19 -0
  165. package/dist/snapshot-file-system.js +49 -0
  166. package/dist/source-watcher.d.ts +20 -0
  167. package/dist/source-watcher.js +150 -0
  168. package/dist/source-writeback-test-harness.d.ts +244 -0
  169. package/dist/source-writeback-test-harness.js +119 -0
  170. package/dist/types.d.ts +68 -0
  171. package/dist/types.js +1 -0
  172. package/dist/webpack-loader.cjs +592 -0
  173. package/dist/webpack-loader.d.ts +27 -0
  174. package/package.json +66 -0
@@ -0,0 +1,281 @@
1
+ // ─── Render Projection ───────────────────────────────
2
+ // 来源: docs/06-development-checklist.md §7
3
+ //
4
+ // 从 graph + topology + capabilities 投影出 protocol-facing 的
5
+ // RenderDocument 和 RenderObjectDetail。
6
+ function isExternalSourceKind(kind) {
7
+ return (kind === "api-field" ||
8
+ kind === "cms-field" ||
9
+ kind === "i18n-message" ||
10
+ kind === "config-entry");
11
+ }
12
+ /**
13
+ * 投影 RenderDocument —— 从 graph + topology + capabilities 构建。
14
+ */
15
+ export function projectRenderDocument(graph, _topology, capabilities, options = {}) {
16
+ const entries = [];
17
+ for (const [key, element] of graph.elements) {
18
+ const cap = capabilities.get(key);
19
+ const operationSummary = {
20
+ canUpdateText: options.canUpdateTextByKey?.get(key) ?? cap?.canUpdateText ?? false,
21
+ canInsertChild: cap?.canInsertChild ?? false,
22
+ canMove: cap?.canMove ?? false,
23
+ canRemove: cap?.canRemove ?? false,
24
+ };
25
+ entries.push({
26
+ key,
27
+ tag: element.tag,
28
+ label: element.tag === element.componentName
29
+ ? element.tag
30
+ : `${element.tag} (${element.componentName})`,
31
+ parentKey: element.parentKey,
32
+ childKeys: [...element.childKeys],
33
+ operationSummary,
34
+ });
35
+ }
36
+ return {
37
+ routeId: graph.routeId,
38
+ version: graph.version,
39
+ rootKeys: [...graph.rootKeys],
40
+ entries,
41
+ };
42
+ }
43
+ /**
44
+ * 投影 RenderObjectDetail —— 按需加载单个节点的详细信息。
45
+ */
46
+ export function projectRenderObjectDetail(key, graph, topology, capabilities, textSources, writeTarget, provenances, conditional, componentSemantic, contentModel, mediaModel, styleSource, styleModel) {
47
+ const element = graph.elements.get(key);
48
+ const topNode = topology.nodes.get(key);
49
+ const cap = capabilities.get(key);
50
+ if (!element || !topNode || !cap) {
51
+ throw new Error(`Node not found: ${key}`);
52
+ }
53
+ const primaryProvenance = pickPrimaryProvenance(element.textSegments, provenances);
54
+ const projectedCapability = projectCapabilityModes(key, graph, element, cap, primaryProvenance);
55
+ const provenanceChain = primaryProvenance
56
+ ? projectProvenanceChain(primaryProvenance)
57
+ : undefined;
58
+ const effectiveWriteTarget = projectEffectiveWriteTarget(writeTarget, primaryProvenance);
59
+ const textSegments = element.textSegments.map((seg) => ({
60
+ index: seg.index,
61
+ value: seg.value,
62
+ editable: projectTextSegmentEditable(seg, cap, provenances?.get(seg.index) ?? null),
63
+ source: textSources.get(seg.index) ?? null,
64
+ }));
65
+ // Build ancestors chain
66
+ const ancestors = [];
67
+ let currentKey = element.parentKey;
68
+ while (currentKey) {
69
+ const parent = graph.elements.get(currentKey);
70
+ if (!parent)
71
+ break;
72
+ ancestors.push({
73
+ key: currentKey,
74
+ tag: parent.tag,
75
+ label: parent.tag,
76
+ });
77
+ currentKey = parent.parentKey;
78
+ }
79
+ ancestors.reverse(); // root first
80
+ // Build children refs
81
+ const children = element.childKeys
82
+ .map((ck) => {
83
+ const child = graph.elements.get(ck);
84
+ return child ? { key: ck, tag: child.tag, label: child.tag } : null;
85
+ })
86
+ .filter((c) => c !== null);
87
+ // Build siblings refs (exclude self)
88
+ const siblings = [];
89
+ if (element.parentKey) {
90
+ const parent = graph.elements.get(element.parentKey);
91
+ if (parent) {
92
+ for (const sibKey of parent.childKeys) {
93
+ if (sibKey === key)
94
+ continue;
95
+ const sib = graph.elements.get(sibKey);
96
+ if (sib) {
97
+ siblings.push({ key: sibKey, tag: sib.tag, label: sib.tag });
98
+ }
99
+ }
100
+ }
101
+ }
102
+ return {
103
+ key,
104
+ tag: element.tag,
105
+ componentName: element.componentName,
106
+ sourceFile: element.sourceFile,
107
+ label: element.tag,
108
+ capabilities: projectedCapability,
109
+ writeTarget,
110
+ effectiveWriteTarget,
111
+ provenanceChain,
112
+ componentSemantic,
113
+ contentModel,
114
+ mediaModel,
115
+ styleSource,
116
+ styleModel,
117
+ conditional,
118
+ textSegments,
119
+ boundaryKind: element.boundaryKind,
120
+ isOpaque: element.isOpaque,
121
+ ancestors,
122
+ children,
123
+ siblings,
124
+ };
125
+ }
126
+ /**
127
+ * 选择 detail 的写回目标。
128
+ * 只有可编辑 segment 解析到 value target 时,才升级为 value-binding。
129
+ * 否则保持 jsx-node,并保留上游传入的 file / isProxy 元数据。
130
+ */
131
+ export function projectDetailWriteTarget(topWriteTarget, segments) {
132
+ const resolvedEditableSegment = segments.find((segment) => segment.editable && segment.source && segment.source.kind !== "literal");
133
+ if (resolvedEditableSegment?.source) {
134
+ return {
135
+ kind: "value-binding",
136
+ file: resolvedEditableSegment.source.file,
137
+ componentName: topWriteTarget.componentName,
138
+ isProxy: resolvedEditableSegment.source.file !== topWriteTarget.file,
139
+ };
140
+ }
141
+ return {
142
+ kind: "jsx-node",
143
+ file: topWriteTarget.file,
144
+ componentName: topWriteTarget.componentName,
145
+ isProxy: topWriteTarget.isProxy,
146
+ };
147
+ }
148
+ function pickPrimaryProvenance(segments, provenances) {
149
+ if (!provenances) {
150
+ return null;
151
+ }
152
+ for (const segment of segments) {
153
+ const provenance = provenances.get(segment.index);
154
+ if (provenance) {
155
+ return provenance;
156
+ }
157
+ }
158
+ return null;
159
+ }
160
+ function projectCapabilityModes(key, graph, element, capability, provenance) {
161
+ const isRepeatTemplate = element.identity.structuralPath.includes("#repeat:");
162
+ const isRepeatItemRoot = graph.regions.some((region) => region.kind === "repeat-region" && region.childKeys.includes(key));
163
+ const externalReasonCode = provenance?.diagnostics.find((diagnostic) => diagnostic.code === "missing-adapter" ||
164
+ diagnostic.code === "external-source-readonly")?.code;
165
+ const updateTextMode = capability.canUpdateText
166
+ ? {
167
+ mode: provenance?.editMode ?? "direct",
168
+ reasonCode: externalReasonCode ??
169
+ (provenance?.editMode === "upstream"
170
+ ? "component-prop"
171
+ : provenance?.finalSource?.kind === "repeat-template"
172
+ ? "repeat-item-data"
173
+ : undefined),
174
+ }
175
+ : { mode: "unsupported", reasonCode: "capability-denied" };
176
+ const canUpdateText = capability.canUpdateText && isWritableUpdateTextMode(updateTextMode.mode);
177
+ return {
178
+ ...capability,
179
+ canUpdateText,
180
+ editModes: {
181
+ updateText: updateTextMode,
182
+ insertChild: capability.canInsertChild
183
+ ? {
184
+ mode: "direct",
185
+ reasonCode: isRepeatTemplate || isRepeatItemRoot
186
+ ? "repeat-template"
187
+ : undefined,
188
+ }
189
+ : { mode: "unsupported", reasonCode: "capability-denied" },
190
+ move: capability.canMove
191
+ ? {
192
+ mode: isRepeatItemRoot ? "proxy" : "direct",
193
+ reasonCode: isRepeatItemRoot ? "repeat-collection" : undefined,
194
+ }
195
+ : { mode: "unsupported", reasonCode: "capability-denied" },
196
+ remove: capability.canRemove
197
+ ? {
198
+ mode: isRepeatItemRoot ? "proxy" : "direct",
199
+ reasonCode: isRepeatItemRoot ? "repeat-collection" : undefined,
200
+ }
201
+ : { mode: "unsupported", reasonCode: "capability-denied" },
202
+ },
203
+ };
204
+ }
205
+ function projectTextSegmentEditable(segment, capability, provenance) {
206
+ if (!segment.editable || !capability.canUpdateText) {
207
+ return false;
208
+ }
209
+ if (!provenance) {
210
+ return true;
211
+ }
212
+ return isWritableUpdateTextMode(provenance.editMode);
213
+ }
214
+ function isWritableUpdateTextMode(mode) {
215
+ return mode === "direct" || mode === "proxy" || mode === "upstream";
216
+ }
217
+ function projectProvenanceChain(provenance) {
218
+ return {
219
+ finalSource: provenance.finalSource
220
+ ? {
221
+ kind: provenance.finalSource.kind,
222
+ file: provenance.finalSource.file,
223
+ displayPath: provenance.finalSource.displayPath,
224
+ externalSource: provenance.finalSource.externalSource,
225
+ }
226
+ : null,
227
+ chain: provenance.chain.map((hop) => ({
228
+ kind: hop.kind,
229
+ file: hop.file,
230
+ displayName: hop.displayName,
231
+ canEditHere: hop.canEditHere,
232
+ })),
233
+ confidence: provenance.confidence,
234
+ editMode: provenance.editMode,
235
+ diagnostics: provenance.diagnostics.map((diagnostic) => ({
236
+ code: diagnostic.code,
237
+ message: diagnostic.message,
238
+ })),
239
+ };
240
+ }
241
+ function projectEffectiveWriteTarget(writeTarget, provenance) {
242
+ if (!provenance?.finalSource) {
243
+ return {
244
+ kind: writeTarget.kind === "route-export" ? "route-export" : "jsx-node",
245
+ file: writeTarget.file,
246
+ isProxy: writeTarget.isProxy,
247
+ };
248
+ }
249
+ if (provenance.finalSource.kind === "jsx-literal") {
250
+ return {
251
+ kind: "jsx-node",
252
+ file: writeTarget.file,
253
+ isProxy: writeTarget.isProxy,
254
+ };
255
+ }
256
+ if (provenance.finalSource.kind === "config-entry" &&
257
+ provenance.finalSource.locator) {
258
+ return {
259
+ kind: "value-path",
260
+ file: provenance.finalSource.file,
261
+ isProxy: provenance.finalSource.file !== writeTarget.file,
262
+ displayPath: provenance.finalSource.displayPath,
263
+ };
264
+ }
265
+ if (isExternalSourceKind(provenance.finalSource.kind)) {
266
+ return {
267
+ kind: "external-entry",
268
+ file: provenance.finalSource.file,
269
+ isProxy: false,
270
+ displayPath: provenance.finalSource.displayPath,
271
+ sourceType: provenance.finalSource.externalSource?.sourceType,
272
+ sourceId: provenance.finalSource.externalSource?.sourceId,
273
+ };
274
+ }
275
+ return {
276
+ kind: "value-path",
277
+ file: provenance.finalSource.file,
278
+ isProxy: provenance.finalSource.file !== writeTarget.file,
279
+ displayPath: provenance.finalSource.displayPath,
280
+ };
281
+ }
@@ -0,0 +1,19 @@
1
+ import type { OperationValue, StyleBreakpoint, StyleModelView, StyleProperty, StyleSourceView, StyleStateMode } from "../protocol.js";
2
+ import type { ElementNode } from "../graph/types.js";
3
+ type TailwindStyleRule = {
4
+ property: StyleProperty;
5
+ options?: string[];
6
+ prefix?: string;
7
+ exact?: readonly string[];
8
+ isMatch?: (token: string) => boolean;
9
+ };
10
+ type TailwindStyleTokenContext = {
11
+ breakpoint?: StyleBreakpoint;
12
+ state?: StyleStateMode;
13
+ };
14
+ export declare const TAILWIND_STYLE_RULES: readonly TailwindStyleRule[];
15
+ export declare function buildStyleModel(element: ElementNode): StyleModelView;
16
+ export declare function buildStyleSource(element: ElementNode): StyleSourceView;
17
+ export declare function updateStylePropertyInClassName(currentValue: string, property: StyleProperty, value: OperationValue | null, context?: TailwindStyleTokenContext): string | null;
18
+ export declare function matchesStyleProperty(property: StyleProperty, token: string): boolean;
19
+ export {};