veryfront 0.1.89 → 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/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/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/server/handlers/dev/styles-candidate-scanner.ts +18 -15
- package/src/src/server/handlers/dev/styles-css.handler.ts +88 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,SAAS,EACT,eAAe,EAEf,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AA2BnE,qBAAa,kBAAmB,YAAW,SAAS;IAClD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,WAAW,CAAS;IAE5B,kFAAkF;IAClF,OAAO,CAAC,oBAAoB,CAA6B;IACzD,0EAA0E;IAC1E,OAAO,CAAC,qBAAqB,CAA8B;IAC3D,OAAO,CAAC,iBAAiB,CAAuB;IAEhD,OAAO,CAAC,WAAW,CAAC,CAAU;IAC9B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,SAAS,CAAmB;IAEpC,4DAA4D;IAC5D,OAAO,CAAC,aAAa,CAAuB;IAE5C,+CAA+C;IAC/C,OAAO,CAAC,aAAa,CAAgB;IACrC,iGAAiG;IACjG,OAAO,CAAC,cAAc,CAAuC;IAC7D,mFAAmF;IACnF,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,EAAE,eAAe;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -164,6 +164,7 @@ export class VeryfrontFSAdapter {
|
|
|
164
164
|
},
|
|
165
165
|
clearFileListIndex: () => this.readOps.clearFileListIndex(),
|
|
166
166
|
setFileListCache: (cacheKey, files) => this.cache.setAsync(cacheKey, files),
|
|
167
|
+
pregenerateStyles: (files) => this.triggerCSSPregeneration(files),
|
|
167
168
|
});
|
|
168
169
|
logger.debug("Created", {
|
|
169
170
|
apiBaseUrl: this.apiBaseUrl,
|
|
@@ -245,10 +246,10 @@ export class VeryfrontFSAdapter {
|
|
|
245
246
|
sourceFiles: fileSummary.sourceFiles,
|
|
246
247
|
sourceFilesWithContent: fileSummary.sourceFilesWithContent,
|
|
247
248
|
});
|
|
248
|
-
// Trigger CSS pre-generation
|
|
249
|
-
// This
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
// Trigger CSS pre-generation after the initial file snapshot is ready.
|
|
250
|
+
// This keeps stylesheet generation off the first styles request for both
|
|
251
|
+
// preview branches and published content.
|
|
252
|
+
if (fileSummary.sourceFilesWithContent > 0) {
|
|
252
253
|
this.triggerCSSPregeneration(files).catch(() => {
|
|
253
254
|
// Error already logged in triggerCSSPregeneration
|
|
254
255
|
});
|
|
@@ -326,6 +327,12 @@ export class VeryfrontFSAdapter {
|
|
|
326
327
|
});
|
|
327
328
|
const files = await fetchFileListForContext(this.client, warmupContext);
|
|
328
329
|
await this.cache.setAsync(effectiveCacheKey, files);
|
|
330
|
+
const fileSummary = summarizeFileList(files);
|
|
331
|
+
if (fileSummary.sourceFilesWithContent > 0) {
|
|
332
|
+
this.triggerCSSPregeneration(files).catch(() => {
|
|
333
|
+
// Error already logged in triggerCSSPregeneration
|
|
334
|
+
});
|
|
335
|
+
}
|
|
329
336
|
logger.debug("File list warmup complete", {
|
|
330
337
|
reason,
|
|
331
338
|
cacheKey: effectiveCacheKey,
|
|
@@ -542,31 +549,49 @@ export class VeryfrontFSAdapter {
|
|
|
542
549
|
async triggerCSSPregeneration(files) {
|
|
543
550
|
try {
|
|
544
551
|
const { pregenerateCSSFromFiles, findStylesheetFromFiles } = await import("../../../../html/styles-builder/css-pregeneration.js");
|
|
552
|
+
const { resolveStyleContentVersion } = await import("../../../../html/styles-builder/content-version.js");
|
|
553
|
+
const { createStyleScopeProfile } = await import("../../../../html/styles-builder/style-scope-profile.js");
|
|
545
554
|
let stylesheetPath;
|
|
555
|
+
let styleProfile = createStyleScopeProfile();
|
|
546
556
|
const projectDir = this.normalizer.getProjectDir();
|
|
547
|
-
if (projectDir) {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
557
|
+
if (!projectDir) {
|
|
558
|
+
logger.debug("Skipping CSS pre-generation without projectDir", {
|
|
559
|
+
projectSlug: this.projectSlug,
|
|
560
|
+
});
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
try {
|
|
564
|
+
const { runtime } = await import("../../registry.js");
|
|
565
|
+
const { getConfig } = await import("../../../../config/index.js");
|
|
566
|
+
const adapter = await runtime.get();
|
|
567
|
+
const cacheKey = this.client.getProjectId() || this.projectSlug;
|
|
568
|
+
const config = await getConfig(projectDir, adapter, { cacheKey });
|
|
569
|
+
stylesheetPath = config?.tailwind?.stylesheet;
|
|
570
|
+
styleProfile = createStyleScopeProfile(config);
|
|
571
|
+
}
|
|
572
|
+
catch (error) {
|
|
573
|
+
logger.debug("Failed to load config for CSS pre-generation", {
|
|
574
|
+
projectSlug: this.projectSlug,
|
|
575
|
+
error: error instanceof Error ? error.message : String(error),
|
|
576
|
+
});
|
|
562
577
|
}
|
|
563
578
|
const stylesheet = findStylesheetFromFiles(files, stylesheetPath);
|
|
579
|
+
const projectVersion = resolveStyleContentVersion(this.contentContext, {
|
|
580
|
+
branch: this.contentContext?.branch ?? null,
|
|
581
|
+
releaseId: this.contentContext?.releaseId ?? null,
|
|
582
|
+
environmentName: this.contentContext?.environmentName ?? null,
|
|
583
|
+
});
|
|
564
584
|
await pregenerateCSSFromFiles({
|
|
565
585
|
projectSlug: this.projectSlug,
|
|
586
|
+
projectVersion,
|
|
587
|
+
projectDir,
|
|
566
588
|
files,
|
|
589
|
+
styleProfile,
|
|
567
590
|
stylesheet,
|
|
568
591
|
stylesheetPath,
|
|
569
592
|
minify: true,
|
|
593
|
+
environment: "preview",
|
|
594
|
+
buildMode: "production",
|
|
570
595
|
});
|
|
571
596
|
}
|
|
572
597
|
catch (error) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-invalidation-callbacks.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/default-invalidation-callbacks.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,wBAAgB,kCAAkC,CAChD,SAAS,CAAC,EAAE,qBAAqB,GAChC,qBAAqB,CAgBvB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { clearSSRModuleCache, clearSSRModuleCacheForProject, } from "../../../../modules/react-loader/ssr-module-loader/cache/index.js";
|
|
2
|
+
import { clearRouterDetectionCacheForProject } from "../../../../rendering/router-detection.js";
|
|
3
|
+
import { clearModulePathCache, invalidateModulePaths, } from "../../../../transforms/mdx/esm-module-loader/cache/index.js";
|
|
4
|
+
import { clearSnippetCacheForProject } from "../../../../rendering/snippet-renderer.js";
|
|
5
|
+
import { clearRendererCacheForProject } from "../../../../rendering/renderer.js";
|
|
6
|
+
import { invalidateProjectCSS } from "../../../../html/styles-builder/tailwind-compiler.js";
|
|
7
|
+
import { invalidatePreparedProjectCSS } from "../../../../html/styles-builder/prepared-project-css-cache.js";
|
|
8
|
+
import { invalidateProjectCandidateManifests } from "../../../../rendering/orchestrator/css-candidate-manifest.js";
|
|
9
|
+
export function createDefaultInvalidationCallbacks(callbacks) {
|
|
10
|
+
return {
|
|
11
|
+
clearSSRModuleCache,
|
|
12
|
+
clearModulePathCache,
|
|
13
|
+
invalidateModulePaths,
|
|
14
|
+
clearSSRModuleCacheForProject,
|
|
15
|
+
clearRouterDetectionCacheForProject,
|
|
16
|
+
clearSnippetCacheForProject,
|
|
17
|
+
clearRendererCacheForProject,
|
|
18
|
+
clearProjectCSSCache: (projectSlug) => {
|
|
19
|
+
invalidateProjectCSS(projectSlug);
|
|
20
|
+
invalidatePreparedProjectCSS(projectSlug);
|
|
21
|
+
invalidateProjectCandidateManifests(projectSlug);
|
|
22
|
+
},
|
|
23
|
+
...callbacks,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/proxy-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/proxy-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;AAetF,UAAU,2BAA2B;IACnC,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAkD;IACzE,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAC,CAAyC;gBAElD,MAAM,EAAE,2BAA2B;IAkBzC,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,EAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,kBAAkB,CAAC;IA+H9B,OAAO,CAAC,oBAAoB;IAuC5B,OAAO,CAAC,wBAAwB;IAyChC,OAAO,CAAC,aAAa;IAqGrB,OAAO,CAAC,sBAAsB;IAsB9B,OAAO,CAAC,mBAAmB;IAY3B,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,OAAO,EACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO;IAUV,QAAQ,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE;IAUnE,OAAO,IAAI,IAAI;CAchB"}
|
|
@@ -3,12 +3,8 @@ import { logger as baseLogger } from "../../../../utils/index.js";
|
|
|
3
3
|
import { CACHE_INVARIANT_VIOLATION, INVALID_ARGUMENT } from "../../../../errors/index.js";
|
|
4
4
|
import { buildProxyManagerCacheKey } from "../../../../cache/index.js";
|
|
5
5
|
import { VeryfrontFSAdapter } from "./index.js";
|
|
6
|
-
import { clearSSRModuleCache, clearSSRModuleCacheForProject, } from "../../../../modules/react-loader/ssr-module-loader/cache/index.js";
|
|
7
|
-
import { clearRouterDetectionCacheForProject } from "../../../../rendering/router-detection.js";
|
|
8
|
-
import { clearModulePathCache, invalidateModulePaths, } from "../../../../transforms/mdx/esm-module-loader/cache/index.js";
|
|
9
|
-
import { clearSnippetCacheForProject } from "../../../../rendering/snippet-renderer.js";
|
|
10
|
-
import { clearRendererCacheForProject } from "../../../../rendering/renderer.js";
|
|
11
6
|
import { GetAdapterParamsSchema } from "./schemas/index.js";
|
|
7
|
+
import { createDefaultInvalidationCallbacks } from "./default-invalidation-callbacks.js";
|
|
12
8
|
const logger = baseLogger.component("proxy-fs-adapter-manager");
|
|
13
9
|
const DEFAULT_MAX_ADAPTERS = 100;
|
|
14
10
|
const DEFAULT_MAX_IDLE_MS = 30 * 60 * 1_000;
|
|
@@ -193,16 +189,7 @@ export class ProxyFSAdapterManager {
|
|
|
193
189
|
projectId,
|
|
194
190
|
apiToken: effectiveToken,
|
|
195
191
|
},
|
|
196
|
-
invalidationCallbacks:
|
|
197
|
-
clearSSRModuleCache,
|
|
198
|
-
clearModulePathCache,
|
|
199
|
-
invalidateModulePaths,
|
|
200
|
-
clearSSRModuleCacheForProject,
|
|
201
|
-
clearRouterDetectionCacheForProject,
|
|
202
|
-
clearSnippetCacheForProject,
|
|
203
|
-
clearRendererCacheForProject,
|
|
204
|
-
...this.baseConfig.invalidationCallbacks,
|
|
205
|
-
},
|
|
192
|
+
invalidationCallbacks: createDefaultInvalidationCallbacks(this.baseConfig.invalidationCallbacks),
|
|
206
193
|
};
|
|
207
194
|
const adapter = new VeryfrontFSAdapter(config);
|
|
208
195
|
let context;
|
|
@@ -17,6 +17,10 @@ interface WebSocketDeps {
|
|
|
17
17
|
path: string;
|
|
18
18
|
content?: string;
|
|
19
19
|
}>) => Promise<void>;
|
|
20
|
+
pregenerateStyles?: (files: Array<{
|
|
21
|
+
path: string;
|
|
22
|
+
content?: string;
|
|
23
|
+
}>) => Promise<void>;
|
|
20
24
|
}
|
|
21
25
|
export declare class WebSocketManager {
|
|
22
26
|
private readonly deps;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/websocket-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAwB/F,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,qBAAqB,EAAE,qBAAqB,CAAC;IAE7C,iBAAiB,EAAE,MAAM,sBAAsB,GAAG,IAAI,CAAC;IACvD,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,aAAa,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACxC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"websocket-manager.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/websocket-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAwB/F,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,qBAAqB,EAAE,qBAAqB,CAAC;IAE7C,iBAAiB,EAAE,MAAM,sBAAsB,GAAG,IAAI,CAAC;IACvD,gBAAgB,EAAE,MAAM,aAAa,CAAC;IACtC,aAAa,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACxC,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzF;AAED,qBAAa,gBAAgB;IAqBf,OAAO,CAAC,QAAQ,CAAC,IAAI;IApBjC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,gBAAgB,CAAsD;IAC9E,OAAO,CAAC,gBAAgB,CAAuD;IAC/E,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,iBAAiB,CAAsD;IAC/E,OAAO,CAAC,0BAA0B,CAAsD;IACxF,OAAO,CAAC,mBAAmB,CAAqB;IAEhD,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,0BAA0B,CAAK;IACvC,OAAO,CAAC,iCAAiC,CAAqB;IAC9D,OAAO,CAAC,WAAW,CAIjB;gBAE2B,IAAI,EAAE,aAAa;IAEhD,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,8BAA8B;IAOtC,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,2BAA2B;IAUnC,cAAc,IAAI;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B;IAID,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IA+GhC,OAAO,CAAC,iBAAiB;IAMzB,OAAO,IAAI,IAAI;IA8Bf,OAAO,CAAC,iBAAiB;IAyJzB,OAAO,CAAC,8BAA8B;IA0GtC,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,6BAA6B;YAiBvB,4BAA4B;YAyI5B,mBAAmB;IA4IjC,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,WAAW;CAyBpB"}
|
|
@@ -481,6 +481,7 @@ export class WebSocketManager {
|
|
|
481
481
|
const cacheKey = buildFileListCacheKey(contentContext);
|
|
482
482
|
await this.deps.setFileListCache(cacheKey, files);
|
|
483
483
|
this.deps.clearFileListIndex();
|
|
484
|
+
await this.deps.pregenerateStyles?.(files);
|
|
484
485
|
logger.debug("Fresh files cached (memory + Redis)", {
|
|
485
486
|
cacheKey,
|
|
486
487
|
fileCount: files.length,
|
|
@@ -586,6 +587,7 @@ export class WebSocketManager {
|
|
|
586
587
|
const cacheKey = buildFileListCacheKey(contentContext);
|
|
587
588
|
await this.deps.setFileListCache(cacheKey, files);
|
|
588
589
|
this.deps.clearFileListIndex();
|
|
590
|
+
await this.deps.pregenerateStyles?.(files);
|
|
589
591
|
logger.debug("FRESH FILES FETCHED", {
|
|
590
592
|
cacheKey,
|
|
591
593
|
fileCount: files.length,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type StyleScopeProfile } from "../../html/styles-builder/style-scope-profile.js";
|
|
1
2
|
interface SourceFileLike {
|
|
2
3
|
path: string;
|
|
3
4
|
content?: string;
|
|
@@ -6,6 +7,7 @@ interface RouteCandidateOptions {
|
|
|
6
7
|
projectScope: string;
|
|
7
8
|
projectVersion: string;
|
|
8
9
|
projectDir: string;
|
|
10
|
+
styleProfile?: StyleScopeProfile;
|
|
9
11
|
routeKey: string;
|
|
10
12
|
routeFilePaths: string[];
|
|
11
13
|
files: SourceFileLike[];
|
|
@@ -15,6 +17,7 @@ interface ProjectCandidateOptions {
|
|
|
15
17
|
projectScope: string;
|
|
16
18
|
projectVersion: string;
|
|
17
19
|
projectDir: string;
|
|
20
|
+
styleProfile?: StyleScopeProfile;
|
|
18
21
|
files: SourceFileLike[];
|
|
19
22
|
developmentMode: boolean;
|
|
20
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-candidate-manifest.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/css-candidate-manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"css-candidate-manifest.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/css-candidate-manifest.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,kDAAkD,CAAC;AAI1D,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,UAAU,uBAAuB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAqHD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,qBAAqB,GAAG,GAAG,CAAC,MAAM,CAAC,CAuC9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,GAAG,CAAC,MAAM,CAAC,CAGlF;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAc/E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractCandidates } from "../../html/styles-builder/tailwind-compiler.js";
|
|
2
|
+
import { filterFilesForStyleScope, } from "../../html/styles-builder/style-scope-profile.js";
|
|
2
3
|
import { getRouteModulePaths } from "../../modules/manifest/route-module-manifest.js";
|
|
3
4
|
import { rendererLogger } from "../../utils/index.js";
|
|
4
5
|
const logger = rendererLogger.component("css-candidate-manifest");
|
|
@@ -17,8 +18,8 @@ function toRelativeProjectPath(path, projectDir) {
|
|
|
17
18
|
}
|
|
18
19
|
return normalized.replace(/^\/+/, "");
|
|
19
20
|
}
|
|
20
|
-
function buildManifestCacheKey(projectScope, projectVersion) {
|
|
21
|
-
return `${projectScope}:${projectVersion}`;
|
|
21
|
+
function buildManifestCacheKey(projectScope, projectVersion, styleProfileHash) {
|
|
22
|
+
return `${projectScope}:${projectVersion}:${styleProfileHash ?? "default"}`;
|
|
22
23
|
}
|
|
23
24
|
function shouldRebuildManifest(existing, developmentMode) {
|
|
24
25
|
if (!existing)
|
|
@@ -59,10 +60,13 @@ function buildCandidateManifest(files, projectDir) {
|
|
|
59
60
|
return { fileCandidates, allCandidates, builtAt: Date.now() };
|
|
60
61
|
}
|
|
61
62
|
function getOrBuildManifest(options) {
|
|
62
|
-
const manifestKey = buildManifestCacheKey(options.projectScope, options.projectVersion);
|
|
63
|
+
const manifestKey = buildManifestCacheKey(options.projectScope, options.projectVersion, options.styleProfile?.hash);
|
|
63
64
|
const existingManifest = manifestCache.get(manifestKey);
|
|
65
|
+
const scopedFiles = options.styleProfile
|
|
66
|
+
? filterFilesForStyleScope(options.files, options.styleProfile, options.projectDir)
|
|
67
|
+
: options.files;
|
|
64
68
|
const manifest = shouldRebuildManifest(existingManifest, options.developmentMode)
|
|
65
|
-
? buildCandidateManifest(
|
|
69
|
+
? buildCandidateManifest(scopedFiles, options.projectDir)
|
|
66
70
|
: existingManifest;
|
|
67
71
|
if (manifest !== existingManifest) {
|
|
68
72
|
manifestCache.set(manifestKey, manifest);
|
|
@@ -87,7 +91,7 @@ function addCandidatesForPath(target, manifest, path, projectDir) {
|
|
|
87
91
|
* Resolve route-scoped Tailwind candidates from a precomputed per-project manifest.
|
|
88
92
|
*/
|
|
89
93
|
export function getRouteCandidates(options) {
|
|
90
|
-
const manifestKey = buildManifestCacheKey(options.projectScope, options.projectVersion);
|
|
94
|
+
const manifestKey = buildManifestCacheKey(options.projectScope, options.projectVersion, options.styleProfile?.hash);
|
|
91
95
|
const manifest = getOrBuildManifest(options);
|
|
92
96
|
const routeCacheKey = `${manifestKey}:${options.routeKey}`;
|
|
93
97
|
const cachedRoute = routeCandidateCache.get(routeCacheKey);
|
|
@@ -111,6 +115,7 @@ export function getRouteCandidates(options) {
|
|
|
111
115
|
logger.debug("Resolved route candidates", {
|
|
112
116
|
projectScope: options.projectScope,
|
|
113
117
|
projectVersion: options.projectVersion,
|
|
118
|
+
styleProfileHash: options.styleProfile?.hash,
|
|
114
119
|
route: options.routeKey,
|
|
115
120
|
count: routeCandidates.size,
|
|
116
121
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EAET,UAAU,EACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../../src/src/rendering/orchestrator/html.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EAET,UAAU,EACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiBhD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,SAAS,GAAG,SAAS,CAAC;IACpC,aAAa,EAAE,UAAU,EAAE,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAIjC,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjE,kBAAkB,CACtB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAC3C,OAAO,CAAC,cAAc,CAAC;YAmCZ,sBAAsB;YAsBtB,wBAAwB;YAmBxB,gBAAgB;YAehB,kBAAkB;IAsDhC,OAAO,CAAC,iBAAiB;IA4DzB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,cAAc;YAQR,eAAe;YAaf,gBAAgB;IAwE9B;;;;OAIG;YACW,gBAAgB;IA2D9B,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,qBAAqB;YAOf,6BAA6B;CAyD5C"}
|
|
@@ -9,6 +9,8 @@ import { resolveAppComponentPath } from "../layouts/utils/app-resolver.js";
|
|
|
9
9
|
import { StreamTimeoutError, streamToString } from "../utils/stream-utils.js";
|
|
10
10
|
import { normalizeCssModuleKey, rewriteCssModuleContent, } from "../../transforms/css-modules/naming.js";
|
|
11
11
|
import { getRouteCandidates } from "./css-candidate-manifest.js";
|
|
12
|
+
import { resolveStyleContentVersion } from "../../html/styles-builder/content-version.js";
|
|
13
|
+
import { createStyleScopeProfile } from "../../html/styles-builder/style-scope-profile.js";
|
|
12
14
|
const logger = rendererLogger.component("html-generator");
|
|
13
15
|
export class HTMLGenerator {
|
|
14
16
|
config;
|
|
@@ -317,6 +319,11 @@ export class HTMLGenerator {
|
|
|
317
319
|
if (typeof wrappedFs.getUnderlyingAdapter !== "function")
|
|
318
320
|
return undefined;
|
|
319
321
|
const fsAdapter = wrappedFs.getUnderlyingAdapter();
|
|
322
|
+
const contentContext = typeof fsAdapter.getContentContext === "function"
|
|
323
|
+
? fsAdapter.getContentContext()
|
|
324
|
+
: null;
|
|
325
|
+
if (contentContext)
|
|
326
|
+
return resolveStyleContentVersion(contentContext);
|
|
320
327
|
return fsAdapter.getProjectData?.()?.updated_at;
|
|
321
328
|
}
|
|
322
329
|
buildRouteManifestKey(pagePath) {
|
|
@@ -351,6 +358,7 @@ export class HTMLGenerator {
|
|
|
351
358
|
projectScope,
|
|
352
359
|
projectVersion,
|
|
353
360
|
projectDir: this.config.projectDir,
|
|
361
|
+
styleProfile: createStyleScopeProfile(this.config.config),
|
|
354
362
|
routeKey,
|
|
355
363
|
routeFilePaths,
|
|
356
364
|
files,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles-candidate-scanner.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/dev/styles-candidate-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"styles-candidate-scanner.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/dev/styles-candidate-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAiBlD;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAgDxF"}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* @module server/handlers/dev/styles-candidate-scanner
|
|
9
9
|
*/
|
|
10
10
|
import { extractCandidates } from "../../../html/styles-builder/tailwind-compiler.js";
|
|
11
|
+
import { resolveStyleContentVersion } from "../../../html/styles-builder/content-version.js";
|
|
12
|
+
import { createStyleScopeProfile, shouldIncludeStylePath, shouldTraverseStyleDirectory, } from "../../../html/styles-builder/style-scope-profile.js";
|
|
11
13
|
import { serverLogger } from "../../../utils/index.js";
|
|
12
14
|
import { createFileSystem } from "../../../platform/compat/fs.js";
|
|
13
15
|
import { join } from "../../../platform/compat/path/index.js";
|
|
@@ -15,22 +17,8 @@ import { getProjectCandidates } from "../../../rendering/orchestrator/css-candid
|
|
|
15
17
|
import { FRAMEWORK_CANDIDATES } from "./framework-candidates.generated.js";
|
|
16
18
|
const logger = serverLogger.component("styles-candidate-scanner");
|
|
17
19
|
const SOURCE_EXTENSIONS = [".tsx", ".jsx", ".mdx", ".ts", ".js"];
|
|
18
|
-
const SKIP_DIRS = new Set(["node_modules", ".cache", ".git", "dist", "build", ".vscode"]);
|
|
19
20
|
/** De-duplicated set of framework candidates, computed once at import time. */
|
|
20
21
|
const frameworkCandidates = new Set(FRAMEWORK_CANDIDATES);
|
|
21
|
-
function resolveProjectVersion(ctx, contentContext) {
|
|
22
|
-
if (contentContext?.releaseId)
|
|
23
|
-
return `release:${contentContext.releaseId}`;
|
|
24
|
-
if (contentContext?.branch)
|
|
25
|
-
return `branch:${contentContext.branch}`;
|
|
26
|
-
if (contentContext?.environmentName)
|
|
27
|
-
return `environment:${contentContext.environmentName}`;
|
|
28
|
-
if (ctx.releaseId)
|
|
29
|
-
return `release:${ctx.releaseId}`;
|
|
30
|
-
if (ctx.parsedDomain?.branch)
|
|
31
|
-
return `branch:${ctx.parsedDomain.branch}`;
|
|
32
|
-
return "live";
|
|
33
|
-
}
|
|
34
22
|
/**
|
|
35
23
|
* Extract Tailwind CSS candidate class names from all project source files.
|
|
36
24
|
*
|
|
@@ -39,6 +27,7 @@ function resolveProjectVersion(ctx, contentContext) {
|
|
|
39
27
|
* method is available (local dev mode).
|
|
40
28
|
*/
|
|
41
29
|
export async function extractProjectCandidates(ctx) {
|
|
30
|
+
const styleProfile = createStyleScopeProfile(ctx.config);
|
|
42
31
|
const wrappedFs = ctx.adapter.fs;
|
|
43
32
|
if (typeof wrappedFs.getUnderlyingAdapter !== "function") {
|
|
44
33
|
logger.debug("[StylesCandidateScanner] No FS adapter wrapper, falling back to local file scanning");
|
|
@@ -57,8 +46,13 @@ export async function extractProjectCandidates(ctx) {
|
|
|
57
46
|
: null;
|
|
58
47
|
for (const cls of getProjectCandidates({
|
|
59
48
|
projectScope: ctx.projectSlug ?? contentContext?.projectSlug ?? ctx.projectDir,
|
|
60
|
-
projectVersion:
|
|
49
|
+
projectVersion: resolveStyleContentVersion(contentContext, {
|
|
50
|
+
releaseId: ctx.releaseId,
|
|
51
|
+
branch: ctx.parsedDomain?.branch,
|
|
52
|
+
environmentName: ctx.environmentName,
|
|
53
|
+
}),
|
|
61
54
|
projectDir: ctx.projectDir,
|
|
55
|
+
styleProfile,
|
|
62
56
|
files,
|
|
63
57
|
developmentMode: contentContext?.sourceType === "branch",
|
|
64
58
|
})) {
|
|
@@ -71,6 +65,7 @@ export async function extractProjectCandidates(ctx) {
|
|
|
71
65
|
* Used in local development mode where projects are read directly from disk.
|
|
72
66
|
*/
|
|
73
67
|
async function scanLocalFiles(projectDir, ctx) {
|
|
68
|
+
const styleProfile = createStyleScopeProfile(ctx.config);
|
|
74
69
|
const candidates = new Set(frameworkCandidates);
|
|
75
70
|
const fs = createFileSystem();
|
|
76
71
|
const scanDir = async (dir) => {
|
|
@@ -85,12 +80,15 @@ async function scanLocalFiles(projectDir, ctx) {
|
|
|
85
80
|
for await (const entry of entries) {
|
|
86
81
|
const fullPath = join(dir, entry.name);
|
|
87
82
|
if (entry.isDirectory) {
|
|
88
|
-
if (
|
|
83
|
+
if (shouldTraverseStyleDirectory(styleProfile, fullPath, projectDir)) {
|
|
89
84
|
await scanDir(fullPath);
|
|
85
|
+
}
|
|
90
86
|
continue;
|
|
91
87
|
}
|
|
92
88
|
if (!entry.isFile)
|
|
93
89
|
continue;
|
|
90
|
+
if (!shouldIncludeStylePath(styleProfile, fullPath, projectDir))
|
|
91
|
+
continue;
|
|
94
92
|
if (!SOURCE_EXTENSIONS.some((ext) => entry.name.endsWith(ext)))
|
|
95
93
|
continue;
|
|
96
94
|
try {
|
|
@@ -12,5 +12,7 @@ export declare class StylesCSSHandler extends BaseHandler {
|
|
|
12
12
|
handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult>;
|
|
13
13
|
private loadStylesheet;
|
|
14
14
|
private generateStylesheet;
|
|
15
|
+
private getContentContext;
|
|
16
|
+
private createPreparedCSSContext;
|
|
15
17
|
}
|
|
16
18
|
//# sourceMappingURL=styles-css.handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles-css.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/dev/styles-css.handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"styles-css.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/dev/styles-css.handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAoBnG,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,EAAE,eAAe,CAKvB;IAEI,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;YAqIjE,cAAc;IAkB5B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,wBAAwB;CAyBjC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { BaseHandler } from "../response/base.js";
|
|
2
2
|
import { HTTP_OK, PRIORITY_HIGH_DEV } from "../../../utils/constants/index.js";
|
|
3
3
|
import { joinPath } from "../../../utils/path-utils.js";
|
|
4
|
-
import { formatCSSError,
|
|
4
|
+
import { formatCSSError, getProjectCSS } from "../../../html/styles-builder/tailwind-compiler.js";
|
|
5
5
|
import { DEFAULT_STYLESHEET } from "../../../html/styles-builder/css-hash-cache.js";
|
|
6
|
+
import { resolveStyleContentVersion } from "../../../html/styles-builder/content-version.js";
|
|
7
|
+
import { createPreparedProjectCSSContext, storePreparedProjectCSS, tryGetPreparedProjectCSS, } from "../../../html/styles-builder/prepared-project-css-cache.js";
|
|
8
|
+
import { createStyleScopeProfile } from "../../../html/styles-builder/style-scope-profile.js";
|
|
6
9
|
import { serverLogger } from "../../../utils/index.js";
|
|
7
10
|
import { extractProjectCandidates } from "./styles-candidate-scanner.js";
|
|
8
11
|
const logger = serverLogger.component("styles-css-handler");
|
|
@@ -19,6 +22,9 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
19
22
|
try {
|
|
20
23
|
return await this.withProxyContext(ctx, async () => {
|
|
21
24
|
const responseBuilder = this.createResponseBuilder(ctx).withCache("no-cache");
|
|
25
|
+
const projectScope = ctx.projectSlug ?? ctx.projectDir;
|
|
26
|
+
const styleProfile = createStyleScopeProfile(ctx.config);
|
|
27
|
+
const contentContext = this.getContentContext(ctx);
|
|
22
28
|
let rawCss;
|
|
23
29
|
try {
|
|
24
30
|
rawCss = await this.loadStylesheet(ctx);
|
|
@@ -29,6 +35,19 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
29
35
|
});
|
|
30
36
|
rawCss = DEFAULT_STYLESHEET;
|
|
31
37
|
}
|
|
38
|
+
const preparedContext = this.createPreparedCSSContext(projectScope, rawCss, styleProfile.hash, contentContext, ctx);
|
|
39
|
+
if (preparedContext) {
|
|
40
|
+
const prepared = await tryGetPreparedProjectCSS(preparedContext);
|
|
41
|
+
if (prepared) {
|
|
42
|
+
logger.debug("Prepared CSS cache hit", {
|
|
43
|
+
projectScope,
|
|
44
|
+
projectVersion: preparedContext.projectVersion,
|
|
45
|
+
styleProfileHash: styleProfile.hash,
|
|
46
|
+
cssHash: prepared.hash,
|
|
47
|
+
});
|
|
48
|
+
return this.respond(responseBuilder.withContentType("text/css; charset=utf-8", prepared.css, HTTP_OK));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
32
51
|
let candidates;
|
|
33
52
|
try {
|
|
34
53
|
candidates = await extractProjectCandidates(ctx);
|
|
@@ -39,9 +58,12 @@ export class StylesCSSHandler extends BaseHandler {
|
|
|
39
58
|
});
|
|
40
59
|
candidates = new Set();
|
|
41
60
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
let result;
|
|
62
|
+
try {
|
|
63
|
+
result = await this.generateStylesheet(ctx, rawCss, candidates);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const formatted = formatCSSError(error instanceof Error ? error : String(error));
|
|
45
67
|
logger.error("Tailwind error", {
|
|
46
68
|
error: formatted.message,
|
|
47
69
|
suggestion: formatted.suggestion,
|
|
@@ -78,11 +100,18 @@ body::before {
|
|
|
78
100
|
});
|
|
79
101
|
}
|
|
80
102
|
logger.debug("CSS generated", {
|
|
103
|
+
projectScope,
|
|
81
104
|
candidates: candidates.size,
|
|
82
105
|
cssLength: result.css.length,
|
|
83
106
|
fromCache: "fromCache" in result ? result.fromCache : false,
|
|
84
107
|
cssHash: "hash" in result ? result.hash : undefined,
|
|
85
108
|
});
|
|
109
|
+
if (preparedContext && "hash" in result) {
|
|
110
|
+
await storePreparedProjectCSS(preparedContext, {
|
|
111
|
+
css: result.css,
|
|
112
|
+
hash: result.hash,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
86
115
|
return this.respond(responseBuilder.withContentType("text/css; charset=utf-8", result.css, HTTP_OK));
|
|
87
116
|
});
|
|
88
117
|
}
|
|
@@ -115,10 +144,28 @@ body::before {
|
|
|
115
144
|
}
|
|
116
145
|
}
|
|
117
146
|
generateStylesheet(ctx, rawCss, candidates) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
147
|
+
const projectScope = ctx.projectSlug ?? ctx.projectDir;
|
|
148
|
+
return getProjectCSS(projectScope, rawCss, candidates, {
|
|
149
|
+
minify: true,
|
|
150
|
+
environment: "preview",
|
|
151
|
+
buildMode: "production",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
getContentContext(ctx) {
|
|
155
|
+
const wrappedFs = ctx.adapter.fs;
|
|
156
|
+
if (typeof wrappedFs.getUnderlyingAdapter !== "function")
|
|
157
|
+
return null;
|
|
158
|
+
const fsAdapter = wrappedFs.getUnderlyingAdapter();
|
|
159
|
+
return typeof fsAdapter.getContentContext === "function" ? fsAdapter.getContentContext() : null;
|
|
160
|
+
}
|
|
161
|
+
createPreparedCSSContext(projectScope, rawCss, styleProfileHash, contentContext, ctx) {
|
|
162
|
+
if (!projectScope)
|
|
163
|
+
return undefined;
|
|
164
|
+
return createPreparedProjectCSSContext(projectScope, resolveStyleContentVersion(contentContext, {
|
|
165
|
+
releaseId: ctx.releaseId,
|
|
166
|
+
branch: ctx.parsedDomain?.branch,
|
|
167
|
+
environmentName: ctx.environmentName,
|
|
168
|
+
}), rawCss, styleProfileHash, {
|
|
122
169
|
minify: true,
|
|
123
170
|
environment: "preview",
|
|
124
171
|
buildMode: "production",
|
package/package.json
CHANGED
|
@@ -219,6 +219,23 @@ function slugify(value: string): string {
|
|
|
219
219
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "document";
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Strip the chat-upload prefix that Studio prepends to uploaded files.
|
|
224
|
+
*
|
|
225
|
+
* Studio stores uploads with a generated prefix like:
|
|
226
|
+
* chat-<uuid>-<timestamp>-<shortid>-<original-filename>
|
|
227
|
+
*
|
|
228
|
+
* This function removes the prefix so knowledge files use the clean
|
|
229
|
+
* original filename (e.g. "agents" instead of
|
|
230
|
+
* "chat-909d3dbc-5a9a-4156-97e4-bcceb5c2ec0d-1773942180291-fv1qg5-agents").
|
|
231
|
+
*/
|
|
232
|
+
const CHAT_UPLOAD_PREFIX_RE =
|
|
233
|
+
/^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;
|
|
234
|
+
|
|
235
|
+
export function stripChatUploadPrefix(name: string): string {
|
|
236
|
+
return name.replace(CHAT_UPLOAD_PREFIX_RE, "");
|
|
237
|
+
}
|
|
238
|
+
|
|
222
239
|
function defaultOutputRoot(): Promise<string> {
|
|
223
240
|
return dntShim.Deno.makeTempDir({ prefix: "veryfront-knowledge-" });
|
|
224
241
|
}
|
|
@@ -361,7 +378,7 @@ function buildSourceReference(source: KnowledgeSource): string {
|
|
|
361
378
|
: source.localPath;
|
|
362
379
|
}
|
|
363
380
|
|
|
364
|
-
function buildSuggestedSlug(source: KnowledgeSource, index: number): string {
|
|
381
|
+
export function buildSuggestedSlug(source: KnowledgeSource, index: number): string {
|
|
365
382
|
const normalized = normalize(
|
|
366
383
|
source.kind === "upload" ? source.uploadPath : source.localPath,
|
|
367
384
|
).replace(/\\/g, "/");
|
|
@@ -383,9 +400,20 @@ function buildSuggestedSlug(source: KnowledgeSource, index: number): string {
|
|
|
383
400
|
stripped = normalized.replace(/\.[^.]+$/, "");
|
|
384
401
|
}
|
|
385
402
|
|
|
403
|
+
// Strip Studio's chat-upload prefix from the filename portion so that
|
|
404
|
+
// knowledge files use the original clean filename.
|
|
405
|
+
const lastSlash = stripped.lastIndexOf("/");
|
|
406
|
+
if (lastSlash >= 0) {
|
|
407
|
+
const dir = stripped.slice(0, lastSlash + 1);
|
|
408
|
+
const file = stripChatUploadPrefix(stripped.slice(lastSlash + 1));
|
|
409
|
+
stripped = file ? `${dir}${file}` : stripped;
|
|
410
|
+
} else {
|
|
411
|
+
stripped = stripChatUploadPrefix(stripped) || stripped;
|
|
412
|
+
}
|
|
413
|
+
|
|
386
414
|
return slugify(stripped || basename(normalized, extname(normalized)) || `document-${index + 1}`);
|
|
387
415
|
}
|
|
388
|
-
function ensureUniqueSlugs(sources: KnowledgeSource[]): string[] {
|
|
416
|
+
export function ensureUniqueSlugs(sources: KnowledgeSource[]): string[] {
|
|
389
417
|
const counts = new Map<string, number>();
|
|
390
418
|
return sources.map((source, index) => {
|
|
391
419
|
const baseSlug = buildSuggestedSlug(source, index);
|