@solidjs/start 2.0.0-rc.2 → 2.0.0-rc.4
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 +18 -0
- package/dist/config/env.js +2 -2
- package/dist/config/fs-routes/tree-shake.js +5 -0
- package/dist/config/index.d.ts +78 -3
- package/dist/config/manifest.js +3 -2
- package/dist/directives/remove-unused-variables.js +2 -2
- package/dist/directives/xxhash32.js +5 -13
- package/dist/fns/handler.js +9 -8
- package/dist/fns/serialization.js +21 -1
- package/dist/server/assets/render.jsx +1 -1
- package/dist/server/handler.d.ts +3 -4
- package/dist/server/handler.js +3 -43
- package/dist/server/index.d.ts +1 -1
- package/dist/server/spa/handler.d.ts +2 -3
- 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/clientOnly.js +3 -1
- package/dist/shared/dev-toolbar/error-viewer/CodeView.jsx +1 -1
- package/dist/shared/dev-toolbar/functions/BlobViewer.css +1 -1
- package/dist/shared/dev-toolbar/functions/BlobViewer.d.ts +2 -2
- package/dist/shared/dev-toolbar/functions/BlobViewer.jsx +7 -11
- package/dist/shared/dev-toolbar/functions/FormDataViewer.d.ts +1 -1
- package/dist/shared/dev-toolbar/functions/FormDataViewer.jsx +7 -11
- package/dist/shared/dev-toolbar/functions/HeadersViewer.d.ts +1 -1
- package/dist/shared/dev-toolbar/functions/HeadersViewer.jsx +2 -2
- package/dist/shared/dev-toolbar/functions/HexViewer.d.ts +1 -1
- package/dist/shared/dev-toolbar/functions/HexViewer.jsx +7 -15
- package/dist/shared/dev-toolbar/functions/SerovalValue.css +0 -2
- package/dist/shared/dev-toolbar/functions/SerovalValue.d.ts +1 -1
- package/dist/shared/dev-toolbar/functions/SerovalValue.jsx +3 -3
- package/dist/shared/dev-toolbar/functions/SerovalViewer.css +0 -1
- package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.d.ts +1 -1
- package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.jsx +5 -7
- package/dist/shared/dev-toolbar/functions/styles.css +0 -1
- package/dist/shared/dev-toolbar/index.jsx +5 -0
- package/dist/shared/ui/Badge.css +0 -1
- package/dist/shared/ui/Badge.d.ts +3 -3
- package/dist/shared/ui/Badge.jsx +3 -3
- package/dist/shared/ui/Button.jsx +1 -1
- package/dist/shared/ui/Cascade.jsx +3 -3
- package/dist/shared/ui/Dialog.css +1 -2
- package/dist/shared/ui/Dialog.jsx +3 -3
- package/dist/shared/ui/IconButton.jsx +1 -1
- package/dist/shared/ui/Placeholder.css +1 -1
- package/dist/shared/ui/Placeholder.d.ts +2 -2
- package/dist/shared/ui/Placeholder.jsx +2 -4
- package/dist/shared/ui/Section.css +0 -1
- package/dist/shared/ui/Section.d.ts +2 -2
- package/dist/shared/ui/Section.jsx +3 -5
- package/dist/shared/ui/Select.jsx +3 -3
- package/dist/shared/ui/Table.d.ts +6 -6
- package/dist/shared/ui/Table.jsx +5 -5
- package/dist/shared/ui/Tabs.jsx +4 -4
- package/dist/shared/ui/Text.css +7 -3
- package/dist/shared/ui/Text.d.ts +8 -8
- package/dist/shared/ui/Text.jsx +9 -9
- package/package.json +27 -27
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @solidjs/start
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b6dfaac: Updated dependencies, including `cookie-es` to 3, `shiki` to 4, `srvx` to 0.12.4, `oxc-parser` to 0.141 and `seroval` to 1.5.6. `parseSetCookie` now returns `undefined` for cookies with a forbidden name or an empty name and value, and those cookies are no longer forwarded to nested server function requests.
|
|
8
|
+
- 02cd41e: Stop the dev toolbar from reporting benign `ResizeObserver loop` notifications as application errors. Browsers dispatch these as window `error` events carrying no error object, so the toolbar was capturing the raw `ErrorEvent` and force-opening the error panel over the app on every resize.
|
|
9
|
+
- d3c2af2: Don't send server error stack traces to the client in production builds. When a server function throws, the error is serialized and rethrown on the client, and seroval included `Error.prototype.stack` by default, leaking server file paths and internal function names. Stacks are still serialized in development.
|
|
10
|
+
|
|
11
|
+
## 2.0.0-rc.3
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- d9018d6: fix(types): add missing properties to `SolidStartOptions` and expose them via Vite plugin configuration
|
|
16
|
+
- e26cef0: Fix TS2883/TS2742 when emitting declarations for `entry-server.tsx`. `createHandler` now returns `StartHandler`, a type owned by `@solidjs/start`, instead of h3's `H3`, so the inferred type of `export default createHandler(...)` no longer has to be named through a nested `node_modules/@solidjs/start/node_modules/h3` path.
|
|
17
|
+
- 7c8dbe6: keep TypeScript namespace members in route files during production builds
|
|
18
|
+
- b3c7aaf: Update `h3` to `2.0.1-rc.26`.
|
|
19
|
+
- b3c7aaf: Fixed event response status and headers set during server-side rendering with deferred async resources, not being applied on the outgoing response.
|
|
20
|
+
|
|
3
21
|
## 2.0.0-rc.2
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
package/dist/config/env.js
CHANGED
|
@@ -58,13 +58,13 @@ export function envPlugin(options) {
|
|
|
58
58
|
}
|
|
59
59
|
const vars = currentOptions.server?.load
|
|
60
60
|
? currentOptions.server.load(env)
|
|
61
|
-
: loadEnv(env,
|
|
61
|
+
: loadEnv(env, ".", serverPrefix);
|
|
62
62
|
return convertObjectToModule(vars);
|
|
63
63
|
}
|
|
64
64
|
if (filename === CLIENT_ENV) {
|
|
65
65
|
const vars = currentOptions.client?.load
|
|
66
66
|
? currentOptions.client.load(env)
|
|
67
|
-
: loadEnv(env,
|
|
67
|
+
: loadEnv(env, ".", clientPrefix);
|
|
68
68
|
return convertObjectToModule(vars);
|
|
69
69
|
}
|
|
70
70
|
if (filename === SERVER_RUNTIME_LOADER) {
|
|
@@ -133,6 +133,11 @@ function treeShakeTransform({ types: t }) {
|
|
|
133
133
|
if (!state.opts.pick) {
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
+
// Only module-level exports are route exports; `export` inside a
|
|
137
|
+
// TS namespace/module block is unrelated to the pick list.
|
|
138
|
+
if (!exportNamedPath.parentPath.isProgram()) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
136
141
|
const specifiers = exportNamedPath.get("specifiers");
|
|
137
142
|
if (specifiers.length) {
|
|
138
143
|
specifiers.forEach(s => {
|
package/dist/config/index.d.ts
CHANGED
|
@@ -2,24 +2,99 @@ import type { PluginOption } from "vite";
|
|
|
2
2
|
import { type Options as SolidOptions } from "vite-plugin-solid";
|
|
3
3
|
import { type ServerFunctionsOptions } from "../directives/index.ts";
|
|
4
4
|
import { type EnvPluginOptions } from "./env.ts";
|
|
5
|
+
/**
|
|
6
|
+
* Configuration options for SolidStart. (previously in `app.config.ts`)
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.solidjs.com/solid-start/v2/migrating-from-v1#move-framework-configuration-into-viteconfigts
|
|
9
|
+
*/
|
|
5
10
|
export interface SolidStartOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Path to the root of the application (where `app.tsx` / `app.jsx` lives).
|
|
13
|
+
*
|
|
14
|
+
* @default "./src"
|
|
15
|
+
*/
|
|
16
|
+
appRoot?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Options forwarded to `vite-plugin-solid`.
|
|
19
|
+
*
|
|
20
|
+
* @see https://github.com/solidjs/vite-plugin-solid#api
|
|
21
|
+
*/
|
|
6
22
|
solid?: Partial<SolidOptions>;
|
|
23
|
+
/**
|
|
24
|
+
* Enable or disable server-side rendering.
|
|
25
|
+
*
|
|
26
|
+
* - `true` — SSR (default)
|
|
27
|
+
* - `false` — client-side rendering only (SPA mode)
|
|
28
|
+
*
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
7
31
|
ssr?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Show the SolidStart development overlay (error overlay, etc.) in development.
|
|
34
|
+
*
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
devOverlay?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Experimental features.
|
|
40
|
+
*/
|
|
41
|
+
experimental?: {
|
|
42
|
+
/**
|
|
43
|
+
* Enable islands architecture mode.
|
|
44
|
+
*
|
|
45
|
+
* Currently fixed to `false` (not yet fully supported).
|
|
46
|
+
*
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
islands?: false;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Directory containing file-system routes, relative to {@link appRoot}.
|
|
53
|
+
*
|
|
54
|
+
* @default "./routes"
|
|
55
|
+
*/
|
|
8
56
|
routeDir?: string;
|
|
57
|
+
/**
|
|
58
|
+
* File extensions that should be treated as routes.
|
|
59
|
+
*
|
|
60
|
+
* @default ["js", "jsx", "ts", "tsx"]
|
|
61
|
+
*/
|
|
9
62
|
extensions?: string[];
|
|
63
|
+
/**
|
|
64
|
+
* Path to an optional middleware module.
|
|
65
|
+
*
|
|
66
|
+
* The module should export a middleware created with `createMiddleware`
|
|
67
|
+
* from `@solidjs/start/middleware`.
|
|
68
|
+
*
|
|
69
|
+
* @example "src/middleware/index.ts"
|
|
70
|
+
*/
|
|
10
71
|
middleware?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Serialization settings for server-function / action payloads
|
|
74
|
+
* that cross the server-client boundary.
|
|
75
|
+
*/
|
|
11
76
|
serialization?: {
|
|
12
77
|
/**
|
|
13
78
|
* The serialization mode to use for server functions/actions.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
79
|
+
*
|
|
80
|
+
* - `"js"` — Uses a custom binary format (Seroval) that is more efficient
|
|
81
|
+
* than JSON, but requires a custom deserializer (with `eval()`) on the client.
|
|
82
|
+
* A strong CSP that blocks `eval()` will prevent this mode from working.
|
|
83
|
+
* - `"json"` — Uses JSON for serialization. Less efficient / larger payloads,
|
|
84
|
+
* but can be deserialized with `JSON.parse` on the client and is CSP-friendly.
|
|
17
85
|
*
|
|
18
86
|
* @default "json"
|
|
19
87
|
*/
|
|
20
88
|
mode?: "js" | "json";
|
|
21
89
|
};
|
|
90
|
+
/**
|
|
91
|
+
* Configures plugin behavior per build environment
|
|
92
|
+
*/
|
|
22
93
|
env?: EnvPluginOptions;
|
|
94
|
+
/**
|
|
95
|
+
* Options controlling which files are processed as server functions
|
|
96
|
+
* (inclusion / exclusion filters for the `"use server"` transform).
|
|
97
|
+
*/
|
|
23
98
|
serverFunctions?: Pick<ServerFunctionsOptions, "filter">;
|
|
24
99
|
}
|
|
25
100
|
export declare function solidStart(options?: SolidStartOptions): Array<PluginOption>;
|
package/dist/config/manifest.js
CHANGED
|
@@ -40,7 +40,7 @@ export function manifest(start) {
|
|
|
40
40
|
if (!entry)
|
|
41
41
|
throw new Error("No client entry found");
|
|
42
42
|
let rawManifest;
|
|
43
|
-
const viteMajor = parseInt(viteVersion.split(
|
|
43
|
+
const viteMajor = parseInt(viteVersion.split(".")[0], 10);
|
|
44
44
|
const manifestKey = Object.keys(globalThis.START_CLIENT_BUNDLE).find(k => k.endsWith("manifest.json"));
|
|
45
45
|
if (manifestKey && viteMajor < 8) {
|
|
46
46
|
const manifestAsset = globalThis.START_CLIENT_BUNDLE[manifestKey];
|
|
@@ -53,7 +53,8 @@ export function manifest(start) {
|
|
|
53
53
|
if (devServer?.environments?.client?.config?.build?.outDir) {
|
|
54
54
|
outDir = devServer.environments.client.config.build.outDir;
|
|
55
55
|
}
|
|
56
|
-
else if (this.environment?.config?.build?.outDir &&
|
|
56
|
+
else if (this.environment?.config?.build?.outDir &&
|
|
57
|
+
this.environment?.config?.consumer === "client") {
|
|
57
58
|
outDir = this.environment.config.build.outDir;
|
|
58
59
|
}
|
|
59
60
|
else if (globalThis.START_CLIENT_OUT_DIR) {
|
|
@@ -8,7 +8,7 @@ function isInvalidForRemoval(path) {
|
|
|
8
8
|
// This one is for destructured variables
|
|
9
9
|
let target = path;
|
|
10
10
|
if (isPathValid(path, t.isVariableDeclarator)) {
|
|
11
|
-
target = path.get(
|
|
11
|
+
target = path.get("id");
|
|
12
12
|
}
|
|
13
13
|
return isPathValid(target, t.isObjectPattern) || isPathValid(target, t.isArrayPattern);
|
|
14
14
|
}
|
|
@@ -42,7 +42,7 @@ export function removeUnusedVariables(program) {
|
|
|
42
42
|
}
|
|
43
43
|
dirty = true;
|
|
44
44
|
}
|
|
45
|
-
else if (!
|
|
45
|
+
else if (!isInvalidForRemoval(binding.path)) {
|
|
46
46
|
binding.path.remove();
|
|
47
47
|
dirty = true;
|
|
48
48
|
}
|
|
@@ -34,7 +34,7 @@ function toUtf8(text) {
|
|
|
34
34
|
* @param seed - optional seed (32-bit unsigned);
|
|
35
35
|
*/
|
|
36
36
|
export default function xxHash32(buffer, seed = 0) {
|
|
37
|
-
buffer = typeof buffer ===
|
|
37
|
+
buffer = typeof buffer === "string" ? toUtf8(buffer) : buffer;
|
|
38
38
|
const b = buffer;
|
|
39
39
|
/*
|
|
40
40
|
Step 1. Initialize internal accumulators
|
|
@@ -144,9 +144,7 @@ export default function xxHash32(buffer, seed = 0) {
|
|
|
144
144
|
const laneP = laneN0 * PRIME32_3 + ((laneN1 * PRIME32_3) << 16);
|
|
145
145
|
acc = (acc + laneP) & 0xffffffff;
|
|
146
146
|
acc = (acc << 17) | (acc >>> 15);
|
|
147
|
-
acc =
|
|
148
|
-
((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) &
|
|
149
|
-
0xffffffff;
|
|
147
|
+
acc = ((acc & 0xffff) * PRIME32_4 + (((acc >>> 16) * PRIME32_4) << 16)) & 0xffffffff;
|
|
150
148
|
}
|
|
151
149
|
/*
|
|
152
150
|
```
|
|
@@ -162,9 +160,7 @@ export default function xxHash32(buffer, seed = 0) {
|
|
|
162
160
|
const lane = b[offset];
|
|
163
161
|
acc += lane * PRIME32_5;
|
|
164
162
|
acc = (acc << 11) | (acc >>> 21);
|
|
165
|
-
acc =
|
|
166
|
-
((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) &
|
|
167
|
-
0xffffffff;
|
|
163
|
+
acc = ((acc & 0xffff) * PRIME32_1 + (((acc >>> 16) * PRIME32_1) << 16)) & 0xffffffff;
|
|
168
164
|
}
|
|
169
165
|
/*
|
|
170
166
|
Step 6. Final mix (avalanche)
|
|
@@ -180,13 +176,9 @@ export default function xxHash32(buffer, seed = 0) {
|
|
|
180
176
|
```
|
|
181
177
|
*/
|
|
182
178
|
acc ^= acc >>> 15;
|
|
183
|
-
acc =
|
|
184
|
-
(((acc & 0xffff) * PRIME32_2) & 0xffffffff) +
|
|
185
|
-
(((acc >>> 16) * PRIME32_2) << 16);
|
|
179
|
+
acc = (((acc & 0xffff) * PRIME32_2) & 0xffffffff) + (((acc >>> 16) * PRIME32_2) << 16);
|
|
186
180
|
acc ^= acc >>> 13;
|
|
187
|
-
acc =
|
|
188
|
-
(((acc & 0xffff) * PRIME32_3) & 0xffffffff) +
|
|
189
|
-
(((acc >>> 16) * PRIME32_3) << 16);
|
|
181
|
+
acc = (((acc & 0xffff) * PRIME32_3) & 0xffffffff) + (((acc >>> 16) * PRIME32_3) << 16);
|
|
190
182
|
acc ^= acc >>> 16;
|
|
191
183
|
// turn any negatives back into a positive number;
|
|
192
184
|
return acc < 0 ? acc + 4294967296 : acc;
|
package/dist/fns/handler.js
CHANGED
|
@@ -132,8 +132,7 @@ export async function handleServerFunction(h3Event) {
|
|
|
132
132
|
if (x.headers)
|
|
133
133
|
mergeResponseHeaders(h3Event, x.headers);
|
|
134
134
|
// forward non-redirect statuses
|
|
135
|
-
if (x.status &&
|
|
136
|
-
(!instance || x.status < 300 || x.status >= 400))
|
|
135
|
+
if (x.status && (!instance || x.status < 300 || x.status >= 400))
|
|
137
136
|
h3Event.res.status = x.status;
|
|
138
137
|
if (x.customBody) {
|
|
139
138
|
x = await x.customBody();
|
|
@@ -204,10 +203,7 @@ function handleNoJS(result, request, parsed, thrown) {
|
|
|
204
203
|
result: isError ? result.message : result,
|
|
205
204
|
thrown: thrown,
|
|
206
205
|
error: isError,
|
|
207
|
-
input: [
|
|
208
|
-
...parsed.slice(0, -1),
|
|
209
|
-
[...parsed[parsed.length - 1].entries()],
|
|
210
|
-
],
|
|
206
|
+
input: [...parsed.slice(0, -1), [...parsed[parsed.length - 1].entries()]],
|
|
211
207
|
}))}; Secure; HttpOnly;`);
|
|
212
208
|
}
|
|
213
209
|
return new Response(null, {
|
|
@@ -229,10 +225,15 @@ export function createSingleFlightHeaders(sourceEvent) {
|
|
|
229
225
|
// useH3Internals = true;
|
|
230
226
|
// sourceEvent.nativeEvent.node.req.headers.cookie = "";
|
|
231
227
|
// }
|
|
232
|
-
SetCookies.forEach(
|
|
228
|
+
SetCookies.forEach(cookie => {
|
|
233
229
|
if (!cookie)
|
|
234
230
|
return;
|
|
235
|
-
|
|
231
|
+
// `parseSetCookie` returns undefined for forbidden cookie names and for
|
|
232
|
+
// cookies with an empty name and value.
|
|
233
|
+
const parsed = parseSetCookie(cookie);
|
|
234
|
+
if (!parsed)
|
|
235
|
+
return;
|
|
236
|
+
const { maxAge, expires, name, value } = parsed;
|
|
236
237
|
if (maxAge != null && maxAge <= 0) {
|
|
237
238
|
delete cookies[name];
|
|
238
239
|
return;
|
|
@@ -16,6 +16,25 @@ const DEFAULT_PLUGINS = [
|
|
|
16
16
|
];
|
|
17
17
|
const MAX_SERIALIZATION_DEPTH_LIMIT = 64;
|
|
18
18
|
const DISABLED_FEATURES = Feature.RegExp;
|
|
19
|
+
/**
|
|
20
|
+
* An error thrown by a server function is serialized and rethrown on the
|
|
21
|
+
* client, and seroval includes `Error.prototype.stack` by default. In
|
|
22
|
+
* production that leaks server file paths, internal function names and the
|
|
23
|
+
* shape of the deployment to anyone who can trigger a throw, so strip it.
|
|
24
|
+
* Development keeps the stack: that's where it's actually useful, and the
|
|
25
|
+
* paths it exposes are the developer's own.
|
|
26
|
+
*
|
|
27
|
+
* Only applied when writing; parsing leaves `DISABLED_FEATURES` alone so an
|
|
28
|
+
* incoming payload that does carry a stack still deserializes.
|
|
29
|
+
*/
|
|
30
|
+
const SERIALIZE_DISABLED_FEATURES = import.meta.env.PROD
|
|
31
|
+
? DISABLED_FEATURES | Feature.ErrorPrototypeStack
|
|
32
|
+
: DISABLED_FEATURES;
|
|
33
|
+
/**
|
|
34
|
+
* `crossSerializeStream` historically ran with every feature enabled, so only
|
|
35
|
+
* add the stack removal here rather than the full serialize set.
|
|
36
|
+
*/
|
|
37
|
+
const JS_SERIALIZE_DISABLED_FEATURES = import.meta.env.PROD ? Feature.ErrorPrototypeStack : 0;
|
|
19
38
|
/**
|
|
20
39
|
* Alexis:
|
|
21
40
|
*
|
|
@@ -47,6 +66,7 @@ export function serializeToJSStream(id, value) {
|
|
|
47
66
|
start(controller) {
|
|
48
67
|
crossSerializeStream(value, {
|
|
49
68
|
scopeId: id,
|
|
69
|
+
disabledFeatures: JS_SERIALIZE_DISABLED_FEATURES,
|
|
50
70
|
plugins: DEFAULT_PLUGINS,
|
|
51
71
|
onSerialize(data, initial) {
|
|
52
72
|
controller.enqueue(createChunk(initial ? `(${getCrossReferenceHeader(id)},${data})` : data));
|
|
@@ -65,7 +85,7 @@ export function serializeToJSONStream(value) {
|
|
|
65
85
|
return new ReadableStream({
|
|
66
86
|
start(controller) {
|
|
67
87
|
toCrossJSONStream(value, {
|
|
68
|
-
disabledFeatures:
|
|
88
|
+
disabledFeatures: SERIALIZE_DISABLED_FEATURES,
|
|
69
89
|
depthLimit: MAX_SERIALIZATION_DEPTH_LIMIT,
|
|
70
90
|
plugins: DEFAULT_PLUGINS,
|
|
71
91
|
onParse(node) {
|
|
@@ -9,6 +9,6 @@ const assetMap = {
|
|
|
9
9
|
noscript: (props) => (<noscript {...props.attrs}>{props.children}</noscript>),
|
|
10
10
|
};
|
|
11
11
|
export function renderAsset(asset, nonce) {
|
|
12
|
-
let { tag, attrs: { key, ...attrs } = { key: undefined }, children
|
|
12
|
+
let { tag, attrs: { key, ...attrs } = { key: undefined }, children } = asset;
|
|
13
13
|
return assetMap[tag]({ attrs: { ...attrs, nonce }, key, children });
|
|
14
14
|
}
|
package/dist/server/handler.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { H3 } from "h3/generic";
|
|
2
1
|
import type { JSX } from "solid-js";
|
|
3
|
-
import type { FetchEvent, HandlerOptions, PageEvent } from "./types.ts";
|
|
4
|
-
export declare function createBaseHandler(createPageEvent: (e: FetchEvent) => Promise<PageEvent>, fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>), routerLoad?: (event: FetchEvent) => Promise<void>):
|
|
5
|
-
export declare function createHandler(fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>), routerLoad?: (event: FetchEvent) => Promise<void>):
|
|
2
|
+
import type { FetchEvent, HandlerOptions, PageEvent, StartHandler } from "./types.ts";
|
|
3
|
+
export declare function createBaseHandler(createPageEvent: (e: FetchEvent) => Promise<PageEvent>, fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>), routerLoad?: (event: FetchEvent) => Promise<void>): StartHandler;
|
|
4
|
+
export declare function createHandler(fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>), routerLoad?: (event: FetchEvent) => Promise<void>): StartHandler;
|
|
6
5
|
export declare function createPageEvent(ctx: FetchEvent): Promise<PageEvent>;
|
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";
|
|
@@ -19,12 +19,7 @@ export function createBaseHandler(createPageEvent, fn, options = {}, routerLoad)
|
|
|
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 = {}, routerLoad)
|
|
|
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") {
|
|
@@ -96,10 +89,9 @@ export function createBaseHandler(createPageEvent, fn, options = {}, routerLoad)
|
|
|
96
89
|
}
|
|
97
90
|
if (mode === "async")
|
|
98
91
|
return await stream;
|
|
99
|
-
delete stream.then;
|
|
100
92
|
// h3 expects a standard web ReadableStream across runtimes. The adapter
|
|
101
93
|
// also tolerates cancellation while Solid finishes outstanding work.
|
|
102
|
-
return toWebReadableStream(stream);
|
|
94
|
+
return iterable(toWebReadableStream(stream));
|
|
103
95
|
}),
|
|
104
96
|
});
|
|
105
97
|
const app = new H3();
|
|
@@ -182,38 +174,6 @@ function handleStreamCompleteRedirect(context) {
|
|
|
182
174
|
to && write(`<script>window.location=${JSON.stringify(to).replace(/</g, "\\u003c")}</script>`);
|
|
183
175
|
};
|
|
184
176
|
}
|
|
185
|
-
function produceResponseWithEventHeaders(res) {
|
|
186
|
-
const event = getRequestEvent();
|
|
187
|
-
let ret = res;
|
|
188
|
-
// Response.redirect returns an immutable value, so we clone on any redirect just in case
|
|
189
|
-
if (300 <= res.status && res.status < 400) {
|
|
190
|
-
const cookies = res.headers.getSetCookie?.() ?? [];
|
|
191
|
-
const headers = new Headers();
|
|
192
|
-
res.headers.forEach((value, key) => {
|
|
193
|
-
if (key.toLowerCase() !== "set-cookie") {
|
|
194
|
-
headers.set(key, value);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
for (const cookie of cookies) {
|
|
198
|
-
headers.append("Set-Cookie", cookie);
|
|
199
|
-
}
|
|
200
|
-
ret = new Response(res.body, {
|
|
201
|
-
status: res.status,
|
|
202
|
-
statusText: res.statusText,
|
|
203
|
-
headers,
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
const eventCookies = event.response.headers.getSetCookie?.() ?? [];
|
|
207
|
-
for (const cookie of eventCookies) {
|
|
208
|
-
ret.headers.append("Set-Cookie", cookie);
|
|
209
|
-
}
|
|
210
|
-
for (const [name, value] of event.response.headers) {
|
|
211
|
-
if (name.toLowerCase() !== "set-cookie") {
|
|
212
|
-
ret.headers.set(name, value);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return ret;
|
|
216
|
-
}
|
|
217
177
|
function stripBaseUrl(path) {
|
|
218
178
|
const base = import.meta.env.SERVER_BASE_URL || import.meta.env.BASE_URL || "/";
|
|
219
179
|
return stripPathBase(path, base);
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ 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 { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta, } from "./types.ts";
|
|
6
|
+
export type { APIEvent, APIHandler, Asset, ContextMatches, DocumentComponentProps, FetchEvent, HandlerOptions, PageEvent, ResponseStub, ServerFunctionMeta, StartHandler, } from "./types.ts";
|
|
7
7
|
/**
|
|
8
8
|
* Checks if user has set a redirect status in the response.
|
|
9
9
|
* If not, falls back to the 302 (temporary redirect)
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type { H3 } from "h3/generic";
|
|
2
1
|
import type { JSX } from "solid-js";
|
|
3
|
-
import type { FetchEvent, 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), routerLoad?: (event: FetchEvent) => Promise<void>):
|
|
7
|
+
export declare function createHandler(fn: (context: PageEvent) => JSX.Element, options?: HandlerOptions | ((context: PageEvent) => HandlerOptions), routerLoad?: (event: FetchEvent) => Promise<void>): StartHandler;
|
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)
|
|
@@ -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,7 +51,7 @@ 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.startErrorViewerErrorLine =
|
|
54
|
+
el.dataset.startErrorViewerErrorLine = "";
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { createMemo, createResource, onCleanup, Show, Suspense } from
|
|
1
|
+
import { createMemo, createResource, onCleanup, Show, Suspense } from "solid-js";
|
|
2
2
|
import { Badge } from "../../ui/Badge.jsx";
|
|
3
3
|
import Button from "../../ui/Button.jsx";
|
|
4
|
-
import
|
|
4
|
+
import "./BlobViewer.css";
|
|
5
5
|
function DocumentIcon(props) {
|
|
6
6
|
return (<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" {...props}>
|
|
7
7
|
<title>{props.title}</title>
|
|
@@ -23,19 +23,15 @@ function BlobViewerInner(props) {
|
|
|
23
23
|
document.body.removeChild(link);
|
|
24
24
|
}
|
|
25
25
|
return (<Button data-start-blob-viewer onClick={() => openFileInNewTab()}>
|
|
26
|
-
{props.source instanceof File
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
</Badge>)
|
|
31
|
-
: <Badge type="info">{props.source.type}</Badge>}
|
|
26
|
+
{props.source instanceof File ? (<Badge type="info">
|
|
27
|
+
<DocumentIcon title={props.source.name}/>
|
|
28
|
+
{props.source.name}
|
|
29
|
+
</Badge>) : (<Badge type="info">{props.source.type}</Badge>)}
|
|
32
30
|
</Button>);
|
|
33
31
|
}
|
|
34
32
|
export function BlobViewer(props) {
|
|
35
33
|
const [data] = createResource(() => props.source);
|
|
36
34
|
return (<Suspense>
|
|
37
|
-
<Show when={data()}>
|
|
38
|
-
{(current) => <BlobViewerInner source={current()}/>}
|
|
39
|
-
</Show>
|
|
35
|
+
<Show when={data()}>{current => <BlobViewerInner source={current()}/>}</Show>
|
|
40
36
|
</Suspense>);
|
|
41
37
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { createResource, For, Show, Suspense } from
|
|
2
|
-
import { Section } from
|
|
3
|
-
import { BlobViewer } from
|
|
4
|
-
import { PropertySeparator, SerovalValue } from
|
|
1
|
+
import { createResource, For, Show, Suspense } from "solid-js";
|
|
2
|
+
import { Section } from "../../ui/Section.jsx";
|
|
3
|
+
import { BlobViewer } from "./BlobViewer.jsx";
|
|
4
|
+
import { PropertySeparator, SerovalValue } from "./SerovalValue.jsx";
|
|
5
5
|
function FormDataViewerInner(props) {
|
|
6
|
-
return (<Section title="FormData" options={{ size:
|
|
6
|
+
return (<Section title="FormData" options={{ size: "sm" }}>
|
|
7
7
|
<div data-start-form-data-viewer data-start-properties>
|
|
8
8
|
<For each={Array.from(props.source.entries())}>
|
|
9
9
|
{([key, value]) => (<div data-start-property>
|
|
10
10
|
<SerovalValue value={`"${key}"`}/>
|
|
11
11
|
<PropertySeparator />
|
|
12
|
-
{typeof value ===
|
|
13
|
-
? <SerovalValue value={`"${JSON.stringify(value)}"`}/>
|
|
14
|
-
: <BlobViewer source={value}/>}
|
|
12
|
+
{typeof value === "string" ? (<SerovalValue value={`"${JSON.stringify(value)}"`}/>) : (<BlobViewer source={value}/>)}
|
|
15
13
|
</div>)}
|
|
16
14
|
</For>
|
|
17
15
|
</div>
|
|
@@ -20,8 +18,6 @@ function FormDataViewerInner(props) {
|
|
|
20
18
|
export function FormDataViewer(props) {
|
|
21
19
|
const [data] = createResource(() => props.source);
|
|
22
20
|
return (<Suspense>
|
|
23
|
-
<Show when={data()}>
|
|
24
|
-
{(current) => <FormDataViewerInner source={current()}/>}
|
|
25
|
-
</Show>
|
|
21
|
+
<Show when={data()}>{current => <FormDataViewerInner source={current()}/>}</Show>
|
|
26
22
|
</Suspense>);
|
|
27
23
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { For } from "solid-js";
|
|
2
2
|
import { PropertySeparator, SerovalValue } from "./SerovalValue.jsx";
|
|
3
|
-
import
|
|
3
|
+
import "./HeadersViewer.css";
|
|
4
4
|
import { Text } from "../../ui/Text.jsx";
|
|
5
5
|
export function HeadersViewer(props) {
|
|
6
6
|
return (<div data-start-headers-viewer data-start-properties>
|
|
7
7
|
<For each={Array.from(props.headers.entries())}>
|
|
8
8
|
{([key, value]) => (<div data-start-property>
|
|
9
|
-
<Text options={{ size:
|
|
9
|
+
<Text options={{ size: "xs", weight: "semibold", wrap: "nowrap" }}>{key}</Text>
|
|
10
10
|
<PropertySeparator />
|
|
11
11
|
<SerovalValue value={value}/>
|
|
12
12
|
</div>)}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createMemo, createResource, For, Show, Suspense } from "solid-js";
|
|
2
2
|
import { Text } from "../../ui/Text.jsx";
|
|
3
|
-
import
|
|
3
|
+
import "./HexViewer.css";
|
|
4
4
|
function toHex(num, digits = 2) {
|
|
5
|
-
return num.toString(16).padStart(digits,
|
|
5
|
+
return num.toString(16).padStart(digits, "0").toUpperCase();
|
|
6
6
|
}
|
|
7
7
|
function HexChunk(props) {
|
|
8
8
|
const content = createMemo(() => {
|
|
@@ -12,7 +12,7 @@ function HexChunk(props) {
|
|
|
12
12
|
const byte4 = props.bytes[3] || 0;
|
|
13
13
|
return `${toHex(byte1)} ${toHex(byte2)} ${toHex(byte3)} ${toHex(byte4)}`;
|
|
14
14
|
});
|
|
15
|
-
return (<Text data-start-hex-chunk options={{ size:
|
|
15
|
+
return (<Text data-start-hex-chunk options={{ size: "xs", weight: "bold", wrap: "nowrap" }}>
|
|
16
16
|
{content()}
|
|
17
17
|
</Text>);
|
|
18
18
|
}
|
|
@@ -42,9 +42,7 @@ function HexText(props) {
|
|
|
42
42
|
return result;
|
|
43
43
|
});
|
|
44
44
|
return (<div data-start-hex-text>
|
|
45
|
-
<Text options={{ size:
|
|
46
|
-
{text()}
|
|
47
|
-
</Text>
|
|
45
|
+
<Text options={{ size: "xs", weight: "bold", wrap: "nowrap" }}>{text()}</Text>
|
|
48
46
|
</div>);
|
|
49
47
|
}
|
|
50
48
|
export function HexViewerInner(props) {
|
|
@@ -57,22 +55,16 @@ export function HexViewerInner(props) {
|
|
|
57
55
|
});
|
|
58
56
|
return (<div data-start-hex-viewer>
|
|
59
57
|
<div data-start-hex-viewer-bytes>
|
|
60
|
-
<For each={rows()}>
|
|
61
|
-
{(current) => <HexRow bytes={current}/>}
|
|
62
|
-
</For>
|
|
58
|
+
<For each={rows()}>{current => <HexRow bytes={current}/>}</For>
|
|
63
59
|
</div>
|
|
64
60
|
<div data-start-hex-viewer-text>
|
|
65
|
-
<For each={rows()}>
|
|
66
|
-
{(current) => <HexText bytes={current}/>}
|
|
67
|
-
</For>
|
|
61
|
+
<For each={rows()}>{current => <HexText bytes={current}/>}</For>
|
|
68
62
|
</div>
|
|
69
63
|
</div>);
|
|
70
64
|
}
|
|
71
65
|
export function HexViewer(props) {
|
|
72
66
|
const [data] = createResource(() => props.bytes);
|
|
73
67
|
return (<Suspense>
|
|
74
|
-
<Show when={data()}>
|
|
75
|
-
{(current) => <HexViewerInner bytes={current()}/>}
|
|
76
|
-
</Show>
|
|
68
|
+
<Show when={data()}>{current => <HexViewerInner bytes={current()}/>}</Show>
|
|
77
69
|
</Suspense>);
|
|
78
70
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Text } from "../../ui/Text.jsx";
|
|
2
|
-
import
|
|
2
|
+
import "./SerovalValue.css";
|
|
3
3
|
export function SerovalValue(props) {
|
|
4
|
-
return (<Text data-start-seroval-value options={{ size:
|
|
4
|
+
return (<Text data-start-seroval-value options={{ size: "xs", weight: "semibold", wrap: "nowrap" }}>
|
|
5
5
|
{`${props.value}`}
|
|
6
6
|
</Text>);
|
|
7
7
|
}
|
|
8
8
|
export function PropertySeparator() {
|
|
9
|
-
return <Text options={{ size:
|
|
9
|
+
return <Text options={{ size: "xs", weight: "semibold", wrap: "nowrap" }}>:</Text>;
|
|
10
10
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createResource, For, Show, Suspense } from
|
|
2
|
-
import { Section } from
|
|
3
|
-
import { PropertySeparator, SerovalValue } from
|
|
1
|
+
import { createResource, For, Show, Suspense } from "solid-js";
|
|
2
|
+
import { Section } from "../../ui/Section.jsx";
|
|
3
|
+
import { PropertySeparator, SerovalValue } from "./SerovalValue.jsx";
|
|
4
4
|
function URLSearchParamsViewerInner(props) {
|
|
5
|
-
return (<Section title="URLSearchParams" options={{ size:
|
|
5
|
+
return (<Section title="URLSearchParams" options={{ size: "sm" }}>
|
|
6
6
|
<div data-start-properties>
|
|
7
7
|
<For each={Array.from(props.source.entries())}>
|
|
8
8
|
{([key, value]) => (<div data-start-property>
|
|
@@ -17,8 +17,6 @@ function URLSearchParamsViewerInner(props) {
|
|
|
17
17
|
export function URLSearchParamsViewer(props) {
|
|
18
18
|
const [data] = createResource(() => props.source);
|
|
19
19
|
return (<Suspense>
|
|
20
|
-
<Show when={data()}>
|
|
21
|
-
{(current) => <URLSearchParamsViewerInner source={current()}/>}
|
|
22
|
-
</Show>
|
|
20
|
+
<Show when={data()}>{current => <URLSearchParamsViewerInner source={current()}/>}</Show>
|
|
23
21
|
</Suspense>);
|
|
24
22
|
}
|
|
@@ -104,6 +104,11 @@ export function DevToolbar(props) {
|
|
|
104
104
|
}
|
|
105
105
|
createEffect(() => {
|
|
106
106
|
const onErrorEvent = (error) => {
|
|
107
|
+
// Browsers dispatch benign ResizeObserver loop notifications as window
|
|
108
|
+
// "error" events carrying no error object. They aren't app errors.
|
|
109
|
+
if (!error.error && error.message?.startsWith("ResizeObserver loop")) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
107
112
|
pushError(error.error ?? error);
|
|
108
113
|
};
|
|
109
114
|
window.addEventListener("error", onErrorEvent);
|
package/dist/shared/ui/Badge.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { JSX } from
|
|
2
|
-
import
|
|
1
|
+
import type { JSX } from "solid-js";
|
|
2
|
+
import "./Badge.css";
|
|
3
3
|
export interface BadgeProps {
|
|
4
|
-
type:
|
|
4
|
+
type: "info" | "success" | "failure" | "warning";
|
|
5
5
|
children: JSX.Element;
|
|
6
6
|
}
|
|
7
7
|
export declare function Badge(props: BadgeProps): JSX.Element;
|
package/dist/shared/ui/Badge.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Text } from
|
|
1
|
+
import "./Badge.css";
|
|
2
|
+
import { Text } from "./Text.jsx";
|
|
3
3
|
export function Badge(props) {
|
|
4
|
-
return (<Text options={{ size:
|
|
4
|
+
return (<Text options={{ size: "xs", wrap: "nowrap", weight: "semibold" }} data-start-badge={props.type}>
|
|
5
5
|
{props.children}
|
|
6
6
|
</Text>);
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Button as BaseButton } from "terracotta";
|
|
2
2
|
import "./Button.css";
|
|
3
|
-
const Button =
|
|
3
|
+
const Button = props => (<BaseButton type="button" data-start-button {...props}/>);
|
|
4
4
|
export default Button;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Select as BaseSelect, SelectOption as BaseSelectOption
|
|
1
|
+
import { Select as BaseSelect, SelectOption as BaseSelectOption } from "terracotta";
|
|
2
2
|
import "./Cascade.css";
|
|
3
|
-
export const Cascade =
|
|
4
|
-
export const CascadeOption =
|
|
3
|
+
export const Cascade = props => <BaseSelect data-start-cascade {...props}/>;
|
|
4
|
+
export const CascadeOption = props => (<BaseSelectOption data-start-cascade-option {...props}/>);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dialog as BaseDialog, DialogOverlay as BaseDialogOverlay, DialogPanel as BaseDialogPanel, } from "terracotta";
|
|
2
2
|
import "./Dialog.css";
|
|
3
|
-
export const Dialog =
|
|
4
|
-
export const DialogOverlay =
|
|
5
|
-
export const DialogPanel =
|
|
3
|
+
export const Dialog = props => <BaseDialog data-start-dialog {...props}/>;
|
|
4
|
+
export const DialogOverlay = props => (<BaseDialogOverlay data-start-dialog-overlay {...props}/>);
|
|
5
|
+
export const DialogPanel = props => (<BaseDialogPanel data-start-dialog-panel {...props}/>);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Button as BaseButton } from "terracotta";
|
|
2
2
|
import "./IconButton.css";
|
|
3
|
-
const IconButton =
|
|
3
|
+
const IconButton = props => (<BaseButton type="button" data-start-icon-button {...props}/>);
|
|
4
4
|
export default IconButton;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { JSX } from "solid-js";
|
|
2
2
|
import { type TextProps } from "./Text.tsx";
|
|
3
|
-
import
|
|
3
|
+
import "./Section.css";
|
|
4
4
|
export interface SectionProps {
|
|
5
5
|
title: string;
|
|
6
|
-
options?: TextProps<
|
|
6
|
+
options?: TextProps<"span">["options"];
|
|
7
7
|
children: JSX.Element;
|
|
8
8
|
}
|
|
9
9
|
export declare function Section(props: SectionProps): JSX.Element;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Text } from "./Text.jsx";
|
|
2
|
-
import
|
|
2
|
+
import "./Section.css";
|
|
3
3
|
export function Section(props) {
|
|
4
4
|
return (<div data-start-section>
|
|
5
|
-
<Text data-start-section-title options={{ weight:
|
|
5
|
+
<Text data-start-section-title options={{ weight: "bold", font: "sans", ...props.options }}>
|
|
6
6
|
{props.title}
|
|
7
7
|
</Text>
|
|
8
|
-
<div data-start-section-content>
|
|
9
|
-
{props.children}
|
|
10
|
-
</div>
|
|
8
|
+
<div data-start-section-content>{props.children}</div>
|
|
11
9
|
</div>);
|
|
12
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Select as BaseSelect, SelectOption as BaseSelectOption
|
|
1
|
+
import { Select as BaseSelect, SelectOption as BaseSelectOption } from "terracotta";
|
|
2
2
|
import "./Select.css";
|
|
3
|
-
export const Select =
|
|
4
|
-
export const SelectOption =
|
|
3
|
+
export const Select = props => <BaseSelect data-start-select {...props}/>;
|
|
4
|
+
export const SelectOption = props => (<BaseSelectOption data-start-select-option {...props}/>);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ComponentProps, JSX } from
|
|
2
|
-
import
|
|
3
|
-
type TableProps = ComponentProps<
|
|
1
|
+
import type { ComponentProps, JSX } from "solid-js";
|
|
2
|
+
import "./Table.css";
|
|
3
|
+
type TableProps = ComponentProps<"div">;
|
|
4
4
|
export declare function Table(props: TableProps): JSX.Element;
|
|
5
|
-
type TableHeaderProps = ComponentProps<
|
|
5
|
+
type TableHeaderProps = ComponentProps<"div">;
|
|
6
6
|
export declare function TableHeader(props: TableHeaderProps): JSX.Element;
|
|
7
|
-
type TableRowProps = ComponentProps<
|
|
7
|
+
type TableRowProps = ComponentProps<"div">;
|
|
8
8
|
export declare function TableRow(props: TableRowProps): JSX.Element;
|
|
9
|
-
type TableCellProps = ComponentProps<
|
|
9
|
+
type TableCellProps = ComponentProps<"div">;
|
|
10
10
|
export declare function TableCell(props: TableCellProps): JSX.Element;
|
|
11
11
|
export {};
|
package/dist/shared/ui/Table.jsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "./Table.css";
|
|
2
2
|
export function Table(props) {
|
|
3
|
-
return
|
|
3
|
+
return <div data-start-table {...props}/>;
|
|
4
4
|
}
|
|
5
5
|
export function TableHeader(props) {
|
|
6
|
-
return
|
|
6
|
+
return <div data-start-table-header {...props}/>;
|
|
7
7
|
}
|
|
8
8
|
export function TableRow(props) {
|
|
9
|
-
return
|
|
9
|
+
return <div data-start-table-row {...props}/>;
|
|
10
10
|
}
|
|
11
11
|
export function TableCell(props) {
|
|
12
|
-
return
|
|
12
|
+
return <div data-start-table-cell {...props}/>;
|
|
13
13
|
}
|
package/dist/shared/ui/Tabs.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Tab as BaseTab, TabGroup as BaseTabGroup, TabList as BaseTabList, TabPanel as BaseTabPanel, } from "terracotta";
|
|
2
2
|
import "./Tabs.css";
|
|
3
|
-
export const Tab =
|
|
4
|
-
export const TabGroup =
|
|
5
|
-
export const TabPanel =
|
|
6
|
-
export const TabList =
|
|
3
|
+
export const Tab = props => <BaseTab data-start-tab {...props}/>;
|
|
4
|
+
export const TabGroup = props => (<BaseTabGroup data-start-tab-group {...props}/>);
|
|
5
|
+
export const TabPanel = props => (<BaseTabPanel data-start-tab-panel {...props}/>);
|
|
6
|
+
export const TabList = props => <BaseTabList data-start-tab-list {...props}/>;
|
package/dist/shared/ui/Text.css
CHANGED
|
@@ -24,13 +24,17 @@
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
[data-start-text-font="sans"] {
|
|
27
|
-
font-family:
|
|
27
|
+
font-family:
|
|
28
|
+
system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
|
29
|
+
"Noto Color Emoji";
|
|
28
30
|
}
|
|
29
31
|
[data-start-text-font="serif"] {
|
|
30
|
-
font-family: ui-serif, Georgia, Cambria,
|
|
32
|
+
font-family: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
|
31
33
|
}
|
|
32
34
|
[data-start-text-font="mono"] {
|
|
33
|
-
font-family:
|
|
35
|
+
font-family:
|
|
36
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
|
37
|
+
monospace;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
[data-start-text-weight="thin"] {
|
package/dist/shared/ui/Text.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { type ComponentProps, type JSX } from
|
|
2
|
-
import
|
|
3
|
-
export type TextProps<T extends keyof JSX.IntrinsicElements =
|
|
1
|
+
import { type ComponentProps, type JSX } from "solid-js";
|
|
2
|
+
import "./Text.css";
|
|
3
|
+
export type TextProps<T extends keyof JSX.IntrinsicElements = "span"> = ComponentProps<T> & {
|
|
4
4
|
options?: {
|
|
5
5
|
as?: T;
|
|
6
|
-
size?:
|
|
7
|
-
font?:
|
|
8
|
-
weight?:
|
|
9
|
-
wrap?:
|
|
6
|
+
size?: "xs" | "sm" | "base" | "lg" | "xl" | "2xl";
|
|
7
|
+
font?: "sans" | "serif" | "mono";
|
|
8
|
+
weight?: "thin" | "extralight" | "light" | "normal" | "medium" | "semibold" | "bold" | "extrabold";
|
|
9
|
+
wrap?: "wrap" | "nowrap";
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
-
export declare function Text<T extends keyof JSX.IntrinsicElements =
|
|
12
|
+
export declare function Text<T extends keyof JSX.IntrinsicElements = "span">(props: TextProps<T>): JSX.Element;
|
package/dist/shared/ui/Text.jsx
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { createMemo, splitProps } from
|
|
2
|
-
import { Dynamic } from
|
|
3
|
-
import
|
|
1
|
+
import { createMemo, splitProps } from "solid-js";
|
|
2
|
+
import { Dynamic } from "solid-js/web";
|
|
3
|
+
import "./Text.css";
|
|
4
4
|
export function Text(props) {
|
|
5
|
-
const [current, rest] = splitProps(props, [
|
|
5
|
+
const [current, rest] = splitProps(props, ["options"]);
|
|
6
6
|
const customization = createMemo(() => {
|
|
7
7
|
const options = Object.assign({}, {
|
|
8
|
-
size:
|
|
9
|
-
font:
|
|
10
|
-
weight:
|
|
11
|
-
wrap:
|
|
8
|
+
size: "base",
|
|
9
|
+
font: "mono",
|
|
10
|
+
weight: "normal",
|
|
11
|
+
wrap: "wrap",
|
|
12
12
|
}, current.options);
|
|
13
13
|
const entries = Object.entries(options);
|
|
14
14
|
return Object.fromEntries(entries.map(([key, value]) => [`data-start-text-${key}`, value]));
|
|
15
15
|
});
|
|
16
|
-
return (<Dynamic component={(current.options?.as ||
|
|
16
|
+
return (<Dynamic component={(current.options?.as || "span")} {...rest} {...customization()}/>);
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/start",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"files": [
|
|
6
|
-
"dist",
|
|
7
|
-
"env.d.ts",
|
|
8
|
-
"CHANGELOG.md"
|
|
9
|
-
],
|
|
3
|
+
"version": "2.0.0-rc.4",
|
|
10
4
|
"repository": {
|
|
11
5
|
"type": "git",
|
|
12
6
|
"url": "git+https://github.com/solidjs/solid-start.git",
|
|
13
7
|
"directory": "packages/start"
|
|
14
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"env.d.ts",
|
|
12
|
+
"CHANGELOG.md"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
15
|
"exports": {
|
|
16
16
|
".": "./dist/index.jsx",
|
|
17
17
|
"./config": "./dist/config/index.js",
|
|
@@ -30,44 +30,44 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@babel/core": "^7.29.
|
|
34
|
-
"@babel/traverse": "^7.29.
|
|
35
|
-
"@babel/types": "^7.29.
|
|
33
|
+
"@babel/core": "^7.29.7",
|
|
34
|
+
"@babel/traverse": "^7.29.7",
|
|
35
|
+
"@babel/types": "^7.29.7",
|
|
36
36
|
"@solidjs/meta": "^0.29.4",
|
|
37
37
|
"@types/babel__traverse": "^7.28.0",
|
|
38
38
|
"@types/micromatch": "^4.0.10",
|
|
39
|
-
"cookie-es": "^
|
|
40
|
-
"defu": "^6.1.
|
|
39
|
+
"cookie-es": "^3.1.1",
|
|
40
|
+
"defu": "^6.1.7",
|
|
41
41
|
"error-stack-parser": "^2.1.4",
|
|
42
42
|
"fast-glob": "^3.3.3",
|
|
43
|
-
"h3": "^2.0.1-rc.
|
|
43
|
+
"h3": "^2.0.1-rc.26",
|
|
44
44
|
"html-to-image": "^1.11.13",
|
|
45
45
|
"micromatch": "^4.0.8",
|
|
46
|
-
"oxc-parser": "^0.
|
|
47
|
-
"path-to-regexp": "^8.
|
|
46
|
+
"oxc-parser": "^0.141.0",
|
|
47
|
+
"path-to-regexp": "^8.4.2",
|
|
48
48
|
"pathe": "^2.0.3",
|
|
49
49
|
"radix3": "^1.1.2",
|
|
50
|
-
"seroval": "^1.5.
|
|
51
|
-
"seroval-plugins": "^1.5.
|
|
52
|
-
"shiki": "^
|
|
53
|
-
"solid-js": "^1.9.
|
|
50
|
+
"seroval": "^1.5.6",
|
|
51
|
+
"seroval-plugins": "^1.5.6",
|
|
52
|
+
"shiki": "^4.3.1",
|
|
53
|
+
"solid-js": "^1.9.14",
|
|
54
54
|
"source-map-js": "^1.2.1",
|
|
55
|
-
"srvx": "^0.12.
|
|
55
|
+
"srvx": "^0.12.4",
|
|
56
56
|
"terracotta": "^1.1.1",
|
|
57
|
-
"vite-plugin-solid": "^2.11.
|
|
58
|
-
},
|
|
59
|
-
"engines": {
|
|
60
|
-
"node": ">=24"
|
|
57
|
+
"vite-plugin-solid": "^2.11.13"
|
|
61
58
|
},
|
|
62
59
|
"devDependencies": {
|
|
63
60
|
"@types/babel__core": "^7.20.5",
|
|
64
|
-
"@types/node": "^
|
|
65
|
-
"vite": "^8.
|
|
66
|
-
"vitest": "^4.1.
|
|
61
|
+
"@types/node": "^26.1.1",
|
|
62
|
+
"vite": "^8.1.5",
|
|
63
|
+
"vitest": "^4.1.10"
|
|
67
64
|
},
|
|
68
65
|
"peerDependencies": {
|
|
69
66
|
"vite": "^8 || ^9"
|
|
70
67
|
},
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": ">=24"
|
|
70
|
+
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "pnpm validate-imports && tsc && node scripts/build.js",
|
|
73
73
|
"dev": "tsc --watch",
|