@master/css-compiler 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 +466 -0
- package/dist/compiler.d.ts +42 -0
- package/dist/compiler.js +248 -0
- package/dist/contracts.d.ts +31 -0
- package/dist/contracts.js +13 -0
- package/dist/diagnostics/contracts.d.ts +119 -0
- package/dist/diagnostics/contracts.js +1 -0
- package/dist/diagnostics/design-system.d.ts +31 -0
- package/dist/diagnostics/design-system.js +75 -0
- package/dist/diagnostics/index.d.ts +28 -0
- package/dist/diagnostics/index.js +304 -0
- package/dist/diagnostics/project-comparison.d.ts +4 -0
- package/dist/diagnostics/project-comparison.js +8 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +34 -0
- package/dist/node-compiler.d.ts +133 -0
- package/dist/node-compiler.js +417 -0
- package/dist/node-imports.d.ts +54 -0
- package/dist/node-imports.js +253 -0
- package/dist/node.d.ts +21 -0
- package/dist/node.js +47 -0
- package/dist/notices.d.ts +5 -0
- package/dist/notices.js +29 -0
- package/dist/prepared-graph-cache.d.ts +5 -0
- package/dist/prepared-graph-cache.js +31 -0
- package/dist/project/binding-project.d.ts +29 -0
- package/dist/project/binding-project.js +100 -0
- package/dist/project/entries.d.ts +7 -0
- package/dist/project/entries.js +30 -0
- package/dist/project/manifest-sync.d.ts +5 -0
- package/dist/project/manifest-sync.js +40 -0
- package/dist/project/manifest.d.ts +5 -0
- package/dist/project/manifest.js +49 -0
- package/dist/project/options.d.ts +43 -0
- package/dist/project/options.js +1 -0
- package/dist/pure-css-cache.d.ts +11 -0
- package/dist/pure-css-cache.js +39 -0
- package/dist/session.d.ts +19 -0
- package/dist/session.js +46 -0
- package/dist/stylesheet/browser.d.ts +32 -0
- package/dist/stylesheet/browser.js +71 -0
- package/dist/stylesheet/compiled-source.d.ts +11 -0
- package/dist/stylesheet/compiled-source.js +96 -0
- package/dist/stylesheet/composition-cache.d.ts +18 -0
- package/dist/stylesheet/composition-cache.js +79 -0
- package/dist/stylesheet/delivery.d.ts +103 -0
- package/dist/stylesheet/delivery.js +367 -0
- package/dist/stylesheet/directives.d.ts +31 -0
- package/dist/stylesheet/directives.js +105 -0
- package/dist/stylesheet/index-public.d.ts +3 -0
- package/dist/stylesheet/index-public.js +4 -0
- package/dist/stylesheet/index.d.ts +39 -0
- package/dist/stylesheet/index.js +501 -0
- package/dist/stylesheet/linked-stylesheet.d.ts +10 -0
- package/dist/stylesheet/linked-stylesheet.js +13 -0
- package/dist/stylesheet/output-map.d.ts +20 -0
- package/dist/stylesheet/output-map.js +222 -0
- package/dist/stylesheet/public.d.ts +171 -0
- package/dist/stylesheet/public.js +346 -0
- package/dist/stylesheet/reference-files.d.ts +6 -0
- package/dist/stylesheet/reference-files.js +13 -0
- package/dist/stylesheet/reference-origins.d.ts +4 -0
- package/dist/stylesheet/reference-origins.js +28 -0
- package/dist/stylesheet/render-core.d.ts +35 -0
- package/dist/stylesheet/render-core.js +28 -0
- package/dist/stylesheet/render-delivery.d.ts +4 -0
- package/dist/stylesheet/render-delivery.js +61 -0
- package/dist/stylesheet/render.d.ts +5 -0
- package/dist/stylesheet/render.js +31 -0
- package/dist/stylesheet/source-context.d.ts +8 -0
- package/dist/stylesheet/source-context.js +71 -0
- package/dist/stylesheet/source-map-url.d.ts +4 -0
- package/dist/stylesheet/source-map-url.js +11 -0
- package/dist/stylesheet/source.d.ts +3 -0
- package/dist/stylesheet/source.js +52 -0
- package/dist/stylesheet/types.d.ts +162 -0
- package/dist/stylesheet/types.js +1 -0
- package/dist/value-validation.d.ts +19 -0
- package/dist/value-validation.js +96 -0
- package/package.json +79 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { findCSSManifestEntryFilesSync, isCSSManifestRequest } from "./entries.js";
|
|
2
|
+
import { loadBindingProjectManifest } from "./binding-project.js";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { MASTER_CSS_DIAGNOSTIC_VERSION } from "@master/css-schema";
|
|
5
|
+
// src/project/manifest.ts
|
|
6
|
+
function throwIfAborted(signal) {
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
}
|
|
9
|
+
function assertStylesheetEntries(entries) {
|
|
10
|
+
for (const entry of entries ?? []) if (!isCSSManifestRequest(entry)) throw new TypeError("Master CSS project entries must be CSS files.");
|
|
11
|
+
}
|
|
12
|
+
function warningDiagnostic(message) {
|
|
13
|
+
return Object.freeze({
|
|
14
|
+
version: MASTER_CSS_DIAGNOSTIC_VERSION,
|
|
15
|
+
code: "PROJECT_WARNING",
|
|
16
|
+
domain: "project",
|
|
17
|
+
severity: "warning",
|
|
18
|
+
message
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function immutableProjectResult(result, onDiagnostic) {
|
|
22
|
+
const diagnostics = Object.freeze(result.warnings.map(warningDiagnostic));
|
|
23
|
+
for (const diagnostic of diagnostics) onDiagnostic?.(diagnostic);
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
manifest: Object.freeze(result.manifest),
|
|
26
|
+
nativeClassNames: Object.freeze([...result.nativeClassNames]),
|
|
27
|
+
entries: Object.freeze([...result.entries]),
|
|
28
|
+
dependencies: Object.freeze([...result.dependencies]),
|
|
29
|
+
diagnostics,
|
|
30
|
+
...result.sourceGraph ? { sourceGraph: result.sourceGraph } : {}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async function discoverManifestEntries(options = {}) {
|
|
34
|
+
throwIfAborted(options.signal);
|
|
35
|
+
const entries = findCSSManifestEntryFilesSync(resolve(options.root ?? process.cwd()));
|
|
36
|
+
throwIfAborted(options.signal);
|
|
37
|
+
return Object.freeze(entries);
|
|
38
|
+
}
|
|
39
|
+
async function loadProjectManifest(options) {
|
|
40
|
+
throwIfAborted(options.signal);
|
|
41
|
+
assertStylesheetEntries(options.entries);
|
|
42
|
+
const result = loadBindingProjectManifest(resolve(options.root ?? process.cwd()), options.baseManifest, options.entries, options.onDependency, options.includeSourceGraph);
|
|
43
|
+
throwIfAborted(options.signal);
|
|
44
|
+
return immutableProjectResult(result, options.onDiagnostic);
|
|
45
|
+
}
|
|
46
|
+
async function compileProjectManifest(options) {
|
|
47
|
+
return loadProjectManifest(options);
|
|
48
|
+
}
|
|
49
|
+
export { compileProjectManifest, discoverManifestEntries, loadProjectManifest };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { MasterCSSDiagnostic } from "@master/css-schema";
|
|
2
|
+
import { MasterCSSManifest } from "@master/css-schema/manifest";
|
|
3
|
+
interface MasterCSSProjectDiscoveryOptions {
|
|
4
|
+
readonly root?: string;
|
|
5
|
+
readonly signal?: AbortSignal;
|
|
6
|
+
}
|
|
7
|
+
interface MasterCSSProjectLoadOptions extends MasterCSSProjectDiscoveryOptions {
|
|
8
|
+
readonly baseManifest: MasterCSSManifest;
|
|
9
|
+
readonly entries?: readonly string[];
|
|
10
|
+
readonly onDiagnostic?: (diagnostic: MasterCSSDiagnostic) => void;
|
|
11
|
+
/** Reports each project CSS file before reading it, including missing imports/references. */
|
|
12
|
+
readonly onDependency?: (file: string) => void;
|
|
13
|
+
/** Include authored source and import/reference edges for build-time inspection only. */
|
|
14
|
+
readonly includeSourceGraph?: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface MasterCSSProjectSourceGraph {
|
|
17
|
+
readonly version: 1;
|
|
18
|
+
readonly files: readonly Readonly<{
|
|
19
|
+
source: string;
|
|
20
|
+
content: string;
|
|
21
|
+
/** Both authored and real paths are inside the project root, outside node_modules. */
|
|
22
|
+
projectOwned: boolean;
|
|
23
|
+
}>[];
|
|
24
|
+
/** Definition reachability, including @reference; these edges do not imply CSS delivery. */
|
|
25
|
+
readonly edges: readonly Readonly<{
|
|
26
|
+
from: string;
|
|
27
|
+
specifier: string;
|
|
28
|
+
resolved: string;
|
|
29
|
+
}>[];
|
|
30
|
+
}
|
|
31
|
+
interface MasterCSSProjectCompileOptions extends MasterCSSProjectLoadOptions {
|
|
32
|
+
readonly entries: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
interface MasterCSSProjectResult {
|
|
35
|
+
/** Decoded native class registrations from the resolved CSS graph. */
|
|
36
|
+
readonly nativeClassNames: readonly string[];
|
|
37
|
+
readonly manifest: MasterCSSManifest;
|
|
38
|
+
readonly entries: readonly string[];
|
|
39
|
+
readonly dependencies: readonly string[];
|
|
40
|
+
readonly diagnostics: readonly MasterCSSDiagnostic[];
|
|
41
|
+
readonly sourceGraph?: MasterCSSProjectSourceGraph;
|
|
42
|
+
}
|
|
43
|
+
export { MasterCSSProjectCompileOptions, MasterCSSProjectDiscoveryOptions, MasterCSSProjectLoadOptions, MasterCSSProjectResult, MasterCSSProjectSourceGraph };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Pure binding values only; filesystem discovery and observation stay outside. */
|
|
2
|
+
declare class PureCSSCache {
|
|
3
|
+
private readonly budget;
|
|
4
|
+
private readonly capacity;
|
|
5
|
+
private readonly values;
|
|
6
|
+
private bytes;
|
|
7
|
+
constructor(budget?: number, capacity?: number);
|
|
8
|
+
run<T>(operation: string, input: unknown, compute: () => T): T;
|
|
9
|
+
}
|
|
10
|
+
declare const pureCSSCache: PureCSSCache;
|
|
11
|
+
export { PureCSSCache, pureCSSCache };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
// src/pure-css-cache.ts
|
|
3
|
+
/** Pure binding values only; filesystem discovery and observation stay outside. */
|
|
4
|
+
var PureCSSCache = class {
|
|
5
|
+
budget;
|
|
6
|
+
capacity;
|
|
7
|
+
values = /* @__PURE__ */ new Map();
|
|
8
|
+
bytes = 0;
|
|
9
|
+
constructor(budget = 4194304, capacity = 128) {
|
|
10
|
+
this.budget = budget;
|
|
11
|
+
this.capacity = capacity;
|
|
12
|
+
}
|
|
13
|
+
run(operation, input, compute) {
|
|
14
|
+
const key = operation + ":" + createHash("sha256").update(JSON.stringify(input)).digest("hex");
|
|
15
|
+
const cached = this.values.get(key);
|
|
16
|
+
if (cached) {
|
|
17
|
+
this.values.delete(key);
|
|
18
|
+
this.values.set(key, cached);
|
|
19
|
+
return structuredClone(cached.value);
|
|
20
|
+
}
|
|
21
|
+
const value = compute();
|
|
22
|
+
const bytes = JSON.stringify(value).length * 2;
|
|
23
|
+
if (bytes <= this.budget && this.capacity > 0) {
|
|
24
|
+
while (this.bytes + bytes > this.budget || this.values.size >= this.capacity) {
|
|
25
|
+
const oldest = this.values.keys().next().value;
|
|
26
|
+
this.bytes -= this.values.get(oldest).bytes;
|
|
27
|
+
this.values.delete(oldest);
|
|
28
|
+
}
|
|
29
|
+
this.values.set(key, {
|
|
30
|
+
value: structuredClone(value),
|
|
31
|
+
bytes
|
|
32
|
+
});
|
|
33
|
+
this.bytes += bytes;
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const pureCSSCache = new PureCSSCache();
|
|
39
|
+
export { PureCSSCache, pureCSSCache };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MasterCSSBindingLoadOptions, MasterCSSCompilerBindingSession } from "@master/css-binding/compiler";
|
|
2
|
+
import { CompileCSSOptions, CompileCSSResult } from "./contracts.js";
|
|
3
|
+
interface BindingCompilerSession {
|
|
4
|
+
readonly binding: MasterCSSCompilerBindingSession['binding'];
|
|
5
|
+
compareProjectSnapshots: MasterCSSCompilerBindingSession['compareProjectSnapshots'];
|
|
6
|
+
inspectCSS: MasterCSSCompilerBindingSession['inspectCSS'];
|
|
7
|
+
compileCSS(source: string, options?: CompileCSSOptions): CompileCSSResult;
|
|
8
|
+
lowerCSSDirectives: MasterCSSCompilerBindingSession['lowerCSSDirectives'];
|
|
9
|
+
prepareCSSStylesheetBundle: MasterCSSCompilerBindingSession['prepareCSSStylesheetBundle'];
|
|
10
|
+
renderCSSStylesheetBundle: MasterCSSCompilerBindingSession['renderCSSStylesheetBundle'];
|
|
11
|
+
compileCSSStylesheetGraph(request: Parameters<MasterCSSCompilerBindingSession['compileCSSStylesheetGraph']>[0]): Omit<ReturnType<MasterCSSCompilerBindingSession['compileCSSStylesheetGraph']>, 'directives'> & {
|
|
12
|
+
directives: CompileCSSResult;
|
|
13
|
+
};
|
|
14
|
+
dispose(): void;
|
|
15
|
+
}
|
|
16
|
+
declare function createCompilerBindingSession(options?: MasterCSSBindingLoadOptions): Promise<BindingCompilerSession>;
|
|
17
|
+
/** @internal */
|
|
18
|
+
declare function bindCompilerBindingSessionInternal(session: MasterCSSCompilerBindingSession): BindingCompilerSession;
|
|
19
|
+
export { BindingCompilerSession, bindCompilerBindingSessionInternal, createCompilerBindingSession };
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { assertValidationOptions } from "./value-validation.js";
|
|
2
|
+
import { createCompilerBindingSession as createCompilerBindingSession$1 } from "@master/css-binding/compiler";
|
|
3
|
+
// src/session.ts
|
|
4
|
+
function reviveCompileResult(result) {
|
|
5
|
+
result.extractionPolicy.blocklist = result.extractionPolicy.blocklist.map((entry) => {
|
|
6
|
+
if (entry && typeof entry === "object" && "source" in entry && typeof entry.source === "string") return new RegExp(entry.source, "flags" in entry && typeof entry.flags === "string" ? entry.flags : "");
|
|
7
|
+
return entry;
|
|
8
|
+
});
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
11
|
+
function bindCompilerSession(session) {
|
|
12
|
+
return {
|
|
13
|
+
binding: session.binding,
|
|
14
|
+
compareProjectSnapshots: (request) => session.compareProjectSnapshots(request),
|
|
15
|
+
inspectCSS: (source) => session.inspectCSS(source),
|
|
16
|
+
compileCSS(source, options = {}) {
|
|
17
|
+
assertValidationOptions(options);
|
|
18
|
+
return reviveCompileResult(session.compileCSSDirectives(source, {
|
|
19
|
+
from: options.from || "master.css",
|
|
20
|
+
preserveNativeCSS: options.preserveNativeCSS !== false,
|
|
21
|
+
pruneNativeCSS: options.pruneNativeCSS === true,
|
|
22
|
+
...options.preserveNativeSource === void 0 ? {} : { preserveNativeSource: options.preserveNativeSource },
|
|
23
|
+
...options.classes ? { classes: options.classes } : {}
|
|
24
|
+
}));
|
|
25
|
+
},
|
|
26
|
+
lowerCSSDirectives: (request, options, sourceText) => session.lowerCSSDirectives(request, options, sourceText),
|
|
27
|
+
prepareCSSStylesheetBundle: (request) => session.prepareCSSStylesheetBundle(request),
|
|
28
|
+
renderCSSStylesheetBundle: (request) => session.renderCSSStylesheetBundle(request),
|
|
29
|
+
compileCSSStylesheetGraph(request) {
|
|
30
|
+
const result = session.compileCSSStylesheetGraph(request);
|
|
31
|
+
return {
|
|
32
|
+
...result,
|
|
33
|
+
directives: reviveCompileResult(result.directives)
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
dispose: () => session.dispose()
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async function createCompilerBindingSession(options = {}) {
|
|
40
|
+
return bindCompilerSession(await createCompilerBindingSession$1(options));
|
|
41
|
+
}
|
|
42
|
+
/** @internal */
|
|
43
|
+
function bindCompilerBindingSessionInternal(session) {
|
|
44
|
+
return bindCompilerSession(session);
|
|
45
|
+
}
|
|
46
|
+
export { bindCompilerBindingSessionInternal, createCompilerBindingSession };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { MasterCSSDiagnostic } from "@master/css-schema";
|
|
2
|
+
import { MasterCSSManifest } from "@master/css-schema/manifest";
|
|
3
|
+
import { MasterCSSCompileManifestResult } from "../index.js";
|
|
4
|
+
import { MasterCSSEmittedGlobals } from "@master/css-schema/emitted-globals";
|
|
5
|
+
interface MasterCSSBrowserStylesheetCompileOptions {
|
|
6
|
+
readonly baseManifest: MasterCSSManifest;
|
|
7
|
+
readonly classNames?: readonly string[];
|
|
8
|
+
readonly from?: string;
|
|
9
|
+
readonly preserveNativeCSS?: boolean;
|
|
10
|
+
readonly pruneNativeCSS?: boolean;
|
|
11
|
+
readonly validation?: 'report' | 'error';
|
|
12
|
+
/** Keep untouched native source for host transforms; incompatible with class pruning. */
|
|
13
|
+
readonly preserveNativeSource?: boolean;
|
|
14
|
+
/** Globals already present outside this render; emit only additional resources. */
|
|
15
|
+
readonly emittedGlobals?: MasterCSSEmittedGlobals;
|
|
16
|
+
readonly binding?: Readonly<{
|
|
17
|
+
input?: RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
18
|
+
}>;
|
|
19
|
+
readonly signal?: AbortSignal;
|
|
20
|
+
readonly onDiagnostic?: (diagnostic: import('@master/css-schema').MasterCSSDiagnostic) => void;
|
|
21
|
+
}
|
|
22
|
+
interface MasterCSSBrowserStylesheetCompileResult {
|
|
23
|
+
readonly css: string;
|
|
24
|
+
readonly nativeCSS: string;
|
|
25
|
+
readonly generatedCSS: string;
|
|
26
|
+
readonly manifest: MasterCSSManifest;
|
|
27
|
+
readonly diagnostics: readonly MasterCSSDiagnostic[];
|
|
28
|
+
readonly emittedGlobals: Required<MasterCSSEmittedGlobals>;
|
|
29
|
+
readonly result: MasterCSSCompileManifestResult;
|
|
30
|
+
}
|
|
31
|
+
declare function compileBrowserStylesheet(source: string, options: MasterCSSBrowserStylesheetCompileOptions): Promise<MasterCSSBrowserStylesheetCompileResult>;
|
|
32
|
+
export { MasterCSSBrowserStylesheetCompileOptions, MasterCSSBrowserStylesheetCompileResult, type MasterCSSCompileManifestResult, compileBrowserStylesheet };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { assertValidationOptions, validateCompiledCSS } from "../value-validation.js";
|
|
2
|
+
import { renderCompiledManifestCSSWithSession } from "./render-core.js";
|
|
3
|
+
import { createCompiler } from "../index.js";
|
|
4
|
+
import { createCompilerRenderBindingSession } from "@master/css-binding/compiler";
|
|
5
|
+
// src/stylesheet/browser.ts
|
|
6
|
+
async function compileBrowserStylesheet(source, options) {
|
|
7
|
+
assertValidationOptions(options);
|
|
8
|
+
const { baseManifest, classNames, from, preserveNativeCSS, preserveNativeSource, emittedGlobals, binding, signal, onDiagnostic } = options;
|
|
9
|
+
signal?.throwIfAborted();
|
|
10
|
+
const compiler = await createCompiler({
|
|
11
|
+
binding: "wasm",
|
|
12
|
+
...binding ? { wasm: binding } : {}
|
|
13
|
+
});
|
|
14
|
+
let result;
|
|
15
|
+
try {
|
|
16
|
+
result = compiler.compileManifest(source, {
|
|
17
|
+
baseManifest,
|
|
18
|
+
pruneNativeCSS: options.pruneNativeCSS,
|
|
19
|
+
classes: classNames,
|
|
20
|
+
validation: options.validation,
|
|
21
|
+
...from ? { from } : {},
|
|
22
|
+
...preserveNativeCSS === void 0 ? {} : { preserveNativeCSS },
|
|
23
|
+
...preserveNativeSource === void 0 ? {} : { preserveNativeSource },
|
|
24
|
+
...onDiagnostic ? { onDiagnostic } : {}
|
|
25
|
+
});
|
|
26
|
+
} finally {
|
|
27
|
+
compiler.dispose();
|
|
28
|
+
}
|
|
29
|
+
signal?.throwIfAborted();
|
|
30
|
+
const bindingSession = await createCompilerRenderBindingSession({
|
|
31
|
+
manifest: result.manifest,
|
|
32
|
+
emittedGlobals
|
|
33
|
+
}, {
|
|
34
|
+
binding: "wasm",
|
|
35
|
+
wasm: binding
|
|
36
|
+
});
|
|
37
|
+
const renderSession = {
|
|
38
|
+
ensureClasses: (classNames) => bindingSession.ensureClasses(classNames),
|
|
39
|
+
ensureStylesheetResources: (nativeCSS) => bindingSession.ensureStylesheetResources(nativeCSS),
|
|
40
|
+
emittedGlobals: () => bindingSession.emittedGlobals(),
|
|
41
|
+
snapshot: () => bindingSession.snapshot(),
|
|
42
|
+
dispose: () => bindingSession.dispose()
|
|
43
|
+
};
|
|
44
|
+
let renderedCSS;
|
|
45
|
+
try {
|
|
46
|
+
renderedCSS = renderCompiledManifestCSSWithSession({
|
|
47
|
+
manifest: result.manifest,
|
|
48
|
+
nativeCSS: result.css || "",
|
|
49
|
+
classNames
|
|
50
|
+
}, renderSession);
|
|
51
|
+
} finally {
|
|
52
|
+
renderSession.dispose();
|
|
53
|
+
}
|
|
54
|
+
signal?.throwIfAborted();
|
|
55
|
+
return Object.freeze({
|
|
56
|
+
css: renderedCSS.css,
|
|
57
|
+
nativeCSS: renderedCSS.nativeCSS,
|
|
58
|
+
generatedCSS: renderedCSS.generatedCSS,
|
|
59
|
+
manifest: result.manifest,
|
|
60
|
+
diagnostics: Object.freeze([...result.diagnostics, ...validateCompiledCSS([{
|
|
61
|
+
css: renderedCSS.generatedCSS,
|
|
62
|
+
source: from
|
|
63
|
+
}], options)]),
|
|
64
|
+
emittedGlobals: Object.freeze({
|
|
65
|
+
variables: Object.freeze({ ...renderedCSS.emittedGlobals.variables }),
|
|
66
|
+
keyframes: Object.freeze({ ...renderedCSS.emittedGlobals.keyframes })
|
|
67
|
+
}),
|
|
68
|
+
result
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export { compileBrowserStylesheet };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CSSOutputMapping } from "@master/css-schema/css-directives";
|
|
2
|
+
import { CompileCSSManifestResult, CompileCSSResult } from "../node-compiler.js";
|
|
3
|
+
import { CompileStylesheetOptions } from "./types.js";
|
|
4
|
+
/** Preserve input origins while joining parsed and lowered compiler output. */
|
|
5
|
+
declare function compilePreparedStylesheet(filename: string, css: string, options: CompileStylesheetOptions, resolveImports: boolean): {
|
|
6
|
+
compileOptions: Omit<CompileStylesheetOptions, 'projectDir' | 'loadSass' | 'baseManifest' | 'sourceMap' | 'baseFile' | 'onDependency' | 'references' | 'referenceFiles'>;
|
|
7
|
+
finalizedResult: CompileCSSManifestResult;
|
|
8
|
+
result: CompileCSSResult;
|
|
9
|
+
outputMap: (code: string, resources?: CSSOutputMapping[]) => string;
|
|
10
|
+
};
|
|
11
|
+
export { compilePreparedStylesheet };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { stylesheetInputMap, stylesheetOutputMap, stylesheetOutputMappings } from "./output-map.js";
|
|
2
|
+
import { prepareCSSImportGraph } from "../node-imports.js";
|
|
3
|
+
import { analyzeCSSDependencies, compileCSS, compileCSSManifestGraph, createManifestFromCSSResult } from "../node-compiler.js";
|
|
4
|
+
import { resolveReferenceOrigins } from "./reference-origins.js";
|
|
5
|
+
import { referenceFileInputs } from "./reference-files.js";
|
|
6
|
+
import { mapStylesheetError } from "./source-context.js";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { MasterCSSError } from "@master/css-schema";
|
|
9
|
+
// src/stylesheet/compiled-source.ts
|
|
10
|
+
/** Preserve input origins while joining parsed and lowered compiler output. */
|
|
11
|
+
function compilePreparedStylesheet(filename, css, options, resolveImports) {
|
|
12
|
+
const { projectDir, loadSass: _loadSass, baseManifest, sourceMap, baseFile, onDependency, referenceFiles, references: suppliedReferences, ...compileOptions } = options;
|
|
13
|
+
const hostReferences = referenceFileInputs(referenceFiles);
|
|
14
|
+
onDependency?.(baseFile ?? filename);
|
|
15
|
+
let compilationFile = filename;
|
|
16
|
+
const compilationSource = css;
|
|
17
|
+
let errorContext;
|
|
18
|
+
try {
|
|
19
|
+
if (resolveImports) {
|
|
20
|
+
const root = resolve(projectDir ?? "", filename);
|
|
21
|
+
compilationFile = root;
|
|
22
|
+
const graph = prepareCSSImportGraph(root, css, {
|
|
23
|
+
projectDir,
|
|
24
|
+
onDependency
|
|
25
|
+
}, analyzeCSSDependencies);
|
|
26
|
+
const context = {
|
|
27
|
+
file: root,
|
|
28
|
+
source: css,
|
|
29
|
+
compilationFile: root,
|
|
30
|
+
sourceMap,
|
|
31
|
+
graph: { sources: graph.files }
|
|
32
|
+
};
|
|
33
|
+
errorContext = context;
|
|
34
|
+
const finalizedResult = compileCSSManifestGraph(graph, {
|
|
35
|
+
...compileOptions,
|
|
36
|
+
baseManifest,
|
|
37
|
+
from: root,
|
|
38
|
+
root: projectDir,
|
|
39
|
+
onDependency,
|
|
40
|
+
referenceStack: [root],
|
|
41
|
+
resolveReferenceResources: Boolean(referenceFiles?.length),
|
|
42
|
+
mapReferences: (file, text, references) => file === root ? [...hostReferences, ...suppliedReferences ?? resolveReferenceOrigins(text, references, baseFile ?? root, sourceMap)] : references
|
|
43
|
+
});
|
|
44
|
+
if (finalizedResult.stylesheets.length > 1) throw new MasterCSSError({
|
|
45
|
+
code: "CSS_IMPORT_ERROR",
|
|
46
|
+
domain: "compiler",
|
|
47
|
+
message: "This stylesheet retains import or resource boundaries and requires stylesheet asset delivery."
|
|
48
|
+
});
|
|
49
|
+
const outputMap = (code, resources = []) => stylesheetOutputMap(code, [...finalizedResult.outputMappings, ...resources], context, finalizedResult.css.length);
|
|
50
|
+
return {
|
|
51
|
+
compileOptions,
|
|
52
|
+
finalizedResult,
|
|
53
|
+
result: finalizedResult.directives,
|
|
54
|
+
outputMap
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const context = {
|
|
58
|
+
file: baseFile ?? filename,
|
|
59
|
+
source: css,
|
|
60
|
+
compilationFile,
|
|
61
|
+
sourceMap
|
|
62
|
+
};
|
|
63
|
+
errorContext = context;
|
|
64
|
+
const result = compileCSS(compilationSource, {
|
|
65
|
+
...compileOptions,
|
|
66
|
+
from: compilationFile
|
|
67
|
+
});
|
|
68
|
+
if (suppliedReferences) result.references = suppliedReferences;
|
|
69
|
+
else if (sourceMap && result.references) result.references = [...resolveReferenceOrigins(css, result.references, baseFile ?? filename, sourceMap)];
|
|
70
|
+
if (hostReferences.length) result.references = [...hostReferences, ...result.references ?? []];
|
|
71
|
+
const finalizedResult = createManifestFromCSSResult(result, {
|
|
72
|
+
...compileOptions,
|
|
73
|
+
onDependency,
|
|
74
|
+
baseManifest,
|
|
75
|
+
root: projectDir,
|
|
76
|
+
from: filename,
|
|
77
|
+
sourceText: compilationSource,
|
|
78
|
+
resolveReferenceResources: Boolean(referenceFiles?.length)
|
|
79
|
+
});
|
|
80
|
+
const mappings = finalizedResult.outputMappings ?? stylesheetOutputMappings(result.nativeCSS, result.nativeMappings, finalizedResult.generatedMappings);
|
|
81
|
+
const outputMap = (code, resources = []) => stylesheetOutputMap(code, [...mappings, ...resources], context, finalizedResult.css.length);
|
|
82
|
+
return {
|
|
83
|
+
compileOptions,
|
|
84
|
+
finalizedResult,
|
|
85
|
+
result,
|
|
86
|
+
outputMap
|
|
87
|
+
};
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const inputMap = errorContext?.graph?.sourceMappings ? stylesheetInputMap(compilationSource, errorContext) : sourceMap;
|
|
90
|
+
throw mapStylesheetError(error, compilationFile, {
|
|
91
|
+
...options,
|
|
92
|
+
sourceMap: inputMap
|
|
93
|
+
}, compilationSource);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export { compilePreparedStylesheet };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MasterCSSStylesheetCompositionOptions } from "./public.js";
|
|
2
|
+
import { CreateExtractedCSSResult, StylesheetSources } from "./types.js";
|
|
3
|
+
/** One result, scoped to its collection. Class-sensitive compositions always run. */
|
|
4
|
+
declare class StylesheetCompositionCache {
|
|
5
|
+
generation: number;
|
|
6
|
+
private entry?;
|
|
7
|
+
private readonly functions;
|
|
8
|
+
private nextFunction;
|
|
9
|
+
clear(): void;
|
|
10
|
+
private fingerprint;
|
|
11
|
+
get(options: MasterCSSStylesheetCompositionOptions, sources: StylesheetSources): CreateExtractedCSSResult | undefined;
|
|
12
|
+
capture(options: MasterCSSStylesheetCompositionOptions, sources: StylesheetSources): {
|
|
13
|
+
generation: number;
|
|
14
|
+
versions: Map<string, string>;
|
|
15
|
+
} | undefined;
|
|
16
|
+
set(options: MasterCSSStylesheetCompositionOptions, sources: StylesheetSources, result: CreateExtractedCSSResult, captured: ReturnType<StylesheetCompositionCache['capture']>): void;
|
|
17
|
+
}
|
|
18
|
+
export { StylesheetCompositionCache };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
// src/stylesheet/composition-cache.ts
|
|
4
|
+
function fileVersion(file) {
|
|
5
|
+
try {
|
|
6
|
+
return createHash("sha256").update(readFileSync(file)).digest("hex");
|
|
7
|
+
} catch {
|
|
8
|
+
return "missing";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** One result, scoped to its collection. Class-sensitive compositions always run. */
|
|
12
|
+
var StylesheetCompositionCache = class {
|
|
13
|
+
generation = 0;
|
|
14
|
+
entry;
|
|
15
|
+
functions = /* @__PURE__ */ new WeakMap();
|
|
16
|
+
nextFunction = 0;
|
|
17
|
+
clear() {
|
|
18
|
+
this.generation++;
|
|
19
|
+
this.entry = void 0;
|
|
20
|
+
}
|
|
21
|
+
fingerprint(options, sources, dependencies, version = fileVersion) {
|
|
22
|
+
if (options.includeGeneratedCSS !== false || options.pruneNativeCSS || options.onDiagnostic || options.loadSass || options.delivery?.resolveImport) return;
|
|
23
|
+
const hash = createHash("sha256");
|
|
24
|
+
hash.update(JSON.stringify(options.projectDir ?? options.scanner.cwd));
|
|
25
|
+
for (const [id, source] of sources) {
|
|
26
|
+
if (!source.graph || !source.classIndependent) return;
|
|
27
|
+
hash.update(JSON.stringify([id, source]));
|
|
28
|
+
}
|
|
29
|
+
const { scanner: _scanner, signal: _signal, onDependency: _dependency, onDiagnostic: _diagnostic, ...input } = options;
|
|
30
|
+
hash.update(JSON.stringify(input, (_key, value) => {
|
|
31
|
+
if (typeof value !== "function") return value;
|
|
32
|
+
let id = this.functions.get(value);
|
|
33
|
+
if (id === void 0) {
|
|
34
|
+
id = ++this.nextFunction;
|
|
35
|
+
this.functions.set(value, id);
|
|
36
|
+
}
|
|
37
|
+
return id;
|
|
38
|
+
}));
|
|
39
|
+
for (const file of new Set([...sources.values()].flatMap((source) => source.dependencies).concat([...dependencies]))) {
|
|
40
|
+
const content = version(file);
|
|
41
|
+
if (content === void 0) return;
|
|
42
|
+
hash.update(JSON.stringify([file, content]));
|
|
43
|
+
}
|
|
44
|
+
return hash.digest("hex");
|
|
45
|
+
}
|
|
46
|
+
get(options, sources) {
|
|
47
|
+
if (!this.entry || this.fingerprint(options, sources, this.entry.dependencies) !== this.entry.key) return;
|
|
48
|
+
const result = structuredClone(this.entry.result);
|
|
49
|
+
for (const dependency of this.entry.dependencies) {
|
|
50
|
+
options.onDependency?.(dependency);
|
|
51
|
+
if (options.delivery?.onDependency !== options.onDependency) options.delivery?.onDependency?.(dependency);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
capture(options, sources) {
|
|
56
|
+
const versions = /* @__PURE__ */ new Map();
|
|
57
|
+
const dependencies = [...this.entry?.dependencies ?? [], ...options.referenceFiles ?? []];
|
|
58
|
+
return this.fingerprint(options, sources, dependencies, (file) => {
|
|
59
|
+
const version = fileVersion(file);
|
|
60
|
+
versions.set(file, version);
|
|
61
|
+
return version;
|
|
62
|
+
}) ? {
|
|
63
|
+
generation: this.generation,
|
|
64
|
+
versions
|
|
65
|
+
} : void 0;
|
|
66
|
+
}
|
|
67
|
+
set(options, sources, result, captured) {
|
|
68
|
+
if (!captured || captured.generation !== this.generation) return;
|
|
69
|
+
const dependencies = [...new Set([...sources.values()].flatMap((source) => source.dependencies).concat([...result.dependencies ?? []]))];
|
|
70
|
+
const key = this.fingerprint(options, sources, dependencies);
|
|
71
|
+
const before = this.fingerprint(options, sources, dependencies, (file) => captured.versions.get(file));
|
|
72
|
+
this.entry = key && key === before && JSON.stringify(result).length * 2 <= 4194304 ? {
|
|
73
|
+
key,
|
|
74
|
+
dependencies,
|
|
75
|
+
result: structuredClone(result)
|
|
76
|
+
} : void 0;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
export { StylesheetCompositionCache };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { MasterCSSManifest } from "@master/css-schema/manifest";
|
|
2
|
+
import { CompileCSSResult } from "../contracts.js";
|
|
3
|
+
import { CSSOutputMapping } from "@master/css-schema/css-directives";
|
|
4
|
+
import { CSSImportFileResolver } from "../node-imports.js";
|
|
5
|
+
import { CompileStylesheetOptions, CreateExtractedCSSResult, ScannerState, StylesheetSource, StylesheetSources, TransformLocalStylesheetOptions } from "./types.js";
|
|
6
|
+
interface StylesheetDeliveryOptions {
|
|
7
|
+
/** Filesystem owner of a supplied virtual entry source. */
|
|
8
|
+
readonly baseFile?: string;
|
|
9
|
+
/** Serialized source map v3 for original reference origins in the supplied entry. */
|
|
10
|
+
readonly sourceMap?: string;
|
|
11
|
+
/** Final URL of the emitted entry stylesheet. */
|
|
12
|
+
readonly entryURL: string;
|
|
13
|
+
/** Reports attempted filesystem dependencies, including files that are missing. */
|
|
14
|
+
readonly onDependency?: (file: string) => void;
|
|
15
|
+
readonly stylesheetURL: (file: string, variant?: string) => string;
|
|
16
|
+
readonly resourceURL: (file: string) => string;
|
|
17
|
+
/** Standalone sibling assets only; the resulting manifest is not for inline CSS. */
|
|
18
|
+
readonly relativeResourceURLs?: boolean;
|
|
19
|
+
/** Resolve CSS package exports with the Node host and preserve their native rules. */
|
|
20
|
+
readonly resolveNodePackageImports?: boolean;
|
|
21
|
+
/** Async registration only: resolve imports with a build host before Node fallback. */
|
|
22
|
+
readonly resolveImport?: CSSImportFileResolver;
|
|
23
|
+
}
|
|
24
|
+
interface StylesheetResourceAsset {
|
|
25
|
+
readonly file: string;
|
|
26
|
+
readonly href: string;
|
|
27
|
+
}
|
|
28
|
+
/** Compile native resource usage without flattening imports or reading host-owned assets. */
|
|
29
|
+
declare function compileStylesheetMetadata(file: string, source: string, options: CompileStylesheetOptions): {
|
|
30
|
+
manifest: MasterCSSManifest;
|
|
31
|
+
resolutionManifest: MasterCSSManifest;
|
|
32
|
+
directives: CompileCSSResult;
|
|
33
|
+
resources: StylesheetResourceAsset[];
|
|
34
|
+
stylesheets: {
|
|
35
|
+
id: string;
|
|
36
|
+
href: string;
|
|
37
|
+
css: string;
|
|
38
|
+
nativeCSS: string;
|
|
39
|
+
generatedCSS: string;
|
|
40
|
+
outputMappings: CSSOutputMapping[];
|
|
41
|
+
}[];
|
|
42
|
+
} | undefined;
|
|
43
|
+
/** Compile one file and its dependencies for a host that publishes every asset. */
|
|
44
|
+
declare function compileDeliveredFile(file: string, options: CompileStylesheetOptions): {
|
|
45
|
+
manifest: MasterCSSManifest;
|
|
46
|
+
resolutionManifest: MasterCSSManifest;
|
|
47
|
+
directives: CompileCSSResult;
|
|
48
|
+
resources: StylesheetResourceAsset[];
|
|
49
|
+
stylesheets: {
|
|
50
|
+
id: string;
|
|
51
|
+
href: string;
|
|
52
|
+
css: string;
|
|
53
|
+
nativeCSS: string;
|
|
54
|
+
generatedCSS: string;
|
|
55
|
+
outputMappings: CSSOutputMapping[];
|
|
56
|
+
}[];
|
|
57
|
+
entry: string;
|
|
58
|
+
};
|
|
59
|
+
/** Compile supplied local CSS and its imports without flattening their boundaries. */
|
|
60
|
+
declare function compileDeliveredSource(id: string, source: string, options: TransformLocalStylesheetOptions, nativeClasses?: readonly string[]): Promise<{
|
|
61
|
+
manifest: MasterCSSManifest;
|
|
62
|
+
resolutionManifest: MasterCSSManifest;
|
|
63
|
+
directives: CompileCSSResult;
|
|
64
|
+
resources: StylesheetResourceAsset[];
|
|
65
|
+
stylesheets: {
|
|
66
|
+
id: string;
|
|
67
|
+
href: string;
|
|
68
|
+
css: string;
|
|
69
|
+
nativeCSS: string;
|
|
70
|
+
generatedCSS: string;
|
|
71
|
+
outputMappings: CSSOutputMapping[];
|
|
72
|
+
sourceMap: string;
|
|
73
|
+
}[];
|
|
74
|
+
entry: string;
|
|
75
|
+
outputMap: (css: string, mappings: CSSOutputMapping[], file?: string) => string;
|
|
76
|
+
} | undefined>;
|
|
77
|
+
declare function registerDeliveredStylesheet(scanner: ScannerState, sources: StylesheetSources, id: string, source: string, options: CompileStylesheetOptions, inlineImports?: boolean): Promise<{
|
|
78
|
+
notices?: import("@master/css-schema/css-directives").CSSDirectiveNotice[];
|
|
79
|
+
definitionSources?: import("@master/css-schema/css-directives").CSSDefinitionSource[];
|
|
80
|
+
nativeOutput?: import("@master/css-schema/css-directives").CSSNativeOutput;
|
|
81
|
+
outputMappings?: CSSOutputMapping[];
|
|
82
|
+
sourceMap?: string;
|
|
83
|
+
nativeMappings?: CSSOutputMapping[];
|
|
84
|
+
generatedMappings?: CSSOutputMapping[];
|
|
85
|
+
manifestInput: import("@master/css-schema/css-directives").CSSDirectiveManifestInput;
|
|
86
|
+
extractionPolicy: import("@master/css-schema/css-directives").CSSDirectiveExtractionPolicy;
|
|
87
|
+
classNames: string[];
|
|
88
|
+
nativeClassNames: string[];
|
|
89
|
+
nativeCSS: string;
|
|
90
|
+
css: string;
|
|
91
|
+
generatedCSS: string;
|
|
92
|
+
warnings: string[];
|
|
93
|
+
references?: import("@master/css-schema/css-directives").CSSDirectiveReference[];
|
|
94
|
+
styleDefinitions?: import("@master/css-schema/css-directives").CSSDirectiveStyleDefinition[];
|
|
95
|
+
dependencies: string[];
|
|
96
|
+
}>;
|
|
97
|
+
declare function composeDeliveredStylesheets(sources: StylesheetSources, options: CompileStylesheetOptions & {
|
|
98
|
+
manifest?: MasterCSSManifest;
|
|
99
|
+
includeGeneratedCSS?: boolean;
|
|
100
|
+
includeNativeCSS?: boolean;
|
|
101
|
+
includeMasterBaseCSS?: boolean;
|
|
102
|
+
}, classes: readonly string[], styleClasses: (source: StylesheetSource) => readonly string[], inlineImports?: boolean): Required<CreateExtractedCSSResult>;
|
|
103
|
+
export { StylesheetDeliveryOptions, StylesheetResourceAsset, compileDeliveredFile, compileDeliveredSource, compileStylesheetMetadata, composeDeliveredStylesheets, registerDeliveredStylesheet };
|