@animus-ui/layergate 0.0.0-stage → 0.1.35
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 +239 -2
- package/dist/compile-C4GyCiuY.cjs +323 -0
- package/dist/compile-Cu_GFS3l.mjs +295 -0
- package/dist/compile-DZwVBjTM.d.cts +126 -0
- package/dist/compile-DZwVBjTM.d.cts.map +1 -0
- package/dist/compile-DZwVBjTM.d.mts +126 -0
- package/dist/compile-DZwVBjTM.d.mts.map +1 -0
- package/dist/host-BGcb1rMJ.mjs +169 -0
- package/dist/host-C4ZaMdkx.cjs +210 -0
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +3 -0
- package/dist/plan-Bsn_yxS9.mjs +29 -0
- package/dist/plan-hvk04qzh.cjs +40 -0
- package/dist/plan-w-y0limy.d.cts +35 -0
- package/dist/plan-w-y0limy.d.cts.map +1 -0
- package/dist/plan-w-y0limy.d.mts +35 -0
- package/dist/plan-w-y0limy.d.mts.map +1 -0
- package/dist/sheet-BUnyt5Jt.cjs +576 -0
- package/dist/sheet-DJGhbeYI.mjs +571 -0
- package/dist/vite.cjs +295 -0
- package/dist/vite.d.cts +59 -0
- package/dist/vite.d.cts.map +1 -0
- package/dist/vite.d.mts +59 -0
- package/dist/vite.d.mts.map +1 -0
- package/dist/vite.mjs +290 -0
- package/dist/webpack-loader.cjs +104 -0
- package/dist/webpack-loader.d.cts +35 -0
- package/dist/webpack-loader.d.cts.map +1 -0
- package/dist/webpack-loader.d.mts +36 -0
- package/dist/webpack-loader.d.mts.map +1 -0
- package/dist/webpack-loader.mjs +104 -0
- package/dist/webpack-state-BpF2PPjA.d.cts +15 -0
- package/dist/webpack-state-BpF2PPjA.d.cts.map +1 -0
- package/dist/webpack-state-BtmtzsWZ.cjs +61 -0
- package/dist/webpack-state-CXoQQ7XR.d.mts +15 -0
- package/dist/webpack-state-CXoQQ7XR.d.mts.map +1 -0
- package/dist/webpack-state-DwltSkQq.mjs +44 -0
- package/dist/webpack.cjs +161 -0
- package/dist/webpack.d.cts +98 -0
- package/dist/webpack.d.cts.map +1 -0
- package/dist/webpack.d.mts +98 -0
- package/dist/webpack.d.mts.map +1 -0
- package/dist/webpack.mjs +155 -0
- package/package.json +90 -4
package/dist/vite.mjs
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { t as readSheet } from "./sheet-DJGhbeYI.mjs";
|
|
2
|
+
import { t as compileUnit } from "./compile-Cu_GFS3l.mjs";
|
|
3
|
+
import { n as resolvePlan } from "./plan-Bsn_yxS9.mjs";
|
|
4
|
+
import { a as real, i as ownership, n as fileOf, o as resolveEach, r as formatDiagnostic, t as Units } from "./host-BGcb1rMJ.mjs";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
7
|
+
import { watch } from "node:fs";
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { createIdResolver, isCSSRequest, isFileLoadingAllowed, normalizePath, searchForWorkspaceRoot } from "vite";
|
|
10
|
+
//#region src/vite.ts
|
|
11
|
+
/**
|
|
12
|
+
* The Vite adapter. layergate owns the load of each selected stylesheet:
|
|
13
|
+
* the declared sheets, which `virtual:layergate` (or a host's own
|
|
14
|
+
* stylesheet, `declaredBy`) delivers as one finished stylesheet, and, opted
|
|
15
|
+
* in, the `.css` a JS module imports from another package, which loads as
|
|
16
|
+
* `<realpath>?layergate`. Each finished stylesheet has no local `@import`
|
|
17
|
+
* left, and Vite's own CSS pipeline then processes it once: PostCSS,
|
|
18
|
+
* minification, injection or extraction. A JS module's import of an owned
|
|
19
|
+
* sheet reaches it through a proxy that imports the declared sheets first,
|
|
20
|
+
* so they keep their order wherever the app imports an owned sheet first.
|
|
21
|
+
* A stylesheet Vite loads itself that is owned, or reaches an owned file,
|
|
22
|
+
* is finished in `transform`. CSS Modules and special requests (`?inline`,
|
|
23
|
+
* `?url`, `?raw`) stay Vite's.
|
|
24
|
+
*/
|
|
25
|
+
const OWNED = "?layergate";
|
|
26
|
+
const ENTRY_ID = "virtual:layergate";
|
|
27
|
+
/** `virtual:layergate` is a stylesheet: the declared sheets, finished. */
|
|
28
|
+
const RESOLVED_ENTRY = `\0${ENTRY_ID}.css`;
|
|
29
|
+
/** A JS module's import of an owned sheet: the declared sheets, then it.
|
|
30
|
+
* Its id names the file encoded and ends in `.js`, so Vite never takes it
|
|
31
|
+
* for a stylesheet. */
|
|
32
|
+
const PROXY = "\0layergate-proxy:";
|
|
33
|
+
const proxyId = (file) => `${PROXY}${encodeURIComponent(file)}.js`;
|
|
34
|
+
const proxiedFile = (id) => decodeURIComponent(id.slice(17, -3));
|
|
35
|
+
const PLAIN_CSS = /\.css$/;
|
|
36
|
+
const MODULE_CSS = /\.module\.css$/;
|
|
37
|
+
/** The stylesheet a request id names when the request is plain stylesheet
|
|
38
|
+
* delivery: no query, or only Vite's `direct` (a stylesheet an HTML link
|
|
39
|
+
* loads in development) and its `t`/`v` cache-busting params. Special
|
|
40
|
+
* requests (`?inline`, `?url`, `?raw`) and CSS Modules are not. */
|
|
41
|
+
function plainCssFile(id) {
|
|
42
|
+
const at = id.indexOf("?");
|
|
43
|
+
const path = at === -1 ? id : id.slice(0, at);
|
|
44
|
+
if (!PLAIN_CSS.test(path) || MODULE_CSS.test(path)) return null;
|
|
45
|
+
return (at === -1 ? [] : id.slice(at + 1).split("&")).every((param) => param === "direct" || /^[tv]=/.test(param)) ? path : null;
|
|
46
|
+
}
|
|
47
|
+
/** Whether `file` lies outside the directory `root`. */
|
|
48
|
+
const outside = (root, file) => {
|
|
49
|
+
const path = relative(root, file);
|
|
50
|
+
return path.startsWith("..") || isAbsolute(path);
|
|
51
|
+
};
|
|
52
|
+
function layergate(options = {}) {
|
|
53
|
+
const plan = resolvePlan(options);
|
|
54
|
+
const declaredBy = options.declaredBy ?? ENTRY_ID;
|
|
55
|
+
let root = process.cwd();
|
|
56
|
+
const owner = ownership(plan);
|
|
57
|
+
const { owns, owning } = owner;
|
|
58
|
+
/** `@import` inside an owned sheet resolves as Vite resolves a CSS
|
|
59
|
+
* import: the `style` field and condition, CSS files only. */
|
|
60
|
+
let resolveCss;
|
|
61
|
+
/** Declared sheets, in order. */
|
|
62
|
+
let optedOut = /* @__PURE__ */ new Set();
|
|
63
|
+
/** Parsed files, the files each owned id's finished stylesheet read,
|
|
64
|
+
* and reach answers. */
|
|
65
|
+
const units = new Units();
|
|
66
|
+
/** Each module's finished declared head, kept until a file it read
|
|
67
|
+
* changes. */
|
|
68
|
+
const heads = /* @__PURE__ */ new Map();
|
|
69
|
+
let server;
|
|
70
|
+
/** Vite's watcher ignores node_modules, so an owned file there is
|
|
71
|
+
* watched here through its directory, which sees edits, atomic saves,
|
|
72
|
+
* deletion and creation alike, and its change handed to Vite's HMR. One
|
|
73
|
+
* watch serves every owned file of a directory. */
|
|
74
|
+
const directories = /* @__PURE__ */ new Map();
|
|
75
|
+
const unwatch = (file) => {
|
|
76
|
+
const dir = dirname(file);
|
|
77
|
+
const watched = directories.get(dir);
|
|
78
|
+
watched?.files.delete(file);
|
|
79
|
+
if (watched?.files.size === 0) {
|
|
80
|
+
watched.watcher.close();
|
|
81
|
+
directories.delete(dir);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const watchInstalled = (file) => {
|
|
85
|
+
if (!server || !file.includes("/node_modules/")) return;
|
|
86
|
+
const dir = dirname(file);
|
|
87
|
+
const watched = directories.get(dir);
|
|
88
|
+
if (watched) {
|
|
89
|
+
watched.files.add(file);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const files = /* @__PURE__ */ new Set([file]);
|
|
94
|
+
const watcher = watch(dir, (_event, name) => {
|
|
95
|
+
const changed = name ? `${dir}/${basename(name)}` : null;
|
|
96
|
+
if (changed && files.has(changed)) server?.watcher.emit("change", changed);
|
|
97
|
+
});
|
|
98
|
+
directories.set(dir, {
|
|
99
|
+
watcher,
|
|
100
|
+
files
|
|
101
|
+
});
|
|
102
|
+
} catch {}
|
|
103
|
+
};
|
|
104
|
+
/** Records the files `id`'s finished stylesheet read, forgetting and
|
|
105
|
+
* unwatching what it no longer reads. */
|
|
106
|
+
const reconcile = (id, files) => {
|
|
107
|
+
for (const file of units.record(id, files)) unwatch(file);
|
|
108
|
+
for (const file of files) watchInstalled(file);
|
|
109
|
+
};
|
|
110
|
+
/** A root-relative URL for `target`, which Vite resolves from any
|
|
111
|
+
* stylesheet, its own virtual ones too; one outside the root through
|
|
112
|
+
* Vite's `/@fs/`, which the dev server serves only inside
|
|
113
|
+
* `server.fs.allow`: the directory of an owned file outside it is
|
|
114
|
+
* allowed, and nothing more. */
|
|
115
|
+
const rootUrl = (target) => {
|
|
116
|
+
if (!outside(real(root), target)) return `/${normalizePath(relative(real(root), target))}`;
|
|
117
|
+
if (server && !isFileLoadingAllowed(server.config, normalizePath(target))) server.config.server.fs.allow.push(normalizePath(dirname(target)));
|
|
118
|
+
return `/@fs${normalizePath(target)}`;
|
|
119
|
+
};
|
|
120
|
+
/** The file an `@import` in `importer` reaches, as Vite resolves CSS. */
|
|
121
|
+
const resolveImport = async (context, specifier, importer) => {
|
|
122
|
+
const resolved = await resolveCss?.(context.environment, specifier, importer);
|
|
123
|
+
return resolved && PLAIN_CSS.test(fileOf(resolved)) ? fileOf(resolved) : null;
|
|
124
|
+
};
|
|
125
|
+
/** Compiles `roots` with the host's CSS resolver, the plan and the
|
|
126
|
+
* parsed-file cache. */
|
|
127
|
+
const finish = (context, roots, extra = {}) => compileUnit(roots, {
|
|
128
|
+
layer: plan.layer,
|
|
129
|
+
order: plan.order,
|
|
130
|
+
base: root,
|
|
131
|
+
resolve: (specifier, from) => resolveImport(context, specifier, from),
|
|
132
|
+
read: (file) => readFile(file, "utf8"),
|
|
133
|
+
quarantined: (file) => !optedOut.has(file),
|
|
134
|
+
owns,
|
|
135
|
+
cache: units.parsed,
|
|
136
|
+
...extra
|
|
137
|
+
});
|
|
138
|
+
/** Reports `unit`'s diagnostics through `context` and records the files
|
|
139
|
+
* module `id` now reads. */
|
|
140
|
+
const publish = (context, id, unit) => {
|
|
141
|
+
for (const file of unit.files) context.addWatchFile(file);
|
|
142
|
+
reconcile(id, unit.files);
|
|
143
|
+
for (const diagnostic of unit.diagnostics) {
|
|
144
|
+
const message = formatDiagnostic(diagnostic);
|
|
145
|
+
if (diagnostic.severity === "error") context.error(message);
|
|
146
|
+
else if (diagnostic.severity === "warning") context.warn(message);
|
|
147
|
+
else context.info(message);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
/** The declared sheets as one finished stylesheet for module `id`, with
|
|
151
|
+
* root-relative URLs; empty when nothing is declared. */
|
|
152
|
+
const head = async (context, id) => {
|
|
153
|
+
if (owner.declared.length === 0) return "";
|
|
154
|
+
const kept = heads.get(id);
|
|
155
|
+
if (kept !== void 0) return kept;
|
|
156
|
+
const unit = await finish(context, owner.declared, {
|
|
157
|
+
url: rootUrl,
|
|
158
|
+
map: false
|
|
159
|
+
});
|
|
160
|
+
publish(context, id, unit);
|
|
161
|
+
heads.set(id, unit.css);
|
|
162
|
+
return unit.css;
|
|
163
|
+
};
|
|
164
|
+
return Object.assign({
|
|
165
|
+
name: "layergate",
|
|
166
|
+
enforce: "pre",
|
|
167
|
+
config(userConfig, env) {
|
|
168
|
+
if (env.command !== "serve") return;
|
|
169
|
+
const base = resolve(userConfig.root ?? process.cwd());
|
|
170
|
+
const require = createRequire(join(base, "package.json"));
|
|
171
|
+
const dirs = [];
|
|
172
|
+
for (const specifier of plan.sheets) {
|
|
173
|
+
let file;
|
|
174
|
+
try {
|
|
175
|
+
file = real(specifier.startsWith(".") || isAbsolute(specifier) ? resolve(base, specifier) : require.resolve(specifier));
|
|
176
|
+
} catch {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (outside(real(base), file)) dirs.push(dirname(file));
|
|
180
|
+
}
|
|
181
|
+
if (dirs.length === 0) return;
|
|
182
|
+
return { server: { fs: { allow: userConfig.server?.fs?.allow ? dirs : [searchForWorkspaceRoot(base), ...dirs] } } };
|
|
183
|
+
},
|
|
184
|
+
configResolved(config) {
|
|
185
|
+
root = config.root;
|
|
186
|
+
owner.reset(root, []);
|
|
187
|
+
resolveCss = createIdResolver(config, {
|
|
188
|
+
extensions: [".css"],
|
|
189
|
+
mainFields: ["style"],
|
|
190
|
+
conditions: ["style", "development|production"],
|
|
191
|
+
tryIndex: false,
|
|
192
|
+
preferRelative: true
|
|
193
|
+
});
|
|
194
|
+
},
|
|
195
|
+
configureServer(devServer) {
|
|
196
|
+
server = devServer;
|
|
197
|
+
},
|
|
198
|
+
buildEnd() {
|
|
199
|
+
for (const { watcher } of directories.values()) watcher.close();
|
|
200
|
+
directories.clear();
|
|
201
|
+
},
|
|
202
|
+
async buildStart() {
|
|
203
|
+
const importer = join(root, "index.html");
|
|
204
|
+
const resolveOne = async (specifier) => {
|
|
205
|
+
const resolved = await this.resolve(specifier, importer, { skipSelf: true });
|
|
206
|
+
return resolved && !resolved.external ? fileOf(resolved.id) : null;
|
|
207
|
+
};
|
|
208
|
+
const declared = await resolveEach(plan.sheets, "sheets", root, resolveOne);
|
|
209
|
+
owner.reset(root, declared);
|
|
210
|
+
const cssModule = declared.find((file) => MODULE_CSS.test(file));
|
|
211
|
+
if (cssModule) this.error(`[layergate] sheets: ${cssModule} is a CSS Module; layergate does not own CSS Modules yet`);
|
|
212
|
+
optedOut = new Set(await resolveEach(plan.optOut, "optOut", root, resolveOne));
|
|
213
|
+
heads.clear();
|
|
214
|
+
},
|
|
215
|
+
async resolveId(source, importer, resolveOptions) {
|
|
216
|
+
if (source === ENTRY_ID) return RESOLVED_ENTRY;
|
|
217
|
+
if (source.endsWith(OWNED) || source.startsWith(PROXY)) return source;
|
|
218
|
+
if (!owning()) return null;
|
|
219
|
+
if (!importer || importer.startsWith("\0") || isCSSRequest(importer)) return null;
|
|
220
|
+
if (source.includes("?") || !PLAIN_CSS.test(source)) return null;
|
|
221
|
+
const resolved = await this.resolve(source, importer, {
|
|
222
|
+
...resolveOptions,
|
|
223
|
+
skipSelf: true
|
|
224
|
+
});
|
|
225
|
+
if (!resolved || resolved.external) return null;
|
|
226
|
+
const file = fileOf(resolved.id);
|
|
227
|
+
if (!PLAIN_CSS.test(file) || MODULE_CSS.test(file)) return null;
|
|
228
|
+
return owns(file) ? proxyId(file) : null;
|
|
229
|
+
},
|
|
230
|
+
async load(id) {
|
|
231
|
+
if (id === RESOLVED_ENTRY) return head(this, id);
|
|
232
|
+
if (id.startsWith(PROXY)) {
|
|
233
|
+
const file = proxiedFile(id);
|
|
234
|
+
return (owner.declared.includes(file) ? [declaredBy] : [declaredBy, file + OWNED]).map((request) => `import ${JSON.stringify(request)};`).join("\n");
|
|
235
|
+
}
|
|
236
|
+
if (!id.endsWith(OWNED)) return null;
|
|
237
|
+
const unit = await finish(this, [id.slice(0, -10)]);
|
|
238
|
+
publish(this, id, unit);
|
|
239
|
+
return {
|
|
240
|
+
code: unit.css,
|
|
241
|
+
map: unit.map
|
|
242
|
+
};
|
|
243
|
+
},
|
|
244
|
+
async transform(code, id) {
|
|
245
|
+
if (!owning() || id.startsWith("\0")) return null;
|
|
246
|
+
const requested = plainCssFile(id);
|
|
247
|
+
if (!requested) return null;
|
|
248
|
+
const file = real(requested);
|
|
249
|
+
const { imports } = readSheet(code);
|
|
250
|
+
if (!owns(file) && imports.length === 0) return null;
|
|
251
|
+
if (!await units.reaches(file, imports, {
|
|
252
|
+
resolve: (specifier, from) => resolveImport(this, specifier, from),
|
|
253
|
+
read: (path) => readFile(path, "utf8"),
|
|
254
|
+
owns
|
|
255
|
+
})) return null;
|
|
256
|
+
units.parsed.delete(file);
|
|
257
|
+
const unit = await finish(this, [file], { read: (path) => path === file ? code : readFile(path, "utf8") });
|
|
258
|
+
publish(this, id, unit);
|
|
259
|
+
return {
|
|
260
|
+
code: unit.css,
|
|
261
|
+
map: unit.map
|
|
262
|
+
};
|
|
263
|
+
},
|
|
264
|
+
hotUpdate({ file, modules }) {
|
|
265
|
+
const stale = units.changed(normalizePath(file));
|
|
266
|
+
if (stale.size === 0) return;
|
|
267
|
+
const graph = this.environment.moduleGraph;
|
|
268
|
+
const affected = [];
|
|
269
|
+
for (const id of stale) {
|
|
270
|
+
heads.delete(id);
|
|
271
|
+
const node = graph.getModuleById(id);
|
|
272
|
+
if (!node) continue;
|
|
273
|
+
graph.invalidateModule(node);
|
|
274
|
+
affected.push(node);
|
|
275
|
+
}
|
|
276
|
+
return [...modules, ...affected];
|
|
277
|
+
}
|
|
278
|
+
}, {
|
|
279
|
+
/**
|
|
280
|
+
* The declared sheets as one finished stylesheet, for a host that
|
|
281
|
+
* delivers them at the head of its own stylesheet module `id` (and
|
|
282
|
+
* names it `declaredBy`): URLs are root-relative, and an edit to any
|
|
283
|
+
* file read updates module `id`. Empty when nothing is declared.
|
|
284
|
+
*/
|
|
285
|
+
stylesheetHead(id) {
|
|
286
|
+
return head(this, id);
|
|
287
|
+
} });
|
|
288
|
+
}
|
|
289
|
+
//#endregion
|
|
290
|
+
export { layergate as default, layergate };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const require_compile = require("./compile-C4GyCiuY.cjs");
|
|
2
|
+
const require_sheet = require("./sheet-BUnyt5Jt.cjs");
|
|
3
|
+
const require_host = require("./host-C4ZaMdkx.cjs");
|
|
4
|
+
const require_webpack_state = require("./webpack-state-BtmtzsWZ.cjs");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
//#region src/webpack-loader.ts
|
|
7
|
+
/**
|
|
8
|
+
* layergate's webpack loader. It runs on each global stylesheet before
|
|
9
|
+
* PostCSS and css-loader (the plugin inserts it so). The declared sheets'
|
|
10
|
+
* stylesheet gets them at its head; a declared sheet a module imports
|
|
11
|
+
* itself loads nothing; an owned stylesheet is finished as an owned graph;
|
|
12
|
+
* an app stylesheet whose imports reach an owned file is finished with its
|
|
13
|
+
* own rules unlayered; anything else passes through. A finished stylesheet
|
|
14
|
+
* has no local `@import` left, and a remote one that would need a layer is
|
|
15
|
+
* refused: Next's css-loader renders `layer()` as media.
|
|
16
|
+
*/
|
|
17
|
+
/** A file through the compiler's file system. */
|
|
18
|
+
const readFrom = (context) => (path) => new Promise((done, fail) => context.fs.readFile(path, (error, data) => error ? fail(error) : done(String(data))));
|
|
19
|
+
/** The file an `@import` in `importer` reaches, where css-loader would
|
|
20
|
+
* reach it: by realpath unless `resolve.symlinks` is false. */
|
|
21
|
+
const resolveFrom = (context) => {
|
|
22
|
+
const resolver = context.getResolve(require_webpack_state.CSS_RESOLVE);
|
|
23
|
+
return async (specifier, importer) => {
|
|
24
|
+
const resolved = await resolver((0, node_path.dirname)(importer), specifier).catch(() => null);
|
|
25
|
+
return resolved ? require_host.slashes(resolved) : null;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
async function finish(context, state, file, source, roots, extra = {}) {
|
|
29
|
+
const readFile = readFrom(context);
|
|
30
|
+
const read = (path) => path === file ? Promise.resolve(source) : readFile(path);
|
|
31
|
+
state.units.parsed.delete(file);
|
|
32
|
+
const { units, owner, optedOut, declaredBy } = state;
|
|
33
|
+
const unit = await require_compile.compileUnit(roots, {
|
|
34
|
+
layer: state.plan.layer,
|
|
35
|
+
order: state.plan.order,
|
|
36
|
+
base: context.rootContext,
|
|
37
|
+
resolve: resolveFrom(context),
|
|
38
|
+
read,
|
|
39
|
+
quarantined: (path) => {
|
|
40
|
+
const canonical = units.canonical(path);
|
|
41
|
+
return !optedOut.has(canonical) && canonical !== declaredBy;
|
|
42
|
+
},
|
|
43
|
+
owns: (path) => owner.owns(units.canonical(path)),
|
|
44
|
+
remote: "refuse",
|
|
45
|
+
cache: state.units.parsed,
|
|
46
|
+
...extra
|
|
47
|
+
});
|
|
48
|
+
state.units.record(file, unit.files);
|
|
49
|
+
for (const path of unit.files) context.addDependency(path);
|
|
50
|
+
for (const diagnostic of unit.diagnostics) {
|
|
51
|
+
const error = new Error(require_host.formatDiagnostic(diagnostic));
|
|
52
|
+
if (diagnostic.severity === "error") context.emitError(error);
|
|
53
|
+
else if (diagnostic.severity === "warning") context.emitWarning(error);
|
|
54
|
+
}
|
|
55
|
+
return unit;
|
|
56
|
+
}
|
|
57
|
+
async function run(context, source) {
|
|
58
|
+
const state = require_webpack_state.registry().states.get(context.getOptions().id ?? "");
|
|
59
|
+
if (!state) return null;
|
|
60
|
+
const file = require_host.slashes(context.resourcePath);
|
|
61
|
+
const id = state.units.canonical(file);
|
|
62
|
+
const { owner, declaredBy } = state;
|
|
63
|
+
if (id === declaredBy) {
|
|
64
|
+
if (owner.declared.length === 0) return null;
|
|
65
|
+
const unit = await finish(context, state, file, source, state.roots, {
|
|
66
|
+
delivery: file,
|
|
67
|
+
map: false
|
|
68
|
+
});
|
|
69
|
+
context.cacheable(false);
|
|
70
|
+
return {
|
|
71
|
+
code: `${unit.css}\n${source}`,
|
|
72
|
+
map: null
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!owner.owning()) return null;
|
|
76
|
+
if (declaredBy && owner.declared.includes(id)) {
|
|
77
|
+
context.cacheable(false);
|
|
78
|
+
return {
|
|
79
|
+
code: "",
|
|
80
|
+
map: null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!owner.owns(id)) {
|
|
84
|
+
const { imports } = require_sheet.readSheet(source);
|
|
85
|
+
if (imports.length === 0) return null;
|
|
86
|
+
if (!await state.units.reaches(file, imports, {
|
|
87
|
+
resolve: resolveFrom(context),
|
|
88
|
+
read: readFrom(context),
|
|
89
|
+
owns: (path) => owner.owns(state.units.canonical(path))
|
|
90
|
+
})) return null;
|
|
91
|
+
}
|
|
92
|
+
const unit = await finish(context, state, file, source, [file]);
|
|
93
|
+
context.cacheable(false);
|
|
94
|
+
return {
|
|
95
|
+
code: unit.css,
|
|
96
|
+
map: unit.map
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function layergateLoader(source, map, meta) {
|
|
100
|
+
const done = this.async();
|
|
101
|
+
run(this, source).then((finished) => finished ? done(null, finished.code, finished.map) : done(null, source, map, meta), (error) => done(error));
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
module.exports = layergateLoader;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { n as CompiledUnit } from "./compile-DZwVBjTM.cjs";
|
|
2
|
+
import { t as CSS_RESOLVE } from "./webpack-state-BpF2PPjA.cjs";
|
|
3
|
+
//#region src/webpack-loader.d.ts
|
|
4
|
+
type SourceMap = CompiledUnit['map'];
|
|
5
|
+
/** The source map and metadata the loaders before this one passed on,
|
|
6
|
+
* handed through untouched when the stylesheet passes. */
|
|
7
|
+
interface IncomingMap {
|
|
8
|
+
readonly mappings?: string;
|
|
9
|
+
}
|
|
10
|
+
interface IncomingMeta {
|
|
11
|
+
readonly ast?: {
|
|
12
|
+
readonly type?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** The loader context, as far as layergate reads it. */
|
|
16
|
+
interface LoaderContext {
|
|
17
|
+
resourcePath: string;
|
|
18
|
+
rootContext: string;
|
|
19
|
+
getOptions(): {
|
|
20
|
+
id?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Whether webpack may cache this module's build. */
|
|
23
|
+
cacheable(flag: boolean): void;
|
|
24
|
+
async(): (error: Error | null, code?: string, map?: SourceMap | IncomingMap, meta?: IncomingMeta) => void;
|
|
25
|
+
getResolve(options: typeof CSS_RESOLVE): (context: string, request: string) => Promise<string | false>;
|
|
26
|
+
fs: {
|
|
27
|
+
readFile(path: string, done: (error: Error | null, data?: Buffer | string) => void): void;
|
|
28
|
+
};
|
|
29
|
+
addDependency(file: string): void;
|
|
30
|
+
emitError(error: Error): void;
|
|
31
|
+
emitWarning(error: Error): void;
|
|
32
|
+
}
|
|
33
|
+
declare function layergateLoader(this: LoaderContext, source: string, map?: IncomingMap, meta?: IncomingMeta): void;
|
|
34
|
+
export = layergateLoader;
|
|
35
|
+
//# sourceMappingURL=webpack-loader.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-loader.d.cts","names":[],"sources":["../src/webpack-loader.ts"],"mappings":";;;KAoBK,YAAY;;;UAIP;WACC;;UAED;WACC;aAAiB;;;;UAIlB;EACR;EACA;EACA;IAAgB;;;EAEhB,UAAU;EACV,UACE,OAAO,cACP,eACA,MAAM,YAAY,aAClB,OAAO;EAET,WACE,gBAAgB,eACd,iBAAiB,oBAAoB;EACzC;IACE,SACE,cACA,OAAO,OAAO,cAAc,OAAO;;EAGvC,cAAc;EACd,UAAU,OAAO;EACjB,YAAY,OAAO;;iBA6GG,gBACtB,MAAM,eACN,gBACA,MAAM,aACN,OAAO"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { n as CompiledUnit } from "./compile-DZwVBjTM.mjs";
|
|
2
|
+
import { t as CSS_RESOLVE } from "./webpack-state-CXoQQ7XR.mjs";
|
|
3
|
+
//#region src/webpack-loader.d.ts
|
|
4
|
+
type SourceMap = CompiledUnit['map'];
|
|
5
|
+
/** The source map and metadata the loaders before this one passed on,
|
|
6
|
+
* handed through untouched when the stylesheet passes. */
|
|
7
|
+
interface IncomingMap {
|
|
8
|
+
readonly mappings?: string;
|
|
9
|
+
}
|
|
10
|
+
interface IncomingMeta {
|
|
11
|
+
readonly ast?: {
|
|
12
|
+
readonly type?: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** The loader context, as far as layergate reads it. */
|
|
16
|
+
interface LoaderContext {
|
|
17
|
+
resourcePath: string;
|
|
18
|
+
rootContext: string;
|
|
19
|
+
getOptions(): {
|
|
20
|
+
id?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Whether webpack may cache this module's build. */
|
|
23
|
+
cacheable(flag: boolean): void;
|
|
24
|
+
async(): (error: Error | null, code?: string, map?: SourceMap | IncomingMap, meta?: IncomingMeta) => void;
|
|
25
|
+
getResolve(options: typeof CSS_RESOLVE): (context: string, request: string) => Promise<string | false>;
|
|
26
|
+
fs: {
|
|
27
|
+
readFile(path: string, done: (error: Error | null, data?: Buffer | string) => void): void;
|
|
28
|
+
};
|
|
29
|
+
addDependency(file: string): void;
|
|
30
|
+
emitError(error: Error): void;
|
|
31
|
+
emitWarning(error: Error): void;
|
|
32
|
+
}
|
|
33
|
+
export default function layergateLoader(this: LoaderContext, source: string, map?: IncomingMap, meta?: IncomingMeta): void;
|
|
34
|
+
//#endregion
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=webpack-loader.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-loader.d.mts","names":[],"sources":["../src/webpack-loader.ts"],"mappings":";;;KAoBK,YAAY;;;UAIP;WACC;;UAED;WACC;aAAiB;;;;UAIlB;EACR;EACA;EACA;IAAgB;;;EAEhB,UAAU;EACV,UACE,OAAO,cACP,eACA,MAAM,YAAY,aAClB,OAAO;EAET,WACE,gBAAgB,eACd,iBAAiB,oBAAoB;EACzC;IACE,SACE,cACA,OAAO,OAAO,cAAc,OAAO;;EAGvC,cAAc;EACd,UAAU,OAAO;EACjB,YAAY,OAAO;;wBA6GG,gBACtB,MAAM,eACN,gBACA,MAAM,aACN,OAAO"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { t as readSheet } from "./sheet-DJGhbeYI.mjs";
|
|
2
|
+
import { t as compileUnit } from "./compile-Cu_GFS3l.mjs";
|
|
3
|
+
import { r as formatDiagnostic, s as slashes } from "./host-BGcb1rMJ.mjs";
|
|
4
|
+
import { r as registry, t as CSS_RESOLVE } from "./webpack-state-DwltSkQq.mjs";
|
|
5
|
+
import { dirname } from "node:path";
|
|
6
|
+
//#region src/webpack-loader.ts
|
|
7
|
+
/**
|
|
8
|
+
* layergate's webpack loader. It runs on each global stylesheet before
|
|
9
|
+
* PostCSS and css-loader (the plugin inserts it so). The declared sheets'
|
|
10
|
+
* stylesheet gets them at its head; a declared sheet a module imports
|
|
11
|
+
* itself loads nothing; an owned stylesheet is finished as an owned graph;
|
|
12
|
+
* an app stylesheet whose imports reach an owned file is finished with its
|
|
13
|
+
* own rules unlayered; anything else passes through. A finished stylesheet
|
|
14
|
+
* has no local `@import` left, and a remote one that would need a layer is
|
|
15
|
+
* refused: Next's css-loader renders `layer()` as media.
|
|
16
|
+
*/
|
|
17
|
+
/** A file through the compiler's file system. */
|
|
18
|
+
const readFrom = (context) => (path) => new Promise((done, fail) => context.fs.readFile(path, (error, data) => error ? fail(error) : done(String(data))));
|
|
19
|
+
/** The file an `@import` in `importer` reaches, where css-loader would
|
|
20
|
+
* reach it: by realpath unless `resolve.symlinks` is false. */
|
|
21
|
+
const resolveFrom = (context) => {
|
|
22
|
+
const resolver = context.getResolve(CSS_RESOLVE);
|
|
23
|
+
return async (specifier, importer) => {
|
|
24
|
+
const resolved = await resolver(dirname(importer), specifier).catch(() => null);
|
|
25
|
+
return resolved ? slashes(resolved) : null;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
async function finish(context, state, file, source, roots, extra = {}) {
|
|
29
|
+
const readFile = readFrom(context);
|
|
30
|
+
const read = (path) => path === file ? Promise.resolve(source) : readFile(path);
|
|
31
|
+
state.units.parsed.delete(file);
|
|
32
|
+
const { units, owner, optedOut, declaredBy } = state;
|
|
33
|
+
const unit = await compileUnit(roots, {
|
|
34
|
+
layer: state.plan.layer,
|
|
35
|
+
order: state.plan.order,
|
|
36
|
+
base: context.rootContext,
|
|
37
|
+
resolve: resolveFrom(context),
|
|
38
|
+
read,
|
|
39
|
+
quarantined: (path) => {
|
|
40
|
+
const canonical = units.canonical(path);
|
|
41
|
+
return !optedOut.has(canonical) && canonical !== declaredBy;
|
|
42
|
+
},
|
|
43
|
+
owns: (path) => owner.owns(units.canonical(path)),
|
|
44
|
+
remote: "refuse",
|
|
45
|
+
cache: state.units.parsed,
|
|
46
|
+
...extra
|
|
47
|
+
});
|
|
48
|
+
state.units.record(file, unit.files);
|
|
49
|
+
for (const path of unit.files) context.addDependency(path);
|
|
50
|
+
for (const diagnostic of unit.diagnostics) {
|
|
51
|
+
const error = new Error(formatDiagnostic(diagnostic));
|
|
52
|
+
if (diagnostic.severity === "error") context.emitError(error);
|
|
53
|
+
else if (diagnostic.severity === "warning") context.emitWarning(error);
|
|
54
|
+
}
|
|
55
|
+
return unit;
|
|
56
|
+
}
|
|
57
|
+
async function run(context, source) {
|
|
58
|
+
const state = registry().states.get(context.getOptions().id ?? "");
|
|
59
|
+
if (!state) return null;
|
|
60
|
+
const file = slashes(context.resourcePath);
|
|
61
|
+
const id = state.units.canonical(file);
|
|
62
|
+
const { owner, declaredBy } = state;
|
|
63
|
+
if (id === declaredBy) {
|
|
64
|
+
if (owner.declared.length === 0) return null;
|
|
65
|
+
const unit = await finish(context, state, file, source, state.roots, {
|
|
66
|
+
delivery: file,
|
|
67
|
+
map: false
|
|
68
|
+
});
|
|
69
|
+
context.cacheable(false);
|
|
70
|
+
return {
|
|
71
|
+
code: `${unit.css}\n${source}`,
|
|
72
|
+
map: null
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!owner.owning()) return null;
|
|
76
|
+
if (declaredBy && owner.declared.includes(id)) {
|
|
77
|
+
context.cacheable(false);
|
|
78
|
+
return {
|
|
79
|
+
code: "",
|
|
80
|
+
map: null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!owner.owns(id)) {
|
|
84
|
+
const { imports } = readSheet(source);
|
|
85
|
+
if (imports.length === 0) return null;
|
|
86
|
+
if (!await state.units.reaches(file, imports, {
|
|
87
|
+
resolve: resolveFrom(context),
|
|
88
|
+
read: readFrom(context),
|
|
89
|
+
owns: (path) => owner.owns(state.units.canonical(path))
|
|
90
|
+
})) return null;
|
|
91
|
+
}
|
|
92
|
+
const unit = await finish(context, state, file, source, [file]);
|
|
93
|
+
context.cacheable(false);
|
|
94
|
+
return {
|
|
95
|
+
code: unit.css,
|
|
96
|
+
map: unit.map
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function layergateLoader(source, map, meta) {
|
|
100
|
+
const done = this.async();
|
|
101
|
+
run(this, source).then((finished) => finished ? done(null, finished.code, finished.map) : done(null, source, map, meta), (error) => done(error));
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { layergateLoader as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "./compile-DZwVBjTM.cjs";
|
|
2
|
+
//#region src/webpack-state.d.ts
|
|
3
|
+
/** CSS resolution as css-loader resolves an `@import`: the `style`
|
|
4
|
+
* condition alone, its fields, CSS files only, relative first. */
|
|
5
|
+
declare const CSS_RESOLVE: {
|
|
6
|
+
conditionNames: string[];
|
|
7
|
+
mainFields: string[];
|
|
8
|
+
mainFiles: string[];
|
|
9
|
+
extensions: string[];
|
|
10
|
+
restrictions: RegExp[];
|
|
11
|
+
preferRelative: boolean;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { CSS_RESOLVE as t };
|
|
15
|
+
//# sourceMappingURL=webpack-state-BpF2PPjA.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-state-BpF2PPjA.d.cts","names":[],"sources":["../src/webpack-state.ts"],"mappings":";;;;cA8Ba;EACX;EACA;EACA;EACA;EACA,cAAY;EACZ"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let node_path = require("node:path");
|
|
2
|
+
let node_fs = require("node:fs");
|
|
3
|
+
let node_url = require("node:url");
|
|
4
|
+
//#region src/webpack-state.ts
|
|
5
|
+
/**
|
|
6
|
+
* What the webpack plugin and its loader share. webpack loads the loader
|
|
7
|
+
* from its own file, a module instance apart from the plugin's, so the
|
|
8
|
+
* state is kept on `globalThis`, by plugin id.
|
|
9
|
+
*/
|
|
10
|
+
/** CSS resolution as css-loader resolves an `@import`: the `style`
|
|
11
|
+
* condition alone, its fields, CSS files only, relative first. */
|
|
12
|
+
const CSS_RESOLVE = {
|
|
13
|
+
conditionNames: ["style"],
|
|
14
|
+
mainFields: [
|
|
15
|
+
"css",
|
|
16
|
+
"style",
|
|
17
|
+
"main",
|
|
18
|
+
"..."
|
|
19
|
+
],
|
|
20
|
+
mainFiles: ["index", "..."],
|
|
21
|
+
extensions: [".css"],
|
|
22
|
+
restrictions: [/\.css$/i],
|
|
23
|
+
preferRelative: true
|
|
24
|
+
};
|
|
25
|
+
const KEY = Symbol.for("@animus-ui/layergate/webpack");
|
|
26
|
+
function registry() {
|
|
27
|
+
const global = globalThis;
|
|
28
|
+
return global[KEY] ??= {
|
|
29
|
+
states: /* @__PURE__ */ new Map(),
|
|
30
|
+
made: 0
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const here = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
|
|
34
|
+
/** The loader's file: the built one beside this module, or the source in
|
|
35
|
+
* the workspace. */
|
|
36
|
+
function loaderPath() {
|
|
37
|
+
for (const built of ["webpack-loader.cjs", "webpack-loader.mjs"]) {
|
|
38
|
+
const path = (0, node_path.resolve)(here, built);
|
|
39
|
+
if ((0, node_fs.existsSync)(path)) return path;
|
|
40
|
+
}
|
|
41
|
+
return (0, node_path.resolve)(here, "webpack-loader.ts");
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
Object.defineProperty(exports, "CSS_RESOLVE", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function() {
|
|
47
|
+
return CSS_RESOLVE;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(exports, "loaderPath", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
get: function() {
|
|
53
|
+
return loaderPath;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
Object.defineProperty(exports, "registry", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
get: function() {
|
|
59
|
+
return registry;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "./compile-DZwVBjTM.mjs";
|
|
2
|
+
//#region src/webpack-state.d.ts
|
|
3
|
+
/** CSS resolution as css-loader resolves an `@import`: the `style`
|
|
4
|
+
* condition alone, its fields, CSS files only, relative first. */
|
|
5
|
+
declare const CSS_RESOLVE: {
|
|
6
|
+
conditionNames: string[];
|
|
7
|
+
mainFields: string[];
|
|
8
|
+
mainFiles: string[];
|
|
9
|
+
extensions: string[];
|
|
10
|
+
restrictions: RegExp[];
|
|
11
|
+
preferRelative: boolean;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { CSS_RESOLVE as t };
|
|
15
|
+
//# sourceMappingURL=webpack-state-CXoQQ7XR.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-state-CXoQQ7XR.d.mts","names":[],"sources":["../src/webpack-state.ts"],"mappings":";;;;cA8Ba;EACX;EACA;EACA;EACA;EACA,cAAY;EACZ"}
|