@kirana-style/rolldown 0.1.0 → 0.2.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0](https://github.com/kirana-style/kirana/compare/v0.1.0...v0.2.0) (2026-10-15)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * one command name, kirana-style ([#29](https://github.com/kirana-style/kirana/issues/29))
9
+
10
+ ### Features
11
+
12
+ * **editor:** real editor output on the site, open vsx trusted publishing ([#21](https://github.com/kirana-style/kirana/issues/21)) ([350fa4e](https://github.com/kirana-style/kirana/commit/350fa4ec0d8054a082d6c7dcdae2b5be53f8d98a))
13
+ * one command name, kirana-style ([#29](https://github.com/kirana-style/kirana/issues/29)) ([b3f3154](https://github.com/kirana-style/kirana/commit/b3f3154662589dd1bd43fd0ff2341acf4f3df628))
14
+ * **site:** paper, ink, scenery and type for one identity ([#27](https://github.com/kirana-style/kirana/issues/27)) ([5da3c6f](https://github.com/kirana-style/kirana/commit/5da3c6f0f1c8cbfdb450b36a6609a3ab4b20e358))
15
+ * **site:** reorganise the homepage, product pages and docs ([#28](https://github.com/kirana-style/kirana/issues/28)) ([88b5209](https://github.com/kirana-style/kirana/commit/88b52093488b2aa0112b458ca04b836c83d03954))
16
+ * **site:** scenery gradients, logo downloads, pixel k, glass icons ([#25](https://github.com/kirana-style/kirana/issues/25)) ([2953dc1](https://github.com/kirana-style/kirana/commit/2953dc126f47b68257ebfdb33c61992984708c49))
17
+
18
+
19
+ ### Bug fixes
20
+
21
+ * hold emnapi at 2.0.0-alpha.6, the wasi engine fails on the beta ([#26](https://github.com/kirana-style/kirana/issues/26)) ([8aa33e1](https://github.com/kirana-style/kirana/commit/8aa33e1dbccaefa15b87f6487ac0a346bbf6581a))
22
+ * settle the ember dev check, resolve code scanning findings ([#23](https://github.com/kirana-style/kirana/issues/23)) ([0c266c8](https://github.com/kirana-style/kirana/commit/0c266c8428c1453892beeeb5f98918cbc0eae6ff))
23
+ * **site:** keep syntax colours in the production build ([#22](https://github.com/kirana-style/kirana/issues/22)) ([621f2fc](https://github.com/kirana-style/kirana/commit/621f2fcf67dada773ca66110e295ab7ac5605f56))
24
+
25
+
26
+ ### Documentation
27
+
28
+ * fix the extension's settings table ([#13](https://github.com/kirana-style/kirana/issues/13)) ([457e06d](https://github.com/kirana-style/kirana/commit/457e06d12f9e3b005e0820aab36faac5bf3f80b3))
29
+
30
+
31
+ ### Dependencies
32
+
33
+ * bump the minor-and-patch group across 1 directory with 3 updates ([#19](https://github.com/kirana-style/kirana/issues/19)) ([7ea00ed](https://github.com/kirana-style/kirana/commit/7ea00edcc5cc02b9ab5e41b13f152ae344ea448f))
34
+ * emnapi 2.0.0-beta.1, minor and patch updates ([#24](https://github.com/kirana-style/kirana/issues/24)) ([a399fa7](https://github.com/kirana-style/kirana/commit/a399fa78e53dcfd7f41f249ccee1133809e66544))
35
+
36
+ ## [0.1.0](https://github.com/kirana-style/kirana/compare/v0.1.0...v0.1.0) (2026-10-13)
37
+
38
+
39
+ ### Features
40
+
41
+ * kirana goes public — write objects, read classes, ship css ([79732ed](https://github.com/kirana-style/kirana/commit/79732edd5cab419169ab74ad59e1c70053dfa57d))
42
+
43
+
44
+ ### Dependencies
45
+
46
+ * bump the minor-and-patch group in /packages/kirana with 6 updates ([#10](https://github.com/kirana-style/kirana/issues/10)) ([0deaf9f](https://github.com/kirana-style/kirana/commit/0deaf9f3e75ebc377d764c294250bd2577d53844))
47
+ * bump the oxc group in /packages/kirana with 7 updates ([#9](https://github.com/kirana-style/kirana/issues/9)) ([a3ca94c](https://github.com/kirana-style/kirana/commit/a3ca94c170b2ca49c9691abf5ad48c3ef4ac8620))
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kirana authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kirana-style/rolldown",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Kirana for Rolldown: compiles modules and emits the stylesheet.",
5
5
  "license": "MIT",
6
6
  "author": "The Kirana authors",
@@ -14,6 +14,9 @@
14
14
  "url": "https://github.com/kirana-style/kirana/issues"
15
15
  },
16
16
  "type": "module",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
17
20
  "exports": {
18
21
  ".": {
19
22
  "types": "./src/index.d.ts",
@@ -22,8 +25,8 @@
22
25
  "./package.json": "./package.json"
23
26
  },
24
27
  "dependencies": {
25
- "@kirana-style/compiler": "0.1.0",
26
- "@kirana-style/core": "0.1.0"
28
+ "@kirana-style/compiler": "0.2.0",
29
+ "@kirana-style/core": "0.2.0"
27
30
  },
28
31
  "peerDependencies": {
29
32
  "rolldown": "^1.2.12"
@@ -39,6 +42,8 @@
39
42
  "*.d.ts",
40
43
  "*.css",
41
44
  "README.md",
45
+ "CHANGELOG.md",
46
+ "LICENSE",
42
47
  "builders.json",
43
48
  "schemas",
44
49
  "gatsby-node.mjs",
package/src/index.d.ts CHANGED
@@ -1,102 +1,93 @@
1
- /**
2
- * The Rolldown host adapter (KRN-INT-001, KRN-INT-002). It selects modules, forwards transform
3
- * results, emits the stylesheet entry and forwards file changes to the Driver; it never interprets
4
- * styles (D-028).
5
- *
6
- * The Vite adapter is this plugin plus Vite's dev-server hooks, because Vite's plugin API extends
7
- * Rolldown's: one implementation of the build path serves both hosts. The one difference is CSS:
8
- * Vite bundles it, so the stylesheet entry is a placeholder Vite processes and the plugin fills in;
9
- * Rolldown alone does not, so the plugin emits the stylesheet as an asset of its own.
10
- */
11
- import { Driver } from "@kirana-style/compiler";
12
- import type { DriverOptions } from "@kirana-style/compiler";
13
- import type { KiranaConfig } from "@kirana-style/core/config";
14
- import type { OutputBundle, Plugin } from "rolldown";
1
+ import { Driver, DriverOptions } from "@kirana-style/compiler";
2
+ import { KiranaConfig } from "@kirana-style/core/config";
3
+ import { OutputBundle, Plugin } from "rolldown";
4
+ //#region src/index.d.ts
15
5
  export type KiranaRolldownOptions = {
16
- /** The project root: where `kirana.config.*` and `@kirana-style/core` are found. Default: the working directory. */
17
- root?: string;
18
- /** Options that override `kirana.config.*`. */
19
- config?: KiranaConfig;
20
- /** Report `info` diagnostics (such as `dynamic-bridged`) as warnings. */
21
- reportInfo?: boolean;
22
- /**
23
- * Where the stylesheet is written in the output, when Rolldown builds on its own. Rolldown does
24
- * not bundle CSS, so importing `@kirana-style/core/stylesheet.css` yields this name and the finished
25
- * stylesheet is emitted under it; link it from your HTML. Default `kirana.css`. Under Vite, which
26
- * bundles CSS, the stylesheet follows Vite's asset naming instead.
27
- */
28
- fileName?: string;
29
- /** Injected Driver options (tests). */
30
- driver?: Pick<DriverOptions, "native" | "importModule">;
6
+ /** The project root: where `kirana.config.*` and `@kirana-style/core` are found. Default: the working directory. */
7
+ root?: string;
8
+ /** Options that override `kirana.config.*`. */
9
+ config?: KiranaConfig;
10
+ /** Report `info` diagnostics (such as `dynamic-bridged`) as warnings. */
11
+ reportInfo?: boolean;
12
+ /**
13
+ * Where the stylesheet is written in the output, when Rolldown builds on its own. Rolldown does
14
+ * not bundle CSS, so importing `@kirana-style/core/stylesheet.css` yields this name and the finished
15
+ * stylesheet is emitted under it; link it from your HTML. Default `kirana.css`. Under Vite, which
16
+ * bundles CSS, the stylesheet follows Vite's asset naming instead.
17
+ */
18
+ fileName?: string;
19
+ /** Injected Driver options (tests). */
20
+ driver?: Pick<DriverOptions, "native" | "importModule">;
31
21
  };
32
22
  /** What a host that extends this plugin supplies. */
33
23
  export type Host = {
34
- /** True while a dev server serves the live stylesheet instead of the placeholder. */
35
- development?: () => boolean;
36
- /** A transform changed the stylesheet. */
37
- cssChanged?: () => void;
38
- /** The host bundles CSS (Vite): the entry is a placeholder stylesheet it processes like any other. */
39
- bundlesCss?: boolean;
40
- /**
41
- * False when something later renames the finished stylesheet itself (`@kirana-style/astro`, because
42
- * Astro links each page's CSS by the name it recorded before `generateBundle`): the asset is filled
43
- * where it is, and its name is added to `filled`.
44
- */
45
- renames?: boolean;
24
+ /** True while a dev server serves the live stylesheet instead of the placeholder. */
25
+ development?: () => boolean;
26
+ /** A transform changed the stylesheet. */
27
+ cssChanged?: () => void;
28
+ /** The host bundles CSS (Vite): the entry is a placeholder stylesheet it processes like any other. */
29
+ bundlesCss?: boolean;
30
+ /**
31
+ * False when something later renames the finished stylesheet itself (`@kirana-style/astro`, because
32
+ * Astro links each page's CSS by the name it recorded before `generateBundle`): the asset is filled
33
+ * where it is, and its name is added to `filled`.
34
+ */
35
+ renames?: boolean;
46
36
  };
47
37
  /**
48
38
  * The plugin, with the session and the settings a host that extends it may change (the Vite
49
39
  * adapter sets the root from Vite's resolved configuration).
50
40
  */
51
41
  export declare function createKirana(options?: KiranaRolldownOptions, host?: Host): {
52
- plugin: {
53
- name: string;
54
- buildStart(): Promise<void>;
55
- load: {
56
- filter: {
57
- id: RegExp[];
58
- };
59
- handler(this: import("rolldown").PluginContext, id: string): Promise<string | {
60
- code: string;
61
- map: string | undefined;
62
- moduleType?: undefined;
63
- } | {
64
- map?: undefined;
65
- code: string;
66
- moduleType: "js";
67
- } | null>;
68
- };
69
- transform: {
70
- filter: {
71
- id: {
72
- include: RegExp;
73
- exclude: RegExp[];
74
- };
75
- code: RegExp;
76
- };
77
- handler(this: import("rolldown").TransformPluginContext, code: string, id: string): Promise<{
78
- code: string;
79
- map: string | undefined;
80
- } | null>;
81
- };
82
- /** A watch rebuild: modules that read the changed file's tokens or relations compile again. */
83
- watchChange(id: string): Promise<void>;
84
- buildEnd(this: import("rolldown").PluginContext): Promise<void>;
85
- generateBundle: {
86
- order: "pre";
87
- handler(this: import("rolldown").PluginContext, _output: import("rolldown").NormalizedOutputOptions, bundle: OutputBundle): Promise<void>;
42
+ plugin: {
43
+ name: string;
44
+ buildStart(): Promise<void>;
45
+ load: {
46
+ filter: {
47
+ id: RegExp[];
48
+ };
49
+ handler(this: import("rolldown").PluginContext, id: string): Promise<string | {
50
+ code: string;
51
+ map: string | undefined;
52
+ moduleType?: undefined;
53
+ } | {
54
+ map?: undefined;
55
+ code: string;
56
+ moduleType: "js";
57
+ } | null>;
58
+ };
59
+ transform: {
60
+ filter: {
61
+ id: {
62
+ include: RegExp;
63
+ exclude: RegExp[];
88
64
  };
65
+ code: RegExp;
66
+ };
67
+ handler(this: import("rolldown").TransformPluginContext, code: string, id: string): Promise<{
68
+ code: string;
69
+ map: string | undefined;
70
+ } | null>;
89
71
  };
90
- session: () => Promise<Driver>;
91
- state: {
92
- root: string;
93
- stylesheetFile: string;
72
+ /** A watch rebuild: modules that read the changed file's tokens or relations compile again. */
73
+ watchChange(id: string): Promise<void>;
74
+ buildEnd(this: import("rolldown").PluginContext): Promise<void>;
75
+ generateBundle: {
76
+ order: "pre";
77
+ handler(this: import("rolldown").PluginContext, _output: import("rolldown").NormalizedOutputOptions, bundle: OutputBundle): Promise<void>;
94
78
  };
95
- filled: Set<string>;
96
- fill: (bundle: OutputBundle, emitFile: (file: {
97
- type: "asset";
98
- fileName: string;
99
- source: string;
100
- }) => unknown) => Promise<void>;
79
+ };
80
+ session: () => Promise<Driver>;
81
+ state: {
82
+ root: string;
83
+ stylesheetFile: string;
84
+ };
85
+ filled: Set<string>;
86
+ fill: (bundle: OutputBundle, emitFile: (file: {
87
+ type: "asset";
88
+ fileName: string;
89
+ source: string;
90
+ }) => unknown) => Promise<void>;
101
91
  };
102
92
  export default function kirana(options?: KiranaRolldownOptions): Plugin;
93
+ //#endregion
package/src/index.js CHANGED
@@ -1,184 +1,167 @@
1
- /**
2
- * The Rolldown host adapter (KRN-INT-001, KRN-INT-002). It selects modules, forwards transform
3
- * results, emits the stylesheet entry and forwards file changes to the Driver; it never interprets
4
- * styles (D-028).
5
- *
6
- * The Vite adapter is this plugin plus Vite's dev-server hooks, because Vite's plugin API extends
7
- * Rolldown's: one implementation of the build path serves both hosts. The one difference is CSS:
8
- * Vite bundles it, so the stylesheet entry is a placeholder Vite processes and the plugin fills in;
9
- * Rolldown alone does not, so the plugin emits the stylesheet as an asset of its own.
10
- */
11
1
  import { COMPONENT, Driver } from "@kirana-style/compiler";
12
- import { ASSET_QUERY, PLACEHOLDER, SCRIPT, STYLE_BEARING, cleanId, createReporter, fillStylesheet, renameAsset, stylesheetPath, } from "@kirana-style/compiler/host";
2
+ import { ASSET_QUERY, PLACEHOLDER, SCRIPT, STYLE_BEARING, cleanId, createReporter, fillStylesheet, renameAsset, stylesheetPath } from "@kirana-style/compiler/host";
13
3
  import { readFile } from "node:fs/promises";
14
4
  import path from "node:path";
5
+ //#region src/index.ts
6
+ /**
7
+ * The Rolldown host adapter (KRN-INT-001, KRN-INT-002). It selects modules, forwards transform
8
+ * results, emits the stylesheet entry and forwards file changes to the Driver; it never interprets
9
+ * styles (D-028).
10
+ *
11
+ * The Vite adapter is this plugin plus Vite's dev-server hooks, because Vite's plugin API extends
12
+ * Rolldown's: one implementation of the build path serves both hosts. The one difference is CSS:
13
+ * Vite bundles it, so the stylesheet entry is a placeholder Vite processes and the plugin fills in;
14
+ * Rolldown alone does not, so the plugin emits the stylesheet as an asset of its own.
15
+ */
15
16
  /** A request for part of a Vue, Svelte or Astro component, which carries a query. */
16
17
  const COMPONENT_PART = /\.(?:vue|svelte|astro)\?/;
17
18
  /**
18
- * The plugin, with the session and the settings a host that extends it may change (the Vite
19
- * adapter sets the root from Vite's resolved configuration).
20
- */
21
- export function createKirana(options = {}, host = {}) {
22
- const state = { root: options.root ?? process.cwd(), stylesheetFile: "" };
23
- let driver;
24
- const reporter = createReporter(options);
25
- const renamed = new Map();
26
- /** Stylesheet assets filled in place (`Host.renames` false), by output file name. */
27
- const filled = new Set();
28
- const development = () => host.development?.() ?? false;
29
- const fileName = options.fileName ?? "kirana.css";
30
- const session = () => {
31
- driver ??= Driver.create({
32
- root: state.root,
33
- config: options.config,
34
- ...options.driver,
35
- });
36
- return driver;
37
- };
38
- const stylesheetFile = () => (state.stylesheetFile ||= stylesheetPath(state.root));
39
- const plugin = {
40
- name: "kirana",
41
- async buildStart() {
42
- await session();
43
- },
44
- load: {
45
- // No `node_modules` exclusion here: in an installed app the stylesheet entry lives there.
46
- filter: { id: [/stylesheet\.css/, COMPONENT] },
47
- async handler(id) {
48
- // A Vue, Svelte or Astro component is compiled as it is read, before any framework plugin's
49
- // `transform` — Astro's compiles `.astro` files ahead of every user plugin, so a transform
50
- // would only ever see its output (design-notes/sfc-masking.md).
51
- if (COMPONENT.test(id)) {
52
- // An installed component is compiled only when its package is in `libraries`.
53
- const compiler = await session();
54
- if (!compiler.compiles(id))
55
- return null;
56
- const source = await readFile(id, "utf8");
57
- const result = await compiler.transformComponent(id, source);
58
- for (const dependency of result.dependencies)
59
- this.addWatchFile(dependency);
60
- reporter.module(this, id, source, result.diagnostics);
61
- if (result.cssChanged)
62
- host.cssChanged?.();
63
- return result.code === undefined
64
- ? null
65
- : { code: result.code, map: result.map };
66
- }
67
- if (cleanId(id) !== stylesheetFile())
68
- return null;
69
- // Rolldown alone: the import is a module naming the file emitted at the end of the build.
70
- if (!host.bundlesCss) {
71
- return {
72
- code: `export default ${JSON.stringify(fileName)}`,
73
- moduleType: "js",
74
- };
75
- }
76
- // `?inline` asks for the stylesheet as a string: in development that is the live stylesheet
77
- // (SvelteKit's server render inlines CSS this way). `?url` and `?raw`, and `?inline` in a
78
- // build, are Vite's to answer from the file.
79
- if (ASSET_QUERY.test(id)) {
80
- return development() && /[?&]inline\b/.test(id)
81
- ? (await session()).stylesheet(false)
82
- : null;
83
- }
84
- return development() ? (await session()).stylesheet(false) : PLACEHOLDER;
85
- },
86
- },
87
- transform: {
88
- filter: {
89
- id: {
90
- include: SCRIPT,
91
- // A framework's own requests for a component's parts (`Card.vue?vue&type=script&lang.ts`)
92
- // hold what it derived from the component, which `load` compiled already.
93
- // Installed packages are excluded in the handler, which knows `libraries`.
94
- exclude: [ASSET_QUERY, COMPONENT_PART],
95
- },
96
- code: STYLE_BEARING,
97
- },
98
- async handler(code, id) {
99
- const file = cleanId(id);
100
- const compiler = await session();
101
- if (!compiler.compiles(file))
102
- return null;
103
- const result = compiler.transform(file, code);
104
- for (const dependency of result.dependencies)
105
- this.addWatchFile(dependency);
106
- reporter.module(this, file, code, result.diagnostics);
107
- if (result.cssChanged)
108
- host.cssChanged?.();
109
- return result.code === undefined
110
- ? null
111
- : { code: result.code, map: result.map };
112
- },
113
- },
114
- /** A watch rebuild: modules that read the changed file's tokens or relations compile again. */
115
- async watchChange(id) {
116
- ;
117
- (await session()).invalidate(id);
118
- },
119
- async buildEnd() {
120
- if (development())
121
- return;
122
- reporter.project(this, state.root, (await session()).diagnostics());
123
- },
124
- // First, so every plugin that reads CSS assets reads the finished stylesheet: Astro inlines
125
- // small stylesheets into its pages in its own `generateBundle`. Vite writes HTML later from each
126
- // chunk's `viteMetadata.importedCss`, which is renamed here along with the asset.
127
- generateBundle: {
128
- order: "pre",
129
- async handler(_output, bundle) {
130
- if (!host.bundlesCss) {
131
- const css = (await session()).stylesheet(true);
132
- this.emitFile({ type: "asset", fileName, source: css });
133
- return;
134
- }
135
- await fill(bundle, this.emitFile.bind(this));
136
- },
137
- },
138
- };
139
- /**
140
- * Fills every stylesheet asset still holding the placeholder, renaming it by content unless the
141
- * host keeps names, and points the chunks and assets that named it at the new name. A second pass
142
- * finds nothing to do, so a host may run it again later in `generateBundle` for assets another
143
- * plugin added after the first pass (Qwik's).
144
- */
145
- const fill = async (bundle, emitFile) => {
146
- const css = (await session()).stylesheet(true);
147
- for (const [key, asset] of Object.entries(bundle)) {
148
- if (asset.type !== "asset")
149
- continue;
150
- const source = fillStylesheet(String(asset.source), css);
151
- if (source === undefined)
152
- continue;
153
- if (host.renames === false) {
154
- asset.source = source;
155
- filled.add(asset.fileName);
156
- continue;
157
- }
158
- const hashed = renamed.get(asset.fileName) ?? renameAsset(asset.fileName, source);
159
- renamed.set(asset.fileName, hashed);
160
- delete bundle[key];
161
- emitFile({ type: "asset", fileName: hashed, source });
162
- }
163
- // Every rename so far, not only this pass's: a server bundle names the client's asset.
164
- for (const [from, to] of renamed) {
165
- const oldBase = path.posix.basename(from);
166
- const newBase = path.posix.basename(to);
167
- for (const file of Object.values(bundle)) {
168
- if (file.type === "chunk") {
169
- file.code = file.code.replaceAll(oldBase, newBase);
170
- const imported = file.viteMetadata?.importedCss;
171
- if (imported?.delete(from))
172
- imported.add(to);
173
- }
174
- else if (typeof file.source === "string") {
175
- file.source = file.source.replaceAll(oldBase, newBase);
176
- }
177
- }
178
- }
179
- };
180
- return { plugin, session, state, filled, fill };
19
+ * The plugin, with the session and the settings a host that extends it may change (the Vite
20
+ * adapter sets the root from Vite's resolved configuration).
21
+ */
22
+ function createKirana(options = {}, host = {}) {
23
+ const state = {
24
+ root: options.root ?? process.cwd(),
25
+ stylesheetFile: ""
26
+ };
27
+ let driver;
28
+ const reporter = createReporter(options);
29
+ const renamed = /* @__PURE__ */ new Map();
30
+ /** Stylesheet assets filled in place (`Host.renames` false), by output file name. */
31
+ const filled = /* @__PURE__ */ new Set();
32
+ const development = () => host.development?.() ?? false;
33
+ const fileName = options.fileName ?? "kirana.css";
34
+ const session = () => {
35
+ driver ??= Driver.create({
36
+ root: state.root,
37
+ config: options.config,
38
+ ...options.driver
39
+ });
40
+ return driver;
41
+ };
42
+ const stylesheetFile = () => state.stylesheetFile ||= stylesheetPath(state.root);
43
+ const plugin = {
44
+ name: "kirana",
45
+ async buildStart() {
46
+ await session();
47
+ },
48
+ load: {
49
+ filter: { id: [/stylesheet\.css/, COMPONENT] },
50
+ async handler(id) {
51
+ if (COMPONENT.test(id)) {
52
+ const compiler = await session();
53
+ if (!compiler.compiles(id)) return null;
54
+ const source = await readFile(id, "utf8");
55
+ const result = await compiler.transformComponent(id, source);
56
+ for (const dependency of result.dependencies) this.addWatchFile(dependency);
57
+ reporter.module(this, id, source, result.diagnostics);
58
+ if (result.cssChanged) host.cssChanged?.();
59
+ return result.code === void 0 ? null : {
60
+ code: result.code,
61
+ map: result.map
62
+ };
63
+ }
64
+ if (cleanId(id) !== stylesheetFile()) return null;
65
+ if (!host.bundlesCss) return {
66
+ code: `export default ${JSON.stringify(fileName)}`,
67
+ moduleType: "js"
68
+ };
69
+ if (ASSET_QUERY.test(id)) return development() && /[?&]inline\b/.test(id) ? (await session()).stylesheet(false) : null;
70
+ return development() ? (await session()).stylesheet(false) : PLACEHOLDER;
71
+ }
72
+ },
73
+ transform: {
74
+ filter: {
75
+ id: {
76
+ include: SCRIPT,
77
+ exclude: [ASSET_QUERY, COMPONENT_PART]
78
+ },
79
+ code: STYLE_BEARING
80
+ },
81
+ async handler(code, id) {
82
+ const file = cleanId(id);
83
+ const compiler = await session();
84
+ if (!compiler.compiles(file)) return null;
85
+ const result = compiler.transform(file, code);
86
+ for (const dependency of result.dependencies) this.addWatchFile(dependency);
87
+ reporter.module(this, file, code, result.diagnostics);
88
+ if (result.cssChanged) host.cssChanged?.();
89
+ return result.code === void 0 ? null : {
90
+ code: result.code,
91
+ map: result.map
92
+ };
93
+ }
94
+ },
95
+ /** A watch rebuild: modules that read the changed file's tokens or relations compile again. */
96
+ async watchChange(id) {
97
+ (await session()).invalidate(id);
98
+ },
99
+ async buildEnd() {
100
+ if (development()) return;
101
+ reporter.project(this, state.root, (await session()).diagnostics());
102
+ },
103
+ generateBundle: {
104
+ order: "pre",
105
+ async handler(_output, bundle) {
106
+ if (!host.bundlesCss) {
107
+ const css = (await session()).stylesheet(true);
108
+ this.emitFile({
109
+ type: "asset",
110
+ fileName,
111
+ source: css
112
+ });
113
+ return;
114
+ }
115
+ await fill(bundle, this.emitFile.bind(this));
116
+ }
117
+ }
118
+ };
119
+ /**
120
+ * Fills every stylesheet asset still holding the placeholder, renaming it by content unless the
121
+ * host keeps names, and points the chunks and assets that named it at the new name. A second pass
122
+ * finds nothing to do, so a host may run it again later in `generateBundle` for assets another
123
+ * plugin added after the first pass (Qwik's).
124
+ */
125
+ const fill = async (bundle, emitFile) => {
126
+ const css = (await session()).stylesheet(true);
127
+ for (const [key, asset] of Object.entries(bundle)) {
128
+ if (asset.type !== "asset") continue;
129
+ const source = fillStylesheet(String(asset.source), css);
130
+ if (source === void 0) continue;
131
+ if (host.renames === false) {
132
+ asset.source = source;
133
+ filled.add(asset.fileName);
134
+ continue;
135
+ }
136
+ const hashed = renamed.get(asset.fileName) ?? renameAsset(asset.fileName, source);
137
+ renamed.set(asset.fileName, hashed);
138
+ delete bundle[key];
139
+ emitFile({
140
+ type: "asset",
141
+ fileName: hashed,
142
+ source
143
+ });
144
+ }
145
+ for (const [from, to] of renamed) {
146
+ const oldBase = path.posix.basename(from);
147
+ const newBase = path.posix.basename(to);
148
+ for (const file of Object.values(bundle)) if (file.type === "chunk") {
149
+ file.code = file.code.replaceAll(oldBase, newBase);
150
+ const imported = file.viteMetadata?.importedCss;
151
+ if (imported?.delete(from)) imported.add(to);
152
+ } else if (typeof file.source === "string") file.source = file.source.replaceAll(oldBase, newBase);
153
+ }
154
+ };
155
+ return {
156
+ plugin,
157
+ session,
158
+ state,
159
+ filled,
160
+ fill
161
+ };
181
162
  }
182
- export default function kirana(options = {}) {
183
- return createKirana(options).plugin;
163
+ function kirana(options = {}) {
164
+ return createKirana(options).plugin;
184
165
  }
166
+ //#endregion
167
+ export { createKirana, kirana as default };