@nifrajs/cli 2.1.0 → 2.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/dist/check.d.ts +4 -1
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +71 -0
- package/dist/check.js.map +1 -1
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +165 -23
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +5 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +66 -6
- package/dist/doctor.js.map +1 -1
- package/dist/load.d.ts +11 -0
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +30 -0
- package/dist/load.js.map +1 -1
- package/dist/mcp-docs-tools.d.ts.map +1 -1
- package/dist/mcp-docs-tools.js +7 -3
- package/dist/mcp-docs-tools.js.map +1 -1
- package/dist/mcp-http.js +1 -1
- package/dist/mcp-render.js +9 -1
- package/dist/mcp-render.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +44 -2
- package/dist/mcp.js.map +1 -1
- package/dist/pipeline-guard.d.ts +83 -0
- package/dist/pipeline-guard.d.ts.map +1 -0
- package/dist/pipeline-guard.js +136 -0
- package/dist/pipeline-guard.js.map +1 -0
- package/dist/types-search.d.ts +1 -1
- package/dist/types-search.d.ts.map +1 -1
- package/dist/types-search.js +47 -2
- package/dist/types-search.js.map +1 -1
- package/docs/examples.json +6 -0
- package/docs/llms-full.txt +81 -30
- package/docs/types.json +613 -36
- package/package.json +9 -9
- package/src/check.ts +91 -0
- package/src/cli.ts +173 -24
- package/src/doctor.ts +71 -6
- package/src/load.ts +44 -0
- package/src/mcp-docs-tools.ts +13 -3
- package/src/mcp-http.ts +1 -1
- package/src/mcp-render.ts +9 -1
- package/src/mcp.ts +45 -2
- package/src/pipeline-guard.ts +186 -0
- package/src/types-search.ts +50 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline separation guard — one bundler owns a phase, never two.
|
|
3
|
+
*
|
|
4
|
+
* nifra supports both Vite and Bun, and the config keeps them in separate slots: `vitePlugins` for
|
|
5
|
+
* the Vite pipeline, `clientPlugins`/`serverPlugins` for the Bun one. Nothing enforces the split, so
|
|
6
|
+
* a plugin lands in the wrong slot and is silently ignored - a Vite plugin in `clientPlugins` is
|
|
7
|
+
* handed to `Bun.build`, which has no `transform` hook to call, so the transform simply never runs
|
|
8
|
+
* and the build succeeds.
|
|
9
|
+
*
|
|
10
|
+
* That failure mode is the whole reason for this file. nifra's expensive bugs are not caused by Vite
|
|
11
|
+
* or by Bun; they are caused by two toolchains disagreeing about one module. Dual-React is that, the
|
|
12
|
+
* dedupe plugins are patches for that, and a `resolve.alias` that never reaches SSR is that. Mixing
|
|
13
|
+
* is the defect - choice is not - so the separation has to be checked rather than documented.
|
|
14
|
+
*
|
|
15
|
+
* Detection is by hook shape, which is what each bundler actually dispatches on:
|
|
16
|
+
* - a Bun plugin has `setup(build)`
|
|
17
|
+
* - a Rollup/Vite plugin has `resolveId` / `load` / `transform` / `config` / `configResolved` /
|
|
18
|
+
* `transformIndexHtml` and no `setup`
|
|
19
|
+
*
|
|
20
|
+
* Deliberately conservative: a plugin that matches neither shape is left alone rather than guessed
|
|
21
|
+
* at. A guard that fires on correct config is a guard people turn off.
|
|
22
|
+
*/
|
|
23
|
+
/** Which pipeline a slot belongs to. */
|
|
24
|
+
export type PipelineSlot = "vitePlugins" | "clientPlugins" | "serverPlugins";
|
|
25
|
+
export interface PipelineMismatch {
|
|
26
|
+
readonly slot: PipelineSlot;
|
|
27
|
+
/** The plugin's `name`, or a positional label when it has none. */
|
|
28
|
+
readonly plugin: string;
|
|
29
|
+
/** The pipeline the slot feeds. */
|
|
30
|
+
readonly expected: "vite" | "bun";
|
|
31
|
+
/** The pipeline the plugin's hooks say it belongs to. */
|
|
32
|
+
readonly actual: "vite" | "bun";
|
|
33
|
+
readonly fix: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check one slot's resolved plugin list. Pure: takes the already-resolved array so a thunk-valued
|
|
37
|
+
* field is awaited by the caller, and so this stays testable without loading a project.
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkPipelineSlot(slot: PipelineSlot, plugins: readonly unknown[]): PipelineMismatch[];
|
|
40
|
+
/** Check every slot of a resolved framework config. */
|
|
41
|
+
export declare function checkPipelineSeparation(slots: {
|
|
42
|
+
readonly vitePlugins?: readonly unknown[];
|
|
43
|
+
readonly clientPlugins?: readonly unknown[];
|
|
44
|
+
readonly serverPlugins?: readonly unknown[];
|
|
45
|
+
}): PipelineMismatch[];
|
|
46
|
+
/** Which bundler a build runs on. */
|
|
47
|
+
export type BuildPipeline = "bun" | "vite";
|
|
48
|
+
export interface PipelineDecision {
|
|
49
|
+
readonly pipeline: BuildPipeline;
|
|
50
|
+
/**
|
|
51
|
+
* Why this pipeline, for the `nifra build` log line - so an auto-selected Vite build never looks
|
|
52
|
+
* like the user got the default. `undefined` when the choice was the plain default or was forced.
|
|
53
|
+
*/
|
|
54
|
+
readonly reason?: string;
|
|
55
|
+
}
|
|
56
|
+
/** The plugin slots a decision reads, already resolved. */
|
|
57
|
+
export interface PipelineSlots {
|
|
58
|
+
readonly vitePlugins?: readonly unknown[];
|
|
59
|
+
readonly clientPlugins?: readonly unknown[];
|
|
60
|
+
readonly serverPlugins?: readonly unknown[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Pick the bundler for `nifra build`, per app rather than per global default.
|
|
64
|
+
*
|
|
65
|
+
* The phase defaults are deliberately asymmetric - `nifra dev` is Vite (for the plugin ecosystem, and
|
|
66
|
+
* because Bun's DEV-server bundler cannot compile CSS Modules), `nifra build` is Bun (faster and
|
|
67
|
+
* Bun-native). For an app with no transforms that asymmetry is free: there is nothing to disagree about.
|
|
68
|
+
* For an app whose ONLY transforms are Vite plugins it is not. Those plugins run in dev and are then
|
|
69
|
+
* dropped by the Bun build - `buildForTarget` reads `clientPlugins`/`serverPlugins`, never `vitePlugins`
|
|
70
|
+
* - so the build succeeds, the output looks plausible, and the transform simply did not happen. That is
|
|
71
|
+
* the same failure {@link checkPipelineSeparation} exists to prevent, reached by crossing PHASES instead
|
|
72
|
+
* of slots, and the slot check cannot see it because the plugins are correctly placed.
|
|
73
|
+
*
|
|
74
|
+
* So the default follows the app: Vite plugins with no Bun counterpart means the app has exactly one
|
|
75
|
+
* pipeline that can build it, and that is the one used. An app declaring BOTH has supplied the Bun
|
|
76
|
+
* equivalent on purpose - nothing is dropped - so the fast Bun default stands.
|
|
77
|
+
*
|
|
78
|
+
* `forced` is `--vite` / `--bun` and always wins, except for the one combination that silently discards
|
|
79
|
+
* work, which throws instead. Refusing rather than warning matches the slot guard: a build that succeeds
|
|
80
|
+
* and omits the transform is worse than one that stops and says so.
|
|
81
|
+
*/
|
|
82
|
+
export declare function chooseBuildPipeline(slots: PipelineSlots, forced?: BuildPipeline): PipelineDecision;
|
|
83
|
+
//# sourceMappingURL=pipeline-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-guard.d.ts","sourceRoot":"","sources":["../src/pipeline-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,wCAAwC;AACxC,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,eAAe,GAAG,eAAe,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAA;IACjC,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAA;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAmCD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,gBAAgB,EAAE,CAqBpB;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAC5C,GAAG,gBAAgB,EAAE,CAMrB;AAED,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAA;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;IAChC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAC5C;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,MAAM,CAAC,EAAE,aAAa,GACrB,gBAAgB,CAsBlB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline separation guard — one bundler owns a phase, never two.
|
|
3
|
+
*
|
|
4
|
+
* nifra supports both Vite and Bun, and the config keeps them in separate slots: `vitePlugins` for
|
|
5
|
+
* the Vite pipeline, `clientPlugins`/`serverPlugins` for the Bun one. Nothing enforces the split, so
|
|
6
|
+
* a plugin lands in the wrong slot and is silently ignored - a Vite plugin in `clientPlugins` is
|
|
7
|
+
* handed to `Bun.build`, which has no `transform` hook to call, so the transform simply never runs
|
|
8
|
+
* and the build succeeds.
|
|
9
|
+
*
|
|
10
|
+
* That failure mode is the whole reason for this file. nifra's expensive bugs are not caused by Vite
|
|
11
|
+
* or by Bun; they are caused by two toolchains disagreeing about one module. Dual-React is that, the
|
|
12
|
+
* dedupe plugins are patches for that, and a `resolve.alias` that never reaches SSR is that. Mixing
|
|
13
|
+
* is the defect - choice is not - so the separation has to be checked rather than documented.
|
|
14
|
+
*
|
|
15
|
+
* Detection is by hook shape, which is what each bundler actually dispatches on:
|
|
16
|
+
* - a Bun plugin has `setup(build)`
|
|
17
|
+
* - a Rollup/Vite plugin has `resolveId` / `load` / `transform` / `config` / `configResolved` /
|
|
18
|
+
* `transformIndexHtml` and no `setup`
|
|
19
|
+
*
|
|
20
|
+
* Deliberately conservative: a plugin that matches neither shape is left alone rather than guessed
|
|
21
|
+
* at. A guard that fires on correct config is a guard people turn off.
|
|
22
|
+
*/
|
|
23
|
+
const ROLLUP_HOOKS = [
|
|
24
|
+
"resolveId",
|
|
25
|
+
"load",
|
|
26
|
+
"transform",
|
|
27
|
+
"config",
|
|
28
|
+
"configResolved",
|
|
29
|
+
"configureServer",
|
|
30
|
+
"transformIndexHtml",
|
|
31
|
+
"generateBundle",
|
|
32
|
+
"renderChunk",
|
|
33
|
+
];
|
|
34
|
+
/** Classify a plugin by the hooks it exposes, or `undefined` when its shape says nothing. */
|
|
35
|
+
function classify(plugin) {
|
|
36
|
+
if (typeof plugin !== "object" || plugin === null)
|
|
37
|
+
return undefined;
|
|
38
|
+
const record = plugin;
|
|
39
|
+
// `setup` is Bun's only entry point, so its presence is decisive even alongside other keys.
|
|
40
|
+
if (typeof record.setup === "function")
|
|
41
|
+
return "bun";
|
|
42
|
+
if (ROLLUP_HOOKS.some((hook) => typeof record[hook] === "function"))
|
|
43
|
+
return "vite";
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const SLOT_PIPELINE = {
|
|
47
|
+
vitePlugins: "vite",
|
|
48
|
+
clientPlugins: "bun",
|
|
49
|
+
serverPlugins: "bun",
|
|
50
|
+
};
|
|
51
|
+
const MOVE_TO = {
|
|
52
|
+
vite: "`vitePlugins`",
|
|
53
|
+
bun: "`clientPlugins` (client bundle) or `serverPlugins` (SSR)",
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Check one slot's resolved plugin list. Pure: takes the already-resolved array so a thunk-valued
|
|
57
|
+
* field is awaited by the caller, and so this stays testable without loading a project.
|
|
58
|
+
*/
|
|
59
|
+
export function checkPipelineSlot(slot, plugins) {
|
|
60
|
+
const expected = SLOT_PIPELINE[slot];
|
|
61
|
+
const out = [];
|
|
62
|
+
for (let i = 0; i < plugins.length; i++) {
|
|
63
|
+
const plugin = plugins[i];
|
|
64
|
+
const actual = classify(plugin);
|
|
65
|
+
if (actual === undefined || actual === expected)
|
|
66
|
+
continue;
|
|
67
|
+
const named = plugin.name;
|
|
68
|
+
const label = typeof named === "string" && named !== "" ? named : `${slot}[${i}]`;
|
|
69
|
+
out.push({
|
|
70
|
+
slot,
|
|
71
|
+
plugin: label,
|
|
72
|
+
expected,
|
|
73
|
+
actual,
|
|
74
|
+
fix: actual === "vite"
|
|
75
|
+
? `"${label}" is a Vite/Rollup plugin (it defines Rollup hooks, not \`setup\`) but sits in \`${slot}\`, which feeds Bun.build. Bun never calls those hooks, so the transform silently does not run. Move it to ${MOVE_TO.vite}.`
|
|
76
|
+
: `"${label}" is a Bun plugin (it defines \`setup\`) but sits in \`${slot}\`, which feeds Vite. Vite never calls \`setup\`, so the transform silently does not run. Move it to ${MOVE_TO.bun}.`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
/** Check every slot of a resolved framework config. */
|
|
82
|
+
export function checkPipelineSeparation(slots) {
|
|
83
|
+
return [
|
|
84
|
+
...checkPipelineSlot("vitePlugins", slots.vitePlugins ?? []),
|
|
85
|
+
...checkPipelineSlot("clientPlugins", slots.clientPlugins ?? []),
|
|
86
|
+
...checkPipelineSlot("serverPlugins", slots.serverPlugins ?? []),
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
const pluginNames = (plugins) => plugins
|
|
90
|
+
.map((plugin, i) => {
|
|
91
|
+
const named = plugin.name;
|
|
92
|
+
return typeof named === "string" && named !== "" ? named : `vitePlugins[${i}]`;
|
|
93
|
+
})
|
|
94
|
+
.join(", ");
|
|
95
|
+
/**
|
|
96
|
+
* Pick the bundler for `nifra build`, per app rather than per global default.
|
|
97
|
+
*
|
|
98
|
+
* The phase defaults are deliberately asymmetric - `nifra dev` is Vite (for the plugin ecosystem, and
|
|
99
|
+
* because Bun's DEV-server bundler cannot compile CSS Modules), `nifra build` is Bun (faster and
|
|
100
|
+
* Bun-native). For an app with no transforms that asymmetry is free: there is nothing to disagree about.
|
|
101
|
+
* For an app whose ONLY transforms are Vite plugins it is not. Those plugins run in dev and are then
|
|
102
|
+
* dropped by the Bun build - `buildForTarget` reads `clientPlugins`/`serverPlugins`, never `vitePlugins`
|
|
103
|
+
* - so the build succeeds, the output looks plausible, and the transform simply did not happen. That is
|
|
104
|
+
* the same failure {@link checkPipelineSeparation} exists to prevent, reached by crossing PHASES instead
|
|
105
|
+
* of slots, and the slot check cannot see it because the plugins are correctly placed.
|
|
106
|
+
*
|
|
107
|
+
* So the default follows the app: Vite plugins with no Bun counterpart means the app has exactly one
|
|
108
|
+
* pipeline that can build it, and that is the one used. An app declaring BOTH has supplied the Bun
|
|
109
|
+
* equivalent on purpose - nothing is dropped - so the fast Bun default stands.
|
|
110
|
+
*
|
|
111
|
+
* `forced` is `--vite` / `--bun` and always wins, except for the one combination that silently discards
|
|
112
|
+
* work, which throws instead. Refusing rather than warning matches the slot guard: a build that succeeds
|
|
113
|
+
* and omits the transform is worse than one that stops and says so.
|
|
114
|
+
*/
|
|
115
|
+
export function chooseBuildPipeline(slots, forced) {
|
|
116
|
+
const vitePlugins = slots.vitePlugins ?? [];
|
|
117
|
+
const bunPlugins = [...(slots.clientPlugins ?? []), ...(slots.serverPlugins ?? [])];
|
|
118
|
+
const viteOnly = vitePlugins.length > 0 && bunPlugins.length === 0;
|
|
119
|
+
if (forced === "bun" && viteOnly) {
|
|
120
|
+
throw new Error("[nifra] `nifra build --bun` would silently drop this app's only transforms. `vitePlugins` are " +
|
|
121
|
+
"read by the Vite build; the Bun build reads `clientPlugins`/`serverPlugins`, so these would " +
|
|
122
|
+
"never run and the output would look plausible without them.\n" +
|
|
123
|
+
` Would be dropped: ${pluginNames(vitePlugins)}\n` +
|
|
124
|
+
" Drop the flag to build with Vite, or add the Bun equivalents to `clientPlugins`/`serverPlugins`.");
|
|
125
|
+
}
|
|
126
|
+
if (forced !== undefined)
|
|
127
|
+
return { pipeline: forced };
|
|
128
|
+
if (viteOnly) {
|
|
129
|
+
return {
|
|
130
|
+
pipeline: "vite",
|
|
131
|
+
reason: `auto: this app's only transforms are \`vitePlugins\` (${pluginNames(vitePlugins)}), which the Bun build cannot run`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { pipeline: "bun" };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=pipeline-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-guard.js","sourceRoot":"","sources":["../src/pipeline-guard.ts"],"names":[],"mappings":"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"}
|
package/dist/types-search.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export declare function searchTypes(types: readonly TypeEntry[], query: string,
|
|
|
30
30
|
* per-package index of type names. The signatures are authoritative (generated from the built `.d.ts`),
|
|
31
31
|
* so this is the complete answer — there is no need to read a `.d.ts` file.
|
|
32
32
|
*/
|
|
33
|
-
export declare function renderTypesResult(types: readonly TypeEntry[], name: string | undefined, query: string | undefined, limit: number): string;
|
|
33
|
+
export declare function renderTypesResult(types: readonly TypeEntry[], name: string | undefined, query: string | undefined, limit: number, full?: boolean): string;
|
|
34
34
|
/** Load the bundled type corpus (`docs/types.json`), resolved relative to this module so it works from
|
|
35
35
|
* `src/` (dev) and `dist/` (published) alike. */
|
|
36
36
|
export declare function loadTypesCorpus(): Promise<TypeEntry[] | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-search.d.ts","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;6BAC6B;AAC7B,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAGjF;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,UAAU,EAAE,CAed;
|
|
1
|
+
{"version":3,"file":"types-search.d.ts","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAA;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED;6BAC6B;AAC7B,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAGjF;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,UAAU,EAAE,CAed;AAuDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,EACb,IAAI,UAAQ,GACX,MAAM,CA2BR;AAED;iDACiD;AACjD,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAUxE"}
|
package/dist/types-search.js
CHANGED
|
@@ -40,12 +40,56 @@ function renderEntry(t) {
|
|
|
40
40
|
const doc = t.doc ? `${t.doc}\n` : "";
|
|
41
41
|
return `${head}\n\n\`\`\`ts\n${doc}${t.signature}\n\`\`\``;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Longest signature rendered whole in a SEARCH result.
|
|
45
|
+
*
|
|
46
|
+
* Search is "which symbol did I mean?", not "show me everything about it" - and the corpus is wildly
|
|
47
|
+
* uneven: the median declaration is small, while `Server` alone is ~32,000 characters, five times the
|
|
48
|
+
* next largest. One broad query that happened to match it returned the entire class for near-zero
|
|
49
|
+
* value. Above this, a search result shows the head plus a member count and says how to get the rest;
|
|
50
|
+
* an exact `name` lookup is never collapsed, because there the caller asked for that symbol.
|
|
51
|
+
*/
|
|
52
|
+
const SEARCH_SIGNATURE_MAX = 600;
|
|
53
|
+
/** First sentence of the doc block, flattened to one line - enough to pick between candidates. */
|
|
54
|
+
function summarize(doc) {
|
|
55
|
+
if (doc === undefined)
|
|
56
|
+
return "";
|
|
57
|
+
const text = doc
|
|
58
|
+
.replace(/\/\*\*|\*\/|^\s*\*/gm, " ")
|
|
59
|
+
.replace(/\s+/g, " ")
|
|
60
|
+
.trim();
|
|
61
|
+
if (text === "")
|
|
62
|
+
return "";
|
|
63
|
+
const end = text.search(/\.\s|\.$/);
|
|
64
|
+
const sentence = end === -1 ? text : text.slice(0, end + 1);
|
|
65
|
+
return sentence.length > 200 ? `${sentence.slice(0, 197)}...` : sentence;
|
|
66
|
+
}
|
|
67
|
+
/** Keep the declaration head; replace a long body with a member count. */
|
|
68
|
+
function collapseSignature(signature) {
|
|
69
|
+
const open = signature.indexOf("{");
|
|
70
|
+
if (open === -1)
|
|
71
|
+
return `${signature.slice(0, SEARCH_SIGNATURE_MAX)}…`;
|
|
72
|
+
const body = signature.slice(open);
|
|
73
|
+
// Rough but honest: count top-level-looking member lines rather than parsing TypeScript here.
|
|
74
|
+
const members = body.split("\n").filter((line) => /^\s{2,4}\S/.test(line)).length;
|
|
75
|
+
return `${signature.slice(0, open).trim()} { … ${members} members … }`;
|
|
76
|
+
}
|
|
77
|
+
/** A search hit: enough to choose, not the whole declaration. */
|
|
78
|
+
function renderSearchHit(t) {
|
|
79
|
+
const head = `## ${t.name} — ${t.kind}, \`${t.package}\``;
|
|
80
|
+
const summary = summarize(t.doc);
|
|
81
|
+
const signature = t.signature.length <= SEARCH_SIGNATURE_MAX ? t.signature : collapseSignature(t.signature);
|
|
82
|
+
const note = t.signature.length <= SEARCH_SIGNATURE_MAX
|
|
83
|
+
? ""
|
|
84
|
+
: `\n_Collapsed (${t.signature.length} chars). Call \`nifra_types({ name: "${t.name}" })\` for the full declaration._`;
|
|
85
|
+
return `${head}\n${summary ? `\n${summary}\n` : ""}\n\`\`\`ts\n${signature}\n\`\`\`${note}`;
|
|
86
|
+
}
|
|
43
87
|
/**
|
|
44
88
|
* Render the tool result. `name` → the exact declaration(s); else `query` → the top matches; else a
|
|
45
89
|
* per-package index of type names. The signatures are authoritative (generated from the built `.d.ts`),
|
|
46
90
|
* so this is the complete answer — there is no need to read a `.d.ts` file.
|
|
47
91
|
*/
|
|
48
|
-
export function renderTypesResult(types, name, query, limit) {
|
|
92
|
+
export function renderTypesResult(types, name, query, limit, full = false) {
|
|
49
93
|
if (name !== undefined && name.trim() !== "") {
|
|
50
94
|
const hits = lookupType(types, name);
|
|
51
95
|
if (hits.length === 0) {
|
|
@@ -58,7 +102,8 @@ export function renderTypesResult(types, name, query, limit) {
|
|
|
58
102
|
if (matches.length === 0) {
|
|
59
103
|
return `No types matched ${JSON.stringify(query)}. Try a broader term, pass an exact \`name\`, or call with no args for the index.`;
|
|
60
104
|
}
|
|
61
|
-
|
|
105
|
+
// Search results are collapsed by default; `full` opts back into whole declarations.
|
|
106
|
+
return matches.map(full ? renderEntry : renderSearchHit).join("\n\n---\n\n");
|
|
62
107
|
}
|
|
63
108
|
const byPkg = new Map();
|
|
64
109
|
for (const t of types) {
|
package/dist/types-search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-search.js","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAgBzF;6BAC6B;AAC7B,MAAM,UAAU,UAAU,CAAC,KAA2B,EAAE,IAAY;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACxC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAA;AAC7D,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CACzB,KAA2B,EAC3B,KAAa,EACb,KAAa;IAEb,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5C,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAA;QAC1D,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC;gBAAE,KAAK,IAAI,CAAC,CAAA;YAC7C,KAAK,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACvC,CAAC;QACD,IAAI,KAAK,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AACjG,CAAC;AAED,SAAS,WAAW,CAAC,CAAY;IAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,IAAI,CAAA;IACzD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,OAAO,GAAG,IAAI,iBAAiB,GAAG,GAAG,CAAC,CAAC,SAAS,UAAU,CAAA;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAA2B,EAC3B,IAAwB,EACxB,KAAyB,EACzB,KAAa;
|
|
1
|
+
{"version":3,"file":"types-search.js","sourceRoot":"","sources":["../src/types-search.ts"],"names":[],"mappings":"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"}
|
package/docs/examples.json
CHANGED
|
@@ -125,6 +125,12 @@
|
|
|
125
125
|
"slug": "deployment",
|
|
126
126
|
"code": "// _worker.ts — the edge SSR entry\nimport { toFetchHandler } from \"@nifrajs/core/server\"\nimport { createWebApp } from \"@nifrajs/web\"\nimport { reactAdapter } from \"@nifrajs/web-react\"\nimport { clientEntry, manifest } from \"./server-manifest\" // generated by buildServer\n\nconst app = createWebApp({ adapter: reactAdapter, manifest, clientEntry })\nexport default toFetchHandler(app) // a Workers/Pages fetch handler\n\n// build.ts — buildClient (→ /assets) + buildServer (edge conditions → _worker.js)\nimport { buildClient, buildServer } from \"@nifrajs/web/build\""
|
|
127
127
|
},
|
|
128
|
+
{
|
|
129
|
+
"name": "VITE_PROD",
|
|
130
|
+
"topic": "Nifra — Dev & HMR",
|
|
131
|
+
"slug": "dev",
|
|
132
|
+
"code": "// vite.config.ts — a Vite/Rollup PRODUCTION client build (the escape hatch, not the default).\n// Only reach for this when an app needs a Vite-only transform with no Bun equivalent; nifra's default\n// production bundler stays Bun (buildClient), which is faster and Bun-native.\nimport { viteLeakGuard } from \"@nifrajs/web/plugins/vite-leak-guard\"\n\nexport default {\n build: {\n // The SAME two client-leak guards nifra's Bun build runs — server-only code or a node: builtin\n // reaching the browser fails the build, with the identical error message. A second production\n // pipeline must not ship without them.\n rollupOptions: { plugins: [viteLeakGuard()] },\n },\n}"
|
|
133
|
+
},
|
|
128
134
|
{
|
|
129
135
|
"name": "LAB",
|
|
130
136
|
"topic": "Nifra - Failure laboratory",
|
package/docs/llms-full.txt
CHANGED
|
@@ -780,15 +780,15 @@ cache. Pass the same `draftSecret` to `createWebApp` and
|
|
|
780
780
|
|
|
781
781
|
```ts
|
|
782
782
|
// doc-check: skip — fragment spanning three files: your `app`, `env`, `redirect`, and route `slug`.
|
|
783
|
-
// 1.
|
|
784
|
-
|
|
783
|
+
// 1. Mount the preview entry point your CMS links to. It checks the token in CONSTANT TIME,
|
|
784
|
+
// sets the signed HttpOnly cookie, and refuses an off-site ?to= (an open redirect otherwise).
|
|
785
|
+
import { previewEndpoint, disableDraft } from "@nifrajs/web"
|
|
785
786
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
await enableDraft(c, env.DRAFT_SECRET) // signed, HttpOnly cookie
|
|
789
|
-
return redirect(String(c.query.to ?? "/"))
|
|
790
|
-
})
|
|
787
|
+
const preview = previewEndpoint({ secret: env.PREVIEW_TOKEN, draftSecret: env.DRAFT_SECRET })
|
|
788
|
+
app.get("/api/preview", (c) => preview(c.req)) // ?token=…&to=/posts/hello
|
|
791
789
|
app.get("/api/preview/exit", (c) => (disableDraft(c), redirect("/")))
|
|
790
|
+
// Gating it yourself instead? Use enableDraft(c, env.DRAFT_SECRET) AFTER your own check — and
|
|
791
|
+
// compare the token in constant time, since === leaks it one character at a time.
|
|
792
792
|
|
|
793
793
|
// 2. Loaders branch on ctx.draft to load unpublished content.
|
|
794
794
|
export async function loader({ api, draft }: LoaderArgs<typeof app>) {
|
|
@@ -2817,11 +2817,13 @@ the command printed by the build.
|
|
|
2817
2817
|
|
|
2818
2818
|
## Nifra — Dev & HMR
|
|
2819
2819
|
|
|
2820
|
-
> Use `nifra dev` for a Vite-backed state-preserving HMR loop, or `@nifrajs/web/dev` for a Bun-native
|
|
2820
|
+
> Use `nifra dev` for a Vite-backed state-preserving HMR loop, or `@nifrajs/web/dev` for a Bun-native HMR loop with no Vite dependency. Production builds use Bun.
|
|
2821
2821
|
|
|
2822
|
-
Nifra gives you two local development loops
|
|
2823
|
-
|
|
2824
|
-
|
|
2822
|
+
Nifra gives you two local development loops, and the rule between them is that one
|
|
2823
|
+
toolchain owns a whole phase. **Both** give you React Fast Refresh with state
|
|
2824
|
+
preserved. Use `nifra dev` (Vite) for the plugin ecosystem, or
|
|
2825
|
+
`nifra dev --bun` for one bundler across dev and prod with no Vite dependency.
|
|
2826
|
+
Both serve your real SSR app locally, and neither mixes the two bundlers in one process.
|
|
2825
2827
|
|
|
2826
2828
|
### Two loops, same app
|
|
2827
2829
|
|
|
@@ -2832,9 +2834,9 @@ use when
|
|
|
2832
2834
|
|
|
2833
2835
|
`@nifrajs/web/dev`
|
|
2834
2836
|
|
|
2835
|
-
|
|
2837
|
+
Bun HMR + Fast Refresh (native)
|
|
2836
2838
|
none (Bun only)
|
|
2837
|
-
|
|
2839
|
+
one bundler dev+prod; no Vite dep (no CSS Modules)
|
|
2838
2840
|
|
|
2839
2841
|
`@nifrajs/web/vite`
|
|
2840
2842
|
|
|
@@ -2882,50 +2884,44 @@ can edit routes, components, loaders, actions, and styles in one local loop.
|
|
|
2882
2884
|
|
|
2883
2885
|
### Framework coverage
|
|
2884
2886
|
|
|
2885
|
-
All five adapters have a dev setup. Pass the framework's official Vite plugin
|
|
2886
|
-
|
|
2887
|
+
All five adapters have a dev setup. Pass the framework's official Vite plugin and you are
|
|
2888
|
+
done: under `nifra dev` the Vite pipeline compiles both halves, so the same plugin
|
|
2889
|
+
that transforms your components for the browser also transforms them for SSR. No separate
|
|
2890
|
+
server-side compiler plugin to preload, and no way for the two halves to disagree about a
|
|
2891
|
+
specifier.
|
|
2887
2892
|
|
|
2888
2893
|
framework
|
|
2889
|
-
|
|
2890
|
-
SSR compile
|
|
2894
|
+
Vite plugin (client + SSR)
|
|
2891
2895
|
local state on edit
|
|
2892
2896
|
|
|
2893
2897
|
React
|
|
2894
2898
|
|
|
2895
2899
|
`@vitejs/plugin-react`
|
|
2896
2900
|
|
|
2897
|
-
Bun-native
|
|
2898
2901
|
preserved (Fast Refresh)
|
|
2899
2902
|
|
|
2900
2903
|
Preact
|
|
2901
2904
|
|
|
2902
2905
|
`@preact/preset-vite`
|
|
2903
2906
|
|
|
2904
|
-
Bun-native
|
|
2905
2907
|
preserved (prefresh)
|
|
2906
2908
|
|
|
2907
2909
|
Vue
|
|
2908
2910
|
|
|
2909
2911
|
`@vitejs/plugin-vue`
|
|
2910
2912
|
|
|
2911
|
-
`vueBunPlugin` preload
|
|
2912
|
-
|
|
2913
2913
|
preserved (rerender)
|
|
2914
2914
|
|
|
2915
2915
|
Solid
|
|
2916
2916
|
|
|
2917
2917
|
`vite-plugin-solid` (`{ ssr: true }`)
|
|
2918
2918
|
|
|
2919
|
-
`solidBunPlugin` preload
|
|
2920
|
-
|
|
2921
2919
|
resets (solid-refresh)
|
|
2922
2920
|
|
|
2923
2921
|
Svelte
|
|
2924
2922
|
|
|
2925
2923
|
`@sveltejs/vite-plugin-svelte`
|
|
2926
2924
|
|
|
2927
|
-
`svelteBunPlugin` preload
|
|
2928
|
-
|
|
2929
2925
|
resets (svelte HMR)
|
|
2930
2926
|
|
|
2931
2927
|
For **React, Preact, and Vue**, an edit hot-swaps with component state preserved.
|
|
@@ -2968,17 +2964,72 @@ instead.
|
|
|
2968
2964
|
|
|
2969
2965
|
### The zero-dep alternative
|
|
2970
2966
|
|
|
2971
|
-
`@nifrajs/web/dev` is
|
|
2972
|
-
|
|
2967
|
+
`nifra dev --bun` (library: `@nifrajs/web/dev`) is self-contained —
|
|
2968
|
+
no Vite anywhere. `Bun.serve`'s native HMR bundles and hot-reloads the client while
|
|
2969
|
+
Bun's runtime resolves SSR, and it applies **React Fast Refresh natively**: editing
|
|
2970
|
+
a component-only module swaps its markup with `useState` state intact, no reload. The
|
|
2971
|
+
boundary rule is the same as Vite's (see below). The real prize is that dev and production use
|
|
2972
|
+
the _same bundler_, so the dev/prod seam disappears.
|
|
2973
|
+
|
|
2974
|
+
One gap: **CSS Modules**. Bun's dev-server bundler has no
|
|
2975
|
+
`*.module.css` transform (its production `Bun.build` does), so the CLI
|
|
2976
|
+
refuses `--bun` for a CSS-Modules app rather than serving a broken client. Plain CSS
|
|
2977
|
+
and Tailwind work normally.
|
|
2973
2978
|
|
|
2974
2979
|
```ts
|
|
2975
2980
|
// doc-check: skip — fragment: routesDir/outDir/clientModule/createApp are your app's dev config.
|
|
2976
|
-
// dev.ts — Bun-native
|
|
2981
|
+
// dev.ts — Bun-native HMR, no Vite in the process
|
|
2977
2982
|
import { createDevServer } from "@nifrajs/web/dev"
|
|
2978
|
-
//
|
|
2983
|
+
// Bun.serve bundles + hot-reloads the client; Bun's runtime resolves SSR. An edit reloads the
|
|
2984
|
+
// changed module graph — with React Fast Refresh (state preserved) applied natively by Bun, no plugin.
|
|
2985
|
+
// CSS + the entry URL come from Bun. Plain CSS/Tailwind work; *.module.css does not (Bun's dev bundler).
|
|
2979
2986
|
const server = await createDevServer({ routesDir, outDir, clientModule, createApp })
|
|
2980
2987
|
```
|
|
2981
2988
|
|
|
2989
|
+
### Production is Bun — with a Vite escape hatch
|
|
2990
|
+
|
|
2991
|
+
Production builds default to **Bun** (`buildClient` /
|
|
2992
|
+
`nifra build`): faster, Bun-native, and the profile Nifra is tuned for. If an app
|
|
2993
|
+
genuinely needs a **Vite-only transform** with no Bun equivalent, you can run a
|
|
2994
|
+
Vite/Rollup production client build instead — but it must carry the same client-leak guards the
|
|
2995
|
+
Bun build enforces, or a second pipeline becomes a way for server-only code to reach the
|
|
2996
|
+
browser unnoticed. Add `viteLeakGuard()`: it runs the _same_ detection and
|
|
2997
|
+
emits the _same_ error as the Bun build (one implementation, adapted to Rollup's graph),
|
|
2998
|
+
so `node:` builtins and `server-only` modules fail the build either way.
|
|
2999
|
+
|
|
3000
|
+
```ts
|
|
3001
|
+
// vite.config.ts — a Vite/Rollup PRODUCTION client build (the escape hatch, not the default).
|
|
3002
|
+
// Only reach for this when an app needs a Vite-only transform with no Bun equivalent; nifra's default
|
|
3003
|
+
// production bundler stays Bun (buildClient), which is faster and Bun-native.
|
|
3004
|
+
import { viteLeakGuard } from "@nifrajs/web/plugins/vite-leak-guard"
|
|
3005
|
+
|
|
3006
|
+
export default {
|
|
3007
|
+
build: {
|
|
3008
|
+
// The SAME two client-leak guards nifra's Bun build runs — server-only code or a node: builtin
|
|
3009
|
+
// reaching the browser fails the build, with the identical error message. A second production
|
|
3010
|
+
// pipeline must not ship without them.
|
|
3011
|
+
rollupOptions: { plugins: [viteLeakGuard()] },
|
|
3012
|
+
},
|
|
3013
|
+
}
|
|
3014
|
+
```
|
|
3015
|
+
|
|
3016
|
+
For the full deploy, `nifra build --vite --target <t>` builds
|
|
3017
|
+
_both_ halves — client and SSR worker — with Vite and assembles the identical per-target
|
|
3018
|
+
deploy dir the Bun build produces (same `_worker.js` / `server.js`, same
|
|
3019
|
+
`_routes.json`, same prerender + size report). Only the bundler differs: both go
|
|
3020
|
+
through one orchestrator, so the deploy shape can't drift between pipelines. The leak guards run
|
|
3021
|
+
automatically.
|
|
3022
|
+
|
|
3023
|
+
You usually don't need the flag. `nifra build` picks the bundler from your config:
|
|
3024
|
+
Bun by default, but Vite when your _only_ transforms are `vitePlugins`, and it
|
|
3025
|
+
prints the reason. That case is the one where the phase defaults would otherwise bite — dev runs
|
|
3026
|
+
Vite, so your plugins run; the Bun build reads `clientPlugins`/
|
|
3027
|
+
`serverPlugins` and never `vitePlugins`, so it would drop them and still
|
|
3028
|
+
succeed. An app declaring both slots has supplied the Bun equivalent on purpose, so it keeps the
|
|
3029
|
+
faster Bun default. `--vite` and `--bun` force the choice; `--bun`
|
|
3030
|
+
is refused for a `vitePlugins`-only app rather than silently building without your
|
|
3031
|
+
transforms.
|
|
3032
|
+
|
|
2982
3033
|
### Styling (CSS)
|
|
2983
3034
|
|
|
2984
3035
|
Import a stylesheet anywhere — `import "./app.css"` in a route, layout, or component.
|
|
@@ -7486,7 +7537,7 @@ done-gate, or `nifra mcp` to give the agent live project tools.
|
|
|
7486
7537
|
|
|
7487
7538
|
## @nifrajs/web
|
|
7488
7539
|
|
|
7489
|
-
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `hashQueryKey`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NavigateOptions`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderedPage`, `renderPage`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `routeStyles`, `ScriptDescriptor`, `serializeData`, `ServerOnly`, `setBrowserNavigate`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `styles`, `Submission`, `SubmitOptions`, `withISR`
|
|
7540
|
+
`Action`, `ACTION_GLOBAL`, `apiKey`, `assertRenderAdapterConformance`, `BrowserNavigate`, `buildManifest`, `CachedResponse`, `CacheStore`, `canonical`, `clientEntry`, `ClientRouter`, `ClientRouterOptions`, `createClientRouter`, `createMatcher`, `createMutation`, `createQueryClient`, `createWebApp`, `CreateWebAppOptions`, `DATA_GLOBAL`, `DATA_HEADER`, `DEFAULT_DEV_PORT`, `defer`, `Deferred`, `DehydratedState`, `disableDraft`, `DRAFT_COOKIE`, `DraftCookieControls`, `enableDraft`, `EnableDraftOptions`, `enumerateStaticRoutes`, `Fetcher`, `FetcherState`, `FetchRouteData`, `filePathToPattern`, `filePathToPatterns`, `FontDisplay`, `fontFace`, `FontFace`, `fontPreload`, `FontPreloadInput`, `FontSource`, `gate`, `generateClientEntry`, `GenerateClientEntryOptions`, `generateServerManifest`, `GenerateServerManifestOptions`, `getBrowserNavigate`, `GetStaticPaths`, `gone`, `hashQueryKey`, `InfiniteData`, `InfiniteQueryHandle`, `InfiniteQueryOptions`, `isDraftEnabled`, `ISR_REVALIDATE_HEADER`, `ISR_STATUS_HEADER`, `ISRApp`, `ISROptions`, `ISRPlatform`, `jsonLd`, `KVCacheStore`, `KVCacheStoreOptions`, `KVNamespaceLike`, `LAYOUT_DATA_GLOBAL`, `LayoutEntry`, `LinkDescriptor`, `Loader`, `LoaderContext`, `manifest`, `Manifest`, `MemoryCacheStore`, `MemoryCacheStoreOptions`, `mergeHeads`, `meta`, `Meta`, `MetaArgs`, `MetaInput`, `MountRouterOptions`, `MutationCallbacks`, `MutationHandle`, `MutationState`, `MutationStatus`, `NAV_FROM_HEADER`, `NavigateOptions`, `notFound`, `openGraph`, `OpenGraphInput`, `PRE_HYDRATION_GUARD`, `previewEndpoint`, `PreviewEndpointOptions`, `PublicDirCache`, `QueryClient`, `QueryClientOptions`, `QueryHandle`, `QueryOptions`, `QueryState`, `QueryStatus`, `redirect`, `REDIRECT_HEADER`, `RedirectOptions`, `RenderAdapter`, `RenderAdapterConformanceError`, `RenderAdapterConformanceFixture`, `RenderedPage`, `renderPage`, `RenderPageOptions`, `renderPageResult`, `RenderProps`, `resolveMeta`, `resolvePublicPath`, `RETAIN_HEADER`, `revalidate`, `REVALIDATE_HEADER`, `revalidateEndpoint`, `RevalidateEndpointOptions`, `RevalidateResult`, `ROUTE_GLOBAL`, `RouteEntry`, `RouteMatch`, `RouteModule`, `RoutePattern`, `RouterState`, `routeStyles`, `ScriptDescriptor`, `serializeData`, `servePublicDir`, `ServePublicDirOptions`, `ServerOnly`, `setBrowserNavigate`, `StaticPath`, `StaticPaths`, `StaticRoutes`, `STATUS_HEADER`, `statusPage`, `StatusPageOptions`, `styles`, `Submission`, `SubmitOptions`, `withISR`
|
|
7490
7541
|
|
|
7491
7542
|
## @nifrajs/web-preact
|
|
7492
7543
|
|