@master/css-astro 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 +110 -0
- package/dist/core.d.ts +35 -0
- package/dist/core.js +147 -0
- package/dist/external-hydration-manifest.d.ts +2 -0
- package/dist/external-hydration-manifest.js +68 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/internal/src/emitted-globals-module.js +11 -0
- package/dist/internal/src/node.js +7 -0
- package/dist/internal/src/program-module.js +25 -0
- package/dist/internal/src/runtime-bootstrap.js +12 -0
- package/dist/middleware.d.ts +2 -0
- package/dist/middleware.js +6 -0
- package/dist/options.d.ts +11 -0
- package/dist/options.js +14 -0
- package/dist/output-stylesheets.d.ts +4 -0
- package/dist/output-stylesheets.js +24 -0
- package/dist/prerender-stylesheets.d.ts +14 -0
- package/dist/prerender-stylesheets.js +15 -0
- package/dist/runtime-preload.d.ts +2 -0
- package/dist/runtime-preload.js +96 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +43 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<br>
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://css.master.co">
|
|
6
|
+
<picture>
|
|
7
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/33840671/201701649-3bb7d698-abec-4d5f-ac30-ccc4d7bafcd4.svg">
|
|
8
|
+
<source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg">
|
|
9
|
+
<img alt="Master CSS" src="https://user-images.githubusercontent.com/33840671/201703010-77bf2373-9899-40cc-98f5-30cf9b546941.svg" width="100%">
|
|
10
|
+
</picture>
|
|
11
|
+
</a>
|
|
12
|
+
</p>
|
|
13
|
+
<p align="center">Astro integration for Master CSS</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a aria-label="GitHub release (latest by date including pre-releases)" href="https://github.com/master-co/css/releases">
|
|
17
|
+
<picture>
|
|
18
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=212022&label=&style=for-the-badge&logo=github&logoColor=fff">
|
|
19
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github&logoColor=%23000">
|
|
20
|
+
<img alt="NPM Version" src="https://img.shields.io/github/v/release/master-co/css?include_prereleases&color=f6f7f8&label=&style=for-the-badge&logo=github">
|
|
21
|
+
</picture>
|
|
22
|
+
</a>
|
|
23
|
+
<a aria-label="NPM Package" href="https://www.npmjs.com/package/@master/css-astro">
|
|
24
|
+
<picture>
|
|
25
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/npm/dm/@master/css-astro?color=212022&label=%20&logo=npm&style=for-the-badge">
|
|
26
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/npm/dm/@master/css-astro?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
|
|
27
|
+
<img alt="NPM package ( download / month )" src="https://img.shields.io/npm/dm/@master/css-astro?color=f6f7f8&label=%20&logo=npm&style=for-the-badge">
|
|
28
|
+
</picture>
|
|
29
|
+
</a>
|
|
30
|
+
<a aria-label="Discord Community" href="https://discord.gg/sZNKpAAAw6">
|
|
31
|
+
<picture>
|
|
32
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/discord/917780624314613760?color=212022&label=%20&logo=discord&style=for-the-badge">
|
|
33
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
|
|
34
|
+
<img alt="Discord online" src="https://img.shields.io/discord/917780624314613760?color=f6f7f8&label=%20&logo=discord&style=for-the-badge">
|
|
35
|
+
</picture>
|
|
36
|
+
</a>
|
|
37
|
+
<a aria-label="Follow @mastercorg" href="https://twitter.com/mastercorg">
|
|
38
|
+
<picture>
|
|
39
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=212022&logo=twitter&style=for-the-badge">
|
|
40
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
41
|
+
<img alt="Follow @mastercorg" src="https://img.shields.io/static/v1?label=%20&message=twitter&color=f6f7f8&logo=twitter&style=for-the-badge">
|
|
42
|
+
</picture>
|
|
43
|
+
</a>
|
|
44
|
+
<a aria-label="Github Actions" href="https://github.com/master-co/css/actions/workflows/ci-release.yml">
|
|
45
|
+
<picture>
|
|
46
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=212022&logo=githubactions&style=for-the-badge">
|
|
47
|
+
<source media="(prefers-color-scheme: light)" srcset="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
48
|
+
<img alt="Github release actions" src="https://img.shields.io/github/actions/workflow/status/master-co/css/ci-release.yml?branch=rc&label=%20&message=twitter&color=f6f7f8&logo=githubactions&style=for-the-badge&logoColor=%23000">
|
|
49
|
+
</picture>
|
|
50
|
+
</a>
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @master/css-astro
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import { defineConfig } from 'astro/config'
|
|
65
|
+
import masterCSS from '@master/css-astro'
|
|
66
|
+
|
|
67
|
+
export default defineConfig({
|
|
68
|
+
integrations: [
|
|
69
|
+
masterCSS()
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The integration uses `static` mode by default, generating CSS at build time without injecting the browser runtime. Choose `mode: 'progressive'` to register Astro middleware that pre-renders initial CSS into `<style id="master-css">` and injects the runtime script for browser hydration. The runtime downloads its engine and the runtime program only when a page introduces a class that was not pre-rendered. Source extraction for `.astro` files is handled automatically by `@master/css-tooling/source`.
|
|
75
|
+
|
|
76
|
+
In static builds with `mode: 'runtime'`, the integration modulepreloads the runtime script and preloads the emitted runtime program with `<link rel="preload" as="fetch">` when it also injects the runtime script. To omit the browser runtime, choose `static` or `pre-render`; `runtime: false` conflicts with `runtime` and `progressive` modes and is rejected. SSR-only Astro output does not receive these preloads because the integration cannot reliably resolve the final client program asset URL at build time.
|
|
77
|
+
|
|
78
|
+
```css
|
|
79
|
+
@import '@master/css';
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Options
|
|
83
|
+
|
|
84
|
+
The `options` object extends `@master/css-vite` plugin options and is passed to the Astro integration.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
import { defineConfig } from 'astro/config'
|
|
88
|
+
import masterCSS from '@master/css-astro'
|
|
89
|
+
|
|
90
|
+
export default defineConfig({
|
|
91
|
+
integrations: [
|
|
92
|
+
masterCSS({
|
|
93
|
+
mode: 'progressive'
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
})
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For `pre-render` and `progressive` modes, Astro owns the HTML rendering step through `@master/css-astro/middleware`, so you do not need to add `@master/css-server` manually.
|
|
100
|
+
|
|
101
|
+
Default options:
|
|
102
|
+
|
|
103
|
+
| Option | Default | Description |
|
|
104
|
+
| --- | --- | --- |
|
|
105
|
+
| `enabled` | `true` | Enables the integration. |
|
|
106
|
+
| `mode` | `'static'` | Selects static, pre-render, runtime, or progressive rendering. |
|
|
107
|
+
| `scanner` | `{}` | Scanner configuration passed through to the shared Vite pipeline. |
|
|
108
|
+
| `runtime` | `{ enabled: false }` | Enabled by runtime/progressive modes; optional FOUC protection. Explicit enabled values must agree with the mode. |
|
|
109
|
+
|
|
110
|
+
See the [Astro installation guide](https://rc.css.master.co/guide/installation/astro) for a full project setup.
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MasterCSSVitePluginOptions, createMasterCSSVitePlugin } from "@master/css-vite";
|
|
2
|
+
import { AstroIntegration } from "astro";
|
|
3
|
+
import { MasterCSSEmittedGlobals } from "@master/css-schema/emitted-globals";
|
|
4
|
+
import { MasterCSSAstroIntegrationOptions } from "./options.js";
|
|
5
|
+
declare const ASTRO_MIDDLEWARE_ENTRYPOINT = "@master/css-astro/middleware";
|
|
6
|
+
declare const ASTRO_SSR_EXTERNAL: string[];
|
|
7
|
+
declare const ASTRO_RUNTIME_INJECTION = "import \"virtual:master-css-runtime\";";
|
|
8
|
+
type Plugin = ReturnType<typeof createMasterCSSVitePlugin>[number];
|
|
9
|
+
type BuildEnvironment = {
|
|
10
|
+
name: string;
|
|
11
|
+
config: {
|
|
12
|
+
consumer?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/** The emitted-globals plugin's `api` from @master/css-vite. */
|
|
16
|
+
type EmittedGlobalsPluginAPI = {
|
|
17
|
+
finalize?: (environment: BuildEnvironment, emittedGlobals: Required<MasterCSSEmittedGlobals>) => MasterCSSEmittedGlobals;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Astro renders server asset URLs as public paths and moves server assets into
|
|
21
|
+
* the client output before prerendering, so a server bundle cannot import an
|
|
22
|
+
* emitted manifest asset. Server environments therefore receive inline manifests;
|
|
23
|
+
* client environments keep the emitted asset and its preload.
|
|
24
|
+
*/
|
|
25
|
+
declare function inlineServerManifests(plugin: Plugin): Plugin;
|
|
26
|
+
/**
|
|
27
|
+
* Astro links the CSS its server environments process on pages whose runtime
|
|
28
|
+
* the client environment bundles without importing that CSS. Astro builds the
|
|
29
|
+
* server environments first, so the client bundle also counts their emitted
|
|
30
|
+
* globals, as a Vite runtime bundle counts the CSS delivered beside it.
|
|
31
|
+
*/
|
|
32
|
+
declare function deliverServerEmittedGlobals(plugins: readonly Plugin[]): void;
|
|
33
|
+
declare function createAstroVitePlugins(options: MasterCSSVitePluginOptions): import("vite").Plugin<any>[];
|
|
34
|
+
declare function createMasterCSSAstroIntegration(specifiedOptions?: MasterCSSAstroIntegrationOptions): AstroIntegration;
|
|
35
|
+
export { ASTRO_MIDDLEWARE_ENTRYPOINT, ASTRO_RUNTIME_INJECTION, ASTRO_SSR_EXTERNAL, EmittedGlobalsPluginAPI, createAstroVitePlugins, createMasterCSSAstroIntegration, createMasterCSSAstroIntegration as default, deliverServerEmittedGlobals, inlineServerManifests };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { providePrerenderStylesheets } from "./prerender-stylesheets.js";
|
|
2
|
+
import { mergeEmittedGlobals } from "./internal/src/emitted-globals-module.js";
|
|
3
|
+
import { externalizeAstroHydrationManifests } from "./external-hydration-manifest.js";
|
|
4
|
+
import { preloadAstroRuntimeAssets } from "./runtime-preload.js";
|
|
5
|
+
import { describeOutputStylesheets } from "./output-stylesheets.js";
|
|
6
|
+
import { resolveMasterCSSAstroIntegrationOptions } from "./options.js";
|
|
7
|
+
import { createMasterCSSVitePlugin } from "@master/css-vite";
|
|
8
|
+
// src/core.ts
|
|
9
|
+
const ASTRO_MIDDLEWARE_ENTRYPOINT = "@master/css-astro/middleware";
|
|
10
|
+
const ASTRO_SSR_EXTERNAL = ["@master/css-server"];
|
|
11
|
+
const ASTRO_RUNTIME_INJECTION = "import \"virtual:master-css-runtime\";";
|
|
12
|
+
const ASTRO_OMITTED_VITE_PLUGINS = /* @__PURE__ */ new Set([
|
|
13
|
+
"master-css:pre-render",
|
|
14
|
+
"master-css:inject-runtime",
|
|
15
|
+
"master-css:inject-runtime:serve",
|
|
16
|
+
"master-css:runtime-preload",
|
|
17
|
+
"master-css:manifest-preload"
|
|
18
|
+
]);
|
|
19
|
+
const MANIFEST_MODULE_PLUGINS = /* @__PURE__ */ new Set(["master-css:virtual-module:manifest", "master-css:manifest-loader"]);
|
|
20
|
+
const EMITTED_GLOBALS_PLUGIN = "master-css:virtual-module:emitted-globals";
|
|
21
|
+
function withoutAssetEmission(context) {
|
|
22
|
+
return new Proxy(context, { get(target, key) {
|
|
23
|
+
if (key === "emitFile") return void 0;
|
|
24
|
+
const value = Reflect.get(target, key, target);
|
|
25
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
26
|
+
} });
|
|
27
|
+
}
|
|
28
|
+
function inlineServerManifestLoad(plugin) {
|
|
29
|
+
const load = plugin.load;
|
|
30
|
+
if (!load) return plugin;
|
|
31
|
+
const handler = typeof load === "function" ? load : load.handler;
|
|
32
|
+
const inlineLoad = function(...args) {
|
|
33
|
+
return handler.apply(this.environment?.config.consumer === "server" ? withoutAssetEmission(this) : this, args);
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
...plugin,
|
|
37
|
+
load: typeof load === "function" ? inlineLoad : {
|
|
38
|
+
...load,
|
|
39
|
+
handler: inlineLoad
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Astro renders server asset URLs as public paths and moves server assets into
|
|
45
|
+
* the client output before prerendering, so a server bundle cannot import an
|
|
46
|
+
* emitted manifest asset. Server environments therefore receive inline manifests;
|
|
47
|
+
* client environments keep the emitted asset and its preload.
|
|
48
|
+
*/
|
|
49
|
+
function inlineServerManifests(plugin) {
|
|
50
|
+
if (!MANIFEST_MODULE_PLUGINS.has(plugin.name)) return plugin;
|
|
51
|
+
const applyToEnvironment = plugin.applyToEnvironment;
|
|
52
|
+
const applyInlineServerManifests = async function(environment) {
|
|
53
|
+
const applied = applyToEnvironment ? await applyToEnvironment.call(this, environment) : true;
|
|
54
|
+
if (!applied || applied === true || Array.isArray(applied)) return applied;
|
|
55
|
+
return environment.config.consumer === "server" ? inlineServerManifestLoad(applied) : applied;
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
...inlineServerManifestLoad(plugin),
|
|
59
|
+
applyToEnvironment: applyInlineServerManifests
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Astro links the CSS its server environments process on pages whose runtime
|
|
64
|
+
* the client environment bundles without importing that CSS. Astro builds the
|
|
65
|
+
* server environments first, so the client bundle also counts their emitted
|
|
66
|
+
* globals, as a Vite runtime bundle counts the CSS delivered beside it.
|
|
67
|
+
*/
|
|
68
|
+
function deliverServerEmittedGlobals(plugins) {
|
|
69
|
+
const api = plugins.find((plugin) => plugin.name === EMITTED_GLOBALS_PLUGIN)?.api;
|
|
70
|
+
if (!api) return;
|
|
71
|
+
const server = /* @__PURE__ */ new Map();
|
|
72
|
+
api.finalize = (environment, emittedGlobals) => {
|
|
73
|
+
if (environment.config.consumer === "client") return mergeEmittedGlobals(emittedGlobals, ...server.values());
|
|
74
|
+
server.set(environment.name, emittedGlobals);
|
|
75
|
+
return emittedGlobals;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function createAstroVitePlugins(options) {
|
|
79
|
+
const plugins = createMasterCSSVitePlugin(options);
|
|
80
|
+
if (options.mode === "runtime") deliverServerEmittedGlobals(plugins);
|
|
81
|
+
return plugins.filter((plugin) => !ASTRO_OMITTED_VITE_PLUGINS.has(plugin.name)).map(inlineServerManifests);
|
|
82
|
+
}
|
|
83
|
+
function getViteOptions(options) {
|
|
84
|
+
return {
|
|
85
|
+
enabled: options.enabled,
|
|
86
|
+
mode: options.mode,
|
|
87
|
+
scanner: options.scanner,
|
|
88
|
+
pruneNativeCSS: options.pruneNativeCSS,
|
|
89
|
+
runtime: options.runtime
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function createMasterCSSAstroIntegration(specifiedOptions = {}) {
|
|
93
|
+
const options = resolveMasterCSSAstroIntegrationOptions(specifiedOptions);
|
|
94
|
+
if (!options.enabled) return {
|
|
95
|
+
name: "@master/css-astro",
|
|
96
|
+
hooks: {}
|
|
97
|
+
};
|
|
98
|
+
let astroBase;
|
|
99
|
+
let buildOutput;
|
|
100
|
+
let clientDir;
|
|
101
|
+
let outputStylesheets;
|
|
102
|
+
return {
|
|
103
|
+
name: "@master/css-astro",
|
|
104
|
+
hooks: {
|
|
105
|
+
"astro:config:setup": async ({ addMiddleware, injectScript, updateConfig }) => {
|
|
106
|
+
switch (options.mode) {
|
|
107
|
+
case "progressive":
|
|
108
|
+
case "runtime": if (options.injectRuntime) injectScript("page", ASTRO_RUNTIME_INJECTION);
|
|
109
|
+
}
|
|
110
|
+
switch (options.mode) {
|
|
111
|
+
case "pre-render":
|
|
112
|
+
case "progressive": addMiddleware({
|
|
113
|
+
order: "pre",
|
|
114
|
+
entrypoint: ASTRO_MIDDLEWARE_ENTRYPOINT
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
updateConfig({
|
|
118
|
+
build: { inlineStylesheets: "never" },
|
|
119
|
+
vite: {
|
|
120
|
+
define: { __MASTER_CSS_ASTRO_PROGRESSIVE__: JSON.stringify(options.mode === "progressive") },
|
|
121
|
+
plugins: createAstroVitePlugins(getViteOptions(options)),
|
|
122
|
+
ssr: { external: ASTRO_SSR_EXTERNAL },
|
|
123
|
+
build: { rollupOptions: { external: ASTRO_SSR_EXTERNAL } }
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
"astro:config:done": async ({ config, buildOutput: output }) => {
|
|
128
|
+
astroBase = config.base;
|
|
129
|
+
buildOutput = output;
|
|
130
|
+
clientDir = output === "static" ? config.outDir : config.build?.client;
|
|
131
|
+
},
|
|
132
|
+
"astro:build:start": () => {
|
|
133
|
+
outputStylesheets = void 0;
|
|
134
|
+
if (options.mode !== "pre-render" && options.mode !== "progressive") return;
|
|
135
|
+
providePrerenderStylesheets({ stylesheets: () => outputStylesheets ??= describeOutputStylesheets(clientDir, astroBase) });
|
|
136
|
+
},
|
|
137
|
+
"astro:build:done": async ({ dir }) => {
|
|
138
|
+
providePrerenderStylesheets(void 0);
|
|
139
|
+
if (options.mode === "runtime" && options.injectRuntime && buildOutput !== "server") await preloadAstroRuntimeAssets(dir, astroBase);
|
|
140
|
+
switch (options.mode) {
|
|
141
|
+
case "progressive": await externalizeAstroHydrationManifests(dir, astroBase);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
export { ASTRO_MIDDLEWARE_ENTRYPOINT, ASTRO_RUNTIME_INJECTION, ASTRO_SSR_EXTERNAL, createAstroVitePlugins, createMasterCSSAstroIntegration, createMasterCSSAstroIntegration as default, deliverServerEmittedGlobals, inlineServerManifests };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { toHashedManifestAssetFileName } from "./internal/src/node.js";
|
|
2
|
+
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { MASTER_CSS_RUNTIME_STYLE_ID } from "@master/css-schema/runtime-style";
|
|
6
|
+
import { MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE, MASTER_CSS_HYDRATION_MANIFEST_ATTR, MASTER_CSS_HYDRATION_MANIFEST_FILE_BASENAME, MASTER_CSS_HYDRATION_MANIFEST_SCRIPT_ID } from "@master/css-schema/hydration-manifest";
|
|
7
|
+
// src/external-hydration-manifest.ts
|
|
8
|
+
function isMasterCSSRenderedHTML(html) {
|
|
9
|
+
return new RegExp(String.raw`<style\b(?=[^>]*\bid=(["'])${MASTER_CSS_RUNTIME_STYLE_ID}\1)`, "i").test(html);
|
|
10
|
+
}
|
|
11
|
+
function escapeRegExp(source) {
|
|
12
|
+
return source.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13
|
+
}
|
|
14
|
+
function escapeAttributeValue(value) {
|
|
15
|
+
return value.replace(/&/g, "&").replace(/"/g, """);
|
|
16
|
+
}
|
|
17
|
+
function createHydrationManifestScriptPattern(flags) {
|
|
18
|
+
return new RegExp(String.raw`<script\b(?=[^>]*\bid=(["'])${escapeRegExp(MASTER_CSS_HYDRATION_MANIFEST_SCRIPT_ID)}\1)[^>]*>([\s\S]*?)<\/script>`, flags);
|
|
19
|
+
}
|
|
20
|
+
function getInlineMasterCSSHydrationManifestJSON(html) {
|
|
21
|
+
return html.match(createHydrationManifestScriptPattern("i"))?.[2]?.trim();
|
|
22
|
+
}
|
|
23
|
+
function externalizeMasterCSSHydrationManifest(html, source) {
|
|
24
|
+
const stylePattern = new RegExp(String.raw`<style\b(?=[^>]*\bid=(["'])${escapeRegExp(MASTER_CSS_RUNTIME_STYLE_ID)}\1)[^>]*>`, "i");
|
|
25
|
+
const attributePattern = new RegExp(String.raw`\s${escapeRegExp(MASTER_CSS_HYDRATION_MANIFEST_ATTR)}(?:=(?:"[^"]*"|'[^']*'|[^\s>]*))?`, "i");
|
|
26
|
+
return html.replace(createHydrationManifestScriptPattern("gi"), "").replace(stylePattern, (openingTag) => openingTag.replace(attributePattern, "").replace(/>$/, ` ${MASTER_CSS_HYDRATION_MANIFEST_ATTR}="${escapeAttributeValue(source)}">`));
|
|
27
|
+
}
|
|
28
|
+
function toHydrationManifestAssetURL(fileName, base = MASTER_CSS_HYDRATION_MANIFEST_ASSET_BASE) {
|
|
29
|
+
return `${base.replace(/\/?$/, "/")}${fileName}`;
|
|
30
|
+
}
|
|
31
|
+
function toPublicAssetBase(base = "/") {
|
|
32
|
+
return `${base.replace(/\/?$/, "/")}_master-css/hydration/`;
|
|
33
|
+
}
|
|
34
|
+
async function collectHTMLFiles(dir, files = []) {
|
|
35
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
const filePath = join(dir, entry.name);
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
if (entry.name !== "_master-css") await collectHTMLFiles(filePath, files);
|
|
40
|
+
} else if (entry.isFile() && entry.name.endsWith(".html")) files.push(filePath);
|
|
41
|
+
}
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
async function externalizeAstroHydrationManifests(dir, base) {
|
|
45
|
+
const root = typeof dir === "string" ? dir : fileURLToPath(dir);
|
|
46
|
+
const htmlFiles = await collectHTMLFiles(root);
|
|
47
|
+
const writtenFiles = [];
|
|
48
|
+
for (const htmlFile of htmlFiles) {
|
|
49
|
+
const html = await readFile(htmlFile, "utf8");
|
|
50
|
+
if (!isMasterCSSRenderedHTML(html)) continue;
|
|
51
|
+
const json = getInlineMasterCSSHydrationManifestJSON(html);
|
|
52
|
+
if (!json) continue;
|
|
53
|
+
try {
|
|
54
|
+
JSON.parse(json);
|
|
55
|
+
} catch {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const fileName = toHashedManifestAssetFileName(json, MASTER_CSS_HYDRATION_MANIFEST_FILE_BASENAME);
|
|
59
|
+
const outputDir = join(root, "_master-css", "hydration");
|
|
60
|
+
const outputFile = join(outputDir, fileName);
|
|
61
|
+
await mkdir(outputDir, { recursive: true });
|
|
62
|
+
await writeFile(outputFile, json);
|
|
63
|
+
await writeFile(htmlFile, externalizeMasterCSSHydrationManifest(html, toHydrationManifestAssetURL(fileName, toPublicAssetBase(base))));
|
|
64
|
+
writtenFiles.push(outputFile);
|
|
65
|
+
}
|
|
66
|
+
return writtenFiles;
|
|
67
|
+
}
|
|
68
|
+
export { externalizeAstroHydrationManifests };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { MasterCSSAstroIntegrationOptions } from "./options.js";
|
|
2
|
+
import { createMasterCSSAstroIntegration, createMasterCSSAstroIntegration as core_default } from "./core.js";
|
|
3
|
+
export { type MasterCSSAstroIntegrationOptions, createMasterCSSAstroIntegration, core_default as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createMasterCSSAstroIntegration, createMasterCSSAstroIntegration as default } from "./core.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ../internal/src/emitted-globals-module.ts
|
|
2
|
+
/** Count globals that separate stylesheet hosts emit, as runtime engines register them. */
|
|
3
|
+
function mergeEmittedGlobals(...sources) {
|
|
4
|
+
const merged = {
|
|
5
|
+
variables: {},
|
|
6
|
+
keyframes: {}
|
|
7
|
+
};
|
|
8
|
+
for (const source of sources) for (const kind of ["variables", "keyframes"]) for (const [name, count] of Object.entries(source[kind] || {})) if (count) merged[kind][name] = Math.min(4294967295, (merged[kind][name] || 0) + count);
|
|
9
|
+
return merged;
|
|
10
|
+
}
|
|
11
|
+
export { mergeEmittedGlobals };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
// ../internal/src/node.ts
|
|
4
|
+
function toHashedManifestAssetFileName(json, basename = "master-css-manifest") {
|
|
5
|
+
return `${basename}.${createHash("sha256").update(json).digest("hex").slice(0, 8)}.json`;
|
|
6
|
+
}
|
|
7
|
+
export { toHashedManifestAssetFileName };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// ../internal/src/program-module.ts
|
|
2
|
+
const MASTER_CSS_PROGRAM_PRELOAD_REL = "preload";
|
|
3
|
+
const MASTER_CSS_PROGRAM_PRELOAD_AS = "fetch";
|
|
4
|
+
function escapeAttributeValue(value) {
|
|
5
|
+
return value.replace(/&/g, "&").replace(/"/g, """);
|
|
6
|
+
}
|
|
7
|
+
function toProgramPreloadLinkAttrs(href) {
|
|
8
|
+
return {
|
|
9
|
+
rel: MASTER_CSS_PROGRAM_PRELOAD_REL,
|
|
10
|
+
as: MASTER_CSS_PROGRAM_PRELOAD_AS,
|
|
11
|
+
crossorigin: "",
|
|
12
|
+
href
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function toProgramPreloadLinkTag(href) {
|
|
16
|
+
const attrs = toProgramPreloadLinkAttrs(href);
|
|
17
|
+
return [
|
|
18
|
+
"<link",
|
|
19
|
+
`rel="${attrs.rel}"`,
|
|
20
|
+
`as="${attrs.as}"`,
|
|
21
|
+
"crossorigin",
|
|
22
|
+
`href="${escapeAttributeValue(attrs.href)}">`
|
|
23
|
+
].join(" ");
|
|
24
|
+
}
|
|
25
|
+
export { MASTER_CSS_PROGRAM_PRELOAD_AS, MASTER_CSS_PROGRAM_PRELOAD_REL, toProgramPreloadLinkAttrs, toProgramPreloadLinkTag };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// ../internal/src/runtime-bootstrap.ts
|
|
2
|
+
/** Resolve the public delivery contract before any adapter injects code. */
|
|
3
|
+
function resolveIntegrationRuntime(mode, runtime) {
|
|
4
|
+
const options = typeof runtime === "object" ? runtime : { enabled: runtime };
|
|
5
|
+
const enabled = mode === "runtime" || mode === "progressive";
|
|
6
|
+
if (options.enabled !== void 0 && options.enabled !== enabled) throw new TypeError(`Master CSS mode "${mode}" requires runtime.enabled=${enabled}. Select a consistent rendering mode.`);
|
|
7
|
+
return {
|
|
8
|
+
...options,
|
|
9
|
+
enabled
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export { resolveIntegrationRuntime };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createMasterCSSMiddleware } from "./server.js";
|
|
2
|
+
import manifest from "virtual:master-css-manifest";
|
|
3
|
+
import emittedGlobals from "virtual:master-css-emitted-globals";
|
|
4
|
+
// src/middleware.ts
|
|
5
|
+
const onRequest = createMasterCSSMiddleware(manifest, emittedGlobals, __MASTER_CSS_ASTRO_PROGRESSIVE__);
|
|
6
|
+
export { onRequest };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MasterCSSVitePluginOptions } from "@master/css-vite";
|
|
2
|
+
import { MasterCSSIntegrationRuntimeOptions } from "@master/css-schema/integration";
|
|
3
|
+
type MasterCSSAstroIntegrationOptions = MasterCSSVitePluginOptions;
|
|
4
|
+
interface ResolvedMasterCSSAstroIntegrationOptions extends Omit<MasterCSSAstroIntegrationOptions, 'runtime'> {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
mode: NonNullable<MasterCSSAstroIntegrationOptions['mode']>;
|
|
7
|
+
injectRuntime: boolean;
|
|
8
|
+
runtime: MasterCSSIntegrationRuntimeOptions;
|
|
9
|
+
}
|
|
10
|
+
declare function resolveMasterCSSAstroIntegrationOptions(options?: MasterCSSAstroIntegrationOptions): ResolvedMasterCSSAstroIntegrationOptions;
|
|
11
|
+
export { MasterCSSAstroIntegrationOptions, ResolvedMasterCSSAstroIntegrationOptions, resolveMasterCSSAstroIntegrationOptions };
|
package/dist/options.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { resolveIntegrationRuntime } from "./internal/src/runtime-bootstrap.js";
|
|
2
|
+
// src/options.ts
|
|
3
|
+
function resolveMasterCSSAstroIntegrationOptions(options = {}) {
|
|
4
|
+
const mode = options.mode ?? "static";
|
|
5
|
+
const runtime = resolveIntegrationRuntime(mode, options.runtime);
|
|
6
|
+
return {
|
|
7
|
+
...options,
|
|
8
|
+
enabled: options.enabled ?? true,
|
|
9
|
+
mode,
|
|
10
|
+
runtime,
|
|
11
|
+
injectRuntime: runtime.enabled
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export { resolveMasterCSSAstroIntegrationOptions };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { MasterCSSServerStylesheet } from "@master/css-server";
|
|
2
|
+
/** Describe every final stylesheet in Astro's client output for server rendering. */
|
|
3
|
+
declare function describeOutputStylesheets(dir: URL | string, base?: string): Promise<MasterCSSServerStylesheet[]>;
|
|
4
|
+
export { describeOutputStylesheets };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import { join, relative, sep } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { describeLinkedStylesheet } from "@master/css-compiler/stylesheet";
|
|
5
|
+
// src/output-stylesheets.ts
|
|
6
|
+
async function collectStylesheetFiles(dir, files = []) {
|
|
7
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
8
|
+
const file = join(dir, entry.name);
|
|
9
|
+
if (entry.isDirectory()) await collectStylesheetFiles(file, files);
|
|
10
|
+
else if (entry.isFile() && entry.name.endsWith(".css")) files.push(file);
|
|
11
|
+
}
|
|
12
|
+
return files;
|
|
13
|
+
}
|
|
14
|
+
/** Describe every final stylesheet in Astro's client output for server rendering. */
|
|
15
|
+
async function describeOutputStylesheets(dir, base = "/") {
|
|
16
|
+
const root = typeof dir === "string" ? dir : fileURLToPath(dir);
|
|
17
|
+
const files = (await collectStylesheetFiles(root)).sort();
|
|
18
|
+
if (!files.length) return [];
|
|
19
|
+
const prefix = base.replace(/\/?$/, "/");
|
|
20
|
+
const hrefs = files.map((file) => prefix + relative(root, file).split(sep).join("/"));
|
|
21
|
+
const sources = await Promise.all(files.map((file) => readFile(file, "utf8")));
|
|
22
|
+
return files.map((_, index) => describeLinkedStylesheet(sources[index], hrefs[index], hrefs));
|
|
23
|
+
}
|
|
24
|
+
export { describeOutputStylesheets };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MasterCSSServerStylesheet } from "@master/css-server";
|
|
2
|
+
interface PrerenderStylesheets {
|
|
3
|
+
/** Final stylesheets in the client output. */
|
|
4
|
+
stylesheets(): Promise<readonly MasterCSSServerStylesheet[]>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Astro prerenders after it moves the final CSS into the client output, inside
|
|
8
|
+
* the building process. The integration lends the middleware those stylesheets
|
|
9
|
+
* there, keeping the compiler and filesystem out of server bundles; deployed
|
|
10
|
+
* server routes render without them.
|
|
11
|
+
*/
|
|
12
|
+
declare function providePrerenderStylesheets(provider: PrerenderStylesheets | undefined): void;
|
|
13
|
+
declare function prerenderStylesheets(): PrerenderStylesheets | undefined;
|
|
14
|
+
export { PrerenderStylesheets, prerenderStylesheets, providePrerenderStylesheets };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/prerender-stylesheets.ts
|
|
2
|
+
const PRERENDER_STYLESHEETS = Symbol.for("@master/css-astro:prerender-stylesheets");
|
|
3
|
+
/**
|
|
4
|
+
* Astro prerenders after it moves the final CSS into the client output, inside
|
|
5
|
+
* the building process. The integration lends the middleware those stylesheets
|
|
6
|
+
* there, keeping the compiler and filesystem out of server bundles; deployed
|
|
7
|
+
* server routes render without them.
|
|
8
|
+
*/
|
|
9
|
+
function providePrerenderStylesheets(provider) {
|
|
10
|
+
globalThis[PRERENDER_STYLESHEETS] = provider;
|
|
11
|
+
}
|
|
12
|
+
function prerenderStylesheets() {
|
|
13
|
+
return globalThis[PRERENDER_STYLESHEETS];
|
|
14
|
+
}
|
|
15
|
+
export { prerenderStylesheets, providePrerenderStylesheets };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { toProgramPreloadLinkTag } from "./internal/src/program-module.js";
|
|
2
|
+
import { readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, relative, sep } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
// src/runtime-preload.ts
|
|
6
|
+
const RUNTIME_PROGRAM_REFERENCE_PATTERN = /new URL\((["'])([^"']*master-css-program[^"']*\.bin)\1\s*,\s*import\.meta\.url\)\.href/g;
|
|
7
|
+
function escapeRegExp(source) {
|
|
8
|
+
return source.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9
|
+
}
|
|
10
|
+
function toRootPath(dir) {
|
|
11
|
+
return typeof dir === "string" ? dir : fileURLToPath(dir);
|
|
12
|
+
}
|
|
13
|
+
function toPublicBase(base = "/") {
|
|
14
|
+
return `${base || "/"}`.replace(/\/?$/, "/");
|
|
15
|
+
}
|
|
16
|
+
function toPublicAssetHref(root, file, base) {
|
|
17
|
+
const outputPath = relative(root, file).split(sep).join("/");
|
|
18
|
+
return `${toPublicBase(base)}${outputPath.replace(/^\/+/, "")}`;
|
|
19
|
+
}
|
|
20
|
+
function hasProgramPreloadLink(html, href) {
|
|
21
|
+
const quotedHref = escapeRegExp(href);
|
|
22
|
+
return new RegExp(String.raw`<link\b(?=[^>]*\brel=(["'])preload\1)(?=[^>]*\bas=(["'])fetch\2)(?=[^>]*\bhref=(["'])${quotedHref}\3)[^>]*>`, "i").test(html);
|
|
23
|
+
}
|
|
24
|
+
function escapeAttributeValue(value) {
|
|
25
|
+
return value.replace(/&/g, "&").replace(/"/g, """);
|
|
26
|
+
}
|
|
27
|
+
function hasRuntimeScriptPreloadLink(html, href) {
|
|
28
|
+
const quotedHref = escapeRegExp(href);
|
|
29
|
+
return new RegExp(String.raw`<link\b(?=[^>]*\brel=(["'])modulepreload\1)(?=[^>]*\bhref=(["'])${quotedHref}\2)[^>]*>`, "i").test(html);
|
|
30
|
+
}
|
|
31
|
+
function toRuntimeScriptPreloadLinkTag(href) {
|
|
32
|
+
return `<link rel="modulepreload" crossorigin href="${escapeAttributeValue(href)}">`;
|
|
33
|
+
}
|
|
34
|
+
function injectRuntimePreloads(html, runtimeScriptHref, programHref) {
|
|
35
|
+
const tags = [];
|
|
36
|
+
if (runtimeScriptHref && !hasRuntimeScriptPreloadLink(html, runtimeScriptHref)) tags.push(toRuntimeScriptPreloadLinkTag(runtimeScriptHref));
|
|
37
|
+
if (!hasProgramPreloadLink(html, programHref)) tags.push(toProgramPreloadLinkTag(programHref));
|
|
38
|
+
if (!tags.length) return html;
|
|
39
|
+
return html.replace(/<head\b[^>]*>/i, (openingTag) => `${openingTag}${tags.join("")}`);
|
|
40
|
+
}
|
|
41
|
+
async function pathExists(file) {
|
|
42
|
+
try {
|
|
43
|
+
return (await stat(file)).isFile();
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function collectOutputFiles(dir, files = []) {
|
|
49
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
50
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
51
|
+
const filePath = join(dir, entry.name);
|
|
52
|
+
if (entry.isDirectory()) await collectOutputFiles(filePath, files);
|
|
53
|
+
else if (entry.isFile()) files.push(filePath);
|
|
54
|
+
}
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
57
|
+
function isProgramAssetFile(file) {
|
|
58
|
+
const name = basename(file);
|
|
59
|
+
return name.startsWith("master-css-program") && name.endsWith(".bin");
|
|
60
|
+
}
|
|
61
|
+
async function findRuntimePreloadAssets(files) {
|
|
62
|
+
for (const file of files) {
|
|
63
|
+
if (!file.endsWith(".js")) continue;
|
|
64
|
+
const source = await readFile(file, "utf8");
|
|
65
|
+
for (const match of source.matchAll(RUNTIME_PROGRAM_REFERENCE_PATTERN)) {
|
|
66
|
+
const specifier = match[2];
|
|
67
|
+
if (!specifier) continue;
|
|
68
|
+
const programFile = join(dirname(file), specifier);
|
|
69
|
+
if (await pathExists(programFile)) return {
|
|
70
|
+
programFile,
|
|
71
|
+
runtimeScriptFile: file
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const programFile = files.find(isProgramAssetFile);
|
|
76
|
+
if (!programFile) return;
|
|
77
|
+
return { programFile };
|
|
78
|
+
}
|
|
79
|
+
async function preloadAstroRuntimeAssets(dir, base) {
|
|
80
|
+
const root = toRootPath(dir);
|
|
81
|
+
const files = await collectOutputFiles(root);
|
|
82
|
+
const assets = await findRuntimePreloadAssets(files);
|
|
83
|
+
if (!assets) return [];
|
|
84
|
+
const programHref = toPublicAssetHref(root, assets.programFile, base);
|
|
85
|
+
const runtimeScriptHref = assets.runtimeScriptFile ? toPublicAssetHref(root, assets.runtimeScriptFile, base) : void 0;
|
|
86
|
+
const updatedFiles = [];
|
|
87
|
+
for (const htmlFile of files.filter((file) => file.endsWith(".html"))) {
|
|
88
|
+
const html = await readFile(htmlFile, "utf8");
|
|
89
|
+
const nextHTML = injectRuntimePreloads(html, runtimeScriptHref, programHref);
|
|
90
|
+
if (nextHTML === html) continue;
|
|
91
|
+
await writeFile(htmlFile, nextHTML);
|
|
92
|
+
updatedFiles.push(htmlFile);
|
|
93
|
+
}
|
|
94
|
+
return updatedFiles;
|
|
95
|
+
}
|
|
96
|
+
export { preloadAstroRuntimeAssets };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MasterCSSManifest } from "@master/css-schema/manifest";
|
|
2
|
+
import { MiddlewareHandler } from "astro";
|
|
3
|
+
import { MasterCSSEmittedGlobals } from "@master/css-schema/emitted-globals";
|
|
4
|
+
declare function isHTMLResponse(response: Response): boolean;
|
|
5
|
+
declare function createResponse(response: Response, body: BodyInit | null): Response;
|
|
6
|
+
declare function renderResponse(response: Response, manifest: MasterCSSManifest): Promise<Response>;
|
|
7
|
+
declare function createMasterCSSMiddleware(manifest: MasterCSSManifest, emittedGlobals?: MasterCSSEmittedGlobals, hydrate?: boolean): MiddlewareHandler;
|
|
8
|
+
export { createMasterCSSMiddleware, createResponse, isHTMLResponse, renderResponse };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { prerenderStylesheets } from "./prerender-stylesheets.js";
|
|
2
|
+
import { createServerRenderer, renderHTML } from "@master/css-server";
|
|
3
|
+
// src/server.ts
|
|
4
|
+
const BODYLESS_STATUSES = /* @__PURE__ */ new Set([
|
|
5
|
+
204,
|
|
6
|
+
205,
|
|
7
|
+
304
|
|
8
|
+
]);
|
|
9
|
+
function isHTMLResponse(response) {
|
|
10
|
+
return response.headers.get("content-type")?.toLowerCase().includes("text/html") || false;
|
|
11
|
+
}
|
|
12
|
+
function createResponse(response, body) {
|
|
13
|
+
const headers = new Headers(response.headers);
|
|
14
|
+
headers.delete("content-length");
|
|
15
|
+
return new Response(body, {
|
|
16
|
+
headers,
|
|
17
|
+
status: response.status,
|
|
18
|
+
statusText: response.statusText
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function renderResponse(response, manifest) {
|
|
22
|
+
if (BODYLESS_STATUSES.has(response.status) || !isHTMLResponse(response)) return response;
|
|
23
|
+
return createResponse(response, renderHTML(await response.text(), {
|
|
24
|
+
manifest,
|
|
25
|
+
hydrationManifest: "inject"
|
|
26
|
+
}).html);
|
|
27
|
+
}
|
|
28
|
+
function createMasterCSSMiddleware(manifest, emittedGlobals = {}, hydrate = true) {
|
|
29
|
+
const renderer = createServerRenderer({
|
|
30
|
+
manifest,
|
|
31
|
+
emittedGlobals
|
|
32
|
+
});
|
|
33
|
+
return async (context, next) => {
|
|
34
|
+
const response = await next();
|
|
35
|
+
if (BODYLESS_STATUSES.has(response.status) || !isHTMLResponse(response)) return response;
|
|
36
|
+
const prerender = context.isPrerendered ? prerenderStylesheets() : void 0;
|
|
37
|
+
return createResponse(response, renderer.renderHTML(await response.text(), {
|
|
38
|
+
hydrationManifest: hydrate ? "inject" : false,
|
|
39
|
+
stylesheets: await prerender?.stylesheets()
|
|
40
|
+
}).html);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export { createMasterCSSMiddleware, createResponse, isHTMLResponse, renderResponse };
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@master/css-astro",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": "^24"
|
|
6
|
+
},
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"description": "Astro integration for Master CSS",
|
|
9
|
+
"author": "Aoyue Design LLC.",
|
|
10
|
+
"homepage": "https://css.master.co",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/master-co/css/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/master-co/css.git",
|
|
17
|
+
"directory": "packages/astro"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"plugin",
|
|
21
|
+
"integration",
|
|
22
|
+
"astro",
|
|
23
|
+
"build tools",
|
|
24
|
+
"static rendering",
|
|
25
|
+
"static",
|
|
26
|
+
"runtime",
|
|
27
|
+
"css runtime",
|
|
28
|
+
"css",
|
|
29
|
+
"mastercss",
|
|
30
|
+
"astro-plugin"
|
|
31
|
+
],
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./middleware": {
|
|
41
|
+
"types": "./dist/middleware.d.ts",
|
|
42
|
+
"import": "./dist/middleware.js",
|
|
43
|
+
"default": "./dist/middleware.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public",
|
|
51
|
+
"provenance": true
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"astro": ">=5",
|
|
55
|
+
"vite": ">=6"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@master/css": "0.0.0-site.1793659883.g69c9aebcf628",
|
|
59
|
+
"@master/css-compiler": "0.0.0-site.1793659883.g69c9aebcf628",
|
|
60
|
+
"@master/css-server": "0.0.0-site.1793659883.g69c9aebcf628",
|
|
61
|
+
"@master/css-vite": "0.0.0-site.1793659883.g69c9aebcf628",
|
|
62
|
+
"@master/css-schema": "0.0.0-site.1793659883.g69c9aebcf628"
|
|
63
|
+
},
|
|
64
|
+
"version": "0.0.0-site.1793659883.g69c9aebcf628",
|
|
65
|
+
"gitHead": "69c9aebcf628eb529001b9fa1b3536306f1b139e"
|
|
66
|
+
}
|