@void/react 0.10.13 → 0.20.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present, Cloudflare, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -219,8 +219,9 @@ export const loader = defineHandler(() => ({ title: 'Home' }));
219
219
 
220
220
  ## Tests
221
221
 
222
- - `test/unit/use-form.test.ts`
223
222
  - `test/unit/link.test.ts`
224
223
  - `test/integration/react-pages-client.test.ts`
225
224
 
226
- Cross-package SSR/protocol coverage for React pages mode also lives in `framework/packages/void/test/integration/*`.
225
+ Cross-package SSR/protocol coverage for React pages mode also lives in `packages/void/test/integration/*`.
226
+
227
+ The [shared client](../../test/pages-client-contract.ts) and [island](../../test/pages-island-contract.ts) contracts run against this adapter in both dev and preview. Shared form equality is tested directly in [Void](../void/test/unit/form-value-equality.test.ts); tests do not copy the hook implementation.
@@ -2,7 +2,6 @@ import { AnchorHTMLAttributes, ButtonHTMLAttributes, Context, JSX } from "react"
2
2
  import { ActionResult, NavigationState, VoidActionError, VoidRouter } from "void/pages-client";
3
3
  import { CloudContextVariables, InferProps } from "void";
4
4
  import { ActionFormOptions, ActionUrl, ResolveActionBody, ResolveActionParams } from "void/routes";
5
-
6
5
  //#region src/runtime/link.d.ts
7
6
  type PrefetchStrategy = "hover" | "click" | "mount" | "visible";
8
7
  type LinkMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
@@ -22,28 +21,7 @@ type CommonProps = {
22
21
  }) => void;
23
22
  };
24
23
  type LinkProps = CommonProps & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof CommonProps> & Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof CommonProps>;
25
- declare function Link({
26
- href,
27
- method,
28
- data,
29
- preserveScroll,
30
- preserveState,
31
- replace,
32
- reloadDocument,
33
- viewTransition,
34
- prefetch: prefetchProp,
35
- cacheFor,
36
- onNavigate,
37
- children,
38
- style,
39
- onClick: onClickProp,
40
- onMouseEnter: onMouseEnterProp,
41
- onMouseLeave: onMouseLeaveProp,
42
- onFocus: onFocusProp,
43
- onMouseDown: onMouseDownProp,
44
- onTouchStart: onTouchStartProp,
45
- ...rest
46
- }: LinkProps): JSX.Element;
24
+ declare function Link({ href, method, data, preserveScroll, preserveState, replace, reloadDocument, viewTransition, prefetch: prefetchProp, cacheFor, onNavigate, children, style, onClick: onClickProp, onMouseEnter: onMouseEnterProp, onMouseLeave: onMouseLeaveProp, onFocus: onFocusProp, onMouseDown: onMouseDownProp, onTouchStart: onTouchStartProp, ...rest }: LinkProps): JSX.Element;
47
25
  //#endregion
48
26
  //#region src/runtime/use-router.d.ts
49
27
  declare function useRouter(): VoidRouter;
@@ -95,9 +73,9 @@ type IslandFormReturn<T extends Record<string, unknown>> = Readonly<{
95
73
  delete: (url: string) => Promise<void>;
96
74
  }>;
97
75
  /**
98
- * Form hook for island pages. Uses fetch + page reload instead of the
99
- * Void Router (which is not available in island mode).
100
- */
76
+ * Form hook for island pages. Uses fetch + page reload instead of the
77
+ * Void Router (which is not available in island mode).
78
+ */
101
79
  declare function useIslandForm<T extends Record<string, unknown>>(defaults: T): IslandFormReturn<T>;
102
80
  //#endregion
103
81
  //#region src/runtime/action.d.ts
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ParamsContext, c as action, d as useNavigation, f as useForm, g as Link, h as useRouter, i as NavigationContext, l as setActionRouter, m as useParams, n as InferProps, o as RouterContext, p as useShared, r as ErrorsContext, s as SharedContext, t as Deferred, u as useIslandForm } from "./index-5JoQg_-q.mjs";
1
+ import { a as ParamsContext, c as action, d as useNavigation, f as useForm, g as Link, h as useRouter, i as NavigationContext, l as setActionRouter, m as useParams, n as InferProps, o as RouterContext, p as useShared, r as ErrorsContext, s as SharedContext, t as Deferred, u as useIslandForm } from "./index-Cx2A1XEu.mjs";
2
2
  export { Deferred, ErrorsContext, type InferProps, Link, NavigationContext, ParamsContext, RouterContext, SharedContext, action, setActionRouter, useForm, useIslandForm, useNavigation, useParams, useRouter, useShared };
package/dist/plugin.d.mts CHANGED
@@ -1,16 +1,14 @@
1
1
  import react from "@vitejs/plugin-react";
2
2
  import { Plugin } from "vite";
3
-
4
3
  //#region src/plugin.d.ts
5
4
  type PrefetchConfig = {
6
5
  hoverDelay?: number;
7
6
  cacheFor?: number | string | [string, string];
8
7
  };
9
- type VoidReactOptions = Readonly<{
8
+ export type VoidReactOptions = Readonly<{
10
9
  react?: Parameters<typeof react>[0];
11
10
  viewTransitions?: boolean;
12
11
  prefetch?: PrefetchConfig;
13
12
  }>;
14
- declare function voidReact(options?: VoidReactOptions): Array<Plugin>;
15
- //#endregion
16
- export { VoidReactOptions, voidReact };
13
+ export declare function voidReact(options?: VoidReactOptions): Array<Plugin>;
14
+ //#endregion
package/dist/plugin.mjs CHANGED
@@ -319,6 +319,7 @@ initIslands(islands, hydrateIsland);
319
319
  }
320
320
  //#endregion
321
321
  //#region src/plugin-pages.ts
322
+ const RENDERER_ID = "virtual:void-pages-renderer";
322
323
  const CLIENT_ENTRY_ID = "virtual:void-pages-client";
323
324
  const WORKER_ENVIRONMENT_NAME = "void_worker";
324
325
  const REACT_DEDUPE = ["react", "react-dom"];
@@ -364,7 +365,7 @@ function pagesPlugin(pagesDir, options) {
364
365
  return pendingRescan;
365
366
  };
366
367
  const invalidatePageModules = (server) => {
367
- for (const env of Object.values(server.environments)) for (const id of ["\0virtual:void-pages-renderer", "\0virtual:void-pages-client"]) {
368
+ for (const env of Object.values(server.environments)) for (const id of ["\0" + RENDERER_ID, "\0" + CLIENT_ENTRY_ID]) {
368
369
  const mod = env.moduleGraph.getModuleById(id);
369
370
  if (mod) env.moduleGraph.invalidateModule(mod);
370
371
  }
@@ -385,11 +386,11 @@ function pagesPlugin(pagesDir, options) {
385
386
  async handler(id) {
386
387
  if (isDev && pendingRescan) await pendingRescan;
387
388
  if (!pageScan && existsSync(pagesDir)) await runRescan();
388
- if (id === "\0virtual:void-pages-renderer") {
389
+ if (id === "\0" + RENDERER_ID) {
389
390
  if (!pageScan) return "export function renderPage() { throw new Error('No pages found'); }";
390
391
  return generateRendererModule(pageScan, pagesDir, isDev);
391
392
  }
392
- if (id === "\0virtual:void-pages-client") {
393
+ if (id === "\0" + CLIENT_ENTRY_ID) {
393
394
  if (!pageScan) return "";
394
395
  return generateClientEntry(pageScan, pagesDir, options?.viewTransitions, options?.prefetch, resolveStaticPageDataBuildOptions(root, { publicDir: viteConfig?.publicDir }));
395
396
  }
@@ -1,2 +1,2 @@
1
- import { a as ParamsContext, c as action, d as useNavigation, f as useForm, g as Link, h as useRouter, i as NavigationContext, l as setActionRouter, m as useParams, n as InferProps, o as RouterContext, p as useShared, r as ErrorsContext, s as SharedContext, t as Deferred, u as useIslandForm } from "../index-5JoQg_-q.mjs";
1
+ import { a as ParamsContext, c as action, d as useNavigation, f as useForm, g as Link, h as useRouter, i as NavigationContext, l as setActionRouter, m as useParams, n as InferProps, o as RouterContext, p as useShared, r as ErrorsContext, s as SharedContext, t as Deferred, u as useIslandForm } from "../index-Cx2A1XEu.mjs";
2
2
  export { Deferred, ErrorsContext, type InferProps, Link, NavigationContext, ParamsContext, RouterContext, SharedContext, action, setActionRouter, useForm, useIslandForm, useNavigation, useParams, useRouter, useShared };
@@ -1,12 +1,11 @@
1
1
  import { ComponentType } from "react";
2
2
  import { VoidRouter } from "void/pages-client";
3
3
  import { CacheForResult } from "void/pages-prefetch";
4
-
5
4
  //#region src/runtime/pages-client.d.ts
6
5
  type ComponentModule = {
7
6
  default: ComponentType<any>;
8
7
  };
9
- type ReactPagesConfig = Readonly<{
8
+ export type ReactPagesConfig = Readonly<{
10
9
  components: Record<string, () => Promise<ComponentModule>>;
11
10
  layoutTree: Record<string, Array<string>>;
12
11
  routeMeta: Record<string, {
@@ -19,9 +18,8 @@ type ReactPagesConfig = Readonly<{
19
18
  prefetchHoverDelay: number;
20
19
  prefetchDefaultCacheFor: CacheForResult;
21
20
  }>;
22
- type ReactPagesClient = Readonly<{
21
+ export type ReactPagesClient = Readonly<{
23
22
  router: VoidRouter;
24
23
  }>;
25
- declare function startReactPages(config: ReactPagesConfig): Promise<ReactPagesClient>;
26
- //#endregion
27
- export { ReactPagesClient, ReactPagesConfig, startReactPages };
24
+ export declare function startReactPages(config: ReactPagesConfig): Promise<ReactPagesClient>;
25
+ //#endregion
@@ -193,27 +193,28 @@ function startViewTransition(resource, reveal, enabled) {
193
193
  function App({ engine, router, viewTransitions }) {
194
194
  const initialPageData = engine.initialPageData;
195
195
  const sharedStateRef = useRef(initialPageData.shared);
196
+ const initialResource = useMemo(() => ({
197
+ id: 0,
198
+ url: initialPageData.url || currentUrl(),
199
+ fetchUrl: initialPageData.url || currentUrl(),
200
+ hash: window.location.hash,
201
+ method: "GET",
202
+ options: {},
203
+ immediate: false,
204
+ shell: Promise.resolve({
205
+ pageData: {
206
+ ...initialPageData,
207
+ shared: initialPageData.shared
208
+ },
209
+ component: engine.initialComponent,
210
+ layouts: engine.initialLayouts
211
+ }),
212
+ abort() {},
213
+ async commit() {},
214
+ dispose() {}
215
+ }), [engine, initialPageData]);
196
216
  const [state, dispatch] = useReducer(appReducer, {
197
- resource: useMemo(() => ({
198
- id: 0,
199
- url: initialPageData.url || currentUrl(),
200
- fetchUrl: initialPageData.url || currentUrl(),
201
- hash: window.location.hash,
202
- method: "GET",
203
- options: {},
204
- immediate: false,
205
- shell: Promise.resolve({
206
- pageData: {
207
- ...initialPageData,
208
- shared: initialPageData.shared
209
- },
210
- component: engine.initialComponent,
211
- layouts: engine.initialLayouts
212
- }),
213
- abort() {},
214
- async commit() {},
215
- dispose() {}
216
- }), [engine, initialPageData]),
217
+ resource: initialResource,
217
218
  rollbackResource: null,
218
219
  pendingId: null,
219
220
  routeUrl: currentUrl(),
@@ -1,11 +1,10 @@
1
1
  import { ComponentType } from "react";
2
2
  import { PageObject } from "void/pages-protocol";
3
-
4
3
  //#region src/runtime/pages-server.d.ts
5
4
  type ComponentModule = {
6
5
  default: ComponentType<any>;
7
6
  };
8
- type ReactPagesServerConfig = Readonly<{
7
+ export type ReactPagesServerConfig = Readonly<{
9
8
  pageObj: PageObject;
10
9
  assetTags: {
11
10
  css: string;
@@ -16,12 +15,5 @@ type ReactPagesServerConfig = Readonly<{
16
15
  layoutTree: Record<string, Array<string>>;
17
16
  preambleScript?: string;
18
17
  }>;
19
- declare function renderReactPage({
20
- pageObj,
21
- assetTags,
22
- components,
23
- layoutTree,
24
- preambleScript
25
- }: ReactPagesServerConfig): Promise<ReadableStream<Uint8Array>>;
26
- //#endregion
27
- export { ReactPagesServerConfig, renderReactPage };
18
+ export declare function renderReactPage({ pageObj, assetTags, components, layoutTree, preambleScript }: ReactPagesServerConfig): Promise<ReadableStream<Uint8Array>>;
19
+ //#endregion
@@ -84,7 +84,8 @@ async function renderReactPage({ pageObj, assetTags, components, layoutTree, pre
84
84
  let element = React.createElement(PageComponent, renderProps);
85
85
  for (let i = layoutComponents.length - 1; i >= 0; i--) element = React.createElement(layoutComponents[i], null, element);
86
86
  element = React.createElement(RouterContext.Provider, { value: createSsrRouter(pageObj.url || "/", pageObj.params ?? {}) }, React.createElement(NavigationContext.Provider, { value: idleNavigationState() }, React.createElement(React.Suspense, { fallback: null }, React.createElement(SharedContext.Provider, { value: pageObj.shared || {} }, React.createElement(ParamsContext.Provider, { value: pageObj.params ?? {} }, React.createElement(ErrorsContext.Provider, { value: pageObj.errors || {} }, element))))));
87
- const appStream = await renderToReadableStream(pageObj.deferredKeys ? React.createElement(React.Fragment, null, element, React.createElement("template", { id: DEFERRED_SHELL_END_ID })) : element, { onError(error) {
87
+ const renderElement = pageObj.deferredKeys ? React.createElement(React.Fragment, null, element, React.createElement("template", { id: DEFERRED_SHELL_END_ID })) : element;
88
+ const appStream = await renderToReadableStream(renderElement, { onError(error) {
88
89
  if (error === DEFERRED_SHELL_CANCEL_REASON) return;
89
90
  throw error;
90
91
  } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@void/react",
3
- "version": "0.10.13",
3
+ "version": "0.20.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/voidzero-dev/void.git",
@@ -19,14 +19,6 @@
19
19
  "types": "./dist/plugin.d.mts",
20
20
  "import": "./dist/plugin.mjs"
21
21
  },
22
- "./runtime": {
23
- "types": "./dist/runtime/index.d.mts",
24
- "import": "./dist/runtime/index.mjs"
25
- },
26
- "./prefetch": {
27
- "types": "./dist/runtime/prefetch.d.mts",
28
- "import": "./dist/runtime/prefetch.mjs"
29
- },
30
22
  "./pages-client": {
31
23
  "types": "./dist/runtime/pages-client.d.mts",
32
24
  "import": "./dist/runtime/pages-client.mjs"
@@ -40,28 +32,28 @@
40
32
  "access": "public"
41
33
  },
42
34
  "dependencies": {
43
- "@vitejs/plugin-react": "^6.0.3"
35
+ "@vitejs/plugin-react": "^6.1.1"
44
36
  },
45
37
  "devDependencies": {
46
- "@types/node": "^26.1.0",
47
- "@types/react": "^19.2.17",
48
- "@types/react-dom": "^19.2.3",
38
+ "@types/node": "^26.5.1",
39
+ "@types/react": "^19.3.0",
40
+ "@types/react-dom": "^19.3.0",
49
41
  "pathslash": "^0.1.0",
50
- "react": "^19.2.7",
51
- "react-dom": "^19.2.7",
52
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2",
53
- "vite-plus": "^0.2.2",
54
- "void": "0.10.13"
42
+ "react": "^19.3.0",
43
+ "react-dom": "^19.3.0",
44
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.1",
45
+ "vite-plus": "0.3.1",
46
+ "void": "0.20.1"
55
47
  },
56
48
  "peerDependencies": {
57
49
  "react": "^19.0.0",
58
50
  "react-dom": "^19.0.0",
59
51
  "vite": "^8.0.0",
60
- "void": "0.10.13"
52
+ "void": "0.20.1"
61
53
  },
62
54
  "scripts": {
63
55
  "build": "vp pack",
64
56
  "dev": "vp pack --watch",
65
- "typecheck": "tsgo --noEmit"
57
+ "typecheck": "tsc --noEmit --rootDir ../.."
66
58
  }
67
59
  }
@@ -1,2 +0,0 @@
1
- import { CacheEntry, CacheForInput, CacheForResult, PrefetchCache, parseCacheFor } from "void/pages-prefetch";
2
- export { type CacheEntry, type CacheForInput, type CacheForResult, PrefetchCache, parseCacheFor };
@@ -1,2 +0,0 @@
1
- import { PrefetchCache, parseCacheFor } from "void/pages-prefetch";
2
- export { PrefetchCache, parseCacheFor };