@master/css-vite 0.0.0-site.1793659883.g69c9aebcf628

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +348 -0
  2. package/dist/common.d.ts +14 -0
  3. package/dist/common.js +26 -0
  4. package/dist/core.d.ts +23 -0
  5. package/dist/core.js +165 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.js +1 -0
  8. package/dist/internal/src/emitted-globals-module.js +12 -0
  9. package/dist/internal/src/manifest-facade.js +68 -0
  10. package/dist/internal/src/manifest-loader.js +33 -0
  11. package/dist/internal/src/manifest-module.js +58 -0
  12. package/dist/internal/src/manifest-virtual-module.js +123 -0
  13. package/dist/internal/src/node.js +22 -0
  14. package/dist/internal/src/program-module.js +50 -0
  15. package/dist/internal/src/project.js +10 -0
  16. package/dist/internal/src/runtime-bootstrap.js +80 -0
  17. package/dist/internal/src/style-module.js +3 -0
  18. package/dist/modes/pre-render.d.ts +5 -0
  19. package/dist/modes/pre-render.js +6 -0
  20. package/dist/modes/progressive.d.ts +5 -0
  21. package/dist/modes/progressive.js +12 -0
  22. package/dist/modes/runtime.d.ts +5 -0
  23. package/dist/modes/runtime.js +17 -0
  24. package/dist/modes/static.d.ts +5 -0
  25. package/dist/modes/static.js +5 -0
  26. package/dist/options.d.ts +20 -0
  27. package/dist/options.js +23 -0
  28. package/dist/plugins/avoid-fouc.d.ts +5 -0
  29. package/dist/plugins/avoid-fouc.js +48 -0
  30. package/dist/plugins/build-stylesheet-recovery.d.ts +5 -0
  31. package/dist/plugins/build-stylesheet-recovery.js +26 -0
  32. package/dist/plugins/context.d.ts +5 -0
  33. package/dist/plugins/context.js +12 -0
  34. package/dist/plugins/dev-stylesheet.d.ts +4 -0
  35. package/dist/plugins/dev-stylesheet.js +63 -0
  36. package/dist/plugins/emitted-globals-virtual-module.d.ts +14 -0
  37. package/dist/plugins/emitted-globals-virtual-module.js +167 -0
  38. package/dist/plugins/inject-runtime.d.ts +5 -0
  39. package/dist/plugins/inject-runtime.js +51 -0
  40. package/dist/plugins/inline-stylesheet.d.ts +5 -0
  41. package/dist/plugins/inline-stylesheet.js +197 -0
  42. package/dist/plugins/local-styles.d.ts +5 -0
  43. package/dist/plugins/local-styles.js +214 -0
  44. package/dist/plugins/manifest-loader.d.ts +4 -0
  45. package/dist/plugins/manifest-loader.js +102 -0
  46. package/dist/plugins/manifest-virtual-module.d.ts +4 -0
  47. package/dist/plugins/manifest-virtual-module.js +70 -0
  48. package/dist/plugins/pre-render.d.ts +5 -0
  49. package/dist/plugins/pre-render.js +224 -0
  50. package/dist/plugins/program-preload.d.ts +5 -0
  51. package/dist/plugins/program-preload.js +37 -0
  52. package/dist/plugins/runtime-bootstrap.d.ts +3 -0
  53. package/dist/plugins/runtime-bootstrap.js +14 -0
  54. package/dist/plugins/runtime-preload.d.ts +4 -0
  55. package/dist/plugins/runtime-preload.js +38 -0
  56. package/dist/plugins/sass-source.d.ts +5 -0
  57. package/dist/plugins/sass-source.js +176 -0
  58. package/dist/plugins/scanner.d.ts +5 -0
  59. package/dist/plugins/scanner.js +24 -0
  60. package/dist/plugins/style-entry-build.d.ts +5 -0
  61. package/dist/plugins/style-entry-build.js +121 -0
  62. package/dist/plugins/style-entry-hmr.d.ts +6 -0
  63. package/dist/plugins/style-entry-hmr.js +78 -0
  64. package/dist/plugins/style-entry.d.ts +5 -0
  65. package/dist/plugins/style-entry.js +89 -0
  66. package/dist/plugins/stylesheet-recovery.d.ts +5 -0
  67. package/dist/plugins/stylesheet-recovery.js +70 -0
  68. package/dist/plugins/usage-graph.d.ts +5 -0
  69. package/dist/plugins/usage-graph.js +48 -0
  70. package/dist/preset/src/default-manifest.js +15913 -0
  71. package/dist/utils/build-import-resolver.d.ts +29 -0
  72. package/dist/utils/build-import-resolver.js +101 -0
  73. package/dist/utils/build-sass-source.d.ts +38 -0
  74. package/dist/utils/build-sass-source.js +225 -0
  75. package/dist/utils/build-stylesheet-delivery.d.ts +12 -0
  76. package/dist/utils/build-stylesheet-delivery.js +130 -0
  77. package/dist/utils/build-watch-recovery.d.ts +10 -0
  78. package/dist/utils/build-watch-recovery.js +119 -0
  79. package/dist/utils/coalesced-task.d.ts +3 -0
  80. package/dist/utils/coalesced-task.js +25 -0
  81. package/dist/utils/dev-module-refresh.d.ts +9 -0
  82. package/dist/utils/dev-module-refresh.js +17 -0
  83. package/dist/utils/dev-stylesheet-delivery.d.ts +21 -0
  84. package/dist/utils/dev-stylesheet-delivery.js +98 -0
  85. package/dist/utils/environment-closing.d.ts +3 -0
  86. package/dist/utils/environment-closing.js +28 -0
  87. package/dist/utils/extracted-css.d.ts +4 -0
  88. package/dist/utils/extracted-css.js +34 -0
  89. package/dist/utils/failed-dependency-reconciliation.d.ts +15 -0
  90. package/dist/utils/failed-dependency-reconciliation.js +150 -0
  91. package/dist/utils/failed-stylesheet-dependencies.d.ts +16 -0
  92. package/dist/utils/failed-stylesheet-dependencies.js +92 -0
  93. package/dist/utils/html.d.ts +8 -0
  94. package/dist/utils/html.js +36 -0
  95. package/dist/utils/inline-stylesheet.d.ts +37 -0
  96. package/dist/utils/inline-stylesheet.js +129 -0
  97. package/dist/utils/local-stylesheet.d.ts +10 -0
  98. package/dist/utils/local-stylesheet.js +25 -0
  99. package/dist/utils/manifest-recovery.d.ts +11 -0
  100. package/dist/utils/manifest-recovery.js +77 -0
  101. package/dist/utils/module-sources.d.ts +26 -0
  102. package/dist/utils/module-sources.js +131 -0
  103. package/dist/utils/path.d.ts +5 -0
  104. package/dist/utils/path.js +27 -0
  105. package/dist/utils/recovery-error.d.ts +3 -0
  106. package/dist/utils/recovery-error.js +17 -0
  107. package/dist/utils/register-style-source.d.ts +4 -0
  108. package/dist/utils/register-style-source.js +23 -0
  109. package/dist/utils/sass-diagnostics.d.ts +4 -0
  110. package/dist/utils/sass-diagnostics.js +109 -0
  111. package/dist/utils/sass-proxy-access.d.ts +4 -0
  112. package/dist/utils/sass-proxy-access.js +28 -0
  113. package/dist/utils/sass-source-markers.d.ts +8 -0
  114. package/dist/utils/sass-source-markers.js +50 -0
  115. package/dist/utils/scanner-context.d.ts +12 -0
  116. package/dist/utils/scanner-context.js +100 -0
  117. package/dist/utils/scoped-plugins.d.ts +4 -0
  118. package/dist/utils/scoped-plugins.js +81 -0
  119. package/dist/utils/write-file.d.ts +3 -0
  120. package/dist/utils/write-file.js +9 -0
  121. package/package.json +62 -0
@@ -0,0 +1,214 @@
1
+ import { defaultBuildManifest } from "../internal/src/project.js";
2
+ import { includesFile } from "../utils/path.js";
3
+ import { withStylesheetDependencies } from "../utils/failed-stylesheet-dependencies.js";
4
+ import { getPreparedSassSource, getPreparedSassSourceMap, getSassSourceFile, isRawStyleRequest } from "../utils/build-sass-source.js";
5
+ import { withSassDiagnostics } from "../utils/sass-diagnostics.js";
6
+ import { getBuildStylesheetDelivery } from "../utils/build-stylesheet-delivery.js";
7
+ import { getDevStylesheetDelivery, publishDevGlobalStylesheet, publishDevStylesheets } from "../utils/dev-stylesheet-delivery.js";
8
+ import { captureBuildStylesheetSource, clearBuildStylesheetSources, getBuildImportResolver } from "../utils/build-import-resolver.js";
9
+ import { inlineDelivery, isInlineStylesheet, registerLocalInlineStylesheet } from "../utils/inline-stylesheet.js";
10
+ import { clearLocalStylesheets, registerLocalStylesheet } from "../utils/local-stylesheet.js";
11
+ import { readFileSync } from "node:fs";
12
+ import { discoverManifestEntries, loadProjectManifest } from "@master/css-compiler/project";
13
+ import { collectStylesheetDependenciesSync, inspectCSSSync } from "@master/css-compiler/node";
14
+ import { resolveStylesheet, transformStylesheet } from "@master/css-compiler/stylesheet";
15
+ // src/plugins/local-styles.ts
16
+ function declaresManifestEntry(file) {
17
+ try {
18
+ return inspectCSSSync(readFileSync(file, "utf8")).hasMasterEntry;
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+ function LocalStylesPlugin(options, context) {
24
+ let projectManifest;
25
+ let projectManifestEntries = [];
26
+ let projectManifestDependencies = [];
27
+ let manifestGeneration = 0;
28
+ let loadingManifest;
29
+ const localStyleModules = /* @__PURE__ */ new Set();
30
+ const addServerAllow = (paths) => {
31
+ const allow = context.config?.server.fs.allow;
32
+ if (!allow) return;
33
+ for (const path of paths) if (!allow.includes(path)) allow.push(path);
34
+ };
35
+ const loadStyleContext = async (pluginContext) => {
36
+ if (projectManifest) {
37
+ for (const dependency of projectManifestDependencies) pluginContext.addWatchFile?.(dependency);
38
+ return projectManifest;
39
+ }
40
+ if (!loadingManifest) {
41
+ const generation = manifestGeneration;
42
+ const dependencies = /* @__PURE__ */ new Set();
43
+ const hosts = /* @__PURE__ */ new Set();
44
+ const observe = (file) => {
45
+ if (dependencies.has(file)) return;
46
+ dependencies.add(file);
47
+ for (const host of hosts) host.addWatchFile?.(file);
48
+ };
49
+ loadingManifest = {
50
+ generation,
51
+ dependencies,
52
+ hosts,
53
+ promise: (async () => {
54
+ const root = context.config?.root;
55
+ const entries = await discoverManifestEntries({ root });
56
+ if (generation === manifestGeneration) projectManifestEntries = [...entries];
57
+ try {
58
+ for (const entry of entries) for (const dependency of collectStylesheetDependenciesSync(entry, void 0, { projectDir: root })) observe(dependency);
59
+ const result = await loadProjectManifest({
60
+ root,
61
+ entries,
62
+ baseManifest: defaultBuildManifest,
63
+ onDependency: observe
64
+ });
65
+ for (const dependency of result.dependencies) observe(dependency);
66
+ if (generation === manifestGeneration) projectManifest = result;
67
+ return result;
68
+ } finally {
69
+ if (generation === manifestGeneration) {
70
+ projectManifestDependencies = [...dependencies];
71
+ addServerAllow(projectManifestDependencies);
72
+ }
73
+ }
74
+ })()
75
+ };
76
+ }
77
+ const operation = loadingManifest;
78
+ operation.hosts.add(pluginContext);
79
+ for (const dependency of operation.dependencies) pluginContext.addWatchFile?.(dependency);
80
+ try {
81
+ const result = await operation.promise;
82
+ if (operation.generation !== manifestGeneration) return loadStyleContext(pluginContext);
83
+ return result;
84
+ } finally {
85
+ for (const dependency of operation.dependencies) pluginContext.addWatchFile?.(dependency);
86
+ operation.hosts.delete(pluginContext);
87
+ if (loadingManifest === operation) loadingManifest = void 0;
88
+ }
89
+ };
90
+ return {
91
+ name: "master-css:local-styles",
92
+ enforce: "pre",
93
+ async buildStart() {
94
+ clearBuildStylesheetSources(context);
95
+ if (context.config?.command === "build") clearLocalStylesheets(context);
96
+ projectManifest = void 0;
97
+ manifestGeneration++;
98
+ loadingManifest = void 0;
99
+ projectManifestEntries = [];
100
+ projectManifestDependencies = [];
101
+ },
102
+ async transform(code, id) {
103
+ return withStylesheetDependencies(context, this, id, (onDependency) => withSassDiagnostics(context, async () => {
104
+ if (isRawStyleRequest(id)) return;
105
+ const dependencyHost = {
106
+ addWatchFile: onDependency,
107
+ resolve: this.resolve?.bind(this),
108
+ load: this.load?.bind(this)
109
+ };
110
+ const sourceMeta = captureBuildStylesheetSource(context, id, code);
111
+ if (id.startsWith("\0") && context.config?.command !== "build") return;
112
+ const resolution = await resolveStylesheet(id, code, {
113
+ projectDir: context.config?.root,
114
+ baseFile: getSassSourceFile(id),
115
+ preserveImports: true,
116
+ resolveImport: getBuildImportResolver(context, dependencyHost),
117
+ onDependency
118
+ }).catch((error) => {
119
+ onDependency(getSassSourceFile(id) ?? id.replace(/[?#].*$/, ""));
120
+ throw error;
121
+ });
122
+ const prepared = getPreparedSassSource(context, id);
123
+ const moduleGraph = prepared && (await prepared.prepared).moduleSources;
124
+ const nativeModuleGraph = resolution?.kind === "plain" && Boolean(moduleGraph && moduleGraph.size > 1);
125
+ if (resolution?.kind !== "local" && resolution?.kind !== "plain") return sourceMeta ? { meta: sourceMeta } : void 0;
126
+ const dependencies = new Set(resolution.dependencies);
127
+ for (const dependency of dependencies) onDependency(dependency);
128
+ const manifestResult = await loadStyleContext(dependencyHost);
129
+ localStyleModules.add(id);
130
+ if (!projectManifestEntries.length && resolution.kind === "plain" && !nativeModuleGraph) return sourceMeta ? { meta: sourceMeta } : void 0;
131
+ const scopedVueStyle = id.includes("?vue&") && /(?:^|[?&])scoped(?:=|&|$)/u.test(id);
132
+ const compileOptions = {
133
+ baseManifest: manifestResult.manifest,
134
+ projectDir: context.config?.root,
135
+ referenceFiles: projectManifestEntries,
136
+ transformNativeStylesheets: true,
137
+ baseFile: getSassSourceFile(id),
138
+ sourceMap: await getPreparedSassSourceMap(context, id),
139
+ onDependency,
140
+ generatedGlobals: scopedVueStyle ? "separate" : "inline"
141
+ };
142
+ const inline = context.config?.command === "build" && isInlineStylesheet(id);
143
+ const delivery = inline ? inlineDelivery(context) : getBuildStylesheetDelivery(context) ?? getDevStylesheetDelivery(context);
144
+ const result = await transformStylesheet(id, code, {
145
+ ...compileOptions,
146
+ preserveUnchangedNativeCSS: resolution.kind === "plain" && !nativeModuleGraph,
147
+ ...delivery ? { delivery: {
148
+ ...delivery,
149
+ baseFile: getSassSourceFile(id),
150
+ sourceMap: await getPreparedSassSourceMap(context, id),
151
+ resolveImport: getBuildImportResolver(context, dependencyHost),
152
+ onDependency
153
+ } } : {}
154
+ });
155
+ if (!result.transformed) return sourceMeta ? { meta: sourceMeta } : void 0;
156
+ localStyleModules.add(id);
157
+ for (const dependency of result.dependencies) {
158
+ if (dependencies.has(dependency)) continue;
159
+ onDependency(dependency);
160
+ }
161
+ let output = result.code;
162
+ if (inline) registerLocalInlineStylesheet(context, id, result);
163
+ else if (context.config?.command === "build") {
164
+ if (scopedVueStyle && !result.stylesheets?.length) {
165
+ if (result.globalStylesheet) {
166
+ const slot = registerLocalStylesheet(context, id, {
167
+ ...result,
168
+ code: result.globalStylesheet.css,
169
+ globalStylesheet: void 0
170
+ });
171
+ output = `${result.code}\n:global(${slot.slice(0, slot.indexOf("{"))})${slot.slice(slot.indexOf("{"))}`;
172
+ } else output = result.code;
173
+ } else output = registerLocalStylesheet(context, id, result);
174
+ } else if (context.config?.command === "serve") {
175
+ output = publishDevStylesheets(context, {
176
+ ...result,
177
+ css: result.code,
178
+ emittedGlobals: {
179
+ variables: {},
180
+ keyframes: {}
181
+ }
182
+ }, "#master-css-local-slot{--slot:0}");
183
+ if (result.globalStylesheet) output = publishDevGlobalStylesheet(context, result.globalStylesheet.css) + "\n" + output;
184
+ }
185
+ return {
186
+ code: output,
187
+ map: null,
188
+ ...sourceMeta ? { meta: sourceMeta } : {}
189
+ };
190
+ }));
191
+ },
192
+ async hotUpdate({ type, file, modules }) {
193
+ const entriesChanged = file.endsWith(".css") && (declaresManifestEntry(file) || projectManifestEntries.some((entry) => !declaresManifestEntry(entry))) && JSON.stringify(await discoverManifestEntries({ root: context.config?.root })) !== JSON.stringify(projectManifestEntries);
194
+ if (!includesFile(projectManifestDependencies, file) && !includesFile([...loadingManifest?.dependencies ?? []], file) && !entriesChanged) return;
195
+ projectManifest = void 0;
196
+ manifestGeneration++;
197
+ loadingManifest = void 0;
198
+ const affected = new Set(modules);
199
+ for (const moduleId of localStyleModules) {
200
+ const module = this.environment.moduleGraph.getModuleById(moduleId);
201
+ if (!module) continue;
202
+ this.environment.moduleGraph.invalidateModule(module);
203
+ affected.add(module);
204
+ }
205
+ const hasSvelteStyle = [...affected].some((module) => /\.svelte\?svelte&type=style(?:&|$)/u.test(module.id ?? ""));
206
+ if (type === "delete" && entriesChanged && hasSvelteStyle) {
207
+ if (this.environment.name === "client") this.environment.hot.send({ type: "full-reload" });
208
+ return [];
209
+ }
210
+ return [...affected];
211
+ }
212
+ };
213
+ }
214
+ export { LocalStylesPlugin as default };
@@ -0,0 +1,4 @@
1
+ import { Plugin } from "vite";
2
+ import { MasterCSSVitePluginContext } from "../core.js";
3
+ declare function ManifestLoaderPlugin(context: MasterCSSVitePluginContext): Plugin;
4
+ export { ManifestLoaderPlugin as default };
@@ -0,0 +1,102 @@
1
+ import { MANIFEST_ASSET_FILE, toBrowserManifestFacadeModule, toInlineManifestModule, toServerManifestFileURL, toUniversalManifestFacadeModule } from "../internal/src/manifest-facade.js";
2
+ import { isMasterCSSManifestRequest, stripMasterCSSManifestQuery, toProductionManifestJSON } from "../internal/src/manifest-module.js";
3
+ import { isMasterCSSProgramRequest, stripMasterCSSProgramQuery } from "../internal/src/program-module.js";
4
+ import { fromResolvedMasterCSSManifestId, fromResolvedMasterCSSProgramId, toResolvedMasterCSSManifestId, toResolvedMasterCSSProgramId } from "../internal/src/node.js";
5
+ import { createMasterCSSProgramModule } from "../internal/src/manifest-virtual-module.js";
6
+ import { defaultBuildManifest, isManifestStylesheetRequest } from "../internal/src/project.js";
7
+ import { includesFile } from "../utils/path.js";
8
+ import { serializeMasterCSSManifest } from "@master/css-schema/manifest";
9
+ import { compileRuntimeProgram } from "@master/css/node";
10
+ import { compileProjectManifest } from "@master/css-compiler/project";
11
+ import { collectStylesheetDependenciesSync } from "@master/css-compiler/node";
12
+ // src/plugins/manifest-loader.ts
13
+ function invalidateManifestModule(module, server) {
14
+ if (!module) return [];
15
+ server.moduleGraph.invalidateModule(module);
16
+ return [module];
17
+ }
18
+ function isProductionBuild(context) {
19
+ return context.config?.command === "build";
20
+ }
21
+ function isServerBuild(context, pluginContext) {
22
+ if (pluginContext.environment) return pluginContext.environment.config.consumer === "server";
23
+ return Boolean(context.config?.build.ssr);
24
+ }
25
+ function createManifestModule(context, pluginContext, manifest, serverReferences) {
26
+ if (!isProductionBuild(context)) return toInlineManifestModule(serializeMasterCSSManifest(manifest));
27
+ const json = toProductionManifestJSON(manifest);
28
+ if (!pluginContext.emitFile) return toInlineManifestModule(json);
29
+ const referenceId = pluginContext.emitFile({
30
+ type: "asset",
31
+ name: MANIFEST_ASSET_FILE,
32
+ source: json
33
+ });
34
+ const urlExpression = `import.meta.ROLLUP_FILE_URL_${referenceId}`;
35
+ const server = isServerBuild(context, pluginContext);
36
+ if (server) serverReferences.add(referenceId);
37
+ return server ? toUniversalManifestFacadeModule(urlExpression) : toBrowserManifestFacadeModule(urlExpression);
38
+ }
39
+ function ManifestLoaderPlugin(context) {
40
+ const cssManifestDependencies = /* @__PURE__ */ new Map();
41
+ const serverManifestReferences = /* @__PURE__ */ new Set();
42
+ const addServerAllow = (paths) => {
43
+ const allow = context.config?.server.fs.allow;
44
+ if (!allow) return;
45
+ for (const path of paths) if (!allow.includes(path)) allow.push(path);
46
+ };
47
+ const watchManifestDependencies = (manifestPath, dependencies = []) => {
48
+ cssManifestDependencies.set(manifestPath, dependencies);
49
+ addServerAllow(dependencies);
50
+ };
51
+ return {
52
+ name: "master-css:manifest-loader",
53
+ enforce: "pre",
54
+ async resolveId(id, importer) {
55
+ const program = isMasterCSSProgramRequest(id);
56
+ if (!program && !isMasterCSSManifestRequest(id)) return;
57
+ const sourceId = program ? stripMasterCSSProgramQuery(id) : stripMasterCSSManifestQuery(id);
58
+ const resolved = await this.resolve(sourceId, importer, { skipSelf: true });
59
+ if (!resolved) return;
60
+ return program ? toResolvedMasterCSSProgramId(resolved.id) : toResolvedMasterCSSManifestId(resolved.id);
61
+ },
62
+ async load(id) {
63
+ const programPath = fromResolvedMasterCSSProgramId(id);
64
+ const manifestPath = programPath ?? fromResolvedMasterCSSManifestId(id);
65
+ if (!manifestPath) return;
66
+ if (!isManifestStylesheetRequest(manifestPath)) throw new TypeError(`Master CSS ${programPath ? "program" : "manifest"} queries only support CSS entry files.`);
67
+ const dependencies = new Set(collectStylesheetDependenciesSync(manifestPath, void 0, { projectDir: context.config?.root }));
68
+ for (const dependency of dependencies) this.addWatchFile(dependency);
69
+ watchManifestDependencies(manifestPath, [...dependencies]);
70
+ const result = await compileProjectManifest({
71
+ root: context.config?.root,
72
+ entries: [manifestPath],
73
+ baseManifest: defaultBuildManifest
74
+ });
75
+ for (const dependency of result.dependencies) {
76
+ if (dependencies.has(dependency)) continue;
77
+ dependencies.add(dependency);
78
+ this.addWatchFile(dependency);
79
+ }
80
+ watchManifestDependencies(manifestPath, [...dependencies]);
81
+ if (programPath) return (await createMasterCSSProgramModule(context, this, result.manifest, compileRuntimeProgram)).code;
82
+ return createManifestModule(context, this, result.manifest, serverManifestReferences);
83
+ },
84
+ resolveFileUrl({ referenceId, relativePath, format }) {
85
+ if (serverManifestReferences.has(referenceId)) return toServerManifestFileURL(relativePath, format);
86
+ },
87
+ async handleHotUpdate({ file, server }) {
88
+ let handled = false;
89
+ const modules = [];
90
+ const queryManifestPaths = /* @__PURE__ */ new Set([file]);
91
+ for (const [manifestPath, dependencies] of cssManifestDependencies) if (includesFile(dependencies, file)) queryManifestPaths.add(manifestPath);
92
+ for (const manifestPath of queryManifestPaths) for (const queryId of [toResolvedMasterCSSManifestId(manifestPath), toResolvedMasterCSSProgramId(manifestPath)]) {
93
+ const queryModule = server.moduleGraph.getModuleById(queryId);
94
+ if (!queryModule) continue;
95
+ handled = true;
96
+ modules.push(...invalidateManifestModule(queryModule, server));
97
+ }
98
+ if (handled) return modules;
99
+ }
100
+ };
101
+ }
102
+ export { ManifestLoaderPlugin as default };
@@ -0,0 +1,4 @@
1
+ import { Plugin } from "vite";
2
+ import { MasterCSSVitePluginContext } from "../core.js";
3
+ declare function ManifestVirtualModulePlugin(context: MasterCSSVitePluginContext): Plugin;
4
+ export { ManifestVirtualModulePlugin as default };
@@ -0,0 +1,70 @@
1
+ import { RESOLVED_VIRTUAL_MANIFEST_ID, RESOLVED_VIRTUAL_PROGRAM_ID } from "../common.js";
2
+ import { createMasterCSSManifestVirtualModulePlugin } from "../internal/src/manifest-virtual-module.js";
3
+ import { loadMasterCSSVirtualManifest } from "../internal/src/manifest-loader.js";
4
+ import { createManifestRecovery } from "../utils/manifest-recovery.js";
5
+ import { compileRuntimeProgram } from "@master/css/node";
6
+ import { discoverManifestEntries, loadProjectManifest } from "@master/css-compiler/project";
7
+ import { collectStylesheetDependenciesSync } from "@master/css-compiler/node";
8
+ import { normalizePath } from "vite";
9
+ // src/plugins/manifest-virtual-module.ts
10
+ const manifestHost = {
11
+ discoverManifestEntries,
12
+ loadProjectManifest,
13
+ collectStylesheetDependencies(entry, options) {
14
+ return collectStylesheetDependenciesSync(entry, void 0, { projectDir: options.root });
15
+ }
16
+ };
17
+ function ManifestVirtualModulePlugin(context) {
18
+ const plugin = createMasterCSSManifestVirtualModulePlugin(async (options) => {
19
+ const result = await loadMasterCSSVirtualManifest({
20
+ ...options,
21
+ onDependency: (file) => options.onDependency(normalizePath(file)),
22
+ host: manifestHost
23
+ });
24
+ return {
25
+ ...result,
26
+ dependencies: result.dependencies.map(normalizePath)
27
+ };
28
+ }, context, (manifest) => compileRuntimeProgram(manifest));
29
+ const createRecovery = (id) => createManifestRecovery(context, id, (onDependency, host) => plugin.load.call({
30
+ environment: host.environment,
31
+ addWatchFile: onDependency,
32
+ emitFile: host.emitFile?.bind(host)
33
+ }, id));
34
+ const recovery = createRecovery(RESOLVED_VIRTUAL_MANIFEST_ID);
35
+ const programRecovery = createRecovery(RESOLVED_VIRTUAL_PROGRAM_ID);
36
+ return {
37
+ ...plugin,
38
+ async buildStart() {
39
+ if (programRecovery.failed) try {
40
+ await programRecovery.run(this);
41
+ } catch {}
42
+ if (context.config?.command === "build" && !recovery.failed) return;
43
+ try {
44
+ await recovery.run(this);
45
+ } catch {}
46
+ },
47
+ async load(id) {
48
+ if (id === RESOLVED_VIRTUAL_MANIFEST_ID) return recovery.run(this);
49
+ if (id === RESOLVED_VIRTUAL_PROGRAM_ID) return programRecovery.run(this);
50
+ },
51
+ transformIndexHtml: {
52
+ order: "pre",
53
+ handler() {
54
+ recovery.assertReady();
55
+ programRecovery.assertReady();
56
+ }
57
+ },
58
+ closeBundle() {
59
+ if (context.config?.build?.watch || !this.environment) return;
60
+ recovery.close(this.environment);
61
+ programRecovery.close(this.environment);
62
+ },
63
+ closeWatcher() {
64
+ if (!this.environment) return;
65
+ recovery.close(this.environment);
66
+ programRecovery.close(this.environment);
67
+ }
68
+ };
69
+ }
70
+ export { ManifestVirtualModulePlugin as default };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "vite";
2
+ import { ResolvedMasterCSSVitePluginOptions } from "../options.js";
3
+ import { MasterCSSVitePluginContext } from "../core.js";
4
+ declare function PreRenderPlugin(options: ResolvedMasterCSSVitePluginOptions, context: MasterCSSVitePluginContext): Plugin;
5
+ export { PreRenderPlugin as default };
@@ -0,0 +1,224 @@
1
+ import { toHashedManifestAssetFileName } from "../internal/src/node.js";
2
+ import { defaultBuildManifest } from "../internal/src/project.js";
3
+ import { includesFile } from "../utils/path.js";
4
+ import { createManifestRecovery } from "../utils/manifest-recovery.js";
5
+ import { toAssetHref } from "../utils/html.js";
6
+ import { relative } from "node:path";
7
+ import { discoverManifestEntries, loadProjectManifest } from "@master/css-compiler/project";
8
+ import { collectStylesheetEmittedGlobals, describeLinkedStylesheet } from "@master/css-compiler/stylesheet";
9
+ import { createServerRenderer } from "@master/css-server";
10
+ import { MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE, MASTER_CSS_HYDRATION_MANIFEST_FILE_BASENAME } from "@master/css-schema/hydration-manifest";
11
+ // src/plugins/pre-render.ts
12
+ const HYDRATION_MANIFEST_ASSET_DIR = "_master-css/hydration";
13
+ function PreRenderPlugin(options, context) {
14
+ let cssManifest = void 0;
15
+ let cssManifestDependencies = [];
16
+ let manifestSignature;
17
+ let enabled = true;
18
+ let renderer;
19
+ let devServer;
20
+ const hydrationManifestAssets = /* @__PURE__ */ new Map();
21
+ const addServerAllow = (paths) => {
22
+ const allow = context.config?.server.fs.allow;
23
+ if (!allow) return;
24
+ for (const path of paths) if (!allow.includes(path)) allow.push(path);
25
+ };
26
+ const recovery = createManifestRecovery(context, "\0master-css:pre-render-manifest", async (onDependency, _host, active) => {
27
+ try {
28
+ const root = context.config?.root;
29
+ const entries = await discoverManifestEntries({ root });
30
+ const dependencies = /* @__PURE__ */ new Set();
31
+ const addDependency = (file) => {
32
+ if (dependencies.has(file)) return;
33
+ dependencies.add(file);
34
+ if (active()) {
35
+ cssManifestDependencies = [...dependencies];
36
+ addServerAllow([file]);
37
+ }
38
+ onDependency(file);
39
+ };
40
+ const result = await loadProjectManifest({
41
+ root,
42
+ entries,
43
+ baseManifest: defaultBuildManifest,
44
+ onDependency: addDependency
45
+ });
46
+ const emittedGlobalsResult = await collectStylesheetEmittedGlobals([...entries], {
47
+ baseManifest: result.manifest,
48
+ projectDir: root
49
+ });
50
+ const nextSignature = JSON.stringify([result.manifest, emittedGlobalsResult.emittedGlobals]);
51
+ const changed = manifestSignature !== void 0 && manifestSignature !== nextSignature;
52
+ const nextRenderer = createServerRenderer({
53
+ manifest: result.manifest,
54
+ emittedGlobals: emittedGlobalsResult.emittedGlobals,
55
+ maxCachedClasses: context.config?.command === "build" ? Infinity : void 0
56
+ });
57
+ if (active()) {
58
+ manifestSignature = nextSignature;
59
+ cssManifest = result.manifest;
60
+ renderer?.dispose();
61
+ renderer = nextRenderer;
62
+ } else nextRenderer.dispose();
63
+ for (const dependency of result.dependencies) {
64
+ if (dependencies.has(dependency)) continue;
65
+ dependencies.add(dependency);
66
+ onDependency(dependency);
67
+ }
68
+ for (const dependency of emittedGlobalsResult.dependencies) {
69
+ if (dependencies.has(dependency)) continue;
70
+ dependencies.add(dependency);
71
+ onDependency(dependency);
72
+ }
73
+ if (active()) {
74
+ cssManifestDependencies = [...dependencies];
75
+ addServerAllow(cssManifestDependencies);
76
+ }
77
+ return changed;
78
+ } catch (error) {
79
+ if (active()) {
80
+ renderer?.dispose();
81
+ renderer = void 0;
82
+ cssManifest = void 0;
83
+ }
84
+ throw error;
85
+ }
86
+ });
87
+ const loadCSSManifest = (host = { environment: devServer?.environments.client }) => recovery.run(host);
88
+ const toBuildHydrationManifestAssetFileName = (fileName) => {
89
+ return [
90
+ (context.config?.build.assetsDir ?? "assets").replace(/\/$/, ""),
91
+ HYDRATION_MANIFEST_ASSET_DIR,
92
+ fileName
93
+ ].filter(Boolean).join("/");
94
+ };
95
+ const addHydrationManifestAsset = (json, htmlPath) => {
96
+ const fileName = toHashedManifestAssetFileName(json, MASTER_CSS_HYDRATION_MANIFEST_FILE_BASENAME);
97
+ hydrationManifestAssets.set(fileName, json);
98
+ return context.config?.command === "build" ? toAssetHref(toBuildHydrationManifestAssetFileName(fileName), context.config?.base, htmlPath) : `${MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE}${fileName}`;
99
+ };
100
+ const renderHTML = (html, htmlPath, stylesheets) => renderer?.renderHTML(html, {
101
+ stylesheets,
102
+ documentURL: new URL(htmlPath || "/", "https://master-css-render.invalid/").href,
103
+ hydrationManifest: options.mode === "progressive" ? {
104
+ type: "external",
105
+ source: (json) => addHydrationManifestAsset(json, htmlPath)
106
+ } : false
107
+ });
108
+ return {
109
+ name: "master-css:pre-render",
110
+ enforce: "pre",
111
+ async configResolved(config) {
112
+ if (config.plugins.some((p) => p.name?.startsWith("vite-plugin-svelte"))) {
113
+ enabled = false;
114
+ if (process.env.DEBUG) console.log("[@master/css-vite] SvelteKit detected, skipping pre-render plugin");
115
+ return;
116
+ }
117
+ if (config.command === "build" && config.build?.watch) return;
118
+ try {
119
+ await loadCSSManifest();
120
+ } catch (error) {
121
+ if (config.command !== "serve") throw error;
122
+ }
123
+ },
124
+ async buildStart() {
125
+ if (!enabled) return;
126
+ try {
127
+ await loadCSSManifest(this);
128
+ } catch (error) {
129
+ if (context.config?.command !== "serve") throw error;
130
+ }
131
+ },
132
+ async handleHotUpdate({ file, server }) {
133
+ if (!enabled || !includesFile(cssManifestDependencies, file)) return;
134
+ const environment = devServer?.environments.client;
135
+ const wasFailed = recovery.failed;
136
+ try {
137
+ const changed = await loadCSSManifest({ environment });
138
+ if (!recovery.isActive(environment)) return;
139
+ if (wasFailed || changed && options.mode === "pre-render") server.ws.send({ type: "full-reload" });
140
+ } catch (error) {
141
+ if (recovery.isActive(environment)) throw error;
142
+ }
143
+ },
144
+ configureServer(server) {
145
+ devServer = server;
146
+ server.httpServer?.once("close", () => renderer?.dispose());
147
+ server.middlewares.use((request, response, next) => {
148
+ const requestURL = request.url ? new URL(request.url, "http://localhost") : void 0;
149
+ if (!requestURL?.pathname.startsWith(MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE)) {
150
+ next();
151
+ return;
152
+ }
153
+ const fileName = decodeURIComponent(requestURL.pathname.slice(MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE.length));
154
+ const source = hydrationManifestAssets.get(fileName);
155
+ if (source === void 0) {
156
+ next();
157
+ return;
158
+ }
159
+ response.statusCode = 200;
160
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
161
+ response.end(source);
162
+ });
163
+ },
164
+ transformIndexHtml(html, htmlContext) {
165
+ if (!enabled) return;
166
+ recovery.assertReady();
167
+ if (!cssManifest || !renderer) return;
168
+ const rendered = renderHTML(html, htmlContext?.path);
169
+ if (!rendered) return;
170
+ return {
171
+ html: rendered.html,
172
+ tags: []
173
+ };
174
+ },
175
+ transform(code, id) {
176
+ if (!enabled) return;
177
+ if (id.endsWith(".html")) {
178
+ recovery.assertReady();
179
+ if (!cssManifest || !renderer) return null;
180
+ const htmlPath = context.config?.root ? relative(context.config.root, id).replace(/\\/g, "/") : void 0;
181
+ const rendered = renderHTML(code, htmlPath);
182
+ if (!rendered) return null;
183
+ return {
184
+ code: rendered.html,
185
+ map: null
186
+ };
187
+ }
188
+ return null;
189
+ },
190
+ generateBundle(_options, bundle) {
191
+ if (!enabled) return;
192
+ const cssAssets = Object.values(bundle).filter((asset) => asset.type === "asset" && asset.fileName.endsWith(".css"));
193
+ for (const output of Object.values(bundle)) {
194
+ if (output.type !== "asset" || !output.fileName.endsWith(".html")) continue;
195
+ const urls = cssAssets.map((asset) => toAssetHref(asset.fileName, context.config?.base, output.fileName));
196
+ const stylesheets = cssAssets.flatMap((asset, index) => {
197
+ if (asset.type !== "asset") return [];
198
+ const source = typeof asset.source === "string" ? asset.source : new TextDecoder().decode(asset.source);
199
+ return [describeLinkedStylesheet(source, urls[index], urls)];
200
+ });
201
+ const source = typeof output.source === "string" ? output.source : new TextDecoder().decode(output.source);
202
+ const rendered = renderHTML(source, output.fileName, stylesheets);
203
+ if (rendered) output.source = rendered.html;
204
+ }
205
+ for (const [fileName, source] of hydrationManifestAssets) this.emitFile({
206
+ type: "asset",
207
+ fileName: toBuildHydrationManifestAssetFileName(fileName),
208
+ source
209
+ });
210
+ },
211
+ buildEnd(error) {
212
+ if (error && context.config?.command === "build") renderer?.dispose();
213
+ },
214
+ closeBundle() {
215
+ if (!context.config?.build?.watch && this.environment) recovery.close(this.environment);
216
+ if (context.config?.command === "build") renderer?.dispose();
217
+ },
218
+ closeWatcher() {
219
+ if (this.environment) recovery.close(this.environment);
220
+ renderer?.dispose();
221
+ }
222
+ };
223
+ }
224
+ export { PreRenderPlugin as default };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from "vite";
2
+ import { MasterCSSVitePluginContext } from "../core.js";
3
+ /** Runtime-mode pages start fetching the runtime program with the HTML. */
4
+ declare function ProgramPreloadPlugin(context: MasterCSSVitePluginContext): Plugin;
5
+ export { ProgramPreloadPlugin as default };
@@ -0,0 +1,37 @@
1
+ import { toProgramPreloadLinkAttrs } from "../internal/src/program-module.js";
2
+ import { hasFetchPreloadLink, toAssetHref } from "../utils/html.js";
3
+ // src/plugins/program-preload.ts
4
+ function sameBytes(left, right) {
5
+ return left instanceof Uint8Array && left.length === right.length && left.every((byte, index) => byte === right[index]);
6
+ }
7
+ function findDefaultProgramAssetFileName(context, bundle) {
8
+ const source = context.defaultProgramAssetSource;
9
+ if (!source) return;
10
+ for (const output of Object.values(bundle)) if (output.type === "asset" && (output.name === "master-css-program.bin" || output.names?.includes("master-css-program.bin")) && sameBytes(output.source, source)) return output.fileName;
11
+ }
12
+ /** Runtime-mode pages start fetching the runtime program with the HTML. */
13
+ function ProgramPreloadPlugin(context) {
14
+ return {
15
+ name: "master-css:program-preload",
16
+ apply: "build",
17
+ transformIndexHtml: {
18
+ order: "post",
19
+ handler(html, htmlContext) {
20
+ if (!context.defaultProgramAssetReferenceId || !htmlContext.bundle) return;
21
+ const fileName = findDefaultProgramAssetFileName(context, htmlContext.bundle);
22
+ if (!fileName) return;
23
+ const href = toAssetHref(fileName, context.config?.base, htmlContext.path);
24
+ if (hasFetchPreloadLink(html, href)) return;
25
+ return {
26
+ html,
27
+ tags: [{
28
+ tag: "link",
29
+ attrs: { ...toProgramPreloadLinkAttrs(href) },
30
+ injectTo: "head-prepend"
31
+ }]
32
+ };
33
+ }
34
+ }
35
+ };
36
+ }
37
+ export { ProgramPreloadPlugin as default };
@@ -0,0 +1,3 @@
1
+ import { Plugin } from "vite";
2
+ declare function RuntimeBootstrapPlugin(progressive: boolean): Plugin;
3
+ export { RuntimeBootstrapPlugin as default };