@vcp-dev/site-edit-engine 0.3.15 → 0.4.1

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.
@@ -1 +1 @@
1
- import u from"node:fs";import a from"node:path";var R=/^page\.(?:tsx|ts|jsx|js|mjs|cjs)$/;function x(t){let r=P(t);return r?l(r).map(e=>({routeId:I(r,e),entryFile:p(a.relative(t,e))})).sort((e,n)=>e.routeId.localeCompare(n.routeId)):[]}function P(t){for(let r of["app","src/app"]){let e=a.join(t,r);if(u.existsSync(e)&&u.statSync(e).isDirectory())return e}return null}function l(t){let r=[];for(let e of u.readdirSync(t,{withFileTypes:!0})){let n=a.join(t,e.name);if(e.isDirectory()){if(e.name==="node_modules"||e.name.startsWith(".")||e.name.startsWith("_"))continue;r.push(...l(n));continue}e.isFile()&&R.test(e.name)&&r.push(n)}return r}function I(t,r){let e=p(a.relative(t,a.dirname(r))),n=e?e.split("/").map(W).filter(i=>!!i):[];return n.length===0?"/":`/${n.join("/")}`}function $(t){return t.startsWith("(")&&t.endsWith(")")}function W(t){return!t||t.startsWith("@")||t.startsWith("_")||$(t)?null:g(t)}function g(t){return t.replace(/^\((?:\.|\.\.|\.\.\.)\)/,"")}function p(t){return t.replace(/\\/g,"/")}var S=/^page\.(?:tsx|ts|jsx|js|mjs|cjs)$/,h=/^\[[^\]]+\]$/,d=/^\[\.\.\.[^\]]+\]$/,m=/^\[\[\.\.\.[^\]]+\]\]$/;function E(t){let r=t.map(n=>C(n.path)),e=A(r);return e?r.filter(n=>j(e,n)).map(n=>({routeId:v(e,n),entryFile:n})).sort((n,i)=>n.routeId.localeCompare(i.routeId)):[]}function G(t,r,e=""){let n=y(t,e);return r.some(o=>o.routeId===n)?n:[...r].sort((o,s)=>f(s.routeId)-f(o.routeId)||s.routeId.length-o.routeId.length||o.routeId.localeCompare(s.routeId)).find(o=>w(o.routeId).test(n))?.routeId}function y(t,r=""){let n=((t??"/").trim()||"/").split(/[?#]/,1)[0]||"/",i=n.startsWith("/")?n:`/${n}`,o=N(r),s=o&&(i===o||i.startsWith(`${o}/`))?i.slice(o.length)||"/":i,c=s.startsWith("/")?s:`/${s}`;return c==="/"?"/":c.replace(/\/+$/,"")}function A(t){return t.some(n=>n.startsWith("app/"))?"app":t.some(n=>n.startsWith("src/app/"))?"src/app":null}function j(t,r){if(!r.startsWith(`${t}/`))return!1;let e=r.slice(r.lastIndexOf("/")+1);return S.test(e)?r.slice(t.length+1,-e.length-1).split("/").filter(Boolean).every(n=>!n.startsWith("_")):!1}function v(t,r){let e=r.slice(t.length+1).split("/").slice(0,-1).map(z).filter(n=>!!n);return e.length===0?"/":`/${e.join("/")}`}function F(t){return t.startsWith("(")&&t.endsWith(")")}function z(t){return!t||t.startsWith("@")||t.startsWith("_")||F(t)?null:B(t)}function B(t){return t.replace(/^\((?:\.|\.\.|\.\.\.)\)/,"")}function w(t){if(t==="/")return/^\/$/;let r=t.split("/").filter(Boolean).map(e=>m.test(e)?"(?:/.*)?":d.test(e)?"/.+":h.test(e)?"/[^/]+":`/${_(e)}`).join("");return new RegExp(`^${r}$`)}function f(t){return t.split("/").filter(Boolean).reduce((r,e)=>m.test(e)?r+1:d.test(e)?r+2:h.test(e)?r+3:r+4,0)}function N(t){let r=t.trim();return!r||r==="/"?"":(r.startsWith("/")?r:`/${r}`).replace(/\/+$/,"")}function _(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function C(t){return t.replace(/\\/g,"/").replace(/^\.\//,"")}export{y as normalizeNextRoutePath,G as resolveNextAppRouteId,x as scanNextAppRouterRoutes,E as scanNextAppRouterRoutesFromFiles};
1
+ import c from"node:fs";import u from"node:path";var I=/^page\.(?:tsx|ts|jsx|js|mjs|cjs)$/;function x(t){let e=$(t);return e?f(e).map(r=>({routeId:P(e,r),entryFile:d(u.relative(t,r))})).sort((r,n)=>r.routeId.localeCompare(n.routeId)):[]}function $(t){for(let e of["app","src/app"]){let r=u.join(t,e);if(c.existsSync(r)&&c.statSync(r).isDirectory())return r}return null}function f(t){let e=[];for(let r of c.readdirSync(t,{withFileTypes:!0})){let n=u.join(t,r.name);if(r.isDirectory()){if(r.name==="node_modules"||r.name.startsWith(".")||r.name.startsWith("_"))continue;e.push(...f(n));continue}r.isFile()&&I.test(r.name)&&e.push(n)}return e}function P(t,e){let r=d(u.relative(t,u.dirname(e))),n=r?r.split("/").map(g).filter(i=>!!i):[];return n.length===0?"/":`/${n.join("/")}`}function W(t){return t.startsWith("(")&&t.endsWith(")")}function g(t){return!t||t.startsWith("@")||t.startsWith("_")||W(t)?null:y(t)}function y(t){return t.replace(/^\((?:\.|\.\.|\.\.\.)\)/,"")}function d(t){return t.replace(/\\/g,"/")}var S=/^page\.(?:tsx|ts|jsx|js|mjs|cjs)$/,l=/^\[[^\]]+\]$/,p=/^\[\.\.\.[^\]]+\]$/,h=/^\[\[\.\.\.[^\]]+\]\]$/,m=new WeakMap;function G(t){let e=t.map(n=>M(n.path)),r=v(e);return r?e.filter(n=>w(r,n)).map(n=>({routeId:B(r,n),entryFile:n})).sort((n,i)=>n.routeId.localeCompare(i.routeId)):[]}function k(t,e,r=""){let n=F(t,r),i=j(e);return i.exactRouteIds.has(n)?n:i.dynamicMatchers.find(o=>o.matcher.test(n))?.routeId}function j(t){let e=t.map(o=>`${o.routeId}\0${o.entryFile}`).join("\0"),r=m.get(t);if(r?.signature===e)return r;let n=new Set(t.map(o=>o.routeId)),i=t.filter(o=>o.routeId!=="/"&&A(o.routeId)).sort((o,s)=>R(s.routeId)-R(o.routeId)||s.routeId.length-o.routeId.length||o.routeId.localeCompare(s.routeId)).map(o=>({routeId:o.routeId,matcher:D(o.routeId)})),a={signature:e,exactRouteIds:n,dynamicMatchers:i};return m.set(t,a),a}function A(t){return t.split("/").filter(Boolean).some(e=>l.test(e)||p.test(e)||h.test(e))}function F(t,e=""){let n=((t??"/").trim()||"/").split(/[?#]/,1)[0]||"/",i=n.startsWith("/")?n:`/${n}`,a=N(e),o=a&&(i===a||i.startsWith(`${a}/`))?i.slice(a.length)||"/":i,s=o.startsWith("/")?o:`/${o}`;return s==="/"?"/":s.replace(/\/+$/,"")}function v(t){return t.some(n=>n.startsWith("app/"))?"app":t.some(n=>n.startsWith("src/app/"))?"src/app":null}function w(t,e){if(!e.startsWith(`${t}/`))return!1;let r=e.slice(e.lastIndexOf("/")+1);return S.test(r)?e.slice(t.length+1,-r.length-1).split("/").filter(Boolean).every(n=>!n.startsWith("_")):!1}function B(t,e){let r=e.slice(t.length+1).split("/").slice(0,-1).map(b).filter(n=>!!n);return r.length===0?"/":`/${r.join("/")}`}function z(t){return t.startsWith("(")&&t.endsWith(")")}function b(t){return!t||t.startsWith("@")||t.startsWith("_")||z(t)?null:C(t)}function C(t){return t.replace(/^\((?:\.|\.\.|\.\.\.)\)/,"")}function D(t){if(t==="/")return/^\/$/;let e=t.split("/").filter(Boolean).map(r=>h.test(r)?"(?:/.*)?":p.test(r)?"/.+":l.test(r)?"/[^/]+":`/${_(r)}`).join("");return new RegExp(`^${e}$`)}function R(t){return t.split("/").filter(Boolean).reduce((e,r)=>h.test(r)?e+1:p.test(r)?e+2:l.test(r)?e+3:e+4,0)}function N(t){let e=t.trim();return!e||e==="/"?"":(e.startsWith("/")?e:`/${e}`).replace(/\/+$/,"")}function _(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function M(t){return t.replace(/\\/g,"/").replace(/^\.\//,"")}export{F as normalizeNextRoutePath,k as resolveNextAppRouteId,x as scanNextAppRouterRoutes,G as scanNextAppRouterRoutesFromFiles};
@@ -1,4 +1,4 @@
1
- import type { SiteEditOperationCommandResult } from "@vcp-dev/contracts";
1
+ import type { SiteEditOperationCommandResult, SiteEditResolveSourceLocationInput } from "@vcp-dev/contracts";
2
2
  import type { PreviewSiteEditEngineRuntime, PreviewSiteEditEngineRuntimeOptions } from "./types.js";
3
3
  export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSiteEditEngineRuntime {
4
4
  private readonly options;
@@ -229,6 +229,61 @@ export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSi
229
229
  } | undefined;
230
230
  };
231
231
  };
232
+ getSourceTree(): Promise<{
233
+ ok: true;
234
+ data: {
235
+ nodes: import("@vcp-dev/contracts").SiteEditSourceTreeNode[];
236
+ totalFiles: number;
237
+ defaultPath?: string | undefined;
238
+ truncated?: {
239
+ reasons: ("max-files" | "max-depth" | "max-total-bytes")[];
240
+ maxFiles: number;
241
+ maxDepth: number;
242
+ maxTotalBytes: number;
243
+ } | undefined;
244
+ };
245
+ }>;
246
+ getSourceFile(input: {
247
+ path: string;
248
+ }): Promise<{
249
+ ok: true;
250
+ data: {
251
+ path: string;
252
+ sizeBytes: number;
253
+ kind: "text";
254
+ language: string;
255
+ readonly: boolean;
256
+ content: string;
257
+ contentHash?: string | undefined;
258
+ } | {
259
+ path: string;
260
+ sizeBytes: number;
261
+ kind: "binary";
262
+ language: null;
263
+ readonly: true;
264
+ mimeType: string;
265
+ contentHash?: string | undefined;
266
+ contentBase64?: string | undefined;
267
+ previewUnavailableReason?: "too-large" | "unsupported-mime" | "bytes-unavailable" | undefined;
268
+ };
269
+ }>;
270
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): {
271
+ ok: true;
272
+ data: {
273
+ key: string;
274
+ sourceFile: string;
275
+ componentName: string;
276
+ openingElementRange: {
277
+ startLine: number;
278
+ startColumn: number;
279
+ endLine: number;
280
+ endColumn: number;
281
+ };
282
+ structuralPath: string;
283
+ routeId?: string | undefined;
284
+ textPreview?: string | undefined;
285
+ };
286
+ };
232
287
  refreshSourceForKey(key: string, routeId?: string): Promise<void>;
233
288
  executeOperation(request: Parameters<PreviewSiteEditEngineRuntime["executeOperation"]>[0]): Promise<SiteEditOperationCommandResult>;
234
289
  undo(): Promise<{
@@ -239,13 +294,19 @@ export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSi
239
294
  };
240
295
  data: {
241
296
  requestId: string;
242
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft";
297
+ kind: "update-text" | "update-array-item" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft" | "source-edit";
243
298
  target: {
244
299
  kind: "node";
245
300
  key: string;
246
301
  } | {
247
302
  kind: "route";
248
303
  routeId: string;
304
+ } | {
305
+ kind: "source-file";
306
+ path: string;
307
+ } | {
308
+ kind: "source-batch";
309
+ paths: string[];
249
310
  };
250
311
  resultVersion: number;
251
312
  };
@@ -253,13 +314,19 @@ export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSi
253
314
  ok: true;
254
315
  data: {
255
316
  requestId: string;
256
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft";
317
+ kind: "update-text" | "update-array-item" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft" | "source-edit";
257
318
  target: {
258
319
  kind: "node";
259
320
  key: string;
260
321
  } | {
261
322
  kind: "route";
262
323
  routeId: string;
324
+ } | {
325
+ kind: "source-file";
326
+ path: string;
327
+ } | {
328
+ kind: "source-batch";
329
+ paths: string[];
263
330
  };
264
331
  resultVersion: number;
265
332
  affectedFiles?: string[] | undefined;
@@ -279,13 +346,19 @@ export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSi
279
346
  };
280
347
  data: {
281
348
  requestId: string;
282
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft";
349
+ kind: "update-text" | "update-array-item" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft" | "source-edit";
283
350
  target: {
284
351
  kind: "node";
285
352
  key: string;
286
353
  } | {
287
354
  kind: "route";
288
355
  routeId: string;
356
+ } | {
357
+ kind: "source-file";
358
+ path: string;
359
+ } | {
360
+ kind: "source-batch";
361
+ paths: string[];
289
362
  };
290
363
  resultVersion: number;
291
364
  };
@@ -293,13 +366,19 @@ export declare class PreviewFileSystemSiteEditEngineRuntime implements PreviewSi
293
366
  ok: true;
294
367
  data: {
295
368
  requestId: string;
296
- kind: "update-text" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft";
369
+ kind: "update-text" | "update-array-item" | "remove-node" | "insert-child" | "move-node" | "set-class-name-source" | "set-props" | "apply-style-draft" | "source-edit";
297
370
  target: {
298
371
  kind: "node";
299
372
  key: string;
300
373
  } | {
301
374
  kind: "route";
302
375
  routeId: string;
376
+ } | {
377
+ kind: "source-file";
378
+ path: string;
379
+ } | {
380
+ kind: "source-batch";
381
+ paths: string[];
303
382
  };
304
383
  resultVersion: number;
305
384
  affectedFiles?: string[] | undefined;
@@ -1,8 +1,27 @@
1
+ export type SiteEditProjectFileInfo = {
2
+ path: string;
3
+ sizeBytes: number;
4
+ };
5
+ export type SiteEditProjectFileListTruncationReason = "max-files" | "max-depth" | "max-total-bytes";
6
+ export type SiteEditProjectFileListResult = {
7
+ files: SiteEditProjectFileInfo[];
8
+ truncated?: {
9
+ reasons: SiteEditProjectFileListTruncationReason[];
10
+ };
11
+ };
1
12
  export interface SiteEditProjectFileSystem {
2
13
  readFile(file: string): Promise<string>;
14
+ readFileBytes?(file: string): Promise<Uint8Array>;
15
+ getFileInfo?(file: string): Promise<SiteEditProjectFileInfo | null>;
3
16
  writeFile(file: string, content: string): Promise<void>;
4
17
  deleteFile(file: string): Promise<void>;
5
18
  exists(file: string): Promise<boolean>;
19
+ listFiles?(input?: {
20
+ roots?: string[];
21
+ maxFiles?: number;
22
+ maxDepth?: number;
23
+ maxTotalBytes?: number;
24
+ }): Promise<SiteEditProjectFileInfo[] | SiteEditProjectFileListResult>;
6
25
  getVersion(file: string): number;
7
26
  bumpVersion(file: string): number;
8
27
  }
package/dist/runtime.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type SiteEditResolveSourceLocationInput } from "@vcp-dev/contracts";
1
2
  import type { SiteEditEngineRuntime, SiteEditEngineRuntimeOptions, SiteEditPlanOperationResult } from "./types.js";
2
3
  export declare class SnapshotSiteEditEngineRuntime implements SiteEditEngineRuntime {
3
4
  private readonly options;
@@ -214,8 +215,59 @@ export declare class SnapshotSiteEditEngineRuntime implements SiteEditEngineRunt
214
215
  computedStyle?: Record<string, string> | undefined;
215
216
  } | undefined;
216
217
  };
218
+ getSourceTree(): Promise<{
219
+ nodes: import("@vcp-dev/contracts").SiteEditSourceTreeNode[];
220
+ totalFiles: number;
221
+ defaultPath?: string | undefined;
222
+ truncated?: {
223
+ reasons: ("max-files" | "max-depth" | "max-total-bytes")[];
224
+ maxFiles: number;
225
+ maxDepth: number;
226
+ maxTotalBytes: number;
227
+ } | undefined;
228
+ }>;
229
+ getSourceFile(input: {
230
+ path: string;
231
+ }): Promise<{
232
+ path: string;
233
+ sizeBytes: number;
234
+ kind: "text";
235
+ language: string;
236
+ readonly: boolean;
237
+ content: string;
238
+ contentHash?: string | undefined;
239
+ } | {
240
+ path: string;
241
+ sizeBytes: number;
242
+ kind: "binary";
243
+ language: null;
244
+ readonly: true;
245
+ mimeType: string;
246
+ contentHash?: string | undefined;
247
+ contentBase64?: string | undefined;
248
+ previewUnavailableReason?: "too-large" | "unsupported-mime" | "bytes-unavailable" | undefined;
249
+ }>;
250
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): {
251
+ key: string;
252
+ sourceFile: string;
253
+ componentName: string;
254
+ openingElementRange: {
255
+ startLine: number;
256
+ startColumn: number;
257
+ endLine: number;
258
+ endColumn: number;
259
+ };
260
+ structuralPath: string;
261
+ routeId?: string | undefined;
262
+ textPreview?: string | undefined;
263
+ };
217
264
  planOperation(request: Parameters<SiteEditEngineRuntime["planOperation"]>[0]): Promise<SiteEditPlanOperationResult>;
218
265
  dispose(): void;
266
+ private getPlanningRouteIds;
267
+ private getExplicitPlanningRouteId;
268
+ private getBuiltRouteIdsForKey;
269
+ private withInferredNodeRouteId;
270
+ private findRouteIdForNodeTarget;
219
271
  private createEngine;
220
272
  private getChangedRouteIds;
221
273
  }
@@ -1 +1 @@
1
- "use strict";var S=require("@babel/generator"),v=require("@babel/parser"),h=require("@babel/traverse"),o=require("@babel/types"),j=typeof S=="function"?S:S.default,k=typeof h=="function"?h:h.default,O={key:"data-vcp-edit-key",parentKey:"data-vcp-edit-parent-key",movable:"data-vcp-movable",removable:"data-vcp-removable",flags:"data-vcp-flags"},M=new Set(["base","body","head","html","link","meta","noscript","script","style","template","title"]);var F="suppressHydrationWarning",$=new Set(["SiteEditBootstrap"]),L="data-vcp-ui-component",f="components/ui";function W(e,t){this.cacheable?.();let n=this.async();try{if(!U(this.resourcePath)){n(null,e,t);return}let r=this.getOptions?.()??{},i=A({source:e,file:this.resourcePath,projectRoot:r.projectRoot});n(null,i.code,i.code===e?t:null)}catch(r){n(r)}}function U(e){return typeof e=="string"&&/\.(jsx|tsx)$/.test(e)&&!e.includes("/node_modules/")&&!e.endsWith(".d.ts")}function A(e){let t=q(e.file,e.projectRoot);if(!D(e.source)||d(t))return{code:e.source,elements:[]};let n=e.attributes??O,r=v.parse(e.source,{sourceType:"module",plugins:["jsx","typescript"]}),i=[],s=H(r,t);return k(r,{JSXElement(c){let u=c.node.openingElement,l=u.name;if(!Y(l)||J(u,n.key))return;let P=ee(c)??"default",R=ne(c),y=z(t,P,R),g=m(l)??"unknown",E=K(l)?"jsx":"component-call";if(E==="component-call"&&!te(c.node.children)&&$.has(g))return;let _=E==="component-call"&&Q(g,s);Z(u,n.key,y),_&&C(u,L),B(c)&&C(u,F),i.push({key:y,tag:g,component_name:P,source_file:t,source_kind:E})}}),{code:j(r,{jsescOption:{minimal:!0}}).code,elements:i}}function B(e){return!e.findParent(t=>t.isJSXElement())}function D(e){return e.includes("<")}function z(e,t,n){return`${e}::${t}::${n}`}function q(e,t){let n=e.replace(/\\/g,"/").replace(/^\.\//,""),r=t?.replace(/\\/g,"/").replace(/\/+$/,"");if(r&&n.startsWith(`${r}/`))return n.slice(r.length+1);for(let[s,c]of[["/src/app/",1],["/src/components/",1],["/app/",1],["/components/",1]]){let u=n.indexOf(s);if(u>=0)return n.slice(u+c)}return n.match(/(?:^|\/)((?:src\/app|src\/components|app|components)\/.+)$/)?.[1]??n}function K(e){return o.isJSXIdentifier(e)&&/^[a-z]/.test(e.name)}function m(e){return o.isJSXIdentifier(e)?e.name:o.isJSXMemberExpression(e)?w(e):null}function H(e,t){let n=new Set;for(let r of e.program.body)if(!(!o.isImportDeclaration(r)||!V(r.source.value,t)))for(let i of r.specifiers)n.add(i.local.name);return n}function Q(e,t){let n=e.split(".")[0]??e;return t.has(n)}function d(e){if(!e)return!1;let t=x(e);return t===f||t.startsWith(`${f}/`)||t.includes(`/${f}/`)||t.endsWith(`/${f}`)}function V(e,t){return e?e.startsWith("@/")||e.startsWith("~/")?d(e.slice(2)):e.startsWith("./")||e.startsWith("../")?d(x(`${G(t)}/${e}`)):d(e):!1}function x(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let i of n.split("/"))if(!(!i||i===".")){if(i===".."){r.pop();continue}r.push(i)}return r.join("/")}function G(e){let t=x(e),n=t.lastIndexOf("/");return n>=0?t.slice(0,n):""}function Y(e){let t=m(e);return!t||t==="Fragment"||t.endsWith(".Fragment")?!1:!M.has(t)}function J(e,t){return e.attributes.some(n=>o.isJSXAttribute(n)&&o.isJSXIdentifier(n.name,{name:t}))}function Z(e,t,n){X(e,o.jsxAttribute(o.jsxIdentifier(t),o.stringLiteral(n)))}function C(e,t){J(e,t)||X(e,o.jsxAttribute(o.jsxIdentifier(t),null))}function X(e,t){let n=e.attributes.findIndex(r=>o.isJSXSpreadAttribute(r));if(n>=0){e.attributes.splice(n,0,t);return}e.attributes.push(t)}function w(e){return`${o.isJSXIdentifier(e.object)?e.object.name:w(e.object)}.${e.property.name}`}function ee(e){let t=e;for(;t;){if(t.isFunctionDeclaration()||t.isClassDeclaration())return t.node.id?.name??null;if(t.isVariableDeclarator()&&o.isIdentifier(t.node.id)){let n=t.get("init");if(!Array.isArray(n)&&(n.isArrowFunctionExpression()||n.isFunctionExpression()))return t.node.id.name}t=t.parentPath}return null}function te(e){return e.some(t=>o.isJSXElement(t)||o.isJSXFragment(t))}var I=new WeakMap,N=new WeakMap,b=new WeakMap;function ne(e){let t=I.get(e.node);if(t!==void 0)return t;let n=[],r=e;for(;r;){if(r.isJSXElement()){let s=re(r);s&&n.unshift(s)}r=r.parentPath}let i=n.join("/");return I.set(e.node,i),i}function re(e){let t=m(e.node.openingElement.name);return!t||t==="Fragment"||t.endsWith(".Fragment")?null:/^[A-Z]/.test(t)?`component:${t}#${T(e,t)}`:`${t}#${T(e,t)}`}function T(e,t){let n=ie(e);if(!n)return 0;let r=b.get(n.node)?.get(t)?.get(e.node);if(r!==void 0)return r;let i=b.get(n.node);i||(i=new Map,b.set(n.node,i));let s=i.get(t);s||(s=new WeakMap,i.set(t,s));let c=0;for(let u of p(n))if(m(u.node.openingElement.name)===t){if(s.set(u.node,c),u.node===e.node)return c;c+=1}return s.get(e.node)??0}function ie(e){let t=e.parentPath,n=null;for(;t;){if(t.isJSXFragment()){n=t,t=t.parentPath;continue}if(t.isJSXElement())return t;t=t.parentPath}return n}function p(e){let t=N.get(e.node);if(t)return t;let n=[],r=e.get("children");for(let i of r)if(!Array.isArray(i)){if(i.isJSXElement()){n.push(i);continue}if(i.isJSXFragment()){n.push(...p(i));continue}i.isJSXExpressionContainer()&&n.push(...a(i.get("expression")))}return N.set(e.node,n),n}function a(e){return e.isJSXElement()?[e]:e.isJSXFragment()?p(e):e.isParenthesizedExpression()?a(e.get("expression")):e.isLogicalExpression()&&e.node.operator==="&&"?a(e.get("right")):e.isConditionalExpression()?[...a(e.get("consequent")),...a(e.get("alternate"))]:e.isCallExpression()&&se(e.node)?oe(e.get("arguments")[0]):[]}function oe(e){if(!e?.isArrowFunctionExpression()&&!e?.isFunctionExpression())return[];let t=e.get("body");if(t.isJSXElement())return[t];if(t.isJSXFragment())return p(t);if(t.isParenthesizedExpression())return a(t.get("expression"));if(!t.isBlockStatement())return[];for(let n of t.get("body")){if(!n.isReturnStatement())continue;let r=n.get("argument");return r.node?a(r):[]}return[]}function se(e){return o.isMemberExpression(e.callee)&&o.isIdentifier(e.callee.property)&&e.callee.property.name==="map"}module.exports=W;module.exports.instrumentSiteEditRuntimeAttributes=A;
1
+ "use strict";var S=require("@babel/generator"),v=require("@babel/parser"),h=require("@babel/traverse"),s=require("@babel/types"),j=typeof S=="function"?S:S.default,k=typeof h=="function"?h:h.default,O={key:"data-vcp-edit-key",parentKey:"data-vcp-edit-parent-key",movable:"data-vcp-movable",removable:"data-vcp-removable",flags:"data-vcp-flags"},M=new Set(["base","body","head","html","link","meta","noscript","script","style","template","title"]);var F="suppressHydrationWarning",$=new Set(["SiteEditBootstrap"]),L="data-vcp-ui-component",f="components/ui";function W(e,t){this.cacheable?.();let n=this.async();try{if(!U(this.resourcePath)){n(null,e,t);return}let r=this.getOptions?.()??{},i=A({source:e,file:this.resourcePath,projectRoot:r.projectRoot});n(null,i.code,i.code===e?t:null)}catch(r){n(r)}}function U(e){return typeof e=="string"&&/\.(jsx|tsx)$/.test(e)&&!e.includes("/node_modules/")&&!e.endsWith(".d.ts")}function A(e){let t=q(e.file,e.projectRoot);if(!B(e.source)||d(t))return{code:e.source,elements:[]};let n=e.attributes??O,r=v.parse(e.source,{sourceType:"module",plugins:["jsx","typescript"]}),i=[],o=H(r,t);return k(r,{JSXElement(c){let u=c.node.openingElement,l=u.name;if(!G(l)||J(u,n.key))return;let y=ee(c)??"default",R=ne(c),P=D(t,y,R),g=m(l)??"unknown",E=K(l)?"jsx":"component-call";if(E==="component-call"&&!te(c.node.children)&&$.has(g))return;let _=E==="component-call"&&Q(g,o);Y(u,n.key,P),_&&C(u,L),z(c)&&C(u,F),i.push({key:P,tag:g,component_name:y,source_file:t,source_kind:E})}}),i.length===0?{code:e.source,elements:i}:{code:j(r,{jsescOption:{minimal:!0}}).code,elements:i}}function z(e){return!e.findParent(t=>t.isJSXElement())}function B(e){if(typeof e!="string")throw new TypeError("site edit instrumentation source must be a string");return/(?:^|[=(:,?;\[{>&|\n\r]|return\s+)\s*<(?:[A-Za-z][\w.:-]*|>)(?:\s|>|\/)/m.test(e)}function D(e,t,n){return`${e}::${t}::${n}`}function q(e,t){let n=e.replace(/\\/g,"/").replace(/^\.\//,""),r=t?.replace(/\\/g,"/").replace(/\/+$/,"");if(r&&n.startsWith(`${r}/`))return n.slice(r.length+1);for(let[o,c]of[["/src/app/",1],["/src/components/",1],["/app/",1],["/components/",1]]){let u=n.indexOf(o);if(u>=0)return n.slice(u+c)}return n.match(/(?:^|\/)((?:src\/app|src\/components|app|components)\/.+)$/)?.[1]??n}function K(e){return s.isJSXIdentifier(e)&&/^[a-z]/.test(e.name)}function m(e){return s.isJSXIdentifier(e)?e.name:s.isJSXMemberExpression(e)?w(e):null}function H(e,t){let n=new Set;for(let r of e.program.body)if(!(!s.isImportDeclaration(r)||!V(r.source.value,t)))for(let i of r.specifiers)n.add(i.local.name);return n}function Q(e,t){let n=e.split(".")[0]??e;return t.has(n)}function d(e){if(!e)return!1;let t=x(e);return t===f||t.startsWith(`${f}/`)||t.includes(`/${f}/`)||t.endsWith(`/${f}`)}function V(e,t){return e?e.startsWith("@/")||e.startsWith("~/")?d(e.slice(2)):e.startsWith("./")||e.startsWith("../")?d(x(`${Z(t)}/${e}`)):d(e):!1}function x(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let i of n.split("/"))if(!(!i||i===".")){if(i===".."){r.pop();continue}r.push(i)}return r.join("/")}function Z(e){let t=x(e),n=t.lastIndexOf("/");return n>=0?t.slice(0,n):""}function G(e){let t=m(e);return!t||t==="Fragment"||t.endsWith(".Fragment")?!1:!M.has(t)}function J(e,t){return e.attributes.some(n=>s.isJSXAttribute(n)&&s.isJSXIdentifier(n.name,{name:t}))}function Y(e,t,n){X(e,s.jsxAttribute(s.jsxIdentifier(t),s.stringLiteral(n)))}function C(e,t){J(e,t)||X(e,s.jsxAttribute(s.jsxIdentifier(t),null))}function X(e,t){let n=e.attributes.findIndex(r=>s.isJSXSpreadAttribute(r));if(n>=0){e.attributes.splice(n,0,t);return}e.attributes.push(t)}function w(e){return`${s.isJSXIdentifier(e.object)?e.object.name:w(e.object)}.${e.property.name}`}function ee(e){let t=e;for(;t;){if(t.isFunctionDeclaration()||t.isClassDeclaration())return t.node.id?.name??null;if(t.isVariableDeclarator()&&s.isIdentifier(t.node.id)){let n=t.get("init");if(!Array.isArray(n)&&(n.isArrowFunctionExpression()||n.isFunctionExpression()))return t.node.id.name}t=t.parentPath}return null}function te(e){return e.some(t=>s.isJSXElement(t)||s.isJSXFragment(t))}var I=new WeakMap,T=new WeakMap,b=new WeakMap;function ne(e){let t=I.get(e.node);if(t!==void 0)return t;let n=[],r=e;for(;r;){if(r.isJSXElement()){let o=re(r);o&&n.unshift(o)}r=r.parentPath}let i=n.join("/");return I.set(e.node,i),i}function re(e){let t=m(e.node.openingElement.name);return!t||t==="Fragment"||t.endsWith(".Fragment")?null:/^[A-Z]/.test(t)?`component:${t}#${N(e,t)}`:`${t}#${N(e,t)}`}function N(e,t){let n=ie(e);if(!n)return 0;let r=b.get(n.node)?.get(t)?.get(e.node);if(r!==void 0)return r;let i=b.get(n.node);i||(i=new Map,b.set(n.node,i));let o=i.get(t);o||(o=new WeakMap,i.set(t,o));let c=0;for(let u of p(n))if(m(u.node.openingElement.name)===t){if(o.set(u.node,c),u.node===e.node)return c;c+=1}return o.get(e.node)??0}function ie(e){let t=e.parentPath,n=null;for(;t;){if(t.isJSXFragment()){n=t,t=t.parentPath;continue}if(t.isJSXElement())return t;t=t.parentPath}return n}function p(e){let t=T.get(e.node);if(t)return t;let n=[],r=e.get("children");for(let i of r)if(!Array.isArray(i)){if(i.isJSXElement()){n.push(i);continue}if(i.isJSXFragment()){n.push(...p(i));continue}i.isJSXExpressionContainer()&&n.push(...a(i.get("expression")))}return T.set(e.node,n),n}function a(e){return e.isJSXElement()?[e]:e.isJSXFragment()?p(e):e.isParenthesizedExpression()?a(e.get("expression")):e.isLogicalExpression()&&e.node.operator==="&&"?a(e.get("right")):e.isConditionalExpression()?[...a(e.get("consequent")),...a(e.get("alternate"))]:e.isCallExpression()&&oe(e.node)?se(e.get("arguments")[0]):[]}function se(e){if(!e?.isArrowFunctionExpression()&&!e?.isFunctionExpression())return[];let t=e.get("body");if(t.isJSXElement())return[t];if(t.isJSXFragment())return p(t);if(t.isParenthesizedExpression())return a(t.get("expression"));if(!t.isBlockStatement())return[];for(let n of t.get("body")){if(!n.isReturnStatement())continue;let r=n.get("argument");return r.node?a(r):[]}return[]}function oe(e){return s.isMemberExpression(e.callee)&&s.isIdentifier(e.callee.property)&&e.callee.property.name==="map"}module.exports=W;module.exports.instrumentSiteEditRuntimeAttributes=A;
@@ -1,14 +1,30 @@
1
+ export type SiteEditSourceWatcherDiagnostic = {
2
+ code: "change-batch-truncated" | "directory-budget-exceeded" | "file-budget-exceeded" | "startup-budget-exceeded" | "watcher-budget-exceeded";
3
+ message: string;
4
+ details?: Record<string, number | string>;
5
+ };
1
6
  export type SiteEditSourceWatcherOptions = {
2
7
  projectRoot: string;
3
8
  watch_dirs?: string[];
4
9
  interval_ms?: number;
10
+ debounce_ms?: number;
11
+ max_dirs?: number;
12
+ max_files?: number;
13
+ max_depth?: number;
14
+ max_startup_ms?: number;
15
+ max_changed_files_per_batch?: number;
5
16
  on_change(file: string): void;
17
+ on_batch_change?: (files: string[]) => void;
18
+ on_diagnostic?: (diagnostic: SiteEditSourceWatcherDiagnostic) => void;
6
19
  };
7
20
  export declare class SiteEditSourceWatcher {
8
21
  private readonly options;
9
22
  private readonly watchers;
23
+ private readonly registeredWatcherDirs;
10
24
  private readonly fileMtimes;
25
+ private readonly queuedChangedFiles;
11
26
  private pollingTimer;
27
+ private changeFlushTimer;
12
28
  private isPolling;
13
29
  private isStarted;
14
30
  private hasScanned;
@@ -16,7 +32,11 @@ export declare class SiteEditSourceWatcher {
16
32
  start(): () => void;
17
33
  stop(): void;
18
34
  private getWatchDirs;
35
+ private getBudget;
19
36
  private registerWatcher;
20
37
  private poll;
21
38
  private scanFiles;
39
+ private queueChangedFile;
40
+ private flushQueuedChanges;
41
+ private emitDiagnostic;
22
42
  }
@@ -1 +1 @@
1
- import c from"node:fs";import l from"node:path";var m=["app","src/app","components","src/components","lib","src/lib"],u=/\.(?:tsx|ts|jsx|js|mjs|cjs|css|scss|sass|mdx|json)$/,p=/^(?:\.next|node_modules|\.git)(?:\/|$)/,f=class{constructor(t){this.options=t,this.watchers=[],this.fileMtimes=new Map,this.pollingTimer=null,this.isPolling=!1,this.isStarted=!1,this.hasScanned=!1}start(){if(this.isStarted)return()=>this.stop();this.isStarted=!0;let t=!1;for(let s of this.getWatchDirs()){let e=l.join(this.options.projectRoot,s);if(c.existsSync(e)){if(this.registerWatcher(e,!0)){t=!0;continue}for(let i of d(e))t=this.registerWatcher(i,!1)||t}}if(this.scanFiles(),!t){let s=this.options.interval_ms??1e3;this.pollingTimer=setInterval(()=>this.poll(),s),this.pollingTimer.unref?.()}return()=>this.stop()}stop(){if(this.isStarted){this.pollingTimer&&(clearInterval(this.pollingTimer),this.pollingTimer=null);for(let t of this.watchers)t.close();this.watchers.length=0,this.isStarted=!1}}getWatchDirs(){return this.options.watch_dirs?.length?this.options.watch_dirs:m}registerWatcher(t,s){try{let e=c.watch(t,{recursive:s},(i,o)=>{let r=y(this.options.projectRoot,t,o);if(r){this.options.on_change(r);return}let h=o?l.join(t,o.toString()):null;if(h&&c.existsSync(h))try{c.statSync(h).isDirectory()&&this.registerWatcher(h,!1)}catch{}});return e.on("error",()=>{this.poll()}),e.unref?.(),this.watchers.push(e),!0}catch{return!1}}poll(){if(!this.isPolling){this.isPolling=!0;try{this.scanFiles()}finally{this.isPolling=!1}}}scanFiles(){let t=new Set;for(let s of this.getWatchDirs()){let e=l.join(this.options.projectRoot,s);if(c.existsSync(e))for(let i of g(this.options.projectRoot,e))try{let o=c.statSync(i),r=a(this.options.projectRoot,i);t.add(r);let h=this.fileMtimes.get(r);this.hasScanned&&(h===void 0||h!==o.mtimeMs)&&this.options.on_change(r),this.fileMtimes.set(r,o.mtimeMs)}catch{}}if(this.hasScanned)for(let s of this.fileMtimes.keys())t.has(s)||(this.fileMtimes.delete(s),this.options.on_change(s));this.hasScanned=!0}};function d(n){let t=[n],s;try{s=c.readdirSync(n,{withFileTypes:!0})}catch{return t}for(let e of s)!e.isDirectory()||e.name.startsWith(".")||e.name==="node_modules"||t.push(...d(l.join(n,e.name)));return t}function g(n,t){let s=[],e;try{e=c.readdirSync(t,{withFileTypes:!0})}catch{return s}for(let i of e){let o=l.join(t,i.name);if(i.isDirectory()){if(i.name.startsWith(".")||i.name==="node_modules")continue;s.push(...g(n,o));continue}let r=a(n,o);!p.test(r)&&u.test(r)&&s.push(o)}return s}function y(n,t,s){if(!s)return null;let e=l.join(t,s.toString()),i=a(n,e);return!i||i.startsWith("..")||p.test(i)||!u.test(i)?null:i}function a(n,t){return l.relative(n,t).replace(/\\/g,"/")}export{f as SiteEditSourceWatcher};
1
+ import u from"node:fs";import h from"node:path";var S=["app","src/app","components/site","src/components/site","lib/generated","src/lib/generated","public"],x=/\.(?:tsx|ts|jsx|js|mjs|cjs|css|scss|sass|mdx|json)$/,D=new Set([".git",".next",".turbo","build","coverage","dist","node_modules","output"]),_=512,y=5e3,M=8,w=1e3,T=50,b=500,p=class{constructor(t){this.options=t,this.watchers=[],this.registeredWatcherDirs=new Set,this.fileMtimes=new Map,this.queuedChangedFiles=new Set,this.pollingTimer=null,this.changeFlushTimer=null,this.isPolling=!1,this.isStarted=!1,this.hasScanned=!1}start(){if(this.isStarted)return()=>this.stop();this.isStarted=!0;let t=!1,e=Date.now(),i=this.getBudget();for(let s of this.getWatchDirs()){if(f(e,i.maxStartupMs)){this.emitDiagnostic({code:"startup-budget-exceeded",message:"Source watcher startup budget was exceeded before all roots were registered.",details:{maxStartupMs:i.maxStartupMs}});break}let a=h.join(this.options.projectRoot,s);if(!u.existsSync(a))continue;if(this.registerWatcher(a,!0)){t=!0;continue}let r=j(this.options.projectRoot,a,{maxDirs:i.maxDirs,maxDepth:i.maxDepth,maxStartupMs:i.maxStartupMs,startedAt:e});r.truncated&&this.emitDiagnostic(r.truncated);for(let n of r.directories)t=this.registerWatcher(n,!1)||t}if(this.scanFiles(),!t){let s=this.options.interval_ms??1e3;this.pollingTimer=setInterval(()=>this.poll(),s),this.pollingTimer?.unref?.()}return()=>this.stop()}stop(){if(this.isStarted){this.pollingTimer&&(clearInterval(this.pollingTimer),this.pollingTimer=null),this.changeFlushTimer&&(clearTimeout(this.changeFlushTimer),this.changeFlushTimer=null),this.queuedChangedFiles.clear();for(let t of this.watchers)t.close();this.watchers.length=0,this.registeredWatcherDirs.clear(),this.isStarted=!1}}getWatchDirs(){return v(this.options.projectRoot,this.options.watch_dirs?.length?this.options.watch_dirs:S)}getBudget(){return{maxDirs:Math.max(1,this.options.max_dirs??_),maxFiles:Math.max(1,this.options.max_files??y),maxDepth:Math.max(1,this.options.max_depth??M),maxStartupMs:Math.max(1,this.options.max_startup_ms??w),debounceMs:Math.max(0,this.options.debounce_ms??T),maxChangedFilesPerBatch:Math.max(1,this.options.max_changed_files_per_batch??b)}}registerWatcher(t,e){let i=d(this.options.projectRoot,t);if(this.registeredWatcherDirs.has(i))return!0;if(this.registeredWatcherDirs.size>=this.getBudget().maxDirs)return this.emitDiagnostic({code:"watcher-budget-exceeded",message:"Source watcher native watcher budget was exceeded.",details:{maxDirs:this.getBudget().maxDirs}}),!1;try{let s=u.watch(t,{recursive:e},(a,r)=>{let n=A(this.options.projectRoot,t,r);if(n){this.queueChangedFile(n);return}let c=r?h.join(t,r.toString()):null;if(c&&u.existsSync(c))try{let l=d(this.options.projectRoot,c);u.statSync(c).isDirectory()&&!m(l)&&this.registerWatcher(c,!1)}catch{}});return s.on("error",()=>{this.poll()}),s?.unref?.(),this.watchers.push(s),this.registeredWatcherDirs.add(i),!0}catch{return!1}}poll(){if(!this.isPolling){this.isPolling=!0;try{this.scanFiles()}finally{this.isPolling=!1}}}scanFiles(){let t=new Set,e=this.getBudget(),i=Date.now();for(let s of this.getWatchDirs()){let a=h.join(this.options.projectRoot,s);if(!u.existsSync(a))continue;let r=W(this.options.projectRoot,a,{maxFiles:e.maxFiles,maxDepth:e.maxDepth,maxStartupMs:e.maxStartupMs,startedAt:i});r.truncated&&this.emitDiagnostic(r.truncated);for(let n of r.files)try{let c=u.statSync(n),l=d(this.options.projectRoot,n);t.add(l);let g=this.fileMtimes.get(l);this.hasScanned&&(g===void 0||g!==c.mtimeMs)&&this.queueChangedFile(l),this.fileMtimes.set(l,c.mtimeMs)}catch{}}if(this.hasScanned)for(let s of this.fileMtimes.keys())t.has(s)||(this.fileMtimes.delete(s),this.queueChangedFile(s));this.hasScanned=!0}queueChangedFile(t){let e=this.getBudget();if(this.queuedChangedFiles.size>=e.maxChangedFilesPerBatch){this.queuedChangedFiles.has(t)||this.emitDiagnostic({code:"change-batch-truncated",message:"Source watcher change batch exceeded the configured file budget.",details:{maxChangedFiles:e.maxChangedFilesPerBatch}});return}if(this.queuedChangedFiles.add(t),this.changeFlushTimer)return;let i=()=>this.flushQueuedChanges();if(e.debounceMs===0){i();return}this.changeFlushTimer=setTimeout(i,e.debounceMs),this.changeFlushTimer?.unref?.()}flushQueuedChanges(){if(this.changeFlushTimer&&(clearTimeout(this.changeFlushTimer),this.changeFlushTimer=null),this.queuedChangedFiles.size===0)return;let t=[...this.queuedChangedFiles].sort();if(this.queuedChangedFiles.clear(),this.options.on_batch_change){this.options.on_batch_change(t);return}for(let e of t)this.options.on_change(e)}emitDiagnostic(t){this.options.on_diagnostic?.(t)}};function v(o,t){let e=h.resolve(o),i=new Set;for(let r of t){let n=C(e,r);!n||m(n)||i.add(n)}let s=[...i].sort((r,n)=>r.split("/").length-n.split("/").length||r.length-n.length||r.localeCompare(n)),a=[];for(let r of s)a.some(n=>r===n||r.startsWith(`${n}/`))||a.push(r);return a}function C(o,t){let e=t.trim();if(!e)return"";let i=h.isAbsolute(e)?h.resolve(e):h.resolve(o,e),s=h.relative(o,i);return!s||s.startsWith("..")?"":s.replace(/\\/g,"/").replace(/^\.\//,"")}function j(o,t,e){let i=[],s=[{directory:t,depth:0}];for(;s.length>0;){let a=s.shift();if(i.length>=e.maxDirs)return{directories:i,truncated:{code:"directory-budget-exceeded",message:"Source watcher fallback directory scan was truncated by max_dirs.",details:{maxDirs:e.maxDirs}}};if(f(e.startedAt,e.maxStartupMs))return{directories:i,truncated:{code:"startup-budget-exceeded",message:"Source watcher fallback directory scan exceeded max_startup_ms.",details:{maxStartupMs:e.maxStartupMs}}};if(i.push(a.directory),a.depth>=e.maxDepth)continue;let r;try{r=u.readdirSync(a.directory,{withFileTypes:!0})}catch{continue}for(let n of r){if(!n.isDirectory()||F(n.name))continue;let c=h.join(a.directory,n.name),l=d(o,c);m(l)||s.push({directory:c,depth:a.depth+1})}}return{directories:i}}function W(o,t,e){let i=[],s=[{directory:t,depth:0}];for(;s.length>0;){let a=s.shift();if(f(e.startedAt,e.maxStartupMs))return{files:i,truncated:{code:"startup-budget-exceeded",message:"Source watcher file scan exceeded max_startup_ms.",details:{maxStartupMs:e.maxStartupMs}}};let r;try{r=u.readdirSync(a.directory,{withFileTypes:!0})}catch{continue}for(let n of r){let c=h.join(a.directory,n.name);if(n.isDirectory()){!F(n.name)&&a.depth<e.maxDepth&&!m(d(o,c))&&s.push({directory:c,depth:a.depth+1});continue}let l=d(o,c);if(!m(l)&&x.test(l)){if(i.length>=e.maxFiles)return{files:i,truncated:{code:"file-budget-exceeded",message:"Source watcher file scan was truncated by max_files.",details:{maxFiles:e.maxFiles}}};i.push(c)}}}return{files:i}}function A(o,t,e){if(!e)return null;let i=h.join(t,e.toString()),s=d(o,i);return!s||s.startsWith("..")||m(s)||!x.test(s)?null:s}function F(o){return o.startsWith(".")||D.has(o)}function m(o){return o.split("/").some(t=>D.has(t))}function f(o,t){return Date.now()-o>t}function d(o,t){return h.relative(o,t).replace(/\\/g,"/")}export{p as SiteEditSourceWatcher};
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { SiteEditCommandSuccess, SiteEditEvent, SiteEditGetClassNameSourceCommandResult, SiteEditGetClassNameSourceResult, SiteEditObjectEditContext, SiteEditObjectSummary, SiteEditOperationCommandResult, SiteEditOperationRequest, SiteEditPatchPlan, SiteEditRenderDocument } from "@vcp-dev/contracts";
1
+ import type { SiteEditCommandSuccess, SiteEditEvent, SiteEditGetClassNameSourceCommandResult, SiteEditGetClassNameSourceResult, SiteEditObjectEditContext, SiteEditObjectSummary, SiteEditOperationCommandResult, SiteEditOperationRequest, SiteEditPatchPlan, SiteEditRenderDocument, SiteEditResolveSourceLocationInput, SiteEditSourceFileResponse, SiteEditSourceLocation, SiteEditSourceTreeResponse } from "@vcp-dev/contracts";
2
2
  import type { SiteEditProjectFileSystem } from "./public-file-system.js";
3
3
  export type { SiteEditProjectFileSystem } from "./public-file-system.js";
4
4
  export interface SiteEditSnapshotFile {
@@ -29,6 +29,11 @@ export interface SiteEditEngineRuntime {
29
29
  getObjectSummary(key: string, routeId?: string): SiteEditObjectSummary;
30
30
  getObjectEditContext(key: string, routeId?: string): SiteEditObjectEditContext;
31
31
  getClassNameSource(key: string, routeId?: string): SiteEditGetClassNameSourceResult;
32
+ getSourceTree(): Promise<SiteEditSourceTreeResponse>;
33
+ getSourceFile(input: {
34
+ path: string;
35
+ }): Promise<SiteEditSourceFileResponse>;
36
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): SiteEditSourceLocation;
32
37
  planOperation(request: SiteEditOperationRequest): Promise<SiteEditPlanOperationResult>;
33
38
  dispose(): void;
34
39
  }
@@ -50,6 +55,11 @@ export interface PreviewSiteEditEngineRuntime {
50
55
  getObjectSummary(key: string, routeId?: string): SiteEditCommandSuccess<SiteEditObjectSummary>;
51
56
  getObjectEditContext(key: string, routeId?: string): SiteEditCommandSuccess<SiteEditObjectEditContext>;
52
57
  getClassNameSource(key: string, routeId?: string): SiteEditGetClassNameSourceCommandResult;
58
+ getSourceTree(): Promise<SiteEditCommandSuccess<SiteEditSourceTreeResponse>>;
59
+ getSourceFile(input: {
60
+ path: string;
61
+ }): Promise<SiteEditCommandSuccess<SiteEditSourceFileResponse>>;
62
+ resolveSourceLocation(input: SiteEditResolveSourceLocationInput): SiteEditCommandSuccess<SiteEditSourceLocation>;
53
63
  refreshSourceForKey(key: string, routeId?: string): Promise<void>;
54
64
  executeOperation(request: SiteEditOperationRequest): Promise<SiteEditOperationCommandResult>;
55
65
  undo(): Promise<SiteEditOperationCommandResult>;
@@ -1 +1 @@
1
- "use strict";var k=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var _=k((fe,P)=>{"use strict";var S=require("@babel/generator"),O=require("@babel/parser"),h=require("@babel/traverse"),o=require("@babel/types"),M=typeof S=="function"?S:S.default,F=typeof h=="function"?h:h.default,$={key:"data-vcp-edit-key",parentKey:"data-vcp-edit-parent-key",movable:"data-vcp-movable",removable:"data-vcp-removable",flags:"data-vcp-flags"},L=new Set(["base","body","head","html","link","meta","noscript","script","style","template","title"]),W="suppressHydrationWarning",U=new Set(["SiteEditBootstrap"]),B="data-vcp-ui-component",f="components/ui";function D(e,t){this.cacheable?.();let n=this.async();try{if(!z(this.resourcePath)){n(null,e,t);return}let r=this.getOptions?.()??{},i=J({source:e,file:this.resourcePath,projectRoot:r.projectRoot});n(null,i.code,i.code===e?t:null)}catch(r){n(r)}}function z(e){return typeof e=="string"&&/\.(jsx|tsx)$/.test(e)&&!e.includes("/node_modules/")&&!e.endsWith(".d.ts")}function J(e){let t=Q(e.file,e.projectRoot);if(!K(e.source)||d(t))return{code:e.source,elements:[]};let n=e.attributes??$,r=O.parse(e.source,{sourceType:"module",plugins:["jsx","typescript"]}),i=[],s=G(r,t);return F(r,{JSXElement(c){let u=c.node.openingElement,l=u.name;if(!te(l)||X(u,n.key))return;let y=re(c)??"default",v=oe(c),C=H(t,y,v),g=m(l)??"unknown",E=V(l)?"jsx":"component-call";if(E==="component-call"&&!ie(c.node.children)&&U.has(g))return;let j=E==="component-call"&&Y(g,s);ne(u,n.key,C),j&&I(u,B),q(c)&&I(u,W),i.push({key:C,tag:g,component_name:y,source_file:t,source_kind:E})}}),{code:M(r,{jsescOption:{minimal:!0}}).code,elements:i}}function q(e){return!e.findParent(t=>t.isJSXElement())}function K(e){return e.includes("<")}function H(e,t,n){return`${e}::${t}::${n}`}function Q(e,t){let n=e.replace(/\\/g,"/").replace(/^\.\//,""),r=t?.replace(/\\/g,"/").replace(/\/+$/,"");if(r&&n.startsWith(`${r}/`))return n.slice(r.length+1);for(let[s,c]of[["/src/app/",1],["/src/components/",1],["/app/",1],["/components/",1]]){let u=n.indexOf(s);if(u>=0)return n.slice(u+c)}return n.match(/(?:^|\/)((?:src\/app|src\/components|app|components)\/.+)$/)?.[1]??n}function V(e){return o.isJSXIdentifier(e)&&/^[a-z]/.test(e.name)}function m(e){return o.isJSXIdentifier(e)?e.name:o.isJSXMemberExpression(e)?R(e):null}function G(e,t){let n=new Set;for(let r of e.program.body)if(!(!o.isImportDeclaration(r)||!Z(r.source.value,t)))for(let i of r.specifiers)n.add(i.local.name);return n}function Y(e,t){let n=e.split(".")[0]??e;return t.has(n)}function d(e){if(!e)return!1;let t=x(e);return t===f||t.startsWith(`${f}/`)||t.includes(`/${f}/`)||t.endsWith(`/${f}`)}function Z(e,t){return e?e.startsWith("@/")||e.startsWith("~/")?d(e.slice(2)):e.startsWith("./")||e.startsWith("../")?d(x(`${ee(t)}/${e}`)):d(e):!1}function x(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let i of n.split("/"))if(!(!i||i===".")){if(i===".."){r.pop();continue}r.push(i)}return r.join("/")}function ee(e){let t=x(e),n=t.lastIndexOf("/");return n>=0?t.slice(0,n):""}function te(e){let t=m(e);return!t||t==="Fragment"||t.endsWith(".Fragment")?!1:!L.has(t)}function X(e,t){return e.attributes.some(n=>o.isJSXAttribute(n)&&o.isJSXIdentifier(n.name,{name:t}))}function ne(e,t,n){w(e,o.jsxAttribute(o.jsxIdentifier(t),o.stringLiteral(n)))}function I(e,t){X(e,t)||w(e,o.jsxAttribute(o.jsxIdentifier(t),null))}function w(e,t){let n=e.attributes.findIndex(r=>o.isJSXSpreadAttribute(r));if(n>=0){e.attributes.splice(n,0,t);return}e.attributes.push(t)}function R(e){return`${o.isJSXIdentifier(e.object)?e.object.name:R(e.object)}.${e.property.name}`}function re(e){let t=e;for(;t;){if(t.isFunctionDeclaration()||t.isClassDeclaration())return t.node.id?.name??null;if(t.isVariableDeclarator()&&o.isIdentifier(t.node.id)){let n=t.get("init");if(!Array.isArray(n)&&(n.isArrowFunctionExpression()||n.isFunctionExpression()))return t.node.id.name}t=t.parentPath}return null}function ie(e){return e.some(t=>o.isJSXElement(t)||o.isJSXFragment(t))}var N=new WeakMap,T=new WeakMap,b=new WeakMap;function oe(e){let t=N.get(e.node);if(t!==void 0)return t;let n=[],r=e;for(;r;){if(r.isJSXElement()){let s=se(r);s&&n.unshift(s)}r=r.parentPath}let i=n.join("/");return N.set(e.node,i),i}function se(e){let t=m(e.node.openingElement.name);return!t||t==="Fragment"||t.endsWith(".Fragment")?null:/^[A-Z]/.test(t)?`component:${t}#${A(e,t)}`:`${t}#${A(e,t)}`}function A(e,t){let n=ue(e);if(!n)return 0;let r=b.get(n.node)?.get(t)?.get(e.node);if(r!==void 0)return r;let i=b.get(n.node);i||(i=new Map,b.set(n.node,i));let s=i.get(t);s||(s=new WeakMap,i.set(t,s));let c=0;for(let u of p(n))if(m(u.node.openingElement.name)===t){if(s.set(u.node,c),u.node===e.node)return c;c+=1}return s.get(e.node)??0}function ue(e){let t=e.parentPath,n=null;for(;t;){if(t.isJSXFragment()){n=t,t=t.parentPath;continue}if(t.isJSXElement())return t;t=t.parentPath}return n}function p(e){let t=T.get(e.node);if(t)return t;let n=[],r=e.get("children");for(let i of r)if(!Array.isArray(i)){if(i.isJSXElement()){n.push(i);continue}if(i.isJSXFragment()){n.push(...p(i));continue}i.isJSXExpressionContainer()&&n.push(...a(i.get("expression")))}return T.set(e.node,n),n}function a(e){return e.isJSXElement()?[e]:e.isJSXFragment()?p(e):e.isParenthesizedExpression()?a(e.get("expression")):e.isLogicalExpression()&&e.node.operator==="&&"?a(e.get("right")):e.isConditionalExpression()?[...a(e.get("consequent")),...a(e.get("alternate"))]:e.isCallExpression()&&ae(e.node)?ce(e.get("arguments")[0]):[]}function ce(e){if(!e?.isArrowFunctionExpression()&&!e?.isFunctionExpression())return[];let t=e.get("body");if(t.isJSXElement())return[t];if(t.isJSXFragment())return p(t);if(t.isParenthesizedExpression())return a(t.get("expression"));if(!t.isBlockStatement())return[];for(let n of t.get("body")){if(!n.isReturnStatement())continue;let r=n.get("argument");return r.node?a(r):[]}return[]}function ae(e){return o.isMemberExpression(e.callee)&&o.isIdentifier(e.callee.property)&&e.callee.property.name==="map"}P.exports=D;P.exports.instrumentSiteEditRuntimeAttributes=J});module.exports=_();
1
+ "use strict";var k=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var _=k((fe,y)=>{"use strict";var S=require("@babel/generator"),O=require("@babel/parser"),h=require("@babel/traverse"),s=require("@babel/types"),M=typeof S=="function"?S:S.default,F=typeof h=="function"?h:h.default,$={key:"data-vcp-edit-key",parentKey:"data-vcp-edit-parent-key",movable:"data-vcp-movable",removable:"data-vcp-removable",flags:"data-vcp-flags"},L=new Set(["base","body","head","html","link","meta","noscript","script","style","template","title"]),W="suppressHydrationWarning",U=new Set(["SiteEditBootstrap"]),z="data-vcp-ui-component",f="components/ui";function B(e,t){this.cacheable?.();let n=this.async();try{if(!D(this.resourcePath)){n(null,e,t);return}let r=this.getOptions?.()??{},i=J({source:e,file:this.resourcePath,projectRoot:r.projectRoot});n(null,i.code,i.code===e?t:null)}catch(r){n(r)}}function D(e){return typeof e=="string"&&/\.(jsx|tsx)$/.test(e)&&!e.includes("/node_modules/")&&!e.endsWith(".d.ts")}function J(e){let t=Q(e.file,e.projectRoot);if(!K(e.source)||d(t))return{code:e.source,elements:[]};let n=e.attributes??$,r=O.parse(e.source,{sourceType:"module",plugins:["jsx","typescript"]}),i=[],o=Z(r,t);return F(r,{JSXElement(c){let u=c.node.openingElement,l=u.name;if(!te(l)||X(u,n.key))return;let P=re(c)??"default",v=se(c),C=H(t,P,v),g=m(l)??"unknown",E=V(l)?"jsx":"component-call";if(E==="component-call"&&!ie(c.node.children)&&U.has(g))return;let j=E==="component-call"&&G(g,o);ne(u,n.key,C),j&&I(u,z),q(c)&&I(u,W),i.push({key:C,tag:g,component_name:P,source_file:t,source_kind:E})}}),i.length===0?{code:e.source,elements:i}:{code:M(r,{jsescOption:{minimal:!0}}).code,elements:i}}function q(e){return!e.findParent(t=>t.isJSXElement())}function K(e){if(typeof e!="string")throw new TypeError("site edit instrumentation source must be a string");return/(?:^|[=(:,?;\[{>&|\n\r]|return\s+)\s*<(?:[A-Za-z][\w.:-]*|>)(?:\s|>|\/)/m.test(e)}function H(e,t,n){return`${e}::${t}::${n}`}function Q(e,t){let n=e.replace(/\\/g,"/").replace(/^\.\//,""),r=t?.replace(/\\/g,"/").replace(/\/+$/,"");if(r&&n.startsWith(`${r}/`))return n.slice(r.length+1);for(let[o,c]of[["/src/app/",1],["/src/components/",1],["/app/",1],["/components/",1]]){let u=n.indexOf(o);if(u>=0)return n.slice(u+c)}return n.match(/(?:^|\/)((?:src\/app|src\/components|app|components)\/.+)$/)?.[1]??n}function V(e){return s.isJSXIdentifier(e)&&/^[a-z]/.test(e.name)}function m(e){return s.isJSXIdentifier(e)?e.name:s.isJSXMemberExpression(e)?R(e):null}function Z(e,t){let n=new Set;for(let r of e.program.body)if(!(!s.isImportDeclaration(r)||!Y(r.source.value,t)))for(let i of r.specifiers)n.add(i.local.name);return n}function G(e,t){let n=e.split(".")[0]??e;return t.has(n)}function d(e){if(!e)return!1;let t=x(e);return t===f||t.startsWith(`${f}/`)||t.includes(`/${f}/`)||t.endsWith(`/${f}`)}function Y(e,t){return e?e.startsWith("@/")||e.startsWith("~/")?d(e.slice(2)):e.startsWith("./")||e.startsWith("../")?d(x(`${ee(t)}/${e}`)):d(e):!1}function x(e){let n=(e.split("?")[0]??e).replace(/\\/g,"/").replace(/^\.\//,""),r=[];for(let i of n.split("/"))if(!(!i||i===".")){if(i===".."){r.pop();continue}r.push(i)}return r.join("/")}function ee(e){let t=x(e),n=t.lastIndexOf("/");return n>=0?t.slice(0,n):""}function te(e){let t=m(e);return!t||t==="Fragment"||t.endsWith(".Fragment")?!1:!L.has(t)}function X(e,t){return e.attributes.some(n=>s.isJSXAttribute(n)&&s.isJSXIdentifier(n.name,{name:t}))}function ne(e,t,n){w(e,s.jsxAttribute(s.jsxIdentifier(t),s.stringLiteral(n)))}function I(e,t){X(e,t)||w(e,s.jsxAttribute(s.jsxIdentifier(t),null))}function w(e,t){let n=e.attributes.findIndex(r=>s.isJSXSpreadAttribute(r));if(n>=0){e.attributes.splice(n,0,t);return}e.attributes.push(t)}function R(e){return`${s.isJSXIdentifier(e.object)?e.object.name:R(e.object)}.${e.property.name}`}function re(e){let t=e;for(;t;){if(t.isFunctionDeclaration()||t.isClassDeclaration())return t.node.id?.name??null;if(t.isVariableDeclarator()&&s.isIdentifier(t.node.id)){let n=t.get("init");if(!Array.isArray(n)&&(n.isArrowFunctionExpression()||n.isFunctionExpression()))return t.node.id.name}t=t.parentPath}return null}function ie(e){return e.some(t=>s.isJSXElement(t)||s.isJSXFragment(t))}var T=new WeakMap,N=new WeakMap,b=new WeakMap;function se(e){let t=T.get(e.node);if(t!==void 0)return t;let n=[],r=e;for(;r;){if(r.isJSXElement()){let o=oe(r);o&&n.unshift(o)}r=r.parentPath}let i=n.join("/");return T.set(e.node,i),i}function oe(e){let t=m(e.node.openingElement.name);return!t||t==="Fragment"||t.endsWith(".Fragment")?null:/^[A-Z]/.test(t)?`component:${t}#${A(e,t)}`:`${t}#${A(e,t)}`}function A(e,t){let n=ue(e);if(!n)return 0;let r=b.get(n.node)?.get(t)?.get(e.node);if(r!==void 0)return r;let i=b.get(n.node);i||(i=new Map,b.set(n.node,i));let o=i.get(t);o||(o=new WeakMap,i.set(t,o));let c=0;for(let u of p(n))if(m(u.node.openingElement.name)===t){if(o.set(u.node,c),u.node===e.node)return c;c+=1}return o.get(e.node)??0}function ue(e){let t=e.parentPath,n=null;for(;t;){if(t.isJSXFragment()){n=t,t=t.parentPath;continue}if(t.isJSXElement())return t;t=t.parentPath}return n}function p(e){let t=N.get(e.node);if(t)return t;let n=[],r=e.get("children");for(let i of r)if(!Array.isArray(i)){if(i.isJSXElement()){n.push(i);continue}if(i.isJSXFragment()){n.push(...p(i));continue}i.isJSXExpressionContainer()&&n.push(...a(i.get("expression")))}return N.set(e.node,n),n}function a(e){return e.isJSXElement()?[e]:e.isJSXFragment()?p(e):e.isParenthesizedExpression()?a(e.get("expression")):e.isLogicalExpression()&&e.node.operator==="&&"?a(e.get("right")):e.isConditionalExpression()?[...a(e.get("consequent")),...a(e.get("alternate"))]:e.isCallExpression()&&ae(e.node)?ce(e.get("arguments")[0]):[]}function ce(e){if(!e?.isArrowFunctionExpression()&&!e?.isFunctionExpression())return[];let t=e.get("body");if(t.isJSXElement())return[t];if(t.isJSXFragment())return p(t);if(t.isParenthesizedExpression())return a(t.get("expression"));if(!t.isBlockStatement())return[];for(let n of t.get("body")){if(!n.isReturnStatement())continue;let r=n.get("argument");return r.node?a(r):[]}return[]}function ae(e){return s.isMemberExpression(e.callee)&&s.isIdentifier(e.callee.property)&&e.callee.property.name==="map"}y.exports=B;y.exports.instrumentSiteEditRuntimeAttributes=J});module.exports=_();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcp-dev/site-edit-engine",
3
- "version": "0.3.15",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -60,7 +60,7 @@
60
60
  "@babel/parser": "^7.29.3",
61
61
  "@babel/traverse": "^7.29.0",
62
62
  "@babel/types": "^7.29.0",
63
- "@vcp-dev/contracts": "0.3.15"
63
+ "@vcp-dev/contracts": "0.4.1"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/babel__generator": "^7.27.0",