@tokenami/unplugin 0.0.96--canary.bootstrap.0 → 0.0.96--canary.496.27369730444.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +1 -7
  2. package/dist/index.js +142 -105
  3. package/package.json +13 -13
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import * as _vite from 'vite';
2
- import { UnpluginFactory } from 'unplugin';
3
2
 
4
3
  interface TokenamiUnpluginOptions {
5
4
  /**
@@ -18,12 +17,7 @@ interface TokenamiUnpluginOptions {
18
17
  * @default "tokenami.css"
19
18
  */
20
19
  output?: string;
21
- /**
22
- * Browserslist query used for Lightning CSS transforms.
23
- */
24
- browserslist?: string | readonly string[];
25
20
  }
26
- declare const tokenamiFactory: UnpluginFactory<TokenamiUnpluginOptions | undefined, false>;
27
21
  declare const vite: (options?: TokenamiUnpluginOptions | undefined) => _vite.Plugin<any>;
28
22
 
29
- export { type TokenamiUnpluginOptions, tokenamiFactory, vite };
23
+ export { type TokenamiUnpluginOptions, vite };
package/dist/index.js CHANGED
@@ -1,125 +1,162 @@
1
- import { utils, TokenStore, generateSheet } from '@tokenami/node';
2
- import browserslist from 'browserslist';
1
+ import { utils, TokenStore, removeUnusedLayers, createSheet, findUsedTokens } from '@tokenami/node';
3
2
  import * as fs from 'node:fs';
4
- import { browserslistToTargets } from 'lightningcss';
5
3
  import * as pathe from 'pathe';
6
4
  import { createUnplugin } from 'unplugin';
5
+ import { normalizePath, createFilter } from 'vite';
7
6
 
8
7
  // src/unplugin.ts
9
8
  var PLUGIN_NAME = "tokenami";
10
- var tokenamiFactory = (options) => {
11
- const opts = normalizeOptions(options);
12
- const configPath = utils.getConfigPath(opts.cwd, opts.config);
13
- const resolvedOutputId = `\0${opts.output}`;
14
- const initialConfig = utils.getConfigAtPath(configPath, { cache: false });
15
- const store = new TokenStore(initialConfig);
16
- let config = initialConfig;
17
- let externalStylesheetFiles = /* @__PURE__ */ new Set();
18
- let resolveExternalStylesheet;
19
- let minify = process.env.NODE_ENV === "production";
20
- async function getCss() {
21
- const queries = opts.browserslist ?? ["supports css-cascade-layers"];
22
- const browsers = browserslist(queries, {
23
- env: process.env.NODE_ENV || "development",
24
- path: opts.cwd
25
- });
26
- const sheet = generateSheet({
27
- output: pathe.join(opts.cwd, opts.output),
28
- targets: browserslistToTargets(browsers),
29
- tokens: store.getTokens(),
30
- config,
31
- minify
32
- });
33
- return sheet;
34
- }
35
- function updateFile(file, content) {
36
- store.updateFile(pathe.relative(opts.cwd, file), content);
37
- }
38
- async function* scanExternalStylesheets() {
39
- const externalStylesheets = getExternalStylesheets(config);
40
- if (!externalStylesheets.length) return;
41
- if (!resolveExternalStylesheet) throw new Error("Vite resolver is not ready.");
42
- externalStylesheetFiles = /* @__PURE__ */ new Set();
43
- for (const stylesheet of externalStylesheets) {
44
- const file = await resolveExternalStylesheet(stylesheet);
45
- if (!file) throw new Error(`Could not resolve external stylesheet: ${stylesheet}`);
46
- externalStylesheetFiles.add(file);
47
- updateFile(file, fs.readFileSync(file, "utf8"));
48
- yield file;
9
+ var tokenami = /* @__PURE__ */ createUnplugin(
10
+ (opts = {}) => {
11
+ const cwd = pathe.resolve(opts.cwd ?? process.cwd());
12
+ const output = opts.output ?? "tokenami.css";
13
+ const configPath = utils.getConfigPath(cwd, opts.config);
14
+ const resolvedOutputId = `\0${output}`;
15
+ const initialConfig = utils.getConfigAtPath(configPath, { cache: false });
16
+ const store = new TokenStore(initialConfig);
17
+ let config = initialConfig;
18
+ let externalStylesheetFiles = /* @__PURE__ */ new Set();
19
+ let resolveExternalStylesheet;
20
+ let command = "serve";
21
+ let sourceFilter = createSourceFilter(cwd, config);
22
+ async function getTokens() {
23
+ return mergeTokens(await findUsedTokens(cwd, config), store.getTokens());
49
24
  }
50
- }
51
- return {
52
- name: PLUGIN_NAME,
53
- async buildStart() {
54
- config = utils.getConfigAtPath(configPath, { cache: false });
55
- store.updateConfig(config);
56
- this.addWatchFile(configPath);
57
- for await (const file of scanExternalStylesheets()) {
58
- this.addWatchFile(file);
25
+ function updateFile(file, content) {
26
+ store.updateFile(pathe.relative(cwd, file), content, {
27
+ mode: command === "serve" ? "hmr" : "build"
28
+ });
29
+ }
30
+ function removeFile(file) {
31
+ const filePath = pathe.relative(cwd, file);
32
+ store.removeFile(filePath);
33
+ }
34
+ function shouldScanFile(file) {
35
+ return sourceFilter(normalizePath(file));
36
+ }
37
+ async function* scanExternalStylesheets() {
38
+ const externalStylesheets = config.include.filter(isExternalStylesheet);
39
+ if (!externalStylesheets.length) return;
40
+ if (!resolveExternalStylesheet) throw new Error("Vite resolver is not ready.");
41
+ externalStylesheetFiles = /* @__PURE__ */ new Set();
42
+ for (const stylesheet of externalStylesheets) {
43
+ const file = await resolveExternalStylesheet(stylesheet);
44
+ if (!file) throw new Error(`Could not resolve external stylesheet: ${stylesheet}`);
45
+ externalStylesheetFiles.add(file);
46
+ updateFile(file, fs.readFileSync(file, "utf8"));
47
+ yield file;
59
48
  }
60
- },
61
- resolveId(id) {
62
- if (id.replace(/^\0/, "") === opts.output) return resolvedOutputId;
63
- return null;
64
- },
65
- async load(id) {
66
- if (id === resolvedOutputId) return getCss();
67
- return null;
68
- },
69
- transform(code, id) {
70
- if (id === resolvedOutputId) return null;
71
- updateFile(id, code);
72
- return null;
73
- },
74
- vite: {
75
- configResolved(viteConfig) {
76
- minify = viteConfig.command === "build" && viteConfig.build.minify !== false;
77
- resolveExternalStylesheet = viteConfig.createResolver();
49
+ }
50
+ return {
51
+ name: PLUGIN_NAME,
52
+ async buildStart() {
53
+ config = utils.getConfigAtPath(configPath, { cache: false });
54
+ store.updateConfig(config);
55
+ sourceFilter = createSourceFilter(cwd, config);
56
+ this.addWatchFile(configPath);
57
+ for await (const file of scanExternalStylesheets()) {
58
+ this.addWatchFile(file);
59
+ }
60
+ },
61
+ resolveId(id) {
62
+ if (getOutputId(id) !== output) return null;
63
+ return resolvedOutputId;
64
+ },
65
+ async load(id) {
66
+ if (id !== resolvedOutputId) return null;
67
+ const tokens = await getTokens();
68
+ return removeUnusedLayers(createSheet({ tokens, config }));
78
69
  },
79
- configureServer(server) {
80
- server.watcher.add(utils.getConfigPath(opts.cwd, opts.config));
70
+ transform(code, id) {
71
+ if (id === resolvedOutputId) return null;
72
+ const file = getFileFromId(id);
73
+ if (!file || !shouldScanFile(file)) return null;
74
+ updateFile(file, code);
75
+ return null;
81
76
  },
82
- async handleHotUpdate(ctx) {
83
- if (ctx.file === configPath) {
84
- config = utils.getConfigAtPath(configPath, { cache: false });
85
- store.updateConfig(config);
86
- store.clear();
87
- for await (const file of scanExternalStylesheets()) {
88
- ctx.server.watcher.add(file);
77
+ watchChange(id, change) {
78
+ if (change.event !== "delete") return;
79
+ if (!externalStylesheetFiles.has(id) && !shouldScanFile(id)) return;
80
+ removeFile(id);
81
+ },
82
+ vite: {
83
+ config(userConfig) {
84
+ var _a;
85
+ const cssMinify = ((_a = userConfig.build) == null ? void 0 : _a.minify) === false ? false : "lightningcss";
86
+ return {
87
+ css: { ...userConfig.css, transformer: "lightningcss" },
88
+ build: { ...userConfig.build, cssMinify }
89
+ };
90
+ },
91
+ configResolved(viteConfig) {
92
+ command = viteConfig.command;
93
+ resolveExternalStylesheet = viteConfig.createResolver();
94
+ },
95
+ generateBundle: {
96
+ order: "post",
97
+ handler(_, bundle) {
98
+ removeBundleUnusedLayers(bundle);
89
99
  }
90
- ctx.server.ws.send({ type: "full-reload" });
91
- return [];
92
- }
93
- if (ctx.modules.length || externalStylesheetFiles.has(ctx.file)) {
94
- try {
95
- updateFile(ctx.file, await ctx.read());
96
- } catch {
97
- store.removeFile(pathe.relative(opts.cwd, ctx.file));
100
+ },
101
+ async handleHotUpdate(ctx) {
102
+ if (ctx.file === configPath) {
103
+ config = utils.getConfigAtPath(configPath, { cache: false });
104
+ store.updateConfig(config);
105
+ sourceFilter = createSourceFilter(cwd, config);
106
+ store.clear();
107
+ for await (const file of scanExternalStylesheets()) {
108
+ ctx.server.watcher.add(file);
109
+ }
110
+ ctx.server.ws.send({ type: "full-reload" });
111
+ return [];
112
+ }
113
+ if (externalStylesheetFiles.has(ctx.file) || shouldScanFile(ctx.file)) {
114
+ try {
115
+ updateFile(ctx.file, await ctx.read());
116
+ } catch {
117
+ removeFile(ctx.file);
118
+ }
119
+ } else {
120
+ return;
98
121
  }
99
- } else {
100
- return;
122
+ const cssModule = ctx.server.moduleGraph.getModuleById(resolvedOutputId);
123
+ if (!cssModule) return;
124
+ ctx.server.moduleGraph.invalidateModule(cssModule);
125
+ return [...ctx.modules, cssModule];
101
126
  }
102
- const cssModule = ctx.server.moduleGraph.getModuleById(resolvedOutputId);
103
- if (!cssModule) return;
104
- ctx.server.moduleGraph.invalidateModule(cssModule);
105
- return [...ctx.modules, cssModule];
106
127
  }
107
- }
108
- };
109
- };
110
- function normalizeOptions(options = {}) {
128
+ };
129
+ }
130
+ );
131
+ function isExternalStylesheet(pattern) {
132
+ return pattern.startsWith("@") || pattern.startsWith("node_modules/");
133
+ }
134
+ function getFileFromId(id) {
135
+ return getOutputId(id).split("?")[0];
136
+ }
137
+ function getOutputId(id) {
138
+ return id.replace(/^\0/, "");
139
+ }
140
+ function createSourceFilter(cwd, config) {
141
+ const resolvePath = (pattern) => normalizePath(pathe.resolve(cwd, pattern));
142
+ const include = config.include.filter((p) => !isExternalStylesheet(p)).map(resolvePath);
143
+ const exclude = (config.exclude ?? []).map(resolvePath);
144
+ return createFilter(include, exclude);
145
+ }
146
+ function mergeTokens(a, b) {
111
147
  return {
112
- ...options,
113
- cwd: pathe.resolve(options.cwd ?? process.cwd()),
114
- output: options.output ?? "tokenami.css"
148
+ properties: Array.from(/* @__PURE__ */ new Set([...a.properties, ...b.properties])),
149
+ values: Array.from(/* @__PURE__ */ new Set([...a.values, ...b.values])),
150
+ composeBlocks: { ...a.composeBlocks, ...b.composeBlocks }
115
151
  };
116
152
  }
117
- function getExternalStylesheets(config) {
118
- return config.include.filter((pattern) => {
119
- return pattern.startsWith("@") || pattern.startsWith("node_modules/");
120
- });
153
+ function removeBundleUnusedLayers(bundle) {
154
+ for (const asset of Object.values(bundle)) {
155
+ if (asset.type !== "asset" || !asset.fileName.endsWith(".css")) continue;
156
+ if (typeof asset.source === "string") asset.source = removeUnusedLayers(asset.source);
157
+ else asset.source = Buffer.from(removeUnusedLayers(asset.source.toString()));
158
+ }
121
159
  }
122
- var tokenami = /* @__PURE__ */ createUnplugin(tokenamiFactory);
123
160
  var vite = tokenami.vite;
124
161
 
125
- export { tokenamiFactory, vite };
162
+ export { vite };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenami/unplugin",
3
- "version": "0.0.96--canary.bootstrap.0",
3
+ "version": "0.0.96--canary.496.27369730444.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,13 +20,19 @@
20
20
  "files": [
21
21
  "dist"
22
22
  ],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "dev": "tsup --watch",
26
+ "test": "vitest --run",
27
+ "test:watch": "vitest",
28
+ "typecheck": "tsc --noEmit"
29
+ },
23
30
  "dependencies": {
24
- "browserslist": "^4.26.3",
31
+ "@tokenami/config": "0.0.96--canary.496.27369730444.0",
32
+ "@tokenami/node": "0.0.96--canary.496.27369730444.0",
25
33
  "lightningcss": "1.29.1",
26
34
  "pathe": "^1.1.1",
27
- "unplugin": "^3.0.0",
28
- "@tokenami/node": "0.0.95",
29
- "@tokenami/config": "0.0.95"
35
+ "unplugin": "^3.0.0"
30
36
  },
31
37
  "devDependencies": {
32
38
  "@types/node": "^20.3.1",
@@ -43,11 +49,5 @@
43
49
  "optional": true
44
50
  }
45
51
  },
46
- "scripts": {
47
- "build": "tsup",
48
- "dev": "tsup --watch",
49
- "test": "vitest --run",
50
- "test:watch": "vitest",
51
- "typecheck": "tsc --noEmit"
52
- }
53
- }
52
+ "gitHead": "4f389196f56b9a6040c0e961cd95be07564c0db3"
53
+ }