@solidjs/start 0.7.1 → 0.7.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.
Files changed (115) hide show
  1. package/config/index.js +4 -4
  2. package/config/server-components.js +1 -1
  3. package/dist/client/StartClient.d.ts +3 -0
  4. package/{client/StartClient.tsx → dist/client/StartClient.jsx} +4 -9
  5. package/{client/index.tsx → dist/client/index.d.ts} +0 -1
  6. package/dist/client/index.jsx +4 -0
  7. package/dist/client/islands.d.ts +3 -0
  8. package/{client/islands.ts → dist/client/islands.jsx} +1 -1
  9. package/dist/client/mount.d.ts +3 -0
  10. package/dist/client/mount.js +85 -0
  11. package/dist/client/spa/index.d.ts +5 -0
  12. package/dist/client/spa/index.jsx +6 -0
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.jsx +5 -0
  15. package/dist/middleware/index.d.ts +18 -0
  16. package/dist/middleware/index.js +40 -0
  17. package/dist/router/FileRoutes.d.ts +2 -0
  18. package/dist/router/FileRoutes.js +25 -0
  19. package/dist/router/index.jsx +2 -0
  20. package/dist/router/lazyRoute.d.ts +6 -0
  21. package/dist/router/lazyRoute.js +48 -0
  22. package/dist/router/routes.d.ts +25 -0
  23. package/dist/router/routes.js +51 -0
  24. package/dist/runtime/server-fns-runtime.d.ts +1 -0
  25. package/dist/runtime/server-fns-runtime.js +30 -0
  26. package/dist/runtime/server-handler.d.ts +2 -0
  27. package/dist/runtime/server-handler.js +242 -0
  28. package/dist/runtime/server-runtime.d.ts +3 -0
  29. package/dist/runtime/server-runtime.js +185 -0
  30. package/dist/server/StartServer.d.ts +5 -0
  31. package/dist/server/StartServer.jsx +78 -0
  32. package/dist/server/fetchEvent.d.ts +6 -0
  33. package/dist/server/fetchEvent.js +88 -0
  34. package/dist/server/handler.d.ts +3 -0
  35. package/dist/server/handler.js +98 -0
  36. package/dist/server/index.jsx +5 -0
  37. package/dist/server/islands/index.d.ts +19 -0
  38. package/dist/server/islands/index.jsx +62 -0
  39. package/dist/server/islands/utils.d.ts +1 -0
  40. package/dist/server/islands/utils.jsx +85 -0
  41. package/dist/server/pageEvent.d.ts +2 -0
  42. package/dist/server/pageEvent.js +43 -0
  43. package/dist/server/renderAsset.d.ts +2 -0
  44. package/dist/server/renderAsset.jsx +13 -0
  45. package/dist/server/serverFunction.d.ts +2 -0
  46. package/dist/server/serverFunction.jsx +4 -0
  47. package/dist/server/spa/StartServer.d.ts +5 -0
  48. package/dist/server/spa/StartServer.jsx +18 -0
  49. package/dist/server/spa/handler.d.ts +3 -0
  50. package/dist/server/spa/handler.js +17 -0
  51. package/{server/spa/index.tsx → dist/server/spa/index.d.ts} +0 -1
  52. package/dist/server/spa/index.jsx +4 -0
  53. package/dist/server/types.d.ts +79 -0
  54. package/dist/server/types.js +1 -0
  55. package/dist/shared/ErrorBoundary.d.ts +2 -0
  56. package/dist/shared/ErrorBoundary.jsx +16 -0
  57. package/dist/shared/GET.d.ts +1 -0
  58. package/dist/shared/GET.js +5 -0
  59. package/dist/shared/HttpHeader.d.ts +6 -0
  60. package/dist/shared/HttpHeader.jsx +32 -0
  61. package/dist/shared/HttpStatusCode.d.ts +5 -0
  62. package/dist/shared/HttpStatusCode.jsx +12 -0
  63. package/dist/shared/clientOnly.d.ts +6 -0
  64. package/dist/shared/clientOnly.jsx +19 -0
  65. package/dist/shared/dev-overlay/CodeView.d.ts +7 -0
  66. package/dist/shared/dev-overlay/CodeView.jsx +71 -0
  67. package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +9 -0
  68. package/dist/shared/dev-overlay/DevOverlayDialog.jsx +209 -0
  69. package/dist/shared/dev-overlay/createStackFrame.d.ts +9 -0
  70. package/dist/shared/dev-overlay/createStackFrame.js +56 -0
  71. package/dist/shared/dev-overlay/download.d.ts +1 -0
  72. package/dist/shared/dev-overlay/download.js +6 -0
  73. package/dist/shared/dev-overlay/get-source-map.d.ts +2 -0
  74. package/dist/shared/dev-overlay/get-source-map.js +25 -0
  75. package/dist/shared/dev-overlay/icons.d.ts +28 -0
  76. package/{shared/dev-overlay/icons.tsx → dist/shared/dev-overlay/icons.jsx} +35 -173
  77. package/dist/shared/dev-overlay/index.d.ts +5 -0
  78. package/dist/shared/dev-overlay/index.jsx +42 -0
  79. package/package.json +22 -23
  80. package/client/mount.ts +0 -99
  81. package/client/spa/index.tsx +0 -10
  82. package/config/server-fns-runtime.ts +0 -28
  83. package/config/server-handler.ts +0 -261
  84. package/config/server-runtime.ts +0 -229
  85. package/middleware/index.ts +0 -70
  86. package/router/FileRoutes.ts +0 -35
  87. package/router/lazyRoute.ts +0 -55
  88. package/router/routes.ts +0 -87
  89. package/server/StartServer.tsx +0 -126
  90. package/server/fetchEvent.ts +0 -113
  91. package/server/handler.ts +0 -112
  92. package/server/islands/index.tsx +0 -103
  93. package/server/islands/utils.tsx +0 -89
  94. package/server/pageEvent.ts +0 -50
  95. package/server/renderAsset.tsx +0 -23
  96. package/server/serverFunction.tsx +0 -6
  97. package/server/spa/StartServer.tsx +0 -52
  98. package/server/spa/handler.ts +0 -24
  99. package/server/types.ts +0 -81
  100. package/shared/ErrorBoundary.tsx +0 -23
  101. package/shared/GET.ts +0 -5
  102. package/shared/HttpHeader.tsx +0 -35
  103. package/shared/HttpStatusCode.tsx +0 -19
  104. package/shared/clientOnly.tsx +0 -29
  105. package/shared/dev-overlay/CodeView.tsx +0 -95
  106. package/shared/dev-overlay/DevOverlayDialog.tsx +0 -280
  107. package/shared/dev-overlay/createStackFrame.ts +0 -77
  108. package/shared/dev-overlay/download.ts +0 -6
  109. package/shared/dev-overlay/env.d.ts +0 -4
  110. package/shared/dev-overlay/get-source-map.ts +0 -35
  111. package/shared/dev-overlay/index.tsx +0 -61
  112. package/shared/index.ts +0 -5
  113. /package/{router/index.ts → dist/router/index.d.ts} +0 -0
  114. /package/{server/index.tsx → dist/server/index.d.ts} +0 -0
  115. /package/{shared → dist/shared}/dev-overlay/styles.css +0 -0
@@ -1,229 +0,0 @@
1
- import { deserialize, toJSONAsync } from "seroval";
2
- import {
3
- CustomEventPlugin,
4
- DOMExceptionPlugin,
5
- EventPlugin,
6
- FormDataPlugin,
7
- HeadersPlugin,
8
- ReadableStreamPlugin,
9
- RequestPlugin,
10
- ResponsePlugin,
11
- URLPlugin,
12
- URLSearchParamsPlugin
13
- } from "seroval-plugins/web";
14
- import { type Component } from "solid-js";
15
- import { createIslandReference } from "../server/islands";
16
-
17
- class SerovalChunkReader {
18
- reader: ReadableStreamDefaultReader<Uint8Array>;
19
- buffer: string;
20
- done: boolean;
21
- constructor(stream: ReadableStream<Uint8Array>) {
22
- this.reader = stream.getReader();
23
- this.buffer = "";
24
- this.done = false;
25
- }
26
-
27
- async readChunk() {
28
- // if there's no chunk, read again
29
- const chunk = await this.reader.read();
30
- if (!chunk.done) {
31
- // repopulate the buffer
32
- this.buffer += new TextDecoder().decode(chunk.value);
33
- } else {
34
- this.done = true;
35
- }
36
- }
37
-
38
- async next(): Promise<any> {
39
- // Check if the buffer is empty
40
- if (this.buffer === "") {
41
- // if we are already done...
42
- if (this.done) {
43
- return {
44
- done: true,
45
- value: undefined
46
- };
47
- }
48
- // Otherwise, read a new chunk
49
- await this.readChunk();
50
- return await this.next();
51
- }
52
- // Read the "byte header"
53
- // The byte header tells us how big the expected data is
54
- // so we know how much data we should wait before we
55
- // deserialize the data
56
- const bytes = Number.parseInt(this.buffer.substring(1, 11), 16); // ;0x00000000;
57
- // Check if the buffer has enough bytes to be parsed
58
- while (bytes > this.buffer.length - 12) {
59
- // If it's not enough, and the reader is done
60
- // then the chunk is invalid.
61
- if (this.done) {
62
- throw new Error("Malformed server function stream.");
63
- }
64
- // Otherwise, we read more chunks
65
- await this.readChunk();
66
- }
67
- // Extract the exact chunk as defined by the byte header
68
- const partial = this.buffer.substring(12, 12 + bytes);
69
- // The rest goes to the buffer
70
- this.buffer = this.buffer.substring(12 + bytes);
71
- // Deserialize the chunk
72
- return {
73
- done: false,
74
- value: deserialize(partial)
75
- };
76
- }
77
-
78
- async drain() {
79
- while (true) {
80
- const result = await this.next();
81
- if (result.done) {
82
- break;
83
- }
84
- }
85
- }
86
- }
87
-
88
- async function deserializeStream(id: string, response: Response) {
89
- if (!response.body) {
90
- throw new Error("missing body");
91
- }
92
- const reader = new SerovalChunkReader(response.body);
93
-
94
- const result = await reader.next();
95
-
96
- if (!result.done) {
97
- reader.drain().then(
98
- () => {
99
- // @ts-ignore
100
- delete $R[id];
101
- },
102
- () => {
103
- // no-op
104
- }
105
- );
106
- }
107
-
108
- return result.value;
109
- }
110
-
111
- let INSTANCE = 0;
112
-
113
- function createRequest(base: string, id: string, instance: string, options: RequestInit) {
114
- return fetch(base, {
115
- method: "POST",
116
- ...options,
117
- headers: {
118
- ...options.headers,
119
- "X-Server-Id": id,
120
- "X-Server-Instance": instance
121
- }
122
- });
123
- }
124
-
125
- async function fetchServerFunction(
126
- base: string,
127
- id: string,
128
- options: Omit<RequestInit, "body">,
129
- args: any[]
130
- ) {
131
- const instance = `server-fn:${INSTANCE++}`;
132
- const response = await (args.length === 0
133
- ? createRequest(base, id, instance, options)
134
- : args.length === 1 && args[0] instanceof FormData
135
- ? createRequest(base, id, instance, { ...options, body: args[0] })
136
- : createRequest(base, id, instance, {
137
- ...options,
138
- body: JSON.stringify(
139
- await Promise.resolve(
140
- toJSONAsync(args, {
141
- plugins: [
142
- CustomEventPlugin,
143
- DOMExceptionPlugin,
144
- EventPlugin,
145
- FormDataPlugin,
146
- HeadersPlugin,
147
- ReadableStreamPlugin,
148
- RequestPlugin,
149
- ResponsePlugin,
150
- URLSearchParamsPlugin,
151
- URLPlugin
152
- ]
153
- })
154
- )
155
- ),
156
- headers: { ...options.headers, "Content-Type": "application/json" }
157
- }));
158
-
159
- if (
160
- response.headers.get("Location") ||
161
- response.headers.get("X-Revalidate") ||
162
- response.headers.get("X-Single-Flight")
163
- ) {
164
- if (response.body) {
165
- /* @ts-ignore-next-line */
166
- response.customBody = () => {
167
- return deserializeStream(instance, response);
168
- };
169
- }
170
- return response;
171
- }
172
-
173
- const contentType = response.headers.get("Content-Type");
174
- let result;
175
- if (contentType && contentType.startsWith("text/plain")) {
176
- result = await response.text();
177
- } else if (contentType && contentType.startsWith("application/json")) {
178
- result = await response.json();
179
- } else {
180
- result = await deserializeStream(instance, response);
181
- }
182
- if (response.headers.has("X-Error")) {
183
- throw result;
184
- }
185
- return result;
186
- }
187
-
188
- export function createServerReference(fn: Function, id: string, name: string) {
189
- const baseURL = import.meta.env.SERVER_BASE_URL;
190
- return new Proxy(fn, {
191
- get(target, prop, receiver) {
192
- if (prop === "url") {
193
- return `${baseURL}/_server?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`;
194
- }
195
- if (prop === "GET") {
196
- return receiver.withOptions({ method: "GET" });
197
- }
198
- if (prop === "withOptions") {
199
- const url = `${baseURL}/_server/?id=${encodeURIComponent(id)}&name=${encodeURIComponent(name)}`
200
- return (options: RequestInit) => {
201
- const fn = (...args: any[]) => {
202
- const encodeArgs = options.method && options.method.toUpperCase() === "GET";
203
- return fetchServerFunction(
204
- encodeArgs
205
- ? url + (args.length ? `&args=${JSON.stringify(args)}` : "")
206
- : `${baseURL}/_server`,
207
- `${id}#${name}`,
208
- options,
209
- encodeArgs ? [] : args
210
- );
211
- };
212
- fn.url = url;
213
- return fn;
214
- };
215
- }
216
- },
217
- apply(target, thisArg, args) {
218
- return fetchServerFunction(`${baseURL}/_server`, `${id}#${name}`, {}, args);
219
- }
220
- });
221
- }
222
-
223
- export function createClientReference(Component: Component<any>, id: string, name: string) {
224
- if (typeof Component === "function") {
225
- return createIslandReference(Component, id, name);
226
- }
227
-
228
- return Component;
229
- }
@@ -1,70 +0,0 @@
1
- import {
2
- HTTPEvent,
3
- defineMiddleware,
4
- sendWebResponse
5
- } from "vinxi/http";
6
- import { getFetchEvent } from "../server/fetchEvent";
7
- import type { FetchEvent } from "../server/types";
8
-
9
- /** Function responsible for receiving an observable [operation]{@link Operation} and returning a [result]{@link OperationResult}. */
10
-
11
- export type MiddlewareFn = (event: FetchEvent) => Promise<unknown> | unknown;
12
- /** This composes an array of Exchanges into a single ExchangeIO function */
13
-
14
- export type RequestMiddleware = (event: FetchEvent) => Response | Promise<Response> | void | Promise<void>;
15
-
16
- // copy-pasted from h3/dist/index.d.ts
17
- type EventHandlerResponse<T = any> = T | Promise<T>;
18
- type ResponseMiddlewareResponseParam = { body?: Awaited<EventHandlerResponse> };
19
-
20
- export type ResponseMiddleware = (
21
- event: FetchEvent,
22
- response: ResponseMiddlewareResponseParam
23
- ) => Response | Promise<Response> | void | Promise<void>;
24
-
25
- function wrapRequestMiddleware(onRequest: RequestMiddleware) {
26
- return async (h3Event: HTTPEvent) => {
27
- const fetchEvent = getFetchEvent(h3Event);
28
- const response = await onRequest(fetchEvent);
29
- if (!response) {
30
- return;
31
- } else {
32
- sendWebResponse(h3Event, response);
33
- }
34
- };
35
- }
36
-
37
- function wrapResponseMiddleware(onBeforeResponse: ResponseMiddleware) {
38
- return async (h3Event: HTTPEvent, response: ResponseMiddlewareResponseParam) => {
39
- const fetchEvent = getFetchEvent(h3Event);
40
- const mwResponse = await onBeforeResponse(fetchEvent, response);
41
- if (!mwResponse) {
42
- return;
43
- } else {
44
- sendWebResponse(h3Event, mwResponse);
45
- }
46
- };
47
- }
48
-
49
- export function createMiddleware({
50
- onRequest,
51
- onBeforeResponse
52
- }: {
53
- onRequest?: RequestMiddleware | RequestMiddleware[] | undefined;
54
- onBeforeResponse?: ResponseMiddleware | ResponseMiddleware[] | undefined;
55
- }) {
56
- return defineMiddleware({
57
- onRequest:
58
- typeof onRequest === "function"
59
- ? wrapRequestMiddleware(onRequest)
60
- : Array.isArray(onRequest)
61
- ? onRequest.map(wrapRequestMiddleware)
62
- : undefined,
63
- onBeforeResponse:
64
- typeof onBeforeResponse === "function"
65
- ? wrapResponseMiddleware(onBeforeResponse)
66
- : Array.isArray(onBeforeResponse)
67
- ? onBeforeResponse.map(wrapResponseMiddleware)
68
- : undefined
69
- });
70
- }
@@ -1,35 +0,0 @@
1
- /* @refresh skip */
2
- import { getRequestEvent, isServer } from "solid-js/web";
3
- import lazyRoute from "./lazyRoute";
4
-
5
- import type { Route } from "vinxi/fs-router";
6
- import type { PageEvent } from "../server/types";
7
- import { pageRoutes as routeConfigs } from "./routes";
8
-
9
- export function createRoutes() {
10
- function createRoute(route: Route) {
11
- return {
12
- ...route,
13
- ...(route.$$route ? route.$$route.require().route : undefined),
14
- info: {
15
- ...(route.$$route ? route.$$route.require().route.info : {}),
16
- filesystem: true
17
- },
18
- component: lazyRoute(
19
- route.$component,
20
- import.meta.env.START_ISLANDS
21
- ? import.meta.env.MANIFEST["ssr"]
22
- : import.meta.env.MANIFEST["client"],
23
- import.meta.env.MANIFEST["ssr"]
24
- ),
25
- children: route.children ? route.children.map(createRoute) : undefined
26
- };
27
- }
28
- const routes = routeConfigs.map(createRoute);
29
- return routes;
30
- }
31
-
32
- let routes: any[];
33
- export const FileRoutes = isServer
34
- ? () => (getRequestEvent() as PageEvent).routes
35
- : () => routes || (routes = createRoutes());
@@ -1,55 +0,0 @@
1
- /// <reference types="vinxi/types/client" />
2
- import { createComponent, lazy, onCleanup, type Component, type JSX } from "solid-js";
3
- import { appendStyles, cleanupStyles, preloadStyles, updateStyles } from "vinxi/css";
4
-
5
- import { renderAsset } from "../server/renderAsset";
6
- import { Asset } from "../server/types";
7
-
8
- export default function lazyRoute<T>(component: any, clientManifest: any, serverManifest: any, exported = "default") {
9
- return lazy(async () => {
10
- if (import.meta.env.DEV) {
11
- let manifest = import.meta.env.SSR ? serverManifest : clientManifest;
12
-
13
- const mod = await manifest.inputs[component.src].import();
14
- if (!mod[exported]) console.error(`Module ${component.src} does not export ${exported}`);
15
- const Component = mod[exported];
16
- let assets = await clientManifest.inputs?.[component.src].assets();
17
- const styles = assets.filter((asset: Asset) => asset.tag === "style");
18
-
19
- if (typeof window !== "undefined" && import.meta.hot) {
20
- import.meta.hot.on("css-update", data => {
21
- updateStyles(styles, data);
22
- });
23
- }
24
-
25
- const Comp: Component<T> = props => {
26
- if (typeof window !== "undefined") {
27
- appendStyles(styles);
28
- }
29
-
30
- onCleanup(() => {
31
- if (typeof window !== "undefined") {
32
- // remove style tags added by vite when a CSS file is imported
33
- cleanupStyles(styles);
34
- }
35
- });
36
- return [...assets.map((asset: Asset) => renderAsset(asset)), createComponent(Component, props)];
37
- };
38
- return { default: Comp };
39
- } else {
40
- const mod = await component.import();
41
- const Component = mod[exported];
42
- let assets = await clientManifest.inputs?.[component.src].assets();
43
- const styles = assets.filter(
44
- (asset: Asset) => asset.tag === "style" || (asset.attrs as JSX.LinkHTMLAttributes<HTMLLinkElement>).rel === "stylesheet"
45
- );
46
- if (typeof window !== "undefined") {
47
- preloadStyles(styles);
48
- }
49
- const Comp: Component<T> = props => {
50
- return [...styles.map((asset: Asset) => renderAsset(asset)), createComponent(Component, props)];
51
- };
52
- return { default: Comp };
53
- }
54
- });
55
- }
package/router/routes.ts DELETED
@@ -1,87 +0,0 @@
1
- import { createRouter } from "radix3";
2
- import fileRoutes from "vinxi/routes";
3
-
4
- interface Route {
5
- path: string;
6
- id: string;
7
- children?: Route[];
8
- $component?: any;
9
- $GET?: any;
10
- $POST?: any;
11
- $PUT?: any;
12
- $PATCH?: any;
13
- $DELETE?: any;
14
- }
15
-
16
- declare module "vinxi/routes" {
17
- export interface Register {
18
- route: {
19
- path: string;
20
- children?: Route[];
21
- };
22
- }
23
- }
24
-
25
- export const pageRoutes = defineRoutes(
26
- (fileRoutes as unknown as Route[]).filter(o => o.$component)
27
- );
28
-
29
- function defineRoutes(fileRoutes: Route[]) {
30
- function processRoute(routes: Route[], route: Route, id: string, full: string) {
31
- const parentRoute = Object.values(routes).find(o => {
32
- return id.startsWith(o.id + "/");
33
- });
34
-
35
- if (!parentRoute) {
36
- routes.push({ ...route, id, path: id.replace(/\/\([^)/]+\)/g, "").replace(/\./g, "/") });
37
- return routes;
38
- }
39
- processRoute(
40
- parentRoute.children || (parentRoute.children = []),
41
- route,
42
- id.slice(parentRoute.id.length),
43
- full
44
- );
45
-
46
- return routes;
47
- }
48
-
49
- return fileRoutes
50
- .sort((a, b) => a.path.length - b.path.length)
51
- .reduce((prevRoutes: Route[], route) => {
52
- return processRoute(prevRoutes, route, route.path, route.path);
53
- }, []);
54
- }
55
-
56
- export function matchAPIRoute(path: string, method: string) {
57
- const match = router.lookup(path);
58
- if (match) {
59
- const handler = match.route[`$${method}`];
60
- if (handler === undefined) return;
61
- return {
62
- handler,
63
- params: match.params
64
- };
65
- }
66
- }
67
-
68
- function containsHTTP(route: Route) {
69
- return route["$GET"] || route["$POST"] || route["$PUT"] || route["$PATCH"] || route["$DELETE"];
70
- }
71
-
72
- const router = createRouter({
73
- routes: (fileRoutes as unknown as Route[]).reduce((memo, route) => {
74
- if (!containsHTTP(route)) return memo;
75
- let path = route.path.replace(/\(.*\)\/?/g, "").replace(/\*([^/]*)/g, (_, m) => `**:${m}`);
76
- if (/:[^/]*\?/g.test(path)) {
77
- throw new Error(`Optional parameters are not supported in API routes: ${path}`);
78
- }
79
- if (memo[path]) {
80
- throw new Error(
81
- `Duplicate API routes for "${path}" found at "${memo[path]!.route.path}" and "${route.path}"`
82
- );
83
- }
84
- memo[path] = { route };
85
- return memo;
86
- }, {} as Record<string, { route: Route }>)
87
- });
@@ -1,126 +0,0 @@
1
- // @refresh skip
2
- // @ts-ignore
3
- import App from "#start/app";
4
- import type { Component, JSX } from "solid-js";
5
- import {
6
- Hydration,
7
- HydrationScript,
8
- NoHydration,
9
- getRequestEvent,
10
- ssr,
11
- useAssets
12
- } from "solid-js/web";
13
- import { ErrorBoundary } from "../shared/ErrorBoundary";
14
- import { renderAsset } from "./renderAsset";
15
- import type { Asset, DocumentComponentProps, PageEvent } from "./types";
16
-
17
- const docType = ssr("<!DOCTYPE html>");
18
-
19
- function matchRoute(matches: any[], routes: any[], matched = []): any[] | undefined {
20
- for (let i = 0; i < routes.length; i++) {
21
- const segment = routes[i];
22
- if (segment.path !== matches[0].path) continue;
23
- let next: any = [...matched, segment];
24
- if (segment.children) {
25
- const nextMatches = matches.slice(1);
26
- if (nextMatches.length === 0) continue;
27
- next = matchRoute(nextMatches, segment.children, next);
28
- if (!next) continue;
29
- }
30
- return next;
31
- }
32
- }
33
-
34
- export function StartServer(props: { document: Component<DocumentComponentProps> }) {
35
- const context = getRequestEvent() as PageEvent;
36
- // @ts-ignore
37
- const nonce = context.nonce;
38
-
39
- let assets: Asset[] = [];
40
- Promise.resolve().then(async () => {
41
- // @ts-ignore
42
- if (context.router && context.router.matches) {
43
- // @ts-ignore
44
- const matches = [...context.router.matches];
45
- while (matches.length && (!matches[0].info || !matches[0].info.filesystem)) matches.shift();
46
- const matched = matches.length && matchRoute(matches, context.routes);
47
- if (matched) {
48
- for (let i = 0; i < matched.length; i++) {
49
- const segment = matched[i];
50
- const part = import.meta.env.MANIFEST[import.meta.env.START_ISLANDS ? "ssr" : "client"]!
51
- .inputs[segment["$component"].src]!;
52
- const asset = (await part.assets()) as any;
53
- assets.push.apply(assets, asset);
54
- }
55
- } else console.warn("No route matched for preloading js assets");
56
- }
57
- // dedupe assets
58
- assets = [...new Map(assets.map(item => [item.attrs.key, item])).values()].filter(asset =>
59
- import.meta.env.START_ISLANDS
60
- ? false
61
- : (asset.attrs as JSX.LinkHTMLAttributes<HTMLLinkElement>).rel === "modulepreload" &&
62
- !context.assets.find((a: Asset) => a.attrs.key === asset.attrs.key)
63
- );
64
- });
65
-
66
- useAssets(() => (assets.length ? assets.map(m => renderAsset(m)) : undefined));
67
-
68
- return (
69
- <NoHydration>
70
- {docType as unknown as any}
71
- <props.document
72
- assets={
73
- <>
74
- <HydrationScript />
75
- {context.assets.map((m: any) => renderAsset(m))}
76
- </>
77
- }
78
- scripts={
79
- nonce ? (
80
- <>
81
- <script
82
- nonce={nonce}
83
- innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`}
84
- />
85
- <script
86
- type="module"
87
- nonce={nonce}
88
- async
89
- src={
90
- import.meta.env.MANIFEST["client"]!.inputs[
91
- import.meta.env.MANIFEST["client"]!.handler
92
- ]!.output.path
93
- }
94
- />
95
- </>
96
- ) : (
97
- <>
98
- <script innerHTML={`window.manifest = ${JSON.stringify(context.manifest)}`} />
99
- <script
100
- type="module"
101
- async
102
- src={
103
- import.meta.env.MANIFEST["client"]!.inputs[
104
- import.meta.env.MANIFEST["client"]!.handler
105
- ]!.output.path
106
- }
107
- />
108
- </>
109
- )
110
- }
111
- >
112
- {!import.meta.env.START_ISLANDS ? (
113
- <Hydration>
114
- <ErrorBoundary>
115
- <App />
116
- </ErrorBoundary>
117
- </Hydration>
118
- ) : (
119
- <ErrorBoundary>
120
- <App />
121
- </ErrorBoundary>
122
- )}
123
- </props.document>
124
- </NoHydration>
125
- );
126
- }