@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.
Files changed (163) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +127 -2
  3. package/dist/internal/protocol/operation.d.ts +2 -0
  4. package/dist/internal/protocol/render.d.ts +3 -30
  5. package/dist/internal/protocol.d.ts +1 -1
  6. package/dist/next-app-router.js +1 -140
  7. package/dist/preview-runtime.d.ts +249 -303
  8. package/dist/runtime-sync.d.ts +8 -8
  9. package/dist/runtime.d.ts +1 -127
  10. package/dist/site-edit-instrumentation.d.ts +1 -1
  11. package/dist/source-watcher.js +1 -150
  12. package/dist/types.d.ts +12 -14
  13. package/dist/webpack-loader.cjs +50 -588
  14. package/package.json +2 -2
  15. package/dist/execute-integration/execute-fixture-harness.d.ts +0 -25
  16. package/dist/execute-integration/execute-fixture-harness.js +0 -37
  17. package/dist/internal/ast/diagnostics/index.d.ts +0 -5
  18. package/dist/internal/ast/diagnostics/index.js +0 -25
  19. package/dist/internal/ast/history/index.d.ts +0 -15
  20. package/dist/internal/ast/history/index.js +0 -62
  21. package/dist/internal/ast/index.d.ts +0 -8
  22. package/dist/internal/ast/index.js +0 -5
  23. package/dist/internal/ast/locators/index.d.ts +0 -1
  24. package/dist/internal/ast/locators/index.js +0 -1
  25. package/dist/internal/ast/locators/resolve-locator.d.ts +0 -16
  26. package/dist/internal/ast/locators/resolve-locator.js +0 -920
  27. package/dist/internal/ast/parser/SourceParser.d.ts +0 -30
  28. package/dist/internal/ast/parser/SourceParser.js +0 -49
  29. package/dist/internal/ast/parser/index.d.ts +0 -21
  30. package/dist/internal/ast/parser/index.js +0 -64
  31. package/dist/internal/ast/primitives/conditional/conditional-primitives.d.ts +0 -18
  32. package/dist/internal/ast/primitives/conditional/conditional-primitives.js +0 -237
  33. package/dist/internal/ast/primitives/conditional/index.d.ts +0 -1
  34. package/dist/internal/ast/primitives/conditional/index.js +0 -1
  35. package/dist/internal/ast/primitives/imports/add-import.d.ts +0 -18
  36. package/dist/internal/ast/primitives/imports/add-import.js +0 -111
  37. package/dist/internal/ast/primitives/imports/index.d.ts +0 -2
  38. package/dist/internal/ast/primitives/imports/index.js +0 -2
  39. package/dist/internal/ast/primitives/imports/remove-import.d.ts +0 -15
  40. package/dist/internal/ast/primitives/imports/remove-import.js +0 -72
  41. package/dist/internal/ast/primitives/index.d.ts +0 -10
  42. package/dist/internal/ast/primitives/index.js +0 -10
  43. package/dist/internal/ast/primitives/jsx/index.d.ts +0 -4
  44. package/dist/internal/ast/primitives/jsx/index.js +0 -4
  45. package/dist/internal/ast/primitives/jsx/insert-child.d.ts +0 -11
  46. package/dist/internal/ast/primitives/jsx/insert-child.js +0 -69
  47. package/dist/internal/ast/primitives/jsx/move-node.d.ts +0 -9
  48. package/dist/internal/ast/primitives/jsx/move-node.js +0 -76
  49. package/dist/internal/ast/primitives/jsx/remove-node.d.ts +0 -7
  50. package/dist/internal/ast/primitives/jsx/remove-node.js +0 -36
  51. package/dist/internal/ast/primitives/jsx/update-text.d.ts +0 -8
  52. package/dist/internal/ast/primitives/jsx/update-text.js +0 -81
  53. package/dist/internal/ast/primitives/next/index.d.ts +0 -1
  54. package/dist/internal/ast/primitives/next/index.js +0 -1
  55. package/dist/internal/ast/primitives/next/next-primitives.d.ts +0 -43
  56. package/dist/internal/ast/primitives/next/next-primitives.js +0 -211
  57. package/dist/internal/ast/primitives/shared.d.ts +0 -60
  58. package/dist/internal/ast/primitives/shared.js +0 -176
  59. package/dist/internal/ast/primitives/style/class-expression.d.ts +0 -23
  60. package/dist/internal/ast/primitives/style/class-expression.js +0 -174
  61. package/dist/internal/ast/primitives/style/index.d.ts +0 -1
  62. package/dist/internal/ast/primitives/style/index.js +0 -1
  63. package/dist/internal/ast/primitives/style/style-primitives.d.ts +0 -49
  64. package/dist/internal/ast/primitives/style/style-primitives.js +0 -555
  65. package/dist/internal/ast/primitives/values/index.d.ts +0 -1
  66. package/dist/internal/ast/primitives/values/index.js +0 -1
  67. package/dist/internal/ast/primitives/values/value-primitives.d.ts +0 -42
  68. package/dist/internal/ast/primitives/values/value-primitives.js +0 -158
  69. package/dist/internal/ast/printer/SourcePrinter.d.ts +0 -21
  70. package/dist/internal/ast/printer/SourcePrinter.js +0 -76
  71. package/dist/internal/ast/printer/index.d.ts +0 -6
  72. package/dist/internal/ast/printer/index.js +0 -126
  73. package/dist/internal/ast/types.d.ts +0 -190
  74. package/dist/internal/ast/types.js +0 -1
  75. package/dist/internal/capability/capability-resolver.d.ts +0 -16
  76. package/dist/internal/capability/capability-resolver.js +0 -127
  77. package/dist/internal/classname-source.d.ts +0 -24
  78. package/dist/internal/classname-source.js +0 -220
  79. package/dist/internal/contracts/IEditEngineRuntime.d.ts +0 -18
  80. package/dist/internal/contracts/IEditEngineRuntime.js +0 -1
  81. package/dist/internal/domain/EditDiagnostic.d.ts +0 -38
  82. package/dist/internal/domain/EditDiagnostic.js +0 -43
  83. package/dist/internal/events/event-bus.d.ts +0 -14
  84. package/dist/internal/events/event-bus.js +0 -21
  85. package/dist/internal/graph/graph-builder.d.ts +0 -12
  86. package/dist/internal/graph/graph-builder.js +0 -1371
  87. package/dist/internal/graph/import-resolver.d.ts +0 -31
  88. package/dist/internal/graph/import-resolver.js +0 -109
  89. package/dist/internal/graph/project-graph-builder.d.ts +0 -32
  90. package/dist/internal/graph/project-graph-builder.js +0 -133
  91. package/dist/internal/graph/types.d.ts +0 -114
  92. package/dist/internal/graph/types.js +0 -6
  93. package/dist/internal/history/undo-redo.d.ts +0 -28
  94. package/dist/internal/history/undo-redo.js +0 -42
  95. package/dist/internal/index.d.ts +0 -2
  96. package/dist/internal/index.js +0 -1
  97. package/dist/internal/planner/planner.d.ts +0 -104
  98. package/dist/internal/planner/planner.js +0 -2533
  99. package/dist/internal/planner/types.d.ts +0 -275
  100. package/dist/internal/planner/types.js +0 -6
  101. package/dist/internal/protocol/boundary.js +0 -3
  102. package/dist/internal/protocol/capability.js +0 -8
  103. package/dist/internal/protocol/error.js +0 -38
  104. package/dist/internal/protocol/event.js +0 -3
  105. package/dist/internal/protocol/identity.js +0 -30
  106. package/dist/internal/protocol/operation.js +0 -8
  107. package/dist/internal/protocol/render.js +0 -3
  108. package/dist/internal/protocol.js +0 -2
  109. package/dist/internal/provenance/binding-graph.d.ts +0 -39
  110. package/dist/internal/provenance/binding-graph.js +0 -184
  111. package/dist/internal/provenance/capability-policy.d.ts +0 -15
  112. package/dist/internal/provenance/capability-policy.js +0 -96
  113. package/dist/internal/provenance/data-source-classifier.d.ts +0 -14
  114. package/dist/internal/provenance/data-source-classifier.js +0 -281
  115. package/dist/internal/provenance/resolve-text-provenance.d.ts +0 -45
  116. package/dist/internal/provenance/resolve-text-provenance.js +0 -3090
  117. package/dist/internal/provenance/types.d.ts +0 -89
  118. package/dist/internal/provenance/types.js +0 -1
  119. package/dist/internal/render/component-semantic.d.ts +0 -11
  120. package/dist/internal/render/component-semantic.js +0 -141
  121. package/dist/internal/render/content-model.d.ts +0 -3
  122. package/dist/internal/render/content-model.js +0 -89
  123. package/dist/internal/render/media-model.d.ts +0 -3
  124. package/dist/internal/render/media-model.js +0 -45
  125. package/dist/internal/render/provenance-types.d.ts +0 -33
  126. package/dist/internal/render/provenance-types.js +0 -1
  127. package/dist/internal/render/render-projection.d.ts +0 -24
  128. package/dist/internal/render/render-projection.js +0 -281
  129. package/dist/internal/render/tailwind-style-model.d.ts +0 -19
  130. package/dist/internal/render/tailwind-style-model.js +0 -1187
  131. package/dist/internal/runtime/EditEngineRuntime.d.ts +0 -25
  132. package/dist/internal/runtime/EditEngineRuntime.js +0 -89
  133. package/dist/internal/runtime/EditEngineRuntimeSnapshot.d.ts +0 -31
  134. package/dist/internal/runtime/EditEngineRuntimeSnapshot.js +0 -15
  135. package/dist/internal/runtime/InternalEditEngine.d.ts +0 -44
  136. package/dist/internal/runtime/InternalEditEngine.js +0 -1391
  137. package/dist/internal/runtime.d.ts +0 -3
  138. package/dist/internal/runtime.js +0 -1
  139. package/dist/internal/topology/topology.d.ts +0 -6
  140. package/dist/internal/topology/topology.js +0 -98
  141. package/dist/internal/topology/types.d.ts +0 -35
  142. package/dist/internal/topology/types.js +0 -5
  143. package/dist/internal/types.d.ts +0 -1
  144. package/dist/internal/types.js +0 -1
  145. package/dist/internal/writeback/in-memory-fs.d.ts +0 -7
  146. package/dist/internal/writeback/in-memory-fs.js +0 -44
  147. package/dist/internal/writeback/types.d.ts +0 -45
  148. package/dist/internal/writeback/types.js +0 -7
  149. package/dist/internal/writeback/writeback-service.d.ts +0 -7
  150. package/dist/internal/writeback/writeback-service.js +0 -568
  151. package/dist/internal-adapter.d.ts +0 -18
  152. package/dist/internal-adapter.js +0 -350
  153. package/dist/next-app-router-fs.js +0 -64
  154. package/dist/preview-runtime.js +0 -102
  155. package/dist/public-file-system.js +0 -1
  156. package/dist/runtime-sync.js +0 -321
  157. package/dist/runtime.js +0 -134
  158. package/dist/site-edit-instrumentation.js +0 -322
  159. package/dist/snapshot-file-system.d.ts +0 -19
  160. package/dist/snapshot-file-system.js +0 -49
  161. package/dist/source-writeback-test-harness.d.ts +0 -244
  162. package/dist/source-writeback-test-harness.js +0 -119
  163. package/dist/types.js +0 -1
@@ -1,322 +0,0 @@
1
- import generateModule from "@babel/generator";
2
- import * as parser from "@babel/parser";
3
- import _traverse from "@babel/traverse";
4
- import * as t from "@babel/types";
5
- import { computeSiteEditSourceIdentityKey } from "@trojanbox-vcp-test/contracts";
6
- import { SITE_EDIT_RUNTIME_ATTRIBUTES } from "./runtime-sync.js";
7
- const generate = (typeof generateModule === "function"
8
- ? generateModule
9
- : generateModule.default);
10
- const traverse = (typeof _traverse === "function" ? _traverse : _traverse.default);
11
- const NON_EDITABLE_INTRINSIC_ELEMENTS = new Set([
12
- "base",
13
- "body",
14
- "head",
15
- "html",
16
- "link",
17
- "meta",
18
- "noscript",
19
- "script",
20
- "style",
21
- "template",
22
- "title",
23
- ]);
24
- const SUPPRESS_HYDRATION_WARNING_PROP = "suppressHydrationWarning";
25
- export function instrumentSiteEditRuntimeAttributes(options) {
26
- if (!mayContainJsx(options.source)) {
27
- return { code: options.source, elements: [] };
28
- }
29
- const attributes = options.attributes ?? SITE_EDIT_RUNTIME_ATTRIBUTES;
30
- const ast = parser.parse(options.source, {
31
- sourceType: "module",
32
- plugins: ["jsx", "typescript"],
33
- });
34
- const elements = [];
35
- const sourceFile = toProjectRelativeFile(options.file, options.projectRoot);
36
- traverse(ast, {
37
- JSXElement(path) {
38
- const opening = path.node.openingElement;
39
- const name = opening.name;
40
- if (!isSiteEditMarkableElement(name) ||
41
- hasAttribute(opening, attributes.key)) {
42
- return;
43
- }
44
- const componentName = findOwningComponentName(path) ?? "default";
45
- const structuralPath = computeStructuralPathFromAst(path);
46
- const key = computeSiteEditSourceIdentityKey(sourceFile, componentName, structuralPath);
47
- const tag = getJsxElementName(name) ?? "unknown";
48
- const sourceKind = isConcreteElement(name) ? "jsx" : "component-call";
49
- if (sourceKind === "component-call" &&
50
- !hasStructuredChild(path.node.children)) {
51
- return;
52
- }
53
- appendStringAttribute(opening, attributes.key, key);
54
- appendBooleanAttribute(opening, SUPPRESS_HYDRATION_WARNING_PROP);
55
- elements.push({
56
- key,
57
- tag,
58
- componentName: componentName,
59
- sourceFile: sourceFile,
60
- source_kind: sourceKind,
61
- });
62
- },
63
- });
64
- return {
65
- code: generate(ast, { jsescOption: { minimal: true } }).code,
66
- elements,
67
- };
68
- }
69
- function mayContainJsx(source) {
70
- return source.includes("<");
71
- }
72
- function toProjectRelativeFile(filename, projectRoot) {
73
- const normalized = filename.replace(/\\/g, "/").replace(/^\.\//, "");
74
- const normalizedRoot = projectRoot?.replace(/\\/g, "/").replace(/\/+$/, "");
75
- if (normalizedRoot && normalized.startsWith(`${normalizedRoot}/`)) {
76
- return normalized.slice(normalizedRoot.length + 1);
77
- }
78
- for (const [marker, offset] of [
79
- ["/src/app/", 1],
80
- ["/src/components/", 1],
81
- ["/app/", 1],
82
- ["/components/", 1],
83
- ]) {
84
- const index = normalized.indexOf(marker);
85
- if (index >= 0) {
86
- return normalized.slice(index + offset);
87
- }
88
- }
89
- const fallback = normalized.match(/(?:^|\/)((?:src\/app|src\/components|app|components)\/.+)$/);
90
- return fallback?.[1] ?? normalized;
91
- }
92
- function isConcreteElement(name) {
93
- return t.isJSXIdentifier(name) && /^[a-z]/.test(name.name);
94
- }
95
- function getJsxElementName(name) {
96
- if (t.isJSXIdentifier(name)) {
97
- return name.name;
98
- }
99
- if (t.isJSXMemberExpression(name)) {
100
- return getJsxMemberExpressionName(name);
101
- }
102
- return null;
103
- }
104
- function isSiteEditMarkableElement(name) {
105
- const elementName = getJsxElementName(name);
106
- if (!elementName ||
107
- elementName === "Fragment" ||
108
- elementName.endsWith(".Fragment")) {
109
- return false;
110
- }
111
- return !NON_EDITABLE_INTRINSIC_ELEMENTS.has(elementName);
112
- }
113
- function hasAttribute(opening, name) {
114
- return opening.attributes.some((attribute) => t.isJSXAttribute(attribute) &&
115
- t.isJSXIdentifier(attribute.name, { name }));
116
- }
117
- function appendStringAttribute(opening, name, value) {
118
- opening.attributes.push(t.jsxAttribute(t.jsxIdentifier(name), t.stringLiteral(value)));
119
- }
120
- function appendOptionalStringAttribute(opening, name, value) {
121
- if (value === undefined || hasAttribute(opening, name)) {
122
- return;
123
- }
124
- appendStringAttribute(opening, name, value);
125
- }
126
- function appendBooleanAttribute(opening, name) {
127
- if (hasAttribute(opening, name)) {
128
- return;
129
- }
130
- opening.attributes.push(t.jsxAttribute(t.jsxIdentifier(name), null));
131
- }
132
- function getJsxMemberExpressionName(name) {
133
- const objectName = t.isJSXIdentifier(name.object)
134
- ? name.object.name
135
- : getJsxMemberExpressionName(name.object);
136
- return `${objectName}.${name.property.name}`;
137
- }
138
- function findOwningComponentName(path) {
139
- let current = path;
140
- while (current) {
141
- if (current.isFunctionDeclaration() || current.isClassDeclaration()) {
142
- return current.node.id?.name ?? null;
143
- }
144
- if (current.isVariableDeclarator() && t.isIdentifier(current.node.id)) {
145
- const init = current.get("init");
146
- if (!Array.isArray(init) &&
147
- (init.isArrowFunctionExpression() || init.isFunctionExpression())) {
148
- return current.node.id.name;
149
- }
150
- }
151
- current = current.parentPath;
152
- }
153
- return null;
154
- }
155
- function hasStructuredChild(children) {
156
- return children.some((child) => t.isJSXElement(child) || t.isJSXFragment(child));
157
- }
158
- const structuralPathCache = new WeakMap();
159
- const structuralChildrenCache = new WeakMap();
160
- const siblingOrdinalCache = new WeakMap();
161
- function computeStructuralPathFromAst(path) {
162
- const cached = structuralPathCache.get(path.node);
163
- if (cached !== undefined) {
164
- return cached;
165
- }
166
- const segments = [];
167
- let current = path;
168
- while (current) {
169
- if (current.isJSXElement()) {
170
- const segment = getStructuralSegment(current);
171
- if (segment) {
172
- segments.unshift(segment);
173
- }
174
- }
175
- current = current.parentPath;
176
- }
177
- const structuralPath = segments.join("/");
178
- structuralPathCache.set(path.node, structuralPath);
179
- return structuralPath;
180
- }
181
- function getStructuralSegment(path) {
182
- const tag = getJsxElementName(path.node.openingElement.name);
183
- if (!tag || tag === "Fragment" || tag.endsWith(".Fragment")) {
184
- return null;
185
- }
186
- if (/^[A-Z]/.test(tag)) {
187
- return `component:${tag}#${computeSiblingOrdinal(path, tag)}`;
188
- }
189
- return `${tag}#${computeSiblingOrdinal(path, tag)}`;
190
- }
191
- function computeSiblingOrdinal(path, tag) {
192
- const owner = findStructuralParent(path);
193
- if (!owner) {
194
- return 0;
195
- }
196
- const cached = siblingOrdinalCache.get(owner.node)?.get(tag)?.get(path.node);
197
- if (cached !== undefined) {
198
- return cached;
199
- }
200
- let ownerCache = siblingOrdinalCache.get(owner.node);
201
- if (!ownerCache) {
202
- ownerCache = new Map();
203
- siblingOrdinalCache.set(owner.node, ownerCache);
204
- }
205
- let tagOrdinals = ownerCache.get(tag);
206
- if (!tagOrdinals) {
207
- tagOrdinals = new WeakMap();
208
- ownerCache.set(tag, tagOrdinals);
209
- }
210
- let ordinal = 0;
211
- for (const sibling of collectStructuralChildren(owner)) {
212
- const siblingTag = getJsxElementName(sibling.node.openingElement.name);
213
- if (siblingTag === tag) {
214
- tagOrdinals.set(sibling.node, ordinal);
215
- if (sibling.node === path.node) {
216
- return ordinal;
217
- }
218
- ordinal += 1;
219
- }
220
- }
221
- return tagOrdinals.get(path.node) ?? 0;
222
- }
223
- function findStructuralParent(path) {
224
- let current = path.parentPath;
225
- let fragmentOwner = null;
226
- while (current) {
227
- if (current.isJSXFragment()) {
228
- fragmentOwner = current;
229
- current = current.parentPath;
230
- continue;
231
- }
232
- if (current.isJSXElement()) {
233
- return current;
234
- }
235
- current = current.parentPath;
236
- }
237
- return fragmentOwner;
238
- }
239
- function collectStructuralChildren(owner) {
240
- const cached = structuralChildrenCache.get(owner.node);
241
- if (cached) {
242
- return cached;
243
- }
244
- const structuralChildren = [];
245
- const children = owner.get("children");
246
- for (const child of children) {
247
- if (Array.isArray(child)) {
248
- continue;
249
- }
250
- if (child.isJSXElement()) {
251
- structuralChildren.push(child);
252
- continue;
253
- }
254
- if (child.isJSXFragment()) {
255
- structuralChildren.push(...collectStructuralChildren(child));
256
- continue;
257
- }
258
- if (child.isJSXExpressionContainer()) {
259
- structuralChildren.push(...collectExpressionStructuralChildren(child.get("expression")));
260
- }
261
- }
262
- structuralChildrenCache.set(owner.node, structuralChildren);
263
- return structuralChildren;
264
- }
265
- function collectExpressionStructuralChildren(expression) {
266
- if (expression.isJSXElement()) {
267
- return [expression];
268
- }
269
- if (expression.isJSXFragment()) {
270
- return collectStructuralChildren(expression);
271
- }
272
- if (expression.isParenthesizedExpression()) {
273
- return collectExpressionStructuralChildren(expression.get("expression"));
274
- }
275
- if (expression.isLogicalExpression() && expression.node.operator === "&&") {
276
- return collectExpressionStructuralChildren(expression.get("right"));
277
- }
278
- if (expression.isConditionalExpression()) {
279
- return [
280
- ...collectExpressionStructuralChildren(expression.get("consequent")),
281
- ...collectExpressionStructuralChildren(expression.get("alternate")),
282
- ];
283
- }
284
- if (expression.isCallExpression() && isMapCallExpression(expression.node)) {
285
- const callback = expression.get("arguments")[0];
286
- return collectFunctionReturnStructuralChildren(callback);
287
- }
288
- return [];
289
- }
290
- function collectFunctionReturnStructuralChildren(path) {
291
- if (!path.isArrowFunctionExpression() && !path.isFunctionExpression()) {
292
- return [];
293
- }
294
- const body = path.get("body");
295
- if (body.isJSXElement()) {
296
- return [body];
297
- }
298
- if (body.isJSXFragment()) {
299
- return collectStructuralChildren(body);
300
- }
301
- if (body.isParenthesizedExpression()) {
302
- return collectExpressionStructuralChildren(body.get("expression"));
303
- }
304
- if (!body.isBlockStatement()) {
305
- return [];
306
- }
307
- for (const statement of body.get("body")) {
308
- if (!statement.isReturnStatement()) {
309
- continue;
310
- }
311
- const argument = statement.get("argument");
312
- return argument.node
313
- ? collectExpressionStructuralChildren(argument)
314
- : [];
315
- }
316
- return [];
317
- }
318
- function isMapCallExpression(node) {
319
- return (t.isMemberExpression(node.callee) &&
320
- t.isIdentifier(node.callee.property) &&
321
- node.callee.property.name === "map");
322
- }
@@ -1,19 +0,0 @@
1
- import type { ProjectFileSystem } from "./internal/types.js";
2
- import type { SiteEditSnapshotFile } from "./types.js";
3
- export declare class SnapshotFileSystem implements ProjectFileSystem {
4
- private readonly original;
5
- private readonly files;
6
- private readonly versions;
7
- constructor(files: SiteEditSnapshotFile[]);
8
- readFile(file: string): Promise<string>;
9
- writeFile(file: string, content: string): Promise<void>;
10
- exists(file: string): Promise<boolean>;
11
- getVersion(file: string): number;
12
- bumpVersion(file: string): number;
13
- getChangedFiles(): Array<{
14
- path: string;
15
- before?: string;
16
- after?: string;
17
- }>;
18
- }
19
- export declare function sha256ContentHash(content: string): `sha256:${string}`;
@@ -1,49 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- export class SnapshotFileSystem {
3
- constructor(files) {
4
- this.original = new Map();
5
- this.files = new Map();
6
- this.versions = new Map();
7
- for (const file of files) {
8
- this.original.set(file.path, file.content);
9
- this.files.set(file.path, file.content);
10
- this.versions.set(file.path, file.version ?? 0);
11
- }
12
- }
13
- async readFile(file) {
14
- const content = this.files.get(file);
15
- if (content === undefined) {
16
- throw new Error(`Snapshot file not found: ${file}`);
17
- }
18
- return content;
19
- }
20
- async writeFile(file, content) {
21
- this.files.set(file, content);
22
- }
23
- async exists(file) {
24
- return this.files.has(file);
25
- }
26
- getVersion(file) {
27
- return this.versions.get(file) ?? 0;
28
- }
29
- bumpVersion(file) {
30
- const next = this.getVersion(file) + 1;
31
- this.versions.set(file, next);
32
- return next;
33
- }
34
- getChangedFiles() {
35
- const paths = new Set([...this.original.keys(), ...this.files.keys()]);
36
- const changes = [];
37
- for (const path of [...paths].sort()) {
38
- const before = this.original.get(path);
39
- const after = this.files.get(path);
40
- if (before !== after) {
41
- changes.push({ path, before, after });
42
- }
43
- }
44
- return changes;
45
- }
46
- }
47
- export function sha256ContentHash(content) {
48
- return `sha256:${createHash("sha256").update(content).digest("hex")}`;
49
- }
@@ -1,244 +0,0 @@
1
- import type { SiteEditSetClassNameSourceRequest, SiteEditOperationParams, SiteEditRenderDocument } from "@trojanbox-vcp-test/contracts";
2
- export type SourceFixtureFile = {
3
- path: string;
4
- content: string;
5
- };
6
- export declare function createSourceWritebackHarness(input: {
7
- files: SourceFixtureFile[];
8
- routeId?: string;
9
- entryFile?: string;
10
- }): {
11
- getSource(path: string): string;
12
- setActiveRoute(nextRouteId?: string): Promise<void>;
13
- getDocument(nextRouteId?: string): SiteEditRenderDocument;
14
- getClassNameSource(key: string, nextRouteId?: string): {
15
- key: string;
16
- routeId: string;
17
- filePath: string;
18
- componentName: string;
19
- sourceKind: "missing" | "expression" | "stringLiteral";
20
- attrRaw: string | null;
21
- valueRaw: string | null;
22
- attrRange: {
23
- start: number;
24
- end: number;
25
- startLine?: number | undefined;
26
- startColumn?: number | undefined;
27
- endLine?: number | undefined;
28
- endColumn?: number | undefined;
29
- } | null;
30
- valueRange: {
31
- start: number;
32
- end: number;
33
- startLine?: number | undefined;
34
- startColumn?: number | undefined;
35
- endLine?: number | undefined;
36
- endColumn?: number | undefined;
37
- } | null;
38
- openingElementRange: {
39
- start: number;
40
- end: number;
41
- startLine?: number | undefined;
42
- startColumn?: number | undefined;
43
- endLine?: number | undefined;
44
- endColumn?: number | undefined;
45
- };
46
- version: {
47
- documentVersion: number;
48
- contentHash: string;
49
- parserVersion: string;
50
- };
51
- diagnostics: {
52
- code: "missing-class-name" | "unsupported-attribute-name" | "source-locator-warning" | "invalid-new-attr" | "version-conflict" | "write-failed";
53
- message: string;
54
- }[];
55
- };
56
- setClassNameSource(request: SiteEditSetClassNameSourceRequest): Promise<{
57
- ok: true;
58
- source: {
59
- key: string;
60
- routeId: string;
61
- filePath: string;
62
- componentName: string;
63
- sourceKind: "missing" | "expression" | "stringLiteral";
64
- attrRaw: string | null;
65
- valueRaw: string | null;
66
- attrRange: {
67
- start: number;
68
- end: number;
69
- startLine?: number | undefined;
70
- startColumn?: number | undefined;
71
- endLine?: number | undefined;
72
- endColumn?: number | undefined;
73
- } | null;
74
- valueRange: {
75
- start: number;
76
- end: number;
77
- startLine?: number | undefined;
78
- startColumn?: number | undefined;
79
- endLine?: number | undefined;
80
- endColumn?: number | undefined;
81
- } | null;
82
- openingElementRange: {
83
- start: number;
84
- end: number;
85
- startLine?: number | undefined;
86
- startColumn?: number | undefined;
87
- endLine?: number | undefined;
88
- endColumn?: number | undefined;
89
- };
90
- version: {
91
- documentVersion: number;
92
- contentHash: string;
93
- parserVersion: string;
94
- };
95
- diagnostics: {
96
- code: "missing-class-name" | "unsupported-attribute-name" | "source-locator-warning" | "invalid-new-attr" | "version-conflict" | "write-failed";
97
- message: string;
98
- }[];
99
- };
100
- } | {
101
- ok: false;
102
- reason: "node_not_found" | "document_version_stale" | "file_hash_mismatch" | "range_mismatch" | "old_attr_mismatch" | "invalid_new_attr" | "unsupported_target" | "write_failed";
103
- diagnostics: {
104
- code: "missing-class-name" | "unsupported-attribute-name" | "source-locator-warning" | "invalid-new-attr" | "version-conflict" | "write-failed";
105
- message: string;
106
- }[];
107
- current?: {
108
- key: string;
109
- routeId: string;
110
- filePath: string;
111
- componentName: string;
112
- sourceKind: "missing" | "expression" | "stringLiteral";
113
- attrRaw: string | null;
114
- valueRaw: string | null;
115
- attrRange: {
116
- start: number;
117
- end: number;
118
- startLine?: number | undefined;
119
- startColumn?: number | undefined;
120
- endLine?: number | undefined;
121
- endColumn?: number | undefined;
122
- } | null;
123
- valueRange: {
124
- start: number;
125
- end: number;
126
- startLine?: number | undefined;
127
- startColumn?: number | undefined;
128
- endLine?: number | undefined;
129
- endColumn?: number | undefined;
130
- } | null;
131
- openingElementRange: {
132
- start: number;
133
- end: number;
134
- startLine?: number | undefined;
135
- startColumn?: number | undefined;
136
- endLine?: number | undefined;
137
- endColumn?: number | undefined;
138
- };
139
- version: {
140
- documentVersion: number;
141
- contentHash: string;
142
- parserVersion: string;
143
- };
144
- diagnostics: {
145
- code: "missing-class-name" | "unsupported-attribute-name" | "source-locator-warning" | "invalid-new-attr" | "version-conflict" | "write-failed";
146
- message: string;
147
- }[];
148
- } | undefined;
149
- }>;
150
- findEntryByTag(tag: string, index?: number): {
151
- key: string;
152
- tag: string;
153
- label: string;
154
- parentKey: string | null;
155
- childKeys: string[];
156
- operationSummary: {
157
- canUpdateText: boolean;
158
- canInsertChild: boolean;
159
- canMove: boolean;
160
- canRemove: boolean;
161
- };
162
- };
163
- executeNodeOperation(input: {
164
- key: string;
165
- params: SiteEditOperationParams;
166
- documentVersion?: number;
167
- }): Promise<{
168
- requestId: string;
169
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "replace-rich-text-content" | "insert-rich-text-block" | "remove-rich-text-block" | "set-media-field" | "set-component-slot-content" | "set-object-field" | "insert-object-field" | "remove-object-field" | "update-array-item" | "insert-array-item" | "remove-array-item" | "move-array-item" | "replace-conditional-expression" | "set-conditional-branch-content" | "set-jsx-prop" | "remove-jsx-prop" | "set-class-name" | "add-class-token" | "remove-class-token" | "set-style-property" | "set-style-properties" | "set-css-module-class" | "set-directive" | "remove-directive" | "set-route-export" | "set-metadata-field" | "set-generate-metadata";
170
- target: {
171
- kind: "node";
172
- key: string;
173
- } | {
174
- kind: "route";
175
- routeId: string;
176
- };
177
- ok: boolean;
178
- resultVersion: number;
179
- error?: {
180
- code: "NODE_NOT_FOUND" | "ROUTE_NOT_FOUND" | "CAPABILITY_REJECTED" | "CONSTRAINT_VIOLATED" | "INVALID_PARAMS" | "PLAN_FAILED" | "VERSION_STALE" | "AST_PARSE_ERROR" | "UNSUPPORTED_OPERATION" | "LOCATOR_FAILED" | "INVALID_TARGET" | "WRITE_IO_ERROR" | "CONCURRENT_MODIFIED" | "ROLLBACK_FAILED" | "INTERNAL_ERROR";
181
- message: string;
182
- details?: Record<string, unknown> | undefined;
183
- } | undefined;
184
- }>;
185
- executeRouteOperation(input: {
186
- routeId?: string;
187
- params: SiteEditOperationParams;
188
- documentVersion?: number;
189
- }): Promise<{
190
- requestId: string;
191
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "replace-rich-text-content" | "insert-rich-text-block" | "remove-rich-text-block" | "set-media-field" | "set-component-slot-content" | "set-object-field" | "insert-object-field" | "remove-object-field" | "update-array-item" | "insert-array-item" | "remove-array-item" | "move-array-item" | "replace-conditional-expression" | "set-conditional-branch-content" | "set-jsx-prop" | "remove-jsx-prop" | "set-class-name" | "add-class-token" | "remove-class-token" | "set-style-property" | "set-style-properties" | "set-css-module-class" | "set-directive" | "remove-directive" | "set-route-export" | "set-metadata-field" | "set-generate-metadata";
192
- target: {
193
- kind: "node";
194
- key: string;
195
- } | {
196
- kind: "route";
197
- routeId: string;
198
- };
199
- ok: boolean;
200
- resultVersion: number;
201
- error?: {
202
- code: "NODE_NOT_FOUND" | "ROUTE_NOT_FOUND" | "CAPABILITY_REJECTED" | "CONSTRAINT_VIOLATED" | "INVALID_PARAMS" | "PLAN_FAILED" | "VERSION_STALE" | "AST_PARSE_ERROR" | "UNSUPPORTED_OPERATION" | "LOCATOR_FAILED" | "INVALID_TARGET" | "WRITE_IO_ERROR" | "CONCURRENT_MODIFIED" | "ROLLBACK_FAILED" | "INTERNAL_ERROR";
203
- message: string;
204
- details?: Record<string, unknown> | undefined;
205
- } | undefined;
206
- }>;
207
- undo(): Promise<{
208
- requestId: string;
209
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "replace-rich-text-content" | "insert-rich-text-block" | "remove-rich-text-block" | "set-media-field" | "set-component-slot-content" | "set-object-field" | "insert-object-field" | "remove-object-field" | "update-array-item" | "insert-array-item" | "remove-array-item" | "move-array-item" | "replace-conditional-expression" | "set-conditional-branch-content" | "set-jsx-prop" | "remove-jsx-prop" | "set-class-name" | "add-class-token" | "remove-class-token" | "set-style-property" | "set-style-properties" | "set-css-module-class" | "set-directive" | "remove-directive" | "set-route-export" | "set-metadata-field" | "set-generate-metadata";
210
- target: {
211
- kind: "node";
212
- key: string;
213
- } | {
214
- kind: "route";
215
- routeId: string;
216
- };
217
- ok: boolean;
218
- resultVersion: number;
219
- error?: {
220
- code: "NODE_NOT_FOUND" | "ROUTE_NOT_FOUND" | "CAPABILITY_REJECTED" | "CONSTRAINT_VIOLATED" | "INVALID_PARAMS" | "PLAN_FAILED" | "VERSION_STALE" | "AST_PARSE_ERROR" | "UNSUPPORTED_OPERATION" | "LOCATOR_FAILED" | "INVALID_TARGET" | "WRITE_IO_ERROR" | "CONCURRENT_MODIFIED" | "ROLLBACK_FAILED" | "INTERNAL_ERROR";
221
- message: string;
222
- details?: Record<string, unknown> | undefined;
223
- } | undefined;
224
- }>;
225
- redo(): Promise<{
226
- requestId: string;
227
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "replace-rich-text-content" | "insert-rich-text-block" | "remove-rich-text-block" | "set-media-field" | "set-component-slot-content" | "set-object-field" | "insert-object-field" | "remove-object-field" | "update-array-item" | "insert-array-item" | "remove-array-item" | "move-array-item" | "replace-conditional-expression" | "set-conditional-branch-content" | "set-jsx-prop" | "remove-jsx-prop" | "set-class-name" | "add-class-token" | "remove-class-token" | "set-style-property" | "set-style-properties" | "set-css-module-class" | "set-directive" | "remove-directive" | "set-route-export" | "set-metadata-field" | "set-generate-metadata";
228
- target: {
229
- kind: "node";
230
- key: string;
231
- } | {
232
- kind: "route";
233
- routeId: string;
234
- };
235
- ok: boolean;
236
- resultVersion: number;
237
- error?: {
238
- code: "NODE_NOT_FOUND" | "ROUTE_NOT_FOUND" | "CAPABILITY_REJECTED" | "CONSTRAINT_VIOLATED" | "INVALID_PARAMS" | "PLAN_FAILED" | "VERSION_STALE" | "AST_PARSE_ERROR" | "UNSUPPORTED_OPERATION" | "LOCATOR_FAILED" | "INVALID_TARGET" | "WRITE_IO_ERROR" | "CONCURRENT_MODIFIED" | "ROLLBACK_FAILED" | "INTERNAL_ERROR";
239
- message: string;
240
- details?: Record<string, unknown> | undefined;
241
- } | undefined;
242
- }>;
243
- subscribe(listener: Parameters<(listener: (event: import("@trojanbox-vcp-test/contracts").SiteEditEvent) => void) => () => void>[0]): () => void;
244
- };