@solidjs/start 2.0.0-alpha.0 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/client/mount.d.ts +1 -7
  3. package/dist/client/mount.js +1 -99
  4. package/dist/config/constants.js +2 -2
  5. package/dist/config/fs-router.js +10 -22
  6. package/dist/config/fs-routes/fs-watcher.js +4 -4
  7. package/dist/config/fs-routes/index.js +4 -6
  8. package/dist/config/fs-routes/router.js +5 -5
  9. package/dist/config/fs-routes/tree-shake.js +12 -21
  10. package/dist/config/index.js +33 -36
  11. package/dist/config/lazy.js +9 -9
  12. package/dist/config/manifest.js +1 -1
  13. package/dist/http/index.d.ts +1 -4
  14. package/dist/http/index.js +3 -5
  15. package/dist/index.d.ts +0 -1
  16. package/dist/router.jsx +2 -2
  17. package/dist/server/assets/index.js +1 -1
  18. package/dist/server/assets/render.jsx +2 -2
  19. package/dist/server/fetchEvent.spec.js +1 -1
  20. package/dist/server/handler.js +29 -15
  21. package/dist/server/index.d.ts +1 -0
  22. package/dist/server/manifest/dev-client-manifest.js +1 -1
  23. package/dist/server/manifest/dev-ssr-manifest.js +1 -1
  24. package/dist/server/manifest/prod-ssr-manifest.js +7 -12
  25. package/dist/server/routes.js +3 -3
  26. package/dist/server/server-fns-runtime.js +2 -2
  27. package/dist/server/server-functions-handler.js +6 -11
  28. package/dist/server/server-runtime.js +8 -8
  29. package/dist/shared/dev-overlay/CodeView.d.ts +1 -1
  30. package/dist/shared/dev-overlay/CodeView.jsx +23 -34
  31. package/dist/shared/dev-overlay/DevOverlayDialog.jsx +4 -4
  32. package/dist/shared/dev-overlay/get-source-map.d.ts +1 -1
  33. package/dist/shared/dev-overlay/get-source-map.js +5 -5
  34. package/dist/shared/dev-overlay/icons.d.ts +10 -10
  35. package/dist/shared/dev-overlay/icons.jsx +91 -91
  36. package/dist/shared/dev-overlay/index.jsx +1 -1
  37. package/dist/shared/lazy.js +4 -2
  38. package/env.d.ts +9 -0
  39. package/package.json +5 -4
  40. package/scripts/build.js +3 -3
  41. package/scripts/validate-imports.js +8 -8
  42. package/src/client/mount.ts +1 -114
  43. package/src/config/constants.ts +3 -3
  44. package/src/config/dev-server.ts +95 -99
  45. package/src/config/fs-router.ts +140 -155
  46. package/src/config/fs-routes/fs-watcher.ts +57 -61
  47. package/src/config/fs-routes/index.ts +117 -119
  48. package/src/config/fs-routes/router.ts +7 -7
  49. package/src/config/fs-routes/tree-shake.ts +342 -363
  50. package/src/config/index.ts +36 -39
  51. package/src/config/lazy.ts +13 -13
  52. package/src/config/manifest.ts +5 -5
  53. package/src/config/vite-utils.ts +2 -6
  54. package/src/env.d.ts +10 -28
  55. package/src/http/index.ts +105 -142
  56. package/src/index.tsx +0 -12
  57. package/src/internal.d.ts +1 -1
  58. package/src/middleware/index.ts +39 -49
  59. package/src/router.tsx +4 -3
  60. package/src/server/StartServer.tsx +1 -7
  61. package/src/server/assets/index.ts +1 -1
  62. package/src/server/assets/render.tsx +6 -2
  63. package/src/server/collect-styles.ts +63 -70
  64. package/src/server/fetchEvent.spec.ts +71 -75
  65. package/src/server/fetchEvent.ts +17 -17
  66. package/src/server/handler.ts +136 -129
  67. package/src/server/index.tsx +13 -0
  68. package/src/server/manifest/client-manifest.ts +1 -1
  69. package/src/server/manifest/dev-client-manifest.ts +7 -5
  70. package/src/server/manifest/dev-ssr-manifest.ts +8 -6
  71. package/src/server/manifest/prod-client-manifest.ts +7 -4
  72. package/src/server/manifest/prod-ssr-manifest.ts +78 -94
  73. package/src/server/manifest/ssr-manifest.ts +4 -2
  74. package/src/server/routes.ts +96 -108
  75. package/src/server/server-fns-runtime.ts +3 -3
  76. package/src/server/server-functions-handler.ts +294 -319
  77. package/src/server/server-runtime.ts +13 -13
  78. package/src/server/spa/handler.ts +12 -12
  79. package/src/server/types.ts +46 -46
  80. package/src/server/util.ts +4 -4
  81. package/src/shared/ErrorBoundary.tsx +1 -1
  82. package/src/shared/HttpHeader.tsx +20 -20
  83. package/src/shared/HttpStatusCode.ts +14 -14
  84. package/src/shared/clientOnly.ts +3 -3
  85. package/src/shared/dev-overlay/CodeView.tsx +43 -46
  86. package/src/shared/dev-overlay/DevOverlayDialog.tsx +4 -4
  87. package/src/shared/dev-overlay/createStackFrame.ts +59 -62
  88. package/src/shared/dev-overlay/env.d.ts +2 -2
  89. package/src/shared/dev-overlay/get-source-map.ts +5 -7
  90. package/src/shared/dev-overlay/icons.tsx +289 -121
  91. package/src/shared/dev-overlay/index.tsx +1 -1
  92. package/src/shared/lazy.ts +4 -3
  93. package/src/shared/serverFunction.ts +1 -1
  94. package/src/virtual.d.ts +10 -10
  95. package/tsconfig.json +2 -2
  96. package/vitest.config.ts +2 -2
@@ -2,93 +2,86 @@ import path from "node:path";
2
2
  import { resolve } from "pathe";
3
3
  import type { DevEnvironment, EnvironmentModuleNode } from "vite";
4
4
 
5
- async function getViteModuleNode(
6
- vite: DevEnvironment,
7
- file: string,
8
- ) {
9
- let nodePath = file;
10
- let node = vite.moduleGraph.getModuleById(file);
5
+ async function getViteModuleNode(vite: DevEnvironment, file: string) {
6
+ let nodePath = file;
7
+ let node = vite.moduleGraph.getModuleById(file);
11
8
 
12
- if (!node) {
13
- const resolvedId = await vite.pluginContainer.resolveId(file, undefined);
14
- if (!resolvedId) return;
9
+ if (!node) {
10
+ const resolvedId = await vite.pluginContainer.resolveId(file, undefined);
11
+ if (!resolvedId) return;
15
12
 
16
- nodePath = resolvedId.id;
17
- node = vite.moduleGraph.getModuleById(file);
18
- }
13
+ nodePath = resolvedId.id;
14
+ node = vite.moduleGraph.getModuleById(file);
15
+ }
19
16
 
20
- if (!node) {
21
- nodePath = resolve(nodePath);
22
- node = await vite.moduleGraph.getModuleByUrl(file);
23
- }
17
+ if (!node) {
18
+ nodePath = resolve(nodePath);
19
+ node = await vite.moduleGraph.getModuleByUrl(file);
20
+ }
24
21
 
25
- if (!node) {
26
- await vite.moduleGraph.ensureEntryFromUrl(nodePath, false);
27
- node = vite.moduleGraph.getModuleById(nodePath);
28
- }
22
+ if (!node) {
23
+ await vite.moduleGraph.ensureEntryFromUrl(nodePath, false);
24
+ node = vite.moduleGraph.getModuleById(nodePath);
25
+ }
29
26
 
30
- return node;
27
+ return node;
31
28
  }
32
29
 
33
30
  async function findModuleDependencies(
34
- vite: DevEnvironment,
35
- file: string,
36
- deps: Set<EnvironmentModuleNode>,
37
- crawledFiles = new Set<string>()
31
+ vite: DevEnvironment,
32
+ file: string,
33
+ deps: Set<EnvironmentModuleNode>,
34
+ crawledFiles = new Set<string>(),
38
35
  ) {
39
- crawledFiles.add(file);
40
- const module = await getViteModuleNode(vite, file);
41
- if (!module?.id || deps.has(module)) return;
42
-
43
- deps.add(module);
44
-
45
- if (module.url.endsWith(".css") || module.url.includes("node_modules")) return;
46
-
47
- if (!module.transformResult) {
48
- await vite.transformRequest(module.id).catch(() => {});
49
- }
50
- if (!module.transformResult?.deps) return;
51
-
52
- // Relying on module.transformResult.deps instead of module.importedModules because:
53
- // transformResult properly separates imports into deps and dynamicDeps, importedModules doesn't
54
- // Style crawling has to skip dynamic imports as such modules load their styles themselves
55
- for (const dep of module.transformResult.deps) {
56
- if (crawledFiles.has(dep)) {
57
- continue;
58
- }
59
- await findModuleDependencies(vite, dep, deps, crawledFiles);
60
- }
36
+ crawledFiles.add(file);
37
+ const module = await getViteModuleNode(vite, file);
38
+ if (!module?.id || deps.has(module)) return;
39
+
40
+ deps.add(module);
41
+
42
+ if (module.url.endsWith(".css") || module.url.includes("node_modules")) return;
43
+
44
+ if (!module.transformResult) {
45
+ await vite.transformRequest(module.id).catch(() => {});
46
+ }
47
+ if (!module.transformResult?.deps) return;
48
+
49
+ // Relying on module.transformResult.deps instead of module.importedModules because:
50
+ // transformResult properly separates imports into deps and dynamicDeps, importedModules doesn't
51
+ // Style crawling has to skip dynamic imports as such modules load their styles themselves
52
+ for (const dep of module.transformResult.deps) {
53
+ if (crawledFiles.has(dep)) {
54
+ continue;
55
+ }
56
+ await findModuleDependencies(vite, dep, deps, crawledFiles);
57
+ }
61
58
  }
62
59
 
63
60
  // Vite doesn't expose these so we just copy the list for now
64
61
  // https://github.com/vitejs/vite/blob/d6bde8b03d433778aaed62afc2be0630c8131908/packages/vite/src/node/constants.ts#L49C23-L50
65
- const cssFileRegExp =
66
- /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
62
+ const cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
67
63
  // https://github.com/vitejs/vite/blob/d6bde8b03d433778aaed62afc2be0630c8131908/packages/vite/src/node/plugins/css.ts#L160
68
64
  const cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
69
65
 
70
66
  const isCssFile = (file: string) => cssFileRegExp.test(file);
71
67
  export const isCssModulesFile = (file: string) => cssModulesRegExp.test(file);
72
68
 
73
- export async function findStylesInModuleGraph(
74
- vite: DevEnvironment,
75
- id: string,
76
- ) {
77
- const absolute = path.resolve(process.cwd(), id);
78
- const dependencies = new Set<EnvironmentModuleNode>();
79
-
80
- try {
81
- await findModuleDependencies(vite, absolute, dependencies);
82
- } catch (e) {
83
- console.error(e);
84
- }
85
-
86
- const styles: Record<string, any> = {};
87
- for (const dep of dependencies) {
88
- if (dep.id && isCssFile(dep.url)) {
89
- styles[dep.id] = dep.url;
90
- }
91
- }
92
-
93
- return styles;
69
+ export async function findStylesInModuleGraph(vite: DevEnvironment, id: string) {
70
+ const absolute = path.resolve(process.cwd(), id);
71
+ const dependencies = new Set<EnvironmentModuleNode>();
72
+
73
+ try {
74
+ await findModuleDependencies(vite, absolute, dependencies);
75
+ } catch (e) {
76
+ console.error(e);
77
+ }
78
+
79
+ const styles: Record<string, any> = {};
80
+ for (const dep of dependencies) {
81
+ if (dep.id && isCssFile(dep.url)) {
82
+ styles[dep.id] = dep.url;
83
+ }
84
+ }
85
+
86
+ return styles;
94
87
  }
@@ -1,89 +1,85 @@
1
1
  import * as h3 from "h3";
2
2
  import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
 
4
- import {
5
- createFetchEvent,
6
- getFetchEvent,
7
- mergeResponseHeaders,
8
- } from "./fetchEvent.ts";
9
-
10
- vi.mock(import("h3"), async (mod) => {
11
- return {
12
- ...(await mod()),
13
- getRequestIP: vi.fn(),
14
- };
4
+ import { createFetchEvent, getFetchEvent, mergeResponseHeaders } from "./fetchEvent.ts";
5
+
6
+ vi.mock(import("h3"), async mod => {
7
+ return {
8
+ ...(await mod()),
9
+ getRequestIP: vi.fn(),
10
+ };
15
11
  });
16
12
 
17
13
  const mockedH3 = vi.mocked(h3);
18
14
 
19
15
  const createMockH3Event = (): h3.H3Event => {
20
- const event = new h3.H3Event(new Request("http://localhost/test"));
16
+ const event = new h3.H3Event(new Request("http://localhost/test"));
21
17
 
22
- event.res.status = 200;
23
- event.res.statusText = "OK";
18
+ event.res.status = 200;
19
+ event.res.statusText = "OK";
24
20
 
25
- return event;
21
+ return event;
26
22
  };
27
23
 
28
24
  describe("fetchEvent", () => {
29
- let mockH3Event: h3.H3Event;
30
-
31
- beforeEach(() => {
32
- mockH3Event = createMockH3Event();
33
- vi.clearAllMocks();
34
-
35
- mockedH3.getRequestIP.mockReturnValue("127.0.0.1");
36
- });
37
-
38
- describe("createFetchEvent", () => {
39
- it("should create a FetchEvent from H3Event", () => {
40
- const fetchEvent = createFetchEvent(mockH3Event);
41
-
42
- expect(fetchEvent).toEqual({
43
- request: mockH3Event.req,
44
- response: expect.any(Object),
45
- clientAddress: "127.0.0.1",
46
- locals: {},
47
- nativeEvent: mockH3Event,
48
- });
49
- });
50
-
51
- it("should create response stub with correct properties", () => {
52
- const fetchEvent = createFetchEvent(mockH3Event);
53
-
54
- expect(fetchEvent.response).toHaveProperty("status");
55
- expect(fetchEvent.response).toHaveProperty("statusText");
56
- expect(fetchEvent.response).toHaveProperty("headers");
57
- });
58
- });
59
-
60
- describe("getFetchEvent", () => {
61
- it("should create and cache FetchEvent on first call", () => {
62
- const fetchEvent = getFetchEvent(mockH3Event);
63
-
64
- expect(mockH3Event.context.solidFetchEvent).toBe(fetchEvent);
65
- expect(fetchEvent.nativeEvent).toBe(mockH3Event);
66
- });
67
-
68
- it("should return cached FetchEvent on subsequent calls", () => {
69
- const firstCall = getFetchEvent(mockH3Event);
70
- const secondCall = getFetchEvent(mockH3Event);
71
-
72
- expect(firstCall).toBe(secondCall);
73
- });
74
- });
75
-
76
- describe("mergeResponseHeaders", () => {
77
- it("should merge headers from Headers object to H3Event", () => {
78
- const headers = new Headers({
79
- "content-type": "application/json",
80
- "x-custom": "value",
81
- });
82
-
83
- mergeResponseHeaders(mockH3Event, headers);
84
-
85
- expect(headers.get("content-type")).toBe("application/json");
86
- expect(headers.get("x-custom")).toBe("value");
87
- });
88
- });
25
+ let mockH3Event: h3.H3Event;
26
+
27
+ beforeEach(() => {
28
+ mockH3Event = createMockH3Event();
29
+ vi.clearAllMocks();
30
+
31
+ mockedH3.getRequestIP.mockReturnValue("127.0.0.1");
32
+ });
33
+
34
+ describe("createFetchEvent", () => {
35
+ it("should create a FetchEvent from H3Event", () => {
36
+ const fetchEvent = createFetchEvent(mockH3Event);
37
+
38
+ expect(fetchEvent).toEqual({
39
+ request: mockH3Event.req,
40
+ response: expect.any(Object),
41
+ clientAddress: "127.0.0.1",
42
+ locals: {},
43
+ nativeEvent: mockH3Event,
44
+ });
45
+ });
46
+
47
+ it("should create response stub with correct properties", () => {
48
+ const fetchEvent = createFetchEvent(mockH3Event);
49
+
50
+ expect(fetchEvent.response).toHaveProperty("status");
51
+ expect(fetchEvent.response).toHaveProperty("statusText");
52
+ expect(fetchEvent.response).toHaveProperty("headers");
53
+ });
54
+ });
55
+
56
+ describe("getFetchEvent", () => {
57
+ it("should create and cache FetchEvent on first call", () => {
58
+ const fetchEvent = getFetchEvent(mockH3Event);
59
+
60
+ expect(mockH3Event.context.solidFetchEvent).toBe(fetchEvent);
61
+ expect(fetchEvent.nativeEvent).toBe(mockH3Event);
62
+ });
63
+
64
+ it("should return cached FetchEvent on subsequent calls", () => {
65
+ const firstCall = getFetchEvent(mockH3Event);
66
+ const secondCall = getFetchEvent(mockH3Event);
67
+
68
+ expect(firstCall).toBe(secondCall);
69
+ });
70
+ });
71
+
72
+ describe("mergeResponseHeaders", () => {
73
+ it("should merge headers from Headers object to H3Event", () => {
74
+ const headers = new Headers({
75
+ "content-type": "application/json",
76
+ "x-custom": "value",
77
+ });
78
+
79
+ mergeResponseHeaders(mockH3Event, headers);
80
+
81
+ expect(headers.get("content-type")).toBe("application/json");
82
+ expect(headers.get("x-custom")).toBe("value");
83
+ });
84
+ });
89
85
  });
@@ -5,32 +5,32 @@ import type { FetchEvent } from "./types.ts";
5
5
  const FETCH_EVENT_CONTEXT = "solidFetchEvent";
6
6
 
7
7
  export function createFetchEvent(event: H3Event): FetchEvent {
8
- return {
9
- request: event.req,
10
- response: event.res,
11
- clientAddress: getRequestIP(event),
12
- locals: {},
13
- nativeEvent: event,
14
- };
8
+ return {
9
+ request: event.req,
10
+ response: event.res,
11
+ clientAddress: getRequestIP(event),
12
+ locals: {},
13
+ nativeEvent: event,
14
+ };
15
15
  }
16
16
 
17
17
  export function getFetchEvent(h3Event: H3Event): FetchEvent {
18
- if (!h3Event.context[FETCH_EVENT_CONTEXT]) {
19
- const fetchEvent = createFetchEvent(h3Event);
20
- h3Event.context[FETCH_EVENT_CONTEXT] = fetchEvent;
21
- }
18
+ if (!h3Event.context[FETCH_EVENT_CONTEXT]) {
19
+ const fetchEvent = createFetchEvent(h3Event);
20
+ h3Event.context[FETCH_EVENT_CONTEXT] = fetchEvent;
21
+ }
22
22
 
23
- return h3Event.context[FETCH_EVENT_CONTEXT] as any;
23
+ return h3Event.context[FETCH_EVENT_CONTEXT] as any;
24
24
  }
25
25
 
26
26
  export function mergeResponseHeaders(h3Event: H3Event, headers: Headers) {
27
- for (const [key, value] of headers.entries()) {
28
- h3Event.res.headers.append(key, value);
29
- }
27
+ for (const [key, value] of headers.entries()) {
28
+ h3Event.res.headers.append(key, value);
29
+ }
30
30
  }
31
31
 
32
32
  export const decorateHandler = <T extends EventHandler>(fn: T) =>
33
- (event => provideRequestEvent(getFetchEvent(event), () => fn(event))) as T;
33
+ (event => provideRequestEvent(getFetchEvent(event), () => fn(event))) as T;
34
34
 
35
35
  export const decorateMiddleware = <T extends Middleware>(fn: T) =>
36
- ((event, next) => provideRequestEvent(getFetchEvent(event), () => fn(event, next))) as T;
36
+ ((event, next) => provideRequestEvent(getFetchEvent(event), () => fn(event, next))) as T;