@vcp-prod/site-edit-engine 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/next-app-router-fs.d.ts +2 -0
- package/dist/next-app-router.d.ts +11 -0
- package/dist/next-app-router.js +1 -0
- package/dist/preview-runtime.d.ts +318 -0
- package/dist/public-file-system.d.ts +8 -0
- package/dist/runtime-sync.d.ts +97 -0
- package/dist/runtime.d.ts +222 -0
- package/dist/site-edit-instrumentation.d.ts +19 -0
- package/dist/source-watcher.d.ts +22 -0
- package/dist/source-watcher.js +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/webpack-loader.cjs +1 -0
- package/dist/webpack-loader.d.ts +27 -0
- package/package.json +67 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SiteEditRuntimeAttributes } from "./runtime-sync.js";
|
|
2
|
+
export type SiteEditInstrumentationOptions = {
|
|
3
|
+
source: string;
|
|
4
|
+
file: string;
|
|
5
|
+
projectRoot?: string;
|
|
6
|
+
attributes?: SiteEditRuntimeAttributes;
|
|
7
|
+
};
|
|
8
|
+
export type SiteEditInstrumentedElement = {
|
|
9
|
+
key: string;
|
|
10
|
+
tag: string;
|
|
11
|
+
componentName: string;
|
|
12
|
+
sourceFile: string;
|
|
13
|
+
sourceKind: "jsx" | "component-call";
|
|
14
|
+
};
|
|
15
|
+
export type SiteEditInstrumentationResult = {
|
|
16
|
+
code: string;
|
|
17
|
+
elements: SiteEditInstrumentedElement[];
|
|
18
|
+
};
|
|
19
|
+
export declare function instrumentSiteEditRuntimeAttributes(options: SiteEditInstrumentationOptions): SiteEditInstrumentationResult;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type SiteEditSourceWatcherOptions = {
|
|
2
|
+
projectRoot: string;
|
|
3
|
+
watch_dirs?: string[];
|
|
4
|
+
interval_ms?: number;
|
|
5
|
+
on_change(file: string): void;
|
|
6
|
+
};
|
|
7
|
+
export declare class SiteEditSourceWatcher {
|
|
8
|
+
private readonly options;
|
|
9
|
+
private readonly watchers;
|
|
10
|
+
private readonly fileMtimes;
|
|
11
|
+
private pollingTimer;
|
|
12
|
+
private isPolling;
|
|
13
|
+
private isStarted;
|
|
14
|
+
private hasScanned;
|
|
15
|
+
constructor(options: SiteEditSourceWatcherOptions);
|
|
16
|
+
start(): () => void;
|
|
17
|
+
stop(): void;
|
|
18
|
+
private getWatchDirs;
|
|
19
|
+
private registerWatcher;
|
|
20
|
+
private poll;
|
|
21
|
+
private scanFiles;
|
|
22
|
+
}
|
|
@@ -0,0 +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};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { SiteEditCommandSuccess, SiteEditEvent, SiteEditGetClassNameSourceCommandResult, SiteEditGetClassNameSourceResult, SiteEditObjectEditContext, SiteEditObjectSummary, SiteEditOperationCommandResult, SiteEditOperationRequest, SiteEditPatchPlan, SiteEditRenderDocument } from "@vcp-prod/contracts";
|
|
2
|
+
import type { SiteEditProjectFileSystem } from "./public-file-system.js";
|
|
3
|
+
export type { SiteEditProjectFileSystem } from "./public-file-system.js";
|
|
4
|
+
export interface SiteEditSnapshotFile {
|
|
5
|
+
path: string;
|
|
6
|
+
content: string;
|
|
7
|
+
version?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SiteEditEngineRoute {
|
|
10
|
+
routeId: string;
|
|
11
|
+
entryFile: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SiteEditEngineRuntimeOptions {
|
|
14
|
+
siteId: string;
|
|
15
|
+
snapshotId: string;
|
|
16
|
+
files: SiteEditSnapshotFile[];
|
|
17
|
+
routes: SiteEditEngineRoute[];
|
|
18
|
+
onEvent?: (event: SiteEditEvent) => void;
|
|
19
|
+
dev?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface SiteEditPlanOperationResult {
|
|
22
|
+
result: SiteEditOperationCommandResult;
|
|
23
|
+
patchPlan?: SiteEditPatchPlan;
|
|
24
|
+
}
|
|
25
|
+
export interface SiteEditEngineRuntime {
|
|
26
|
+
readonly status: "idle" | "building" | "ready" | "disposed";
|
|
27
|
+
setActiveRoute(routeId: string): Promise<void>;
|
|
28
|
+
getDocument(routeId: string): SiteEditRenderDocument;
|
|
29
|
+
getObjectSummary(key: string, routeId?: string): SiteEditObjectSummary;
|
|
30
|
+
getObjectEditContext(key: string, routeId?: string): SiteEditObjectEditContext;
|
|
31
|
+
getClassNameSource(key: string, routeId?: string): SiteEditGetClassNameSourceResult;
|
|
32
|
+
planOperation(request: SiteEditOperationRequest): Promise<SiteEditPlanOperationResult>;
|
|
33
|
+
dispose(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface PreviewSiteEditEngineRuntimeOptions {
|
|
36
|
+
siteId: string;
|
|
37
|
+
snapshotId: string;
|
|
38
|
+
projectRoot: string;
|
|
39
|
+
routes: SiteEditEngineRoute[];
|
|
40
|
+
onEvent?: (event: SiteEditEvent) => void;
|
|
41
|
+
dev?: boolean;
|
|
42
|
+
fileSystem?: SiteEditProjectFileSystem;
|
|
43
|
+
}
|
|
44
|
+
export interface PreviewSiteEditEngineRuntime {
|
|
45
|
+
readonly status: "idle" | "building" | "ready" | "error" | "disposed";
|
|
46
|
+
registerRoute(routeId: string, entryFile: string): void;
|
|
47
|
+
unregisterRoute(routeId: string): void;
|
|
48
|
+
setActiveRoute(routeId: string): Promise<void>;
|
|
49
|
+
getDocument(routeId: string): SiteEditCommandSuccess<SiteEditRenderDocument>;
|
|
50
|
+
getObjectSummary(key: string, routeId?: string): SiteEditCommandSuccess<SiteEditObjectSummary>;
|
|
51
|
+
getObjectEditContext(key: string, routeId?: string): SiteEditCommandSuccess<SiteEditObjectEditContext>;
|
|
52
|
+
getClassNameSource(key: string, routeId?: string): SiteEditGetClassNameSourceCommandResult;
|
|
53
|
+
refreshSourceForKey(key: string, routeId?: string): Promise<void>;
|
|
54
|
+
executeOperation(request: SiteEditOperationRequest): Promise<SiteEditOperationCommandResult>;
|
|
55
|
+
undo(): Promise<SiteEditOperationCommandResult>;
|
|
56
|
+
redo(): Promise<SiteEditOperationCommandResult>;
|
|
57
|
+
notifyFileChanged(file: string): void;
|
|
58
|
+
subscribe(listener: (event: SiteEditEvent) => void): () => void;
|
|
59
|
+
dispose(): void;
|
|
60
|
+
}
|
|
@@ -0,0 +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;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SiteEditInstrumentationOptions,
|
|
3
|
+
SiteEditInstrumentationResult,
|
|
4
|
+
} from "./site-edit-instrumentation.js";
|
|
5
|
+
|
|
6
|
+
declare function siteEditInstrumentationLoader(
|
|
7
|
+
this: {
|
|
8
|
+
cacheable?: () => void;
|
|
9
|
+
async?: () => (
|
|
10
|
+
error?: Error | null,
|
|
11
|
+
code?: string,
|
|
12
|
+
inputSourceMap?: unknown,
|
|
13
|
+
) => void;
|
|
14
|
+
resourcePath?: string;
|
|
15
|
+
getOptions?: () => { projectRoot?: string };
|
|
16
|
+
},
|
|
17
|
+
source: string,
|
|
18
|
+
inputSourceMap?: unknown,
|
|
19
|
+
): void;
|
|
20
|
+
|
|
21
|
+
declare namespace siteEditInstrumentationLoader {
|
|
22
|
+
function instrumentSiteEditRuntimeAttributes(
|
|
23
|
+
options: SiteEditInstrumentationOptions,
|
|
24
|
+
): SiteEditInstrumentationResult;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export = siteEditInstrumentationLoader;
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vcp-prod/site-edit-engine",
|
|
3
|
+
"version": "0.3.14",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://gitlab.cedemo.cn/vibe-coding-platform/vcp.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://gitlab.cedemo.cn/vibe-coding-platform/vcp",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://gitlab.cedemo.cn/vibe-coding-platform/vcp/-/issues"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"development": "./src/index.ts",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./next-app-router": {
|
|
26
|
+
"development": "./src/next-app-router.ts",
|
|
27
|
+
"types": "./dist/next-app-router.d.ts",
|
|
28
|
+
"default": "./dist/next-app-router.js"
|
|
29
|
+
},
|
|
30
|
+
"./source-watcher": {
|
|
31
|
+
"development": "./src/source-watcher.ts",
|
|
32
|
+
"types": "./dist/source-watcher.d.ts",
|
|
33
|
+
"default": "./dist/source-watcher.js"
|
|
34
|
+
},
|
|
35
|
+
"./webpack-loader": {
|
|
36
|
+
"development": "./src/webpack-loader.cjs",
|
|
37
|
+
"types": "./dist/webpack-loader.d.ts",
|
|
38
|
+
"default": "./dist/webpack-loader.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=24.0.0"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "pnpm --dir ../contracts build && node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs'); fs.mkdirSync('dist', { recursive: true }); fs.copyFileSync('src/webpack-loader.cjs', 'dist/webpack-loader.cjs'); fs.copyFileSync('src/webpack-loader.d.ts', 'dist/webpack-loader.d.ts')\"",
|
|
50
|
+
"test": "vitest run --root ../.. packages/site-edit-engine/src",
|
|
51
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@babel/generator": "^7.29.1",
|
|
55
|
+
"@babel/parser": "^7.29.3",
|
|
56
|
+
"@babel/traverse": "^7.29.0",
|
|
57
|
+
"@babel/types": "^7.29.0",
|
|
58
|
+
"@vcp-prod/contracts": "0.3.14"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/babel__generator": "^7.27.0",
|
|
62
|
+
"@types/babel__traverse": "^7.28.0",
|
|
63
|
+
"@types/node": "^24.0.0",
|
|
64
|
+
"typescript": "^5.8.0",
|
|
65
|
+
"vitest": "^3.2.0"
|
|
66
|
+
}
|
|
67
|
+
}
|