@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.
- package/README.md +348 -0
- package/dist/common.d.ts +14 -0
- package/dist/common.js +26 -0
- package/dist/core.d.ts +23 -0
- package/dist/core.js +165 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/internal/src/emitted-globals-module.js +12 -0
- package/dist/internal/src/manifest-facade.js +68 -0
- package/dist/internal/src/manifest-loader.js +33 -0
- package/dist/internal/src/manifest-module.js +58 -0
- package/dist/internal/src/manifest-virtual-module.js +123 -0
- package/dist/internal/src/node.js +22 -0
- package/dist/internal/src/program-module.js +50 -0
- package/dist/internal/src/project.js +10 -0
- package/dist/internal/src/runtime-bootstrap.js +80 -0
- package/dist/internal/src/style-module.js +3 -0
- package/dist/modes/pre-render.d.ts +5 -0
- package/dist/modes/pre-render.js +6 -0
- package/dist/modes/progressive.d.ts +5 -0
- package/dist/modes/progressive.js +12 -0
- package/dist/modes/runtime.d.ts +5 -0
- package/dist/modes/runtime.js +17 -0
- package/dist/modes/static.d.ts +5 -0
- package/dist/modes/static.js +5 -0
- package/dist/options.d.ts +20 -0
- package/dist/options.js +23 -0
- package/dist/plugins/avoid-fouc.d.ts +5 -0
- package/dist/plugins/avoid-fouc.js +48 -0
- package/dist/plugins/build-stylesheet-recovery.d.ts +5 -0
- package/dist/plugins/build-stylesheet-recovery.js +26 -0
- package/dist/plugins/context.d.ts +5 -0
- package/dist/plugins/context.js +12 -0
- package/dist/plugins/dev-stylesheet.d.ts +4 -0
- package/dist/plugins/dev-stylesheet.js +63 -0
- package/dist/plugins/emitted-globals-virtual-module.d.ts +14 -0
- package/dist/plugins/emitted-globals-virtual-module.js +167 -0
- package/dist/plugins/inject-runtime.d.ts +5 -0
- package/dist/plugins/inject-runtime.js +51 -0
- package/dist/plugins/inline-stylesheet.d.ts +5 -0
- package/dist/plugins/inline-stylesheet.js +197 -0
- package/dist/plugins/local-styles.d.ts +5 -0
- package/dist/plugins/local-styles.js +214 -0
- package/dist/plugins/manifest-loader.d.ts +4 -0
- package/dist/plugins/manifest-loader.js +102 -0
- package/dist/plugins/manifest-virtual-module.d.ts +4 -0
- package/dist/plugins/manifest-virtual-module.js +70 -0
- package/dist/plugins/pre-render.d.ts +5 -0
- package/dist/plugins/pre-render.js +224 -0
- package/dist/plugins/program-preload.d.ts +5 -0
- package/dist/plugins/program-preload.js +37 -0
- package/dist/plugins/runtime-bootstrap.d.ts +3 -0
- package/dist/plugins/runtime-bootstrap.js +14 -0
- package/dist/plugins/runtime-preload.d.ts +4 -0
- package/dist/plugins/runtime-preload.js +38 -0
- package/dist/plugins/sass-source.d.ts +5 -0
- package/dist/plugins/sass-source.js +176 -0
- package/dist/plugins/scanner.d.ts +5 -0
- package/dist/plugins/scanner.js +24 -0
- package/dist/plugins/style-entry-build.d.ts +5 -0
- package/dist/plugins/style-entry-build.js +121 -0
- package/dist/plugins/style-entry-hmr.d.ts +6 -0
- package/dist/plugins/style-entry-hmr.js +78 -0
- package/dist/plugins/style-entry.d.ts +5 -0
- package/dist/plugins/style-entry.js +89 -0
- package/dist/plugins/stylesheet-recovery.d.ts +5 -0
- package/dist/plugins/stylesheet-recovery.js +70 -0
- package/dist/plugins/usage-graph.d.ts +5 -0
- package/dist/plugins/usage-graph.js +48 -0
- package/dist/preset/src/default-manifest.js +15913 -0
- package/dist/utils/build-import-resolver.d.ts +29 -0
- package/dist/utils/build-import-resolver.js +101 -0
- package/dist/utils/build-sass-source.d.ts +38 -0
- package/dist/utils/build-sass-source.js +225 -0
- package/dist/utils/build-stylesheet-delivery.d.ts +12 -0
- package/dist/utils/build-stylesheet-delivery.js +130 -0
- package/dist/utils/build-watch-recovery.d.ts +10 -0
- package/dist/utils/build-watch-recovery.js +119 -0
- package/dist/utils/coalesced-task.d.ts +3 -0
- package/dist/utils/coalesced-task.js +25 -0
- package/dist/utils/dev-module-refresh.d.ts +9 -0
- package/dist/utils/dev-module-refresh.js +17 -0
- package/dist/utils/dev-stylesheet-delivery.d.ts +21 -0
- package/dist/utils/dev-stylesheet-delivery.js +98 -0
- package/dist/utils/environment-closing.d.ts +3 -0
- package/dist/utils/environment-closing.js +28 -0
- package/dist/utils/extracted-css.d.ts +4 -0
- package/dist/utils/extracted-css.js +34 -0
- package/dist/utils/failed-dependency-reconciliation.d.ts +15 -0
- package/dist/utils/failed-dependency-reconciliation.js +150 -0
- package/dist/utils/failed-stylesheet-dependencies.d.ts +16 -0
- package/dist/utils/failed-stylesheet-dependencies.js +92 -0
- package/dist/utils/html.d.ts +8 -0
- package/dist/utils/html.js +36 -0
- package/dist/utils/inline-stylesheet.d.ts +37 -0
- package/dist/utils/inline-stylesheet.js +129 -0
- package/dist/utils/local-stylesheet.d.ts +10 -0
- package/dist/utils/local-stylesheet.js +25 -0
- package/dist/utils/manifest-recovery.d.ts +11 -0
- package/dist/utils/manifest-recovery.js +77 -0
- package/dist/utils/module-sources.d.ts +26 -0
- package/dist/utils/module-sources.js +131 -0
- package/dist/utils/path.d.ts +5 -0
- package/dist/utils/path.js +27 -0
- package/dist/utils/recovery-error.d.ts +3 -0
- package/dist/utils/recovery-error.js +17 -0
- package/dist/utils/register-style-source.d.ts +4 -0
- package/dist/utils/register-style-source.js +23 -0
- package/dist/utils/sass-diagnostics.d.ts +4 -0
- package/dist/utils/sass-diagnostics.js +109 -0
- package/dist/utils/sass-proxy-access.d.ts +4 -0
- package/dist/utils/sass-proxy-access.js +28 -0
- package/dist/utils/sass-source-markers.d.ts +8 -0
- package/dist/utils/sass-source-markers.js +50 -0
- package/dist/utils/scanner-context.d.ts +12 -0
- package/dist/utils/scanner-context.js +100 -0
- package/dist/utils/scoped-plugins.d.ts +4 -0
- package/dist/utils/scoped-plugins.js +81 -0
- package/dist/utils/write-file.d.ts +3 -0
- package/dist/utils/write-file.js +9 -0
- package/package.json +62 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { MasterCSSStylesheetImportResolver } from "@master/css-compiler/stylesheet";
|
|
2
|
+
import { MasterCSSVitePluginContext } from "../core.js";
|
|
3
|
+
interface ImportResolverContext {
|
|
4
|
+
resolve?: (id: string, importer: string, options: {
|
|
5
|
+
skipSelf: true;
|
|
6
|
+
}) => Promise<{
|
|
7
|
+
id: string;
|
|
8
|
+
external?: boolean | string;
|
|
9
|
+
} | null>;
|
|
10
|
+
addWatchFile?: (id: string) => void;
|
|
11
|
+
load?: (options: {
|
|
12
|
+
id: string;
|
|
13
|
+
}) => Promise<{
|
|
14
|
+
meta: Record<string, unknown>;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
declare function clearBuildStylesheetSources(context: MasterCSSVitePluginContext): void;
|
|
18
|
+
/** Capture loader CSS before Master or Vite transforms replace it. */
|
|
19
|
+
declare function captureBuildStylesheetSource(context: MasterCSSVitePluginContext, id: string, source: string): {
|
|
20
|
+
"master-css:stylesheet-source": string;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/** Graph-only loads must not create another unconditional stylesheet entry. */
|
|
23
|
+
declare function removeGraphOnlyStylesheetEntries(context: MasterCSSVitePluginContext, getModuleInfo: (id: string) => {
|
|
24
|
+
importers: readonly string[];
|
|
25
|
+
dynamicImporters: readonly string[];
|
|
26
|
+
} | null): void;
|
|
27
|
+
/** Reuse Vite/plugin resolution, including aliases and browser import conditions. */
|
|
28
|
+
declare function getBuildImportResolver(context: MasterCSSVitePluginContext, plugin: ImportResolverContext): MasterCSSStylesheetImportResolver | undefined;
|
|
29
|
+
export { captureBuildStylesheetSource, clearBuildStylesheetSources, getBuildImportResolver, removeGraphOnlyStylesheetEntries };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { normalizeFilePath } from "./path.js";
|
|
2
|
+
import { moduleSourceID, moduleSourceOwner } from "./module-sources.js";
|
|
3
|
+
import { getPreparedSassSource, getPreparedSassSourceMap, getSassSourceFile, prepareBuildSassSource, sassSourceID } from "./build-sass-source.js";
|
|
4
|
+
import { isAbsolute } from "node:path";
|
|
5
|
+
// src/utils/build-import-resolver.ts
|
|
6
|
+
const SOURCE_META = "master-css:stylesheet-source";
|
|
7
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
function state(context) {
|
|
9
|
+
let result = states.get(context);
|
|
10
|
+
if (!result) {
|
|
11
|
+
result = {
|
|
12
|
+
sources: /* @__PURE__ */ new Map(),
|
|
13
|
+
importedModules: /* @__PURE__ */ new Set()
|
|
14
|
+
};
|
|
15
|
+
states.set(context, result);
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
function clearBuildStylesheetSources(context) {
|
|
20
|
+
states.delete(context);
|
|
21
|
+
}
|
|
22
|
+
/** Capture loader CSS before Master or Vite transforms replace it. */
|
|
23
|
+
function captureBuildStylesheetSource(context, id, source) {
|
|
24
|
+
if (context.config?.command !== "build" || !/\.css(?:[?#].*)?$/i.test(id)) return;
|
|
25
|
+
state(context).sources.set(id, source);
|
|
26
|
+
return { [SOURCE_META]: source };
|
|
27
|
+
}
|
|
28
|
+
/** Graph-only loads must not create another unconditional stylesheet entry. */
|
|
29
|
+
function removeGraphOnlyStylesheetEntries(context, getModuleInfo) {
|
|
30
|
+
for (const id of state(context).importedModules) {
|
|
31
|
+
const info = getModuleInfo(id);
|
|
32
|
+
if (info && !info.importers.length && !info.dynamicImporters.length) context.stylesheets?.delete(id);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Reuse Vite/plugin resolution, including aliases and browser import conditions. */
|
|
36
|
+
function getBuildImportResolver(context, plugin) {
|
|
37
|
+
if (!plugin.resolve) return;
|
|
38
|
+
return async (specifier, importer) => {
|
|
39
|
+
if (/^(?:https?:|data:|\/\/|#)/i.test(specifier)) return null;
|
|
40
|
+
const scoped = moduleSourceOwner(importer);
|
|
41
|
+
const owner = scoped?.owner ?? getSassSourceFile(importer);
|
|
42
|
+
const result = await plugin.resolve(specifier, scoped?.file ?? owner ?? importer, { skipSelf: true });
|
|
43
|
+
if (!result) return;
|
|
44
|
+
if (result.external) return specifier === "@master/css" || specifier === "@master/css-preset" ? void 0 : null;
|
|
45
|
+
const sassFile = getSassSourceFile(result.id);
|
|
46
|
+
const original = sassFile ?? result.id.replace(/[?#].*$/, "");
|
|
47
|
+
const originalFile = isAbsolute(original) ? normalizeFilePath(original) : original;
|
|
48
|
+
const preparedOwner = owner && getPreparedSassSource(context, owner);
|
|
49
|
+
const scopedSource = preparedOwner && (await preparedOwner.prepared).moduleSources?.get(originalFile);
|
|
50
|
+
if (typeof scopedSource === "string") {
|
|
51
|
+
plugin.addWatchFile?.(originalFile);
|
|
52
|
+
const id = moduleSourceID(owner, originalFile);
|
|
53
|
+
return {
|
|
54
|
+
id,
|
|
55
|
+
source: scopedSource,
|
|
56
|
+
baseFile: originalFile,
|
|
57
|
+
sourceMap: await getPreparedSassSourceMap(context, id)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (sassFile) {
|
|
61
|
+
plugin.addWatchFile?.(sassFile);
|
|
62
|
+
const prepared = await prepareBuildSassSource(context, sassFile, (file) => plugin.addWatchFile?.(file));
|
|
63
|
+
for (const dependency of prepared.deps ?? []) plugin.addWatchFile?.(dependency);
|
|
64
|
+
return {
|
|
65
|
+
id: sassSourceID(sassFile),
|
|
66
|
+
source: prepared.code,
|
|
67
|
+
baseFile: sassFile,
|
|
68
|
+
sourceMap: await getPreparedSassSourceMap(context, sassFile)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const file = result.id.replace(/(\.(?:css|scss|sass))(?:[?#].*)$/i, "$1");
|
|
72
|
+
if (isAbsolute(file) && /\.(?:scss|sass)$/i.test(file)) {
|
|
73
|
+
plugin.addWatchFile?.(file);
|
|
74
|
+
const prepared = await prepareBuildSassSource(context, file, (file) => plugin.addWatchFile?.(file));
|
|
75
|
+
for (const dependency of prepared.deps ?? []) plugin.addWatchFile?.(dependency);
|
|
76
|
+
return {
|
|
77
|
+
id: file,
|
|
78
|
+
source: prepared.code,
|
|
79
|
+
baseFile: file,
|
|
80
|
+
sourceMap: await getPreparedSassSourceMap(context, file)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (isAbsolute(file) && /\.css$/i.test(file)) return file;
|
|
84
|
+
if (result.id.startsWith("\0") && /\.css(?:[?#].*)?$/i.test(result.id) && plugin.load) {
|
|
85
|
+
const loaded = state(context);
|
|
86
|
+
loaded.importedModules.add(result.id);
|
|
87
|
+
if (!loaded.sources.has(result.id)) {
|
|
88
|
+
const cachedSource = (await plugin.load({ id: result.id })).meta[SOURCE_META];
|
|
89
|
+
if (!loaded.sources.has(result.id) && typeof cachedSource === "string") loaded.sources.set(result.id, cachedSource);
|
|
90
|
+
}
|
|
91
|
+
const source = loaded.sources.get(result.id);
|
|
92
|
+
if (source === void 0) throw new Error(`CSS loader did not provide source: ${result.id}`);
|
|
93
|
+
return {
|
|
94
|
+
id: result.id,
|
|
95
|
+
source,
|
|
96
|
+
baseFile: getSassSourceFile(result.id)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export { captureBuildStylesheetSource, clearBuildStylesheetSources, getBuildImportResolver, removeGraphOnlyStylesheetEntries };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { preprocessCSS } from "vite";
|
|
2
|
+
import { MasterCSSVitePluginContext } from "../core.js";
|
|
3
|
+
import { ModuleSourceDiagnostic } from "./module-sources.js";
|
|
4
|
+
type PreparedSource = Awaited<ReturnType<typeof preprocessCSS>> & {
|
|
5
|
+
moduleSources?: Map<string, string>;
|
|
6
|
+
moduleDiagnostics?: Map<string, ModuleSourceDiagnostic>;
|
|
7
|
+
};
|
|
8
|
+
declare function getSassSourceFile(id: string): string | undefined;
|
|
9
|
+
declare function sassSourceID(file: string): string;
|
|
10
|
+
declare function sassModuleID(file: string): string;
|
|
11
|
+
declare function isSassModuleID(id: string): boolean;
|
|
12
|
+
declare function isRawStyleRequest(id: string): boolean;
|
|
13
|
+
declare function clearBuildSassSources(context: MasterCSSVitePluginContext): void;
|
|
14
|
+
/** Invalidate every prepared owner of an edited source or composed dependency. */
|
|
15
|
+
declare function invalidatePreparedSassSources(context: MasterCSSVitePluginContext, file: string): string[];
|
|
16
|
+
declare function getPreparedSassSource(context: MasterCSSVitePluginContext, id: string): {
|
|
17
|
+
source: string;
|
|
18
|
+
dependencies: Set<string>;
|
|
19
|
+
file: string;
|
|
20
|
+
prepared: Promise<PreparedSource>;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/** Diagnostics for a projected child use its own source and generated map. */
|
|
23
|
+
declare function getPreparedSassDiagnosticSource(context: MasterCSSVitePluginContext, id: string): Promise<{
|
|
24
|
+
file: string;
|
|
25
|
+
source: string;
|
|
26
|
+
generatedID: string;
|
|
27
|
+
prepared: PreparedSource;
|
|
28
|
+
} | {
|
|
29
|
+
file: string;
|
|
30
|
+
source: string;
|
|
31
|
+
generatedID: string;
|
|
32
|
+
prepared: ModuleSourceDiagnostic;
|
|
33
|
+
} | undefined>;
|
|
34
|
+
/** Carry the host's map alongside CSS so reference lookup can retain partial origins. */
|
|
35
|
+
declare function getPreparedSassSourceMap(context: MasterCSSVitePluginContext, id: string): Promise<string | undefined>;
|
|
36
|
+
/** Use Vite's preprocessors/Modules and URL rebasing, leaving imports for Rust. */
|
|
37
|
+
declare function prepareBuildSassSource(context: MasterCSSVitePluginContext, file: string, onDependency?: (file: string) => void): Promise<PreparedSource>;
|
|
38
|
+
export { clearBuildSassSources, getPreparedSassDiagnosticSource, getPreparedSassSource, getPreparedSassSourceMap, getSassSourceFile, invalidatePreparedSassSources, isRawStyleRequest, isSassModuleID, prepareBuildSassSource, sassModuleID, sassSourceID };
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { normalizeFilePath } from "./path.js";
|
|
2
|
+
import { createSassSourceMarkers } from "./sass-source-markers.js";
|
|
3
|
+
import { createModuleSourceProjection, moduleSourceOwner } from "./module-sources.js";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
import { isAbsolute, join } from "node:path";
|
|
7
|
+
import { preprocessCSS } from "vite";
|
|
8
|
+
import { mkdir, mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
|
|
9
|
+
import { pathToFileURL } from "node:url";
|
|
10
|
+
// src/utils/build-sass-source.ts
|
|
11
|
+
const CSS_SUFFIX = ".master-css-sass.css";
|
|
12
|
+
const MODULE_PREFIX = "\0master-css:sass-module:";
|
|
13
|
+
const caches = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
function getSassSourceFile(id) {
|
|
15
|
+
id = id.replace(/[?#].*$/, "");
|
|
16
|
+
if (id.startsWith(MODULE_PREFIX)) return decodeURIComponent(id.slice(24, -3));
|
|
17
|
+
if (id.endsWith(CSS_SUFFIX)) return id.slice(0, -20);
|
|
18
|
+
}
|
|
19
|
+
function sassSourceID(file) {
|
|
20
|
+
return `${file}${CSS_SUFFIX}`;
|
|
21
|
+
}
|
|
22
|
+
function sassModuleID(file) {
|
|
23
|
+
return MODULE_PREFIX + encodeURIComponent(file) + ".js";
|
|
24
|
+
}
|
|
25
|
+
function isSassModuleID(id) {
|
|
26
|
+
return id.startsWith(MODULE_PREFIX);
|
|
27
|
+
}
|
|
28
|
+
function isRawStyleRequest(id) {
|
|
29
|
+
return /[?&](?:raw|url)(?:[=&]|$)/.test(id);
|
|
30
|
+
}
|
|
31
|
+
function clearBuildSassSources(context) {
|
|
32
|
+
caches.delete(context);
|
|
33
|
+
}
|
|
34
|
+
/** Invalidate every prepared owner of an edited source or composed dependency. */
|
|
35
|
+
function invalidatePreparedSassSources(context, file) {
|
|
36
|
+
file = normalizeFilePath(file);
|
|
37
|
+
const cache = caches.get(context);
|
|
38
|
+
const affected = [];
|
|
39
|
+
for (const [owner, entry] of cache ?? []) {
|
|
40
|
+
if (owner !== file && !entry.dependencies.has(file)) continue;
|
|
41
|
+
entry.prepared = void 0;
|
|
42
|
+
affected.push(owner);
|
|
43
|
+
}
|
|
44
|
+
return affected;
|
|
45
|
+
}
|
|
46
|
+
function getPreparedSassSource(context, id) {
|
|
47
|
+
const file = normalizeFilePath(getSassSourceFile(id) ?? id.replace(/[?#].*$/, ""));
|
|
48
|
+
const cached = caches.get(context)?.get(file);
|
|
49
|
+
return cached?.prepared ? {
|
|
50
|
+
file,
|
|
51
|
+
...cached,
|
|
52
|
+
prepared: cached.prepared
|
|
53
|
+
} : void 0;
|
|
54
|
+
}
|
|
55
|
+
/** Diagnostics for a projected child use its own source and generated map. */
|
|
56
|
+
async function getPreparedSassDiagnosticSource(context, id) {
|
|
57
|
+
const scoped = moduleSourceOwner(id);
|
|
58
|
+
const cached = getPreparedSassSource(context, scoped?.owner ?? id);
|
|
59
|
+
if (!cached) return;
|
|
60
|
+
const prepared = await cached.prepared;
|
|
61
|
+
if (!scoped) return {
|
|
62
|
+
file: cached.file,
|
|
63
|
+
source: cached.source,
|
|
64
|
+
generatedID: id,
|
|
65
|
+
prepared
|
|
66
|
+
};
|
|
67
|
+
const child = prepared.moduleDiagnostics?.get(scoped.file);
|
|
68
|
+
if (child) return {
|
|
69
|
+
file: scoped.file,
|
|
70
|
+
source: child.source,
|
|
71
|
+
generatedID: sassSourceID(scoped.file),
|
|
72
|
+
prepared: child
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** Carry the host's map alongside CSS so reference lookup can retain partial origins. */
|
|
76
|
+
async function getPreparedSassSourceMap(context, id) {
|
|
77
|
+
const map = (await getPreparedSassDiagnosticSource(context, id))?.prepared.map;
|
|
78
|
+
return map ? typeof map === "string" ? map : JSON.stringify(map) : void 0;
|
|
79
|
+
}
|
|
80
|
+
/** Use Vite's preprocessors/Modules and URL rebasing, leaving imports for Rust. */
|
|
81
|
+
function prepareBuildSassSource(context, file, onDependency) {
|
|
82
|
+
if (!context.config) throw new Error("Sass preparation requires resolved Vite configuration.");
|
|
83
|
+
file = normalizeFilePath(file);
|
|
84
|
+
let cache = caches.get(context);
|
|
85
|
+
if (!cache) {
|
|
86
|
+
cache = /* @__PURE__ */ new Map();
|
|
87
|
+
caches.set(context, cache);
|
|
88
|
+
}
|
|
89
|
+
let cached = cache.get(file);
|
|
90
|
+
if (!cached?.prepared) {
|
|
91
|
+
const sourceMarkers = createSassSourceMarkers();
|
|
92
|
+
const preserveImports = {
|
|
93
|
+
postcssPlugin: "master-css:preserve-preprocessor-imports",
|
|
94
|
+
prepare({ root }) {
|
|
95
|
+
const imports = [];
|
|
96
|
+
root.walkAtRules((rule) => {
|
|
97
|
+
if (rule.name.toLowerCase() !== "import") return;
|
|
98
|
+
imports.push({
|
|
99
|
+
rule,
|
|
100
|
+
name: rule.name
|
|
101
|
+
});
|
|
102
|
+
rule.name = "--master-css-preserved-import";
|
|
103
|
+
});
|
|
104
|
+
return { OnceExit() {
|
|
105
|
+
for (const { rule, name } of imports) rule.name = name;
|
|
106
|
+
if (!projection) root.walkComments((comment) => {
|
|
107
|
+
if (sourceMarkers.markers.has(comment.text.trim())) comment.remove();
|
|
108
|
+
});
|
|
109
|
+
} };
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const config = context.config;
|
|
113
|
+
const source = readFileSync(file, "utf8");
|
|
114
|
+
const projection = /\.module\.(?:css|scss|sass)$/.test(file) && config.css.modules !== false ? createModuleSourceProjection(file) : void 0;
|
|
115
|
+
const dependencies = new Set(cached?.dependencies);
|
|
116
|
+
const discovered = /* @__PURE__ */ new Set();
|
|
117
|
+
let importDirectory;
|
|
118
|
+
const importedSources = /* @__PURE__ */ new Map();
|
|
119
|
+
const originalFile = (id) => projection?.sourceFiles.get(normalizeFilePath(id)) ?? normalizeFilePath(id);
|
|
120
|
+
const preprocessorConfig = {
|
|
121
|
+
...config,
|
|
122
|
+
createResolver(options) {
|
|
123
|
+
const resolve = config.createResolver(options);
|
|
124
|
+
const cssImport = options?.extensions?.length === 1 && options.extensions[0] === ".css";
|
|
125
|
+
return async (...args) => {
|
|
126
|
+
if (args[1]) args[1] = originalFile(args[1]);
|
|
127
|
+
const resolved = await resolve(...args);
|
|
128
|
+
if (resolved && isAbsolute(resolved)) {
|
|
129
|
+
dependencies.add(originalFile(resolved));
|
|
130
|
+
discovered.add(originalFile(resolved));
|
|
131
|
+
}
|
|
132
|
+
if (resolved && projection && cssImport && /\.(?:scss|sass)$/.test(resolved)) {
|
|
133
|
+
let prepared = importedSources.get(resolved);
|
|
134
|
+
if (!prepared) {
|
|
135
|
+
prepared = prepareImportedSource(resolved);
|
|
136
|
+
importedSources.set(resolved, prepared);
|
|
137
|
+
}
|
|
138
|
+
return prepared;
|
|
139
|
+
}
|
|
140
|
+
return resolved;
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
css: {
|
|
144
|
+
...config.css,
|
|
145
|
+
devSourcemap: true,
|
|
146
|
+
preprocessorOptions: {
|
|
147
|
+
...config.css.preprocessorOptions,
|
|
148
|
+
scss: {
|
|
149
|
+
...config.css.preprocessorOptions?.scss,
|
|
150
|
+
sourceMapIncludeSources: true,
|
|
151
|
+
additionalData: (projection ?? sourceMarkers).additionalData(config.css.preprocessorOptions?.scss?.additionalData)
|
|
152
|
+
},
|
|
153
|
+
sass: {
|
|
154
|
+
...config.css.preprocessorOptions?.sass,
|
|
155
|
+
sourceMapIncludeSources: true,
|
|
156
|
+
additionalData: (projection ?? sourceMarkers).additionalData(config.css.preprocessorOptions?.sass?.additionalData)
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
transformer: "postcss",
|
|
160
|
+
postcss: { plugins: [projection?.plugin ?? preserveImports] }
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
async function prepareImportedSource(id) {
|
|
164
|
+
const result = await preprocessCSS(readFileSync(id, "utf8"), id, {
|
|
165
|
+
...preprocessorConfig,
|
|
166
|
+
css: {
|
|
167
|
+
...preprocessorConfig.css,
|
|
168
|
+
modules: false,
|
|
169
|
+
postcss: { plugins: [preserveImports] }
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
for (const dependency of result.deps ?? []) {
|
|
173
|
+
discovered.add(originalFile(dependency));
|
|
174
|
+
dependencies.add(originalFile(dependency));
|
|
175
|
+
}
|
|
176
|
+
importDirectory ??= mkdir(config.cacheDir, { recursive: true }).then(() => mkdtemp(join(config.cacheDir, "master-css-sass-import-"))).then((directory) => realpath(directory));
|
|
177
|
+
const path = normalizeFilePath(join(await importDirectory, `${createHash("sha256").update(id).digest("hex")}.css`));
|
|
178
|
+
projection.sourceFiles.set(path, id);
|
|
179
|
+
const raw = typeof result.map === "string" ? JSON.parse(result.map) : result.map;
|
|
180
|
+
const root = raw && "sourceRoot" in raw && raw.sourceRoot ? raw.sourceRoot.replace(/\/?$/, "/") : "./";
|
|
181
|
+
const base = isAbsolute(root) ? pathToFileURL(root) : new URL(root, pathToFileURL(id));
|
|
182
|
+
const map = raw && "sources" in raw && raw.sources ? JSON.stringify({
|
|
183
|
+
...raw,
|
|
184
|
+
sourceRoot: "",
|
|
185
|
+
sources: raw.sources.map((source) => source ? (isAbsolute(source) ? pathToFileURL(source) : new URL(source, base)).href : source)
|
|
186
|
+
}) : void 0;
|
|
187
|
+
const annotation = map ? `\n/*# sourceMappingURL=data:application/json;base64,${Buffer.from(map).toString("base64")} */` : "";
|
|
188
|
+
await writeFile(path, result.code + annotation);
|
|
189
|
+
return path;
|
|
190
|
+
}
|
|
191
|
+
cached = {
|
|
192
|
+
source,
|
|
193
|
+
prepared: preprocessCSS(source, file, preprocessorConfig).then((result) => {
|
|
194
|
+
for (const dependency of result.deps ?? []) discovered.add(originalFile(dependency));
|
|
195
|
+
if (projection) for (const dependency of result.deps ?? []) {
|
|
196
|
+
const file = originalFile(dependency);
|
|
197
|
+
if (/\.css$/i.test(file) && !projection.sources.has(file)) projection.copyDuplicate(file, readFileSync(file, "utf8"));
|
|
198
|
+
}
|
|
199
|
+
dependencies.clear();
|
|
200
|
+
for (const dependency of discovered) dependencies.add(dependency);
|
|
201
|
+
return {
|
|
202
|
+
...result,
|
|
203
|
+
deps: dependencies,
|
|
204
|
+
...projection ? {
|
|
205
|
+
moduleSources: projection.sources,
|
|
206
|
+
moduleDiagnostics: projection.diagnostics
|
|
207
|
+
} : {}
|
|
208
|
+
};
|
|
209
|
+
}).finally(async () => {
|
|
210
|
+
await Promise.allSettled(importedSources.values());
|
|
211
|
+
if (importDirectory) await rm(await importDirectory, {
|
|
212
|
+
recursive: true,
|
|
213
|
+
force: true
|
|
214
|
+
});
|
|
215
|
+
}),
|
|
216
|
+
dependencies
|
|
217
|
+
};
|
|
218
|
+
cache.set(file, cached);
|
|
219
|
+
}
|
|
220
|
+
const entry = cached, prepared = entry.prepared;
|
|
221
|
+
return onDependency ? prepared.finally(() => {
|
|
222
|
+
for (const dependency of entry.dependencies) onDependency(dependency);
|
|
223
|
+
}) : prepared;
|
|
224
|
+
}
|
|
225
|
+
export { clearBuildSassSources, getPreparedSassDiagnosticSource, getPreparedSassSource, getPreparedSassSourceMap, getSassSourceFile, invalidatePreparedSassSources, isRawStyleRequest, isSassModuleID, prepareBuildSassSource, sassModuleID, sassSourceID };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MasterCSSStylesheetComposition, MasterCSSStylesheetDeliveryOptions } from "@master/css-compiler/stylesheet";
|
|
2
|
+
import { MasterCSSVitePluginContext } from "../core.js";
|
|
3
|
+
import { MasterCSSCompiler } from "@master/css-compiler";
|
|
4
|
+
import { LocalStylesheet } from "./local-stylesheet.js";
|
|
5
|
+
/** These temporary graph URLs are replaced after the full CSS content is known. */
|
|
6
|
+
declare function getBuildStylesheetDelivery(context: MasterCSSVitePluginContext): MasterCSSStylesheetDeliveryOptions | undefined;
|
|
7
|
+
declare function prepareBuildStylesheet(compiler: MasterCSSCompiler, source: string, slotCSSRule: string, extracted: MasterCSSStylesheetComposition, locals?: readonly LocalStylesheet[]): {
|
|
8
|
+
resources: readonly import("@master/css-compiler/stylesheet").MasterCSSStylesheetResourceAsset[] | undefined;
|
|
9
|
+
source: string;
|
|
10
|
+
assets: readonly import("@master/css-binding/protocol").MasterCSSStylesheetAsset[];
|
|
11
|
+
} | undefined;
|
|
12
|
+
export { getBuildStylesheetDelivery, prepareBuildStylesheet };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { extname } from "node:path";
|
|
4
|
+
// src/utils/build-stylesheet-delivery.ts
|
|
5
|
+
function digest(source) {
|
|
6
|
+
return createHash("sha256").update(source).digest("hex").slice(0, 20);
|
|
7
|
+
}
|
|
8
|
+
/** These temporary graph URLs are replaced after the full CSS content is known. */
|
|
9
|
+
function getBuildStylesheetDelivery(context) {
|
|
10
|
+
if (context.config?.command !== "build") return;
|
|
11
|
+
return {
|
|
12
|
+
entryURL: "./master-css-entry.css",
|
|
13
|
+
stylesheetURL: (file, variant) => `./master-css-source-${digest(variant ?? file)}.css`,
|
|
14
|
+
resourceURL: (file) => `./master-css-resource-${digest(readFileSync(file))}${extname(file)}`,
|
|
15
|
+
relativeResourceURLs: true,
|
|
16
|
+
resolveNodePackageImports: true
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function prepareBuildStylesheet(compiler, source, slotCSSRule, extracted, locals = []) {
|
|
20
|
+
if (locals.length) return prepareLocalBuildStylesheets(compiler, source, slotCSSRule, extracted, locals);
|
|
21
|
+
const managed = {
|
|
22
|
+
entry: "master-css-managed",
|
|
23
|
+
stylesheets: [{
|
|
24
|
+
id: "master-css-managed",
|
|
25
|
+
href: "./master-css-entry.css",
|
|
26
|
+
css: extracted.css
|
|
27
|
+
}, ...extracted.stylesheets ?? []]
|
|
28
|
+
};
|
|
29
|
+
const bundle = compiler.prepareStylesheetBundle({
|
|
30
|
+
source,
|
|
31
|
+
from: "master-css-bundle",
|
|
32
|
+
slotCSSRule,
|
|
33
|
+
managed
|
|
34
|
+
});
|
|
35
|
+
if (!bundle.slots) return;
|
|
36
|
+
return {
|
|
37
|
+
...renderBuildStylesheetBundle(compiler, bundle),
|
|
38
|
+
resources: extracted.resources
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Name fragments after their rendered bytes. Graph node IDs and temporary
|
|
43
|
+
* delivery URLs derive from host file paths, so hashing the prepared bundle
|
|
44
|
+
* would vary with the checkout location.
|
|
45
|
+
*/
|
|
46
|
+
function renderBuildStylesheetBundle(compiler, bundle) {
|
|
47
|
+
const render = (url) => {
|
|
48
|
+
const urls = Object.fromEntries(bundle.graph.stylesheets.map((node, index) => [node.id, url(index)]));
|
|
49
|
+
return {
|
|
50
|
+
urls,
|
|
51
|
+
assets: compiler.renderStylesheetBundle({
|
|
52
|
+
bundle,
|
|
53
|
+
urls,
|
|
54
|
+
preserveResourceBase: true
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
const hash = digest(JSON.stringify(render((index) => `./master-css-${index}.css`).assets.map((asset) => asset.css)));
|
|
59
|
+
const { urls, assets } = render((index) => `./master-css-${hash}-${index}.css`);
|
|
60
|
+
return {
|
|
61
|
+
source: `@import "${urls[bundle.graph.entry]}";`,
|
|
62
|
+
assets
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Compose each local entry at its own position before final content-based naming. */
|
|
66
|
+
function prepareLocalBuildStylesheets(compiler, source, slotCSSRule, extracted, locals) {
|
|
67
|
+
const entry = "./master-css-host.css";
|
|
68
|
+
const graph = /* @__PURE__ */ new Map([[entry, {
|
|
69
|
+
id: entry,
|
|
70
|
+
href: entry,
|
|
71
|
+
css: source
|
|
72
|
+
}]]);
|
|
73
|
+
const resources = /* @__PURE__ */ new Map();
|
|
74
|
+
const replacements = [{
|
|
75
|
+
slot: slotCSSRule,
|
|
76
|
+
css: extracted.css,
|
|
77
|
+
stylesheets: extracted.stylesheets,
|
|
78
|
+
resources: extracted.resources
|
|
79
|
+
}, ...[...locals].sort((a, b) => a.slot < b.slot ? -1 : a.slot > b.slot ? 1 : 0).map(({ slot, result }) => ({
|
|
80
|
+
slot,
|
|
81
|
+
css: result.code,
|
|
82
|
+
stylesheets: result.stylesheets,
|
|
83
|
+
resources: result.resources
|
|
84
|
+
}))];
|
|
85
|
+
let replaced = false;
|
|
86
|
+
for (const [replacementIndex, replacement] of replacements.entries()) for (const [assetIndex, asset] of [...graph.values()].entries()) {
|
|
87
|
+
const bundle = compiler.prepareStylesheetBundle({
|
|
88
|
+
source: asset.css,
|
|
89
|
+
from: asset.id,
|
|
90
|
+
slotCSSRule: replacement.slot,
|
|
91
|
+
managed: {
|
|
92
|
+
entry: "managed",
|
|
93
|
+
stylesheets: [{
|
|
94
|
+
id: "managed",
|
|
95
|
+
href: "./master-css-entry.css",
|
|
96
|
+
css: replacement.css
|
|
97
|
+
}, ...replacement.stylesheets ?? []]
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (!bundle.slots) continue;
|
|
101
|
+
replaced = true;
|
|
102
|
+
const urls = Object.fromEntries(bundle.graph.stylesheets.map((node, index) => [node.id, node.id === bundle.graph.entry ? asset.href : `./master-css-intermediate-${replacementIndex}-${assetIndex}-${index}.css`]));
|
|
103
|
+
const assets = compiler.renderStylesheetBundle({
|
|
104
|
+
bundle,
|
|
105
|
+
urls,
|
|
106
|
+
preserveResourceBase: true
|
|
107
|
+
});
|
|
108
|
+
for (const next of assets) graph.set(next.href, {
|
|
109
|
+
id: next.href,
|
|
110
|
+
href: next.href,
|
|
111
|
+
css: next.css
|
|
112
|
+
});
|
|
113
|
+
for (const resource of replacement.resources ?? []) resources.set(resource.href, resource);
|
|
114
|
+
}
|
|
115
|
+
if (!replaced) return;
|
|
116
|
+
const slot = "#master-css-complete-local-graph{--slot:0}";
|
|
117
|
+
return {
|
|
118
|
+
...renderBuildStylesheetBundle(compiler, compiler.prepareStylesheetBundle({
|
|
119
|
+
source: slot,
|
|
120
|
+
from: "master-css-output",
|
|
121
|
+
slotCSSRule: slot,
|
|
122
|
+
managed: {
|
|
123
|
+
entry,
|
|
124
|
+
stylesheets: [...graph.values()]
|
|
125
|
+
}
|
|
126
|
+
})),
|
|
127
|
+
resources: [...resources.values()]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export { getBuildStylesheetDelivery, prepareBuildStylesheet };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ResolvedConfig } from "vite";
|
|
2
|
+
import { MasterCSSVitePluginContext } from "../core.js";
|
|
3
|
+
import { DependencyHost } from "./failed-stylesheet-dependencies.js";
|
|
4
|
+
type BuildWatch = ResolvedConfig['build']['watch'];
|
|
5
|
+
/** Allocate during config resolution; retain every started owner. */
|
|
6
|
+
declare function prepareBuildStylesheetRecovery(context: MasterCSSVitePluginContext, root: string, cacheDir: string, watch: BuildWatch, environment?: object): void;
|
|
7
|
+
/** An existing owned cache file lets the build host invalidate failed modules. */
|
|
8
|
+
declare function trackBuildStylesheetRecovery(context: MasterCSSVitePluginContext, host: DependencyHost, key: string, id: string, versions: Map<string, string>): void;
|
|
9
|
+
declare function closeBuildStylesheetRecovery(context: MasterCSSVitePluginContext, environment: object): void;
|
|
10
|
+
export { closeBuildStylesheetRecovery, prepareBuildStylesheetRecovery, trackBuildStylesheetRecovery };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { clearFailedDependencyReconciliation, trackFailedDependencyReconciliation } from "./failed-dependency-reconciliation.js";
|
|
2
|
+
import { mkdirSync, mkdtempSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { createFilter } from "vite";
|
|
5
|
+
// src/utils/build-watch-recovery.ts
|
|
6
|
+
const recoveries = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
const held = /* @__PURE__ */ new Set();
|
|
8
|
+
function retain(state, environment) {
|
|
9
|
+
state.owners.add(environment);
|
|
10
|
+
held.add(state.directory);
|
|
11
|
+
}
|
|
12
|
+
function running(pid) {
|
|
13
|
+
try {
|
|
14
|
+
process.kill(pid, 0);
|
|
15
|
+
return true;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
return error.code === "EPERM";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configuration has to allocate before the host can say whether the build will
|
|
22
|
+
* start, and the host runs no hook after a failure during configuration or
|
|
23
|
+
* environment creation, so material from such a run outlives it. Reclaim it
|
|
24
|
+
* here instead: the owning process id is in the directory name, so a directory
|
|
25
|
+
* is stale when no owner in this process holds it and the process that
|
|
26
|
+
* allocated it is gone or is this one.
|
|
27
|
+
*/
|
|
28
|
+
function sweepStaleRecoveries(base, prefix) {
|
|
29
|
+
let entries;
|
|
30
|
+
try {
|
|
31
|
+
entries = readdirSync(base);
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
if (!entry.startsWith(prefix)) continue;
|
|
37
|
+
const directory = join(base, entry);
|
|
38
|
+
if (held.has(directory)) continue;
|
|
39
|
+
const pid = Number.parseInt(entry.slice(prefix.length), 10);
|
|
40
|
+
if (pid !== process.pid && Number.isInteger(pid) && running(pid)) continue;
|
|
41
|
+
rmSync(directory, {
|
|
42
|
+
recursive: true,
|
|
43
|
+
force: true
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The build host applies `build.watch` include and exclude to every watched
|
|
49
|
+
* file, plugin-added ones included, so a project filter can silently drop the
|
|
50
|
+
* file recovery depends on. Take the first location the project's own filter
|
|
51
|
+
* accepts rather than overriding what it asked for.
|
|
52
|
+
*/
|
|
53
|
+
function resolveRecoveryLocation(root, cacheDir, watch) {
|
|
54
|
+
const accepts = createFilter(watch?.include, watch?.exclude, { resolve: false });
|
|
55
|
+
return [
|
|
56
|
+
{
|
|
57
|
+
base: cacheDir,
|
|
58
|
+
prefix: "master-css-watch-",
|
|
59
|
+
name: "invalidate"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
base: cacheDir,
|
|
63
|
+
prefix: "master-css-watch-",
|
|
64
|
+
name: "invalidate.css"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
base: root,
|
|
68
|
+
prefix: ".master-css-watch-",
|
|
69
|
+
name: "invalidate.css"
|
|
70
|
+
}
|
|
71
|
+
].find(({ base, prefix, name }) => accepts(join(base, `${prefix}probe`, name)));
|
|
72
|
+
}
|
|
73
|
+
/** Allocate during config resolution; retain every started owner. */
|
|
74
|
+
function prepareBuildStylesheetRecovery(context, root, cacheDir, watch, environment) {
|
|
75
|
+
const existing = recoveries.get(context);
|
|
76
|
+
if (existing) {
|
|
77
|
+
if (environment) retain(existing, environment);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const location = resolveRecoveryLocation(root, cacheDir, watch);
|
|
81
|
+
if (!location) return;
|
|
82
|
+
mkdirSync(location.base, { recursive: true });
|
|
83
|
+
sweepStaleRecoveries(location.base, location.prefix);
|
|
84
|
+
const directory = mkdtempSync(join(location.base, `${location.prefix}${process.pid}-`)), file = join(directory, location.name);
|
|
85
|
+
writeFileSync(file, "pending");
|
|
86
|
+
const state = {
|
|
87
|
+
directory,
|
|
88
|
+
file,
|
|
89
|
+
owners: /* @__PURE__ */ new Set()
|
|
90
|
+
};
|
|
91
|
+
recoveries.set(context, state);
|
|
92
|
+
if (environment) retain(state, environment);
|
|
93
|
+
}
|
|
94
|
+
/** An existing owned cache file lets the build host invalidate failed modules. */
|
|
95
|
+
function trackBuildStylesheetRecovery(context, host, key, id, versions) {
|
|
96
|
+
const state = recoveries.get(context);
|
|
97
|
+
if (!versions.size || !host.addWatchFile || !state) return;
|
|
98
|
+
const environment = host.environment ?? context;
|
|
99
|
+
retain(state, environment);
|
|
100
|
+
host.addWatchFile(state.file);
|
|
101
|
+
trackFailedDependencyReconciliation(context, environment, key, id, versions, async (_environment, _id, _changed, active) => {
|
|
102
|
+
if (active()) writeFileSync(state.file, String(process.hrtime.bigint()));
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function closeBuildStylesheetRecovery(context, environment) {
|
|
106
|
+
clearFailedDependencyReconciliation(context, environment);
|
|
107
|
+
const state = recoveries.get(context);
|
|
108
|
+
if (!state) return;
|
|
109
|
+
state.owners.delete(environment);
|
|
110
|
+
if (!state.owners.size) {
|
|
111
|
+
rmSync(state.directory, {
|
|
112
|
+
recursive: true,
|
|
113
|
+
force: true
|
|
114
|
+
});
|
|
115
|
+
held.delete(state.directory);
|
|
116
|
+
recoveries.delete(context);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export { closeBuildStylesheetRecovery, prepareBuildStylesheetRecovery, trackBuildStylesheetRecovery };
|