sibujs 4.13.0 → 4.14.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/README.md +1 -1
- package/dist/browser.cjs +15 -2
- package/dist/browser.js +9 -7
- package/dist/build.cjs +880 -281
- package/dist/build.d.cts +68 -3
- package/dist/build.d.ts +68 -3
- package/dist/build.js +88 -30
- package/dist/cdn.dev.global.js +12 -12
- package/dist/cdn.full.dev.global.js +13 -13
- package/dist/cdn.full.global.js +12 -12
- package/dist/cdn.global.js +12 -12
- package/dist/{chunk-7K7W4AA5.js → chunk-2TTRW2TE.js} +6 -6
- package/dist/{chunk-J6FW5TV6.js → chunk-3HEX6QJQ.js} +5 -3
- package/dist/chunk-3HZOSMPX.js +90 -0
- package/dist/{chunk-GNSRXK34.js → chunk-4FJSAUKB.js} +11 -3
- package/dist/{chunk-IV74C2YX.js → chunk-4TQDTWWN.js} +6 -5
- package/dist/{chunk-L3QHS4O4.js → chunk-7ILEHTVX.js} +1 -1
- package/dist/{chunk-CK5F2IR5.js → chunk-A454RAEK.js} +4 -4
- package/dist/{chunk-BRRRVLHQ.js → chunk-AE32RGWX.js} +10 -6
- package/dist/{chunk-EXXSN3BW.js → chunk-B3HOT4TK.js} +1 -1
- package/dist/{chunk-F4W7WYXY.js → chunk-BKZ5N6NK.js} +8 -6
- package/dist/{chunk-MNEITZ27.js → chunk-BNXRWZZV.js} +49 -8
- package/dist/chunk-BOYKGGVD.js +2015 -0
- package/dist/{chunk-G6366I2A.js → chunk-CCKUNHVU.js} +2 -2
- package/dist/{chunk-346BYZL2.js → chunk-CJ7KS3DF.js} +16 -10
- package/dist/chunk-CNPT6NKV.js +1859 -0
- package/dist/{chunk-ENFRHCMK.js → chunk-F67F77IA.js} +2 -2
- package/dist/{chunk-TUCPL2HB.js → chunk-GIJ33UJZ.js} +1 -1
- package/dist/chunk-GVAMIU6K.js +195 -0
- package/dist/{chunk-HDKDBC6V.js → chunk-HQIAL7F2.js} +8 -6
- package/dist/{chunk-ZE5LF44R.js → chunk-JTFQ7IL4.js} +8 -8
- package/dist/{chunk-AM6DZLBM.js → chunk-LJMX4SQ7.js} +2 -2
- package/dist/{chunk-HVVRXRGO.js → chunk-MIRKTVH4.js} +7 -14
- package/dist/{chunk-YJ57VR6Y.js → chunk-N7A6FKWW.js} +5 -3
- package/dist/chunk-NT3ZYB5S.js +167 -0
- package/dist/{chunk-Z3EZX6DZ.js → chunk-QS6GMWDD.js} +151 -86
- package/dist/chunk-R5U7XKVJ.js +16 -0
- package/dist/{chunk-3C56VNCK.js → chunk-RVR5NPFL.js} +3 -3
- package/dist/{chunk-F2UWOZ6J.js → chunk-RVWJGWCL.js} +2 -2
- package/dist/{chunk-NYNYSPK7.js → chunk-S37PZD6I.js} +30 -45
- package/dist/{chunk-QV5WEOFD.js → chunk-SVULV7O4.js} +119 -26
- package/dist/{chunk-C2FAO6VQ.js → chunk-TLS4NVIB.js} +5 -5
- package/dist/{chunk-M25RIH6Y.js → chunk-UUIKJJIK.js} +10 -8
- package/dist/chunk-UYTYNCMZ.js +199 -0
- package/dist/chunk-VM2U5LEL.js +2596 -0
- package/dist/{chunk-24L5RDPS.js → chunk-Y4LUM2XS.js} +8 -6
- package/dist/data.cjs +265 -35
- package/dist/data.d.cts +31 -1
- package/dist/data.d.ts +31 -1
- package/dist/data.js +16 -10
- package/dist/devtools.cjs +15 -2
- package/dist/devtools.js +9 -7
- package/dist/{dispose-GEIG2KOF.js → dispose-EIHHHDC7.js} +3 -1
- package/dist/ecosystem.cjs +62 -23
- package/dist/ecosystem.js +14 -12
- package/dist/extras.cjs +3520 -270
- package/dist/extras.d.cts +3 -3
- package/dist/extras.d.ts +3 -3
- package/dist/extras.js +39 -29
- package/dist/index.cjs +442 -253
- package/dist/index.d.cts +93 -283
- package/dist/index.d.ts +93 -283
- package/dist/index.js +26 -16
- package/dist/motion.cjs +12 -1
- package/dist/motion.js +6 -4
- package/dist/patterns.cjs +15 -2
- package/dist/patterns.js +10 -8
- package/dist/performance.cjs +36 -2
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +14 -10
- package/dist/plugins.cjs +5225 -1807
- package/dist/plugins.d.cts +8 -834
- package/dist/plugins.d.ts +8 -834
- package/dist/plugins.js +64 -2329
- package/dist/prerenderServer-MXJEVWA3.js +350 -0
- package/dist/renderRoute-DP20XwMS.d.cts +86 -0
- package/dist/renderRoute-fxgsm2Ir.d.ts +86 -0
- package/dist/routeHead-CE9SV-cH.d.cts +995 -0
- package/dist/routeHead-DzVxPviY.d.ts +995 -0
- package/dist/{routeMiddleware-B1sp4P7a.d.ts → routeMiddleware-BySbueoE.d.ts} +0 -25
- package/dist/{routeMiddleware-CedQTsLK.d.cts → routeMiddleware-CijZD5eW.d.cts} +0 -25
- package/dist/ssr-JpGpHnpC.d.cts +841 -0
- package/dist/ssr-JpGpHnpC.d.ts +841 -0
- package/dist/{ssr-VBM6J5SJ.js → ssr-NECEU4X4.js} +15 -6
- package/dist/ssr-dom.cjs +1862 -0
- package/dist/ssr-dom.d.cts +341 -0
- package/dist/ssr-dom.d.ts +341 -0
- package/dist/ssr-dom.js +19 -0
- package/dist/ssr.cjs +7630 -2064
- package/dist/ssr.d.cts +63 -5
- package/dist/ssr.d.ts +63 -5
- package/dist/ssr.js +136 -14
- package/dist/testing.cjs +6543 -87
- package/dist/testing.d.cts +80 -1
- package/dist/testing.d.ts +80 -1
- package/dist/testing.js +117 -4
- package/dist/ui.cjs +36 -2
- package/dist/ui.js +17 -14
- package/dist/widgets.cjs +14 -1
- package/dist/widgets.js +11 -9
- package/package.json +9 -2
- package/dist/chunk-2F4PSJ5Z.js +0 -765
- package/dist/chunk-7XHATCIH.js +0 -121
- package/dist/chunk-B36ADEIR.js +0 -21
- package/dist/ssr-Db0Sgdu3.d.cts +0 -245
- package/dist/ssr-Db0Sgdu3.d.ts +0 -245
package/dist/build.d.cts
CHANGED
|
@@ -430,8 +430,62 @@ interface PrerenderRoute {
|
|
|
430
430
|
output?: string;
|
|
431
431
|
}
|
|
432
432
|
interface PrerenderOptions {
|
|
433
|
-
/**
|
|
434
|
-
|
|
433
|
+
/**
|
|
434
|
+
* Routes to render. With `server`, defaults to `"auto"`: every route of the
|
|
435
|
+
* exported table without params, plus the paths `getStaticPaths()` lists
|
|
436
|
+
* for dynamic ones. A query variant (`"/cotizar?servicio=dtf"`) is rendered
|
|
437
|
+
* only when listed, and needs its own `output` file.
|
|
438
|
+
*/
|
|
439
|
+
routes?: Array<string | PrerenderRoute> | "auto";
|
|
440
|
+
/**
|
|
441
|
+
* A SERVER ENTRY module (relative to the Vite root) exporting the app's
|
|
442
|
+
* `routes`, and optionally `head` (router head defaults), `routerOptions`
|
|
443
|
+
* and `app` (the shell around `Route()`). Routes are then rendered with
|
|
444
|
+
* `renderRoute()` on the built-in server DOM — the request-scoped router,
|
|
445
|
+
* async data, the collected head and transferred state — with no jsdom.
|
|
446
|
+
* Without it, the 4.13 mode runs the client entry in jsdom.
|
|
447
|
+
*/
|
|
448
|
+
server?: string;
|
|
449
|
+
/** Output dir (relative to the Vite root). Default: Vite's `build.outDir`. */
|
|
450
|
+
outDir?: string;
|
|
451
|
+
/**
|
|
452
|
+
* Data at build time: a base URL that relative `fetch()` URLs (`/api/…`)
|
|
453
|
+
* resolve against (a running API), or a `fetch` implementation. A request
|
|
454
|
+
* that cannot reach it fails the build, naming the route. Default: `origin`.
|
|
455
|
+
* Server-entry mode only.
|
|
456
|
+
*/
|
|
457
|
+
fetch?: string | typeof fetch;
|
|
458
|
+
/**
|
|
459
|
+
* `"always"` (default): `/cotizar` is written as `cotizar/index.html`, the
|
|
460
|
+
* sitemap lists `/cotizar/`. `"never"`: `cotizar.html`, listed as `/cotizar`
|
|
461
|
+
* (the static server must map `/cotizar` to `cotizar.html`).
|
|
462
|
+
*/
|
|
463
|
+
trailingSlash?: "always" | "never";
|
|
464
|
+
/**
|
|
465
|
+
* URL rendered through the `*` route and written as `404.html` (when it
|
|
466
|
+
* answers 404). Default `"/404"` with `server`; off otherwise. `false` to skip.
|
|
467
|
+
*/
|
|
468
|
+
notFound?: string | false;
|
|
469
|
+
/** Write `sitemap.xml` (pages not `noindex`, not `render: "client"`). Default `true` with `server`, `false` otherwise. */
|
|
470
|
+
sitemap?: boolean;
|
|
471
|
+
/** Write `robots.txt` pointing at the sitemap; a string adds rules (`"Disallow: /admin"`). Default `false`. */
|
|
472
|
+
robots?: boolean | string;
|
|
473
|
+
/** `"adopt"`: mark the output for `hydrate(App, root, { strategy: "adopt" })`. Server-entry mode only. */
|
|
474
|
+
hydration?: "adopt" | "replace";
|
|
475
|
+
/**
|
|
476
|
+
* CSP nonce attribute for the transfer script. Server-entry mode only.
|
|
477
|
+
*
|
|
478
|
+
* A static file carries the SAME value on every response, and a nonce that
|
|
479
|
+
* never changes protects nothing: injected markup can reuse it. Use it only
|
|
480
|
+
* as a PLACEHOLDER your server replaces with a fresh nonce per response
|
|
481
|
+
* (nginx `sub_filter`, a middleware), the same value its CSP header sends.
|
|
482
|
+
* Without such a server, allow the script by hash (`'sha256-…'`) instead.
|
|
483
|
+
*/
|
|
484
|
+
nonce?: string;
|
|
485
|
+
/** Cap on each page's transferred state in bytes. Server-entry mode only. */
|
|
486
|
+
maxStateBytes?: number;
|
|
487
|
+
/** Id of the element the body renders into. Default `"app"`. Server-entry mode only. */
|
|
488
|
+
container?: string;
|
|
435
489
|
/**
|
|
436
490
|
* The client entry module, relative to the Vite root. Default: the first
|
|
437
491
|
* `<script type="module" src>` in the source `index.html`.
|
|
@@ -471,6 +525,13 @@ interface PrerenderResult {
|
|
|
471
525
|
route: string;
|
|
472
526
|
file: string;
|
|
473
527
|
ms: number;
|
|
528
|
+
/** HTTP status the route answered with (server-entry mode). */
|
|
529
|
+
status?: number;
|
|
530
|
+
/**
|
|
531
|
+
* `page` (rendered body), `shell` (head only), `redirect` (listed in
|
|
532
|
+
* redirects.json), `not-found` (404.html), `skipped` (a guard rejected it).
|
|
533
|
+
*/
|
|
534
|
+
kind?: "page" | "shell" | "redirect" | "not-found" | "skipped";
|
|
474
535
|
}
|
|
475
536
|
/** Environment variable marking the nested SSR build, so it does not pre-render again. */
|
|
476
537
|
declare const PRERENDER_CHILD_ENV = "SIBU_PRERENDER_CHILD";
|
|
@@ -484,7 +545,7 @@ declare function findEntryInHtml(html: string): string | null;
|
|
|
484
545
|
* could escape it.
|
|
485
546
|
* @internal
|
|
486
547
|
*/
|
|
487
|
-
declare function outputFileFor(route: PrerenderRoute): string;
|
|
548
|
+
declare function outputFileFor(route: PrerenderRoute, trailingSlash?: "always" | "never"): string;
|
|
488
549
|
/**
|
|
489
550
|
* Absolute destination of `file` inside `outDir`, refusing anything that
|
|
490
551
|
* resolves outside it. The last line of defence at the write boundary, so a
|
|
@@ -752,6 +813,10 @@ declare function sibuVitePlugin(options?: SibuVitePluginOptions): {
|
|
|
752
813
|
file: string;
|
|
753
814
|
modules: unknown[];
|
|
754
815
|
}) => void;
|
|
816
|
+
/** For tooling (`sibujs prerender`): the options this plugin was created with. */
|
|
817
|
+
api: {
|
|
818
|
+
prerender: PrerenderOptions | undefined;
|
|
819
|
+
};
|
|
755
820
|
};
|
|
756
821
|
/**
|
|
757
822
|
* Generate an optimized Vite configuration for SibuJS projects.
|
package/dist/build.d.ts
CHANGED
|
@@ -430,8 +430,62 @@ interface PrerenderRoute {
|
|
|
430
430
|
output?: string;
|
|
431
431
|
}
|
|
432
432
|
interface PrerenderOptions {
|
|
433
|
-
/**
|
|
434
|
-
|
|
433
|
+
/**
|
|
434
|
+
* Routes to render. With `server`, defaults to `"auto"`: every route of the
|
|
435
|
+
* exported table without params, plus the paths `getStaticPaths()` lists
|
|
436
|
+
* for dynamic ones. A query variant (`"/cotizar?servicio=dtf"`) is rendered
|
|
437
|
+
* only when listed, and needs its own `output` file.
|
|
438
|
+
*/
|
|
439
|
+
routes?: Array<string | PrerenderRoute> | "auto";
|
|
440
|
+
/**
|
|
441
|
+
* A SERVER ENTRY module (relative to the Vite root) exporting the app's
|
|
442
|
+
* `routes`, and optionally `head` (router head defaults), `routerOptions`
|
|
443
|
+
* and `app` (the shell around `Route()`). Routes are then rendered with
|
|
444
|
+
* `renderRoute()` on the built-in server DOM — the request-scoped router,
|
|
445
|
+
* async data, the collected head and transferred state — with no jsdom.
|
|
446
|
+
* Without it, the 4.13 mode runs the client entry in jsdom.
|
|
447
|
+
*/
|
|
448
|
+
server?: string;
|
|
449
|
+
/** Output dir (relative to the Vite root). Default: Vite's `build.outDir`. */
|
|
450
|
+
outDir?: string;
|
|
451
|
+
/**
|
|
452
|
+
* Data at build time: a base URL that relative `fetch()` URLs (`/api/…`)
|
|
453
|
+
* resolve against (a running API), or a `fetch` implementation. A request
|
|
454
|
+
* that cannot reach it fails the build, naming the route. Default: `origin`.
|
|
455
|
+
* Server-entry mode only.
|
|
456
|
+
*/
|
|
457
|
+
fetch?: string | typeof fetch;
|
|
458
|
+
/**
|
|
459
|
+
* `"always"` (default): `/cotizar` is written as `cotizar/index.html`, the
|
|
460
|
+
* sitemap lists `/cotizar/`. `"never"`: `cotizar.html`, listed as `/cotizar`
|
|
461
|
+
* (the static server must map `/cotizar` to `cotizar.html`).
|
|
462
|
+
*/
|
|
463
|
+
trailingSlash?: "always" | "never";
|
|
464
|
+
/**
|
|
465
|
+
* URL rendered through the `*` route and written as `404.html` (when it
|
|
466
|
+
* answers 404). Default `"/404"` with `server`; off otherwise. `false` to skip.
|
|
467
|
+
*/
|
|
468
|
+
notFound?: string | false;
|
|
469
|
+
/** Write `sitemap.xml` (pages not `noindex`, not `render: "client"`). Default `true` with `server`, `false` otherwise. */
|
|
470
|
+
sitemap?: boolean;
|
|
471
|
+
/** Write `robots.txt` pointing at the sitemap; a string adds rules (`"Disallow: /admin"`). Default `false`. */
|
|
472
|
+
robots?: boolean | string;
|
|
473
|
+
/** `"adopt"`: mark the output for `hydrate(App, root, { strategy: "adopt" })`. Server-entry mode only. */
|
|
474
|
+
hydration?: "adopt" | "replace";
|
|
475
|
+
/**
|
|
476
|
+
* CSP nonce attribute for the transfer script. Server-entry mode only.
|
|
477
|
+
*
|
|
478
|
+
* A static file carries the SAME value on every response, and a nonce that
|
|
479
|
+
* never changes protects nothing: injected markup can reuse it. Use it only
|
|
480
|
+
* as a PLACEHOLDER your server replaces with a fresh nonce per response
|
|
481
|
+
* (nginx `sub_filter`, a middleware), the same value its CSP header sends.
|
|
482
|
+
* Without such a server, allow the script by hash (`'sha256-…'`) instead.
|
|
483
|
+
*/
|
|
484
|
+
nonce?: string;
|
|
485
|
+
/** Cap on each page's transferred state in bytes. Server-entry mode only. */
|
|
486
|
+
maxStateBytes?: number;
|
|
487
|
+
/** Id of the element the body renders into. Default `"app"`. Server-entry mode only. */
|
|
488
|
+
container?: string;
|
|
435
489
|
/**
|
|
436
490
|
* The client entry module, relative to the Vite root. Default: the first
|
|
437
491
|
* `<script type="module" src>` in the source `index.html`.
|
|
@@ -471,6 +525,13 @@ interface PrerenderResult {
|
|
|
471
525
|
route: string;
|
|
472
526
|
file: string;
|
|
473
527
|
ms: number;
|
|
528
|
+
/** HTTP status the route answered with (server-entry mode). */
|
|
529
|
+
status?: number;
|
|
530
|
+
/**
|
|
531
|
+
* `page` (rendered body), `shell` (head only), `redirect` (listed in
|
|
532
|
+
* redirects.json), `not-found` (404.html), `skipped` (a guard rejected it).
|
|
533
|
+
*/
|
|
534
|
+
kind?: "page" | "shell" | "redirect" | "not-found" | "skipped";
|
|
474
535
|
}
|
|
475
536
|
/** Environment variable marking the nested SSR build, so it does not pre-render again. */
|
|
476
537
|
declare const PRERENDER_CHILD_ENV = "SIBU_PRERENDER_CHILD";
|
|
@@ -484,7 +545,7 @@ declare function findEntryInHtml(html: string): string | null;
|
|
|
484
545
|
* could escape it.
|
|
485
546
|
* @internal
|
|
486
547
|
*/
|
|
487
|
-
declare function outputFileFor(route: PrerenderRoute): string;
|
|
548
|
+
declare function outputFileFor(route: PrerenderRoute, trailingSlash?: "always" | "never"): string;
|
|
488
549
|
/**
|
|
489
550
|
* Absolute destination of `file` inside `outDir`, refusing anything that
|
|
490
551
|
* resolves outside it. The last line of defence at the write boundary, so a
|
|
@@ -752,6 +813,10 @@ declare function sibuVitePlugin(options?: SibuVitePluginOptions): {
|
|
|
752
813
|
file: string;
|
|
753
814
|
modules: unknown[];
|
|
754
815
|
}) => void;
|
|
816
|
+
/** For tooling (`sibujs prerender`): the options this plugin was created with. */
|
|
817
|
+
api: {
|
|
818
|
+
prerender: PrerenderOptions | undefined;
|
|
819
|
+
};
|
|
755
820
|
};
|
|
756
821
|
/**
|
|
757
822
|
* Generate an optimized Vite configuration for SibuJS projects.
|
package/dist/build.js
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
index_exports
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-QS6GMWDD.js";
|
|
4
|
+
import "./chunk-7ILEHTVX.js";
|
|
5
|
+
import "./chunk-BOYKGGVD.js";
|
|
6
|
+
import "./chunk-CNPT6NKV.js";
|
|
7
|
+
import "./chunk-LJMX4SQ7.js";
|
|
8
|
+
import "./chunk-RVR5NPFL.js";
|
|
9
|
+
import "./chunk-CCKUNHVU.js";
|
|
10
|
+
import "./chunk-3HZOSMPX.js";
|
|
9
11
|
import "./chunk-62BDYGAG.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-CJ7KS3DF.js";
|
|
13
|
+
import "./chunk-HQIAL7F2.js";
|
|
14
|
+
import "./chunk-RVWJGWCL.js";
|
|
15
|
+
import "./chunk-N7A6FKWW.js";
|
|
14
16
|
import "./chunk-7ZHH77QA.js";
|
|
15
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-AE32RGWX.js";
|
|
16
18
|
import {
|
|
17
19
|
isEventHandlerAttr,
|
|
18
20
|
isHtmlContentAttribute,
|
|
19
21
|
isUrlAttribute
|
|
20
|
-
} from "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-B3HOT4TK.js";
|
|
23
|
+
import "./chunk-UYTYNCMZ.js";
|
|
22
24
|
import "./chunk-5HZXGZ6T.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-4FJSAUKB.js";
|
|
26
|
+
import "./chunk-MIRKTVH4.js";
|
|
27
|
+
import "./chunk-S37PZD6I.js";
|
|
28
|
+
import "./chunk-NT3ZYB5S.js";
|
|
29
|
+
import "./chunk-R5U7XKVJ.js";
|
|
26
30
|
|
|
27
31
|
// src/build/analyzer.ts
|
|
28
32
|
var moduleSizes = {
|
|
@@ -203,6 +207,7 @@ var SUBPATH_ENTRIES = [
|
|
|
203
207
|
"ui",
|
|
204
208
|
"widgets",
|
|
205
209
|
"ssr",
|
|
210
|
+
"ssr/dom",
|
|
206
211
|
"devtools",
|
|
207
212
|
"performance",
|
|
208
213
|
"ecosystem",
|
|
@@ -277,7 +282,7 @@ function generateImportMap(baseUrl) {
|
|
|
277
282
|
[PACKAGE_NAME]: `${base}/dist/index.js`
|
|
278
283
|
};
|
|
279
284
|
for (const entry of SUBPATH_ENTRIES) {
|
|
280
|
-
imports[`${PACKAGE_NAME}/${entry}`] = `${base}/dist/${entry}.js`;
|
|
285
|
+
imports[`${PACKAGE_NAME}/${entry}`] = `${base}/dist/${entry.replace("/", "-")}.js`;
|
|
281
286
|
}
|
|
282
287
|
return {
|
|
283
288
|
imports,
|
|
@@ -2530,7 +2535,7 @@ function findEntryInHtml(html) {
|
|
|
2530
2535
|
const m = MODULE_SCRIPT.exec(html) ?? MODULE_SCRIPT_SRC_FIRST.exec(html);
|
|
2531
2536
|
return m ? m[1] : null;
|
|
2532
2537
|
}
|
|
2533
|
-
function outputFileFor(route) {
|
|
2538
|
+
function outputFileFor(route, trailingSlash = "always") {
|
|
2534
2539
|
if (route.output) {
|
|
2535
2540
|
const output = route.output;
|
|
2536
2541
|
if (/^[A-Za-z]:/.test(output) || output.includes("\0")) {
|
|
@@ -2560,6 +2565,10 @@ function outputFileFor(route) {
|
|
|
2560
2565
|
}
|
|
2561
2566
|
return decoded;
|
|
2562
2567
|
});
|
|
2568
|
+
if (trailingSlash === "never" && segments.length > 0) {
|
|
2569
|
+
const last = segments.pop();
|
|
2570
|
+
return [...segments, `${last}.html`].join("/");
|
|
2571
|
+
}
|
|
2563
2572
|
return [...segments, "index.html"].join("/");
|
|
2564
2573
|
}
|
|
2565
2574
|
function resolveInsideOutDir(path, outDir, file) {
|
|
@@ -2575,17 +2584,36 @@ async function prerender(options, ctx) {
|
|
|
2575
2584
|
const path = await import("path");
|
|
2576
2585
|
const { pathToFileURL } = await import("url");
|
|
2577
2586
|
const { createRequire } = await import("module");
|
|
2587
|
+
const requireFromRoot = createRequire(path.join(ctx.root, "package.json"));
|
|
2588
|
+
if (options.server) {
|
|
2589
|
+
const { prerenderFromServerEntry } = await import("./prerenderServer-MXJEVWA3.js");
|
|
2590
|
+
return prerenderFromServerEntry(options, ctx, {
|
|
2591
|
+
outputFileFor,
|
|
2592
|
+
resolveInsideOutDir,
|
|
2593
|
+
loadViteBuild: () => loadViteBuild(requireFromRoot, fs, path, pathToFileURL),
|
|
2594
|
+
childEnv: PRERENDER_CHILD_ENV
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
if (options.routes === void 0 || options.routes === "auto") {
|
|
2598
|
+
throw new Error(
|
|
2599
|
+
'[sibu prerender] `routes: "auto"` needs a server entry (`prerender.server`); list the routes instead.'
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2578
2602
|
const routes = options.routes.map((r) => typeof r === "string" ? { path: r } : r);
|
|
2603
|
+
if (options.notFound) routes.push({ path: options.notFound, output: "404.html" });
|
|
2579
2604
|
if (routes.length === 0) return [];
|
|
2605
|
+
const trailingSlash = options.trailingSlash === "never" ? "never" : "always";
|
|
2606
|
+
const outDir = options.outDir ? path.resolve(ctx.root, options.outDir) : ctx.outDir;
|
|
2580
2607
|
const planned = routes.map((route) => {
|
|
2581
|
-
const file = outputFileFor(route);
|
|
2582
|
-
resolveInsideOutDir(path,
|
|
2608
|
+
const file = outputFileFor(route, trailingSlash);
|
|
2609
|
+
resolveInsideOutDir(path, outDir, file);
|
|
2583
2610
|
return { route, file };
|
|
2584
2611
|
});
|
|
2585
2612
|
const origin = (options.origin ?? "http://localhost").replace(/\/+$/, "");
|
|
2586
2613
|
const timeout = options.timeout ?? 15e3;
|
|
2587
2614
|
const settle = options.settle ?? 50;
|
|
2588
|
-
const
|
|
2615
|
+
const keptShell = path.join(ctx.outDir, typeof options.shell === "string" ? options.shell : "200.html");
|
|
2616
|
+
const templatePath = await fs.access(keptShell).then(() => keptShell).catch(() => path.join(ctx.outDir, "index.html"));
|
|
2589
2617
|
const template = await fs.readFile(templatePath, "utf8");
|
|
2590
2618
|
let entry = options.entry;
|
|
2591
2619
|
if (!entry) {
|
|
@@ -2603,7 +2631,7 @@ async function prerender(options, ctx) {
|
|
|
2603
2631
|
} catch {
|
|
2604
2632
|
throw new Error("[sibu prerender] needs jsdom to render routes. Install it: npm i -D jsdom");
|
|
2605
2633
|
}
|
|
2606
|
-
const tmpDir = path.join(
|
|
2634
|
+
const tmpDir = path.join(outDir, ".sibu-prerender");
|
|
2607
2635
|
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
2608
2636
|
const viteBuild = await loadViteBuild(requireFromApp, fs, path, pathToFileURL);
|
|
2609
2637
|
const prev = process.env[PRERENDER_CHILD_ENV];
|
|
@@ -2633,10 +2661,12 @@ async function prerender(options, ctx) {
|
|
|
2633
2661
|
await fs.writeFile(workerFile, WORKER_SOURCE, "utf8");
|
|
2634
2662
|
const entryUrl = pathToFileURL(path.join(tmpDir, "entry.mjs")).href;
|
|
2635
2663
|
const jsdomUrl = pathToFileURL(jsdomPath).href;
|
|
2664
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
2636
2665
|
if (options.shell !== false) {
|
|
2637
|
-
await fs.writeFile(path.join(
|
|
2666
|
+
await fs.writeFile(path.join(outDir, options.shell ?? "200.html"), template, "utf8");
|
|
2638
2667
|
}
|
|
2639
2668
|
const results = [];
|
|
2669
|
+
const indexable = [];
|
|
2640
2670
|
const queue = [...planned];
|
|
2641
2671
|
const concurrency = Math.max(1, options.concurrency ?? 4);
|
|
2642
2672
|
try {
|
|
@@ -2654,16 +2684,35 @@ async function prerender(options, ctx) {
|
|
|
2654
2684
|
timeout,
|
|
2655
2685
|
settle
|
|
2656
2686
|
});
|
|
2657
|
-
const target = resolveInsideOutDir(path,
|
|
2687
|
+
const target = resolveInsideOutDir(path, outDir, file);
|
|
2658
2688
|
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
2659
2689
|
await fs.writeFile(target, html, "utf8");
|
|
2660
2690
|
results.push({ route: route.path, file, ms: Date.now() - started });
|
|
2691
|
+
if (file !== "404.html" && !/<meta\b[^>]*name=["']robots["'][^>]*content=["'][^"']*noindex/i.test(html)) {
|
|
2692
|
+
const pathname = route.path.split(/[?#]/)[0];
|
|
2693
|
+
indexable.push(
|
|
2694
|
+
trailingSlash === "always" && pathname !== "/" ? `${pathname.replace(/\/+$/, "")}/` : pathname
|
|
2695
|
+
);
|
|
2696
|
+
}
|
|
2661
2697
|
}
|
|
2662
2698
|
})
|
|
2663
2699
|
);
|
|
2664
2700
|
} finally {
|
|
2665
2701
|
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
2666
2702
|
}
|
|
2703
|
+
if (options.sitemap && indexable.length > 0) {
|
|
2704
|
+
const { buildSitemap } = await import("./prerenderServer-MXJEVWA3.js");
|
|
2705
|
+
await fs.writeFile(path.join(outDir, "sitemap.xml"), buildSitemap(origin, indexable.sort()), "utf8");
|
|
2706
|
+
}
|
|
2707
|
+
if (options.robots) {
|
|
2708
|
+
const extra = typeof options.robots === "string" ? `${options.robots.trim()}
|
|
2709
|
+
` : "";
|
|
2710
|
+
const sitemapLine = options.sitemap && indexable.length > 0 ? `Sitemap: ${origin}/sitemap.xml
|
|
2711
|
+
` : "";
|
|
2712
|
+
await fs.writeFile(path.join(outDir, "robots.txt"), `User-agent: *
|
|
2713
|
+
Allow: /
|
|
2714
|
+
${extra}${sitemapLine}`, "utf8");
|
|
2715
|
+
}
|
|
2667
2716
|
return results;
|
|
2668
2717
|
}
|
|
2669
2718
|
function esmEntryOf(entry) {
|
|
@@ -2698,6 +2747,7 @@ async function loadViteBuild(requireFromApp, fs, path, pathToFileURL) {
|
|
|
2698
2747
|
}
|
|
2699
2748
|
return build;
|
|
2700
2749
|
}
|
|
2750
|
+
var STARTUP_TIMEOUT = 6e4;
|
|
2701
2751
|
async function renderInWorker(workerFile, input) {
|
|
2702
2752
|
const { Worker } = await import("worker_threads");
|
|
2703
2753
|
return new Promise((resolve, reject) => {
|
|
@@ -2709,12 +2759,14 @@ async function renderInWorker(workerFile, input) {
|
|
|
2709
2759
|
fn();
|
|
2710
2760
|
void worker.terminate();
|
|
2711
2761
|
};
|
|
2712
|
-
const
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
);
|
|
2716
|
-
worker.once("message", (msg) => {
|
|
2762
|
+
const backstop = (ms, what) => setTimeout(() => finish(() => reject(new Error(`[sibu prerender] ${input.route}: ${what}`))), ms);
|
|
2763
|
+
let timer = backstop(Math.max(STARTUP_TIMEOUT, input.timeout + 5e3), "worker did not load the app");
|
|
2764
|
+
worker.on("message", (msg) => {
|
|
2717
2765
|
clearTimeout(timer);
|
|
2766
|
+
if (msg.loaded) {
|
|
2767
|
+
timer = backstop(input.timeout + 5e3, "worker did not respond");
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2718
2770
|
if (typeof msg.html === "string") finish(() => resolve(msg.html));
|
|
2719
2771
|
else finish(() => reject(new Error(`[sibu prerender] ${input.route}: ${msg.error}`)));
|
|
2720
2772
|
});
|
|
@@ -2827,6 +2879,8 @@ try {
|
|
|
2827
2879
|
process.on("unhandledRejection", (reason) => errors.push(reason));
|
|
2828
2880
|
|
|
2829
2881
|
await import(entryUrl);
|
|
2882
|
+
// The route's timeout starts now; the parent's backstop restarts with it.
|
|
2883
|
+
parentPort.postMessage({ loaded: true });
|
|
2830
2884
|
|
|
2831
2885
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
2832
2886
|
const started = Date.now();
|
|
@@ -3233,6 +3287,7 @@ function sibuVitePlugin(options = {}) {
|
|
|
3233
3287
|
return {
|
|
3234
3288
|
name: "sibu-vite-plugin",
|
|
3235
3289
|
enforce: "pre",
|
|
3290
|
+
api: { prerender: prerenderOptions },
|
|
3236
3291
|
config(_userConfig, env) {
|
|
3237
3292
|
isDevMode = resolveDevMode(devMode, env);
|
|
3238
3293
|
return {
|
|
@@ -3273,7 +3328,10 @@ function sibuVitePlugin(options = {}) {
|
|
|
3273
3328
|
const target = prerenderTarget;
|
|
3274
3329
|
prerenderTarget = null;
|
|
3275
3330
|
const results = await prerender(prerenderOptions, target);
|
|
3276
|
-
for (const r of results)
|
|
3331
|
+
for (const r of results) {
|
|
3332
|
+
const what = r.kind === "redirect" ? `redirect ${r.status} (redirects.json)` : r.kind === "skipped" ? `skipped (${r.status})` : r.file;
|
|
3333
|
+
console.log(`[sibu prerender] ${r.route} \u2192 ${what} (${r.ms} ms)`);
|
|
3334
|
+
}
|
|
3277
3335
|
},
|
|
3278
3336
|
transform(code, id) {
|
|
3279
3337
|
if (!matchesPattern(id, include) || matchesPattern(id, exclude)) {
|