@jk2908/solas 0.16.2 → 0.16.3
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 +12 -0
- package/dist/index.js +7 -1
- package/dist/internal/env/browser.js +11 -4
- package/dist/internal/http-router/router.js +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.3
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- Server actions invoked from the browser now request the RSC representation (`accept: text/x-component`). The server previously answered with an HTML document, which surfaced as React's "Connection closed" error (#412) and left the UI un-updated even though the action ran.
|
|
8
|
+
- Static responses carry `Content-Length`, so prerendered HTML, CSS and client assets are no longer sent chunked.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- The client hydrates inside `startTransition`, so the browser can paint the server markup before React walks the tree.
|
|
13
|
+
- Production builds pin `process.env.NODE_ENV` to the build mode and minify server bundles. This removes the development React branches and reduces the deployable output size.
|
|
14
|
+
|
|
3
15
|
## 0.16.2
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/dist/index.js
CHANGED
|
@@ -232,7 +232,7 @@ function solas(c) {
|
|
|
232
232
|
}
|
|
233
233
|
const plugin = {
|
|
234
234
|
name: Config.NAME,
|
|
235
|
-
async config(viteConfig) {
|
|
235
|
+
async config(viteConfig, env) {
|
|
236
236
|
const pkg = JSON.parse(fsSync.readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
|
|
237
237
|
if (typeof pkg.name !== 'string' || pkg.name.length === 0) {
|
|
238
238
|
throw new Error(`Missing ${Config.NAME} package name`);
|
|
@@ -276,6 +276,12 @@ function solas(c) {
|
|
|
276
276
|
viteConfig.define['import.meta.env.VITE_APP_URL'] = JSON.stringify(resolvedUrl);
|
|
277
277
|
viteConfig.define['import.meta.env.SOLAS_VERSION'] = JSON.stringify(pkg.version);
|
|
278
278
|
viteConfig.define['import.meta.env.SOLAS_ADAPTER'] = JSON.stringify(config.adapter?.name ?? '');
|
|
279
|
+
// production builds can drop the development React branches and ship
|
|
280
|
+
// minified server bundles; dev keeps readable output and HMR
|
|
281
|
+
if (env?.command === 'build') {
|
|
282
|
+
viteConfig.define['process.env.NODE_ENV'] = JSON.stringify(env.mode);
|
|
283
|
+
viteConfig.build.minify ??= true;
|
|
284
|
+
}
|
|
279
285
|
viteConfig.optimizeDeps ??= {};
|
|
280
286
|
viteConfig.optimizeDeps.exclude = [
|
|
281
287
|
...new Set([
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { StrictMode, Suspense, useCallback, useState, useTransition } from 'react';
|
|
2
|
+
import { StrictMode, Suspense, startTransition, useCallback, useState, useTransition, } from 'react';
|
|
3
3
|
import { hydrateRoot } from 'react-dom/client';
|
|
4
4
|
import { createFromFetch, createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback, } from '@vitejs/plugin-rsc/browser';
|
|
5
5
|
import { getDocumentNonce } from '../../utils/get-document-nonce.js';
|
|
@@ -35,7 +35,10 @@ export async function browser() {
|
|
|
35
35
|
setServerCallback(async (id, args) => {
|
|
36
36
|
const url = new URL(window.location.href);
|
|
37
37
|
const temporaryReferences = createTemporaryReferenceSet();
|
|
38
|
-
const headers = new Headers({
|
|
38
|
+
const headers = new Headers({
|
|
39
|
+
accept: 'text/x-component',
|
|
40
|
+
'x-rsc-action-id': id,
|
|
41
|
+
});
|
|
39
42
|
const nonce = getDocumentNonce();
|
|
40
43
|
if (nonce)
|
|
41
44
|
headers.set('x-solas-nonce', nonce);
|
|
@@ -50,8 +53,12 @@ export async function browser() {
|
|
|
50
53
|
throw data;
|
|
51
54
|
return data;
|
|
52
55
|
});
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
// hydrate as a transition so the browser can paint the server markup
|
|
57
|
+
// before React starts walking the tree
|
|
58
|
+
startTransition(() => {
|
|
59
|
+
hydrateRoot(document, _jsx(StrictMode, { children: _jsx(A, {}) }), {
|
|
60
|
+
formState: payload.formState,
|
|
61
|
+
});
|
|
55
62
|
});
|
|
56
63
|
if (import.meta.hot) {
|
|
57
64
|
import.meta.hot.on?.('rsc:update', async () => {
|
|
@@ -288,9 +288,13 @@ export class HttpRouter {
|
|
|
288
288
|
}
|
|
289
289
|
// get mime type from original path, not compressed variant
|
|
290
290
|
const mimeType = assets.mimeType(asset.path);
|
|
291
|
-
const
|
|
291
|
+
const buffer = await assets.readBuffer(resolved);
|
|
292
|
+
const res = new Response(buffer, {
|
|
292
293
|
headers: {
|
|
293
294
|
'Content-Type': headers['Content-Type'] ?? mimeType,
|
|
295
|
+
// a static file has a known size; sending it lets the client finish
|
|
296
|
+
// the response without waiting for a chunked terminator
|
|
297
|
+
'Content-Length': String(buffer.byteLength),
|
|
294
298
|
},
|
|
295
299
|
});
|
|
296
300
|
for (const [key, value] of Object.entries(headers)) {
|
package/package.json
CHANGED