veryfront 0.1.88 → 0.1.90
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/esm/cli/commands/knowledge/command.d.ts +3 -0
- package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
- package/esm/cli/commands/knowledge/command.js +27 -2
- package/esm/deno.js +1 -1
- package/esm/src/html/styles-builder/candidate-extractor.d.ts +5 -1
- package/esm/src/html/styles-builder/candidate-extractor.d.ts.map +1 -1
- package/esm/src/html/styles-builder/candidate-extractor.js +6 -1
- package/esm/src/html/styles-builder/content-version.d.ts +9 -0
- package/esm/src/html/styles-builder/content-version.d.ts.map +1 -0
- package/esm/src/html/styles-builder/content-version.js +15 -0
- package/esm/src/html/styles-builder/css-pregeneration.d.ts +11 -0
- package/esm/src/html/styles-builder/css-pregeneration.d.ts.map +1 -1
- package/esm/src/html/styles-builder/css-pregeneration.js +15 -10
- package/esm/src/html/styles-builder/prepared-project-css-cache.d.ts +31 -0
- package/esm/src/html/styles-builder/prepared-project-css-cache.d.ts.map +1 -0
- package/esm/src/html/styles-builder/prepared-project-css-cache.js +165 -0
- package/esm/src/html/styles-builder/style-scope-profile.d.ts +14 -0
- package/esm/src/html/styles-builder/style-scope-profile.d.ts.map +1 -0
- package/esm/src/html/styles-builder/style-scope-profile.js +121 -0
- package/esm/src/platform/adapters/fs/factory.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/factory.js +2 -21
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.js +44 -19
- package/esm/src/platform/adapters/fs/veryfront/default-invalidation-callbacks.d.ts +3 -0
- package/esm/src/platform/adapters/fs/veryfront/default-invalidation-callbacks.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/default-invalidation-callbacks.js +25 -0
- package/esm/src/platform/adapters/fs/veryfront/proxy-manager.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/proxy-manager.js +2 -15
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts +4 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +2 -0
- package/esm/src/rendering/orchestrator/css-candidate-manifest.d.ts +3 -0
- package/esm/src/rendering/orchestrator/css-candidate-manifest.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/css-candidate-manifest.js +10 -5
- package/esm/src/rendering/orchestrator/html.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/html.js +8 -0
- package/esm/src/rendering/orchestrator/module-loader/index.js +2 -2
- package/esm/src/server/handlers/dev/styles-candidate-scanner.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/styles-candidate-scanner.js +14 -16
- package/esm/src/server/handlers/dev/styles-css.handler.d.ts +2 -0
- package/esm/src/server/handlers/dev/styles-css.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/styles-css.handler.js +55 -8
- package/esm/src/transforms/mdx/esm-module-loader/cache/index.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/cache/index.js +6 -7
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.d.ts +10 -0
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.d.ts.map +1 -0
- package/esm/src/transforms/mdx/esm-module-loader/cache-format.js +61 -0
- package/esm/src/transforms/mdx/esm-module-loader/import-transformer.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/import-transformer.js +2 -3
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/cache-keys.js +3 -3
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/framework-validator.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/framework-validator.js +2 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/module-cache.d.ts.map +1 -1
- package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/module-cache.js +5 -5
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/transform.d.ts +2 -2
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/transform.d.ts.map +1 -1
- package/esm/src/transforms/pipeline/stages/ssr-vf-modules/transform.js +4 -4
- package/esm/src/utils/cache-namespace.d.ts +11 -0
- package/esm/src/utils/cache-namespace.d.ts.map +1 -0
- package/esm/src/utils/cache-namespace.js +24 -0
- package/esm/src/utils/version.d.ts +1 -1
- package/esm/src/utils/version.js +1 -1
- package/package.json +1 -1
- package/src/cli/commands/knowledge/command.ts +30 -2
- package/src/deno.js +1 -1
- package/src/src/html/styles-builder/candidate-extractor.ts +13 -0
- package/src/src/html/styles-builder/content-version.ts +20 -0
- package/src/src/html/styles-builder/css-pregeneration.ts +49 -12
- package/src/src/html/styles-builder/prepared-project-css-cache.ts +228 -0
- package/src/src/html/styles-builder/style-scope-profile.ts +164 -0
- package/src/src/platform/adapters/fs/factory.ts +2 -27
- package/src/src/platform/adapters/fs/veryfront/adapter.ts +49 -20
- package/src/src/platform/adapters/fs/veryfront/default-invalidation-callbacks.ts +35 -0
- package/src/src/platform/adapters/fs/veryfront/proxy-manager.ts +4 -21
- package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +3 -0
- package/src/src/rendering/orchestrator/css-candidate-manifest.ts +28 -6
- package/src/src/rendering/orchestrator/html.ts +11 -0
- package/src/src/rendering/orchestrator/module-loader/index.ts +2 -2
- package/src/src/server/handlers/dev/styles-candidate-scanner.ts +18 -15
- package/src/src/server/handlers/dev/styles-css.handler.ts +88 -16
- package/src/src/transforms/mdx/esm-module-loader/cache/index.ts +6 -8
- package/src/src/transforms/mdx/esm-module-loader/cache-format.ts +121 -0
- package/src/src/transforms/mdx/esm-module-loader/import-transformer.ts +2 -3
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/cache-keys.ts +3 -3
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/framework-validator.ts +2 -1
- package/src/src/transforms/mdx/esm-module-loader/module-fetcher/module-cache.ts +5 -5
- package/src/src/transforms/pipeline/stages/ssr-vf-modules/transform.ts +4 -4
- package/src/src/utils/cache-namespace.ts +42 -0
- package/src/src/utils/version.ts +1 -1
|
@@ -108,7 +108,10 @@ export declare function normalizeKnowledgeInputPath(inputPath: string): string;
|
|
|
108
108
|
export declare function normalizeProjectUploadPath(inputPath: string): string;
|
|
109
109
|
export declare function formatKnowledgeUploadSource(uploadPath: string): string;
|
|
110
110
|
export declare function isLikelyLocalPath(value: string): boolean;
|
|
111
|
+
export declare function stripChatUploadPrefix(name: string): string;
|
|
111
112
|
export declare function resolveKnowledgeDownloadOutputDir(outputDir: string): string;
|
|
113
|
+
export declare function buildSuggestedSlug(source: KnowledgeSource, index: number): string;
|
|
114
|
+
export declare function ensureUniqueSlugs(sources: KnowledgeSource[]): string[];
|
|
112
115
|
export declare function deriveKnowledgeRemotePath(outputPath: string, outputDir: string, knowledgePath: string): string;
|
|
113
116
|
export declare function createKnowledgeIngestResult(input: {
|
|
114
117
|
source: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/knowledge/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,KAAK,SAAS,EAA0C,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,EAAuB,KAAK,MAAM,EAAgB,MAAM,6BAA6B,CAAC;AAG7F,OAAO,EAEL,KAAK,+BAA+B,EAEpC,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACtC,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,IAAI,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,gCAAgC,EAAE,CAAC;CAC7C;AAED,KAAK,cAAc,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAIhF,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD7B,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAoD/E,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,UAAU,GACf,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAexD;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKtE;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGxD;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/knowledge/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,KAAK,SAAS,EAA0C,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,EAAuB,KAAK,MAAM,EAAgB,MAAM,6BAA6B,CAAC;AAG7F,OAAO,EAEL,KAAK,+BAA+B,EAEpC,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACtC,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,IAAI,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,gCAAgC,EAAE,CAAC;CAC7C;AAED,KAAK,cAAc,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAIhF,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD7B,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAoD/E,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,UAAU,GACf,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAexD;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKtE;AAcD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGxD;AAyBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAMD,wBAAgB,iCAAiC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3E;AAwID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAkCjF;AACD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAQtE;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,MAAM,CAQR;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC,CAAC;CAChG,GAAG,yBAAyB,CAY5B;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAuDjC;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC,EAC/E,IAAI,EAAE;IACJ,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;CACvE,GACA,OAAO,CAAC,yBAAyB,CAAC,CAuJpC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE;IACJ,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,kBAAkB,CAAC;IACrC,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1F,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACA,OAAO,CAAC;IACT,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,MAAM,EAAE,+BAA+B,EAAE,CAAC;CAC3C,CAAC,CAsGD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwItE"}
|
|
@@ -158,6 +158,20 @@ function isProjectUploadReference(value) {
|
|
|
158
158
|
function slugify(value) {
|
|
159
159
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "document";
|
|
160
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Strip the chat-upload prefix that Studio prepends to uploaded files.
|
|
163
|
+
*
|
|
164
|
+
* Studio stores uploads with a generated prefix like:
|
|
165
|
+
* chat-<uuid>-<timestamp>-<shortid>-<original-filename>
|
|
166
|
+
*
|
|
167
|
+
* This function removes the prefix so knowledge files use the clean
|
|
168
|
+
* original filename (e.g. "agents" instead of
|
|
169
|
+
* "chat-909d3dbc-5a9a-4156-97e4-bcceb5c2ec0d-1773942180291-fv1qg5-agents").
|
|
170
|
+
*/
|
|
171
|
+
const CHAT_UPLOAD_PREFIX_RE = /^chat-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-\d+-[a-z0-9]+-/i;
|
|
172
|
+
export function stripChatUploadPrefix(name) {
|
|
173
|
+
return name.replace(CHAT_UPLOAD_PREFIX_RE, "");
|
|
174
|
+
}
|
|
161
175
|
function defaultOutputRoot() {
|
|
162
176
|
return dntShim.Deno.makeTempDir({ prefix: "veryfront-knowledge-" });
|
|
163
177
|
}
|
|
@@ -267,7 +281,7 @@ function buildSourceReference(source) {
|
|
|
267
281
|
? formatKnowledgeUploadSource(source.uploadPath)
|
|
268
282
|
: source.localPath;
|
|
269
283
|
}
|
|
270
|
-
function buildSuggestedSlug(source, index) {
|
|
284
|
+
export function buildSuggestedSlug(source, index) {
|
|
271
285
|
const normalized = normalize(source.kind === "upload" ? source.uploadPath : source.localPath).replace(/\\/g, "/");
|
|
272
286
|
let stripped;
|
|
273
287
|
if (source.kind === "upload") {
|
|
@@ -289,9 +303,20 @@ function buildSuggestedSlug(source, index) {
|
|
|
289
303
|
else {
|
|
290
304
|
stripped = normalized.replace(/\.[^.]+$/, "");
|
|
291
305
|
}
|
|
306
|
+
// Strip Studio's chat-upload prefix from the filename portion so that
|
|
307
|
+
// knowledge files use the original clean filename.
|
|
308
|
+
const lastSlash = stripped.lastIndexOf("/");
|
|
309
|
+
if (lastSlash >= 0) {
|
|
310
|
+
const dir = stripped.slice(0, lastSlash + 1);
|
|
311
|
+
const file = stripChatUploadPrefix(stripped.slice(lastSlash + 1));
|
|
312
|
+
stripped = file ? `${dir}${file}` : stripped;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
stripped = stripChatUploadPrefix(stripped) || stripped;
|
|
316
|
+
}
|
|
292
317
|
return slugify(stripped || basename(normalized, extname(normalized)) || `document-${index + 1}`);
|
|
293
318
|
}
|
|
294
|
-
function ensureUniqueSlugs(sources) {
|
|
319
|
+
export function ensureUniqueSlugs(sources) {
|
|
295
320
|
const counts = new Map();
|
|
296
321
|
return sources.map((source, index) => {
|
|
297
322
|
const baseSlug = buildSuggestedSlug(source, index);
|
package/esm/deno.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module html/styles-builder/candidate-extractor
|
|
7
7
|
*/
|
|
8
|
+
import type { StyleScopeProfile } from "./style-scope-profile.js";
|
|
8
9
|
/**
|
|
9
10
|
* Extract potential Tailwind class name candidates from source code content.
|
|
10
11
|
* Uses a comprehensive regex pattern matching Tailwind v4 utility patterns.
|
|
@@ -13,7 +14,10 @@ export declare function extractCandidates(content: string): string[];
|
|
|
13
14
|
export declare function extractCandidatesFromFiles(files: Array<{
|
|
14
15
|
path: string;
|
|
15
16
|
content?: string;
|
|
16
|
-
}
|
|
17
|
+
}>, options?: {
|
|
18
|
+
projectDir?: string;
|
|
19
|
+
styleProfile?: StyleScopeProfile;
|
|
20
|
+
}): Set<string>;
|
|
17
21
|
/**
|
|
18
22
|
* Simple DJB2-style hash function.
|
|
19
23
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate-extractor.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/candidate-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3D;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"candidate-extractor.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/candidate-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3D;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAChD,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GACL,GAAG,CAAC,MAAM,CAAC,CAoBb;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAE9D"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module html/styles-builder/candidate-extractor
|
|
7
7
|
*/
|
|
8
|
+
import { shouldIncludeStylePath } from "./style-scope-profile.js";
|
|
8
9
|
/**
|
|
9
10
|
* Extract potential Tailwind class name candidates from source code content.
|
|
10
11
|
* Uses a comprehensive regex pattern matching Tailwind v4 utility patterns.
|
|
@@ -13,12 +14,16 @@ export function extractCandidates(content) {
|
|
|
13
14
|
const pattern = /!?-?@?(?:[a-zA-Z0-9]|\[&?)[a-zA-Z0-9_\-:\/\.\[\]%#,()!'=<>$@{}|*+?;^~]*/g;
|
|
14
15
|
return [...new Set(content.match(pattern) ?? [])];
|
|
15
16
|
}
|
|
16
|
-
export function extractCandidatesFromFiles(files) {
|
|
17
|
+
export function extractCandidatesFromFiles(files, options = {}) {
|
|
17
18
|
const candidates = new Set();
|
|
18
19
|
const sourceExtensions = [".tsx", ".jsx", ".ts", ".js", ".mdx"];
|
|
19
20
|
for (const file of files) {
|
|
20
21
|
if (!file.content)
|
|
21
22
|
continue;
|
|
23
|
+
if (options.styleProfile &&
|
|
24
|
+
!shouldIncludeStylePath(options.styleProfile, file.path, options.projectDir)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
22
27
|
if (!sourceExtensions.some((ext) => file.path.endsWith(ext)))
|
|
23
28
|
continue;
|
|
24
29
|
for (const candidate of extractCandidates(file.content)) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResolvedContentContext } from "../../platform/adapters/fs/veryfront/types.js";
|
|
2
|
+
interface ContentVersionFallback {
|
|
3
|
+
releaseId?: string | null;
|
|
4
|
+
branch?: string | null;
|
|
5
|
+
environmentName?: string | null;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveStyleContentVersion(contentContext: ResolvedContentContext | null, fallback?: ContentVersionFallback): string;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=content-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-version.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/content-version.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAE5F,UAAU,sBAAsB;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,sBAAsB,GAAG,IAAI,EAC7C,QAAQ,GAAE,sBAA2B,GACpC,MAAM,CAQR"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function resolveStyleContentVersion(contentContext, fallback = {}) {
|
|
2
|
+
if (contentContext?.releaseId)
|
|
3
|
+
return `release:${contentContext.releaseId}`;
|
|
4
|
+
if (contentContext?.branch)
|
|
5
|
+
return `branch:${contentContext.branch}`;
|
|
6
|
+
if (contentContext?.environmentName)
|
|
7
|
+
return `environment:${contentContext.environmentName}`;
|
|
8
|
+
if (fallback.releaseId)
|
|
9
|
+
return `release:${fallback.releaseId}`;
|
|
10
|
+
if (fallback.branch)
|
|
11
|
+
return `branch:${fallback.branch}`;
|
|
12
|
+
if (fallback.environmentName)
|
|
13
|
+
return `environment:${fallback.environmentName}`;
|
|
14
|
+
return "live";
|
|
15
|
+
}
|
|
@@ -5,20 +5,31 @@
|
|
|
5
5
|
* until HTML shell generation during SSR. This runs in parallel with other
|
|
6
6
|
* initialization work, reducing first-request latency by ~2-3 seconds.
|
|
7
7
|
*/
|
|
8
|
+
import type { StyleScopeProfile } from "./style-scope-profile.js";
|
|
8
9
|
interface CSSPregenerationOptions {
|
|
9
10
|
/** Project slug for cache keying */
|
|
10
11
|
projectSlug: string;
|
|
12
|
+
/** Current content version for the prepared stylesheet artifact */
|
|
13
|
+
projectVersion: string;
|
|
14
|
+
/** Project root used for style scope filtering */
|
|
15
|
+
projectDir?: string;
|
|
11
16
|
/** List of files with content to extract candidates from */
|
|
12
17
|
files: Array<{
|
|
13
18
|
path: string;
|
|
14
19
|
content?: string;
|
|
15
20
|
}>;
|
|
21
|
+
/** Style scope profile for convention-based filtering */
|
|
22
|
+
styleProfile: StyleScopeProfile;
|
|
16
23
|
/** Optional custom stylesheet (globals.css content) */
|
|
17
24
|
stylesheet?: string;
|
|
18
25
|
/** Optional stylesheet path (from config) to locate content in files */
|
|
19
26
|
stylesheetPath?: string;
|
|
20
27
|
/** Enable minification (default: true) */
|
|
21
28
|
minify?: boolean;
|
|
29
|
+
/** Environment segment used for prepared artifact cache partitioning */
|
|
30
|
+
environment?: string;
|
|
31
|
+
/** Build mode recorded in the prepared artifact profile */
|
|
32
|
+
buildMode?: "development" | "production";
|
|
22
33
|
}
|
|
23
34
|
/**
|
|
24
35
|
* Pre-generate and cache CSS from file list.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-pregeneration.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/css-pregeneration.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"css-pregeneration.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/css-pregeneration.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,UAAU,uBAAuB;IAC/B,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,yDAAyD;IACzD,YAAY,EAAE,iBAAiB,CAAC;IAChC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAChD,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAUpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC/C,MAAM,GAAG,SAAS,CAgBpB"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { serverLogger } from "../../utils/index.js";
|
|
9
9
|
import { extractCandidatesFromFiles, getProjectCSS } from "./tailwind-compiler.js";
|
|
10
|
+
import { createPreparedProjectCSSContext, storePreparedProjectCSS, } from "./prepared-project-css-cache.js";
|
|
10
11
|
const logger = serverLogger.component("css-pregeneration");
|
|
11
12
|
/**
|
|
12
13
|
* Pre-generate and cache CSS from file list.
|
|
@@ -21,28 +22,32 @@ const logger = serverLogger.component("css-pregeneration");
|
|
|
21
22
|
* @returns Promise that resolves when CSS is generated (or immediately on error)
|
|
22
23
|
*/
|
|
23
24
|
export async function pregenerateCSSFromFiles(options) {
|
|
24
|
-
const { projectSlug, files, stylesheet, stylesheetPath, minify = true } = options;
|
|
25
|
+
const { projectSlug, projectVersion, projectDir, files, styleProfile, stylesheet, stylesheetPath, minify = true, environment = "preview", buildMode = "production", } = options;
|
|
25
26
|
const startTime = performance.now();
|
|
26
27
|
try {
|
|
27
|
-
const candidates = extractCandidatesFromFiles(files);
|
|
28
|
-
if (candidates.size === 0) {
|
|
29
|
-
logger.debug("No candidates found, skipping", {
|
|
30
|
-
projectSlug,
|
|
31
|
-
fileCount: files.length,
|
|
32
|
-
});
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
28
|
const resolvedStylesheet = stylesheet ?? findStylesheetFromFiles(files, stylesheetPath);
|
|
29
|
+
const candidates = extractCandidatesFromFiles(files, {
|
|
30
|
+
projectDir,
|
|
31
|
+
styleProfile,
|
|
32
|
+
});
|
|
36
33
|
logger.debug("Starting", {
|
|
37
34
|
projectSlug,
|
|
35
|
+
projectVersion,
|
|
38
36
|
fileCount: files.length,
|
|
39
37
|
candidateCount: candidates.size,
|
|
40
38
|
hasStylesheet: Boolean(resolvedStylesheet),
|
|
39
|
+
styleProfileHash: styleProfile.hash,
|
|
40
|
+
});
|
|
41
|
+
const result = await getProjectCSS(projectSlug, resolvedStylesheet, candidates, {
|
|
42
|
+
minify,
|
|
43
|
+
environment,
|
|
44
|
+
buildMode,
|
|
41
45
|
});
|
|
42
|
-
|
|
46
|
+
await storePreparedProjectCSS(createPreparedProjectCSSContext(projectSlug, projectVersion, resolvedStylesheet, styleProfile.hash, { minify, environment, buildMode }), { css: result.css, hash: result.hash });
|
|
43
47
|
const duration = performance.now() - startTime;
|
|
44
48
|
logger.debug("Complete", {
|
|
45
49
|
projectSlug,
|
|
50
|
+
projectVersion,
|
|
46
51
|
candidateCount: candidates.size,
|
|
47
52
|
cssLength: result.css.length,
|
|
48
53
|
cssHash: result.hash,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface PreparedProjectCSSCacheEntry {
|
|
2
|
+
css: string;
|
|
3
|
+
hash: string;
|
|
4
|
+
}
|
|
5
|
+
interface PreparedProjectCSSProfile {
|
|
6
|
+
minify?: boolean;
|
|
7
|
+
environment?: string;
|
|
8
|
+
buildMode?: "development" | "production";
|
|
9
|
+
}
|
|
10
|
+
export interface PreparedProjectCSSRequestContext {
|
|
11
|
+
projectSlug: string;
|
|
12
|
+
projectVersion: string;
|
|
13
|
+
stylesheet: string;
|
|
14
|
+
stylesheetHash: string;
|
|
15
|
+
styleProfileHash: string;
|
|
16
|
+
environment: string;
|
|
17
|
+
profileHash: string;
|
|
18
|
+
cacheKey: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function initializePreparedProjectCSSCache(): Promise<boolean>;
|
|
21
|
+
export declare function createPreparedProjectCSSContext(projectSlug: string, projectVersion: string, stylesheet: string | undefined, styleProfileHash: string, profile?: PreparedProjectCSSProfile): PreparedProjectCSSRequestContext;
|
|
22
|
+
export declare function tryGetPreparedProjectCSS(context: PreparedProjectCSSRequestContext): Promise<{
|
|
23
|
+
css: string;
|
|
24
|
+
hash: string;
|
|
25
|
+
fromCache: true;
|
|
26
|
+
} | undefined>;
|
|
27
|
+
export declare function storePreparedProjectCSS(context: PreparedProjectCSSRequestContext, entry: PreparedProjectCSSCacheEntry): Promise<void>;
|
|
28
|
+
export declare function invalidatePreparedProjectCSS(projectSlug: string): void;
|
|
29
|
+
export declare function invalidatePreparedProjectCSSAsync(projectSlug: string): Promise<void>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=prepared-project-css-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepared-project-css-cache.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/prepared-project-css-cache.ts"],"names":[],"mappings":"AAYA,UAAU,4BAA4B;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAMD,UAAU,yBAAyB;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;CAC1C;AAED,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAwDD,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,OAAO,CAAC,CAuB1E;AAED,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,yBAAyB,GAClC,gCAAgC,CAwBlC;AAED,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CAAC,CAgCrE;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,gCAAgC,EACzC,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAUtE;AAED,wBAAsB,iCAAiC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ1F"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { createCacheBackend, MemoryCacheBackend, } from "../../cache/backend.js";
|
|
2
|
+
import { registerCache } from "../../utils/memory/index.js";
|
|
3
|
+
import { serverLogger } from "../../utils/index.js";
|
|
4
|
+
import { DEFAULT_STYLESHEET } from "./css-hash-cache.js";
|
|
5
|
+
import { resolveStylesheet } from "./tailwind-compiler-utils.js";
|
|
6
|
+
const logger = serverLogger.component("prepared-project-css-cache");
|
|
7
|
+
const PREPARED_PROJECT_CSS_CACHE_TTL_SECONDS = 24 * 3600;
|
|
8
|
+
const PREPARED_PROJECT_CSS_LOCAL_MAX = 50;
|
|
9
|
+
const PREPARED_PROJECT_CSS_LOCAL_TTL_MS = PREPARED_PROJECT_CSS_CACHE_TTL_SECONDS * 1000;
|
|
10
|
+
let preparedProjectCSSBackend = null;
|
|
11
|
+
let preparedProjectCSSInitialized = false;
|
|
12
|
+
let preparedProjectCSSInitPromise = null;
|
|
13
|
+
const localPreparedProjectCSS = new Map();
|
|
14
|
+
registerCache("prepared-project-css-cache", () => ({
|
|
15
|
+
name: "prepared-project-css-cache",
|
|
16
|
+
entries: localPreparedProjectCSS.size,
|
|
17
|
+
maxEntries: PREPARED_PROJECT_CSS_LOCAL_MAX,
|
|
18
|
+
backend: preparedProjectCSSBackend?.type ?? "uninitialized",
|
|
19
|
+
}));
|
|
20
|
+
function hashValue(input) {
|
|
21
|
+
let hash = 0;
|
|
22
|
+
for (let index = 0; index < input.length; index++) {
|
|
23
|
+
hash = ((hash << 5) - hash) + input.charCodeAt(index);
|
|
24
|
+
hash |= 0;
|
|
25
|
+
}
|
|
26
|
+
return hash.toString(36);
|
|
27
|
+
}
|
|
28
|
+
function setLocalEntry(key, entry) {
|
|
29
|
+
localPreparedProjectCSS.set(key, {
|
|
30
|
+
...entry,
|
|
31
|
+
expiresAt: Date.now() + PREPARED_PROJECT_CSS_LOCAL_TTL_MS,
|
|
32
|
+
});
|
|
33
|
+
if (localPreparedProjectCSS.size <= PREPARED_PROJECT_CSS_LOCAL_MAX)
|
|
34
|
+
return;
|
|
35
|
+
const keys = localPreparedProjectCSS.keys();
|
|
36
|
+
while (localPreparedProjectCSS.size > PREPARED_PROJECT_CSS_LOCAL_MAX) {
|
|
37
|
+
const result = keys.next();
|
|
38
|
+
if (result.done)
|
|
39
|
+
break;
|
|
40
|
+
localPreparedProjectCSS.delete(result.value);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function parsePreparedProjectCSSCacheEntry(raw) {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(raw);
|
|
46
|
+
if (typeof parsed.css !== "string" || typeof parsed.hash !== "string")
|
|
47
|
+
return null;
|
|
48
|
+
return { css: parsed.css, hash: parsed.hash };
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function initializePreparedProjectCSSCache() {
|
|
55
|
+
if (preparedProjectCSSInitialized)
|
|
56
|
+
return preparedProjectCSSBackend?.type !== "memory";
|
|
57
|
+
if (!preparedProjectCSSInitPromise) {
|
|
58
|
+
preparedProjectCSSInitPromise = (async () => {
|
|
59
|
+
try {
|
|
60
|
+
preparedProjectCSSBackend = await createCacheBackend({
|
|
61
|
+
keyPrefix: "prepared-project-css",
|
|
62
|
+
});
|
|
63
|
+
logger.debug("Initialized", { backend: preparedProjectCSSBackend.type });
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger.warn("Backend init failed, using memory", { error });
|
|
67
|
+
preparedProjectCSSBackend = new MemoryCacheBackend(PREPARED_PROJECT_CSS_LOCAL_MAX);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
preparedProjectCSSInitialized = true;
|
|
71
|
+
}
|
|
72
|
+
})();
|
|
73
|
+
}
|
|
74
|
+
await preparedProjectCSSInitPromise;
|
|
75
|
+
preparedProjectCSSInitPromise = null;
|
|
76
|
+
return preparedProjectCSSBackend?.type !== "memory";
|
|
77
|
+
}
|
|
78
|
+
export function createPreparedProjectCSSContext(projectSlug, projectVersion, stylesheet, styleProfileHash, profile) {
|
|
79
|
+
const resolvedStylesheet = resolveStylesheet(stylesheet, DEFAULT_STYLESHEET);
|
|
80
|
+
const stylesheetHash = hashValue(resolvedStylesheet);
|
|
81
|
+
const environment = profile?.environment ?? "preview";
|
|
82
|
+
const profileHash = hashValue(JSON.stringify({
|
|
83
|
+
cacheSchema: "v1",
|
|
84
|
+
minify: profile?.minify ?? false,
|
|
85
|
+
buildMode: profile?.buildMode ?? "production",
|
|
86
|
+
environment,
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
projectSlug,
|
|
90
|
+
projectVersion,
|
|
91
|
+
stylesheet: resolvedStylesheet,
|
|
92
|
+
stylesheetHash,
|
|
93
|
+
styleProfileHash,
|
|
94
|
+
environment,
|
|
95
|
+
profileHash,
|
|
96
|
+
cacheKey: `${projectSlug}:${environment}:prepared:${projectVersion}:${stylesheetHash}:${styleProfileHash}:${profileHash}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export async function tryGetPreparedProjectCSS(context) {
|
|
100
|
+
const local = localPreparedProjectCSS.get(context.cacheKey);
|
|
101
|
+
if (local && local.expiresAt > Date.now()) {
|
|
102
|
+
return { css: local.css, hash: local.hash, fromCache: true };
|
|
103
|
+
}
|
|
104
|
+
if (local) {
|
|
105
|
+
localPreparedProjectCSS.delete(context.cacheKey);
|
|
106
|
+
}
|
|
107
|
+
if (!preparedProjectCSSInitialized) {
|
|
108
|
+
await initializePreparedProjectCSSCache();
|
|
109
|
+
}
|
|
110
|
+
if (!preparedProjectCSSBackend)
|
|
111
|
+
return undefined;
|
|
112
|
+
try {
|
|
113
|
+
const raw = await preparedProjectCSSBackend.get(context.cacheKey);
|
|
114
|
+
if (!raw)
|
|
115
|
+
return undefined;
|
|
116
|
+
const entry = parsePreparedProjectCSSCacheEntry(raw);
|
|
117
|
+
if (!entry)
|
|
118
|
+
return undefined;
|
|
119
|
+
setLocalEntry(context.cacheKey, entry);
|
|
120
|
+
return { css: entry.css, hash: entry.hash, fromCache: true };
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
logger.debug("Failed to read prepared project CSS", {
|
|
124
|
+
cacheKey: context.cacheKey,
|
|
125
|
+
error,
|
|
126
|
+
});
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export async function storePreparedProjectCSS(context, entry) {
|
|
131
|
+
if (!preparedProjectCSSInitialized) {
|
|
132
|
+
await initializePreparedProjectCSSCache();
|
|
133
|
+
}
|
|
134
|
+
setLocalEntry(context.cacheKey, entry);
|
|
135
|
+
if (!preparedProjectCSSBackend)
|
|
136
|
+
return;
|
|
137
|
+
preparedProjectCSSBackend
|
|
138
|
+
.set(context.cacheKey, JSON.stringify(entry), PREPARED_PROJECT_CSS_CACHE_TTL_SECONDS)
|
|
139
|
+
.catch((error) => {
|
|
140
|
+
logger.debug("Failed to store prepared project CSS", {
|
|
141
|
+
cacheKey: context.cacheKey,
|
|
142
|
+
error,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
export function invalidatePreparedProjectCSS(projectSlug) {
|
|
147
|
+
for (const key of localPreparedProjectCSS.keys()) {
|
|
148
|
+
if (key.startsWith(`${projectSlug}:`)) {
|
|
149
|
+
localPreparedProjectCSS.delete(key);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
invalidatePreparedProjectCSSAsync(projectSlug).catch((error) => {
|
|
153
|
+
logger.debug("Failed to invalidate prepared project CSS", { projectSlug, error });
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
export async function invalidatePreparedProjectCSSAsync(projectSlug) {
|
|
157
|
+
if (!preparedProjectCSSBackend?.delByPattern)
|
|
158
|
+
return;
|
|
159
|
+
try {
|
|
160
|
+
await preparedProjectCSSBackend.delByPattern(`${projectSlug}:*`);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
logger.debug("Failed to delete prepared project CSS", { projectSlug, error });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { VeryfrontConfig } from "../../config/index.js";
|
|
2
|
+
export interface StyleScopeProfile {
|
|
3
|
+
hash: string;
|
|
4
|
+
ignoredRoots: string[];
|
|
5
|
+
protectedRoots: string[];
|
|
6
|
+
protectedPaths: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function createStyleScopeProfile(config?: VeryfrontConfig): StyleScopeProfile;
|
|
9
|
+
export declare function shouldIncludeStylePath(profile: StyleScopeProfile, path: string, projectDir?: string): boolean;
|
|
10
|
+
export declare function shouldTraverseStyleDirectory(profile: StyleScopeProfile, directoryPath: string, projectDir?: string): boolean;
|
|
11
|
+
export declare function filterFilesForStyleScope<T extends {
|
|
12
|
+
path: string;
|
|
13
|
+
}>(files: T[], profile: StyleScopeProfile, projectDir?: string): T[];
|
|
14
|
+
//# sourceMappingURL=style-scope-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style-scope-profile.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/style-scope-profile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAqB7D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAkDD,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,iBAAiB,CA2CnF;AAUD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAMT;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAUT;AAED,wBAAgB,wBAAwB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACjE,KAAK,EAAE,CAAC,EAAE,EACV,OAAO,EAAE,iBAAiB,EAC1B,UAAU,CAAC,EAAE,MAAM,GAClB,CAAC,EAAE,CAEL"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const DEFAULT_IGNORED_ROOTS = [
|
|
2
|
+
"knowledge",
|
|
3
|
+
"coverage",
|
|
4
|
+
"dist",
|
|
5
|
+
"build",
|
|
6
|
+
".git",
|
|
7
|
+
"node_modules",
|
|
8
|
+
".cache",
|
|
9
|
+
];
|
|
10
|
+
const DEFAULT_PROTECTED_ROOTS = [
|
|
11
|
+
"app",
|
|
12
|
+
"pages",
|
|
13
|
+
"components",
|
|
14
|
+
"src/app",
|
|
15
|
+
"src/pages",
|
|
16
|
+
"src/components",
|
|
17
|
+
];
|
|
18
|
+
function normalizePath(path) {
|
|
19
|
+
return path.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
|
|
20
|
+
}
|
|
21
|
+
function normalizeRelativePath(path) {
|
|
22
|
+
return normalizePath(path).replace(/^\/+/, "").replace(/\/+$/, "");
|
|
23
|
+
}
|
|
24
|
+
function toRelativeProjectPath(path, projectDir) {
|
|
25
|
+
const normalized = normalizePath(path);
|
|
26
|
+
const normalizedProjectDir = projectDir
|
|
27
|
+
? normalizePath(projectDir).replace(/\/+$/, "")
|
|
28
|
+
: undefined;
|
|
29
|
+
if (normalizedProjectDir && normalized.startsWith(normalizedProjectDir)) {
|
|
30
|
+
return normalized.slice(normalizedProjectDir.length).replace(/^\/+/, "");
|
|
31
|
+
}
|
|
32
|
+
return normalized.replace(/^\/+/, "");
|
|
33
|
+
}
|
|
34
|
+
function isWithinPath(path, root) {
|
|
35
|
+
return path === root || path.startsWith(`${root}/`);
|
|
36
|
+
}
|
|
37
|
+
function getParentDirectory(path) {
|
|
38
|
+
const normalized = normalizeRelativePath(path);
|
|
39
|
+
const slashIndex = normalized.lastIndexOf("/");
|
|
40
|
+
if (slashIndex <= 0)
|
|
41
|
+
return null;
|
|
42
|
+
return normalized.slice(0, slashIndex);
|
|
43
|
+
}
|
|
44
|
+
function stableHash(input) {
|
|
45
|
+
let hash = 0;
|
|
46
|
+
for (let index = 0; index < input.length; index++) {
|
|
47
|
+
hash = ((hash << 5) - hash) + input.charCodeAt(index);
|
|
48
|
+
hash |= 0;
|
|
49
|
+
}
|
|
50
|
+
return hash.toString(36);
|
|
51
|
+
}
|
|
52
|
+
function addNormalizedPath(target, value) {
|
|
53
|
+
if (!value)
|
|
54
|
+
return;
|
|
55
|
+
const normalized = normalizeRelativePath(value);
|
|
56
|
+
if (!normalized)
|
|
57
|
+
return;
|
|
58
|
+
target.add(normalized);
|
|
59
|
+
}
|
|
60
|
+
export function createStyleScopeProfile(config) {
|
|
61
|
+
const ignoredRoots = new Set(DEFAULT_IGNORED_ROOTS);
|
|
62
|
+
const protectedRoots = new Set(DEFAULT_PROTECTED_ROOTS);
|
|
63
|
+
const protectedPaths = new Set();
|
|
64
|
+
addNormalizedPath(protectedRoots, config?.directories?.app);
|
|
65
|
+
addNormalizedPath(protectedRoots, config?.directories?.pages);
|
|
66
|
+
for (const path of config?.directories?.components ?? []) {
|
|
67
|
+
addNormalizedPath(protectedRoots, path);
|
|
68
|
+
}
|
|
69
|
+
const explicitPaths = [
|
|
70
|
+
typeof config?.layout === "string" ? config.layout : undefined,
|
|
71
|
+
typeof config?.app === "string" ? config.app : undefined,
|
|
72
|
+
config?.tailwind?.stylesheet,
|
|
73
|
+
];
|
|
74
|
+
for (const path of explicitPaths) {
|
|
75
|
+
addNormalizedPath(protectedPaths, path);
|
|
76
|
+
addNormalizedPath(protectedRoots, getParentDirectory(path ?? ""));
|
|
77
|
+
}
|
|
78
|
+
for (const root of protectedRoots) {
|
|
79
|
+
ignoredRoots.delete(root);
|
|
80
|
+
}
|
|
81
|
+
const sortedIgnoredRoots = [...ignoredRoots].sort();
|
|
82
|
+
const sortedProtectedRoots = [...protectedRoots].sort();
|
|
83
|
+
const sortedProtectedPaths = [...protectedPaths].sort();
|
|
84
|
+
return {
|
|
85
|
+
ignoredRoots: sortedIgnoredRoots,
|
|
86
|
+
protectedRoots: sortedProtectedRoots,
|
|
87
|
+
protectedPaths: sortedProtectedPaths,
|
|
88
|
+
hash: stableHash(JSON.stringify({
|
|
89
|
+
ignoredRoots: sortedIgnoredRoots,
|
|
90
|
+
protectedRoots: sortedProtectedRoots,
|
|
91
|
+
protectedPaths: sortedProtectedPaths,
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function isProtectedPath(profile, relativePath) {
|
|
96
|
+
return profile.protectedPaths.some((path) => isWithinPath(relativePath, path)) ||
|
|
97
|
+
profile.protectedRoots.some((path) => isWithinPath(relativePath, path));
|
|
98
|
+
}
|
|
99
|
+
export function shouldIncludeStylePath(profile, path, projectDir) {
|
|
100
|
+
const relativePath = normalizeRelativePath(toRelativeProjectPath(path, projectDir));
|
|
101
|
+
if (!relativePath)
|
|
102
|
+
return true;
|
|
103
|
+
if (isProtectedPath(profile, relativePath))
|
|
104
|
+
return true;
|
|
105
|
+
return !profile.ignoredRoots.some((root) => isWithinPath(relativePath, root));
|
|
106
|
+
}
|
|
107
|
+
export function shouldTraverseStyleDirectory(profile, directoryPath, projectDir) {
|
|
108
|
+
const relativePath = normalizeRelativePath(toRelativeProjectPath(directoryPath, projectDir));
|
|
109
|
+
if (!relativePath)
|
|
110
|
+
return true;
|
|
111
|
+
if (isProtectedPath(profile, relativePath))
|
|
112
|
+
return true;
|
|
113
|
+
const ignoredRoot = profile.ignoredRoots.find((root) => isWithinPath(relativePath, root));
|
|
114
|
+
if (!ignoredRoot)
|
|
115
|
+
return true;
|
|
116
|
+
return profile.protectedRoots.some((root) => isWithinPath(root, relativePath)) ||
|
|
117
|
+
profile.protectedPaths.some((path) => isWithinPath(path, relativePath));
|
|
118
|
+
}
|
|
119
|
+
export function filterFilesForStyleScope(files, profile, projectDir) {
|
|
120
|
+
return files.filter((file) => shouldIncludeStylePath(profile, file.path, projectDir));
|
|
121
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/fs/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/adapters/fs/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAgE3E"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { createError, toError } from "../../../errors/veryfront-error.js";
|
|
2
2
|
import { withSpan } from "../../../observability/tracing/otlp-setup.js";
|
|
3
|
-
import {
|
|
4
|
-
import { clearRouterDetectionCacheForProject } from "../../../rendering/router-detection.js";
|
|
5
|
-
import { clearModulePathCache, invalidateModulePaths, } from "../../../transforms/mdx/esm-module-loader/cache/index.js";
|
|
6
|
-
import { clearSnippetCacheForProject } from "../../../rendering/snippet-renderer.js";
|
|
7
|
-
import { clearRendererCacheForProject } from "../../../rendering/renderer.js";
|
|
8
|
-
import { invalidateProjectCSS } from "../../../html/styles-builder/tailwind-compiler.js";
|
|
9
|
-
import { invalidateProjectCandidateManifests } from "../../../rendering/orchestrator/css-candidate-manifest.js";
|
|
3
|
+
import { createDefaultInvalidationCallbacks } from "./veryfront/default-invalidation-callbacks.js";
|
|
10
4
|
export function createFSAdapter(config) {
|
|
11
5
|
const type = config.type ?? "local";
|
|
12
6
|
const proxyMode = config.veryfront?.proxyMode ?? false;
|
|
@@ -22,20 +16,7 @@ export function createFSAdapter(config) {
|
|
|
22
16
|
if (type === "veryfront-api") {
|
|
23
17
|
const configWithCallbacks = {
|
|
24
18
|
...config,
|
|
25
|
-
invalidationCallbacks:
|
|
26
|
-
clearSSRModuleCache,
|
|
27
|
-
clearModulePathCache,
|
|
28
|
-
invalidateModulePaths,
|
|
29
|
-
clearSSRModuleCacheForProject,
|
|
30
|
-
clearRouterDetectionCacheForProject,
|
|
31
|
-
clearSnippetCacheForProject,
|
|
32
|
-
clearRendererCacheForProject,
|
|
33
|
-
clearProjectCSSCache: (projectSlug) => {
|
|
34
|
-
invalidateProjectCSS(projectSlug);
|
|
35
|
-
invalidateProjectCandidateManifests(projectSlug);
|
|
36
|
-
},
|
|
37
|
-
...config.invalidationCallbacks,
|
|
38
|
-
},
|
|
19
|
+
invalidationCallbacks: createDefaultInvalidationCallbacks(config.invalidationCallbacks),
|
|
39
20
|
};
|
|
40
21
|
if (proxyMode) {
|
|
41
22
|
const { MultiProjectFSAdapter } = await import("./veryfront/multi-project-adapter.js");
|