@solidjs/start 2.0.0-rc.1 → 2.0.0-rc.10
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 +123 -0
- package/dist/config/app-root-alias.d.ts +7 -0
- package/dist/config/app-root-alias.js +58 -0
- package/dist/config/constants.d.ts +2 -0
- package/dist/config/constants.js +2 -0
- package/dist/config/env.js +2 -2
- package/dist/config/fs-routes/index.js +3 -3
- package/dist/config/fs-routes/tree-shake.d.ts +27 -0
- package/dist/config/fs-routes/tree-shake.js +51 -1
- package/dist/config/index.d.ts +154 -5
- package/dist/config/index.js +16 -8
- package/dist/config/lazy.js +7 -2
- package/dist/config/manifest.d.ts +3 -0
- package/dist/config/manifest.js +26 -4
- package/dist/directives/remove-unused-variables.js +15 -3
- package/dist/directives/xxhash32.js +5 -13
- package/dist/fns/client.js +14 -5
- package/dist/fns/error-handler.d.ts +34 -0
- package/dist/fns/error-handler.js +10 -0
- package/dist/fns/handler.d.ts +1 -1
- package/dist/fns/handler.js +45 -10
- package/dist/fns/plugins.d.ts +34 -0
- package/dist/fns/plugins.js +33 -0
- package/dist/fns/serialization.d.ts +15 -0
- package/dist/fns/serialization.js +36 -6
- package/dist/server/assets/render.jsx +1 -1
- package/dist/server/collect-styles.d.ts +3 -1
- package/dist/server/collect-styles.js +8 -5
- package/dist/server/handler.d.ts +3 -4
- package/dist/server/handler.js +16 -46
- package/dist/server/index.d.ts +2 -1
- package/dist/server/manifest/dev-client-manifest.js +1 -1
- package/dist/server/manifest/dev-ssr-manifest.js +1 -1
- package/dist/server/spa/StartServer.jsx +1 -1
- package/dist/server/spa/handler.d.ts +2 -3
- package/dist/server/spa/handler.js +2 -2
- package/dist/server/types.d.ts +12 -1
- package/dist/server/web-stream.d.ts +1 -1
- package/dist/server/web-stream.js +5 -2
- package/dist/shared/ErrorBoundary.jsx +3 -3
- package/dist/shared/clientOnly.js +3 -1
- package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/CodeView.jsx +3 -3
- package/dist/shared/{dev-overlay/DevOverlayDialog.d.ts → dev-toolbar/error-viewer/index.d.ts} +3 -2
- package/dist/shared/{dev-overlay/DevOverlayDialog.jsx → dev-toolbar/error-viewer/index.jsx} +66 -77
- package/dist/shared/dev-toolbar/error-viewer/styles.css +224 -0
- package/dist/shared/dev-toolbar/functions/BlobViewer.css +4 -0
- package/dist/shared/dev-toolbar/functions/BlobViewer.d.ts +6 -0
- package/dist/shared/dev-toolbar/functions/BlobViewer.jsx +37 -0
- package/dist/shared/dev-toolbar/functions/FormDataViewer.d.ts +5 -0
- package/dist/shared/dev-toolbar/functions/FormDataViewer.jsx +23 -0
- package/dist/shared/dev-toolbar/functions/HeadersViewer.css +8 -0
- package/dist/shared/dev-toolbar/functions/HeadersViewer.d.ts +6 -0
- package/dist/shared/dev-toolbar/functions/HeadersViewer.jsx +15 -0
- package/dist/shared/dev-toolbar/functions/HexViewer.css +34 -0
- package/dist/shared/dev-toolbar/functions/HexViewer.d.ts +11 -0
- package/dist/shared/dev-toolbar/functions/HexViewer.jsx +70 -0
- package/dist/shared/dev-toolbar/functions/SerovalValue.css +5 -0
- package/dist/shared/dev-toolbar/functions/SerovalValue.d.ts +7 -0
- package/dist/shared/dev-toolbar/functions/SerovalValue.jsx +10 -0
- package/dist/shared/dev-toolbar/functions/SerovalViewer.css +70 -0
- package/dist/shared/dev-toolbar/functions/SerovalViewer.d.ts +6 -0
- package/dist/shared/dev-toolbar/functions/SerovalViewer.jsx +796 -0
- package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.d.ts +5 -0
- package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.jsx +22 -0
- package/dist/shared/dev-toolbar/functions/index.d.ts +13 -0
- package/dist/shared/dev-toolbar/functions/index.jsx +216 -0
- package/dist/shared/dev-toolbar/functions/styles.css +109 -0
- package/dist/shared/dev-toolbar/functions/tracker.d.ts +19 -0
- package/dist/shared/dev-toolbar/functions/tracker.js +29 -0
- package/dist/shared/{dev-overlay → dev-toolbar}/icons.d.ts +9 -0
- package/dist/shared/{dev-overlay → dev-toolbar}/icons.jsx +19 -1
- package/dist/shared/dev-toolbar/index.css +88 -0
- package/dist/shared/dev-toolbar/index.d.ts +6 -0
- package/dist/shared/dev-toolbar/index.jsx +179 -0
- package/dist/shared/ui/Badge.css +33 -0
- package/dist/shared/ui/Badge.d.ts +7 -0
- package/dist/shared/ui/Badge.jsx +7 -0
- package/dist/shared/ui/Button.css +32 -0
- package/dist/shared/ui/Button.d.ts +4 -0
- package/dist/shared/ui/Button.jsx +4 -0
- package/dist/shared/ui/Cascade.css +29 -0
- package/dist/shared/ui/Cascade.d.ts +4 -0
- package/dist/shared/ui/Cascade.jsx +4 -0
- package/dist/shared/ui/Dialog.css +25 -0
- package/dist/shared/ui/Dialog.d.ts +5 -0
- package/dist/shared/ui/Dialog.jsx +5 -0
- package/dist/shared/ui/IconButton.css +39 -0
- package/dist/shared/ui/IconButton.d.ts +4 -0
- package/dist/shared/ui/IconButton.jsx +4 -0
- package/dist/shared/ui/Placeholder.css +12 -0
- package/dist/shared/ui/Placeholder.d.ts +6 -0
- package/dist/shared/ui/Placeholder.jsx +4 -0
- package/dist/shared/ui/Section.css +18 -0
- package/dist/shared/ui/Section.d.ts +9 -0
- package/dist/shared/ui/Section.jsx +10 -0
- package/dist/shared/ui/Select.css +37 -0
- package/dist/shared/ui/Select.d.ts +4 -0
- package/dist/shared/ui/Select.jsx +4 -0
- package/dist/shared/ui/Table.css +22 -0
- package/dist/shared/ui/Table.d.ts +11 -0
- package/dist/shared/ui/Table.jsx +13 -0
- package/dist/shared/ui/Tabs.css +51 -0
- package/dist/shared/ui/Tabs.d.ts +6 -0
- package/dist/shared/ui/Tabs.jsx +6 -0
- package/dist/shared/ui/Text.css +73 -0
- package/dist/shared/ui/Text.d.ts +12 -0
- package/dist/shared/ui/Text.jsx +17 -0
- package/package.json +36 -29
- package/dist/shared/dev-overlay/index.d.ts +0 -5
- package/dist/shared/dev-overlay/index.jsx +0 -39
- package/dist/shared/dev-overlay/styles.css +0 -292
- /package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/CodeView.d.ts +0 -0
- /package/dist/shared/{dev-overlay/createStackFrame.d.ts → dev-toolbar/error-viewer/create-stack-frame.d.ts} +0 -0
- /package/dist/shared/{dev-overlay/createStackFrame.js → dev-toolbar/error-viewer/create-stack-frame.js} +0 -0
- /package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/download.d.ts +0 -0
- /package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/download.js +0 -0
- /package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/get-source-map.d.ts +0 -0
- /package/dist/shared/{dev-overlay → dev-toolbar/error-viewer}/get-source-map.js +0 -0
package/dist/server/handler.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import middleware from "solid-start:middleware";
|
|
2
|
-
import { defineHandler, getCookie, H3, redirect, setCookie } from "h3/generic";
|
|
2
|
+
import { defineHandler, getCookie, H3, iterable, redirect, setCookie, } from "h3/generic";
|
|
3
3
|
import { sharedConfig } from "solid-js";
|
|
4
4
|
import { getRequestEvent, renderToStream, renderToString } from "solid-js/web";
|
|
5
5
|
import { createRoutes } from "../router.jsx";
|
|
@@ -11,7 +11,7 @@ import { getExpectedRedirectStatus } from "./util.js";
|
|
|
11
11
|
import { toWebReadableStream } from "./web-stream.js";
|
|
12
12
|
import { stripPathBase } from "./strip-path-base.js";
|
|
13
13
|
const SERVER_FN_BASE = "/_server";
|
|
14
|
-
export function createBaseHandler(createPageEvent, fn, options = {}) {
|
|
14
|
+
export function createBaseHandler(createPageEvent, fn, options = {}, routerLoad) {
|
|
15
15
|
const handler = defineHandler({
|
|
16
16
|
middleware: middleware.length ? middleware.map(decorateMiddleware) : undefined,
|
|
17
17
|
handler: decorateHandler(async (e) => {
|
|
@@ -19,12 +19,7 @@ export function createBaseHandler(createPageEvent, fn, options = {}) {
|
|
|
19
19
|
const url = new URL(event.request.url);
|
|
20
20
|
const pathname = stripBaseUrl(url.pathname);
|
|
21
21
|
if (pathname.startsWith(SERVER_FN_BASE)) {
|
|
22
|
-
|
|
23
|
-
if (serverFnResponse instanceof Response)
|
|
24
|
-
return produceResponseWithEventHeaders(serverFnResponse);
|
|
25
|
-
return new Response(serverFnResponse, {
|
|
26
|
-
headers: e.res.headers,
|
|
27
|
-
});
|
|
22
|
+
return await handleServerFunction(e);
|
|
28
23
|
}
|
|
29
24
|
const match = matchAPIRoute(pathname, event.request.method);
|
|
30
25
|
if (match) {
|
|
@@ -36,8 +31,6 @@ export function createBaseHandler(createPageEvent, fn, options = {}) {
|
|
|
36
31
|
sharedConfig.context = { event };
|
|
37
32
|
const res = await fn(event);
|
|
38
33
|
if (res !== undefined) {
|
|
39
|
-
if (res instanceof Response)
|
|
40
|
-
return produceResponseWithEventHeaders(res);
|
|
41
34
|
return res;
|
|
42
35
|
}
|
|
43
36
|
if (event.request.method !== "GET") {
|
|
@@ -47,6 +40,8 @@ export function createBaseHandler(createPageEvent, fn, options = {}) {
|
|
|
47
40
|
return;
|
|
48
41
|
}
|
|
49
42
|
}
|
|
43
|
+
if (routerLoad)
|
|
44
|
+
await routerLoad(event);
|
|
50
45
|
const context = await createPageEvent(event);
|
|
51
46
|
const resolvedOptions = typeof options === "function" ? await options(context) : { ...options };
|
|
52
47
|
const mode = resolvedOptions.mode || "stream";
|
|
@@ -94,18 +89,17 @@ export function createBaseHandler(createPageEvent, fn, options = {}) {
|
|
|
94
89
|
}
|
|
95
90
|
if (mode === "async")
|
|
96
91
|
return await stream;
|
|
97
|
-
delete stream.then;
|
|
98
92
|
// h3 expects a standard web ReadableStream across runtimes. The adapter
|
|
99
93
|
// also tolerates cancellation while Solid finishes outstanding work.
|
|
100
|
-
return toWebReadableStream(stream);
|
|
94
|
+
return iterable(toWebReadableStream(stream));
|
|
101
95
|
}),
|
|
102
96
|
});
|
|
103
97
|
const app = new H3();
|
|
104
98
|
app.use(handler);
|
|
105
99
|
return app;
|
|
106
100
|
}
|
|
107
|
-
export function createHandler(fn, options = {}) {
|
|
108
|
-
return createBaseHandler(createPageEvent, fn, options);
|
|
101
|
+
export function createHandler(fn, options = {}, routerLoad) {
|
|
102
|
+
return createBaseHandler(createPageEvent, fn, options, routerLoad);
|
|
109
103
|
}
|
|
110
104
|
export async function createPageEvent(ctx) {
|
|
111
105
|
ctx.response.headers.set("Content-Type", "text/html");
|
|
@@ -177,40 +171,16 @@ function handleStreamCompleteRedirect(context) {
|
|
|
177
171
|
return ({ write }) => {
|
|
178
172
|
context.complete = true;
|
|
179
173
|
const to = context.response && context.response.headers.get("Location");
|
|
180
|
-
|
|
174
|
+
if (!to)
|
|
175
|
+
return;
|
|
176
|
+
// The shell has already flushed, so the redirect has to happen client side.
|
|
177
|
+
// Carry the nonce so a strict `script-src` CSP doesn't block it.
|
|
178
|
+
const nonce = context.nonce ? ` nonce="${escapeAttribute(context.nonce)}"` : "";
|
|
179
|
+
write(`<script${nonce}>window.location=${JSON.stringify(to).replace(/</g, "\\u003c")}</script>`);
|
|
181
180
|
};
|
|
182
181
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
let ret = res;
|
|
186
|
-
// Response.redirect returns an immutable value, so we clone on any redirect just in case
|
|
187
|
-
if (300 <= res.status && res.status < 400) {
|
|
188
|
-
const cookies = res.headers.getSetCookie?.() ?? [];
|
|
189
|
-
const headers = new Headers();
|
|
190
|
-
res.headers.forEach((value, key) => {
|
|
191
|
-
if (key.toLowerCase() !== "set-cookie") {
|
|
192
|
-
headers.set(key, value);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
for (const cookie of cookies) {
|
|
196
|
-
headers.append("Set-Cookie", cookie);
|
|
197
|
-
}
|
|
198
|
-
ret = new Response(res.body, {
|
|
199
|
-
status: res.status,
|
|
200
|
-
statusText: res.statusText,
|
|
201
|
-
headers,
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
const eventCookies = event.response.headers.getSetCookie?.() ?? [];
|
|
205
|
-
for (const cookie of eventCookies) {
|
|
206
|
-
ret.headers.append("Set-Cookie", cookie);
|
|
207
|
-
}
|
|
208
|
-
for (const [name, value] of event.response.headers) {
|
|
209
|
-
if (name.toLowerCase() !== "set-cookie") {
|
|
210
|
-
ret.headers.set(name, value);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return ret;
|
|
182
|
+
function escapeAttribute(value) {
|
|
183
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
214
184
|
}
|
|
215
185
|
function stripBaseUrl(path) {
|
|
216
186
|
const base = import.meta.env.SERVER_BASE_URL || import.meta.env.BASE_URL || "/";
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export { getServerFunctionMeta } from "../shared/serverFunction.ts";
|
|
|
3
3
|
export { StartServer } from "./StartServer.tsx";
|
|
4
4
|
export { decorateHandler, decorateMiddleware } from "./fetchEvent.ts";
|
|
5
5
|
export { createHandler } from "./handler.ts";
|
|
6
|
-
export type {
|
|
6
|
+
export type { ServerFunctionErrorHandler } from "../fns/error-handler.ts";
|
|
7
|
+
export type { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta, StartHandler, } from "./types.ts";
|
|
7
8
|
/**
|
|
8
9
|
* Checks if user has set a redirect status in the response.
|
|
9
10
|
* If not, falls back to the 302 (temporary redirect)
|
|
@@ -13,7 +13,7 @@ export function getClientDevManifest() {
|
|
|
13
13
|
return import(__rewriteRelativeImportExtension(/* @vite-ignore */ join("/", id), true));
|
|
14
14
|
},
|
|
15
15
|
async getAssets(id) {
|
|
16
|
-
const assetsPath = `/@manifest/client/${Date.now()}/assets?id=${id}`;
|
|
16
|
+
const assetsPath = `/@manifest/client/${Date.now()}/assets?id=${encodeURIComponent(id)}`;
|
|
17
17
|
const assets = (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ assetsPath, true))).default;
|
|
18
18
|
return await Promise.all(assets.map(async (v) => ({
|
|
19
19
|
...v,
|
|
@@ -11,7 +11,7 @@ export function getSsrDevManifest(environment) {
|
|
|
11
11
|
return {
|
|
12
12
|
path: (id) => normalize(join(import.meta.env.BASE_URL, id)),
|
|
13
13
|
async getAssets(id) {
|
|
14
|
-
const assetsPath = `/@manifest/${environment}/${Date.now()}/assets?id=${id}`;
|
|
14
|
+
const assetsPath = `/@manifest/${environment}/${Date.now()}/assets?id=${encodeURIComponent(id)}`;
|
|
15
15
|
const assets = (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ assetsPath, true))).default;
|
|
16
16
|
return await Promise.all(assets.map(async (v) => ({
|
|
17
17
|
...v,
|
|
@@ -18,7 +18,7 @@ export function StartServer(props) {
|
|
|
18
18
|
<TopErrorBoundary>
|
|
19
19
|
<props.document scripts={<>
|
|
20
20
|
<PatchVirtualDevStyles nonce={nonce}/>
|
|
21
|
-
<script type="module" src={getSsrManifest("client").path(import.meta.env.START_CLIENT_ENTRY_URL)}/>
|
|
21
|
+
<script type="module" nonce={nonce} src={getSsrManifest("client").path(import.meta.env.START_CLIENT_ENTRY_URL)}/>
|
|
22
22
|
</>}/>
|
|
23
23
|
</TopErrorBoundary>
|
|
24
24
|
</NoHydration>);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { H3 } from "h3/generic";
|
|
2
1
|
import type { JSX } from "solid-js";
|
|
3
|
-
import type { HandlerOptions, PageEvent } from "../types.ts";
|
|
2
|
+
import type { FetchEvent, HandlerOptions, PageEvent, StartHandler } from "../types.ts";
|
|
4
3
|
/**
|
|
5
4
|
*
|
|
6
5
|
* Read more: https://docs.solidjs.com/solid-start/reference/server/create-handler
|
|
7
6
|
*/
|
|
8
|
-
export declare function createHandler(fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions)):
|
|
7
|
+
export declare function createHandler(fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions), routerLoad?: (event: FetchEvent) => Promise<void>): StartHandler;
|
|
@@ -4,8 +4,8 @@ import { getSsrManifest } from "../manifest/ssr-manifest.js";
|
|
|
4
4
|
*
|
|
5
5
|
* Read more: https://docs.solidjs.com/solid-start/reference/server/create-handler
|
|
6
6
|
*/
|
|
7
|
-
export function createHandler(fn, options) {
|
|
8
|
-
return createBaseHandler(createPageEvent, fn, options);
|
|
7
|
+
export function createHandler(fn, options, routerLoad) {
|
|
8
|
+
return createBaseHandler(createPageEvent, fn, options, routerLoad);
|
|
9
9
|
}
|
|
10
10
|
async function createPageEvent(ctx) {
|
|
11
11
|
const manifest = getSsrManifest("ssr");
|
package/dist/server/types.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import type { H3Event } from "h3";
|
|
1
|
+
import type { H3, H3Event } from "h3";
|
|
2
2
|
import type { JSX } from "solid-js";
|
|
3
3
|
import type { RequestEvent } from "solid-js/web";
|
|
4
|
+
/**
|
|
5
|
+
* The h3 app instance returned by `createHandler`.
|
|
6
|
+
*
|
|
7
|
+
* Structurally identical to h3's `H3`, but declared here so that `export default
|
|
8
|
+
* createHandler(...)` in `entry-server.tsx` can be named through `@solidjs/start`.
|
|
9
|
+
* Referring to `H3` directly makes TypeScript emit a reference to h3's internal
|
|
10
|
+
* `H3$1` class, which is not portable when h3 is nested inside
|
|
11
|
+
* `node_modules/@solidjs/start/node_modules` (TS2742 / TS2883).
|
|
12
|
+
*/
|
|
13
|
+
export interface StartHandler extends H3 {
|
|
14
|
+
}
|
|
4
15
|
export type DocumentComponentProps = {
|
|
5
16
|
assets?: JSX.Element;
|
|
6
17
|
scripts: JSX.Element;
|
|
@@ -5,5 +5,5 @@ type PipeableStream = {
|
|
|
5
5
|
}): void;
|
|
6
6
|
};
|
|
7
7
|
/** Convert Solid's streaming SSR result into a cancellation-safe web stream. */
|
|
8
|
-
export declare function toWebReadableStream(stream: PipeableStream): ReadableStream<Uint8Array
|
|
8
|
+
export declare function toWebReadableStream(stream: PipeableStream): ReadableStream<Uint8Array<ArrayBufferLike>>;
|
|
9
9
|
export {};
|
|
@@ -6,8 +6,11 @@ export function toWebReadableStream(stream) {
|
|
|
6
6
|
start(controller) {
|
|
7
7
|
stream.pipe({
|
|
8
8
|
write(payload) {
|
|
9
|
-
if (active)
|
|
10
|
-
|
|
9
|
+
if (!active)
|
|
10
|
+
return;
|
|
11
|
+
// Encoding string to Uint8Array makes sure that
|
|
12
|
+
// the stream can be consumed as Response body
|
|
13
|
+
controller.enqueue(encoder.encode(payload));
|
|
11
14
|
},
|
|
12
15
|
end() {
|
|
13
16
|
if (!active)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @refresh skip
|
|
2
|
-
import { ErrorBoundary as DefaultErrorBoundary
|
|
2
|
+
import { catchError, ErrorBoundary as DefaultErrorBoundary } from "solid-js";
|
|
3
3
|
import { isServer } from "solid-js/web";
|
|
4
|
+
import { DevToolbar } from "./dev-toolbar/index.jsx";
|
|
4
5
|
import { HttpStatusCode } from "./HttpStatusCode.js";
|
|
5
|
-
import { DevOverlay } from "./dev-overlay/index.jsx";
|
|
6
6
|
export const ErrorBoundary = import.meta.env.DEV && import.meta.env.START_DEV_OVERLAY
|
|
7
|
-
? (props) => <
|
|
7
|
+
? (props) => <DevToolbar>{props.children}</DevToolbar>
|
|
8
8
|
: (props) => {
|
|
9
9
|
const message = isServer
|
|
10
10
|
? "500 | Internal Server Error"
|
|
@@ -19,7 +19,9 @@ export default function clientOnly(fn, options = {}) {
|
|
|
19
19
|
return Comp(rest);
|
|
20
20
|
const [mounted, setMounted] = createSignal(!sharedConfig.context);
|
|
21
21
|
onMount(() => setMounted(true));
|
|
22
|
-
return createMemo(() => ((Comp = comp()),
|
|
22
|
+
return createMemo(() => ((Comp = comp()),
|
|
23
|
+
(m = mounted()),
|
|
24
|
+
untrack(() => (Comp && m ? Comp(rest) : props.fallback))));
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
function load(fn, setComp) {
|
|
@@ -51,12 +51,12 @@ export function CodeView(props) {
|
|
|
51
51
|
for (let i = 0, len = lines.length; i < len; i++) {
|
|
52
52
|
const el = lines[i];
|
|
53
53
|
if (props.line - minLine() - 1 === i) {
|
|
54
|
-
el.dataset.
|
|
54
|
+
el.dataset.startErrorViewerErrorLine = "";
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
|
-
return (<div ref={ref} data-start-
|
|
60
|
-
"--
|
|
59
|
+
return (<div ref={ref} data-start-error-viewer-code-view style={{
|
|
60
|
+
"--error-viewer-code-view-start": minLine() + 1,
|
|
61
61
|
}}/>);
|
|
62
62
|
}
|
package/dist/shared/{dev-overlay/DevOverlayDialog.d.ts → dev-toolbar/error-viewer/index.d.ts}
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
2
|
import "./styles.css";
|
|
3
3
|
export declare function classNames(...classes: (string | boolean | undefined)[]): string;
|
|
4
|
-
interface
|
|
4
|
+
interface ErrorViewerProps {
|
|
5
|
+
show?: boolean;
|
|
5
6
|
errors: any[];
|
|
6
7
|
resetError: () => void;
|
|
7
8
|
}
|
|
8
|
-
export default function
|
|
9
|
+
export default function ErrorViewer(props: ErrorViewerProps): JSX.Element;
|
|
9
10
|
export {};
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
import ErrorStackParser from "error-stack-parser";
|
|
3
3
|
import * as htmlToImage from "html-to-image";
|
|
4
4
|
import { createMemo, createSignal, ErrorBoundary, For, Show, Suspense } from "solid-js";
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import info from "../../../package.json" with { type: "json" };
|
|
5
|
+
import IconButton from "../../ui/IconButton.jsx";
|
|
6
|
+
import { Select, SelectOption } from "../../ui/Select.jsx";
|
|
7
|
+
import { ArrowLeftIcon, ArrowRightIcon, CameraIcon, DiscordIcon, GithubIcon, RefreshIcon, ViewCompiledIcon, ViewOriginalIcon, } from "../icons.jsx";
|
|
9
8
|
import { CodeView } from "./CodeView.jsx";
|
|
10
|
-
import { createStackFrame } from "./
|
|
9
|
+
import { createStackFrame } from "./create-stack-frame.js";
|
|
11
10
|
import download from "./download.js";
|
|
12
|
-
import { ArrowLeftIcon, ArrowRightIcon, CameraIcon, DiscordIcon, GithubIcon, RefreshIcon, SolidStartIcon, ViewCompiledIcon, ViewOriginalIcon, } from "./icons.jsx";
|
|
13
11
|
import "./styles.css";
|
|
14
12
|
export function classNames(...classes) {
|
|
15
13
|
return classes.filter(Boolean).join(" ");
|
|
@@ -25,9 +23,9 @@ function ErrorInfo(props) {
|
|
|
25
23
|
}
|
|
26
24
|
return { message: e.toString() };
|
|
27
25
|
});
|
|
28
|
-
return (<span data-start-
|
|
29
|
-
<span data-start-
|
|
30
|
-
<span data-start-
|
|
26
|
+
return (<span data-start-error-viewer-error-info>
|
|
27
|
+
<span data-start-error-viewer-error-info-name>{error().name}</span>
|
|
28
|
+
<span data-start-error-viewer-error-info-message>{error().message}</span>
|
|
31
29
|
</span>);
|
|
32
30
|
}
|
|
33
31
|
function getFileName(source) {
|
|
@@ -46,23 +44,23 @@ function getFilePath(source) {
|
|
|
46
44
|
return `${getFileName(source.source)}${line}${column}`;
|
|
47
45
|
}
|
|
48
46
|
function CodeFallback() {
|
|
49
|
-
return (<div data-start-
|
|
47
|
+
return (<div data-start-error-viewer-stack-frames-code-fallback>
|
|
50
48
|
<span>Source not available.</span>
|
|
51
49
|
</div>);
|
|
52
50
|
}
|
|
53
51
|
function StackFramesContent(props) {
|
|
54
52
|
const stackframes = ErrorStackParser.parse(props.error);
|
|
55
53
|
const [selectedFrame, setSelectedFrame] = createSignal(stackframes[0]);
|
|
56
|
-
return (<div data-start-
|
|
57
|
-
<div data-start-
|
|
54
|
+
return (<div data-start-error-viewer-stack-frames-content>
|
|
55
|
+
<div data-start-error-viewer-stack-frames-code>
|
|
58
56
|
<ErrorBoundary fallback={null}>
|
|
59
57
|
{(() => {
|
|
60
58
|
const data = createStackFrame(selectedFrame(), () => props.isCompiled);
|
|
61
59
|
return (<Suspense fallback={<CodeFallback />}>
|
|
62
60
|
<Show when={data()} keyed fallback={<CodeFallback />}>
|
|
63
61
|
{source => (<>
|
|
64
|
-
<span data-start-
|
|
65
|
-
<div data-start-
|
|
62
|
+
<span data-start-error-viewer-stack-frames-code-source>{source.source}</span>
|
|
63
|
+
<div data-start-error-viewer-stack-frames-code-container>
|
|
66
64
|
<CodeView fileName={source.source} line={source.line} content={source.content}/>
|
|
67
65
|
</div>
|
|
68
66
|
</>)}
|
|
@@ -71,13 +69,13 @@ function StackFramesContent(props) {
|
|
|
71
69
|
})()}
|
|
72
70
|
</ErrorBoundary>
|
|
73
71
|
</div>
|
|
74
|
-
<Select data-start-
|
|
72
|
+
<Select data-start-error-viewer-stack-frames value={selectedFrame()} onChange={setSelectedFrame}>
|
|
75
73
|
<For each={stackframes}>
|
|
76
|
-
{current => (<ErrorBoundary fallback={<
|
|
77
|
-
<span data-start-
|
|
74
|
+
{current => (<ErrorBoundary fallback={<SelectOption value={current} disabled data-start-error-viewer-stack-frame>
|
|
75
|
+
<span data-start-error-viewer-stack-frame-function>
|
|
78
76
|
{current.functionName ?? "<anonymous>"}
|
|
79
77
|
</span>
|
|
80
|
-
<span data-start-
|
|
78
|
+
<span data-start-error-viewer-stack-frame-file>
|
|
81
79
|
{getFilePath({
|
|
82
80
|
source: current.getFileName(),
|
|
83
81
|
content: "",
|
|
@@ -86,16 +84,18 @@ function StackFramesContent(props) {
|
|
|
86
84
|
name: current.getFunctionName(),
|
|
87
85
|
})}
|
|
88
86
|
</span>
|
|
89
|
-
</
|
|
87
|
+
</SelectOption>}>
|
|
90
88
|
{(() => {
|
|
91
89
|
const data = createStackFrame(current, () => props.isCompiled);
|
|
92
90
|
return (<Suspense>
|
|
93
91
|
<Show when={data()} keyed>
|
|
94
|
-
{source => (<SelectOption data-start-
|
|
95
|
-
<span data-start-
|
|
92
|
+
{source => (<SelectOption data-start-error-viewer-stack-frame value={current}>
|
|
93
|
+
<span data-start-error-viewer-stack-frame-function>
|
|
96
94
|
{source.name ?? "<anonymous>"}
|
|
97
95
|
</span>
|
|
98
|
-
<span data-start-
|
|
96
|
+
<span data-start-error-viewer-stack-frame-file>
|
|
97
|
+
{getFilePath(source)}
|
|
98
|
+
</span>
|
|
99
99
|
</SelectOption>)}
|
|
100
100
|
</Show>
|
|
101
101
|
</Suspense>);
|
|
@@ -112,7 +112,7 @@ function StackFrames(props) {
|
|
|
112
112
|
}
|
|
113
113
|
const ISSUE_THREAD = "https://github.com/solidjs/solid-start/issues/new";
|
|
114
114
|
const DISCORD_INVITE = "https://discord.com/invite/solidjs";
|
|
115
|
-
export default function
|
|
115
|
+
export default function ErrorViewer(props) {
|
|
116
116
|
const [currentPage, setCurrentPage] = createSignal(1);
|
|
117
117
|
const [isCompiled, setIsCompiled] = createSignal(false);
|
|
118
118
|
const length = createMemo(() => props.errors.length);
|
|
@@ -164,63 +164,52 @@ export default function DevOverlayDialog(props) {
|
|
|
164
164
|
function redirectToDiscord() {
|
|
165
165
|
window.open(DISCORD_INVITE, "_blank").focus();
|
|
166
166
|
}
|
|
167
|
-
return (<
|
|
168
|
-
<
|
|
169
|
-
<div>
|
|
170
|
-
<
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
<span>{info.version}</span>
|
|
167
|
+
return (<Show when={props.show}>
|
|
168
|
+
<div data-start-dev-toolbar-panel>
|
|
169
|
+
<div ref={setPanel} data-start-error-viewer>
|
|
170
|
+
<div data-start-error-viewer-navbar>
|
|
171
|
+
<div data-start-error-viewer-navbar-left>
|
|
172
|
+
<Show when={props.errors.length > 1}>
|
|
173
|
+
<div data-start-error-viewer-pagination>
|
|
174
|
+
<IconButton data-start-error-viewer-button onClick={goPrev} type="button">
|
|
175
|
+
<ArrowLeftIcon title="Go Previous"/>
|
|
176
|
+
</IconButton>
|
|
177
|
+
<div data-start-error-viewer-page-counter>
|
|
178
|
+
{`${truncated()} of ${props.errors.length}`}
|
|
180
179
|
</div>
|
|
181
|
-
<
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
<ArrowLeftIcon title="Go Previous"/>
|
|
185
|
-
</button>
|
|
186
|
-
<div data-start-dev-overlay-page-counter>
|
|
187
|
-
{`${truncated()} of ${props.errors.length}`}
|
|
188
|
-
</div>
|
|
189
|
-
<button data-start-dev-overlay-button onClick={goNext} type="button">
|
|
190
|
-
<ArrowRightIcon title="Go Next"/>
|
|
191
|
-
</button>
|
|
192
|
-
</div>
|
|
193
|
-
</Show>
|
|
194
|
-
</div>
|
|
195
|
-
<div data-start-dev-overlay-controls>
|
|
196
|
-
<button data-start-dev-overlay-button onClick={redirectToGithub} type="button">
|
|
197
|
-
<GithubIcon title="Create an issue thread on Github"/>
|
|
198
|
-
</button>
|
|
199
|
-
<button data-start-dev-overlay-button onClick={redirectToDiscord} type="button">
|
|
200
|
-
<DiscordIcon title="Join our Discord Channel"/>
|
|
201
|
-
</button>
|
|
202
|
-
<button data-start-dev-overlay-button onClick={downloadScreenshot} type="button">
|
|
203
|
-
<CameraIcon title="Capture Error Overlay"/>
|
|
204
|
-
</button>
|
|
205
|
-
<button data-start-dev-overlay-button onClick={toggleIsCompiled} type="button">
|
|
206
|
-
<Show when={isCompiled()} fallback={<ViewOriginalIcon title="View Original Source"/>}>
|
|
207
|
-
<ViewCompiledIcon title="View Compiled Source"/>
|
|
208
|
-
</Show>
|
|
209
|
-
</button>
|
|
210
|
-
<button data-start-dev-overlay-button onClick={props.resetError} type="button">
|
|
211
|
-
<RefreshIcon title="Reset Error"/>
|
|
212
|
-
</button>
|
|
180
|
+
<IconButton data-start-error-viewer-button onClick={goNext} type="button">
|
|
181
|
+
<ArrowRightIcon title="Go Next"/>
|
|
182
|
+
</IconButton>
|
|
213
183
|
</div>
|
|
214
|
-
</div>
|
|
215
|
-
<Show when={props.errors[truncated() - 1]} keyed>
|
|
216
|
-
{current => (<div data-start-dev-overlay-content>
|
|
217
|
-
<ErrorInfo error={current}/>
|
|
218
|
-
<StackFrames error={current} isCompiled={isCompiled()}/>
|
|
219
|
-
</div>)}
|
|
220
184
|
</Show>
|
|
221
185
|
</div>
|
|
222
|
-
|
|
186
|
+
<div data-start-error-viewer-controls>
|
|
187
|
+
<IconButton data-start-error-viewer-button onClick={redirectToGithub} type="button">
|
|
188
|
+
<GithubIcon title="Create an issue thread on Github"/>
|
|
189
|
+
</IconButton>
|
|
190
|
+
<IconButton data-start-error-viewer-button onClick={redirectToDiscord} type="button">
|
|
191
|
+
<DiscordIcon title="Join our Discord Channel"/>
|
|
192
|
+
</IconButton>
|
|
193
|
+
<IconButton data-start-error-viewer-button onClick={downloadScreenshot} type="button">
|
|
194
|
+
<CameraIcon title="Capture Error Overlay"/>
|
|
195
|
+
</IconButton>
|
|
196
|
+
<IconButton data-start-error-viewer-button onClick={toggleIsCompiled} type="button">
|
|
197
|
+
<Show when={isCompiled()} fallback={<ViewOriginalIcon title="View Original Source"/>}>
|
|
198
|
+
<ViewCompiledIcon title="View Compiled Source"/>
|
|
199
|
+
</Show>
|
|
200
|
+
</IconButton>
|
|
201
|
+
<IconButton data-start-error-viewer-button onClick={props.resetError} type="button">
|
|
202
|
+
<RefreshIcon title="Reset Error"/>
|
|
203
|
+
</IconButton>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
<Show when={props.errors[truncated() - 1]} keyed>
|
|
207
|
+
{current => (<div data-start-error-viewer-content>
|
|
208
|
+
<ErrorInfo error={current}/>
|
|
209
|
+
<StackFrames error={current} isCompiled={isCompiled()}/>
|
|
210
|
+
</div>)}
|
|
211
|
+
</Show>
|
|
223
212
|
</div>
|
|
224
|
-
</
|
|
225
|
-
</
|
|
213
|
+
</div>
|
|
214
|
+
</Show>);
|
|
226
215
|
}
|