@navecss/core 0.2.0 → 0.4.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.
@@ -0,0 +1,86 @@
1
+ import { A as AtomName } from './atom-names-2OreuBx9.js';
2
+
3
+ /**
4
+ * The options that choose which atoms the Vite plugin ships, and their validation. A value a
5
+ * type would refuse in TypeScript is refused here too, so a JavaScript config gets the same
6
+ * answer; every text opens `navePlugin(): `, the prefix of the plugin's config-level messages.
7
+ */
8
+
9
+ interface UsedAtomOptions {
10
+ /**
11
+ * Which atoms the build ships. `'used'` (the default): the atoms your `cx()` calls and your
12
+ * written Nave classes name, plus those in `keep` and `keepFor`. Under the default the build
13
+ * filters the atomic layer of every stylesheet it can reach, and the dev server serves the same
14
+ * set as far as it has read; a stylesheet imported with `?inline` or `?raw` ships every atom
15
+ * with a warning; a `cx()` call whose atoms the build cannot read fails the build, and is an
16
+ * error in the dev server. In a build, each `cx()` call the plugin read also becomes the class
17
+ * string it returns.
18
+ * `'all'`: every atom, and no `cx()` call is read or rewritten, as with the PostCSS plugin.
19
+ */
20
+ atomic?: 'all' | 'used';
21
+ /**
22
+ * Atoms always shipped, whether or not the build reads a use of them: every atom your own
23
+ * `cx.dynamic()` calls can take, and the atom of each Nave class written where the build cannot
24
+ * read it, such as in a server template or in CMS text.
25
+ */
26
+ keep?: readonly AtomName[];
27
+ /**
28
+ * By package name: the atoms a dependency's own `cx()` calls can produce, for a package whose
29
+ * calls the build cannot read. They ship as if they were in `keep`, beside the atoms of the
30
+ * package's calls the build does read. The calls it cannot read are not changed, so any other
31
+ * atom they apply has no rule unless the build ships it for another reason. An empty list is
32
+ * accepted: it says those calls produce no atom, so the list adds none, and a `cx.dynamic()` call
33
+ * in the package still fails the build, as it does with no entry. A package in your own workspace
34
+ * is your code, not a dependency. The entry stands in for the package's own calls only: a
35
+ * re-export of `cx` in the package that the build reads and a module of yours takes (imports,
36
+ * re-exports or reads off a namespace, directly or through re-exports of it that the build reads,
37
+ * as `export ... from` or an import exported unchanged, in this package or another) still fails
38
+ * the build, because the calls your module makes through it would ship with no rule, and the
39
+ * message says how to clear it. Listing here a package that only re-exports it does not clear a
40
+ * take of yours, since a re-export is not a call. A server build that leaves the package external
41
+ * does not read it, so a take only your server code makes is judged by what the client build
42
+ * read: it fails the build as above when the client build read the re-export it takes and the
43
+ * build can read the take, and gets a warning naming `ssr.noExternal` when the build cannot tell,
44
+ * because no environment read the file the server loads, or your file reaches the package in a
45
+ * way the build cannot read as a take (a `require()`, say, or a `#` import); with separate client
46
+ * and server commands, the next client command judges what the last build of each server recorded
47
+ * of server files that still exist.
48
+ */
49
+ keepFor?: Readonly<Record<string, readonly AtomName[]>>;
50
+ /**
51
+ * Modules that re-export `cx` from `@navecss/core/cx` unchanged, as
52
+ * `export { cx } from '@navecss/core/cx'`, in your code or in a dependency: a file that imports
53
+ * `cx` from one is read as if it imported it from `@navecss/core/cx`. The build follows a listed
54
+ * module one step. A relative entry (`'./src/ui/index.ts'`) is a path from Vite's `root`. A
55
+ * package name or subpath, an alias or an absolute path matches an import written the same way.
56
+ * A `#` entry matches an import written the same way only where that import resolves to a listed
57
+ * file, since a `#` import resolves through the `package.json` nearest the file that writes it.
58
+ * Every entry also matches an import that resolves to its file through a specifier naming that
59
+ * file or, for an `index` file, its directory; in your code, an import that reaches the file
60
+ * through any other specifier fails the build instead. A relative entry that resolves to no file
61
+ * is ignored, and so is an entry naming `@navecss/core/cx`, which the build always reads. The
62
+ * same setting, with the same entries, as `@navecss/eslint-plugin`'s `cxModules`, which reads a
63
+ * relative entry from the working directory instead of Vite's `root`.
64
+ */
65
+ cxModules?: readonly string[];
66
+ }
67
+ interface ResolvedUsedOptions {
68
+ readonly atomic: 'all' | 'used';
69
+ readonly keep: readonly string[];
70
+ readonly keepFor: Readonly<Record<string, readonly string[]>>;
71
+ readonly cxModules: readonly string[];
72
+ }
73
+ /**
74
+ * Throws the first problem in the options, if there is one.
75
+ */
76
+ declare function assertOptions(options: UsedAtomOptions | ResolvedUsedOptions, own: ReadonlySet<string> | undefined): void;
77
+ /**
78
+ * The options with their defaults filled in.
79
+ */
80
+ declare function resolveUsedOptions(options: UsedAtomOptions): ResolvedUsedOptions;
81
+ /**
82
+ * Every atom the options always ship: `keep` and every `keepFor` list.
83
+ */
84
+ declare function keptAtoms(options: ResolvedUsedOptions): string[];
85
+
86
+ export { type ResolvedUsedOptions as R, type UsedAtomOptions as U, assertOptions as a, keptAtoms as k, resolveUsedOptions as r };
package/dist/vite.d.ts ADDED
@@ -0,0 +1,368 @@
1
+ import { AtomDefinition } from './atoms.js';
2
+ import { U as UsedAtomOptions } from './vite-options-D1-hGA9L.js';
3
+ import './atom-names-2OreuBx9.js';
4
+
5
+ /**
6
+ * The few shapes of Vite's (and Rollup's) own objects the plugin touches, declared here rather
7
+ * than imported: `@navecss/core/vite` takes no dependency and no peer, and a type import from
8
+ * `vite` would make the peer real for every consumer who type-checks it. Each interface is a
9
+ * structural subset of the real one, so Vite's own `Plugin` type accepts the plugin as it is.
10
+ */
11
+ interface LoggerLike {
12
+ warn(message: string, options?: unknown): void;
13
+ }
14
+ interface ResolvedConfigLike {
15
+ readonly root: string;
16
+ readonly command: string;
17
+ /**
18
+ * The config object the host was handed, which every environment of one invocation shares.
19
+ */
20
+ readonly inlineConfig?: object;
21
+ readonly cacheDir?: string;
22
+ /**
23
+ * Set when the config asks for a builder, so one process builds every environment.
24
+ */
25
+ readonly builder?: unknown;
26
+ readonly css?: {
27
+ readonly devSourcemap?: boolean;
28
+ readonly transformer?: string;
29
+ };
30
+ readonly build?: {
31
+ readonly lib?: unknown;
32
+ readonly sourcemap?: unknown;
33
+ };
34
+ readonly logger: LoggerLike;
35
+ /**
36
+ * The plugins of the build, Vite's own among them.
37
+ */
38
+ readonly plugins?: readonly PluginLike[];
39
+ }
40
+ /**
41
+ * A plugin as another plugin finds it in an environment's list: by name, with a `transform` that
42
+ * is a function or Rolldown's `{ handler }` object.
43
+ */
44
+ interface PluginLike {
45
+ readonly name: string;
46
+ readonly transform?: unknown;
47
+ }
48
+ /**
49
+ * A module of a dev server's module graph: its id and URL, the modules that import it and the
50
+ * ones it imports (static and dynamic alike).
51
+ */
52
+ interface GraphModuleLike {
53
+ readonly id: string | null;
54
+ readonly url: string;
55
+ readonly importers: ReadonlySet<GraphModuleLike>;
56
+ readonly importedModules: ReadonlySet<GraphModuleLike>;
57
+ }
58
+ /**
59
+ * The builder `buildApp` is given: its environments by name, and whether each has been built.
60
+ */
61
+ interface BuilderLike {
62
+ readonly environments: Readonly<Record<string, {
63
+ readonly isBuilt: boolean;
64
+ }>>;
65
+ }
66
+ /**
67
+ * The environment a hook runs for: a name, whether it renders for a browser or a server, and the
68
+ * plugins it runs.
69
+ */
70
+ interface EnvironmentLike {
71
+ readonly name: string;
72
+ readonly config: {
73
+ readonly command?: string;
74
+ readonly consumer: string;
75
+ readonly inlineConfig?: object;
76
+ readonly root?: string;
77
+ };
78
+ readonly plugins: readonly PluginLike[];
79
+ }
80
+ /**
81
+ * A location in the shape Rollup reports one: 1-based line, 0-based column.
82
+ */
83
+ interface LogLocation {
84
+ readonly file?: string;
85
+ readonly line: number;
86
+ readonly column: number;
87
+ }
88
+ interface PluginLog {
89
+ readonly message: string;
90
+ readonly id?: string;
91
+ readonly loc?: LogLocation;
92
+ }
93
+ interface IncomingSourceMap {
94
+ readonly sources: readonly string[];
95
+ readonly sourceRoot?: string | undefined;
96
+ readonly sourcesContent?: readonly (string | null)[] | undefined;
97
+ readonly names?: readonly string[] | undefined;
98
+ readonly mappings: string;
99
+ }
100
+ /**
101
+ * What the host tells a `transform` hook about the module besides its text.
102
+ */
103
+ interface TransformMeta {
104
+ readonly moduleType?: string;
105
+ }
106
+ interface TransformContext {
107
+ error(error: PluginLog): never;
108
+ warn(warning: PluginLog): void;
109
+ addWatchFile(id: string): void;
110
+ getCombinedSourcemap(): IncomingSourceMap;
111
+ /**
112
+ The environment the module is being transformed for; `client` when a host gives none.
113
+ */
114
+ readonly environment?: EnvironmentLike;
115
+ /**
116
+ * The host's parse of `code`, an ESTree (read as an `AstNode`).
117
+ */
118
+ parse(code: string, options?: {
119
+ readonly lang?: 'dts' | 'js' | 'jsx' | 'ts' | 'tsx';
120
+ }): unknown;
121
+ /**
122
+ * Resolves `source` as imported from `importer`.
123
+ */
124
+ resolve?(source: string, importer: string): Promise<{
125
+ readonly id: string;
126
+ } | null>;
127
+ /**
128
+ * Loads, and so transforms, the module `options.id`.
129
+ */
130
+ load?(options: {
131
+ readonly id: string;
132
+ }): Promise<unknown>;
133
+ }
134
+ /**
135
+ * What the dev server hands `hotUpdate`: the file that changed.
136
+ */
137
+ interface HotUpdateOptions {
138
+ readonly file: string;
139
+ /**
140
+ * The modules the changed file belongs to, which the update is about to reload.
141
+ */
142
+ readonly modules?: readonly GraphModuleLike[];
143
+ }
144
+ /**
145
+ * The environment `hotUpdate` runs in: its module graph, and the channel to its client.
146
+ */
147
+ interface HotUpdateContext {
148
+ readonly environment: {
149
+ readonly config?: {
150
+ readonly command?: string;
151
+ readonly consumer?: string;
152
+ readonly inlineConfig?: object;
153
+ };
154
+ readonly hot: {
155
+ send(payload: {
156
+ type: 'full-reload';
157
+ }): void;
158
+ };
159
+ readonly moduleGraph: {
160
+ getModuleById(id: string): unknown;
161
+ invalidateModule(module: never): void;
162
+ };
163
+ readonly name: string;
164
+ transformRequest?(url: string): Promise<unknown>;
165
+ };
166
+ }
167
+ interface BundleContext {
168
+ error(error: PluginLog): never;
169
+ warn(warning: PluginLog | string): void;
170
+ readonly environment?: EnvironmentLike;
171
+ }
172
+ /**
173
+ * What the module graph holds about one module: its transformed text, and who imports it.
174
+ */
175
+ interface ModuleInfoLike {
176
+ readonly code: string | null;
177
+ readonly importers: readonly string[];
178
+ readonly dynamicImporters: readonly string[];
179
+ /**
180
+ * The ids the module imports, statically and dynamically, externals included.
181
+ */
182
+ readonly importedIds?: readonly string[];
183
+ readonly dynamicallyImportedIds?: readonly string[];
184
+ }
185
+ /**
186
+ * What `renderChunk` and `buildEnd` are given: the environment, and the ways to fail or warn.
187
+ */
188
+ interface RenderContext {
189
+ error(error: PluginLog | string): never;
190
+ warn(warning: PluginLog | string): void;
191
+ readonly environment: EnvironmentLike;
192
+ /**
193
+ * The ids of every module the environment's build loaded, externals included.
194
+ */
195
+ getModuleIds?(): IterableIterator<string>;
196
+ /**
197
+ * What the module graph holds about the module `id`, or `null` when it holds none.
198
+ */
199
+ getModuleInfo?(id: string): ModuleInfoLike | null;
200
+ /**
201
+ * Resolves `source` as imported from `importer`.
202
+ */
203
+ resolve?(source: string, importer?: string): Promise<{
204
+ readonly id: string;
205
+ } | null>;
206
+ /**
207
+ * The host's parse of `code`, an ESTree (read as an `AstNode`).
208
+ */
209
+ parse?(code: string): unknown;
210
+ }
211
+ interface RenderedChunk {
212
+ readonly modules: Readonly<Record<string, unknown>>;
213
+ }
214
+ interface BundleEntry {
215
+ readonly type: string;
216
+ readonly fileName: string;
217
+ readonly source?: string | Uint8Array;
218
+ }
219
+ interface TransformResultLike {
220
+ readonly code: string;
221
+ readonly map: string;
222
+ }
223
+
224
+ interface HtmlHook {
225
+ readonly order: 'pre';
226
+ handler(html: string, context: {
227
+ readonly filename?: string;
228
+ }): undefined;
229
+ }
230
+ interface NaveCollectPlugin {
231
+ readonly name: 'nave:collect';
232
+ readonly enforce: 'post';
233
+ transform(this: TransformContext, code: string, id: string, meta?: TransformMeta): Promise<TransformResultLike | undefined>;
234
+ readonly transformIndexHtml: HtmlHook;
235
+ buildStart(this: RenderContext): Promise<void>;
236
+ buildEnd(this: RenderContext, error?: unknown): Promise<void>;
237
+ }
238
+
239
+ /**
240
+ * A module worker is bundled by a build of its own, which runs the plugins of `worker.plugins`
241
+ * and none of the build's. The code it ships is code the build reads, so the plugin adds this one:
242
+ * it reads each module of that build as a module of the client environment, into the state the
243
+ * build's own plugins share, and reports nothing itself (its problems are reported once, with
244
+ * the rest, when the build ends), except that a worker's import of `cx` through an alias fails
245
+ * its own build, since no later step sees the worker's module graph.
246
+ */
247
+
248
+ interface NaveWorkerPlugin {
249
+ readonly name: 'nave:collect-worker';
250
+ readonly enforce: 'post';
251
+ transform(this: TransformContext, code: string, id: string, meta?: TransformMeta): Promise<TransformResultLike | undefined>;
252
+ buildEnd(this: RenderContext, error?: unknown): Promise<void>;
253
+ }
254
+
255
+ /**
256
+ * The config the plugin adds under the default. `cx.dynamic()` resolves through the map of the
257
+ * atoms in `keep` and every `keepFor` list, handed to it as a `define` constant: static data,
258
+ * folded into the bundle in a build, and in dev the same map behind the console texts. And
259
+ * `@navecss/core` is bundled into every server environment, so that constant folds into a server
260
+ * build's `cx.dynamic()` too, and it is left out of the dev server's prebundling, so a
261
+ * prebundled dependency keeps its import of `cx` and the plugin reads the calls it makes.
262
+ */
263
+
264
+ interface UsedConfig {
265
+ readonly define: Record<string, string>;
266
+ /**
267
+ * The dev server serves `@navecss/core` as its own modules, not one prebundled chunk.
268
+ */
269
+ readonly optimizeDeps: {
270
+ readonly exclude: string[];
271
+ };
272
+ /**
273
+ * A module worker is bundled by a build of its own: this adds the plugin that reads its code.
274
+ */
275
+ readonly worker: {
276
+ readonly plugins: () => NaveWorkerPlugin[];
277
+ };
278
+ }
279
+
280
+ /**
281
+ * Nave Vite plugin: expands `@nave` directives in every stylesheet Vite compiles, fails the build
282
+ * when one survives into its CSS output, and by default filters the atomic layer of every stylesheet it can reach down to the atoms the build reads a use for.
283
+ *
284
+ * Setup:
285
+ * import { navePlugin } from '@navecss/core/vite'
286
+ * export default { plugins: [navePlugin()] } // Nave atoms only, fails on a problem
287
+ * navePlugin({ extend: myAtoms }) // Nave + consumer atoms
288
+ * navePlugin({ extend: './my-atoms.mjs' }) // the same, from a module Vite watches
289
+ * navePlugin({ onUnknown: 'warn' }) // report a problem and skip it
290
+ * navePlugin({ keep: ['grid'] }) // atoms a cx.dynamic() call can take
291
+ * navePlugin({ cxModules: ['./src/ui/index.ts'] }) // modules that re-export cx
292
+ * navePlugin({ atomic: 'all' }) // ship every atom, read no cx() call
293
+ *
294
+ * `navePlugin()` returns two plain Vite plugin objects with no dependency and no peer, in an array
295
+ * that `plugins` takes as one entry. The first runs in Vite's normal order, after Vite's own CSS
296
+ * step, so a stylesheet reached through `@import`, a Sass or Less file, a CSS Module, and a Vue
297
+ * or Svelte style block are all read as the CSS they compile to. It never runs before Vite's CSS
298
+ * step: that order misses `@import`-reached files and breaks Sass `@mixin`. The second runs in
299
+ * post order and reads the JavaScript. Neither adds runtime machinery to the browser bundle.
300
+ */
301
+
302
+ interface NaveViteOptions extends UsedAtomOptions {
303
+ /**
304
+ * Consumer-defined atoms merged with Nave built-in atoms. Consumer atoms win on name collision.
305
+ * These atoms resolve via @nave only. No global class. Not available in cx().
306
+ *
307
+ * A string is a path to a module instead, resolved against Vite's project root, whose default
308
+ * export is the atom map. The module is loaded again whenever its bytes change and Vite watches
309
+ * it, so editing it re-runs the stylesheets that use it with no restart. An atom object written
310
+ * inline here is not a file Vite can watch.
311
+ */
312
+ extend?: Record<string, AtomDefinition> | string;
313
+ /**
314
+ * Behaviour on a problem in a @nave directive: an unknown atom name, no atom named at all,
315
+ * anything but a name between the names (a comma, a string), a {} block, or a place the
316
+ * directive cannot expand. Under 'error', every such problem in one stylesheet is reported in
317
+ * one error.
318
+ * 'warn' — log and skip
319
+ * 'error' — fail the build (default)
320
+ * 'ignore' — silently skip
321
+ */
322
+ onUnknown?: 'warn' | 'error' | 'ignore';
323
+ }
324
+ /**
325
+ * The first plugin object. Its `name` is the public string `nave`, the prefix of every message it
326
+ * prints.
327
+ */
328
+ interface NaveVitePlugin {
329
+ readonly name: 'nave';
330
+ config(config?: unknown, env?: {
331
+ readonly command?: string;
332
+ }): UsedConfig | undefined;
333
+ configEnvironment(name: string, options: {
334
+ readonly consumer?: string;
335
+ }): {
336
+ resolve: {
337
+ noExternal: string[];
338
+ };
339
+ } | undefined;
340
+ configResolved(config: ResolvedConfigLike): void;
341
+ configureServer(server: unknown): void;
342
+ closeBundle(this: {
343
+ readonly environment?: object;
344
+ }): void;
345
+ readonly buildApp: {
346
+ handler(this: {
347
+ warn(message: string): void;
348
+ }, builder: BuilderLike): Promise<void>;
349
+ readonly order: 'post';
350
+ };
351
+ transform(this: TransformContext, code: string, id: string): Promise<TransformResultLike | undefined>;
352
+ hotUpdate(this: HotUpdateContext, options: HotUpdateOptions): Promise<never[] | undefined> | never[] | undefined;
353
+ renderChunk(this: RenderContext, code: string, chunk: RenderedChunk): Promise<undefined>;
354
+ readonly generateBundle: {
355
+ handler(this: BundleContext, options: unknown, bundle: Record<string, BundleEntry>): void;
356
+ readonly order: 'post';
357
+ };
358
+ }
359
+ /**
360
+ * What `navePlugin()` returns: the same two plugin objects whatever the options.
361
+ */
362
+ type NavePlugins = [NaveVitePlugin, NaveCollectPlugin];
363
+ /**
364
+ * The Nave Vite plugin: one entry in `plugins`.
365
+ */
366
+ declare function navePlugin(options?: NaveViteOptions): NavePlugins;
367
+
368
+ export { type NavePlugins, type NaveViteOptions, type NaveVitePlugin, navePlugin as default, navePlugin };