@statorjs/stator 1.7.0 → 1.7.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/package.json +2 -2
- package/src/server/query-route.ts +11 -2
- package/src/server/routing.ts +12 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statorjs/stator",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Server-canonical web framework: business logic in composable state machines, UI as a thin renderer binding machine outputs to DOM positions. Ships TypeScript source (Vite/tsx-native by design).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"pino-pretty": "^13.1.3",
|
|
89
89
|
"vite": "^6.0.0",
|
|
90
90
|
"vitest": "^2.1.0",
|
|
91
|
-
"@statorjs/stator": "1.7.
|
|
91
|
+
"@statorjs/stator": "1.7.1"
|
|
92
92
|
},
|
|
93
93
|
"scripts": {
|
|
94
94
|
"typecheck": "tsc --noEmit",
|
|
@@ -6,7 +6,12 @@ import { scopedLogger } from './logger.ts'
|
|
|
6
6
|
import type { MachineStore } from './machine-store.ts'
|
|
7
7
|
import type { DiscoveredRoute } from './route-discovery.ts'
|
|
8
8
|
import { buildRouteRequest } from './route-request.ts'
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
QueryRouteDefinition,
|
|
11
|
+
QueryRouteHelpers,
|
|
12
|
+
QueryRouteResult,
|
|
13
|
+
RouteContext,
|
|
14
|
+
} from './routing.ts'
|
|
10
15
|
import { getOrCreateSessionId } from './session.ts'
|
|
11
16
|
import { withSessionLock } from './session-lock.ts'
|
|
12
17
|
import { SessionRuntime } from './session-runtime.ts'
|
|
@@ -74,7 +79,11 @@ export async function runQueryRoute(
|
|
|
74
79
|
|
|
75
80
|
let result: QueryRouteResult
|
|
76
81
|
try {
|
|
77
|
-
|
|
82
|
+
// The map is built dynamically by machine name; the typed ReadsMap
|
|
83
|
+
// guarantee is for the user's handler, recovered at their call site.
|
|
84
|
+
result = await route.handler(request, {
|
|
85
|
+
machines: machines as QueryRouteHelpers['machines'],
|
|
86
|
+
})
|
|
78
87
|
} catch (err) {
|
|
79
88
|
queryLog.error({ err: String(err), path: c.req.path }, 'data route handler threw')
|
|
80
89
|
return c.text('Internal Server Error', 500)
|
package/src/server/routing.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HtmlFragment } from '../template/types.ts'
|
|
2
2
|
import type { WireEnvelope } from '../wire/index.ts'
|
|
3
|
-
import type { AnyMachineDef, EventOf } from './define-machine.ts'
|
|
3
|
+
import type { AnyMachineDef, EventOf, ReadsMap } from './define-machine.ts'
|
|
4
4
|
|
|
5
5
|
/** Machine context passed to a route's render function. Keyed by machine name. */
|
|
6
6
|
export type RouteContext = Record<string, unknown>
|
|
@@ -170,7 +170,7 @@ export interface DefineApiRouteConfig<TReads extends ReadonlyArray<AnyMachineDef
|
|
|
170
170
|
/** `method: 'GET'` discriminates: with it, the handler is a read-only data
|
|
171
171
|
* route typed with `{ machines }`; without it, a command route typed with
|
|
172
172
|
* `{ dispatch, rotateSession }` — exactly as before. */
|
|
173
|
-
export function defineApiRoute<TReads extends ReadonlyArray<AnyMachineDef
|
|
173
|
+
export function defineApiRoute<TReads extends ReadonlyArray<AnyMachineDef> = readonly []>(
|
|
174
174
|
config: DefineQueryRouteConfig<TReads>,
|
|
175
175
|
): QueryRouteDefinition
|
|
176
176
|
export function defineApiRoute<TReads extends ReadonlyArray<AnyMachineDef>>(
|
|
@@ -209,10 +209,15 @@ export function isStatorApiRoute(v: unknown): v is ApiRouteDefinition {
|
|
|
209
209
|
* there is no `dispatch` here, and that structural absence is what makes
|
|
210
210
|
* handler reads safe — a handler that cannot dispatch has nothing to
|
|
211
211
|
* interleave with effect completions or other sessions' commits. */
|
|
212
|
-
export interface QueryRouteHelpers
|
|
212
|
+
export interface QueryRouteHelpers<
|
|
213
|
+
TReads extends ReadonlyArray<AnyMachineDef> = ReadonlyArray<AnyMachineDef>,
|
|
214
|
+
> {
|
|
213
215
|
/** Read proxies keyed by machine name — the same shape a page's render
|
|
214
|
-
* context uses (selector + context reads; no send).
|
|
215
|
-
machines
|
|
216
|
+
* context uses (selector + context reads; no send). Typed off the route's
|
|
217
|
+
* `reads:` tuple (`ReadsMap`), so `machines.SitesMachine` is a real proxy
|
|
218
|
+
* and a mistyped name is a compile error rather than `unknown`. The default
|
|
219
|
+
* keeps the erased runtime definition loose. */
|
|
220
|
+
machines: ReadsMap<TReads>
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
/** What a data GET handler may return: a raw `Response` (passed through
|
|
@@ -231,14 +236,14 @@ export interface QueryRouteDefinition {
|
|
|
231
236
|
) => Promise<QueryRouteResult> | QueryRouteResult
|
|
232
237
|
}
|
|
233
238
|
|
|
234
|
-
export interface DefineQueryRouteConfig<TReads extends ReadonlyArray<AnyMachineDef
|
|
239
|
+
export interface DefineQueryRouteConfig<TReads extends ReadonlyArray<AnyMachineDef> = readonly []> {
|
|
235
240
|
/** The capability discriminant: `'GET'` declares a read-only data route.
|
|
236
241
|
* Discovery cross-checks it against the export name. */
|
|
237
242
|
method: 'GET'
|
|
238
243
|
reads?: TReads
|
|
239
244
|
handler: (
|
|
240
245
|
request: RouteRequest,
|
|
241
|
-
helpers: QueryRouteHelpers
|
|
246
|
+
helpers: QueryRouteHelpers<TReads>,
|
|
242
247
|
) => Promise<QueryRouteResult> | QueryRouteResult
|
|
243
248
|
}
|
|
244
249
|
|