@solidjs/router 0.17.0-next.4 → 0.17.0-next.5

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.
@@ -1,5 +1,6 @@
1
1
  import { $TRACK, action as createSolidAction, createMemo, onCleanup, getOwner } from "solid-js";
2
- import { isServer } from "@solidjs/web";
2
+ import { isResponseEnvelope, isServer } from "@solidjs/web";
3
+ import { decodeResponse } from "@solidjs/web/server-functions";
3
4
  import { useRouter } from "../routing.js";
4
5
  import { mockBase, setFunctionName } from "../utils.js";
5
6
  import { cacheKeyOp, hashKey, revalidate, query } from "./query.js";
@@ -151,19 +152,35 @@ async function handleResponse(response, error, navigate) {
151
152
  let custom;
152
153
  let keys;
153
154
  let flightKeys;
154
- if (response instanceof Response) {
155
- if (response.headers.has("X-Revalidate"))
156
- keys = response.headers.get("X-Revalidate").split(",");
157
- if (response.customBody) {
158
- data = custom = await response.customBody();
155
+ let metadata;
156
+ if (isResponseEnvelope(response)) {
157
+ // client-only respond(): the value rides in memory beside the metadata
158
+ data = response.value;
159
+ metadata = response.response;
160
+ }
161
+ else if (response instanceof Response) {
162
+ metadata = response;
163
+ // responses the transport hands over whole (redirects, revalidation,
164
+ // single-flight) carry a codec-encoded body the router decodes itself
165
+ if (response.body) {
166
+ data = await decodeResponse(response);
159
167
  if (response.headers.has("X-Single-Flight")) {
160
- data = data._$value;
168
+ custom = data;
169
+ data = custom._$value;
161
170
  delete custom._$value;
162
171
  flightKeys = Object.keys(custom);
163
172
  }
164
173
  }
165
- if (response.headers.has("Location")) {
166
- const locationUrl = response.headers.get("Location") || "/";
174
+ }
175
+ else if (error)
176
+ return { error: response };
177
+ else
178
+ data = response;
179
+ if (metadata) {
180
+ if (metadata.headers.has("X-Revalidate"))
181
+ keys = metadata.headers.get("X-Revalidate").split(",");
182
+ if (metadata.headers.has("Location")) {
183
+ const locationUrl = metadata.headers.get("Location") || "/";
167
184
  if (locationUrl.startsWith("http")) {
168
185
  window.location.href = locationUrl;
169
186
  }
@@ -172,10 +189,6 @@ async function handleResponse(response, error, navigate) {
172
189
  }
173
190
  }
174
191
  }
175
- else if (error)
176
- return { error: response };
177
- else
178
- data = response;
179
192
  // invalidate
180
193
  cacheKeyOp(keys, entry => (entry[0] = 0));
181
194
  // set cache
@@ -1,3 +1,2 @@
1
1
  export { action, useSubmissions, useAction, type Action } from "./action.js";
2
2
  export { query, revalidate, type CachedFunction } from "./query.js";
3
- export { redirect, reload, json } from "./response.js";
@@ -1,3 +1,2 @@
1
1
  export { action, useSubmissions, useAction } from "./action.js";
2
2
  export { query, revalidate } from "./query.js";
3
- export { redirect, reload, json } from "./response.js";
@@ -1,5 +1,6 @@
1
1
  import { createSignal, getObserver, getOwner, onCleanup, sharedConfig } from "solid-js";
2
- import { getRequestEvent, isServer } from "@solidjs/web";
2
+ import { getRequestEvent, isResponseEnvelope, isServer } from "@solidjs/web";
3
+ import { decodeResponse } from "@solidjs/web/server-functions";
3
4
  import { useNavigate, getIntent, getInPreloadFn } from "../routing.js";
4
5
  const LocationHeader = "Location";
5
6
  const PRELOAD_TIMEOUT = 5000;
@@ -143,6 +144,14 @@ export function query(fn, name) {
143
144
  return res;
144
145
  function handleResponse(error) {
145
146
  return async (v) => {
147
+ let enveloped;
148
+ let hasEnveloped = false;
149
+ if (isResponseEnvelope(v)) {
150
+ // respond(): the value rides in memory beside the metadata
151
+ enveloped = v.value;
152
+ hasEnveloped = true;
153
+ v = v.response;
154
+ }
146
155
  if (v instanceof Response) {
147
156
  const e = getRequestEvent();
148
157
  if (e) {
@@ -164,8 +173,15 @@ export function query(fn, name) {
164
173
  e.response.status = 302;
165
174
  return;
166
175
  }
167
- if (v.customBody)
168
- v = await v.customBody();
176
+ if (hasEnveloped)
177
+ v = enveloped;
178
+ else if (v.body) {
179
+ // responses the transport hands over whole (revalidation) carry a
180
+ // codec-encoded body; anything else (a raw user Response) stays whole
181
+ const decoded = await decodeResponse(v);
182
+ if (decoded !== undefined)
183
+ v = decoded;
184
+ }
169
185
  }
170
186
  if (error)
171
187
  throw v;
package/dist/index.d.ts CHANGED
@@ -4,4 +4,4 @@ export * from "./lifecycle.js";
4
4
  export { useHref, useIsRouting, useLocation, useMatch, useCurrentMatches, useNavigate, useParams, useResolvedPath, useSearchParams, useBeforeLeave, usePreloadRoute, RouterContextObj as RouterContext } from "./routing.js";
5
5
  export { mergeSearchString as _mergeSearchString } from "./utils.js";
6
6
  export * from "./data/index.js";
7
- export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, Submission, BeforeLeaveEventArgs, RouterResponseInit, CustomResponse } from "./types.js";
7
+ export type { Location, LocationChange, SearchParams, MatchFilter, MatchFilters, NavigateOptions, Navigator, OutputMatch, Params, PathMatch, RouteSectionProps, RoutePreloadFunc, RoutePreloadFuncArgs, RouteDefinition, RouteDescription, RouteMatch, RouterIntegration, RouterUtils, SetParams, Submission, BeforeLeaveEventArgs } from "./types.js";
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { isServer, getRequestEvent, createComponent as createComponent$1, memo, delegateEvents, spread, mergeProps, template } from '@solidjs/web';
1
+ import { isServer, getRequestEvent, createComponent as createComponent$1, memo, isResponseEnvelope, delegateEvents, spread, mergeProps, template } from '@solidjs/web';
2
2
  import { getOwner, runWithOwner, createMemo, createContext, onCleanup, useContext, untrack, createSignal, flush, createComponent, children, merge, createRoot, sharedConfig, getObserver, $TRACK, action as action$1, omit } from 'solid-js';
3
+ import { decodeResponse } from '@solidjs/web/server-functions';
3
4
 
4
5
  function createBeforeLeave() {
5
6
  let listeners = new Set();
@@ -1250,6 +1251,14 @@ function query(fn, name) {
1250
1251
  return res;
1251
1252
  function handleResponse(error) {
1252
1253
  return async v => {
1254
+ let enveloped;
1255
+ let hasEnveloped = false;
1256
+ if (isResponseEnvelope(v)) {
1257
+ // respond(): the value rides in memory beside the metadata
1258
+ enveloped = v.value;
1259
+ hasEnveloped = true;
1260
+ v = v.response;
1261
+ }
1253
1262
  if (v instanceof Response) {
1254
1263
  const e = getRequestEvent();
1255
1264
  if (e) {
@@ -1265,7 +1274,12 @@ function query(fn, name) {
1265
1274
  });else if (!isServer) window.location.href = url;else if (e) e.response.status = 302;
1266
1275
  return;
1267
1276
  }
1268
- if (v.customBody) v = await v.customBody();
1277
+ if (hasEnveloped) v = enveloped;else if (v.body) {
1278
+ // responses the transport hands over whole (revalidation) carry a
1279
+ // codec-encoded body; anything else (a raw user Response) stays whole
1280
+ const decoded = await decodeResponse(v);
1281
+ if (decoded !== undefined) v = decoded;
1282
+ }
1269
1283
  }
1270
1284
  if (error) throw v;
1271
1285
  cached[2] = v;
@@ -1471,27 +1485,38 @@ async function handleResponse(response, error, navigate) {
1471
1485
  let custom;
1472
1486
  let keys;
1473
1487
  let flightKeys;
1474
- if (response instanceof Response) {
1475
- if (response.headers.has("X-Revalidate")) keys = response.headers.get("X-Revalidate").split(",");
1476
- if (response.customBody) {
1477
- data = custom = await response.customBody();
1488
+ let metadata;
1489
+ if (isResponseEnvelope(response)) {
1490
+ // client-only respond(): the value rides in memory beside the metadata
1491
+ data = response.value;
1492
+ metadata = response.response;
1493
+ } else if (response instanceof Response) {
1494
+ metadata = response;
1495
+ // responses the transport hands over whole (redirects, revalidation,
1496
+ // single-flight) carry a codec-encoded body the router decodes itself
1497
+ if (response.body) {
1498
+ data = await decodeResponse(response);
1478
1499
  if (response.headers.has("X-Single-Flight")) {
1479
- data = data._$value;
1500
+ custom = data;
1501
+ data = custom._$value;
1480
1502
  delete custom._$value;
1481
1503
  flightKeys = Object.keys(custom);
1482
1504
  }
1483
1505
  }
1484
- if (response.headers.has("Location")) {
1485
- const locationUrl = response.headers.get("Location") || "/";
1506
+ } else if (error) return {
1507
+ error: response
1508
+ };else data = response;
1509
+ if (metadata) {
1510
+ if (metadata.headers.has("X-Revalidate")) keys = metadata.headers.get("X-Revalidate").split(",");
1511
+ if (metadata.headers.has("Location")) {
1512
+ const locationUrl = metadata.headers.get("Location") || "/";
1486
1513
  if (locationUrl.startsWith("http")) {
1487
1514
  window.location.href = locationUrl;
1488
1515
  } else {
1489
1516
  navigate(locationUrl);
1490
1517
  }
1491
1518
  }
1492
- } else if (error) return {
1493
- error: response
1494
- };else data = response;
1519
+ }
1495
1520
  // invalidate
1496
1521
  cacheKeyOp(keys, entry => entry[0] = 0);
1497
1522
  // set cache
@@ -1840,57 +1865,4 @@ function Navigate(props) {
1840
1865
  return null;
1841
1866
  }
1842
1867
 
1843
- function redirect(url, init = 302) {
1844
- let responseInit;
1845
- let revalidate;
1846
- if (typeof init === "number") {
1847
- responseInit = {
1848
- status: init
1849
- };
1850
- } else {
1851
- ({
1852
- revalidate,
1853
- ...responseInit
1854
- } = init);
1855
- if (typeof responseInit.status === "undefined") {
1856
- responseInit.status = 302;
1857
- }
1858
- }
1859
- const headers = new Headers(responseInit.headers);
1860
- headers.set("Location", url);
1861
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
1862
- const response = new Response(null, {
1863
- ...responseInit,
1864
- headers: headers
1865
- });
1866
- return response;
1867
- }
1868
- function reload(init = {}) {
1869
- const {
1870
- revalidate,
1871
- ...responseInit
1872
- } = init;
1873
- const headers = new Headers(responseInit.headers);
1874
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
1875
- return new Response(null, {
1876
- ...responseInit,
1877
- headers
1878
- });
1879
- }
1880
- function json(data, init = {}) {
1881
- const {
1882
- revalidate,
1883
- ...responseInit
1884
- } = init;
1885
- const headers = new Headers(responseInit.headers);
1886
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
1887
- headers.set("Content-Type", "application/json");
1888
- const response = new Response(JSON.stringify(data), {
1889
- ...responseInit,
1890
- headers
1891
- });
1892
- response.customBody = () => data;
1893
- return response;
1894
- }
1895
-
1896
- export { A, HashRouter, MemoryRouter, Navigate, Route, Router, RouterContextObj as RouterContext, StaticRouter, mergeSearchString as _mergeSearchString, action, createBeforeLeave, createMemoryHistory, createRouter, json, keepDepth, notifyIfNotBlocked, query, redirect, reload, revalidate, saveCurrentDepth, useAction, useBeforeLeave, useCurrentMatches, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, usePreloadRoute, useResolvedPath, useSearchParams, useSubmissions };
1868
+ export { A, HashRouter, MemoryRouter, Navigate, Route, Router, RouterContextObj as RouterContext, StaticRouter, mergeSearchString as _mergeSearchString, action, createBeforeLeave, createMemoryHistory, createRouter, keepDepth, notifyIfNotBlocked, query, revalidate, saveCurrentDepth, useAction, useBeforeLeave, useCurrentMatches, useHref, useIsRouting, useLocation, useMatch, useNavigate, useParams, usePreloadRoute, useResolvedPath, useSearchParams, useSubmissions };
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Component, Signal } from "solid-js";
2
- import type { JSX } from "@solidjs/web";
2
+ import type { JSX, ResponseEnvelope } from "@solidjs/web";
3
3
  declare module "@solidjs/web" {
4
4
  interface RequestEvent {
5
5
  response: {
@@ -181,11 +181,4 @@ export interface MaybePreloadableComponent extends Component {
181
181
  export type CacheEntry = [number, Promise<any>, any, Intent | undefined, Signal<number> & {
182
182
  count: number;
183
183
  }];
184
- export type NarrowResponse<T> = T extends CustomResponse<infer U> ? U : Exclude<T, Response>;
185
- export type RouterResponseInit = Omit<ResponseInit, "body"> & {
186
- revalidate?: string | string[];
187
- };
188
- export type CustomResponse<T> = Omit<Response, "clone"> & {
189
- customBody: () => T;
190
- clone(...args: readonly unknown[]): CustomResponse<T>;
191
- };
184
+ export type NarrowResponse<T> = T extends ResponseEnvelope<infer U> ? U : Exclude<T, Response>;
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "Ryan Turnquist"
7
7
  ],
8
8
  "license": "MIT",
9
- "version": "0.17.0-next.4",
9
+ "version": "0.17.0-next.5",
10
10
  "homepage": "https://github.com/solidjs/solid-router#readme",
11
11
  "repository": {
12
12
  "type": "git",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "devDependencies": {
32
- "@solidjs/web": "2.0.0-beta.18",
32
+ "@solidjs/web": "2.0.0-beta.19",
33
33
  "@babel/core": "^7.26.0",
34
34
  "@babel/preset-typescript": "^7.26.0",
35
35
  "@changesets/cli": "^2.27.10",
@@ -38,19 +38,19 @@
38
38
  "@rollup/plugin-terser": "0.4.4",
39
39
  "@types/jest": "^29.5.14",
40
40
  "@types/node": "^22.10.0",
41
- "babel-preset-solid": "2.0.0-beta.18",
41
+ "babel-preset-solid": "2.0.0-beta.19",
42
42
  "jsdom": "^25.0.1",
43
43
  "prettier": "^3.4.1",
44
44
  "rollup": "^4.27.4",
45
- "solid-js": "2.0.0-beta.18",
45
+ "solid-js": "2.0.0-beta.19",
46
46
  "typescript": "^5.7.2",
47
47
  "vite": "^6.0.0",
48
48
  "vite-plugin-solid": "3.0.0-next.10",
49
49
  "vitest": "^2.1.6"
50
50
  },
51
51
  "peerDependencies": {
52
- "@solidjs/web": ">=2.0.0-beta.18 <2.0.0-experimental.0",
53
- "solid-js": ">=2.0.0-beta.18 <2.0.0-experimental.0"
52
+ "@solidjs/web": ">=2.0.0-beta.19 <2.0.0-experimental.0",
53
+ "solid-js": ">=2.0.0-beta.19 <2.0.0-experimental.0"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "rm -rf dist && tsc && rollup -c",
@@ -1,4 +0,0 @@
1
- import type { RouterResponseInit, CustomResponse } from "../types.js";
2
- export declare function redirect(url: string, init?: number | RouterResponseInit): CustomResponse<never>;
3
- export declare function reload(init?: RouterResponseInit): CustomResponse<never>;
4
- export declare function json<T>(data: T, init?: RouterResponseInit): CustomResponse<T>;
@@ -1,42 +0,0 @@
1
- export function redirect(url, init = 302) {
2
- let responseInit;
3
- let revalidate;
4
- if (typeof init === "number") {
5
- responseInit = { status: init };
6
- }
7
- else {
8
- ({ revalidate, ...responseInit } = init);
9
- if (typeof responseInit.status === "undefined") {
10
- responseInit.status = 302;
11
- }
12
- }
13
- const headers = new Headers(responseInit.headers);
14
- headers.set("Location", url);
15
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
16
- const response = new Response(null, {
17
- ...responseInit,
18
- headers: headers
19
- });
20
- return response;
21
- }
22
- export function reload(init = {}) {
23
- const { revalidate, ...responseInit } = init;
24
- const headers = new Headers(responseInit.headers);
25
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
26
- return new Response(null, {
27
- ...responseInit,
28
- headers
29
- });
30
- }
31
- export function json(data, init = {}) {
32
- const { revalidate, ...responseInit } = init;
33
- const headers = new Headers(responseInit.headers);
34
- revalidate !== undefined && headers.set("X-Revalidate", revalidate.toString());
35
- headers.set("Content-Type", "application/json");
36
- const response = new Response(JSON.stringify(data), {
37
- ...responseInit,
38
- headers
39
- });
40
- response.customBody = () => data;
41
- return response;
42
- }