@octanejs/vite-plugin 0.1.3 → 0.1.4
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/CHANGELOG.md +73 -1
- package/package.json +7 -2
- package/src/bin/preview.js +20 -5
- package/src/config-entry.js +31 -0
- package/src/constants.js +1 -0
- package/src/index.js +362 -73
- package/src/load-config.js +6 -126
- package/src/project-codegen.js +75 -15
- package/src/resolve-config.js +171 -0
- package/src/routes.js +7 -1
- package/src/server/component-wrappers.js +1 -0
- package/src/server/middleware.js +1 -0
- package/src/server/node-http.js +188 -0
- package/src/server/production.js +276 -16
- package/src/server/render-route.js +86 -37
- package/src/server/router.js +1 -0
- package/src/server/server-route.js +1 -0
- package/src/server/virtual-entry.js +176 -7
- package/tests/_fixtures/app/index.html +11 -0
- package/tests/_fixtures/app/octane.config.ts +14 -0
- package/tests/_fixtures/app/package.json +7 -0
- package/tests/_fixtures/app/src/Layout.tsrx +6 -0
- package/tests/_fixtures/app/src/Page.tsrx +17 -0
- package/tests/_fixtures/app/vite.config.ts +12 -0
- package/tests/handler.test.ts +134 -0
- package/tests/plugin.test.ts +155 -0
- package/tests/production.test.ts +157 -0
- package/tsconfig.typecheck.json +2 -2
- package/types/index.d.ts +102 -13
- package/types/node.d.ts +31 -0
- package/types/production.d.ts +34 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,77 @@
|
|
|
1
1
|
# @octanejs/vite-plugin
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6d332ad: octane.config `adapter` is now the full deploy contract `{ name?, adapt?, serve?, runtime? }`: after the production server build, closeBundle runs `adapter.adapt({ root, outDir, clientDir, serverDir, log })` so an adapter package (e.g. `@octanejs/adapter-vercel`) can restructure the output for its platform (SvelteKit-style). All parts are optional and independent — `serve`/`runtime` keep their existing meanings. `@octanejs/adapter-vercel` is registered as a server-only package: client-side imports of it resolve to the browser stub (which now also covers the octane adapter surface, `vercel`/`adapt`) instead of dragging node builtins into the client graph.
|
|
8
|
+
- 8fc8554: Production SSR builds — octane apps now deploy server-rendered instead of SPA-only:
|
|
9
|
+
|
|
10
|
+
- `vite build` produces BOTH bundles: hashed client assets in `{outDir}/client` (with the generated hydrate entry bundled into index.html via a static, Rollup-analyzable import map over the routes' entry/layout/preHydrate modules) and a self-contained SSR server at `{outDir}/server/entry.js` (app + octane bundled, only node builtins external; octane.config.ts is compiled in through a config-surface facade so neither the compiler nor vite ride along). The built index.html moves to `dist/server` — it is the SSR template, and leaving it in the static dir would shadow the handler at `/` on filesystem-first hosts.
|
|
11
|
+
- `createHandler` (`@octanejs/vite-plugin/production`) is implemented: it matches RenderRoutes/ServerRoutes, runs middleware chains, and streams via the same `renderToReadableStream` engine dev SSR uses — the rendered body region and the `#__octane_data` payload are byte-identical to dev, so `hydrateRoot()` adopts production responses unchanged (covered by an end-to-end fixture test). Per-route `<link rel="stylesheet">`/`modulepreload` tags come from the client manifest. `server.render: 'buffered'` in octane.config.ts switches to the await-everything `prerender` for hosts that break streamed responses.
|
|
12
|
+
- The server entry exports `handler` (Web fetch) and `nodeHandler` (Node `(req, res)`, for serverless wrappers such as a Vercel Node function), and auto-boots under `node dist/server/entry.js` — with the adapter's `serve()` when configured, else the new built-in Node server (`@octanejs/vite-plugin/node`) serving the client assets with immutable caching for `/assets/*`.
|
|
13
|
+
- `octane-preview` now runs that entry for real (pre-deploy verification) and accepts `--port`.
|
|
14
|
+
|
|
15
|
+
- 3c56d95: Close the four metaframework gaps the octane website surfaced:
|
|
16
|
+
|
|
17
|
+
- `octane()` now accepts `exclude` and forwards it to the bundled compiler, so monorepo / aliased-to-source setups can skip the hook-slotting pass for hand-slot-forwarding binding sources (pnpm symlinks resolve `@octanejs/*` to `packages/*/src`, which the automatic node_modules skip can't see).
|
|
18
|
+
- The dev SSR middleware skips Vite-owned requests (`/@` namespaces, `/__` internals, node_modules, `?import`-style transform queries, and extension-bearing paths that name a real file under the Vite root/publicDir — dotted page URLs like `/docs/v2.0` still SSR) before route matching, so a catch-all `'/*splat'` RenderRoute can SSR a real not-found page without swallowing `/@vite/client` or `/src/*.ts`. `RenderRoute` also takes a `status` (e.g. 404 for the catch-all) applied to the rendered response.
|
|
19
|
+
- `appType: 'custom'` is now only a default: an explicit user `appType` wins, and `vite preview` is left on Vite's own SPA fallback so it can serve the client build (production SSR serving is still Phase 2).
|
|
20
|
+
- RenderRoute components (and layouts) receive the request `url` (pathname + search) alongside `params`, on the server and on the hydrating client, and the new `router.preHydrate` config names a module whose default export the client entry awaits before `hydrateRoot` — the hook an app-level client router uses to commit its match tree so hydration adopts the server DOM. The generated client entry also hides its dynamic imports from Vite's `?import` query injection so the page/hook share module singletons with statically-imported copies.
|
|
21
|
+
|
|
22
|
+
Dev SSR now streams: RenderRoutes render through `renderToReadableStream` (shell first, suspense boundaries flush out of order behind it) instead of the buffered `prerender`.
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [05fdef8]
|
|
25
|
+
- Updated dependencies [e9ebfbf]
|
|
26
|
+
- Updated dependencies [4ac4c98]
|
|
27
|
+
- Updated dependencies [c2129eb]
|
|
28
|
+
- Updated dependencies [4ac4c98]
|
|
29
|
+
- Updated dependencies [8a44bb5]
|
|
30
|
+
- Updated dependencies [6b0c244]
|
|
31
|
+
- Updated dependencies [d3cf678]
|
|
32
|
+
- Updated dependencies [05fdef8]
|
|
33
|
+
- Updated dependencies [d19d4f3]
|
|
34
|
+
- Updated dependencies [7e84258]
|
|
35
|
+
- Updated dependencies [2f8c6ed]
|
|
36
|
+
- Updated dependencies [8de4584]
|
|
37
|
+
- Updated dependencies [9be6ba5]
|
|
38
|
+
- Updated dependencies [db409de]
|
|
39
|
+
- Updated dependencies [4f3c6c8]
|
|
40
|
+
- Updated dependencies [62c3c4e]
|
|
41
|
+
- Updated dependencies [3c56d95]
|
|
42
|
+
- Updated dependencies [4c5b1d0]
|
|
43
|
+
- Updated dependencies [b732399]
|
|
44
|
+
- Updated dependencies [6d27cb0]
|
|
45
|
+
- Updated dependencies [a3784b1]
|
|
46
|
+
- Updated dependencies [fa77edf]
|
|
47
|
+
- Updated dependencies [f5c9dba]
|
|
48
|
+
- Updated dependencies [12d5410]
|
|
49
|
+
- Updated dependencies [d71f1fc]
|
|
50
|
+
- Updated dependencies [2f8c6ed]
|
|
51
|
+
- Updated dependencies [63e51e8]
|
|
52
|
+
- Updated dependencies [6d3b269]
|
|
53
|
+
- Updated dependencies [b171c6d]
|
|
54
|
+
- Updated dependencies [7f3d9c9]
|
|
55
|
+
- Updated dependencies [820baaf]
|
|
56
|
+
- Updated dependencies [c36cb32]
|
|
57
|
+
- Updated dependencies [c33f409]
|
|
58
|
+
- Updated dependencies [63e51e8]
|
|
59
|
+
- Updated dependencies [8fc8554]
|
|
60
|
+
- Updated dependencies [569daad]
|
|
61
|
+
- Updated dependencies [6b7b727]
|
|
62
|
+
- Updated dependencies [2ce7bc5]
|
|
63
|
+
- Updated dependencies [c6a23f5]
|
|
64
|
+
- Updated dependencies [c93aad5]
|
|
65
|
+
- Updated dependencies [2942afb]
|
|
66
|
+
- Updated dependencies [388b23c]
|
|
67
|
+
- Updated dependencies [352cff1]
|
|
68
|
+
- Updated dependencies [c7989eb]
|
|
69
|
+
- Updated dependencies [dda2854]
|
|
70
|
+
- Updated dependencies [dda2854]
|
|
71
|
+
- Updated dependencies [3a9d855]
|
|
72
|
+
- Updated dependencies [1f85217]
|
|
73
|
+
- octane@0.1.4
|
|
74
|
+
|
|
3
75
|
## 0.1.3
|
|
4
76
|
|
|
5
77
|
### Patch Changes
|
|
@@ -43,7 +115,7 @@
|
|
|
43
115
|
### Patch Changes
|
|
44
116
|
|
|
45
117
|
- b3a9191: Rename `hydrate` → `hydrateRoot` and adopt React 18's shape. The hydration entry is now `hydrateRoot(container, <App/>)` — container first — and returns a full `Root` (with `.render()` and `.unmount()`), symmetric with `createRoot`. Previously `hydrate(Component, container, props)` put the component first and returned only `{ unmount }`. After hydration the returned root's `.render()` performs a normal client update against the adopted DOM (no re-hydration). The vite-plugin's generated client entry now imports and calls `hydrateRoot`.
|
|
46
|
-
- 43d940d: Exclude `@octanejs/query` from esbuild pre-bundling (optimizeDeps.exclude + ssr.noExternal). It ships a `.tsrx` provider component, so — like `octane` itself — its source must flow through the octane `.tsrx` transform rather than being pre-bundled by esbuild.
|
|
118
|
+
- 43d940d: Exclude `@octanejs/tanstack-query` from esbuild pre-bundling (optimizeDeps.exclude + ssr.noExternal). It ships a `.tsrx` provider component, so — like `octane` itself — its source must flow through the octane `.tsrx` transform rather than being pre-bundled by esbuild.
|
|
47
119
|
- cb9ad82: Rename the project from `vyre` to `octane`. The runtime now publishes as `octane` and the Vite metaframework plugin as `@octanejs/vite-plugin`. Identifiers inherited from the Ripple fork were also renamed to Octane (e.g. `setIsRippleActEnvironment` → `setIsOctaneActEnvironment`, the metaframework `ripple()` plugin → `octane()`, and the `ripple.config.ts` convention → `octane.config.ts`). References to the upstream Ripple framework and its `@ripple-ts`/`@tsrx` packages are unchanged.
|
|
48
120
|
- fcac573: Unify the server-rendering ABI to props-first, matching the client. A component body is now invoked as `(props, scope, extra)` on the server (it used to be `(scope, props, extra)`). This makes a plain `function Foo(props)` used at a `<Foo/>` site work the same on the server as on the client — including components that return a non-JSX value (a primitive coerced to text, an early return, `null`). SSR markup is unchanged (only the invocation order flipped), so hydration is unaffected. The server layout/page wrappers in the vite-plugin were updated to match.
|
|
49
121
|
- 634fd52: Align the SSR API with React and reshape the render result to `{ html, css }`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/vite-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Vite metaframework plugin for the octane renderer (dev SSR + routing + hydrate)",
|
|
@@ -31,11 +31,16 @@
|
|
|
31
31
|
"types": "./types/production.d.ts",
|
|
32
32
|
"import": "./src/server/production.js",
|
|
33
33
|
"default": "./src/server/production.js"
|
|
34
|
+
},
|
|
35
|
+
"./node": {
|
|
36
|
+
"types": "./types/node.d.ts",
|
|
37
|
+
"import": "./src/server/node-http.js",
|
|
38
|
+
"default": "./src/server/node-http.js"
|
|
34
39
|
}
|
|
35
40
|
},
|
|
36
41
|
"dependencies": {
|
|
37
42
|
"@ripple-ts/adapter": "^0.3.86",
|
|
38
|
-
"octane": "0.1.
|
|
43
|
+
"octane": "0.1.4"
|
|
39
44
|
},
|
|
40
45
|
"devDependencies": {
|
|
41
46
|
"@types/node": "^24.3.0",
|
package/src/bin/preview.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// @ts-check
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* octane-preview — Start the production SSR server.
|
|
5
6
|
*
|
|
6
|
-
* Loads octane.config.ts, reads `build.outDir`,
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* build. Until then this validates existence and errors clearly.
|
|
7
|
+
* Loads octane.config.ts, reads `build.outDir`, and spawns
|
|
8
|
+
* `node {outDir}/server/entry.js` — the self-contained server bundle
|
|
9
|
+
* `vite build` produced. This is the pre-deploy verification step: the exact
|
|
10
|
+
* handler + static assets a production host runs, on localhost.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { spawn } from 'node:child_process';
|
|
@@ -18,6 +18,20 @@ import { ENTRY_FILENAME } from '../constants.js';
|
|
|
18
18
|
|
|
19
19
|
const projectRoot = process.cwd();
|
|
20
20
|
|
|
21
|
+
// `--port <n>` / `-p <n>` sets the port (else $PORT, else the entry's 3000
|
|
22
|
+
// default). `--strictPort` is accepted for `vite preview` muscle-memory and
|
|
23
|
+
// ignored — the port is always exact (the entry never probes for a free one).
|
|
24
|
+
/** @type {string | undefined} */
|
|
25
|
+
let portArg;
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
for (let i = 0; i < args.length; i++) {
|
|
28
|
+
if (args[i] === '--port' || args[i] === '-p') {
|
|
29
|
+
portArg = args[++i];
|
|
30
|
+
} else if (args[i].startsWith('--port=')) {
|
|
31
|
+
portArg = args[i].slice('--port='.length);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
21
35
|
try {
|
|
22
36
|
const config = await loadOctaneConfig(projectRoot);
|
|
23
37
|
const outDir = config.build.outDir;
|
|
@@ -34,6 +48,7 @@ try {
|
|
|
34
48
|
const child = spawn(process.execPath, [entryPath], {
|
|
35
49
|
stdio: 'inherit',
|
|
36
50
|
cwd: projectRoot,
|
|
51
|
+
env: portArg ? { ...process.env, PORT: portArg } : process.env,
|
|
37
52
|
});
|
|
38
53
|
|
|
39
54
|
child.on('close', (code) => {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Config-surface facade for the PRODUCTION server bundle.
|
|
4
|
+
*
|
|
5
|
+
* octane.config.ts imports `RenderRoute` / `ServerRoute` / `defineConfig` from
|
|
6
|
+
* '@octanejs/vite-plugin'. The real package entry (`src/index.js`) also pulls
|
|
7
|
+
* in the octane compiler, the dev-SSR middleware, and a dynamic `import('vite')`
|
|
8
|
+
* — none of which belong in dist/server/entry.js. The SSR sub-build therefore
|
|
9
|
+
* aliases the BARE '@octanejs/vite-plugin' specifier to this module, which
|
|
10
|
+
* re-exports only what a config file can legitimately use. Subpath imports
|
|
11
|
+
* ('@octanejs/vite-plugin/production', '/node') are not affected by the alias.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export { RenderRoute, ServerRoute } from './routes.js';
|
|
15
|
+
export { resolveOctaneConfig } from './resolve-config.js';
|
|
16
|
+
|
|
17
|
+
// Mirrors src/index.js — enforce types / DX only.
|
|
18
|
+
export function defineConfig(/** @type {any} */ options) {
|
|
19
|
+
return options;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The plugin factory must never run inside the built server: the sub-build
|
|
24
|
+
* aliases it away precisely because it drags the compiler + vite along.
|
|
25
|
+
* @returns {never}
|
|
26
|
+
*/
|
|
27
|
+
export function octane() {
|
|
28
|
+
throw new Error(
|
|
29
|
+
'[@octanejs/vite-plugin] octane() is a Vite plugin — it cannot run inside the production server bundle.',
|
|
30
|
+
);
|
|
31
|
+
}
|
package/src/constants.js
CHANGED