silgi 0.51.7 → 0.52.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.
- package/README.md +47 -0
- package/dist/adapters/_fetch-adapter.d.mts +6 -0
- package/dist/adapters/_fetch-adapter.mjs +14 -8
- package/dist/adapters/astro.mjs +1 -1
- package/dist/adapters/nextjs.mjs +1 -1
- package/dist/adapters/remix.mjs +1 -1
- package/dist/adapters/solidstart.mjs +1 -1
- package/dist/adapters/sveltekit.mjs +1 -1
- package/dist/client/client.d.mts +42 -4
- package/dist/client/client.mjs +42 -4
- package/dist/client/server.d.mts +27 -2
- package/dist/client/server.mjs +27 -2
- package/dist/compile.d.mts +10 -1
- package/dist/compile.mjs +13 -4
- package/dist/core/context-bridge.d.mts +49 -0
- package/dist/core/context-bridge.mjs +43 -7
- package/dist/core/context.d.mts +26 -0
- package/dist/core/ctx-symbols.mjs +21 -0
- package/dist/core/error.d.mts +183 -2
- package/dist/core/error.mjs +259 -16
- package/dist/core/handler.d.mts +15 -1
- package/dist/core/handler.mjs +33 -17
- package/dist/core/schema-converter.d.mts +131 -0
- package/dist/core/schema-converter.mjs +82 -0
- package/dist/core/serve.d.mts +2 -2
- package/dist/core/serve.mjs +9 -2
- package/dist/core/task.mjs +2 -2
- package/dist/index.d.mts +5 -2
- package/dist/index.mjs +4 -2
- package/dist/integrations/better-auth/index.d.mts +22 -1
- package/dist/integrations/better-auth/index.mjs +79 -11
- package/dist/integrations/drizzle/index.mjs +22 -5
- package/dist/integrations/zod/converter.d.mts +1 -1
- package/dist/integrations/zod/index.d.mts +29 -2
- package/dist/integrations/zod/index.mjs +60 -1
- package/dist/lazy.d.mts +40 -3
- package/dist/lazy.mjs +40 -3
- package/dist/map-input.mjs +1 -1
- package/dist/plugins/analytics/collector.d.mts +1 -1
- package/dist/plugins/analytics/trace.mjs +1 -1
- package/dist/plugins/analytics/types.d.mts +3 -3
- package/dist/plugins/analytics/utils.mjs +1 -4
- package/dist/plugins/analytics.d.mts +5 -3
- package/dist/plugins/analytics.mjs +16 -29
- package/dist/plugins/cache.mjs +1 -1
- package/dist/plugins/coerce.mjs +1 -1
- package/dist/scalar.d.mts +2 -1
- package/dist/scalar.mjs +9 -30
- package/dist/silgi.d.mts +165 -18
- package/dist/silgi.mjs +47 -11
- package/package.json +6 -2
- package/dist/core/trace-map.d.mts +0 -13
- package/dist/core/trace-map.mjs +0 -13
package/dist/silgi.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AnySchema, InferSchemaInput, InferSchemaOutput } from "./core/schema.mjs";
|
|
2
2
|
import { ErrorDef, GuardDef, GuardFn, InferClient, ProcedureDef, ResolveContext, RouterDef, WrapDef, WrapFn } from "./types.mjs";
|
|
3
3
|
import { AnalyticsOptions } from "./plugins/analytics/types.mjs";
|
|
4
|
+
import { SchemaConverter } from "./core/schema-converter.mjs";
|
|
4
5
|
import { ScalarOptions } from "./scalar.mjs";
|
|
5
6
|
import { ProcedureBuilder } from "./builder.mjs";
|
|
6
7
|
import { ServeOptions, SilgiServer } from "./core/serve.mjs";
|
|
@@ -37,11 +38,53 @@ interface SilgiHooks {
|
|
|
37
38
|
port: number;
|
|
38
39
|
hostname: string;
|
|
39
40
|
}) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Fires after base context is applied and params are merged, before input parsing.
|
|
43
|
+
* Framework plugins (e.g. analytics) use this to inject fields into `ctx`
|
|
44
|
+
* before any user code runs.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
'request:prepare': (event: {
|
|
49
|
+
request: Request;
|
|
50
|
+
ctx: Record<string, unknown>;
|
|
51
|
+
}) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Fires after the pipeline produces output, before the `Response` is built.
|
|
54
|
+
* Framework plugins use this to capture output for trace recording.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
'response:finalize': (event: {
|
|
59
|
+
request: Request;
|
|
60
|
+
ctx: Record<string, unknown>;
|
|
61
|
+
output: unknown;
|
|
62
|
+
}) => void;
|
|
40
63
|
}
|
|
41
64
|
interface SilgiConfig<TCtx extends Record<string, unknown>> {
|
|
42
65
|
context: (req: Request) => TCtx | Promise<TCtx>;
|
|
43
66
|
/** Register lifecycle hooks */
|
|
44
67
|
hooks?: Partial<{ [K in keyof SilgiHooks]: SilgiHooks[K] | SilgiHooks[K][] }>;
|
|
68
|
+
/**
|
|
69
|
+
* Schema converters for OpenAPI spec generation and analytics schema extraction.
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* Pass a converter for each schema library you use. Schemas with a native
|
|
73
|
+
* `jsonSchema.input()` implementation (Valibot, ArkType, Zod v4) work
|
|
74
|
+
* without registering anything. Converters are required for libraries
|
|
75
|
+
* that do not implement the Standard JSON Schema extension.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* import { zodConverter } from 'silgi/zod'
|
|
80
|
+
*
|
|
81
|
+
* const k = silgi({
|
|
82
|
+
* context: (req) => ({ db: getDB() }),
|
|
83
|
+
* schemaConverters: [zodConverter],
|
|
84
|
+
* })
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
schemaConverters?: SchemaConverter[];
|
|
45
88
|
/**
|
|
46
89
|
* Storage configuration — mount drivers by path prefix.
|
|
47
90
|
*
|
|
@@ -69,35 +112,106 @@ interface SilgiInstance<TBaseCtx extends Record<string, unknown>> {
|
|
|
69
112
|
removeHook: Hookable<SilgiHooks>['removeHook'];
|
|
70
113
|
/** Access storage with optional prefix — uses configured mounts */
|
|
71
114
|
useStorage: typeof useStorage;
|
|
72
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Run `fn` inside this instance's per-request `AsyncLocalStorage` scope.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* Instrumented integrations (Drizzle, Better Auth) read the installed
|
|
120
|
+
* context via {@link SilgiInstance.currentContext}. Because each silgi
|
|
121
|
+
* instance owns its own bridge, calls across instances do not collide.
|
|
122
|
+
*
|
|
123
|
+
* @param ctx - Context to install for the duration of `fn`.
|
|
124
|
+
* @param fn - Function executed with `ctx` as the ambient context.
|
|
125
|
+
* @returns Whatever `fn` returns.
|
|
126
|
+
*/
|
|
127
|
+
runInContext: <T>(ctx: TBaseCtx, fn: () => T) => T;
|
|
128
|
+
/**
|
|
129
|
+
* Read the context installed by the nearest enclosing
|
|
130
|
+
* {@link SilgiInstance.runInContext}, or `undefined` if none.
|
|
131
|
+
*/
|
|
132
|
+
currentContext: () => TBaseCtx | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Await storage initialization.
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* When `storage` is configured, resolves after `initStorage` completes.
|
|
138
|
+
* When storage is not configured, resolves immediately (no dynamic
|
|
139
|
+
* import). Errors during storage init reject this promise — no silent
|
|
140
|
+
* `console.error` fallback.
|
|
141
|
+
*
|
|
142
|
+
* `useStorage()` awaits this promise internally, so calling `ready()`
|
|
143
|
+
* is optional unless you need an explicit ordering guarantee before
|
|
144
|
+
* your first `useStorage()` call.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const k = silgi({ context: () => ({}), storage: { cache: redisDriver() } })
|
|
149
|
+
* await k.ready() // storage driver connected
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
ready: () => Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Create a guard middleware — a flat, zero-closure helper that runs
|
|
155
|
+
* before the resolver and can throw or return partial context.
|
|
156
|
+
*
|
|
157
|
+
* @remarks
|
|
158
|
+
* Prefer `guard` over `wrap` when you only need a pre-step. The
|
|
159
|
+
* returned object is passed to `$use(guard)` on any builder.
|
|
160
|
+
*/
|
|
73
161
|
guard: GuardFactory<TBaseCtx>;
|
|
74
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* Create a wrap middleware — onion-style before/after hook that can
|
|
164
|
+
* short-circuit the pipeline or transform the output.
|
|
165
|
+
*/
|
|
75
166
|
wrap: (fn: WrapFn<TBaseCtx>) => WrapDef<TBaseCtx>;
|
|
76
|
-
/** Start a builder —
|
|
167
|
+
/** Start a builder chain — set the resolver for a query procedure. */
|
|
77
168
|
$resolve: ProcedureBuilder<'query', TBaseCtx>['$resolve'];
|
|
78
|
-
/** Start a builder — set input schema */
|
|
169
|
+
/** Start a builder chain — set the input schema (Standard Schema). */
|
|
79
170
|
$input: ProcedureBuilder<'query', TBaseCtx>['$input'];
|
|
80
|
-
/** Start a builder — add middleware */
|
|
171
|
+
/** Start a builder chain — add guard/wrap middleware. */
|
|
81
172
|
$use: ProcedureBuilder<'query', TBaseCtx>['$use'];
|
|
82
|
-
/** Start a builder — set output schema */
|
|
173
|
+
/** Start a builder chain — set the output schema. */
|
|
83
174
|
$output: ProcedureBuilder<'query', TBaseCtx>['$output'];
|
|
84
|
-
/** Start a builder —
|
|
175
|
+
/** Start a builder chain — declare typed errors. */
|
|
85
176
|
$errors: ProcedureBuilder<'query', TBaseCtx>['$errors'];
|
|
86
|
-
/** Start a builder — set route metadata */
|
|
177
|
+
/** Start a builder chain — set HTTP route metadata (method, path, etc). */
|
|
87
178
|
$route: ProcedureBuilder<'query', TBaseCtx>['$route'];
|
|
88
|
-
/** Start a builder —
|
|
179
|
+
/** Start a builder chain — attach custom metadata for tooling. */
|
|
89
180
|
$meta: ProcedureBuilder<'query', TBaseCtx>['$meta'];
|
|
90
|
-
/** Define a subscription
|
|
181
|
+
/** Define a subscription — returns an SSE stream of events. */
|
|
91
182
|
subscription: SubscriptionFactory<TBaseCtx>;
|
|
92
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Start a builder chain — create a background/cron task.
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* Tasks are collected from the router on `serve()` and scheduled via
|
|
188
|
+
* `croner` when a `cron` spec is provided.
|
|
189
|
+
*/
|
|
93
190
|
$task: ProcedureBuilder<'query', TBaseCtx>['$task'];
|
|
94
|
-
/**
|
|
191
|
+
/**
|
|
192
|
+
* Assemble a router from nested procedures and pre-compile each
|
|
193
|
+
* pipeline.
|
|
194
|
+
*
|
|
195
|
+
* @remarks
|
|
196
|
+
* The returned value is the same object you passed in — path
|
|
197
|
+
* assignment and compilation happen off to the side, cached in a
|
|
198
|
+
* `WeakMap` keyed on the def. Never mutate the router after handing
|
|
199
|
+
* it to `router()`; build a new one instead.
|
|
200
|
+
*/
|
|
95
201
|
router: <T extends RouterDef>(def: T) => T;
|
|
96
|
-
/**
|
|
202
|
+
/**
|
|
203
|
+
* Create a Fetch API handler — `(Request) => Response | Promise<Response>`.
|
|
204
|
+
*
|
|
205
|
+
* @remarks
|
|
206
|
+
* Use this from any Fetch-compatible adapter (Next.js App Router,
|
|
207
|
+
* SvelteKit, Remix, srvx, Cloudflare Workers, Bun, Deno, hono over
|
|
208
|
+
* Lambda, etc.). The router has subscriptions mounted automatically
|
|
209
|
+
* when `hasWsProcedures` is detected.
|
|
210
|
+
*/
|
|
97
211
|
handler: (router: RouterDef, options?: {
|
|
98
212
|
/** URL path prefix (e.g. "/api"). Only requests matching this prefix are handled; others return 404. */basePath?: string; /** Enable Scalar API Reference UI at /api/reference and /api/openapi.json */
|
|
99
|
-
scalar?: boolean | ScalarOptions; /** Enable analytics dashboard at /api/analytics */
|
|
100
|
-
analytics?:
|
|
213
|
+
scalar?: boolean | ScalarOptions; /** Enable analytics dashboard at /api/analytics — requires `auth` to be set */
|
|
214
|
+
analytics?: AnalyticsOptions;
|
|
101
215
|
}) => (request: Request) => Response | Promise<Response>;
|
|
102
216
|
/** Create a direct caller — call procedures without HTTP. For testing and server-side usage. */
|
|
103
217
|
createCaller: <T extends RouterDef>(router: T, options?: {
|
|
@@ -105,8 +219,24 @@ interface SilgiInstance<TBaseCtx extends Record<string, unknown>> {
|
|
|
105
219
|
headers?: Record<string, string>; /** Default timeout in ms (default: 30000, null = no timeout) */
|
|
106
220
|
timeout?: number | null;
|
|
107
221
|
}) => InferClient<T>;
|
|
108
|
-
/**
|
|
109
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Create & start a Node.js HTTP server. Returns a handle to gracefully shut down.
|
|
224
|
+
*
|
|
225
|
+
* @remarks
|
|
226
|
+
* When `options.handleSignals` is `true`, registers `process.once('SIGINT')`
|
|
227
|
+
* and `process.once('SIGTERM')` listeners that invoke `server.close()`.
|
|
228
|
+
* Default `false` — opt in explicitly. The srvx-level graceful HTTP drain
|
|
229
|
+
* is controlled by `ServeOptions.gracefulShutdown`; `handleSignals`
|
|
230
|
+
* governs only the silgi-layer cron-stop wiring on OS signals.
|
|
231
|
+
*/
|
|
232
|
+
serve: (router: RouterDef, options?: ServeOptions & {
|
|
233
|
+
/**
|
|
234
|
+
* Register `process.once('SIGINT')` / `'SIGTERM'` listeners that call
|
|
235
|
+
* `server.close()`. Default `false` (opt-in). The close wrapper stops
|
|
236
|
+
* cron jobs regardless of this setting when called explicitly.
|
|
237
|
+
*/
|
|
238
|
+
handleSignals?: boolean;
|
|
239
|
+
}) => Promise<SilgiServer>;
|
|
110
240
|
}
|
|
111
241
|
interface GuardConfig<TBaseCtx, TReturn extends Record<string, unknown> | void, TErrors extends ErrorDef> {
|
|
112
242
|
errors?: TErrors;
|
|
@@ -129,6 +259,20 @@ interface SubscriptionFactory<TBaseCtx extends Record<string, unknown>> {
|
|
|
129
259
|
/**
|
|
130
260
|
* Create a Silgi RPC instance with typed context.
|
|
131
261
|
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* Every call returns a self-contained instance with its own schema
|
|
264
|
+
* registry, `AsyncLocalStorage` bridge, hook emitter and storage state.
|
|
265
|
+
* Two `silgi()` instances in the same process never share mutable state
|
|
266
|
+
* — see [ARCHITECTURE.md §3](../ARCHITECTURE.md) for the "de-magic"
|
|
267
|
+
* invariants.
|
|
268
|
+
*
|
|
269
|
+
* @typeParam TBaseCtx - Shape of the base context returned by
|
|
270
|
+
* `config.context(req)`. Flows into every procedure's `ResolveContext`.
|
|
271
|
+
* @param config - Instance configuration. `context` is required; all
|
|
272
|
+
* other fields are opt-in.
|
|
273
|
+
* @returns A {@link SilgiInstance} exposing builder, router, handler,
|
|
274
|
+
* caller and server helpers.
|
|
275
|
+
*
|
|
132
276
|
* @example
|
|
133
277
|
* ```ts
|
|
134
278
|
* const k = silgi({
|
|
@@ -139,7 +283,10 @@ interface SubscriptionFactory<TBaseCtx extends Record<string, unknown>> {
|
|
|
139
283
|
* })
|
|
140
284
|
* // k.$input(), k.$resolve(), k.guard(), k.router(), k.serve()
|
|
141
285
|
* ```
|
|
286
|
+
*
|
|
287
|
+
* @see {@link SilgiInstance}
|
|
288
|
+
* @see {@link SilgiConfig}
|
|
142
289
|
*/
|
|
143
290
|
declare function silgi<TBaseCtx extends Record<string, unknown>>(config: SilgiConfig<TBaseCtx>): SilgiInstance<TBaseCtx>;
|
|
144
291
|
//#endregion
|
|
145
|
-
export { SilgiConfig, SilgiInstance, silgi };
|
|
292
|
+
export { SilgiConfig, SilgiHooks, SilgiInstance, silgi };
|
package/dist/silgi.mjs
CHANGED
|
@@ -3,8 +3,10 @@ import { createProcedureBuilder } from "./builder.mjs";
|
|
|
3
3
|
import { assignPaths, routerCache } from "./core/router-utils.mjs";
|
|
4
4
|
import { compileRouter } from "./compile.mjs";
|
|
5
5
|
import { createCaller } from "./caller.mjs";
|
|
6
|
+
import { createContextBridge } from "./core/context-bridge.mjs";
|
|
6
7
|
import { normalizePrefix } from "./core/url.mjs";
|
|
7
8
|
import { createFetchHandler, wrapHandler } from "./core/handler.mjs";
|
|
9
|
+
import { createSchemaRegistry } from "./core/schema-converter.mjs";
|
|
8
10
|
import { createHooks } from "hookable";
|
|
9
11
|
//#region src/silgi.ts
|
|
10
12
|
/**
|
|
@@ -45,6 +47,20 @@ function createProcedure(type, ...args) {
|
|
|
45
47
|
/**
|
|
46
48
|
* Create a Silgi RPC instance with typed context.
|
|
47
49
|
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* Every call returns a self-contained instance with its own schema
|
|
52
|
+
* registry, `AsyncLocalStorage` bridge, hook emitter and storage state.
|
|
53
|
+
* Two `silgi()` instances in the same process never share mutable state
|
|
54
|
+
* — see [ARCHITECTURE.md §3](../ARCHITECTURE.md) for the "de-magic"
|
|
55
|
+
* invariants.
|
|
56
|
+
*
|
|
57
|
+
* @typeParam TBaseCtx - Shape of the base context returned by
|
|
58
|
+
* `config.context(req)`. Flows into every procedure's `ResolveContext`.
|
|
59
|
+
* @param config - Instance configuration. `context` is required; all
|
|
60
|
+
* other fields are opt-in.
|
|
61
|
+
* @returns A {@link SilgiInstance} exposing builder, router, handler,
|
|
62
|
+
* caller and server helpers.
|
|
63
|
+
*
|
|
48
64
|
* @example
|
|
49
65
|
* ```ts
|
|
50
66
|
* const k = silgi({
|
|
@@ -55,24 +71,32 @@ function createProcedure(type, ...args) {
|
|
|
55
71
|
* })
|
|
56
72
|
* // k.$input(), k.$resolve(), k.guard(), k.router(), k.serve()
|
|
57
73
|
* ```
|
|
74
|
+
*
|
|
75
|
+
* @see {@link SilgiInstance}
|
|
76
|
+
* @see {@link SilgiConfig}
|
|
58
77
|
*/
|
|
59
78
|
function silgi(config) {
|
|
60
79
|
const contextFactory = config.context;
|
|
80
|
+
const schemaRegistry = createSchemaRegistry(config.schemaConverters ?? []);
|
|
81
|
+
const bridge = createContextBridge();
|
|
61
82
|
const hooks = createHooks();
|
|
62
83
|
if (config.hooks) {
|
|
63
84
|
for (const [name, fn] of Object.entries(config.hooks)) if (Array.isArray(fn)) for (const f of fn) hooks.hook(name, f);
|
|
64
85
|
else if (fn) hooks.hook(name, fn);
|
|
65
86
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
87
|
+
const readyPromise = config.storage ? import("./core/storage.mjs").then((m) => {
|
|
88
|
+
m.initStorage(config.storage);
|
|
89
|
+
}) : Promise.resolve();
|
|
69
90
|
const ctxFactory = () => contextFactory(new Request("http://localhost"));
|
|
70
91
|
return {
|
|
71
92
|
hook: hooks.hook.bind(hooks),
|
|
72
93
|
removeHook: hooks.removeHook.bind(hooks),
|
|
73
94
|
useStorage: (...args) => {
|
|
74
|
-
return import("./core/storage.mjs").then((m) => m.useStorage(...args));
|
|
95
|
+
return readyPromise.then(() => import("./core/storage.mjs")).then((m) => m.useStorage(...args));
|
|
75
96
|
},
|
|
97
|
+
runInContext: (ctx, fn) => bridge.run(ctx, fn),
|
|
98
|
+
currentContext: () => bridge.current(),
|
|
99
|
+
ready: () => readyPromise,
|
|
76
100
|
guard: (fnOrConfig) => {
|
|
77
101
|
if (typeof fnOrConfig === "function") return {
|
|
78
102
|
kind: "guard",
|
|
@@ -115,7 +139,14 @@ function silgi(config) {
|
|
|
115
139
|
},
|
|
116
140
|
handler: (routerDef, options) => {
|
|
117
141
|
const prefix = options?.basePath ? normalizePrefix(options.basePath) : void 0;
|
|
118
|
-
const fetchHandler = wrapHandler(createFetchHandler(routerDef, contextFactory, hooks, prefix), routerDef, options
|
|
142
|
+
const fetchHandler = wrapHandler(createFetchHandler(routerDef, contextFactory, hooks, prefix, bridge), routerDef, options ? {
|
|
143
|
+
...options,
|
|
144
|
+
schemaRegistry,
|
|
145
|
+
hooks
|
|
146
|
+
} : {
|
|
147
|
+
schemaRegistry,
|
|
148
|
+
hooks
|
|
149
|
+
}, prefix);
|
|
119
150
|
if (!(function checkWs(def) {
|
|
120
151
|
if (!def || typeof def !== "object") return false;
|
|
121
152
|
if (def.type === "subscription") return true;
|
|
@@ -146,7 +177,7 @@ function silgi(config) {
|
|
|
146
177
|
},
|
|
147
178
|
serve: async (routerDef, options) => {
|
|
148
179
|
const { createServeHandler } = await import("./core/serve.mjs");
|
|
149
|
-
const server = await createServeHandler(routerDef, contextFactory, hooks, options);
|
|
180
|
+
const server = await createServeHandler(routerDef, contextFactory, hooks, options, schemaRegistry, bridge);
|
|
150
181
|
const { collectCronTasks, startCronJobs, stopCronJobs } = await import("./core/task.mjs");
|
|
151
182
|
const cronTasks = collectCronTasks(routerDef);
|
|
152
183
|
if (cronTasks.length > 0) {
|
|
@@ -154,14 +185,19 @@ function silgi(config) {
|
|
|
154
185
|
console.log(` ${cronTasks.length} cron task(s) scheduled`);
|
|
155
186
|
}
|
|
156
187
|
const originalClose = server.close.bind(server);
|
|
157
|
-
|
|
188
|
+
const wrappedClose = async (force) => {
|
|
158
189
|
stopCronJobs();
|
|
159
190
|
return originalClose(force);
|
|
160
191
|
};
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
192
|
+
const silgiServer = Object.assign(Object.create(Object.getPrototypeOf(server)), server, { close: wrappedClose });
|
|
193
|
+
if (options?.handleSignals) {
|
|
194
|
+
const onSignal = () => {
|
|
195
|
+
wrappedClose().catch(() => {});
|
|
196
|
+
};
|
|
197
|
+
process.once("SIGINT", onSignal);
|
|
198
|
+
process.once("SIGTERM", onSignal);
|
|
199
|
+
}
|
|
200
|
+
return silgiServer;
|
|
165
201
|
}
|
|
166
202
|
};
|
|
167
203
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "silgi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The fastest end-to-end type-safe RPC framework for TypeScript — compiled pipelines, single package, every runtime",
|
|
6
6
|
"keywords": [
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"lib"
|
|
42
42
|
],
|
|
43
43
|
"type": "module",
|
|
44
|
-
"sideEffects":
|
|
44
|
+
"sideEffects": [
|
|
45
|
+
"./dist/integrations/zod/index.mjs"
|
|
46
|
+
],
|
|
45
47
|
"exports": {
|
|
46
48
|
".": {
|
|
47
49
|
"import": "./dist/index.mjs",
|
|
@@ -286,6 +288,7 @@
|
|
|
286
288
|
"pinia": "^3.0.4",
|
|
287
289
|
"rou3": "^0.8.1",
|
|
288
290
|
"tsdown": "^0.21.7",
|
|
291
|
+
"typedoc": "^0.28.19",
|
|
289
292
|
"typescript": "^6.0.2",
|
|
290
293
|
"vitest": "^4.1.2",
|
|
291
294
|
"vue": "^3.5.31",
|
|
@@ -337,6 +340,7 @@
|
|
|
337
340
|
"fix": "oxlint --fix . && oxfmt --ignore-path .oxfmtignore .",
|
|
338
341
|
"test": "vitest run",
|
|
339
342
|
"typecheck": "tsgo --noEmit",
|
|
343
|
+
"docs:check": "typedoc --options typedoc.json",
|
|
340
344
|
"release": "bumpp"
|
|
341
345
|
}
|
|
342
346
|
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
//#region src/core/trace-map.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Shared WeakMap for passing analytics traces between handler and analytics plugin.
|
|
4
|
-
*
|
|
5
|
-
* Lives in core/ so the dependency direction is correct:
|
|
6
|
-
* core/handler.ts → core/trace-map.ts ← plugins/analytics.ts
|
|
7
|
-
*
|
|
8
|
-
* The WeakMap maps Request → RequestTrace, allowing the handler to inject
|
|
9
|
-
* trace data into context without importing the analytics plugin.
|
|
10
|
-
*/
|
|
11
|
-
declare const analyticsTraceMap: WeakMap<Request, unknown>;
|
|
12
|
-
//#endregion
|
|
13
|
-
export { analyticsTraceMap };
|
package/dist/core/trace-map.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
//#region src/core/trace-map.ts
|
|
2
|
-
/**
|
|
3
|
-
* Shared WeakMap for passing analytics traces between handler and analytics plugin.
|
|
4
|
-
*
|
|
5
|
-
* Lives in core/ so the dependency direction is correct:
|
|
6
|
-
* core/handler.ts → core/trace-map.ts ← plugins/analytics.ts
|
|
7
|
-
*
|
|
8
|
-
* The WeakMap maps Request → RequestTrace, allowing the handler to inject
|
|
9
|
-
* trace data into context without importing the analytics plugin.
|
|
10
|
-
*/
|
|
11
|
-
const analyticsTraceMap = /* @__PURE__ */ new WeakMap();
|
|
12
|
-
//#endregion
|
|
13
|
-
export { analyticsTraceMap };
|