@valbuild/next 0.135.0 → 0.136.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.
- package/CHANGELOG.md +53 -0
- package/dist/declarations/src/rsc/initValRsc.d.ts +52 -6
- package/dist/valbuild-next.cjs.dev.js +1 -1
- package/dist/valbuild-next.cjs.prod.js +1 -1
- package/dist/valbuild-next.esm.js +1 -1
- package/dist/{version-58fd6989.cjs.prod.js → version-52797e16.cjs.prod.js} +1 -1
- package/dist/{version-12fffb44.esm.js → version-b626279e.esm.js} +1 -1
- package/dist/{version-77226c0a.cjs.dev.js → version-f31c6541.cjs.dev.js} +1 -1
- package/package.json +8 -8
- package/rsc/dist/valbuild-next-rsc.cjs.dev.js +374 -254
- package/rsc/dist/valbuild-next-rsc.cjs.prod.js +374 -254
- package/rsc/dist/valbuild-next-rsc.esm.js +375 -255
- package/server/dist/valbuild-next-server.cjs.dev.js +1 -1
- package/server/dist/valbuild-next-server.cjs.prod.js +1 -1
- package/server/dist/valbuild-next-server.esm.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @valbuild/next
|
|
2
2
|
|
|
3
|
+
## 0.136.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#697](https://github.com/valbuild/val/pull/697) [`5c82928`](https://github.com/valbuild/val/commit/5c82928992d29f133f81cf0704a273c0449b18f1) Thanks [@freekh](https://github.com/freekh)! - Read draft content once per request instead of once per `fetchVal`
|
|
8
|
+
|
|
9
|
+
In draft mode, `fetchVal` resolves its selector by asking the Val server for the
|
|
10
|
+
whole module tree. It did that on every call, so a page with three reads made
|
|
11
|
+
three requests for three identical answers — and `fetchValRouteUrl` added a
|
|
12
|
+
fourth by calling `fetchVal` again on top of the caller's own. The answer cannot
|
|
13
|
+
differ between reads in one request, so it is now read once and shared. On a
|
|
14
|
+
60-module project a three-read draft render goes from ~187ms to ~70ms.
|
|
15
|
+
|
|
16
|
+
The memo is scoped to the request and nothing wider, because the response it
|
|
17
|
+
holds contains the caller's own unpublished patches: React's `cache()` in a
|
|
18
|
+
Next RSC, a `WeakMap` keyed on the `Request` in TanStack Start, and no caching
|
|
19
|
+
at all where neither is available.
|
|
20
|
+
|
|
21
|
+
What this does **not** change:
|
|
22
|
+
|
|
23
|
+
- **Production is untouched.** With Val disabled the reader never calls the
|
|
24
|
+
server; it resolves against the statically imported module, as before.
|
|
25
|
+
- **What a draft shows is unchanged.** Same query, same patch scoping — a draft
|
|
26
|
+
still shows the caller's own staged work and nobody else's.
|
|
27
|
+
- **The client readers are untouched.** `useVal` already subscribed to exactly
|
|
28
|
+
the modules its selector names.
|
|
29
|
+
- **The server still evaluates every module per request.** Narrowing the
|
|
30
|
+
request's path was measured and does not help: `/sources/~` evaluates,
|
|
31
|
+
previews and validates everything and only then filters the response, so a
|
|
32
|
+
narrow path returns less for the same milliseconds. That remains open.
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [[`cf89e74`](https://github.com/valbuild/val/commit/cf89e7429a79c4304ecbedd4f8b571a0de0f145f), [`c219574`](https://github.com/valbuild/val/commit/c21957498f3c7f4f47cef197c5dc0d591aa744ca), [`e673b43`](https://github.com/valbuild/val/commit/e673b43feaf48b7f30881d6786c858a0cb6a44a2), [`5c82928`](https://github.com/valbuild/val/commit/5c82928992d29f133f81cf0704a273c0449b18f1), [`4450be5`](https://github.com/valbuild/val/commit/4450be570ec3a66d7d98ba273c333ca2d2f163d9), [`d2f385a`](https://github.com/valbuild/val/commit/d2f385a04978992a5036379235e447ba7775faef)]:
|
|
35
|
+
- @valbuild/ui@0.136.1
|
|
36
|
+
- @valbuild/shared@0.136.1
|
|
37
|
+
- @valbuild/server@0.136.1
|
|
38
|
+
- @valbuild/core@0.136.1
|
|
39
|
+
- @valbuild/react@0.136.1
|
|
40
|
+
- @valbuild/language-server@0.136.1
|
|
41
|
+
- @valbuild/mcp@0.136.1
|
|
42
|
+
|
|
43
|
+
## 0.136.0
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- Updated dependencies [[`f3a4bb7`](https://github.com/valbuild/val/commit/f3a4bb7aea604943b92545c122243798c759715c), [`1d72d00`](https://github.com/valbuild/val/commit/1d72d00a1b036959ae0f1540121701cbb2694dcb)]:
|
|
48
|
+
- @valbuild/ui@0.136.0
|
|
49
|
+
- @valbuild/core@0.136.0
|
|
50
|
+
- @valbuild/server@0.136.0
|
|
51
|
+
- @valbuild/shared@0.136.0
|
|
52
|
+
- @valbuild/language-server@0.136.0
|
|
53
|
+
- @valbuild/react@0.136.0
|
|
54
|
+
- @valbuild/mcp@0.136.0
|
|
55
|
+
|
|
3
56
|
## 0.135.0
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
|
@@ -1,23 +1,69 @@
|
|
|
1
1
|
import { type JsonEntryContentOf, type Resolvable, type ResolvedVal, type RouteValueOf } from "@valbuild/react/stega";
|
|
2
2
|
import { ValConfig, ValModules, type ResolvableModule } from "@valbuild/core";
|
|
3
3
|
import { cookies, draftMode, headers } from "next/headers";
|
|
4
|
+
import { type RequestScopedMemo } from "@valbuild/shared/internal";
|
|
4
5
|
import { ValServer } from "@valbuild/server";
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The `modules` map every `fetchVal` in one render shares.
|
|
8
|
+
*
|
|
9
|
+
* Derived from the route's own response type rather than restated, so it cannot
|
|
10
|
+
* drift from what `/sources/~` actually returns.
|
|
11
|
+
*/
|
|
12
|
+
export type DraftSources = Extract<Awaited<ReturnType<ValServer["/sources/~"]["PUT"]>>, {
|
|
13
|
+
status: 200;
|
|
14
|
+
}>["json"]["modules"];
|
|
15
|
+
/**
|
|
16
|
+
* The slice of `ValServer` the draft-sources reader uses.
|
|
17
|
+
*
|
|
18
|
+
* Narrower than `ValServer` for the same reason `JsonEntryValServer` below is:
|
|
19
|
+
* it says what the dependency IS, and it lets a test drive the reader with a
|
|
20
|
+
* one-route fake instead of casting a partial object to the whole server type.
|
|
21
|
+
*/
|
|
22
|
+
export type DraftSourcesValServer = Pick<ValServer, "/sources/~">;
|
|
23
|
+
/** What the route readers need: the tree, plus the single-entry route. */
|
|
24
|
+
export type RouteReaderValServer = Pick<ValServer, "/sources/~" | "/json">;
|
|
25
|
+
/**
|
|
26
|
+
* Where the reader gets its per-request memo box.
|
|
27
|
+
*
|
|
28
|
+
* Injected rather than reached for, so that "this reader needs a request to
|
|
29
|
+
* scope its cache to" is part of its contract and a test can supply a scope it
|
|
30
|
+
* controls — in jest, React's non-`react-server` build makes `cache` a
|
|
31
|
+
* pass-through, so the real wiring memoises nothing there.
|
|
32
|
+
*/
|
|
33
|
+
export type GetDraftSourcesScope = () => Promise<RequestScopedMemo<DraftSources | null> | null>;
|
|
34
|
+
/**
|
|
35
|
+
* A per-request memo box, from React's request memoisation.
|
|
36
|
+
*
|
|
37
|
+
* `cache()` is what makes this safe: in an RSC render React hands back the SAME
|
|
38
|
+
* object for the length of one request and a fresh one for the next. Outside
|
|
39
|
+
* that — a route handler, a test, the non-`react-server` build of React —
|
|
40
|
+
* `cache` is a pass-through, so every call gets its own object, the memo misses,
|
|
41
|
+
* and the reader does exactly what it did before. Ineffective, never shared.
|
|
42
|
+
* See `memoizePerRequest`. `fetchVal` is an RSC API (`SET_RSC(true)` above, and
|
|
43
|
+
* its own error messages say so), so the effective case is the normal one.
|
|
44
|
+
*
|
|
45
|
+
* Built PER `initValRsc` rather than once for the module, because the box is
|
|
46
|
+
* only as specific as the `cache()` it came from: two Val servers in one
|
|
47
|
+
* process sharing one would answer each other's reads within a request, and
|
|
48
|
+
* they hold different content.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createReactCacheScope(): GetDraftSourcesScope;
|
|
51
|
+
export declare const initFetchValStega: (config: ValConfig, valApiEndpoints: string, valServerPromise: Promise<DraftSourcesValServer>, isEnabled: () => Promise<boolean>, getHeaders: () => Promise<{
|
|
6
52
|
get(name: string): string | null;
|
|
7
53
|
}>, getCookies: () => Promise<{
|
|
8
54
|
get(name: string): {
|
|
9
55
|
name: string;
|
|
10
56
|
value: string;
|
|
11
57
|
} | undefined;
|
|
12
|
-
}
|
|
13
|
-
declare const initFetchValRouteStega: (config: ValConfig, valApiEndpoints: string, valServerPromise: Promise<
|
|
58
|
+
}>, getDraftSourcesScope: GetDraftSourcesScope) => <T extends Resolvable>(selector: T) => Promise<ResolvedVal<T>>;
|
|
59
|
+
declare const initFetchValRouteStega: (config: ValConfig, valApiEndpoints: string, valServerPromise: Promise<RouteReaderValServer>, isEnabled: () => Promise<boolean>, getHeaders: () => Promise<{
|
|
14
60
|
get(name: string): string | null;
|
|
15
61
|
}>, getCookies: () => Promise<{
|
|
16
62
|
get(name: string): {
|
|
17
63
|
name: string;
|
|
18
64
|
value: string;
|
|
19
65
|
} | undefined;
|
|
20
|
-
}
|
|
66
|
+
}>, getDraftSourcesScope: GetDraftSourcesScope) => <T extends ResolvableModule>(selector: T, params: Promise<Record<string, string | string[]>> | Record<string, string | string[]> | unknown) => Promise<RouteValueOf<T>>;
|
|
21
67
|
/**
|
|
22
68
|
* Loads a single `.jsonValues()` entry's DRAFT content via the in-process
|
|
23
69
|
* `/json` endpoint (which replays pending patches). Returns `undefined` when the
|
|
@@ -75,14 +121,14 @@ export declare const initFetchValKeyStega: (valServerPromise: Promise<JsonEntryV
|
|
|
75
121
|
value: string;
|
|
76
122
|
} | undefined;
|
|
77
123
|
}>) => <T extends ResolvableModule>(selector: T, key: string) => Promise<JsonEntryContentOf<T> | undefined>;
|
|
78
|
-
declare const initFetchValRouteUrl: (config: ValConfig, valApiEndpoints: string, valServerPromise: Promise<
|
|
124
|
+
declare const initFetchValRouteUrl: (config: ValConfig, valApiEndpoints: string, valServerPromise: Promise<RouteReaderValServer>, isEnabled: () => Promise<boolean>, getHeaders: () => Promise<{
|
|
79
125
|
get(name: string): string | null;
|
|
80
126
|
}>, getCookies: () => Promise<{
|
|
81
127
|
get(name: string): {
|
|
82
128
|
name: string;
|
|
83
129
|
value: string;
|
|
84
130
|
} | undefined;
|
|
85
|
-
}
|
|
131
|
+
}>, getDraftSourcesScope: GetDraftSourcesScope) => <T extends ResolvableModule>(selector: T, params?: Promise<Record<string, string | string[]>> | Record<string, string | string[]> | unknown) => Promise<string | null>;
|
|
86
132
|
type ValNextRscConfig = {
|
|
87
133
|
draftMode: typeof draftMode;
|
|
88
134
|
headers: typeof headers;
|
|
@@ -12,7 +12,7 @@ var NextImage = require('next/image');
|
|
|
12
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
13
|
var ValApp = require('./ValApp-294e5b53.cjs.dev.js');
|
|
14
14
|
var ValModulesClient = require('./ValModulesClient-4ecabf99.cjs.dev.js');
|
|
15
|
-
var version = require('./version-
|
|
15
|
+
var version = require('./version-f31c6541.cjs.dev.js');
|
|
16
16
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-0445603c.cjs.dev.js');
|
|
17
17
|
require('./defineProperty-f90345d7.cjs.dev.js');
|
|
18
18
|
require('./unsupportedIterableToArray-c8ab77c9.cjs.dev.js');
|
|
@@ -12,7 +12,7 @@ var NextImage = require('next/image');
|
|
|
12
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
13
13
|
var ValApp = require('./ValApp-ab8a96fd.cjs.prod.js');
|
|
14
14
|
var ValModulesClient = require('./ValModulesClient-10c0721c.cjs.prod.js');
|
|
15
|
-
var version = require('./version-
|
|
15
|
+
var version = require('./version-52797e16.cjs.prod.js');
|
|
16
16
|
var createForOfIteratorHelper = require('./createForOfIteratorHelper-d4afcad8.cjs.prod.js');
|
|
17
17
|
require('./defineProperty-8951f469.cjs.prod.js');
|
|
18
18
|
require('./unsupportedIterableToArray-0d2087a2.cjs.prod.js');
|
|
@@ -11,7 +11,7 @@ import NextImage from 'next/image';
|
|
|
11
11
|
import { jsx } from 'react/jsx-runtime';
|
|
12
12
|
export { ValApp } from './ValApp-3a70afe1.esm.js';
|
|
13
13
|
export { ValModulesClient, useRegisterValModules } from './ValModulesClient-0dd601a1.esm.js';
|
|
14
|
-
import { V as VERSION } from './version-
|
|
14
|
+
import { V as VERSION } from './version-b626279e.esm.js';
|
|
15
15
|
import { _ as _createForOfIteratorHelper } from './createForOfIteratorHelper-5758a730.esm.js';
|
|
16
16
|
import './defineProperty-cca5affa.esm.js';
|
|
17
17
|
import './unsupportedIterableToArray-5baabfdc.esm.js';
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"next",
|
|
13
13
|
"react"
|
|
14
14
|
],
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.136.1",
|
|
16
16
|
"main": "dist/valbuild-next.cjs.js",
|
|
17
17
|
"module": "dist/valbuild-next.esm.js",
|
|
18
18
|
"exports": {
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"client-only": "^0.0.1",
|
|
49
49
|
"server-only": "^0.0.1",
|
|
50
|
-
"@valbuild/core": "0.
|
|
51
|
-
"@valbuild/
|
|
52
|
-
"@valbuild/
|
|
53
|
-
"@valbuild/react": "0.
|
|
54
|
-
"@valbuild/server": "0.
|
|
55
|
-
"@valbuild/shared": "0.
|
|
56
|
-
"@valbuild/ui": "0.
|
|
50
|
+
"@valbuild/core": "0.136.1",
|
|
51
|
+
"@valbuild/mcp": "0.136.1",
|
|
52
|
+
"@valbuild/language-server": "0.136.1",
|
|
53
|
+
"@valbuild/react": "0.136.1",
|
|
54
|
+
"@valbuild/server": "0.136.1",
|
|
55
|
+
"@valbuild/shared": "0.136.1",
|
|
56
|
+
"@valbuild/ui": "0.136.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@testing-library/react": "^16.3.3",
|