sibujs 4.12.0 → 4.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/browser.cjs +71 -18
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +6618 -6178
  4. package/dist/build.d.cts +554 -415
  5. package/dist/build.d.ts +554 -415
  6. package/dist/build.js +2091 -1735
  7. package/dist/cdn.dev.global.js +12 -12
  8. package/dist/cdn.full.dev.global.js +13 -13
  9. package/dist/cdn.full.global.js +12 -12
  10. package/dist/cdn.global.js +12 -12
  11. package/dist/{chunk-WFRQ6D7H.js → chunk-22OPSWMF.js} +1 -1
  12. package/dist/{chunk-ZJCHY2IB.js → chunk-2NC56RGY.js} +1 -1
  13. package/dist/{chunk-NB7TFSJE.js → chunk-2O6JJCUR.js} +4 -4
  14. package/dist/{chunk-B2Y5BJSP.js → chunk-4UTGDVSA.js} +70 -16
  15. package/dist/{chunk-NAVLCP4S.js → chunk-5RIBLY2N.js} +4 -4
  16. package/dist/{chunk-T5O2CUHV.js → chunk-5XUGJM3J.js} +1 -1
  17. package/dist/{chunk-HXT2RNH5.js → chunk-ADZHPN2B.js} +1 -1
  18. package/dist/chunk-B36ADEIR.js +21 -0
  19. package/dist/{chunk-DFZL3AX7.js → chunk-C73VBPEF.js} +9 -5
  20. package/dist/{chunk-WH4U2VUE.js → chunk-CPQKWCJ2.js} +13 -5
  21. package/dist/{chunk-LEUEKK4G.js → chunk-EU7T7EB3.js} +2 -2
  22. package/dist/{chunk-QLG5IK7F.js → chunk-G3Z2FEBR.js} +4 -4
  23. package/dist/{chunk-ZPY2UAKM.js → chunk-J4X7ICH4.js} +3 -3
  24. package/dist/{chunk-XX4BRMWF.js → chunk-K4LNUT5L.js} +1 -1
  25. package/dist/{chunk-CI4W6XAU.js → chunk-KC62VURU.js} +3 -3
  26. package/dist/chunk-N5TBYXHW.js +17 -0
  27. package/dist/{chunk-653KGQS2.js → chunk-OIKD7YDY.js} +2 -2
  28. package/dist/{chunk-LYTUTXQP.js → chunk-PBJYCE2Z.js} +46 -4
  29. package/dist/{chunk-EMB5PG7V.js → chunk-QC3NP47A.js} +1 -1
  30. package/dist/{chunk-IHA62NGJ.js → chunk-QKFVMIAV.js} +1 -1
  31. package/dist/{chunk-LXBMVGVB.js → chunk-QZ47OZ25.js} +3 -3
  32. package/dist/{chunk-ZTYCCBU3.js → chunk-VFPLWUT7.js} +44 -26
  33. package/dist/{chunk-RK7EPQPG.js → chunk-YFTBCCVH.js} +1 -1
  34. package/dist/data.cjs +71 -18
  35. package/dist/data.js +5 -5
  36. package/dist/datePicker-DxuxWpgF.d.cts +285 -0
  37. package/dist/datePicker-DxuxWpgF.d.ts +285 -0
  38. package/dist/devtools.cjs +71 -18
  39. package/dist/devtools.js +4 -4
  40. package/dist/ecosystem.cjs +82 -21
  41. package/dist/ecosystem.js +7 -7
  42. package/dist/extras.cjs +131 -23
  43. package/dist/extras.d.cts +2 -2
  44. package/dist/extras.d.ts +2 -2
  45. package/dist/extras.js +21 -20
  46. package/dist/index.cjs +115 -37
  47. package/dist/index.d.cts +59 -5
  48. package/dist/index.d.ts +59 -5
  49. package/dist/index.js +10 -10
  50. package/dist/motion.cjs +69 -16
  51. package/dist/motion.js +3 -3
  52. package/dist/patterns.cjs +71 -18
  53. package/dist/patterns.js +5 -5
  54. package/dist/performance.cjs +69 -16
  55. package/dist/performance.js +4 -4
  56. package/dist/plugins.cjs +1421 -996
  57. package/dist/plugins.d.cts +132 -3
  58. package/dist/plugins.d.ts +132 -3
  59. package/dist/plugins.js +262 -11
  60. package/dist/routeMiddleware-B1sp4P7a.d.ts +688 -0
  61. package/dist/routeMiddleware-CedQTsLK.d.cts +688 -0
  62. package/dist/ssr.cjs +3607 -3524
  63. package/dist/ssr.d.cts +20 -671
  64. package/dist/ssr.d.ts +20 -671
  65. package/dist/ssr.js +15 -7
  66. package/dist/testing.cjs +71 -18
  67. package/dist/testing.js +2 -2
  68. package/dist/ui.cjs +78 -18
  69. package/dist/ui.js +8 -7
  70. package/dist/widgets.cjs +1352 -952
  71. package/dist/widgets.d.cts +100 -268
  72. package/dist/widgets.d.ts +100 -268
  73. package/dist/widgets.js +316 -7
  74. package/package.json +9 -1
package/dist/build.d.cts CHANGED
@@ -1,199 +1,93 @@
1
- /** A version 3 source map, as bundlers accept it from a transform hook. */
2
- interface SourceMapV3 {
3
- version: 3;
4
- file?: string;
5
- sources: string[];
6
- sourcesContent: string[];
7
- names: string[];
8
- mappings: string;
9
- }
10
-
11
- /**
12
- * Official Vite plugin for SibuJS.
13
- * Provides optimized builds, automatic component detection, and development enhancements.
14
- */
15
-
16
- interface SibuVitePluginOptions {
17
- /** Enable HMR support for SibuJS components */
18
- hmr?: boolean;
19
- /**
20
- * Annotate calls to side-effect-free sibujs factories (`tagFactory`,
21
- * `context`, ...) as pure for tree-shaking. Only direct calls to names
22
- * imported from sibujs are annotated. Default: true.
23
- */
24
- pureAnnotations?: boolean;
25
- /** Component file patterns to watch */
26
- include?: string[];
27
- /** File patterns to exclude */
28
- exclude?: string[];
29
- /**
30
- * Enable dev mode features (devtools, debug logging). When omitted it is
31
- * derived from Vite's own command/mode (`vite build` is production unless
32
- * `--mode development`; `vite serve` is development), falling back to
33
- * `NODE_ENV` only when the plugin is driven outside Vite.
34
- */
35
- devMode?: boolean;
36
- /**
37
- * Replace provably static tag-factory calls (`div({ class: "x" }, "text")`)
38
- * with `staticTemplate(...)` markup. Default: **false**, in every mode.
39
- *
40
- * Off by default because it is not a win: `staticTemplate` parses its markup
41
- * on every call, which is slower than the tag factory's `createElement` +
42
- * `setAttribute` for the single-element calls that can be proven static, and
43
- * the proof has to exclude every prop the factory treats specially (URL and
44
- * style sanitizing, IDL-only booleans, event and ref props). The analysis is
45
- * conservative and correct, but a correct pessimization is not a sane
46
- * default. It previously defaulted to on and rewrote non-sibujs calls
47
- * (`db.select({...})`) and the template compiler's output into invalid code.
48
- */
49
- staticOptimize?: boolean;
50
- /**
51
- * Compile `html` tagged templates (imported from sibujs) at build time.
52
- * Default: true in production builds. Most templates become direct DOM
53
- * construction; the rest are parsed at build time and rendered by the
54
- * runtime's own executor, so no template is parsed in the browser (the sole
55
- * exception is a template consisting of one invalid escape sequence).
56
- */
57
- compileTemplates?: boolean;
58
- }
59
- /** The subset of Vite's config environment / resolved config the plugin reads. */
60
- interface ViteModeInfo {
61
- command?: string;
62
- mode?: string;
63
- }
64
1
  /**
65
- * Vite plugin configuration for SibuJS projects.
66
- * Returns a Vite-compatible plugin object.
2
+ * Bundle size analysis utilities for SibuJS.
3
+ * Provides tools to analyze, estimate, and report on bundle sizes
4
+ * for SibuJS projects.
67
5
  */
68
- declare function sibuVitePlugin(options?: SibuVitePluginOptions): {
69
- name: string;
70
- enforce?: "pre" | "post";
71
- config?: (userConfig?: unknown, env?: ViteModeInfo) => Record<string, unknown>;
72
- configResolved?: (config: ViteModeInfo) => void;
73
- transform?: (code: string, id: string) => {
74
- code: string;
75
- map: SourceMapV3;
76
- } | null;
77
- handleHotUpdate?: (ctx: {
78
- file: string;
79
- modules: unknown[];
80
- }) => void;
81
- };
82
6
  /**
83
- * Generate an optimized Vite configuration for SibuJS projects.
84
- */
85
- declare function createViteConfig(options?: {
86
- /** Entry point */
87
- entry?: string;
88
- /** Output directory */
89
- outDir?: string;
90
- /** Enable SSR mode */
91
- ssr?: boolean;
92
- /** Additional Vite config overrides */
93
- overrides?: Record<string, unknown>;
94
- }): Record<string, unknown>;
95
-
96
- /**
97
- * Webpack plugin configuration for SibuJS projects.
98
- * Provides build optimization, pure annotations, and development enhancements.
7
+ * Known approximate sizes (in bytes, minified + gzipped) for SibuJS modules.
8
+ * These estimates are based on the typical compiled output of each module
9
+ * and are useful for pre-build size budgeting.
99
10
  */
100
- interface SibuWebpackPluginOptions {
101
- /**
102
- * NOT applied by the plugin — pure annotations under webpack need a loader
103
- * rule, and webpack loaders must be resolvable module files. Setting this to
104
- * `true` logs how to add the one-line loader instead of silently doing
105
- * nothing:
106
- *
107
- * ```js
108
- * // sibu-pure-loader.cjs
109
- * module.exports = require("sibujs/build").createPureAnnotationsLoader();
110
- *
111
- * // webpack.config.js
112
- * module: {
113
- * rules: [{ test: /\.[cm]?[jt]sx?$/, exclude: /node_modules/, use: "./sibu-pure-loader.cjs" }],
114
- * }
115
- * ```
116
- *
117
- * The rule this plugin used to push named a loader that does not exist
118
- * (`__sibu_inline_loader__`), which failed every build with the default
119
- * options; the option is kept so existing configs keep compiling.
120
- */
121
- pureAnnotations?: boolean;
122
- /**
123
- * Enable dev mode features (devtools, debug logging). When omitted it is
124
- * derived from webpack's own resolved `mode`: `development` is dev,
125
- * `production` and an unset mode (webpack's default is production) are not,
126
- * and `mode: "none"` falls back to `NODE_ENV`.
127
- */
128
- devMode?: boolean;
129
- }
11
+ declare const moduleSizes: Record<string, number>;
130
12
  /**
131
- * Webpack plugin configuration helper for SibuJS.
132
- * Returns webpack-compatible plugin and loader configurations.
13
+ * Analyze module sizes and dependencies.
133
14
  *
134
- * Usage:
135
- * ```js
136
- * const { sibuWebpackPlugin } = require('sibujs/build');
137
- * module.exports = {
138
- * plugins: [sibuWebpackPlugin()],
139
- * };
15
+ * Takes a record of module names to their source code and computes
16
+ * size statistics for each module and the total bundle.
17
+ *
18
+ * @param modules - A map of module names to their source code strings
19
+ * @returns Analysis results with sizes, sorted rankings, and a report generator
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { analyzeBundle } from 'sibu/src/build/analyzer';
24
+ *
25
+ * const result = analyzeBundle({
26
+ * 'app.ts': appSourceCode,
27
+ * 'components/Header.ts': headerSourceCode,
28
+ * 'components/Footer.ts': footerSourceCode,
29
+ * });
30
+ *
31
+ * console.log(result.report());
32
+ * // Total: 12.5 KB
33
+ * // app.ts: 8.2 KB (65.6%)
34
+ * // components/Header.ts: 2.8 KB (22.4%)
35
+ * // components/Footer.ts: 1.5 KB (12.0%)
140
36
  * ```
141
37
  */
142
- /** Minimal webpack compiler interface for plugin compatibility. */
143
- interface WebpackCompiler {
144
- hooks?: Record<string, {
145
- tap: (name: string, callback: (...args: unknown[]) => void) => void;
146
- } | undefined>;
147
- options: {
148
- module?: {
149
- rules?: unknown[];
150
- };
151
- resolve?: {
152
- mainFields?: string[];
153
- };
154
- plugins?: unknown[];
155
- [key: string]: unknown;
156
- };
157
- [key: string]: unknown;
158
- }
159
- declare function sibuWebpackPlugin(options?: SibuWebpackPluginOptions): {
160
- /** Plugin name */
161
- name: string;
162
- /** Apply function for webpack plugin API */
163
- apply: (compiler: WebpackCompiler) => void;
38
+ declare function analyzeBundle(modules: Record<string, string>): {
39
+ /** Total bundle size in bytes */
40
+ totalSize: number;
41
+ /** Size per module in bytes */
42
+ moduleSizes: Record<string, number>;
43
+ /** Modules sorted by size (largest first) */
44
+ sorted: Array<{
45
+ name: string;
46
+ size: number;
47
+ percentage: number;
48
+ }>;
49
+ /** Format as human-readable report */
50
+ report: () => string;
164
51
  };
165
52
  /**
166
- * Create a standalone webpack loader function for pure annotation injection.
53
+ * Estimate the impact of importing specific SibuJS modules.
54
+ * Based on known approximate sizes of each module (minified + gzipped).
167
55
  *
168
- * Webpack resolves loaders by path, so wrap it in a loader module and point a
169
- * rule at that file:
170
- * ```js
171
- * // sibu-pure-loader.cjs
172
- * const { createPureAnnotationsLoader } = require("sibujs/build");
173
- * module.exports = createPureAnnotationsLoader();
174
- * ```
175
- */
176
- declare function createPureAnnotationsLoader(): (source: string) => string;
177
- /**
178
- * Generate Webpack configuration for SibuJS projects.
56
+ * This is useful for understanding the cost of specific imports
57
+ * before building, enabling informed decisions about which features to use.
179
58
  *
180
- * Usage:
181
- * ```js
182
- * const { createWebpackConfig } = require('sibujs/build');
183
- * module.exports = createWebpackConfig({
184
- * entry: './src/index.ts',
185
- * mode: 'production',
186
- * });
59
+ * @param imports - Array of module paths to estimate (e.g., ['core/signal', 'core/html'])
60
+ * @returns Estimated size information with breakdown
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { estimateImportSize } from 'sibu/src/build/analyzer';
65
+ *
66
+ * // Estimate cost of a minimal SibuJS app
67
+ * const estimate = estimateImportSize([
68
+ * 'core/html',
69
+ * 'core/mount',
70
+ * 'core/signal',
71
+ * 'core/effect',
72
+ * 'reactivity/track',
73
+ * 'reactivity/batch',
74
+ * ]);
75
+ *
76
+ * console.log(estimate.formatted);
77
+ * // Estimated bundle size: 3.17 KB (minified + gzipped)
78
+ * // core/html: 1.76 KB
79
+ * // core/effect: 0.34 KB
80
+ * // ...
187
81
  * ```
188
82
  */
189
- declare function createWebpackConfig(options?: {
190
- /** Entry point file */
191
- entry?: string;
192
- /** Output directory path */
193
- outputPath?: string;
194
- /** Build mode */
195
- mode?: "development" | "production";
196
- }): Record<string, unknown>;
83
+ declare function estimateImportSize(imports: string[]): {
84
+ /** Total estimated size in bytes */
85
+ estimated: number;
86
+ /** Size breakdown per module */
87
+ breakdown: Record<string, number>;
88
+ /** Human-readable formatted output */
89
+ formatted: string;
90
+ };
197
91
 
198
92
  /**
199
93
  * CDN distribution utilities for SibuJS.
@@ -284,6 +178,48 @@ declare function generateImportMap(baseUrl?: string): {
284
178
  toScriptTag: () => string;
285
179
  };
286
180
 
181
+ /**
182
+ * Build-time compiler for SibuJS html tagged templates.
183
+ *
184
+ * Transforms:
185
+ * html`<div class=${cls}><span>${() => count()}</span></div>`
186
+ *
187
+ * Into a module-level construction function plus a call that passes the
188
+ * template's expressions in their original order:
189
+ *
190
+ * __sibujs$t0((cls), (() => count()))
191
+ * ...
192
+ * function __sibujs$t0(v0, v1) { ...direct DOM construction... }
193
+ *
194
+ * A compiled template builds exactly the DOM the runtime `html` parser would;
195
+ * any template the compiler cannot reproduce exactly is left to the runtime.
196
+ * The contract, the parser port and the list of templates left to the runtime
197
+ * are documented in templateCompiler.ts.
198
+ */
199
+ interface CompileResult {
200
+ /** The transformed source code, or null if nothing was compiled */
201
+ code: string | null;
202
+ /** Tag names of the elements the compiled templates create */
203
+ usedTags: Set<string>;
204
+ /** Whether any compiled template creates SVG-namespace elements */
205
+ usesSvg: boolean;
206
+ /** Number of templates compiled */
207
+ compiledCount: number;
208
+ /** Number of sibujs `html` templates deliberately left to the runtime parser */
209
+ skippedCount: number;
210
+ }
211
+ /**
212
+ * Compile the sibujs `html` tagged templates in a module to direct DOM
213
+ * construction. The returned code is self-contained: it carries the aliased
214
+ * imports and helpers the compiled templates need, appended at the end of the
215
+ * module (imports are hoisted, and appending keeps every original line where
216
+ * it was — each compiled template also keeps the line breaks it spanned).
217
+ *
218
+ * Returns `code: null` when nothing was compiled — including when the file
219
+ * cannot be scanned with confidence.
220
+ */
221
+ declare function compileHtmlTemplates(code: string): CompileResult;
222
+
287
223
  /**
288
224
  * TypeScript declaration map utilities for SibuJS.
289
225
  * Provides tsconfig helpers and declaration generation support
@@ -344,95 +280,60 @@ declare function validateTsConfig(config: Record<string, unknown>): {
344
280
  };
345
281
 
346
282
  /**
347
- * Bundle size analysis utilities for SibuJS.
348
- * Provides tools to analyze, estimate, and report on bundle sizes
349
- * for SibuJS projects.
350
- */
351
- /**
352
- * Known approximate sizes (in bytes, minified + gzipped) for SibuJS modules.
353
- * These estimates are based on the typical compiled output of each module
354
- * and are useful for pre-build size budgeting.
283
+ * IDE extension support for SibuJS.
284
+ * Provides metadata and utilities for VS Code and other IDE integrations.
355
285
  */
356
- declare const moduleSizes: Record<string, number>;
357
286
  /**
358
- * Analyze module sizes and dependencies.
359
- *
360
- * Takes a record of module names to their source code and computes
361
- * size statistics for each module and the total bundle.
362
- *
363
- * @param modules - A map of module names to their source code strings
364
- * @returns Analysis results with sizes, sorted rankings, and a report generator
365
- *
366
- * @example
367
- * ```ts
368
- * import { analyzeBundle } from 'sibu/src/build/analyzer';
369
- *
370
- * const result = analyzeBundle({
371
- * 'app.ts': appSourceCode,
372
- * 'components/Header.ts': headerSourceCode,
373
- * 'components/Footer.ts': footerSourceCode,
374
- * });
375
- *
376
- * console.log(result.report());
377
- * // Total: 12.5 KB
378
- * // app.ts: 8.2 KB (65.6%)
379
- * // components/Header.ts: 2.8 KB (22.4%)
380
- * // components/Footer.ts: 1.5 KB (12.0%)
381
- * ```
287
+ * Component metadata for IDE IntelliSense.
382
288
  */
383
- declare function analyzeBundle(modules: Record<string, string>): {
384
- /** Total bundle size in bytes */
385
- totalSize: number;
386
- /** Size per module in bytes */
387
- moduleSizes: Record<string, number>;
388
- /** Modules sorted by size (largest first) */
389
- sorted: Array<{
289
+ interface ComponentMeta {
290
+ name: string;
291
+ description: string;
292
+ props: Array<{
293
+ name: string;
294
+ type: string;
295
+ required: boolean;
296
+ default?: string;
297
+ description: string;
298
+ }>;
299
+ events?: Array<{
390
300
  name: string;
391
- size: number;
392
- percentage: number;
301
+ description: string;
393
302
  }>;
394
- /** Format as human-readable report */
395
- report: () => string;
396
- };
303
+ }
397
304
  /**
398
- * Estimate the impact of importing specific SibuJS modules.
399
- * Based on known approximate sizes of each module (minified + gzipped).
400
- *
401
- * This is useful for understanding the cost of specific imports
402
- * before building, enabling informed decisions about which features to use.
403
- *
404
- * @param imports - Array of module paths to estimate (e.g., ['core/signal', 'core/html'])
405
- * @returns Estimated size information with breakdown
406
- *
407
- * @example
408
- * ```ts
409
- * import { estimateImportSize } from 'sibu/src/build/analyzer';
410
- *
411
- * // Estimate cost of a minimal SibuJS app
412
- * const estimate = estimateImportSize([
413
- * 'core/html',
414
- * 'core/mount',
415
- * 'core/signal',
416
- * 'core/effect',
417
- * 'reactivity/track',
418
- * 'reactivity/batch',
419
- * ]);
420
- *
421
- * console.log(estimate.formatted);
422
- * // Estimated bundle size: 3.17 KB (minified + gzipped)
423
- * // core/html: 1.76 KB
424
- * // core/effect: 0.34 KB
425
- * // ...
426
- * ```
305
+ * SibuJS component registry for IDE auto-completion.
306
+ * Returns metadata about all built-in SibuJS exports.
427
307
  */
428
- declare function estimateImportSize(imports: string[]): {
429
- /** Total estimated size in bytes */
430
- estimated: number;
431
- /** Size breakdown per module */
432
- breakdown: Record<string, number>;
433
- /** Human-readable formatted output */
434
- formatted: string;
308
+ declare function getComponentMetadata(): ComponentMeta[];
309
+ /**
310
+ * Generate VS Code snippets for SibuJS.
311
+ */
312
+ declare function generateVSCodeSnippets(): Record<string, {
313
+ prefix: string;
314
+ body: string[];
315
+ description: string;
316
+ }>;
317
+ /**
318
+ * Generate a language configuration for SibuJS files.
319
+ * Provides bracket matching, comment toggling, and auto-close pairs.
320
+ */
321
+ declare function generateLanguageConfig(): {
322
+ comments: {
323
+ lineComment: string;
324
+ blockComment: [string, string];
325
+ };
326
+ brackets: [string, string][];
327
+ autoClosingPairs: Array<{
328
+ open: string;
329
+ close: string;
330
+ }>;
435
331
  };
332
+ /**
333
+ * Generate type stubs for common SibuJS patterns.
334
+ * Useful for IDE auto-import suggestions.
335
+ */
336
+ declare function generateTypeStubs(): Record<string, string>;
436
337
 
437
338
  /**
438
339
  * ESLint plugin configuration for SibuJS best practices.
@@ -494,60 +395,202 @@ declare function generateEslintConfig(options?: {
494
395
  }): Record<string, unknown>;
495
396
 
496
397
  /**
497
- * IDE extension support for SibuJS.
498
- * Provides metadata and utilities for VS Code and other IDE integrations.
398
+ * Build-time pre-rendering for single-page apps.
399
+ *
400
+ * An SPA built with `createRouter({ mode: "history" })` ships an empty
401
+ * `<div id="app">`: crawlers and link-preview bots see no content, and every
402
+ * route shares one `<title>`. A render server fixes that, but many apps are
403
+ * served as static files by a backend that is not Node. This renders each
404
+ * listed route ONCE, at build time, and writes it as a static HTML file.
405
+ *
406
+ * How a route is rendered:
407
+ *
408
+ * 1. The app's own client entry is built a second time as a Node module (a
409
+ * Vite SSR build of the same entry, with the same config).
410
+ * 2. In a fresh worker thread — one per route, so module state such as the
411
+ * router singleton never leaks between routes — a jsdom document is created
412
+ * from the BUILT `index.html` at the route's URL and registered as the
413
+ * global DOM, and the entry is imported. It runs exactly as in a browser.
414
+ * 3. The page is serialized once it has settled: every `fetch`, every promise
415
+ * passed to `prerenderWait()`, the router's initial navigation and its lazy
416
+ * route chunks have finished, and the DOM has been quiet for `settle` ms.
417
+ * 4. The document — rendered body, and the head the router produced for the
418
+ * route (title, description, canonical, Open Graph) — is written to
419
+ * `<outDir>/<route>/index.html`. The built `<script>` tags are kept, so the
420
+ * browser loads the client, which takes over (see the AGENTS.md recipe).
421
+ *
422
+ * Everything here is Node-only and loaded lazily, so importing `sibujs/build`
423
+ * elsewhere never pulls in a Node built-in.
424
+ */
425
+ /** One route to pre-render. */
426
+ interface PrerenderRoute {
427
+ /** The route URL, e.g. `"/pricing"` (a query string is allowed). */
428
+ path: string;
429
+ /** Output file, relative to the build output dir. Default: `<path>/index.html`. */
430
+ output?: string;
431
+ }
432
+ interface PrerenderOptions {
433
+ /** Routes to render. */
434
+ routes: Array<string | PrerenderRoute>;
435
+ /**
436
+ * The client entry module, relative to the Vite root. Default: the first
437
+ * `<script type="module" src>` in the source `index.html`.
438
+ */
439
+ entry?: string;
440
+ /**
441
+ * Origin of the URL each route is rendered at. Relative `fetch()` URLs
442
+ * resolve against it, and `location` reports it. Default `"http://localhost"`.
443
+ */
444
+ origin?: string;
445
+ /** Per-route time limit in ms before the build fails. Default 15000. */
446
+ timeout?: number;
447
+ /** How long the DOM must stay quiet, with nothing pending, before serializing. Default 50 ms. */
448
+ settle?: number;
449
+ /**
450
+ * Where to keep an untouched copy of the SPA shell (the built `index.html`
451
+ * before `/` is pre-rendered over it), for the backend's fallback route.
452
+ * Default `"200.html"`; `false` to skip it.
453
+ */
454
+ shell?: string | false;
455
+ /** Routes rendered at the same time. Default 4. */
456
+ concurrency?: number;
457
+ }
458
+ /** What the pre-renderer needs to know about the Vite build that just ran. */
459
+ interface PrerenderBuildContext {
460
+ /** Vite root (absolute). */
461
+ root: string;
462
+ /** Build output dir (absolute). */
463
+ outDir: string;
464
+ /** The Vite config file used for the client build, if any. */
465
+ configFile?: string | false;
466
+ /** Vite mode. */
467
+ mode?: string;
468
+ }
469
+ /** One rendered route. */
470
+ interface PrerenderResult {
471
+ route: string;
472
+ file: string;
473
+ ms: number;
474
+ }
475
+ /** Environment variable marking the nested SSR build, so it does not pre-render again. */
476
+ declare const PRERENDER_CHILD_ENV = "SIBU_PRERENDER_CHILD";
477
+ /**
478
+ * Find the client entry of a Vite app from its source `index.html`.
479
+ * @internal
499
480
  */
481
+ declare function findEntryInHtml(html: string): string | null;
500
482
  /**
501
- * Component metadata for IDE IntelliSense.
483
+ * The output file for a route, relative to the output dir. Refuses paths that
484
+ * could escape it.
485
+ * @internal
502
486
  */
503
- interface ComponentMeta {
504
- name: string;
505
- description: string;
506
- props: Array<{
507
- name: string;
508
- type: string;
509
- required: boolean;
510
- default?: string;
511
- description: string;
512
- }>;
513
- events?: Array<{
514
- name: string;
515
- description: string;
516
- }>;
517
- }
487
+ declare function outputFileFor(route: PrerenderRoute): string;
518
488
  /**
519
- * SibuJS component registry for IDE auto-completion.
520
- * Returns metadata about all built-in SibuJS exports.
489
+ * Absolute destination of `file` inside `outDir`, refusing anything that
490
+ * resolves outside it. The last line of defence at the write boundary, so a
491
+ * path `outputFileFor` let through can still never escape.
492
+ * @internal
521
493
  */
522
- declare function getComponentMetadata(): ComponentMeta[];
494
+ declare function resolveInsideOutDir(path: {
495
+ resolve: (...p: string[]) => string;
496
+ relative: (a: string, b: string) => string;
497
+ isAbsolute: (p: string) => boolean;
498
+ }, outDir: string, file: string): string;
523
499
  /**
524
- * Generate VS Code snippets for SibuJS.
500
+ * Pre-render `options.routes` into `ctx.outDir`. Called by
501
+ * `sibuVitePlugin({ prerender })` after the client build; callable directly
502
+ * from a build script too.
503
+ *
504
+ * @param options Routes and rendering options.
505
+ * @param ctx The finished client build.
506
+ * @returns One entry per written file.
507
+ * @throws When a route fails to render, throws, or does not settle in time.
525
508
  */
526
- declare function generateVSCodeSnippets(): Record<string, {
527
- prefix: string;
528
- body: string[];
529
- description: string;
530
- }>;
509
+ declare function prerender(options: PrerenderOptions, ctx: PrerenderBuildContext): Promise<PrerenderResult[]>;
531
510
  /**
532
- * Generate a language configuration for SibuJS files.
533
- * Provides bracket matching, comment toggling, and auto-close pairs.
511
+ * The file an export-map entry points at for an ES-module `import`.
512
+ * @internal
534
513
  */
535
- declare function generateLanguageConfig(): {
536
- comments: {
537
- lineComment: string;
538
- blockComment: [string, string];
539
- };
540
- brackets: [string, string][];
541
- autoClosingPairs: Array<{
542
- open: string;
543
- close: string;
544
- }>;
545
- };
514
+ declare function esmEntryOf(entry: unknown): string | undefined;
515
+
546
516
  /**
547
- * Generate type stubs for common SibuJS patterns.
548
- * Useful for IDE auto-import suggestions.
517
+ * Vite plugin for automatic route-based code splitting.
518
+ * Scans a routes directory and generates lazy-loaded route definitions.
549
519
  */
550
- declare function generateTypeStubs(): Record<string, string>;
520
+ interface RouteSplittingOptions {
521
+ /** Directory containing route files (default: "src/routes") */
522
+ routesDir?: string;
523
+ /** Glob patterns to exclude */
524
+ exclude?: string[];
525
+ /** Chunk name prefix (default: "route-") */
526
+ chunkPrefix?: string;
527
+ }
528
+ interface RouteEntry {
529
+ /** URL path pattern (e.g., "/users/:id") */
530
+ path: string;
531
+ /** Import path relative to project root */
532
+ importPath: string;
533
+ /** Generated chunk name */
534
+ chunkName: string;
535
+ /** Whether route has dynamic segments */
536
+ isDynamic: boolean;
537
+ }
538
+ /**
539
+ * Convert a file path within the routes directory to a URL pattern.
540
+ *
541
+ * Conventions:
542
+ * - index.ts -> /
543
+ * - about.ts -> /about
544
+ * - users/[id].ts -> /users/:id
545
+ * - blog/[...slug].ts -> /blog/*
546
+ * - _layout.ts -> skipped (layout file)
547
+ * - _middleware.ts -> skipped
548
+ */
549
+ declare function fileToRoute(relativePath: string): string | null;
550
+ /**
551
+ * Generate route entries from scanned files.
552
+ */
553
+ declare function buildRouteEntries(files: string[], chunkPrefix: string): RouteEntry[];
554
+ /**
555
+ * Vite plugin for automatic route-based code splitting.
556
+ *
557
+ * Scans the routes directory and generates a virtual module `virtual:sibu-routes`
558
+ * that exports lazy-loaded route definitions compatible with Sibu's router.
559
+ *
560
+ * @example
561
+ * ```ts
562
+ * // vite.config.ts
563
+ * import { sibuVitePlugin } from "sibujs/build";
564
+ * import { sibuRouteSplitting } from "sibujs/build";
565
+ *
566
+ * export default {
567
+ * plugins: [sibuVitePlugin(), sibuRouteSplitting()],
568
+ * };
569
+ *
570
+ * // In your app:
571
+ * import { routes } from "virtual:sibu-routes";
572
+ * import { setRoutes } from "sibujs/plugins";
573
+ * setRoutes(routes);
574
+ * ```
575
+ */
576
+ declare function sibuRouteSplitting(options?: RouteSplittingOptions): {
577
+ name: string;
578
+ enforce: "pre";
579
+ resolveId: (id: string) => string | undefined;
580
+ load: (id: string) => Promise<string | undefined>;
581
+ handleHotUpdate?: (ctx: {
582
+ file: string;
583
+ server: {
584
+ moduleGraph: {
585
+ invalidateModule: (mod: unknown) => void;
586
+ getModuleById: (id: string) => unknown;
587
+ };
588
+ ws: {
589
+ send: (msg: unknown) => void;
590
+ };
591
+ };
592
+ }) => void;
593
+ };
551
594
 
552
595
  /**
553
596
  * Static analysis utilities for SibuJS build-time optimizations.
@@ -602,132 +645,228 @@ interface StaticAnalysisResult {
602
645
  * div({ class: "card", id: "main" }, "Hello")
603
646
  *
604
647
  * And identifies them as candidates for:
605
- * staticTemplate('<div class="card" id="main">Hello</div>')
606
- *
607
- * Only calls to tag factories imported from "sibujs" in this file are
608
- * considered, and only when every argument is provably static.
609
- */
610
- declare function analyzeStaticTemplates(code: string): StaticAnalysisResult;
611
-
612
- /**
613
- * Build-time compiler for SibuJS html tagged templates.
614
- *
615
- * Transforms:
616
- * html`<div class=${cls}><span>${() => count()}</span></div>`
617
- *
618
- * Into a module-level construction function plus a call that passes the
619
- * template's expressions in their original order:
620
- *
621
- * __sibujs$t0((cls), (() => count()))
622
- * ...
623
- * function __sibujs$t0(v0, v1) { ...direct DOM construction... }
624
- *
625
- * A compiled template builds exactly the DOM the runtime `html` parser would;
626
- * any template the compiler cannot reproduce exactly is left to the runtime.
627
- * The contract, the parser port and the list of templates left to the runtime
628
- * are documented in templateCompiler.ts.
629
- */
630
- interface CompileResult {
631
- /** The transformed source code, or null if nothing was compiled */
632
- code: string | null;
633
- /** Tag names of the elements the compiled templates create */
634
- usedTags: Set<string>;
635
- /** Whether any compiled template creates SVG-namespace elements */
636
- usesSvg: boolean;
637
- /** Number of templates compiled */
638
- compiledCount: number;
639
- /** Number of sibujs `html` templates deliberately left to the runtime parser */
640
- skippedCount: number;
641
- }
642
- /**
643
- * Compile the sibujs `html` tagged templates in a module to direct DOM
644
- * construction. The returned code is self-contained: it carries the aliased
645
- * imports and helpers the compiled templates need, appended at the end of the
646
- * module (imports are hoisted, and appending keeps every original line where
647
- * it was — each compiled template also keeps the line breaks it spanned).
648
+ * staticTemplate('<div class="card" id="main">Hello</div>')
648
649
  *
649
- * Returns `code: null` when nothing was compiled — including when the file
650
- * cannot be scanned with confidence.
650
+ * Only calls to tag factories imported from "sibujs" in this file are
651
+ * considered, and only when every argument is provably static.
651
652
  */
652
- declare function compileHtmlTemplates(code: string): CompileResult;
653
+ declare function analyzeStaticTemplates(code: string): StaticAnalysisResult;
654
+
655
+ /** A version 3 source map, as bundlers accept it from a transform hook. */
656
+ interface SourceMapV3 {
657
+ version: 3;
658
+ file?: string;
659
+ sources: string[];
660
+ sourcesContent: string[];
661
+ names: string[];
662
+ mappings: string;
663
+ }
653
664
 
654
665
  /**
655
- * Vite plugin for automatic route-based code splitting.
656
- * Scans a routes directory and generates lazy-loaded route definitions.
666
+ * Official Vite plugin for SibuJS.
667
+ * Provides optimized builds, automatic component detection, and development enhancements.
657
668
  */
658
- interface RouteSplittingOptions {
659
- /** Directory containing route files (default: "src/routes") */
660
- routesDir?: string;
661
- /** Glob patterns to exclude */
669
+
670
+ interface SibuVitePluginOptions {
671
+ /** Enable HMR support for SibuJS components */
672
+ hmr?: boolean;
673
+ /**
674
+ * Annotate calls to side-effect-free sibujs factories (`tagFactory`,
675
+ * `context`, ...) as pure for tree-shaking. Only direct calls to names
676
+ * imported from sibujs are annotated. Default: true.
677
+ */
678
+ pureAnnotations?: boolean;
679
+ /** Component file patterns to watch */
680
+ include?: string[];
681
+ /** File patterns to exclude */
662
682
  exclude?: string[];
663
- /** Chunk name prefix (default: "route-") */
664
- chunkPrefix?: string;
683
+ /**
684
+ * Enable dev mode features (devtools, debug logging). When omitted it is
685
+ * derived from Vite's own command/mode (`vite build` is production unless
686
+ * `--mode development`; `vite serve` is development), falling back to
687
+ * `NODE_ENV` only when the plugin is driven outside Vite.
688
+ */
689
+ devMode?: boolean;
690
+ /**
691
+ * Replace provably static tag-factory calls (`div({ class: "x" }, "text")`)
692
+ * with `staticTemplate(...)` markup. Default: **false**, in every mode.
693
+ *
694
+ * Off by default because it is not a win: `staticTemplate` parses its markup
695
+ * on every call, which is slower than the tag factory's `createElement` +
696
+ * `setAttribute` for the single-element calls that can be proven static, and
697
+ * the proof has to exclude every prop the factory treats specially (URL and
698
+ * style sanitizing, IDL-only booleans, event and ref props). The analysis is
699
+ * conservative and correct, but a correct pessimization is not a sane
700
+ * default. It previously defaulted to on and rewrote non-sibujs calls
701
+ * (`db.select({...})`) and the template compiler's output into invalid code.
702
+ */
703
+ staticOptimize?: boolean;
704
+ /**
705
+ * Compile `html` tagged templates (imported from sibujs) at build time.
706
+ * Default: true in production builds. Most templates become direct DOM
707
+ * construction; the rest are parsed at build time and rendered by the
708
+ * runtime's own executor, so no template is parsed in the browser (the sole
709
+ * exception is a template consisting of one invalid escape sequence).
710
+ */
711
+ compileTemplates?: boolean;
712
+ /**
713
+ * Pre-render routes to static HTML after `vite build`, for an SPA served by
714
+ * a backend that cannot render it (SEO, link previews). Each route is run in
715
+ * a registered DOM (jsdom, which the app must install) and written to
716
+ * `dist/<route>/index.html` with its rendered body and its route head; the
717
+ * client then takes over with `hydrate()`. See `PrerenderOptions`.
718
+ *
719
+ * @example
720
+ * ```ts
721
+ * sibuVitePlugin({ prerender: { routes: ["/", "/cotizar", "/galeria"] } })
722
+ * ```
723
+ */
724
+ prerender?: PrerenderOptions;
665
725
  }
666
- interface RouteEntry {
667
- /** URL path pattern (e.g., "/users/:id") */
668
- path: string;
669
- /** Import path relative to project root */
670
- importPath: string;
671
- /** Generated chunk name */
672
- chunkName: string;
673
- /** Whether route has dynamic segments */
674
- isDynamic: boolean;
726
+ /** The subset of Vite's config environment / resolved config the plugin reads. */
727
+ interface ViteModeInfo {
728
+ command?: string;
729
+ mode?: string;
730
+ root?: string;
731
+ configFile?: string | false;
732
+ build?: {
733
+ outDir?: string;
734
+ ssr?: unknown;
735
+ };
675
736
  }
676
737
  /**
677
- * Convert a file path within the routes directory to a URL pattern.
678
- *
679
- * Conventions:
680
- * - index.ts -> /
681
- * - about.ts -> /about
682
- * - users/[id].ts -> /users/:id
683
- * - blog/[...slug].ts -> /blog/*
684
- * - _layout.ts -> skipped (layout file)
685
- * - _middleware.ts -> skipped
738
+ * Vite plugin configuration for SibuJS projects.
739
+ * Returns a Vite-compatible plugin object.
686
740
  */
687
- declare function fileToRoute(relativePath: string): string | null;
741
+ declare function sibuVitePlugin(options?: SibuVitePluginOptions): {
742
+ name: string;
743
+ enforce?: "pre" | "post";
744
+ config?: (userConfig?: unknown, env?: ViteModeInfo) => Record<string, unknown>;
745
+ configResolved?: (config: ViteModeInfo) => void;
746
+ closeBundle?: () => Promise<void>;
747
+ transform?: (code: string, id: string) => {
748
+ code: string;
749
+ map: SourceMapV3;
750
+ } | null;
751
+ handleHotUpdate?: (ctx: {
752
+ file: string;
753
+ modules: unknown[];
754
+ }) => void;
755
+ };
688
756
  /**
689
- * Generate route entries from scanned files.
757
+ * Generate an optimized Vite configuration for SibuJS projects.
690
758
  */
691
- declare function buildRouteEntries(files: string[], chunkPrefix: string): RouteEntry[];
759
+ declare function createViteConfig(options?: {
760
+ /** Entry point */
761
+ entry?: string;
762
+ /** Output directory */
763
+ outDir?: string;
764
+ /** Enable SSR mode */
765
+ ssr?: boolean;
766
+ /** Additional Vite config overrides */
767
+ overrides?: Record<string, unknown>;
768
+ }): Record<string, unknown>;
769
+
692
770
  /**
693
- * Vite plugin for automatic route-based code splitting.
694
- *
695
- * Scans the routes directory and generates a virtual module `virtual:sibu-routes`
696
- * that exports lazy-loaded route definitions compatible with Sibu's router.
697
- *
698
- * @example
699
- * ```ts
700
- * // vite.config.ts
701
- * import { sibuVitePlugin } from "sibujs/build";
702
- * import { sibuRouteSplitting } from "sibujs/build";
771
+ * Webpack plugin configuration for SibuJS projects.
772
+ * Provides build optimization, pure annotations, and development enhancements.
773
+ */
774
+ interface SibuWebpackPluginOptions {
775
+ /**
776
+ * NOT applied by the plugin — pure annotations under webpack need a loader
777
+ * rule, and webpack loaders must be resolvable module files. Setting this to
778
+ * `true` logs how to add the one-line loader instead of silently doing
779
+ * nothing:
780
+ *
781
+ * ```js
782
+ * // sibu-pure-loader.cjs
783
+ * module.exports = require("sibujs/build").createPureAnnotationsLoader();
784
+ *
785
+ * // webpack.config.js
786
+ * module: {
787
+ * rules: [{ test: /\.[cm]?[jt]sx?$/, exclude: /node_modules/, use: "./sibu-pure-loader.cjs" }],
788
+ * }
789
+ * ```
790
+ *
791
+ * The rule this plugin used to push named a loader that does not exist
792
+ * (`__sibu_inline_loader__`), which failed every build with the default
793
+ * options; the option is kept so existing configs keep compiling.
794
+ */
795
+ pureAnnotations?: boolean;
796
+ /**
797
+ * Enable dev mode features (devtools, debug logging). When omitted it is
798
+ * derived from webpack's own resolved `mode`: `development` is dev,
799
+ * `production` and an unset mode (webpack's default is production) are not,
800
+ * and `mode: "none"` falls back to `NODE_ENV`.
801
+ */
802
+ devMode?: boolean;
803
+ }
804
+ /**
805
+ * Webpack plugin configuration helper for SibuJS.
806
+ * Returns webpack-compatible plugin and loader configurations.
703
807
  *
704
- * export default {
705
- * plugins: [sibuVitePlugin(), sibuRouteSplitting()],
808
+ * Usage:
809
+ * ```js
810
+ * const { sibuWebpackPlugin } = require('sibujs/build');
811
+ * module.exports = {
812
+ * plugins: [sibuWebpackPlugin()],
706
813
  * };
707
- *
708
- * // In your app:
709
- * import { routes } from "virtual:sibu-routes";
710
- * import { setRoutes } from "sibujs/plugins";
711
- * setRoutes(routes);
712
814
  * ```
713
815
  */
714
- declare function sibuRouteSplitting(options?: RouteSplittingOptions): {
715
- name: string;
716
- enforce: "pre";
717
- resolveId: (id: string) => string | undefined;
718
- load: (id: string) => Promise<string | undefined>;
719
- handleHotUpdate?: (ctx: {
720
- file: string;
721
- server: {
722
- moduleGraph: {
723
- invalidateModule: (mod: unknown) => void;
724
- getModuleById: (id: string) => unknown;
725
- };
726
- ws: {
727
- send: (msg: unknown) => void;
728
- };
816
+ /** Minimal webpack compiler interface for plugin compatibility. */
817
+ interface WebpackCompiler {
818
+ hooks?: Record<string, {
819
+ tap: (name: string, callback: (...args: unknown[]) => void) => void;
820
+ } | undefined>;
821
+ options: {
822
+ module?: {
823
+ rules?: unknown[];
729
824
  };
730
- }) => void;
825
+ resolve?: {
826
+ mainFields?: string[];
827
+ };
828
+ plugins?: unknown[];
829
+ [key: string]: unknown;
830
+ };
831
+ [key: string]: unknown;
832
+ }
833
+ declare function sibuWebpackPlugin(options?: SibuWebpackPluginOptions): {
834
+ /** Plugin name */
835
+ name: string;
836
+ /** Apply function for webpack plugin API */
837
+ apply: (compiler: WebpackCompiler) => void;
731
838
  };
839
+ /**
840
+ * Create a standalone webpack loader function for pure annotation injection.
841
+ *
842
+ * Webpack resolves loaders by path, so wrap it in a loader module and point a
843
+ * rule at that file:
844
+ * ```js
845
+ * // sibu-pure-loader.cjs
846
+ * const { createPureAnnotationsLoader } = require("sibujs/build");
847
+ * module.exports = createPureAnnotationsLoader();
848
+ * ```
849
+ */
850
+ declare function createPureAnnotationsLoader(): (source: string) => string;
851
+ /**
852
+ * Generate Webpack configuration for SibuJS projects.
853
+ *
854
+ * Usage:
855
+ * ```js
856
+ * const { createWebpackConfig } = require('sibujs/build');
857
+ * module.exports = createWebpackConfig({
858
+ * entry: './src/index.ts',
859
+ * mode: 'production',
860
+ * });
861
+ * ```
862
+ */
863
+ declare function createWebpackConfig(options?: {
864
+ /** Entry point file */
865
+ entry?: string;
866
+ /** Output directory path */
867
+ outputPath?: string;
868
+ /** Build mode */
869
+ mode?: "development" | "production";
870
+ }): Record<string, unknown>;
732
871
 
733
- export { type CompileResult, type ComponentMeta, type LintViolation, type RouteSplittingOptions, type SibuVitePluginOptions, type SibuWebpackPluginOptions, type StaticAnalysisResult, analyzeBundle, analyzeStaticTemplates, buildRouteEntries, cdnUrls, compileHtmlTemplates, createPureAnnotationsLoader, createViteConfig, createWebpackConfig, estimateImportSize, fileToRoute, generateEslintConfig, generateImportMap, generateLanguageConfig, generateTsConfig, generateTypeStubs, generateVSCodeSnippets, getComponentMetadata, lintRules, lintSource, moduleSizes, registerGlobal, sibuRouteSplitting, sibuVitePlugin, sibuWebpackPlugin, umdWrapper, validateTsConfig };
872
+ export { type CompileResult, type ComponentMeta, type LintViolation, PRERENDER_CHILD_ENV, type PrerenderBuildContext, type PrerenderOptions, type PrerenderResult, type PrerenderRoute, type RouteSplittingOptions, type SibuVitePluginOptions, type SibuWebpackPluginOptions, type StaticAnalysisResult, analyzeBundle, analyzeStaticTemplates, buildRouteEntries, cdnUrls, compileHtmlTemplates, createPureAnnotationsLoader, createViteConfig, createWebpackConfig, esmEntryOf, estimateImportSize, fileToRoute, findEntryInHtml, generateEslintConfig, generateImportMap, generateLanguageConfig, generateTsConfig, generateTypeStubs, generateVSCodeSnippets, getComponentMetadata, lintRules, lintSource, moduleSizes, outputFileFor, prerender, registerGlobal, resolveInsideOutDir, sibuRouteSplitting, sibuVitePlugin, sibuWebpackPlugin, umdWrapper, validateTsConfig };