@solidjs/start 1.2.0 → 2.0.0-alpha.0

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 (184) hide show
  1. package/README.md +88 -8
  2. package/dist/client/StartClient.d.ts +0 -1
  3. package/dist/client/StartClient.jsx +2 -4
  4. package/dist/client/index.d.ts +2 -3
  5. package/dist/client/index.jsx +2 -4
  6. package/dist/client/mount.js +10 -2
  7. package/dist/client/spa/index.d.ts +1 -2
  8. package/dist/client/spa/index.jsx +1 -2
  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 +108 -0
  13. package/dist/config/fs-router.d.ts +37 -0
  14. package/dist/config/fs-router.js +153 -0
  15. package/dist/config/fs-routes/fs-watcher.d.ts +3 -0
  16. package/dist/config/fs-routes/fs-watcher.js +49 -0
  17. package/dist/config/fs-routes/index.d.ts +7 -0
  18. package/dist/config/fs-routes/index.js +109 -0
  19. package/dist/config/fs-routes/router.d.ts +37 -0
  20. package/dist/config/fs-routes/router.js +136 -0
  21. package/dist/config/fs-routes/tree-shake.d.ts +2 -0
  22. package/dist/config/fs-routes/tree-shake.js +357 -0
  23. package/dist/config/index.d.ts +10 -0
  24. package/dist/config/index.js +217 -0
  25. package/dist/config/lazy.d.ts +3 -0
  26. package/dist/config/lazy.js +82 -0
  27. package/dist/config/manifest.d.ts +3 -0
  28. package/dist/config/manifest.js +74 -0
  29. package/dist/config/utils.d.ts +4 -0
  30. package/dist/config/utils.js +6 -0
  31. package/dist/config/vite-utils.d.ts +16 -0
  32. package/dist/config/vite-utils.js +81 -0
  33. package/dist/http/index.d.ts +84 -0
  34. package/dist/http/index.js +131 -0
  35. package/dist/index.d.ts +6 -5
  36. package/dist/index.jsx +5 -5
  37. package/dist/middleware/index.d.ts +6 -6
  38. package/dist/middleware/index.js +39 -0
  39. package/dist/{router/FileRoutes.js → router.jsx} +5 -6
  40. package/dist/server/StartServer.d.ts +3 -3
  41. package/dist/server/StartServer.jsx +9 -63
  42. package/dist/server/assets/index.d.ts +2 -0
  43. package/dist/server/assets/index.js +52 -0
  44. package/dist/server/assets/render.d.ts +19 -0
  45. package/dist/server/{renderAsset.jsx → assets/render.jsx} +1 -1
  46. package/dist/server/collect-styles.d.ts +3 -0
  47. package/dist/server/collect-styles.js +69 -0
  48. package/dist/server/fetchEvent.d.ts +4 -3
  49. package/dist/server/fetchEvent.js +12 -74
  50. package/dist/server/fetchEvent.spec.js +18 -197
  51. package/dist/server/handler.d.ts +6 -12
  52. package/dist/server/handler.js +180 -97
  53. package/dist/server/index.d.ts +8 -6
  54. package/dist/server/index.jsx +14 -6
  55. package/dist/server/manifest/client-manifest.d.ts +9 -0
  56. package/dist/server/manifest/client-manifest.js +6 -0
  57. package/dist/server/manifest/dev-client-manifest.d.ts +4 -0
  58. package/dist/server/manifest/dev-client-manifest.js +24 -0
  59. package/dist/server/manifest/dev-ssr-manifest.d.ts +5 -0
  60. package/dist/server/manifest/dev-ssr-manifest.js +23 -0
  61. package/dist/server/manifest/prod-client-manifest.d.ts +5 -0
  62. package/dist/server/manifest/prod-client-manifest.js +26 -0
  63. package/dist/server/manifest/prod-ssr-manifest.d.ts +6 -0
  64. package/dist/server/manifest/prod-ssr-manifest.js +90 -0
  65. package/dist/server/manifest/ssr-manifest.d.ts +4 -0
  66. package/dist/server/manifest/ssr-manifest.js +6 -0
  67. package/dist/{router → server}/routes.d.ts +5 -10
  68. package/dist/{router → server}/routes.js +35 -36
  69. package/dist/{runtime → server}/server-fns-runtime.d.ts +1 -1
  70. package/dist/{runtime → server}/server-fns-runtime.js +7 -6
  71. package/dist/server/server-functions-handler.d.ts +2 -0
  72. package/dist/{runtime/server-handler.js → server/server-functions-handler.js} +65 -100
  73. package/dist/server/server-runtime.d.ts +3 -0
  74. package/dist/{runtime → server}/server-runtime.js +9 -16
  75. package/dist/server/spa/StartServer.d.ts +1 -1
  76. package/dist/server/spa/StartServer.jsx +7 -9
  77. package/dist/server/spa/handler.d.ts +3 -3
  78. package/dist/server/spa/handler.js +9 -11
  79. package/dist/server/spa/index.d.ts +4 -3
  80. package/dist/server/spa/index.jsx +4 -3
  81. package/dist/server/types.d.ts +7 -9
  82. package/dist/server/util.d.ts +2 -0
  83. package/dist/server/util.js +8 -0
  84. package/dist/shared/ErrorBoundary.jsx +2 -2
  85. package/dist/shared/HttpHeader.jsx +4 -2
  86. package/dist/shared/{HttpStatusCode.jsx → HttpStatusCode.js} +3 -1
  87. package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +2 -2
  88. package/dist/shared/dev-overlay/DevOverlayDialog.jsx +75 -66
  89. package/dist/shared/dev-overlay/createStackFrame.js +3 -3
  90. package/dist/shared/dev-overlay/index.jsx +5 -8
  91. package/dist/shared/lazy.d.ts +3 -0
  92. package/dist/shared/lazy.js +40 -0
  93. package/dist/shared/serverFunction.d.ts +1 -1
  94. package/package.json +45 -67
  95. package/scripts/build.js +15 -0
  96. package/scripts/validate-imports.js +316 -0
  97. package/src/client/StartClient.tsx +34 -0
  98. package/src/client/index.tsx +2 -0
  99. package/src/client/mount.ts +114 -0
  100. package/src/client/spa/index.tsx +9 -0
  101. package/src/config/constants.ts +19 -0
  102. package/src/config/dev-server.ts +149 -0
  103. package/src/config/fs-router.ts +177 -0
  104. package/src/config/fs-routes/fs-watcher.ts +81 -0
  105. package/src/config/fs-routes/index.ts +138 -0
  106. package/src/config/fs-routes/router.ts +169 -0
  107. package/src/config/fs-routes/tree-shake.ts +392 -0
  108. package/src/config/index.ts +236 -0
  109. package/src/config/lazy.ts +100 -0
  110. package/src/config/manifest.ts +84 -0
  111. package/src/config/utils.ts +5 -0
  112. package/src/config/vite-utils.ts +113 -0
  113. package/src/env.d.ts +35 -0
  114. package/src/http/index.ts +253 -0
  115. package/src/index.tsx +19 -0
  116. package/src/internal.d.ts +14 -0
  117. package/src/middleware/index.ts +82 -0
  118. package/src/router.tsx +36 -0
  119. package/src/server/StartServer.tsx +62 -0
  120. package/src/server/assets/index.ts +70 -0
  121. package/src/server/assets/render.tsx +42 -0
  122. package/src/server/collect-styles.ts +94 -0
  123. package/src/server/fetchEvent.spec.ts +89 -0
  124. package/src/server/fetchEvent.ts +36 -0
  125. package/src/server/handler.ts +250 -0
  126. package/src/server/index.tsx +16 -0
  127. package/src/server/manifest/client-manifest.ts +8 -0
  128. package/src/server/manifest/dev-client-manifest.ts +19 -0
  129. package/src/server/manifest/dev-ssr-manifest.ts +21 -0
  130. package/src/server/manifest/prod-client-manifest.ts +18 -0
  131. package/src/server/manifest/prod-ssr-manifest.ts +125 -0
  132. package/src/server/manifest/ssr-manifest.ts +8 -0
  133. package/src/server/routes.ts +138 -0
  134. package/src/server/server-fns-runtime.ts +31 -0
  135. package/src/server/server-functions-handler.ts +364 -0
  136. package/src/server/server-runtime.ts +240 -0
  137. package/src/server/spa/StartServer.tsx +40 -0
  138. package/src/server/spa/handler.ts +29 -0
  139. package/src/server/spa/index.tsx +5 -0
  140. package/src/server/types.ts +82 -0
  141. package/src/server/util.ts +12 -0
  142. package/src/shared/ErrorBoundary.tsx +52 -0
  143. package/src/shared/GET.ts +8 -0
  144. package/src/shared/HttpHeader.tsx +42 -0
  145. package/src/shared/HttpStatusCode.ts +27 -0
  146. package/src/shared/clientOnly.ts +44 -0
  147. package/src/shared/dev-overlay/CodeView.tsx +95 -0
  148. package/src/shared/dev-overlay/DevOverlayDialog.tsx +316 -0
  149. package/src/shared/dev-overlay/createStackFrame.ts +77 -0
  150. package/src/shared/dev-overlay/download.ts +6 -0
  151. package/src/shared/dev-overlay/env.d.ts +4 -0
  152. package/src/shared/dev-overlay/get-source-map.ts +35 -0
  153. package/src/shared/dev-overlay/icons.tsx +288 -0
  154. package/src/shared/dev-overlay/index.tsx +63 -0
  155. package/src/shared/dev-overlay/styles.css +292 -0
  156. package/src/shared/lazy.ts +51 -0
  157. package/src/shared/serverFunction.ts +10 -0
  158. package/src/virtual.d.ts +27 -0
  159. package/tsconfig.json +23 -0
  160. package/vitest.config.ts +9 -0
  161. package/config/fs-router.js +0 -142
  162. package/config/index.d.ts +0 -40
  163. package/config/index.js +0 -304
  164. package/config/server-components.js +0 -106
  165. package/dist/client/islands.d.ts +0 -7
  166. package/dist/client/islands.jsx +0 -10
  167. package/dist/middleware/index.jsx +0 -35
  168. package/dist/router/index.d.ts +0 -1
  169. package/dist/router/index.jsx +0 -2
  170. package/dist/router/lazyRoute.d.ts +0 -6
  171. package/dist/router/lazyRoute.js +0 -53
  172. package/dist/runtime/server-handler.d.ts +0 -2
  173. package/dist/runtime/server-runtime.d.ts +0 -3
  174. package/dist/server/islands/index.d.ts +0 -19
  175. package/dist/server/islands/index.jsx +0 -62
  176. package/dist/server/islands/utils.d.ts +0 -1
  177. package/dist/server/islands/utils.jsx +0 -85
  178. package/dist/server/pageEvent.d.ts +0 -2
  179. package/dist/server/pageEvent.js +0 -56
  180. package/dist/server/renderAsset.d.ts +0 -2
  181. package/env.d.ts +0 -26
  182. /package/dist/{router/FileRoutes.d.ts → router.d.ts} +0 -0
  183. /package/dist/shared/{clientOnly.jsx → clientOnly.js} +0 -0
  184. /package/dist/shared/{serverFunction.jsx → serverFunction.js} +0 -0
@@ -0,0 +1,109 @@
1
+ import { relative } from "node:path";
2
+ import { fileSystemWatcher } from "./fs-watcher.js";
3
+ import { treeShake } from "./tree-shake.js";
4
+ export const moduleId = "solid-start:routes";
5
+ export function fsRoutes({ routers }) {
6
+ globalThis.ROUTERS = routers;
7
+ return [
8
+ {
9
+ name: "solid-start-fs-routes",
10
+ enforce: "pre",
11
+ resolveId(id) {
12
+ if (id === moduleId)
13
+ return id;
14
+ },
15
+ async load(id) {
16
+ const root = this.environment.config.root;
17
+ const isBuild = this.environment.mode === "build";
18
+ if (id !== moduleId)
19
+ return;
20
+ const js = jsCode();
21
+ const router = globalThis.ROUTERS[this.environment.name];
22
+ const routes = await router.getRoutes();
23
+ let routesCode = JSON.stringify(routes ?? [], (k, v) => {
24
+ if (v === undefined)
25
+ return undefined;
26
+ if (k.startsWith("$$")) {
27
+ const buildId = `${v.src}?${v.pick.map((p) => `pick=${p}`).join("&")}`;
28
+ /**
29
+ * @type {{ [key: string]: string }}
30
+ */
31
+ const refs = {};
32
+ for (var pick of v.pick) {
33
+ refs[pick] = js.addNamedImport(pick, buildId);
34
+ }
35
+ return {
36
+ require: `_$() => ({ ${Object.entries(refs)
37
+ .map(([pick, namedImport]) => `'${pick}': ${namedImport}`)
38
+ .join(", ")} })$_`,
39
+ // src: isBuild ? relative(root, buildId) : buildId
40
+ };
41
+ }
42
+ else if (k.startsWith("$")) {
43
+ const buildId = `${v.src}?${v.pick.map((p) => `pick=${p}`).join("&")}`;
44
+ return {
45
+ src: relative(root, buildId),
46
+ build: isBuild
47
+ ? `_$() => import(/* @vite-ignore */ '${buildId}')$_`
48
+ : undefined,
49
+ import: `_$() => import(/* @vite-ignore */ '${buildId}')$_`
50
+ };
51
+ }
52
+ return v;
53
+ });
54
+ routesCode = routesCode.replaceAll('"_$(', "(").replaceAll(')$_"', ")");
55
+ const code = `
56
+ ${js.getImportStatements()}
57
+ export default ${routesCode}`;
58
+ return code;
59
+ },
60
+ },
61
+ treeShake(),
62
+ fileSystemWatcher(routers),
63
+ ];
64
+ }
65
+ function jsCode() {
66
+ const imports = new Map();
67
+ let vars = 0;
68
+ function addImport(p) {
69
+ let id = imports.get(p);
70
+ if (!id) {
71
+ id = {};
72
+ imports.set(p, id);
73
+ }
74
+ const d = "routeData" + vars++;
75
+ id["default"] = d;
76
+ return d;
77
+ }
78
+ function addNamedImport(name, p) {
79
+ let id = imports.get(p);
80
+ if (!id) {
81
+ id = {};
82
+ imports.set(p, id);
83
+ }
84
+ const d = "routeData" + vars++;
85
+ id[name] = d;
86
+ return d;
87
+ }
88
+ const getNamedExport = (p) => {
89
+ const id = imports.get(p);
90
+ delete id["default"];
91
+ return Object.keys(id).length > 0
92
+ ? `{ ${Object.keys(id)
93
+ .map((k) => `${k} as ${id[k]}`)
94
+ .join(", ")} }`
95
+ : "";
96
+ };
97
+ const getImportStatements = () => {
98
+ return `${[...imports.keys()]
99
+ .map((i) => `import ${imports.get(i).default
100
+ ? `${imports.get(i).default}${Object.keys(imports.get(i)).length > 1 ? ", " : ""}`
101
+ : ""} ${getNamedExport(i)} from '${i}';`)
102
+ .join("\n")}`;
103
+ };
104
+ return {
105
+ addImport,
106
+ addNamedImport,
107
+ getImportStatements,
108
+ };
109
+ }
@@ -0,0 +1,37 @@
1
+ import { pathToRegexp } from "path-to-regexp";
2
+ export { pathToRegexp };
3
+ export declare const glob: (path: string) => string[];
4
+ export type FileSystemRouterConfig = {
5
+ dir: string;
6
+ extensions: string[];
7
+ };
8
+ type Route = {
9
+ path: string;
10
+ } & Record<string, any>;
11
+ export declare function cleanPath(src: string, config: FileSystemRouterConfig): string;
12
+ export declare function analyzeModule(src: string): readonly [imports: readonly import("es-module-lexer").ImportSpecifier[], exports: readonly import("es-module-lexer").ExportSpecifier[], facade: boolean, hasModuleSyntax: boolean];
13
+ export declare class BaseFileSystemRouter extends EventTarget {
14
+ routes: Route[];
15
+ config: FileSystemRouterConfig;
16
+ /**
17
+ *
18
+ * @param {} config
19
+ */
20
+ constructor(config: FileSystemRouterConfig);
21
+ glob(): string;
22
+ buildRoutes(): Promise<any[]>;
23
+ isRoute(src: string): boolean;
24
+ toPath(src: string): void;
25
+ toRoute(src: string): Route | undefined;
26
+ /**
27
+ * To be attached by vite plugin to the vite dev server
28
+ */
29
+ update: undefined;
30
+ _addRoute(route: Route): void;
31
+ addRoute(src: string): Promise<void>;
32
+ reload(route: string): void;
33
+ updateRoute(src: string): Promise<void>;
34
+ removeRoute(src: string): void;
35
+ buildRoutesPromise?: Promise<any[]>;
36
+ getRoutes(): Promise<Route[]>;
37
+ }
@@ -0,0 +1,136 @@
1
+ import { init } from "es-module-lexer";
2
+ import { parse } from "es-module-lexer";
3
+ import esbuild from "esbuild";
4
+ import fg from "fast-glob";
5
+ import fs from "fs";
6
+ import micromatch from "micromatch";
7
+ import { posix } from "path";
8
+ import { pathToRegexp } from "path-to-regexp";
9
+ import { normalize } from "node:path";
10
+ export { pathToRegexp };
11
+ export const glob = (path) => fg.sync(path, { absolute: true });
12
+ export function cleanPath(src, config) {
13
+ return src
14
+ .slice(config.dir.length)
15
+ .replace(new RegExp(`\.(${(config.extensions ?? []).join("|")})$`), "");
16
+ }
17
+ export function analyzeModule(src) {
18
+ return parse(esbuild.transformSync(fs.readFileSync(src, "utf-8"), {
19
+ jsx: "transform",
20
+ format: "esm",
21
+ loader: "tsx"
22
+ }).code, src);
23
+ }
24
+ export class BaseFileSystemRouter extends EventTarget {
25
+ routes;
26
+ config;
27
+ /**
28
+ *
29
+ * @param {} config
30
+ */
31
+ constructor(config) {
32
+ super();
33
+ this.routes = [];
34
+ this.config = config;
35
+ }
36
+ glob() {
37
+ return (posix.join(fg.convertPathToPattern(this.config.dir), "**/*") +
38
+ `.{${this.config.extensions.join(",")}}`);
39
+ }
40
+ async buildRoutes() {
41
+ await init;
42
+ for (var src of glob(this.glob())) {
43
+ await this.addRoute(src);
44
+ }
45
+ return this.routes;
46
+ }
47
+ isRoute(src) {
48
+ return Boolean(micromatch(src, this.glob())?.length);
49
+ }
50
+ toPath(src) {
51
+ throw new Error("Not implemented");
52
+ }
53
+ toRoute(src) {
54
+ let path = this.toPath(src);
55
+ if (path === undefined)
56
+ return;
57
+ const [_, exports] = analyzeModule(src);
58
+ if (!exports.find(e => e.n === "default")) {
59
+ console.warn("No default export", src);
60
+ }
61
+ return {
62
+ $component: {
63
+ src: src,
64
+ pick: ["default", "$css"]
65
+ },
66
+ path
67
+ // filePath: src
68
+ };
69
+ }
70
+ /**
71
+ * To be attached by vite plugin to the vite dev server
72
+ */
73
+ update = undefined;
74
+ _addRoute(route) {
75
+ this.routes = this.routes.filter(r => r.path !== route.path);
76
+ this.routes.push(route);
77
+ }
78
+ async addRoute(src) {
79
+ src = normalize(src);
80
+ if (this.isRoute(src)) {
81
+ try {
82
+ const route = this.toRoute(src);
83
+ if (route) {
84
+ this._addRoute(route);
85
+ this.reload(route.path);
86
+ }
87
+ }
88
+ catch (e) {
89
+ console.error(e);
90
+ }
91
+ }
92
+ }
93
+ reload(route) {
94
+ this.dispatchEvent(new Event("reload", {
95
+ // @ts-ignore
96
+ detail: {
97
+ route
98
+ }
99
+ }));
100
+ }
101
+ async updateRoute(src) {
102
+ src = normalize(src);
103
+ if (this.isRoute(src)) {
104
+ try {
105
+ const route = this.toRoute(src);
106
+ if (route) {
107
+ this._addRoute(route);
108
+ this.reload(route.path);
109
+ }
110
+ }
111
+ catch (e) {
112
+ console.error(e);
113
+ }
114
+ // this.update?.();
115
+ }
116
+ }
117
+ removeRoute(src) {
118
+ src = normalize(src);
119
+ if (this.isRoute(src)) {
120
+ const path = this.toPath(src);
121
+ if (path === undefined) {
122
+ return;
123
+ }
124
+ this.routes = this.routes.filter(r => r.path !== path);
125
+ this.dispatchEvent(new Event("reload", {}));
126
+ }
127
+ }
128
+ buildRoutesPromise;
129
+ async getRoutes() {
130
+ if (!this.buildRoutesPromise) {
131
+ this.buildRoutesPromise = this.buildRoutes();
132
+ }
133
+ await this.buildRoutesPromise;
134
+ return this.routes;
135
+ }
136
+ }
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "vite";
2
+ export declare function treeShake(): Plugin;
@@ -0,0 +1,357 @@
1
+ // All credit for this work goes to the amazing Next.js team.
2
+ // https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform.ts
3
+ // This is adapted to work with routeData functions. It can be run in two modes, one which preserves the routeData and the Component in the same file, and one which creates a
4
+ import { basename } from "pathe";
5
+ function treeShakeTransform({ types: t }) {
6
+ function getIdentifier(path) {
7
+ const parentPath = path.parentPath;
8
+ if (parentPath.type === "VariableDeclarator") {
9
+ const pp = parentPath;
10
+ const name = pp.get("id");
11
+ return name.node.type === "Identifier" ? name : null;
12
+ }
13
+ if (parentPath.type === "AssignmentExpression") {
14
+ const pp = parentPath;
15
+ const name = pp.get("left");
16
+ return name.node.type === "Identifier" ? name : null;
17
+ }
18
+ if (path.node.type === "ArrowFunctionExpression") {
19
+ return null;
20
+ }
21
+ return path.node.id && path.node.id.type === "Identifier"
22
+ ? path.get("id")
23
+ : null;
24
+ }
25
+ function isIdentifierReferenced(ident) {
26
+ const b = ident.scope.getBinding(ident.node.name);
27
+ if (b?.referenced) {
28
+ if (b.path.type === "FunctionDeclaration") {
29
+ return !b.constantViolations
30
+ .concat(b.referencePaths)
31
+ .every((ref) => ref.findParent((p) => p === b.path));
32
+ }
33
+ return true;
34
+ }
35
+ return false;
36
+ }
37
+ function markFunction(path, state) {
38
+ const ident = getIdentifier(path);
39
+ if (ident && ident.node && isIdentifierReferenced(ident)) {
40
+ state.refs.add(ident);
41
+ }
42
+ }
43
+ function markImport(path, state) {
44
+ const local = path.get("local");
45
+ if (isIdentifierReferenced(local)) {
46
+ state.refs.add(local);
47
+ }
48
+ }
49
+ return {
50
+ visitor: {
51
+ Program: {
52
+ enter(path, state) {
53
+ state.refs = new Set();
54
+ state.done = false;
55
+ path.traverse({
56
+ VariableDeclarator(variablePath, variableState) {
57
+ if (variablePath.node.id.type === "Identifier") {
58
+ const local = variablePath.get("id");
59
+ if (isIdentifierReferenced(local)) {
60
+ variableState.refs.add(local);
61
+ }
62
+ }
63
+ else if (variablePath.node.id.type === "ObjectPattern") {
64
+ const pattern = variablePath.get("id");
65
+ const properties = pattern.get("properties");
66
+ properties.forEach((p) => {
67
+ const local = p.get(p.node.type === "ObjectProperty"
68
+ ? "value"
69
+ : p.node.type === "RestElement"
70
+ ? "argument"
71
+ : (() => {
72
+ throw new Error("invariant");
73
+ })());
74
+ if (isIdentifierReferenced(local)) {
75
+ variableState.refs.add(local);
76
+ }
77
+ });
78
+ }
79
+ else if (variablePath.node.id.type === "ArrayPattern") {
80
+ const pattern = variablePath.get("id");
81
+ const elements = pattern.get("elements");
82
+ elements.forEach((e) => {
83
+ let local;
84
+ if (e.node && e.node.type === "Identifier") {
85
+ local = e;
86
+ }
87
+ else if (e.node && e.node.type === "RestElement") {
88
+ local = e.get("argument");
89
+ }
90
+ else {
91
+ return;
92
+ }
93
+ if (isIdentifierReferenced(local)) {
94
+ variableState.refs.add(local);
95
+ }
96
+ });
97
+ }
98
+ },
99
+ ExportDefaultDeclaration(exportNamedPath) {
100
+ // if opts.keep is true, we don't remove the routeData export
101
+ if (state.opts.pick && !state.opts.pick.includes("default")) {
102
+ exportNamedPath.remove();
103
+ }
104
+ },
105
+ ExportNamedDeclaration(exportNamedPath) {
106
+ // if opts.keep is false, we don't remove the routeData export
107
+ if (!state.opts.pick) {
108
+ return;
109
+ }
110
+ const specifiers = exportNamedPath.get("specifiers");
111
+ if (specifiers.length) {
112
+ specifiers.forEach((s) => {
113
+ if (t.isIdentifier(s.node.exported)
114
+ ? s.node.exported.name
115
+ : state.opts.pick.includes(s.node.exported.value)) {
116
+ s.remove();
117
+ }
118
+ });
119
+ if (exportNamedPath.node.specifiers.length < 1) {
120
+ exportNamedPath.remove();
121
+ }
122
+ return;
123
+ }
124
+ const decl = exportNamedPath.get("declaration");
125
+ if (decl == null || decl.node == null) {
126
+ return;
127
+ }
128
+ switch (decl.node.type) {
129
+ case "FunctionDeclaration": {
130
+ const name = decl.node.id?.name;
131
+ if (name &&
132
+ state.opts.pick &&
133
+ !state.opts.pick.includes(name)) {
134
+ exportNamedPath.remove();
135
+ }
136
+ break;
137
+ }
138
+ case "VariableDeclaration": {
139
+ const inner = decl.get("declarations");
140
+ inner.forEach((d) => {
141
+ if (d.node.id.type !== "Identifier") {
142
+ return;
143
+ }
144
+ const name = d.node.id.name;
145
+ if (state.opts.pick && !state.opts.pick.includes(name)) {
146
+ d.remove();
147
+ }
148
+ });
149
+ break;
150
+ }
151
+ default: {
152
+ break;
153
+ }
154
+ }
155
+ },
156
+ FunctionDeclaration: markFunction,
157
+ FunctionExpression: markFunction,
158
+ ArrowFunctionExpression: markFunction,
159
+ ImportSpecifier: markImport,
160
+ ImportDefaultSpecifier: markImport,
161
+ ImportNamespaceSpecifier: markImport,
162
+ ImportDeclaration: (path, state) => {
163
+ if (path.node.source.value.endsWith(".css") &&
164
+ state.opts.pick &&
165
+ !state.opts.pick.includes("$css")) {
166
+ path.remove();
167
+ }
168
+ },
169
+ }, state);
170
+ const refs = state.refs;
171
+ let count = 0;
172
+ const sweepFunction = (sweepPath) => {
173
+ const ident = getIdentifier(sweepPath);
174
+ if (ident &&
175
+ ident.node &&
176
+ refs.has(ident) &&
177
+ !isIdentifierReferenced(ident)) {
178
+ ++count;
179
+ if (t.isAssignmentExpression(sweepPath.parentPath) ||
180
+ t.isVariableDeclarator(sweepPath.parentPath)) {
181
+ sweepPath.parentPath.remove();
182
+ }
183
+ else {
184
+ sweepPath.remove();
185
+ }
186
+ }
187
+ };
188
+ function sweepImport(sweepPath) {
189
+ const local = sweepPath.get("local");
190
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
191
+ ++count;
192
+ sweepPath.remove();
193
+ if (sweepPath.parent.specifiers.length === 0) {
194
+ sweepPath.parentPath.remove();
195
+ }
196
+ }
197
+ }
198
+ do {
199
+ path.scope.crawl();
200
+ count = 0;
201
+ path.traverse({
202
+ VariableDeclarator(variablePath) {
203
+ if (variablePath.node.id.type === "Identifier") {
204
+ const local = variablePath.get("id");
205
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
206
+ ++count;
207
+ variablePath.remove();
208
+ }
209
+ }
210
+ else if (variablePath.node.id.type === "ObjectPattern") {
211
+ const pattern = variablePath.get("id");
212
+ const beforeCount = count;
213
+ const properties = pattern.get("properties");
214
+ properties.forEach((p) => {
215
+ const local = p.get(p.node.type === "ObjectProperty"
216
+ ? "value"
217
+ : p.node.type === "RestElement"
218
+ ? "argument"
219
+ : (() => {
220
+ throw new Error("invariant");
221
+ })());
222
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
223
+ ++count;
224
+ p.remove();
225
+ }
226
+ });
227
+ if (beforeCount !== count &&
228
+ pattern.get("properties").length < 1) {
229
+ variablePath.remove();
230
+ }
231
+ }
232
+ else if (variablePath.node.id.type === "ArrayPattern") {
233
+ const pattern = variablePath.get("id");
234
+ const beforeCount = count;
235
+ const elements = pattern.get("elements");
236
+ elements.forEach((e) => {
237
+ let local;
238
+ if (e.node && e.node.type === "Identifier") {
239
+ local = e;
240
+ }
241
+ else if (e.node && e.node.type === "RestElement") {
242
+ local = e.get("argument");
243
+ }
244
+ else {
245
+ return;
246
+ }
247
+ if (refs.has(local) && !isIdentifierReferenced(local)) {
248
+ ++count;
249
+ e.remove();
250
+ }
251
+ });
252
+ if (beforeCount !== count &&
253
+ pattern.get("elements").length < 1) {
254
+ variablePath.remove();
255
+ }
256
+ }
257
+ },
258
+ FunctionDeclaration: sweepFunction,
259
+ FunctionExpression: sweepFunction,
260
+ ArrowFunctionExpression: sweepFunction,
261
+ ImportSpecifier: sweepImport,
262
+ ImportDefaultSpecifier: sweepImport,
263
+ ImportNamespaceSpecifier: sweepImport,
264
+ });
265
+ } while (count);
266
+ },
267
+ },
268
+ },
269
+ };
270
+ }
271
+ export function treeShake() {
272
+ let config;
273
+ const cache = {};
274
+ let server;
275
+ async function transform(id, code) {
276
+ const [path, queryString] = id.split("?");
277
+ const query = new URLSearchParams(queryString);
278
+ if (query.has("pick")) {
279
+ const babel = await import("@babel/core");
280
+ const transformed = await babel.transformAsync(code, {
281
+ plugins: [[treeShakeTransform, { pick: query.getAll("pick") }]],
282
+ parserOpts: {
283
+ plugins: ["jsx", "typescript"],
284
+ },
285
+ filename: basename(id),
286
+ ast: false,
287
+ sourceMaps: true,
288
+ configFile: false,
289
+ babelrc: false,
290
+ sourceFileName: id,
291
+ });
292
+ return transformed;
293
+ }
294
+ }
295
+ return {
296
+ name: "tree-shake",
297
+ enforce: "pre",
298
+ configResolved(resolvedConfig) {
299
+ config = resolvedConfig;
300
+ },
301
+ configureServer(s) {
302
+ server = s;
303
+ },
304
+ async handleHotUpdate(ctx) {
305
+ if (cache[ctx.file]) {
306
+ const mods = [];
307
+ const newCode = await ctx.read();
308
+ for (const [id, code] of Object.entries(cache[ctx.file])) {
309
+ const transformed = await transform(id, newCode);
310
+ if (!transformed)
311
+ continue;
312
+ const { code: transformedCode } = transformed;
313
+ if (transformedCode !== code) {
314
+ const mod = server.moduleGraph.getModuleById(id);
315
+ if (mod)
316
+ mods.push(mod);
317
+ }
318
+ cache[ctx.file] ??= {};
319
+ cache[ctx.file][id] = transformedCode;
320
+ // server.moduleGraph.setModuleSource(id, code);
321
+ }
322
+ return mods;
323
+ }
324
+ // const mods = [];
325
+ // [...server.moduleGraph.urlToModuleMap.entries()].forEach(([url, m]) => {
326
+ // if (m.file === ctx.file && m.id.includes("pick=")) {
327
+ // if (!m.id.includes("pick=loader")) {
328
+ // mods.push(m);
329
+ // }
330
+ // }
331
+ // });
332
+ // return mods;
333
+ // // this.router.updateRoute(ctx.path);
334
+ // }
335
+ },
336
+ async transform(code, id) {
337
+ const [path, queryString] = id.split("?");
338
+ if (!path)
339
+ return;
340
+ const query = new URLSearchParams(queryString);
341
+ const ext = path.split(".").pop();
342
+ if (!ext)
343
+ return;
344
+ if (query.has("pick") && ["js", "jsx", "ts", "tsx"].includes(ext)) {
345
+ const transformed = await transform(id, code);
346
+ if (!transformed?.code)
347
+ return;
348
+ cache[path] ??= {};
349
+ cache[path][id] = transformed.code;
350
+ return {
351
+ code: transformed.code,
352
+ map: transformed.map,
353
+ };
354
+ }
355
+ },
356
+ };
357
+ }
@@ -0,0 +1,10 @@
1
+ import { type PluginOption } from "vite";
2
+ import { type Options as SolidOptions } from "vite-plugin-solid";
3
+ export interface SolidStartOptions {
4
+ solid?: Partial<SolidOptions>;
5
+ ssr?: boolean;
6
+ routeDir?: string;
7
+ extensions?: string[];
8
+ middleware?: string;
9
+ }
10
+ export declare function solidStart(options?: SolidStartOptions): Array<PluginOption>;