@solidjs/start 2.0.0-beta.1 → 2.0.0-beta.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 (231) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/client/StartClient.d.ts +7 -0
  3. package/{src/client/StartClient.tsx → dist/client/StartClient.jsx} +7 -15
  4. package/dist/client/index.jsx +2 -0
  5. package/dist/client/mount.d.ts +1 -0
  6. package/dist/client/mount.js +1 -0
  7. package/dist/client/spa/index.d.ts +4 -0
  8. package/dist/client/spa/index.jsx +5 -0
  9. package/dist/config/constants.d.ts +16 -0
  10. package/dist/config/constants.js +16 -0
  11. package/dist/config/dev-server.d.ts +2 -0
  12. package/dist/config/dev-server.js +128 -0
  13. package/dist/config/env.d.ts +19 -0
  14. package/dist/config/env.js +81 -0
  15. package/dist/config/fs-router.d.ts +37 -0
  16. package/dist/config/fs-router.js +141 -0
  17. package/dist/config/fs-routes/fs-watcher.d.ts +3 -0
  18. package/dist/config/fs-routes/fs-watcher.js +53 -0
  19. package/dist/config/fs-routes/index.d.ts +7 -0
  20. package/dist/config/fs-routes/index.js +107 -0
  21. package/dist/config/fs-routes/router.d.ts +42 -0
  22. package/dist/config/fs-routes/router.js +148 -0
  23. package/dist/config/fs-routes/tree-shake.d.ts +2 -0
  24. package/dist/config/fs-routes/tree-shake.js +305 -0
  25. package/dist/config/index.d.ts +25 -0
  26. package/dist/config/index.js +224 -0
  27. package/dist/config/lazy.d.ts +3 -0
  28. package/dist/config/lazy.js +114 -0
  29. package/dist/config/manifest.d.ts +3 -0
  30. package/dist/config/manifest.js +109 -0
  31. package/dist/config/utils.d.ts +4 -0
  32. package/dist/config/utils.js +6 -0
  33. package/dist/config/vite-utils.d.ts +21 -0
  34. package/dist/config/vite-utils.js +85 -0
  35. package/dist/directives/bubble-function-declaration.d.ts +3 -0
  36. package/dist/directives/bubble-function-declaration.js +23 -0
  37. package/dist/directives/compile.d.ts +9 -0
  38. package/dist/directives/compile.js +40 -0
  39. package/dist/directives/generate-unique-name.d.ts +3 -0
  40. package/dist/directives/generate-unique-name.js +16 -0
  41. package/dist/directives/get-descriptive-name.d.ts +2 -0
  42. package/dist/directives/get-descriptive-name.js +37 -0
  43. package/dist/directives/get-import-identifier.d.ts +4 -0
  44. package/dist/directives/get-import-identifier.js +19 -0
  45. package/dist/directives/get-root-statement-path.d.ts +2 -0
  46. package/dist/directives/get-root-statement-path.js +12 -0
  47. package/dist/directives/index.d.ts +14 -0
  48. package/dist/directives/index.js +170 -0
  49. package/dist/directives/is-statement-top-level.d.ts +3 -0
  50. package/dist/directives/is-statement-top-level.js +9 -0
  51. package/dist/directives/paths.d.ts +9 -0
  52. package/dist/directives/paths.js +36 -0
  53. package/dist/directives/plugin.d.ts +21 -0
  54. package/dist/directives/plugin.js +302 -0
  55. package/dist/directives/remove-unused-variables.d.ts +3 -0
  56. package/dist/directives/remove-unused-variables.js +66 -0
  57. package/{src/directives/types.ts → dist/directives/types.d.ts} +5 -7
  58. package/dist/directives/types.js +1 -0
  59. package/dist/directives/xxhash32.d.ts +6 -0
  60. package/dist/directives/xxhash32.js +193 -0
  61. package/dist/fns/client.d.ts +3 -0
  62. package/dist/fns/client.js +106 -0
  63. package/dist/fns/handler.d.ts +5 -0
  64. package/dist/fns/handler.js +269 -0
  65. package/dist/fns/registration.d.ts +2 -0
  66. package/dist/fns/registration.js +12 -0
  67. package/dist/fns/serialization.d.ts +6 -0
  68. package/dist/fns/serialization.js +208 -0
  69. package/dist/fns/server.d.ts +7 -0
  70. package/dist/fns/server.js +38 -0
  71. package/dist/fns/shared.d.ts +17 -0
  72. package/dist/fns/shared.js +105 -0
  73. package/dist/http/index.d.ts +81 -0
  74. package/dist/http/index.js +129 -0
  75. package/{src/index.tsx → dist/index.d.ts} +0 -2
  76. package/dist/index.jsx +6 -0
  77. package/dist/middleware/index.d.ts +38 -0
  78. package/dist/middleware/index.js +59 -0
  79. package/dist/router.d.ts +6 -0
  80. package/dist/router.jsx +29 -0
  81. package/dist/server/StartServer.d.ts +9 -0
  82. package/dist/server/StartServer.jsx +34 -0
  83. package/dist/server/assets/PatchVirtualDevStyles.d.ts +4 -0
  84. package/{src/server/assets/PatchVirtualDevStyles.tsx → dist/server/assets/PatchVirtualDevStyles.jsx} +7 -10
  85. package/dist/server/assets/index.d.ts +2 -0
  86. package/dist/server/assets/index.js +52 -0
  87. package/dist/server/assets/render.d.ts +19 -0
  88. package/dist/server/assets/render.jsx +14 -0
  89. package/dist/server/collect-styles.d.ts +3 -0
  90. package/dist/server/collect-styles.js +57 -0
  91. package/dist/server/fetchEvent.d.ts +7 -0
  92. package/dist/server/fetchEvent.js +26 -0
  93. package/dist/server/handler.d.ts +64 -0
  94. package/dist/server/handler.js +222 -0
  95. package/dist/server/index.d.ts +9 -0
  96. package/{src/server/index.tsx → dist/server/index.jsx} +4 -19
  97. package/dist/server/manifest/client-manifest.d.ts +9 -0
  98. package/dist/server/manifest/client-manifest.js +6 -0
  99. package/dist/server/manifest/dev-client-manifest.d.ts +4 -0
  100. package/dist/server/manifest/dev-client-manifest.js +24 -0
  101. package/dist/server/manifest/dev-ssr-manifest.d.ts +5 -0
  102. package/dist/server/manifest/dev-ssr-manifest.js +23 -0
  103. package/dist/server/manifest/prod-client-manifest.d.ts +5 -0
  104. package/dist/server/manifest/prod-client-manifest.js +26 -0
  105. package/dist/server/manifest/prod-ssr-manifest.d.ts +6 -0
  106. package/dist/server/manifest/prod-ssr-manifest.js +85 -0
  107. package/dist/server/manifest/ssr-manifest.d.ts +4 -0
  108. package/dist/server/manifest/ssr-manifest.js +6 -0
  109. package/dist/server/routes.d.ts +23 -0
  110. package/dist/server/routes.js +74 -0
  111. package/dist/server/spa/StartServer.d.ts +9 -0
  112. package/dist/server/spa/StartServer.jsx +25 -0
  113. package/dist/server/spa/handler.d.ts +36 -0
  114. package/dist/server/spa/handler.js +20 -0
  115. package/{src/server/spa/index.tsx → dist/server/spa/index.d.ts} +0 -1
  116. package/dist/server/spa/index.jsx +5 -0
  117. package/dist/server/types.d.ts +75 -0
  118. package/dist/server/types.js +1 -0
  119. package/dist/server/util.d.ts +2 -0
  120. package/dist/server/util.js +8 -0
  121. package/dist/shared/ErrorBoundary.d.ts +3 -0
  122. package/dist/shared/ErrorBoundary.jsx +36 -0
  123. package/dist/shared/GET.d.ts +5 -0
  124. package/dist/shared/GET.js +8 -0
  125. package/dist/shared/HttpHeader.d.ts +10 -0
  126. package/dist/shared/HttpHeader.jsx +38 -0
  127. package/dist/shared/HttpStatusCode.d.ts +9 -0
  128. package/dist/shared/HttpStatusCode.js +18 -0
  129. package/dist/shared/clientOnly.d.ts +12 -0
  130. package/dist/shared/clientOnly.js +27 -0
  131. package/dist/shared/dev-overlay/CodeView.d.ts +7 -0
  132. package/dist/shared/dev-overlay/CodeView.jsx +62 -0
  133. package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +9 -0
  134. package/dist/shared/dev-overlay/DevOverlayDialog.jsx +226 -0
  135. package/dist/shared/dev-overlay/createStackFrame.d.ts +9 -0
  136. package/dist/shared/dev-overlay/createStackFrame.js +56 -0
  137. package/dist/shared/dev-overlay/download.d.ts +1 -0
  138. package/dist/shared/dev-overlay/download.js +6 -0
  139. package/dist/shared/dev-overlay/get-source-map.d.ts +2 -0
  140. package/dist/shared/dev-overlay/get-source-map.js +25 -0
  141. package/dist/shared/dev-overlay/icons.d.ts +28 -0
  142. package/dist/shared/dev-overlay/icons.jsx +150 -0
  143. package/dist/shared/dev-overlay/index.d.ts +5 -0
  144. package/dist/shared/dev-overlay/index.jsx +39 -0
  145. package/dist/shared/lazy.d.ts +3 -0
  146. package/dist/shared/lazy.js +42 -0
  147. package/dist/shared/serverFunction.d.ts +6 -0
  148. package/dist/shared/serverFunction.js +8 -0
  149. package/dist/utils/debounce.d.ts +4 -0
  150. package/dist/utils/debounce.js +10 -0
  151. package/package.json +7 -2
  152. package/scripts/build.js +0 -15
  153. package/scripts/validate-imports.js +0 -316
  154. package/src/client/mount.ts +0 -1
  155. package/src/client/spa/index.tsx +0 -9
  156. package/src/config/constants.ts +0 -19
  157. package/src/config/dev-server.ts +0 -161
  158. package/src/config/env.ts +0 -105
  159. package/src/config/fs-router.ts +0 -162
  160. package/src/config/fs-routes/fs-watcher.ts +0 -66
  161. package/src/config/fs-routes/index.ts +0 -136
  162. package/src/config/fs-routes/router.ts +0 -184
  163. package/src/config/fs-routes/tree-shake.ts +0 -324
  164. package/src/config/index.ts +0 -239
  165. package/src/config/lazy.ts +0 -132
  166. package/src/config/manifest.ts +0 -120
  167. package/src/config/utils.ts +0 -5
  168. package/src/config/vite-utils.ts +0 -113
  169. package/src/directives/bubble-function-declaration.ts +0 -33
  170. package/src/directives/compile.ts +0 -54
  171. package/src/directives/generate-unique-name.ts +0 -22
  172. package/src/directives/get-descriptive-name.ts +0 -39
  173. package/src/directives/get-import-identifier.ts +0 -34
  174. package/src/directives/get-root-statement-path.ts +0 -14
  175. package/src/directives/index.ts +0 -233
  176. package/src/directives/is-statement-top-level.ts +0 -13
  177. package/src/directives/paths.ts +0 -63
  178. package/src/directives/plugin.ts +0 -389
  179. package/src/directives/remove-unused-variables.ts +0 -70
  180. package/src/directives/xxhash32.ts +0 -214
  181. package/src/env.d.ts +0 -17
  182. package/src/fns/client.ts +0 -141
  183. package/src/fns/handler.spec.ts +0 -85
  184. package/src/fns/handler.ts +0 -287
  185. package/src/fns/registration.ts +0 -19
  186. package/src/fns/serialization.ts +0 -250
  187. package/src/fns/server.ts +0 -46
  188. package/src/fns/shared.ts +0 -116
  189. package/src/http/index.ts +0 -216
  190. package/src/internal.d.ts +0 -14
  191. package/src/middleware/index.ts +0 -92
  192. package/src/router.tsx +0 -37
  193. package/src/server/StartServer.tsx +0 -58
  194. package/src/server/assets/index.ts +0 -70
  195. package/src/server/assets/render.tsx +0 -46
  196. package/src/server/collect-styles.ts +0 -70
  197. package/src/server/fetchEvent.spec.ts +0 -85
  198. package/src/server/fetchEvent.ts +0 -36
  199. package/src/server/handler.ts +0 -261
  200. package/src/server/manifest/client-manifest.ts +0 -8
  201. package/src/server/manifest/dev-client-manifest.ts +0 -21
  202. package/src/server/manifest/dev-ssr-manifest.ts +0 -23
  203. package/src/server/manifest/prod-client-manifest.ts +0 -21
  204. package/src/server/manifest/prod-ssr-manifest.ts +0 -109
  205. package/src/server/manifest/ssr-manifest.ts +0 -10
  206. package/src/server/routes.ts +0 -126
  207. package/src/server/spa/StartServer.tsx +0 -42
  208. package/src/server/spa/handler.ts +0 -29
  209. package/src/server/types.ts +0 -82
  210. package/src/server/util.ts +0 -12
  211. package/src/shared/ErrorBoundary.tsx +0 -52
  212. package/src/shared/GET.ts +0 -8
  213. package/src/shared/HttpHeader.tsx +0 -42
  214. package/src/shared/HttpStatusCode.ts +0 -27
  215. package/src/shared/clientOnly.ts +0 -44
  216. package/src/shared/dev-overlay/CodeView.tsx +0 -90
  217. package/src/shared/dev-overlay/DevOverlayDialog.tsx +0 -316
  218. package/src/shared/dev-overlay/createStackFrame.ts +0 -74
  219. package/src/shared/dev-overlay/download.ts +0 -6
  220. package/src/shared/dev-overlay/env.d.ts +0 -4
  221. package/src/shared/dev-overlay/get-source-map.ts +0 -33
  222. package/src/shared/dev-overlay/icons.tsx +0 -456
  223. package/src/shared/dev-overlay/index.tsx +0 -63
  224. package/src/shared/lazy.ts +0 -52
  225. package/src/shared/serverFunction.ts +0 -10
  226. package/src/utils/debounce.ts +0 -10
  227. package/src/virtual.d.ts +0 -27
  228. package/tsconfig.json +0 -24
  229. package/vitest.config.ts +0 -9
  230. /package/{src/client/index.tsx → dist/client/index.d.ts} +0 -0
  231. /package/{src → dist}/shared/dev-overlay/styles.css +0 -0
@@ -0,0 +1,38 @@
1
+ // @refresh skip
2
+ import { onCleanup } from "solid-js";
3
+ import { getRequestEvent, isServer } from "solid-js/web";
4
+ import { appendHeader, setHeader } from "../http/index.js";
5
+ /**
6
+ *
7
+ * Read more: https://docs.solidjs.com/solid-start/reference/server/http-header
8
+ */
9
+ export const HttpHeader = isServer
10
+ ? (props) => {
11
+ const event = getRequestEvent();
12
+ if (props.append)
13
+ appendHeader(props.name, props.value);
14
+ else
15
+ setHeader(props.name, props.value);
16
+ onCleanup(() => {
17
+ // @ts-expect-error
18
+ if (event.nativeEvent.handled || event.complete)
19
+ return;
20
+ const value = event.response.headers.get(props.name);
21
+ if (!value)
22
+ return;
23
+ if (!value.includes(", ")) {
24
+ if (value === props.value)
25
+ event.response.headers.delete(props.name);
26
+ return;
27
+ }
28
+ const values = value.split(", ");
29
+ const index = values.indexOf(props.value);
30
+ index !== -1 && values.splice(index, 1);
31
+ if (values.length)
32
+ event.response.headers.set(props.name, values.join(","));
33
+ else
34
+ event.response.headers.delete(props.name);
35
+ });
36
+ return null;
37
+ }
38
+ : (_props) => null;
@@ -0,0 +1,9 @@
1
+ export interface HttpStatusCodeProps {
2
+ code: number;
3
+ text?: string;
4
+ }
5
+ /**
6
+ *
7
+ * Read more: https://docs.solidjs.com/solid-start/reference/server/http-status-code
8
+ */
9
+ export declare const HttpStatusCode: (props: HttpStatusCodeProps) => null;
@@ -0,0 +1,18 @@
1
+ // @refresh skip
2
+ import { onCleanup } from "solid-js";
3
+ import { getRequestEvent, isServer } from "solid-js/web";
4
+ /**
5
+ *
6
+ * Read more: https://docs.solidjs.com/solid-start/reference/server/http-status-code
7
+ */
8
+ export const HttpStatusCode = isServer
9
+ ? (props) => {
10
+ const event = getRequestEvent();
11
+ event.response.status = props.code;
12
+ event.response.statusText = props.text;
13
+ onCleanup(() =>
14
+ // !event.nativeEvent.handled &&
15
+ !event.complete && (event.response.status = 200));
16
+ return null;
17
+ }
18
+ : (_props) => null;
@@ -0,0 +1,12 @@
1
+ import type { Component, ComponentProps, JSX } from "solid-js";
2
+ /**
3
+ *
4
+ * Read more: https://docs.solidjs.com/solid-start/reference/client/client-only
5
+ */
6
+ export default function clientOnly<T extends Component<any>>(fn: () => Promise<{
7
+ default: T;
8
+ }>, options?: {
9
+ lazy?: boolean;
10
+ }): (props: ComponentProps<T> & {
11
+ fallback?: JSX.Element;
12
+ }) => any;
@@ -0,0 +1,27 @@
1
+ import { createMemo, createSignal, onMount, sharedConfig, splitProps, untrack } from "solid-js";
2
+ import { isServer } from "solid-js/web";
3
+ /**
4
+ *
5
+ * Read more: https://docs.solidjs.com/solid-start/reference/client/client-only
6
+ */
7
+ // not using Suspense
8
+ export default function clientOnly(fn, options = {}) {
9
+ if (isServer)
10
+ return (props) => props.fallback;
11
+ const [comp, setComp] = createSignal();
12
+ !options.lazy && load(fn, setComp);
13
+ return (props) => {
14
+ let Comp;
15
+ let m;
16
+ const [, rest] = splitProps(props, ["fallback"]);
17
+ options.lazy && load(fn, setComp);
18
+ if ((Comp = comp()) && !sharedConfig.context)
19
+ return Comp(rest);
20
+ const [mounted, setMounted] = createSignal(!sharedConfig.context);
21
+ onMount(() => setMounted(true));
22
+ return createMemo(() => ((Comp = comp()), (m = mounted()), untrack(() => (Comp && m ? Comp(rest) : props.fallback))));
23
+ };
24
+ }
25
+ function load(fn, setComp) {
26
+ fn().then(m => setComp(() => m.default));
27
+ }
@@ -0,0 +1,7 @@
1
+ import { type JSX } from "solid-js";
2
+ export interface CodeViewProps {
3
+ fileName: string;
4
+ content: string;
5
+ line: number;
6
+ }
7
+ export declare function CodeView(props: CodeViewProps): JSX.Element | null;
@@ -0,0 +1,62 @@
1
+ // @refresh skip
2
+ import { getSingletonHighlighter } from "shiki";
3
+ import { loadWasm } from "shiki/engine/oniguruma";
4
+ import langJS from "shiki/langs/javascript.mjs";
5
+ import langJSX from "shiki/langs/jsx.mjs";
6
+ import langTSX from "shiki/langs/tsx.mjs";
7
+ import langTS from "shiki/langs/typescript.mjs";
8
+ import url from "shiki/onig.wasm?url";
9
+ import darkPlus from "shiki/themes/dark-plus.mjs";
10
+ import { createEffect, createResource } from "solid-js";
11
+ let HIGHLIGHTER;
12
+ async function loadHighlighter() {
13
+ if (!HIGHLIGHTER) {
14
+ await loadWasm(await fetch(url));
15
+ HIGHLIGHTER = await getSingletonHighlighter({
16
+ themes: [darkPlus],
17
+ langs: [langJS, langJSX, langTS, langTSX],
18
+ });
19
+ }
20
+ return HIGHLIGHTER;
21
+ }
22
+ const RANGE = 8;
23
+ export function CodeView(props) {
24
+ const lines = () => props.content.split("\n").map((item, index) => ({
25
+ index: index + 1,
26
+ line: item,
27
+ }));
28
+ const minLine = () => Math.max(props.line - (1 + RANGE), 0);
29
+ const maxLine = () => Math.min(props.line + RANGE, lines().length - 1);
30
+ let ref;
31
+ const [data] = createResource(() => lines()
32
+ .slice(minLine(), maxLine())
33
+ .map(item => item.line)
34
+ .join("\n"), async (value) => {
35
+ const highlighter = await loadHighlighter();
36
+ const fileExtension = props.fileName.split(/[#?]/)[0].split(".").pop()?.trim();
37
+ let lang = fileExtension;
38
+ if (fileExtension === "mjs" || fileExtension === "cjs") {
39
+ lang = "js";
40
+ }
41
+ return highlighter.codeToHtml(value, {
42
+ theme: "dark-plus",
43
+ lang,
44
+ });
45
+ });
46
+ createEffect(() => {
47
+ const result = data();
48
+ if (ref && result) {
49
+ ref.innerHTML = result;
50
+ const lines = ref.querySelectorAll('span[class="line"]');
51
+ for (let i = 0, len = lines.length; i < len; i++) {
52
+ const el = lines[i];
53
+ if (props.line - minLine() - 1 === i) {
54
+ el.dataset.startDevOverlayErrorLine = '';
55
+ }
56
+ }
57
+ }
58
+ });
59
+ return (<div ref={ref} data-start-dev-overlay-code-view style={{
60
+ "--dev-overlay-code-view-start": minLine() + 1,
61
+ }}/>);
62
+ }
@@ -0,0 +1,9 @@
1
+ import type { JSX } from "solid-js";
2
+ import "./styles.css";
3
+ export declare function classNames(...classes: (string | boolean | undefined)[]): string;
4
+ interface DevOverlayDialogProps {
5
+ errors: any[];
6
+ resetError: () => void;
7
+ }
8
+ export default function DevOverlayDialog(props: DevOverlayDialogProps): JSX.Element;
9
+ export {};
@@ -0,0 +1,226 @@
1
+ // @refresh skip
2
+ import ErrorStackParser from "error-stack-parser";
3
+ import * as htmlToImage from "html-to-image";
4
+ import { createMemo, createSignal, ErrorBoundary, For, Show, Suspense } from "solid-js";
5
+ import { Portal } from "solid-js/web";
6
+ // @ts-ignore - terracotta module resolution issue with NodeNext
7
+ import { Dialog, DialogOverlay, DialogPanel, Select, SelectOption } from "terracotta";
8
+ import info from "../../../package.json" with { type: "json" };
9
+ import { CodeView } from "./CodeView.jsx";
10
+ import { createStackFrame } from "./createStackFrame.js";
11
+ import download from "./download.js";
12
+ import { ArrowLeftIcon, ArrowRightIcon, CameraIcon, DiscordIcon, GithubIcon, RefreshIcon, SolidStartIcon, ViewCompiledIcon, ViewOriginalIcon, } from "./icons.jsx";
13
+ import "./styles.css";
14
+ export function classNames(...classes) {
15
+ return classes.filter(Boolean).join(" ");
16
+ }
17
+ function ErrorInfo(props) {
18
+ const error = createMemo(() => {
19
+ const e = props.error;
20
+ if (e instanceof Error) {
21
+ return { name: e.name, message: e.message };
22
+ }
23
+ if (e instanceof ErrorEvent) {
24
+ return { message: e.message };
25
+ }
26
+ return { message: e.toString() };
27
+ });
28
+ return (<span data-start-dev-overlay-error-info>
29
+ <span data-start-dev-overlay-error-info-name>{error().name}</span>
30
+ <span data-start-dev-overlay-error-info-message>{error().message}</span>
31
+ </span>);
32
+ }
33
+ function getFileName(source) {
34
+ try {
35
+ const path = source.startsWith("/") ? new URL(source, "file://") : new URL(source);
36
+ const paths = path.pathname.split("/");
37
+ return paths[paths.length - 1];
38
+ }
39
+ catch (error) {
40
+ return getFileName(`/${source}`);
41
+ }
42
+ }
43
+ function getFilePath(source) {
44
+ const line = source.line ? `:${source.line}` : "";
45
+ const column = source.column ? `:${source.column}` : "";
46
+ return `${getFileName(source.source)}${line}${column}`;
47
+ }
48
+ function CodeFallback() {
49
+ return (<div data-start-dev-overlay-stack-frames-code-fallback>
50
+ <span>Source not available.</span>
51
+ </div>);
52
+ }
53
+ function StackFramesContent(props) {
54
+ const stackframes = ErrorStackParser.parse(props.error);
55
+ const [selectedFrame, setSelectedFrame] = createSignal(stackframes[0]);
56
+ return (<div data-start-dev-overlay-stack-frames-content>
57
+ <div data-start-dev-overlay-stack-frames-code>
58
+ <ErrorBoundary fallback={null}>
59
+ {(() => {
60
+ const data = createStackFrame(selectedFrame(), () => props.isCompiled);
61
+ return (<Suspense fallback={<CodeFallback />}>
62
+ <Show when={data()} keyed fallback={<CodeFallback />}>
63
+ {source => (<>
64
+ <span data-start-dev-overlay-stack-frames-code-source>{source.source}</span>
65
+ <div data-start-dev-overlay-stack-frames-code-container>
66
+ <CodeView fileName={source.source} line={source.line} content={source.content}/>
67
+ </div>
68
+ </>)}
69
+ </Show>
70
+ </Suspense>);
71
+ })()}
72
+ </ErrorBoundary>
73
+ </div>
74
+ <Select data-start-dev-overlay-stack-frames value={selectedFrame()} onChange={setSelectedFrame}>
75
+ <For each={stackframes}>
76
+ {current => (<ErrorBoundary fallback={<div data-start-dev-overlay-stack-frame>
77
+ <span data-start-dev-overlay-stack-frame-function>
78
+ {current.functionName ?? "<anonymous>"}
79
+ </span>
80
+ <span data-start-dev-overlay-stack-frame-file>
81
+ {getFilePath({
82
+ source: current.getFileName(),
83
+ content: "",
84
+ line: current.getLineNumber(),
85
+ column: current.getColumnNumber(),
86
+ name: current.getFunctionName(),
87
+ })}
88
+ </span>
89
+ </div>}>
90
+ {(() => {
91
+ const data = createStackFrame(current, () => props.isCompiled);
92
+ return (<Suspense>
93
+ <Show when={data()} keyed>
94
+ {source => (<SelectOption data-start-dev-overlay-stack-frame value={current}>
95
+ <span data-start-dev-overlay-stack-frame-function>
96
+ {source.name ?? "<anonymous>"}
97
+ </span>
98
+ <span data-start-dev-overlay-stack-frame-file>{getFilePath(source)}</span>
99
+ </SelectOption>)}
100
+ </Show>
101
+ </Suspense>);
102
+ })()}
103
+ </ErrorBoundary>)}
104
+ </For>
105
+ </Select>
106
+ </div>);
107
+ }
108
+ function StackFrames(props) {
109
+ return (<Show when={props.error instanceof Error && props.error} keyed>
110
+ {current => <StackFramesContent error={current} isCompiled={props.isCompiled}/>}
111
+ </Show>);
112
+ }
113
+ const ISSUE_THREAD = "https://github.com/solidjs/solid-start/issues/new";
114
+ const DISCORD_INVITE = "https://discord.com/invite/solidjs";
115
+ export default function DevOverlayDialog(props) {
116
+ const [currentPage, setCurrentPage] = createSignal(1);
117
+ const [isCompiled, setIsCompiled] = createSignal(false);
118
+ const length = createMemo(() => props.errors.length);
119
+ const truncated = createMemo(() => {
120
+ return Math.min(currentPage(), length());
121
+ });
122
+ function goPrev() {
123
+ setCurrentPage(c => {
124
+ if (c > 1) {
125
+ return c - 1;
126
+ }
127
+ return length();
128
+ });
129
+ }
130
+ function goNext() {
131
+ setCurrentPage(c => {
132
+ if (c < length()) {
133
+ return c + 1;
134
+ }
135
+ return 1;
136
+ });
137
+ }
138
+ function toggleIsCompiled() {
139
+ setIsCompiled(c => !c);
140
+ }
141
+ const [panel, setPanel] = createSignal();
142
+ function downloadScreenshot() {
143
+ const current = panel();
144
+ if (current) {
145
+ htmlToImage
146
+ .toPng(current, {
147
+ style: {
148
+ transform: "scale(0.75)",
149
+ },
150
+ })
151
+ .then(url => {
152
+ download(url, "start-screenshot.png");
153
+ });
154
+ }
155
+ }
156
+ function redirectToGithub() {
157
+ const url = new URL(ISSUE_THREAD);
158
+ url.searchParams.append("labels", "bug");
159
+ url.searchParams.append("labels", "needs+triage");
160
+ url.searchParams.append("template", "bug.yml");
161
+ url.searchParams.append("title", `[Bug?]:` + props.errors[truncated() - 1].toString());
162
+ window.open(url, "_blank").focus();
163
+ }
164
+ function redirectToDiscord() {
165
+ window.open(DISCORD_INVITE, "_blank").focus();
166
+ }
167
+ return (<Portal>
168
+ <Dialog data-start-dev-overlay isOpen>
169
+ <div>
170
+ <DialogOverlay data-start-dev-overlay-background/>
171
+ <DialogPanel ref={setPanel} data-start-dev-overlay-panel-container>
172
+ <div data-start-dev-overlay-panel>
173
+ <div data-start-dev-overlay-navbar>
174
+ <div data-start-dev-overlay-navbar-left>
175
+ <div data-start-dev-overlay-version>
176
+ <div>
177
+ <SolidStartIcon title="Solid Start Version"/>
178
+ </div>
179
+ <span>{info.version}</span>
180
+ </div>
181
+ <Show when={props.errors.length > 1}>
182
+ <div data-start-dev-overlay-pagination>
183
+ <button data-start-dev-overlay-button onClick={goPrev} type="button">
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>
213
+ </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
+ </Show>
221
+ </div>
222
+ </DialogPanel>
223
+ </div>
224
+ </Dialog>
225
+ </Portal>);
226
+ }
@@ -0,0 +1,9 @@
1
+ import { type Accessor } from "solid-js";
2
+ export interface StackFrameSource {
3
+ content: string;
4
+ source: string;
5
+ name?: string;
6
+ line: number;
7
+ column: number;
8
+ }
9
+ export declare function createStackFrame(stackframe: StackFrame, isCompiled: () => boolean): Accessor<StackFrameSource>;
@@ -0,0 +1,56 @@
1
+ import { createMemo, createResource } from "solid-js";
2
+ import getSourceMap from "./get-source-map.js";
3
+ function getActualFileSource(path) {
4
+ if (path.startsWith("file://")) {
5
+ return "/_build/@fs" + path.substring("file://".length);
6
+ }
7
+ return path;
8
+ }
9
+ export function createStackFrame(stackframe, isCompiled) {
10
+ const [data] = createResource(() => ({
11
+ fileName: stackframe.fileName,
12
+ line: stackframe.lineNumber,
13
+ column: stackframe.columnNumber,
14
+ functionName: stackframe.functionName,
15
+ }), async (source) => {
16
+ if (!source.fileName) {
17
+ return null;
18
+ }
19
+ const response = await fetch(getActualFileSource(source.fileName));
20
+ if (!response.ok) {
21
+ return null;
22
+ }
23
+ const content = await response.text();
24
+ const sourceMap = await getSourceMap(source.fileName, content);
25
+ return {
26
+ source,
27
+ content,
28
+ sourceMap,
29
+ };
30
+ });
31
+ const info = createMemo(() => {
32
+ const current = data();
33
+ if (!current) {
34
+ return undefined;
35
+ }
36
+ const { source, content, sourceMap } = current;
37
+ if (!isCompiled() && source.line && source.column && sourceMap) {
38
+ const result = sourceMap.originalPositionFor({
39
+ line: source.line,
40
+ column: source.column,
41
+ });
42
+ return {
43
+ ...result,
44
+ content: sourceMap.sourceContentFor(result.source),
45
+ };
46
+ }
47
+ return {
48
+ source: source.fileName,
49
+ line: source.line,
50
+ column: source.column,
51
+ name: source.functionName,
52
+ content,
53
+ };
54
+ });
55
+ return info;
56
+ }
@@ -0,0 +1 @@
1
+ export default function download(dataurl: string, filename: string): void;
@@ -0,0 +1,6 @@
1
+ export default function download(dataurl, filename) {
2
+ const link = document.createElement("a");
3
+ link.href = dataurl;
4
+ link.download = filename;
5
+ link.click();
6
+ }
@@ -0,0 +1,2 @@
1
+ import { SourceMapConsumer } from "source-map-js";
2
+ export default function getSourceMap(url: string, content: string): Promise<SourceMapConsumer | null>;
@@ -0,0 +1,25 @@
1
+ import { SourceMapConsumer } from "source-map-js";
2
+ const INLINE_SOURCEMAP_REGEX = /^data:application\/json[^,]+base64,/;
3
+ const SOURCEMAP_REGEX = /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*(?:\*\/)[ \t]*$)/;
4
+ export default async function getSourceMap(url, content) {
5
+ const lines = content.split("\n");
6
+ let sourceMapUrl;
7
+ for (let i = lines.length - 1; i >= 0 && !sourceMapUrl; i--) {
8
+ const result = lines[i].match(SOURCEMAP_REGEX);
9
+ if (result) {
10
+ sourceMapUrl = result[1];
11
+ }
12
+ }
13
+ if (!sourceMapUrl) {
14
+ return null;
15
+ }
16
+ if (!(INLINE_SOURCEMAP_REGEX.test(sourceMapUrl) || sourceMapUrl.startsWith("/"))) {
17
+ // Resolve path if it's a relative access
18
+ const parsedURL = url.split("/");
19
+ parsedURL[parsedURL.length - 1] = sourceMapUrl;
20
+ sourceMapUrl = parsedURL.join("/");
21
+ }
22
+ const response = await fetch(sourceMapUrl);
23
+ const rawSourceMap = await response.json();
24
+ return new SourceMapConsumer(rawSourceMap);
25
+ }
@@ -0,0 +1,28 @@
1
+ import type { JSX } from "solid-js";
2
+ export declare function ArrowRightIcon(props: JSX.IntrinsicElements["svg"] & {
3
+ title: string;
4
+ }): JSX.Element;
5
+ export declare function ArrowLeftIcon(props: JSX.IntrinsicElements["svg"] & {
6
+ title: string;
7
+ }): JSX.Element;
8
+ export declare function RefreshIcon(props: JSX.IntrinsicElements["svg"] & {
9
+ title: string;
10
+ }): JSX.Element;
11
+ export declare function ViewCompiledIcon(props: JSX.IntrinsicElements["svg"] & {
12
+ title: string;
13
+ }): JSX.Element;
14
+ export declare function ViewOriginalIcon(props: JSX.IntrinsicElements["svg"] & {
15
+ title: string;
16
+ }): JSX.Element;
17
+ export declare function CameraIcon(props: JSX.IntrinsicElements["svg"] & {
18
+ title: string;
19
+ }): JSX.Element;
20
+ export declare function DiscordIcon(props: JSX.IntrinsicElements["svg"] & {
21
+ title: string;
22
+ }): JSX.Element;
23
+ export declare function GithubIcon(props: JSX.IntrinsicElements["svg"] & {
24
+ title: string;
25
+ }): JSX.Element;
26
+ export declare function SolidStartIcon(props: JSX.IntrinsicElements["svg"] & {
27
+ title: string;
28
+ }): JSX.Element;