@kasperrt/smolter 0.0.1-rc.1 → 0.0.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.
- package/README.md +36 -36
- package/dist/internal/client/deserialize.d.ts +1 -1
- package/dist/internal/client/deserialize.js +1 -1
- package/dist/internal/preact/context.d.ts +1 -1
- package/dist/internal/preact/context.js +1 -1
- package/dist/internal/preact/fetcher.d.ts +1 -1
- package/dist/internal/preact/fetcher.js +1 -1
- package/dist/internal/preact/form.d.ts +1 -1
- package/dist/internal/preact/form.js +1 -1
- package/dist/internal/preact/hooks.d.ts +1 -1
- package/dist/internal/preact/hooks.js +1 -1
- package/dist/internal/preact/link.d.ts +1 -1
- package/dist/internal/preact/link.js +1 -1
- package/dist/internal/preact/routes.d.ts +1 -1
- package/dist/internal/preact/routes.js +1 -1
- package/dist/internal/react/context.d.ts +1 -1
- package/dist/internal/react/context.js +1 -1
- package/dist/internal/react/fetcher.d.ts +1 -1
- package/dist/internal/react/fetcher.js +1 -1
- package/dist/internal/react/form.d.ts +1 -1
- package/dist/internal/react/form.js +1 -1
- package/dist/internal/react/hooks.d.ts +1 -1
- package/dist/internal/react/hooks.js +1 -1
- package/dist/internal/react/link.d.ts +1 -1
- package/dist/internal/react/link.js +1 -1
- package/dist/internal/react/routes.d.ts +1 -1
- package/dist/internal/react/routes.js +1 -1
- package/dist/internal/vite/index.js +1 -1
- package/dist/internal/vite/transport.js +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/internal/client/deserialize.ts +1 -1
- package/src/internal/preact/context.ts +1 -1
- package/src/internal/preact/fetcher.ts +1 -1
- package/src/internal/preact/form.ts +1 -1
- package/src/internal/preact/hooks.ts +1 -1
- package/src/internal/preact/link.ts +1 -1
- package/src/internal/preact/routes.ts +1 -1
- package/src/internal/react/context.ts +1 -1
- package/src/internal/react/fetcher.ts +1 -1
- package/src/internal/react/form.ts +1 -1
- package/src/internal/react/hooks.ts +1 -1
- package/src/internal/react/link.ts +1 -1
- package/src/internal/react/routes.ts +1 -1
- package/src/internal/vite/index.ts +3 -1
- package/src/internal/vite/transport.ts +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# smolter _
|
|
2
2
|
|
|
3
3
|
<!-- bundlejs:start -->
|
|
4
|
-
[](https://bundlejs.com/?q=%40kasperrt%2Fsmolter%400.0.1%2Freact&treeshake=%5B*%5D&config=%7B%22compression%22%3A%22gzip%22%2C%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react%2F*%22%5D%7D%7D&bundle)
|
|
5
|
+
[](https://bundlejs.com/?q=%40kasperrt%2Fsmolter%400.0.1%2Fpreact&treeshake=%5B*%5D&config=%7B%22compression%22%3A%22gzip%22%2C%22esbuild%22%3A%7B%22external%22%3A%5B%22preact%22%2C%22preact%2F*%22%5D%7D%7D&bundle)
|
|
6
6
|
<!-- bundlejs:end -->
|
|
7
7
|
|
|
8
8
|
A typed data router for React and Preact. **Zero runtime dependencies.**
|
|
@@ -29,16 +29,16 @@ and [React Router](https://reactrouter.com/).
|
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
short imports shown throughout these examples:
|
|
32
|
+
Install the scoped npm package and choose your framework explicitly:
|
|
34
33
|
|
|
35
34
|
```sh
|
|
36
|
-
pnpm add
|
|
35
|
+
pnpm add @kasperrt/smolter
|
|
37
36
|
```
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
```ts
|
|
39
|
+
import { createRouter, useFetcher } from "@kasperrt/smolter/react";
|
|
40
|
+
// Preact: import from "@kasperrt/smolter/preact".
|
|
41
|
+
```
|
|
42
42
|
|
|
43
43
|
## Try the four standalone examples
|
|
44
44
|
|
|
@@ -81,7 +81,7 @@ or filename parser enters the browser bundle.
|
|
|
81
81
|
```ts
|
|
82
82
|
// vite.config.ts
|
|
83
83
|
import { defineConfig } from "vite";
|
|
84
|
-
import { fileRouter } from "smolter/vite";
|
|
84
|
+
import { fileRouter } from "@kasperrt/smolter/vite";
|
|
85
85
|
|
|
86
86
|
export default defineConfig({
|
|
87
87
|
plugins: [fileRouter({ directory: "src/routes" })],
|
|
@@ -90,7 +90,7 @@ export default defineConfig({
|
|
|
90
90
|
|
|
91
91
|
```ts
|
|
92
92
|
// app.ts
|
|
93
|
-
import { createRouter } from "smolter/react";
|
|
93
|
+
import { createRouter } from "@kasperrt/smolter/react";
|
|
94
94
|
import routes from "virtual:smolter/routes";
|
|
95
95
|
|
|
96
96
|
export const router = createRouter(routes, { browser: true });
|
|
@@ -121,18 +121,18 @@ For the virtual module, add this declaration to your app:
|
|
|
121
121
|
// env.d.ts
|
|
122
122
|
// Include vite/client in your tsconfig types as usual.
|
|
123
123
|
declare module "virtual:smolter/routes" {
|
|
124
|
-
const routes: import("smolter/core").Route[];
|
|
124
|
+
const routes: import("@kasperrt/smolter/core").Route[];
|
|
125
125
|
export default routes;
|
|
126
126
|
}
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
Outside Vite, `flatRoutes(directory)` from
|
|
129
|
+
Outside Vite, `flatRoutes(directory)` from `@kasperrt/smolter/files` returns
|
|
130
130
|
`{ path, file }[] | Error` for your build tool to turn into imports.
|
|
131
131
|
|
|
132
132
|
### Manual routes
|
|
133
133
|
|
|
134
134
|
```tsx
|
|
135
|
-
import { createRouter, defineRoute } from "smolter/react";
|
|
135
|
+
import { createRouter, defineRoute } from "@kasperrt/smolter/react";
|
|
136
136
|
import * as tasks from "./tasks/route";
|
|
137
137
|
import * as task from "./task/route";
|
|
138
138
|
|
|
@@ -146,7 +146,7 @@ Or pass handlers directly to `defineRoute(path, { loader, action, default: View
|
|
|
146
146
|
First registered match wins. Trailing slashes are ignored. `/tasks/42` supplies
|
|
147
147
|
`params.id === "42"`; query parameters come from `new URL(request.url)`.
|
|
148
148
|
|
|
149
|
-
Use the same API from
|
|
149
|
+
Use the same API from **`@kasperrt/smolter/preact`** for Preact. Render the selected route
|
|
150
150
|
inside the provider:
|
|
151
151
|
|
|
152
152
|
```tsx
|
|
@@ -184,7 +184,7 @@ With the optional server integration:
|
|
|
184
184
|
|
|
185
185
|
```ts
|
|
186
186
|
// client-loader.ts
|
|
187
|
-
import type { ClientLoaderArgs } from "smolter/client";
|
|
187
|
+
import type { ClientLoaderArgs } from "@kasperrt/smolter/client";
|
|
188
188
|
import type { loader } from "./loader";
|
|
189
189
|
|
|
190
190
|
export async function clientLoader({ serverLoader }: ClientLoaderArgs<typeof loader>) {
|
|
@@ -194,7 +194,7 @@ export async function clientLoader({ serverLoader }: ClientLoaderArgs<typeof loa
|
|
|
194
194
|
|
|
195
195
|
```ts
|
|
196
196
|
// client-action.ts
|
|
197
|
-
import type { ClientActionArgs } from "smolter/client";
|
|
197
|
+
import type { ClientActionArgs } from "@kasperrt/smolter/client";
|
|
198
198
|
import type { action } from "./action";
|
|
199
199
|
|
|
200
200
|
export async function clientAction({ serverAction }: ClientActionArgs<typeof action>) {
|
|
@@ -211,7 +211,7 @@ A new navigation aborts the previous navigation's signal. Pass `signal` (or
|
|
|
211
211
|
|
|
212
212
|
```ts
|
|
213
213
|
// loader.ts
|
|
214
|
-
import type { DataArgs } from "smolter/react";
|
|
214
|
+
import type { DataArgs } from "@kasperrt/smolter/react";
|
|
215
215
|
|
|
216
216
|
export async function clientLoader({ signal }: DataArgs) {
|
|
217
217
|
const response = await fetch("/api/tasks", { signal });
|
|
@@ -234,17 +234,17 @@ in a client bundle. Type-only imports from server handlers are safe. Do not
|
|
|
234
234
|
import server code directly into client views or client handlers.
|
|
235
235
|
|
|
236
236
|
The Vite dev plugin mounts `/_smolter?url=...`. Production hosts dispatch that
|
|
237
|
-
endpoint through `handleRequest(routes, request)` from
|
|
237
|
+
endpoint through `handleRequest(routes, request)` from `@kasperrt/smolter/server`, using
|
|
238
238
|
the requested route URL. Both SSR examples include a working host. The host
|
|
239
239
|
owns authentication, session cookies, HTTP policy, and deployment.
|
|
240
240
|
|
|
241
241
|
Manual server routes use `serverRoute<typeof import("./route")>(path, clientModule)`
|
|
242
|
-
from
|
|
242
|
+
from `@kasperrt/smolter/client` in the browser and `defineRoute` on the server. This keeps
|
|
243
243
|
the type connection without importing server code at runtime. To use manual
|
|
244
244
|
tables with the dev transport:
|
|
245
245
|
|
|
246
246
|
```ts
|
|
247
|
-
import { routerPlugin } from "smolter/vite";
|
|
247
|
+
import { routerPlugin } from "@kasperrt/smolter/vite";
|
|
248
248
|
|
|
249
249
|
routerPlugin({
|
|
250
250
|
clientRoutes: "src/manual-browser-routes.ts",
|
|
@@ -316,7 +316,7 @@ Fetcher results belong to `fetcher.data`, not `useActionData()`.
|
|
|
316
316
|
|
|
317
317
|
```ts
|
|
318
318
|
// should-revalidate.ts
|
|
319
|
-
import type { RevalidationArgs } from "smolter/react";
|
|
319
|
+
import type { RevalidationArgs } from "@kasperrt/smolter/react";
|
|
320
320
|
|
|
321
321
|
export function shouldRevalidate({ actionResult, defaultShouldRevalidate }: RevalidationArgs) {
|
|
322
322
|
if (actionResult && typeof actionResult === "object" && "changed" in actionResult) {
|
|
@@ -366,7 +366,7 @@ remount the fallback during revalidation. Return a `Response` with a `Location`
|
|
|
366
366
|
## Server rendering
|
|
367
367
|
|
|
368
368
|
```tsx
|
|
369
|
-
import { loadRouter, serialize } from "smolter/server";
|
|
369
|
+
import { loadRouter, serialize } from "@kasperrt/smolter/server";
|
|
370
370
|
|
|
371
371
|
const router = await loadRouter(routes, incomingRequest);
|
|
372
372
|
const html = renderToString(
|
|
@@ -376,14 +376,14 @@ const hydrationJSON = serialize(router.getSnapshot());
|
|
|
376
376
|
```
|
|
377
377
|
|
|
378
378
|
Create a fresh router per request. Embed the serialized snapshot in a JSON
|
|
379
|
-
script, restore it with `deserialize` from
|
|
379
|
+
script, restore it with `deserialize` from `@kasperrt/smolter/client`, and pass it as
|
|
380
380
|
`hydrationData` to `createRouter`. This preserves loader errors through hydration
|
|
381
381
|
without exposing server stacks or causes. Error boundaries should display the
|
|
382
382
|
error message, not its stack.
|
|
383
383
|
|
|
384
384
|
```ts
|
|
385
|
-
import { deserialize } from "smolter/client";
|
|
386
|
-
import { createRouter } from "smolter/react";
|
|
385
|
+
import { deserialize } from "@kasperrt/smolter/client";
|
|
386
|
+
import { createRouter } from "@kasperrt/smolter/react";
|
|
387
387
|
import routes from "virtual:smolter/routes";
|
|
388
388
|
|
|
389
389
|
const data = document.getElementById("smolter-data");
|
|
@@ -402,16 +402,16 @@ The SSR examples use the same server route definitions for HTML and data request
|
|
|
402
402
|
|
|
403
403
|
## Package entries
|
|
404
404
|
|
|
405
|
-
Use
|
|
406
|
-
The root
|
|
407
|
-
Server helpers live in
|
|
408
|
-
flat file routing in
|
|
405
|
+
Use `@kasperrt/smolter/react` for React 18+ and `@kasperrt/smolter/preact` for Preact 10.25+.
|
|
406
|
+
The root `@kasperrt/smolter` entry (also available as `@kasperrt/smolter/core`) is framework-independent.
|
|
407
|
+
Server helpers live in `@kasperrt/smolter/server`; optional browser transport in `@kasperrt/smolter/client`;
|
|
408
|
+
flat file routing in `@kasperrt/smolter/vite` and `@kasperrt/smolter/files`.
|
|
409
409
|
|
|
410
410
|
On JSR, install `@kasperrt/smolter` using the
|
|
411
411
|
[JSR package instructions](https://jsr.io/docs/npm-compatibility) and import
|
|
412
412
|
`@kasperrt/smolter/react` or `@kasperrt/smolter/preact`. Its `core`, `client`,
|
|
413
413
|
`server`, and `files` subpaths match npm. The Vite plugin is npm-only:
|
|
414
|
-
use
|
|
414
|
+
use `@kasperrt/smolter/vite` from the npm package when adding file routing.
|
|
415
415
|
|
|
416
416
|
## Size and checks
|
|
417
417
|
|
|
@@ -424,10 +424,10 @@ example labels. File discovery is build-only.
|
|
|
424
424
|
<!-- size-comparison:start -->
|
|
425
425
|
| Browser exports | Gzip bytes |
|
|
426
426
|
| --- | ---: |
|
|
427
|
-
|
|
|
428
|
-
|
|
|
429
|
-
|
|
|
430
|
-
|
|
|
427
|
+
| `@kasperrt/smolter/react` | 2445 |
|
|
428
|
+
| `@kasperrt/smolter/preact` | 2445 |
|
|
429
|
+
| `@kasperrt/smolter/react + @kasperrt/smolter/client` | 2782 |
|
|
430
|
+
| `@kasperrt/smolter/preact + @kasperrt/smolter/client` | 2781 |
|
|
431
431
|
| `wouter@3.13.0` | 3091 |
|
|
432
432
|
| `wouter-preact@3.13.0` | 2450 |
|
|
433
433
|
| `react-router@8.4.0` | 60994 |
|
|
@@ -438,7 +438,7 @@ using production ESM bundles, esbuild, Terser, and gzip level 9. React, React DO
|
|
|
438
438
|
and Preact are external in every bundle. Transitive library dependencies are
|
|
439
439
|
included. React Router provides a broader API; this compares complete entry
|
|
440
440
|
sizes, not equivalent feature sets or the minimum code for one route.
|
|
441
|
-
|
|
441
|
+
`@kasperrt/smolter/client` adds browser transport for server loaders/actions; server-only
|
|
442
442
|
rendering code and the Vite plugin are not shipped to the browser.
|
|
443
443
|
|
|
444
444
|
Exact current measurements are generated in
|
|
@@ -467,5 +467,5 @@ To test a local package build in another project:
|
|
|
467
467
|
|
|
468
468
|
```sh
|
|
469
469
|
pnpm --dir packages/smolter pack --pack-destination ../..
|
|
470
|
-
pnpm add
|
|
470
|
+
pnpm add /absolute/path/to/kasperrt-smolter-0.0.1.tgz
|
|
471
471
|
```
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Snapshot } from "../core/index.ts";
|
|
2
|
-
/** Restore a trusted snapshot produced by smolter/server serialize, including its route error. */
|
|
2
|
+
/** Restore a trusted snapshot produced by @kasperrt/smolter/server serialize, including its route error. */
|
|
3
3
|
export declare function deserialize(json: string): Snapshot;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Restore a trusted snapshot produced by smolter/server serialize, including its route error. */
|
|
1
|
+
/** Restore a trusted snapshot produced by @kasperrt/smolter/server serialize, including its route error. */
|
|
2
2
|
export function deserialize(json) {
|
|
3
3
|
const snapshot = JSON.parse(json);
|
|
4
4
|
const error = snapshot.error;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Preact components and typed data hooks. Import from smolter/preact.
|
|
2
|
+
* Preact components and typed data hooks. Import from @kasperrt/smolter/preact.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
5
|
import { createContext, createElement, useContext, useEffect, useSyncExternalStore, } from "./runtime.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Preact components and typed data hooks. Import from smolter/preact.
|
|
2
|
+
* Preact components and typed data hooks. Import from @kasperrt/smolter/preact.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
5
|
import type { AnyDataFunction, DataFunction, DataOf, FetcherSnapshot, Result, Route as RouteDefinition, RouteModule, SubmitOptions } from "../core/index.ts";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Preact components and typed data hooks. Import from smolter/preact.
|
|
2
|
+
* Preact components and typed data hooks. Import from @kasperrt/smolter/preact.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
5
|
import type { AnyDataFunction, DataOf, RouteModule, Router, Snapshot } from "../core/index.ts";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React components and typed data hooks. Import from smolter/react.
|
|
2
|
+
* React components and typed data hooks. Import from @kasperrt/smolter/react.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
5
|
import { createContext, createElement, useContext, useEffect, useSyncExternalStore, } from "./runtime.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React components and typed data hooks. Import from smolter/react.
|
|
2
|
+
* React components and typed data hooks. Import from @kasperrt/smolter/react.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
5
|
import type { AnyDataFunction, DataFunction, DataOf, FetcherSnapshot, Result, Route as RouteDefinition, RouteModule, SubmitOptions } from "../core/index.ts";
|
|
@@ -103,7 +103,7 @@ export function routerPlugin({ directory = "src/routes", clientRoutes, serverRou
|
|
|
103
103
|
}
|
|
104
104
|
if (!options?.ssr &&
|
|
105
105
|
definitions.some((definition) => definition.startsWith("serverRoute(")))
|
|
106
|
-
imports.unshift('import { serverRoute } from "smolter/client";');
|
|
106
|
+
imports.unshift('import { serverRoute } from "@kasperrt/smolter/client";');
|
|
107
107
|
return `${imports.join("\n")}\nexport default [${definitions.join(",\n")}];\n`;
|
|
108
108
|
},
|
|
109
109
|
configureServer(server) {
|
|
@@ -30,7 +30,7 @@ export function configureTransport(server, publicId) {
|
|
|
30
30
|
});
|
|
31
31
|
const [{ default: routes }, { handleRequest }] = await Promise.all([
|
|
32
32
|
server.ssrLoadModule(publicId),
|
|
33
|
-
server.ssrLoadModule("smolter/server"),
|
|
33
|
+
server.ssrLoadModule("@kasperrt/smolter/server"),
|
|
34
34
|
]);
|
|
35
35
|
const response = await handleRequest(routes, request);
|
|
36
36
|
outgoing.statusCode = response.status;
|
package/jsr.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snapshot } from "../core/index.ts";
|
|
2
2
|
|
|
3
|
-
/** Restore a trusted snapshot produced by smolter/server serialize, including its route error. */
|
|
3
|
+
/** Restore a trusted snapshot produced by @kasperrt/smolter/server serialize, including its route error. */
|
|
4
4
|
export function deserialize(json: string): Snapshot {
|
|
5
5
|
const snapshot: Snapshot = JSON.parse(json);
|
|
6
6
|
const error = snapshot.error;
|
|
@@ -172,7 +172,9 @@ export function routerPlugin({
|
|
|
172
172
|
!options?.ssr &&
|
|
173
173
|
definitions.some((definition) => definition.startsWith("serverRoute("))
|
|
174
174
|
)
|
|
175
|
-
imports.unshift(
|
|
175
|
+
imports.unshift(
|
|
176
|
+
'import { serverRoute } from "@kasperrt/smolter/client";',
|
|
177
|
+
);
|
|
176
178
|
|
|
177
179
|
return `${imports.join("\n")}\nexport default [${definitions.join(",\n")}];\n`;
|
|
178
180
|
},
|
|
@@ -43,7 +43,7 @@ export function configureTransport(
|
|
|
43
43
|
});
|
|
44
44
|
const [{ default: routes }, { handleRequest }] = await Promise.all([
|
|
45
45
|
server.ssrLoadModule(publicId),
|
|
46
|
-
server.ssrLoadModule("smolter/server"),
|
|
46
|
+
server.ssrLoadModule("@kasperrt/smolter/server"),
|
|
47
47
|
]);
|
|
48
48
|
const response: Response = await handleRequest(routes, request);
|
|
49
49
|
|