@lunora/server 1.0.0-alpha.52 → 1.0.0-alpha.54
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/dist/index.d.mts +78 -4
- package/dist/index.d.ts +78 -4
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{PRESENCE_DEFAULT_TTL_MS-D50xfQ1n.mjs → PRESENCE_DEFAULT_TTL_MS-C9RX3Cl6.mjs} +1 -1
- package/dist/packem_shared/initLunora-QNqOuG0A.mjs +1 -0
- package/dist/types.d.mts +96 -6
- package/dist/types.d.ts +96 -6
- package/package.json +2 -2
- package/dist/packem_shared/initLunora-CHh1EmR4.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -70,6 +70,17 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
|
|
|
70
70
|
*/
|
|
71
71
|
expose: (config: ExposeConfig) => QueryBuilder<Context, Args, Output>;
|
|
72
72
|
input: <A extends ArgsValidator>(validators: A) => QueryBuilder<Context, A & Args, Output>;
|
|
73
|
+
/**
|
|
74
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
75
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
76
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
77
|
+
*
|
|
78
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
79
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
80
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
81
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
82
|
+
*/
|
|
83
|
+
meta: (value: Record<string, unknown>) => QueryBuilder<Context, Args, Output>;
|
|
73
84
|
output: <V extends Validator>(validator: V) => QueryBuilder<Context, Args, Infer<V>>;
|
|
74
85
|
query: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
75
86
|
args: InferArgs<Args>;
|
|
@@ -110,6 +121,17 @@ interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefine
|
|
|
110
121
|
*/
|
|
111
122
|
expose: (config: ExposeConfig) => MutationBuilder<Context, Args, Output>;
|
|
112
123
|
input: <A extends ArgsValidator>(validators: A) => MutationBuilder<Context, A & Args, Output>;
|
|
124
|
+
/**
|
|
125
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
126
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
127
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
128
|
+
*
|
|
129
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
130
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
131
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
132
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
133
|
+
*/
|
|
134
|
+
meta: (value: Record<string, unknown>) => MutationBuilder<Context, Args, Output>;
|
|
113
135
|
mutation: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
114
136
|
args: InferArgs<Args>;
|
|
115
137
|
ctx: Context;
|
|
@@ -144,6 +166,17 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
|
|
|
144
166
|
*/
|
|
145
167
|
expose: (config: ExposeConfig) => ActionBuilder<Context, Args, Output>;
|
|
146
168
|
input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
|
|
169
|
+
/**
|
|
170
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
171
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
172
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
173
|
+
*
|
|
174
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
175
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
176
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
177
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
178
|
+
*/
|
|
179
|
+
meta: (value: Record<string, unknown>) => ActionBuilder<Context, Args, Output>;
|
|
147
180
|
output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
|
|
148
181
|
use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
|
|
149
182
|
/**
|
|
@@ -164,6 +197,17 @@ interface InternalQueryBuilder<Context, Args extends ArgsValidator, Output = und
|
|
|
164
197
|
readonly __lunoraProcedure: "query";
|
|
165
198
|
readonly __lunoraVisibility: "internal";
|
|
166
199
|
input: <A extends ArgsValidator>(validators: A) => InternalQueryBuilder<Context, A & Args, Output>;
|
|
200
|
+
/**
|
|
201
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
202
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
203
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
204
|
+
*
|
|
205
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
206
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
207
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
208
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
209
|
+
*/
|
|
210
|
+
meta: (value: Record<string, unknown>) => InternalQueryBuilder<Context, Args, Output>;
|
|
167
211
|
output: <V extends Validator>(validator: V) => InternalQueryBuilder<Context, Args, Infer<V>>;
|
|
168
212
|
query: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
169
213
|
args: InferArgs<Args>;
|
|
@@ -184,6 +228,17 @@ interface InternalMutationBuilder<Context, Args extends ArgsValidator, Output =
|
|
|
184
228
|
readonly __lunoraProcedure: "mutation";
|
|
185
229
|
readonly __lunoraVisibility: "internal";
|
|
186
230
|
input: <A extends ArgsValidator>(validators: A) => InternalMutationBuilder<Context, A & Args, Output>;
|
|
231
|
+
/**
|
|
232
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
233
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
234
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
235
|
+
*
|
|
236
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
237
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
238
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
239
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
240
|
+
*/
|
|
241
|
+
meta: (value: Record<string, unknown>) => InternalMutationBuilder<Context, Args, Output>;
|
|
187
242
|
mutation: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
188
243
|
args: InferArgs<Args>;
|
|
189
244
|
ctx: Context;
|
|
@@ -205,6 +260,17 @@ interface InternalActionBuilder<Context, Args extends ArgsValidator, Output = un
|
|
|
205
260
|
ctx: Context;
|
|
206
261
|
}) => Output | Promise<Output>) => RegisteredAction<Args, Output>;
|
|
207
262
|
input: <A extends ArgsValidator>(validators: A) => InternalActionBuilder<Context, A & Args, Output>;
|
|
263
|
+
/**
|
|
264
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
265
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
266
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
267
|
+
*
|
|
268
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
269
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
270
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
271
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
272
|
+
*/
|
|
273
|
+
meta: (value: Record<string, unknown>) => InternalActionBuilder<Context, Args, Output>;
|
|
208
274
|
output: <V extends Validator>(validator: V) => InternalActionBuilder<Context, Args, Infer<V>>;
|
|
209
275
|
use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => InternalActionBuilder<ContextOut, Args, Output>;
|
|
210
276
|
}
|
|
@@ -517,11 +583,19 @@ type HttpMethod = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PU
|
|
|
517
583
|
/**
|
|
518
584
|
* Context handed to an HTTP action handler. A narrower view of {@link ActionContext}:
|
|
519
585
|
* HTTP actions run in the worker (the "action runtime"), separate from the
|
|
520
|
-
* transactional store, so there is no direct `db` / `vectors` / `
|
|
521
|
-
*
|
|
586
|
+
* transactional store, so there is no direct `db` / `vectors` / `storage`
|
|
587
|
+
* surface — reach the data layer through `runQuery` / `runMutation` /
|
|
522
588
|
* `runAction`, which forward to the owning shard.
|
|
523
|
-
|
|
524
|
-
|
|
589
|
+
*
|
|
590
|
+
* `scheduler` IS present (it talks to the scheduler DO, not the shard) but is
|
|
591
|
+
* optional: it exists only when the app declared `.scheduler(...)` on the
|
|
592
|
+
* generated app builder. "Receive webhook → enqueue the real work → return 200"
|
|
593
|
+
* is what HTTP actions are for, so omitting it forced every app to hand-roll a
|
|
594
|
+
* hop through a mutation plus a closed allow-list of target strings.
|
|
595
|
+
*/
|
|
596
|
+
type HttpActionCtx = Pick<ActionCtx, "auth" | "cache" | "fetch" | "runAction" | "runMutation" | "runQuery"> & {
|
|
597
|
+
readonly scheduler?: ActionCtx["scheduler"];
|
|
598
|
+
};
|
|
525
599
|
/** A raw handler wrapped by {@link httpAction}. Receives the raw request, returns the raw response. */
|
|
526
600
|
type HttpActionHandler = (context: HttpActionCtx, request: Request) => Promise<Response> | Response;
|
|
527
601
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,17 @@ interface QueryBuilder<Context, Args extends ArgsValidator, Output = undefined>
|
|
|
70
70
|
*/
|
|
71
71
|
expose: (config: ExposeConfig) => QueryBuilder<Context, Args, Output>;
|
|
72
72
|
input: <A extends ArgsValidator>(validators: A) => QueryBuilder<Context, A & Args, Output>;
|
|
73
|
+
/**
|
|
74
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
75
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
76
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
77
|
+
*
|
|
78
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
79
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
80
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
81
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
82
|
+
*/
|
|
83
|
+
meta: (value: Record<string, unknown>) => QueryBuilder<Context, Args, Output>;
|
|
73
84
|
output: <V extends Validator>(validator: V) => QueryBuilder<Context, Args, Infer<V>>;
|
|
74
85
|
query: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
75
86
|
args: InferArgs<Args>;
|
|
@@ -110,6 +121,17 @@ interface MutationBuilder<Context, Args extends ArgsValidator, Output = undefine
|
|
|
110
121
|
*/
|
|
111
122
|
expose: (config: ExposeConfig) => MutationBuilder<Context, Args, Output>;
|
|
112
123
|
input: <A extends ArgsValidator>(validators: A) => MutationBuilder<Context, A & Args, Output>;
|
|
124
|
+
/**
|
|
125
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
126
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
127
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
128
|
+
*
|
|
129
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
130
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
131
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
132
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
133
|
+
*/
|
|
134
|
+
meta: (value: Record<string, unknown>) => MutationBuilder<Context, Args, Output>;
|
|
113
135
|
mutation: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
114
136
|
args: InferArgs<Args>;
|
|
115
137
|
ctx: Context;
|
|
@@ -144,6 +166,17 @@ interface ActionBuilder<Context, Args extends ArgsValidator, Output = undefined>
|
|
|
144
166
|
*/
|
|
145
167
|
expose: (config: ExposeConfig) => ActionBuilder<Context, Args, Output>;
|
|
146
168
|
input: <A extends ArgsValidator>(validators: A) => ActionBuilder<Context, A & Args, Output>;
|
|
169
|
+
/**
|
|
170
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
171
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
172
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
173
|
+
*
|
|
174
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
175
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
176
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
177
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
178
|
+
*/
|
|
179
|
+
meta: (value: Record<string, unknown>) => ActionBuilder<Context, Args, Output>;
|
|
147
180
|
output: <V extends Validator>(validator: V) => ActionBuilder<Context, Args, Infer<V>>;
|
|
148
181
|
use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => ActionBuilder<ContextOut, Args, Output>;
|
|
149
182
|
/**
|
|
@@ -164,6 +197,17 @@ interface InternalQueryBuilder<Context, Args extends ArgsValidator, Output = und
|
|
|
164
197
|
readonly __lunoraProcedure: "query";
|
|
165
198
|
readonly __lunoraVisibility: "internal";
|
|
166
199
|
input: <A extends ArgsValidator>(validators: A) => InternalQueryBuilder<Context, A & Args, Output>;
|
|
200
|
+
/**
|
|
201
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
202
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
203
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
204
|
+
*
|
|
205
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
206
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
207
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
208
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
209
|
+
*/
|
|
210
|
+
meta: (value: Record<string, unknown>) => InternalQueryBuilder<Context, Args, Output>;
|
|
167
211
|
output: <V extends Validator>(validator: V) => InternalQueryBuilder<Context, Args, Infer<V>>;
|
|
168
212
|
query: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
169
213
|
args: InferArgs<Args>;
|
|
@@ -184,6 +228,17 @@ interface InternalMutationBuilder<Context, Args extends ArgsValidator, Output =
|
|
|
184
228
|
readonly __lunoraProcedure: "mutation";
|
|
185
229
|
readonly __lunoraVisibility: "internal";
|
|
186
230
|
input: <A extends ArgsValidator>(validators: A) => InternalMutationBuilder<Context, A & Args, Output>;
|
|
231
|
+
/**
|
|
232
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
233
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
234
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
235
|
+
*
|
|
236
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
237
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
238
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
239
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
240
|
+
*/
|
|
241
|
+
meta: (value: Record<string, unknown>) => InternalMutationBuilder<Context, Args, Output>;
|
|
187
242
|
mutation: [Output] extends [undefined] ? <R>(handler: (options: {
|
|
188
243
|
args: InferArgs<Args>;
|
|
189
244
|
ctx: Context;
|
|
@@ -205,6 +260,17 @@ interface InternalActionBuilder<Context, Args extends ArgsValidator, Output = un
|
|
|
205
260
|
ctx: Context;
|
|
206
261
|
}) => Output | Promise<Output>) => RegisteredAction<Args, Output>;
|
|
207
262
|
input: <A extends ArgsValidator>(validators: A) => InternalActionBuilder<Context, A & Args, Output>;
|
|
263
|
+
/**
|
|
264
|
+
* Attach static, per-procedure metadata. Merges across calls, is readable
|
|
265
|
+
* from middleware as `ctx.meta`, and is stamped onto the registration as
|
|
266
|
+
* `fn.meta` so codegen and other tooling can enumerate it.
|
|
267
|
+
*
|
|
268
|
+
* The point is policy that is DATA rather than a call: `.meta({ rateLimit:
|
|
269
|
+
* "pins/create" })` can be walked to generate a rate-limit registry or docs,
|
|
270
|
+
* where the same policy expressed only as `.use(rateLimit("pins/create"))`
|
|
271
|
+
* can only be executed. Mirrors tRPC's `.meta()`.
|
|
272
|
+
*/
|
|
273
|
+
meta: (value: Record<string, unknown>) => InternalActionBuilder<Context, Args, Output>;
|
|
208
274
|
output: <V extends Validator>(validator: V) => InternalActionBuilder<Context, Args, Infer<V>>;
|
|
209
275
|
use: <ContextOut>(middleware: Middleware<Context, ContextOut>) => InternalActionBuilder<ContextOut, Args, Output>;
|
|
210
276
|
}
|
|
@@ -517,11 +583,19 @@ type HttpMethod = "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PU
|
|
|
517
583
|
/**
|
|
518
584
|
* Context handed to an HTTP action handler. A narrower view of {@link ActionContext}:
|
|
519
585
|
* HTTP actions run in the worker (the "action runtime"), separate from the
|
|
520
|
-
* transactional store, so there is no direct `db` / `vectors` / `
|
|
521
|
-
*
|
|
586
|
+
* transactional store, so there is no direct `db` / `vectors` / `storage`
|
|
587
|
+
* surface — reach the data layer through `runQuery` / `runMutation` /
|
|
522
588
|
* `runAction`, which forward to the owning shard.
|
|
523
|
-
|
|
524
|
-
|
|
589
|
+
*
|
|
590
|
+
* `scheduler` IS present (it talks to the scheduler DO, not the shard) but is
|
|
591
|
+
* optional: it exists only when the app declared `.scheduler(...)` on the
|
|
592
|
+
* generated app builder. "Receive webhook → enqueue the real work → return 200"
|
|
593
|
+
* is what HTTP actions are for, so omitting it forced every app to hand-roll a
|
|
594
|
+
* hop through a mutation plus a closed allow-list of target strings.
|
|
595
|
+
*/
|
|
596
|
+
type HttpActionCtx = Pick<ActionCtx, "auth" | "cache" | "fetch" | "runAction" | "runMutation" | "runQuery"> & {
|
|
597
|
+
readonly scheduler?: ActionCtx["scheduler"];
|
|
598
|
+
};
|
|
525
599
|
/** A raw handler wrapped by {@link httpAction}. Receives the raw request, returns the raw response. */
|
|
526
600
|
type HttpActionHandler = (context: HttpActionCtx, request: Request) => Promise<Response> | Response;
|
|
527
601
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{default as t}from"./packem_shared/asBucketStorage-1pFfH-Tn.mjs";import{initLunora as i}from"./packem_shared/initLunora-
|
|
1
|
+
import{default as t}from"./packem_shared/asBucketStorage-1pFfH-Tn.mjs";import{initLunora as i}from"./packem_shared/initLunora-QNqOuG0A.mjs";import{createSecrets as p}from"./packem_shared/createSecrets-CgVPiW2C.mjs";import{LunoraEnvError as m,defineEnv as d,redactSecrets as x}from"./packem_shared/LunoraEnvError-CgpI2Mm_.mjs";import{LunoraError as c}from"./packem_shared/LunoraError-LVhdU0Lo.mjs";import{bindOrm as E,bindTableFacade as u}from"./packem_shared/bindOrm-Bp9hsM2q.mjs";import{httpAction as g,httpRoute as R,httpRouter as L,isSafeHeaderValue as P,serveStorageObject as h}from"./packem_shared/httpAction-C14NuF3V.mjs";import{defineIdentity as I}from"./packem_shared/defineIdentity-B7gfAgxx.mjs";import{onConnect as b,onDisconnect as y}from"./packem_shared/onConnect-CEtRmUpJ.mjs";import{DEFAULT_LIMIT as _,DEFAULT_MAX_LIMIT as D,clampLimit as v,defineListArgs as C}from"./packem_shared/DEFAULT_LIMIT-yHJ5O96W.mjs";import{defineMigration as V}from"./packem_shared/defineMigration-Bfpwxv2f.mjs";import{defineMutator as N}from"./packem_shared/defineMutator-BgpQ-xUo.mjs";import{composePluginMiddleware as U,defineComponent as w,definePlugin as B,defineSchemaExtension as W,installPlugins as j,mergeSchemaExtension as H}from"./packem_shared/composePluginMiddleware-COr09CXA.mjs";import{PRESENCE_DEFAULT_TTL_MS as X,PRESENCE_TABLE as q,definePresence as z,presenceExtension as G}from"./packem_shared/PRESENCE_DEFAULT_TTL_MS-C9RX3Cl6.mjs";import{protectPublic as Q}from"./packem_shared/protectPublic-BhKewPqm.mjs";import{defineAggregateIndex as Z,defineRankIndex as $,defineSchema as ee,defineTable as oe,defineVectorIndex as re}from"./packem_shared/defineAggregateIndex-_gWNmkQZ.mjs";import{defineShape as ne}from"./packem_shared/defineShape-Ds8uNqzX.mjs";import{anyApi as fe}from"./types.mjs";import{cronJobs as ae}from"@lunora/scheduler";import{ValidationError as de,v as xe}from"@lunora/values";import{allowAll as ce,deny as le,isDeny as Ee,toWhereInput as ue}from"./packem_shared/allowAll-BnyNbJZT.mjs";import{buildRlsReadRegistry as ge,composeShapeReadWhere as Re}from"./packem_shared/buildRlsReadRegistry-WdiqSj87.mjs";import{createPolicyDsl as Pe,definePermission as he,definePolicies as Ae,definePolicy as Ie,defineRole as Te}from"./packem_shared/createPolicyDsl-sV1swpkD.mjs";import{defineStorageRule as ye,defineStorageRules as Me}from"./packem_shared/defineStorageRule-BDu01PUn.mjs";import{mask as De}from"./packem_shared/mask-C6Bi78qj.mjs";import{rls as Ce}from"./packem_shared/rls-_iVsPvhX.mjs";import{storageRules as Ve}from"./packem_shared/storageRules-BptPZbi8.mjs";const e="0.0.0";export{_ as DEFAULT_LIMIT,D as DEFAULT_MAX_LIMIT,m as LunoraEnvError,c as LunoraError,X as PRESENCE_DEFAULT_TTL_MS,q as PRESENCE_TABLE,e as VERSION,de as ValidationError,ce as allowAll,fe as anyApi,t as asBucketStorage,E as bindOrm,u as bindTableFacade,ge as buildRlsReadRegistry,v as clampLimit,U as composePluginMiddleware,Re as composeShapeReadWhere,Pe as createPolicyDsl,p as createSecrets,ae as cronJobs,Z as defineAggregateIndex,w as defineComponent,d as defineEnv,I as defineIdentity,C as defineListArgs,V as defineMigration,N as defineMutator,he as definePermission,B as definePlugin,Ae as definePolicies,Ie as definePolicy,z as definePresence,$ as defineRankIndex,Te as defineRole,ee as defineSchema,W as defineSchemaExtension,ne as defineShape,ye as defineStorageRule,Me as defineStorageRules,oe as defineTable,re as defineVectorIndex,le as deny,g as httpAction,R as httpRoute,L as httpRouter,i as initLunora,j as installPlugins,Ee as isDeny,P as isSafeHeaderValue,De as mask,H as mergeSchemaExtension,b as onConnect,y as onDisconnect,G as presenceExtension,Q as protectPublic,x as redactSecrets,Ce as rls,h as serveStorageObject,Ve as storageRules,ue as toWhereInput,xe as v};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{v as o}from"@lunora/values";import{initLunora as E}from"./initLunora-
|
|
1
|
+
import{v as o}from"@lunora/values";import{initLunora as E}from"./initLunora-QNqOuG0A.mjs";import{LunoraError as p}from"./LunoraError-LVhdU0Lo.mjs";import{onDisconnect as q}from"./onConnect-CEtRmUpJ.mjs";import{defineSchemaExtension as v,defineComponent as R}from"./composePluginMiddleware-COr09CXA.mjs";import{defineTable as _}from"./defineAggregateIndex-_gWNmkQZ.mjs";const D=3e4,y=4096,l="presence",h="present",c=`${l}_${h}`,M=v(l,{tables:{[h]:_({data:o.optional(o.record(o.string(),o.any())),lastSeen:o.number(),roomId:o.string(),sessionId:o.string(),userId:o.optional(o.string())}).index("byRoomSession",["roomId","sessionId"]).index("byRoom",["roomId"])}}),{mutation:b,query:T}=E.dataModel().create(),F=(u={})=>{const m=u.ttlMs??D,f=Math.max(0,Math.min(u.disconnectGraceMs??0,m)),w=b.input({data:o.optional(o.record(o.string(),o.any())),roomId:o.string(),sessionId:o.string()}).mutation(async({args:t,ctx:s})=>{const r=Date.now(),i=s.auth.userId??void 0;if(t.data!==void 0&&new TextEncoder().encode(JSON.stringify(t.data)).length>y)throw new p("BAD_REQUEST",`presence data exceeds the ${String(y)}-byte limit`);const e=await s.db.query(c).withIndex("byRoomSession",n=>n.eq("roomId",t.roomId).eq("sessionId",t.sessionId)).first();if(e&&(e.userId??void 0)!==i)throw new p("FORBIDDEN","presence heartbeat denied: this (roomId, sessionId) is held by another identity");const a={lastSeen:r,roomId:t.roomId,sessionId:t.sessionId,...t.data===void 0?{}:{data:t.data},...i===void 0?{}:{userId:i}};return await(e?s.db.patch(e._id,a):s.db.insert(c,a)),{lastSeen:r}}),S=T.input({roomId:o.string()}).query(async({args:t,ctx:s})=>{const r=Date.now()-m,i=(await s.db.query(c).withIndex("byRoom",n=>n.eq("roomId",t.roomId)).collect()).filter(n=>n.lastSeen>r).toSorted((n,d)=>d.lastSeen-n.lastSeen),e=new Set,a=[];for(const n of i){const d=n.userId;if(d!==void 0){if(e.has(d))continue;e.add(d)}const I={lastSeen:n.lastSeen,roomId:n.roomId};d!==void 0&&(I.userId=d),n.data!==void 0&&(I.data=n.data),a.push(I)}return a}),g={...b.input({roomId:o.string()}).mutation(async({args:t,ctx:s})=>{const r=Date.now()-m,i=await s.db.query(c).withIndex("byRoom",e=>e.eq("roomId",t.roomId)).filter(e=>e.lastSeen<=r).collect();return await Promise.all(i.map(e=>s.db.delete(e._id))),{deleted:i.length}}),visibility:"internal"},x=q(async(t,s)=>{const r=s.context?.roomId,i=s.context?.sessionId;if(typeof r!="string"||typeof i!="string")return;const e=await t.db.query(c).withIndex("byRoomSession",d=>d.eq("roomId",r).eq("sessionId",i)).first();if(!e)return;const a=s.userId??void 0;if((e.userId??void 0)!==a)return;if(f===0){await t.db.delete(e._id);return}const n=Math.min(e.lastSeen,Date.now()+f-m);await t.db.patch(e._id,{lastSeen:n})});return R(l,{extension:M,functions:{disconnect:x,heartbeat:w,listPresent:S,sweep:g}})};export{D as PRESENCE_DEFAULT_TTL_MS,c as PRESENCE_TABLE,F as definePresence,M as presenceExtension};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as c}from"./functions-CDC08CWY.mjs";import{l as p}from"./policy-tag-Dprt9JWo.mjs";import{l as x}from"./run-middleware-BeEEqmdE.mjs";const w=(t,e)=>e===void 0||typeof t!="object"||t===null?t:Object.assign(Object.create(Object.getPrototypeOf(t)),t,{meta:e}),g=(t,e)=>x(t,e,r=>r),y=(t,e,r,a,i)=>async(o,m)=>{const n=c(t,m),d=await g(e,w(o,i)),l=await r({args:n,ctx:d});return a?a.parse(l):l},f=(t,e,r)=>(a,i,o)=>{const m=c(t,i);return(async function*(){const n=await g(e,a),d=r({args:m,ctx:n,signal:o})[Symbol.asyncIterator]();try{for(;;){if(o.aborted)return;const l=await d.next();if(l.done||o.aborted)return;yield l.value}}finally{await d.return?.()}})()},u=t=>{const e=[];for(const r of t){const a=p(r);a&&e.push(a)}return e.length>0?{tags:e}:void 0},s=(t,e,r)=>({__lunoraProcedure:t,...r?{__lunoraVisibility:r}:{},input:a=>s(t,{...e,args:{...e.args,...a}},r),[t]:a=>{const i=u(e.middlewares);return{args:e.args,...e.expose?{expose:e.expose}:{},handler:y(e.args,e.middlewares,a,e.output,e.meta),kind:t,...e.meta?{meta:e.meta}:{},...i?{rls:i}:{},...r?{visibility:r}:{},...e.x402?{x402:e.x402}:{}}},meta:a=>s(t,{...e,meta:{...e.meta,...a}},r),output:a=>s(t,{...e,output:a},r),...t==="query"?{stream:a=>{const i=u(e.middlewares);return{args:e.args,...e.expose?{expose:e.expose}:{},handler:f(e.args,e.middlewares,a),kind:"stream",...i?{rls:i}:{},...r?{visibility:r}:{},...e.x402?{x402:e.x402}:{}}}}:{},use:a=>s(t,{...e,middlewares:[...e.middlewares,a]},r),...r?{}:{expose:a=>s(t,{...e,expose:a},r)},...r?{}:{x402:a=>s(t,{...e,x402:a},r)}}),j={dataModel:()=>({create:t=>({action:s("action",{args:{},middlewares:[]}),internalAction:s("action",{args:{},middlewares:[]},"internal"),internalMutation:s("mutation",{args:{},middlewares:[]},"internal"),internalQuery:s("query",{args:{},middlewares:[]},"internal"),mutation:s("mutation",{args:{},middlewares:[]}),query:s("query",{args:{},middlewares:[]})})})};export{j as initLunora};
|
package/dist/types.d.mts
CHANGED
|
@@ -552,6 +552,12 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
|
|
|
552
552
|
* Absent on ordinary registrations.
|
|
553
553
|
*/
|
|
554
554
|
readonly lifecycle?: LifecycleEventKind;
|
|
555
|
+
/**
|
|
556
|
+
* Static per-procedure metadata declared with `.meta(...)`. Present so
|
|
557
|
+
* middleware (via `ctx.meta`) and tooling can read the same object; absent
|
|
558
|
+
* when the chain never called `.meta()`.
|
|
559
|
+
*/
|
|
560
|
+
readonly meta?: Record<string, unknown>;
|
|
555
561
|
readonly visibility?: FunctionVisibility;
|
|
556
562
|
/**
|
|
557
563
|
* Set by the `.x402({ price })` builder modifier. Marks the procedure as paid
|
|
@@ -563,6 +569,48 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
|
|
|
563
569
|
type RegisteredQuery<A extends ArgsValidator, R> = RegisteredFunction<A, R, "query">;
|
|
564
570
|
type RegisteredMutation<A extends ArgsValidator, R> = RegisteredFunction<A, R, "mutation">;
|
|
565
571
|
type RegisteredAction<A extends ArgsValidator, R> = RegisteredFunction<A, R, "action">;
|
|
572
|
+
/**
|
|
573
|
+
* Structural mirror of `@lunora/client`'s `FunctionReference` — the handle the
|
|
574
|
+
* generated `api` / `internal` objects hand you, carrying `<file>:<function>`
|
|
575
|
+
* in `__lunoraRef`. Redeclared here so `@lunora/server` needs no dependency on
|
|
576
|
+
* the client package, exactly as {@link Scheduler} avoids one on
|
|
577
|
+
* `@lunora/scheduler`. `RegisteredFunction` has no `__lunoraRef`, so the two
|
|
578
|
+
* shapes never overlap.
|
|
579
|
+
*/
|
|
580
|
+
interface FunctionHandle<Kind extends "action" | "mutation" | "query" | "stream", Args, Return> {
|
|
581
|
+
/** Phantom marker carrying the type parameters; never present at runtime. */
|
|
582
|
+
readonly __lunoraPhantom?: {
|
|
583
|
+
args: Args;
|
|
584
|
+
kind: Kind;
|
|
585
|
+
returns: Return;
|
|
586
|
+
};
|
|
587
|
+
readonly __lunoraRef: string;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* `ctx.runQuery` — overloaded, see the note above.
|
|
591
|
+
*
|
|
592
|
+
* A single generic signature over the reference would be nicer (TS will not
|
|
593
|
+
* contextually type a parameter against a multi-signature type, so a hand-built
|
|
594
|
+
* ctx object must annotate its `(reference, args)` explicitly — see
|
|
595
|
+
* `@lunora/testing`'s harness). It does not work: a concrete
|
|
596
|
+
* `RegisteredQuery<{…}, number>` is not assignable to a
|
|
597
|
+
* `RegisteredFunction<ArgsValidator, …>` constraint, because `handler`'s args
|
|
598
|
+
* are in a contravariant position. Two inference sites it is.
|
|
599
|
+
*/
|
|
600
|
+
interface RunQuery {
|
|
601
|
+
<A extends ArgsValidator, R>(reference: RegisteredQuery<A, R>, args: InferArgs<A>): Promise<R>;
|
|
602
|
+
<Args, R>(reference: FunctionHandle<"query", Args, R>, args: Args): Promise<R>;
|
|
603
|
+
}
|
|
604
|
+
/** `ctx.runMutation` — overloaded for the same reason as {@link RunQuery}. */
|
|
605
|
+
interface RunMutation {
|
|
606
|
+
<A extends ArgsValidator, R>(reference: RegisteredMutation<A, R>, args: InferArgs<A>): Promise<R>;
|
|
607
|
+
<Args, R>(reference: FunctionHandle<"mutation", Args, R>, args: Args): Promise<R>;
|
|
608
|
+
}
|
|
609
|
+
/** `ctx.runAction` — overloaded for the same reason as {@link RunQuery}. */
|
|
610
|
+
interface RunAction {
|
|
611
|
+
<A extends ArgsValidator, R>(reference: RegisteredAction<A, R>, args: InferArgs<A>): Promise<R>;
|
|
612
|
+
<Args, R>(reference: FunctionHandle<"action", Args, R>, args: Args): Promise<R>;
|
|
613
|
+
}
|
|
566
614
|
/** Which side of the WebSocket lifecycle a hook fires on. */
|
|
567
615
|
type LifecycleEventKind = "connect" | "disconnect";
|
|
568
616
|
/**
|
|
@@ -752,6 +800,27 @@ interface PaginationResult<T = Record<string, unknown>> {
|
|
|
752
800
|
* (schema-agnostic) `@lunora/server` reader.
|
|
753
801
|
*/
|
|
754
802
|
interface TableReader<Row = Record<string, unknown>> {
|
|
803
|
+
/**
|
|
804
|
+
* Iterate rows lazily: `for await (const row of ctx.db.query("t").withIndex(…))`.
|
|
805
|
+
*
|
|
806
|
+
* Pages through the result set behind the scenes and yields row by row, so
|
|
807
|
+
* a consumer that stops early stops the reads too. `.collect()` is still the
|
|
808
|
+
* right terminal when you want the whole set; this exists for the cases
|
|
809
|
+
* where you cannot know up front how far you need to read.
|
|
810
|
+
*
|
|
811
|
+
* That is what merged/ordered index streams need. Reimplementing Convex's
|
|
812
|
+
* `convex-helpers/server/stream` in userland previously meant materialising
|
|
813
|
+
* each branch with a bounded `.take(1024)` before merging, so asking a
|
|
814
|
+
* merged stream for ONE row read up to 1,024 rows per branch. The k-way merge itself is application code and stays there — only
|
|
815
|
+
* the laziness had to come from the database layer.
|
|
816
|
+
*
|
|
817
|
+
* Iteration pages through `.paginate()`, so it follows the same order —
|
|
818
|
+
* which is `.collect()`'s order whenever the sort key is unique. Under a
|
|
819
|
+
* TIED sort key (an unindexed read whose rows share `_creationTime`) the
|
|
820
|
+
* two can disagree, because the tie-break is left to SQLite. Read through
|
|
821
|
+
* an index when order matters, exactly as you would for `.paginate()`.
|
|
822
|
+
*/
|
|
823
|
+
[Symbol.asyncIterator]: () => AsyncIterator<Row>;
|
|
755
824
|
collect: () => Promise<Row[]>;
|
|
756
825
|
filter: (predicate: (document: Row) => boolean) => TableReader<Row>;
|
|
757
826
|
first: () => Promise<Row | null>;
|
|
@@ -1803,6 +1872,13 @@ interface QueryCtx {
|
|
|
1803
1872
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1804
1873
|
readonly log: LunoraLogger;
|
|
1805
1874
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
1875
|
+
/**
|
|
1876
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
1877
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
1878
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
1879
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
1880
|
+
*/
|
|
1881
|
+
readonly meta?: Record<string, unknown>;
|
|
1806
1882
|
readonly metrics: LunoraMetrics;
|
|
1807
1883
|
/**
|
|
1808
1884
|
* Wall-clock time (epoch ms) the function began, captured once so the whole
|
|
@@ -1820,7 +1896,7 @@ interface QueryCtx {
|
|
|
1820
1896
|
* `runMutation` on a `QueryCtx` (writes are not allowed from a query).
|
|
1821
1897
|
* Mirrors Convex's `ctx.runQuery`.
|
|
1822
1898
|
*/
|
|
1823
|
-
readonly runQuery:
|
|
1899
|
+
readonly runQuery: RunQuery;
|
|
1824
1900
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1825
1901
|
readonly secrets: Secrets;
|
|
1826
1902
|
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
@@ -1851,6 +1927,13 @@ interface MutationCtx {
|
|
|
1851
1927
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1852
1928
|
readonly log: LunoraLogger;
|
|
1853
1929
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
1930
|
+
/**
|
|
1931
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
1932
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
1933
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
1934
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
1935
|
+
*/
|
|
1936
|
+
readonly meta?: Record<string, unknown>;
|
|
1854
1937
|
readonly metrics: LunoraMetrics;
|
|
1855
1938
|
/**
|
|
1856
1939
|
* Wall-clock time (epoch ms) the function began, captured once so the whole
|
|
@@ -1868,14 +1951,14 @@ interface MutationCtx {
|
|
|
1868
1951
|
* failure does not roll back earlier writes (the same as a top-level
|
|
1869
1952
|
* mutation). Mirrors Convex's `ctx.runMutation`.
|
|
1870
1953
|
*/
|
|
1871
|
-
readonly runMutation:
|
|
1954
|
+
readonly runMutation: RunMutation;
|
|
1872
1955
|
/**
|
|
1873
1956
|
* Compose a read-only subquery in-process, reusing this mutation's `db`.
|
|
1874
1957
|
* Executes the referenced query's handler directly — no fresh DO RPC — so
|
|
1875
1958
|
* it observes this mutation's in-flight writes. Mirrors Convex's
|
|
1876
1959
|
* `ctx.runQuery`.
|
|
1877
1960
|
*/
|
|
1878
|
-
readonly runQuery:
|
|
1961
|
+
readonly runQuery: RunQuery;
|
|
1879
1962
|
readonly scheduler: Scheduler;
|
|
1880
1963
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1881
1964
|
readonly secrets: Secrets;
|
|
@@ -1917,6 +2000,13 @@ interface ActionCtx {
|
|
|
1917
2000
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1918
2001
|
readonly log: LunoraLogger;
|
|
1919
2002
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
2003
|
+
/**
|
|
2004
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
2005
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
2006
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
2007
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
2008
|
+
*/
|
|
2009
|
+
readonly meta?: Record<string, unknown>;
|
|
1920
2010
|
readonly metrics: LunoraMetrics;
|
|
1921
2011
|
/**
|
|
1922
2012
|
* Wall-clock time (epoch ms) the action began, captured once for convenience
|
|
@@ -1924,9 +2014,9 @@ interface ActionCtx {
|
|
|
1924
2014
|
* may also use ambient `Date.now()` freely.
|
|
1925
2015
|
*/
|
|
1926
2016
|
readonly now: number;
|
|
1927
|
-
readonly runAction:
|
|
1928
|
-
readonly runMutation:
|
|
1929
|
-
readonly runQuery:
|
|
2017
|
+
readonly runAction: RunAction;
|
|
2018
|
+
readonly runMutation: RunMutation;
|
|
2019
|
+
readonly runQuery: RunQuery;
|
|
1930
2020
|
readonly scheduler: Scheduler;
|
|
1931
2021
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1932
2022
|
readonly secrets: Secrets;
|
package/dist/types.d.ts
CHANGED
|
@@ -552,6 +552,12 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
|
|
|
552
552
|
* Absent on ordinary registrations.
|
|
553
553
|
*/
|
|
554
554
|
readonly lifecycle?: LifecycleEventKind;
|
|
555
|
+
/**
|
|
556
|
+
* Static per-procedure metadata declared with `.meta(...)`. Present so
|
|
557
|
+
* middleware (via `ctx.meta`) and tooling can read the same object; absent
|
|
558
|
+
* when the chain never called `.meta()`.
|
|
559
|
+
*/
|
|
560
|
+
readonly meta?: Record<string, unknown>;
|
|
555
561
|
readonly visibility?: FunctionVisibility;
|
|
556
562
|
/**
|
|
557
563
|
* Set by the `.x402({ price })` builder modifier. Marks the procedure as paid
|
|
@@ -563,6 +569,48 @@ interface RegisteredFunction<A extends ArgsValidator, R, Kind extends FunctionKi
|
|
|
563
569
|
type RegisteredQuery<A extends ArgsValidator, R> = RegisteredFunction<A, R, "query">;
|
|
564
570
|
type RegisteredMutation<A extends ArgsValidator, R> = RegisteredFunction<A, R, "mutation">;
|
|
565
571
|
type RegisteredAction<A extends ArgsValidator, R> = RegisteredFunction<A, R, "action">;
|
|
572
|
+
/**
|
|
573
|
+
* Structural mirror of `@lunora/client`'s `FunctionReference` — the handle the
|
|
574
|
+
* generated `api` / `internal` objects hand you, carrying `<file>:<function>`
|
|
575
|
+
* in `__lunoraRef`. Redeclared here so `@lunora/server` needs no dependency on
|
|
576
|
+
* the client package, exactly as {@link Scheduler} avoids one on
|
|
577
|
+
* `@lunora/scheduler`. `RegisteredFunction` has no `__lunoraRef`, so the two
|
|
578
|
+
* shapes never overlap.
|
|
579
|
+
*/
|
|
580
|
+
interface FunctionHandle<Kind extends "action" | "mutation" | "query" | "stream", Args, Return> {
|
|
581
|
+
/** Phantom marker carrying the type parameters; never present at runtime. */
|
|
582
|
+
readonly __lunoraPhantom?: {
|
|
583
|
+
args: Args;
|
|
584
|
+
kind: Kind;
|
|
585
|
+
returns: Return;
|
|
586
|
+
};
|
|
587
|
+
readonly __lunoraRef: string;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* `ctx.runQuery` — overloaded, see the note above.
|
|
591
|
+
*
|
|
592
|
+
* A single generic signature over the reference would be nicer (TS will not
|
|
593
|
+
* contextually type a parameter against a multi-signature type, so a hand-built
|
|
594
|
+
* ctx object must annotate its `(reference, args)` explicitly — see
|
|
595
|
+
* `@lunora/testing`'s harness). It does not work: a concrete
|
|
596
|
+
* `RegisteredQuery<{…}, number>` is not assignable to a
|
|
597
|
+
* `RegisteredFunction<ArgsValidator, …>` constraint, because `handler`'s args
|
|
598
|
+
* are in a contravariant position. Two inference sites it is.
|
|
599
|
+
*/
|
|
600
|
+
interface RunQuery {
|
|
601
|
+
<A extends ArgsValidator, R>(reference: RegisteredQuery<A, R>, args: InferArgs<A>): Promise<R>;
|
|
602
|
+
<Args, R>(reference: FunctionHandle<"query", Args, R>, args: Args): Promise<R>;
|
|
603
|
+
}
|
|
604
|
+
/** `ctx.runMutation` — overloaded for the same reason as {@link RunQuery}. */
|
|
605
|
+
interface RunMutation {
|
|
606
|
+
<A extends ArgsValidator, R>(reference: RegisteredMutation<A, R>, args: InferArgs<A>): Promise<R>;
|
|
607
|
+
<Args, R>(reference: FunctionHandle<"mutation", Args, R>, args: Args): Promise<R>;
|
|
608
|
+
}
|
|
609
|
+
/** `ctx.runAction` — overloaded for the same reason as {@link RunQuery}. */
|
|
610
|
+
interface RunAction {
|
|
611
|
+
<A extends ArgsValidator, R>(reference: RegisteredAction<A, R>, args: InferArgs<A>): Promise<R>;
|
|
612
|
+
<Args, R>(reference: FunctionHandle<"action", Args, R>, args: Args): Promise<R>;
|
|
613
|
+
}
|
|
566
614
|
/** Which side of the WebSocket lifecycle a hook fires on. */
|
|
567
615
|
type LifecycleEventKind = "connect" | "disconnect";
|
|
568
616
|
/**
|
|
@@ -752,6 +800,27 @@ interface PaginationResult<T = Record<string, unknown>> {
|
|
|
752
800
|
* (schema-agnostic) `@lunora/server` reader.
|
|
753
801
|
*/
|
|
754
802
|
interface TableReader<Row = Record<string, unknown>> {
|
|
803
|
+
/**
|
|
804
|
+
* Iterate rows lazily: `for await (const row of ctx.db.query("t").withIndex(…))`.
|
|
805
|
+
*
|
|
806
|
+
* Pages through the result set behind the scenes and yields row by row, so
|
|
807
|
+
* a consumer that stops early stops the reads too. `.collect()` is still the
|
|
808
|
+
* right terminal when you want the whole set; this exists for the cases
|
|
809
|
+
* where you cannot know up front how far you need to read.
|
|
810
|
+
*
|
|
811
|
+
* That is what merged/ordered index streams need. Reimplementing Convex's
|
|
812
|
+
* `convex-helpers/server/stream` in userland previously meant materialising
|
|
813
|
+
* each branch with a bounded `.take(1024)` before merging, so asking a
|
|
814
|
+
* merged stream for ONE row read up to 1,024 rows per branch. The k-way merge itself is application code and stays there — only
|
|
815
|
+
* the laziness had to come from the database layer.
|
|
816
|
+
*
|
|
817
|
+
* Iteration pages through `.paginate()`, so it follows the same order —
|
|
818
|
+
* which is `.collect()`'s order whenever the sort key is unique. Under a
|
|
819
|
+
* TIED sort key (an unindexed read whose rows share `_creationTime`) the
|
|
820
|
+
* two can disagree, because the tie-break is left to SQLite. Read through
|
|
821
|
+
* an index when order matters, exactly as you would for `.paginate()`.
|
|
822
|
+
*/
|
|
823
|
+
[Symbol.asyncIterator]: () => AsyncIterator<Row>;
|
|
755
824
|
collect: () => Promise<Row[]>;
|
|
756
825
|
filter: (predicate: (document: Row) => boolean) => TableReader<Row>;
|
|
757
826
|
first: () => Promise<Row | null>;
|
|
@@ -1803,6 +1872,13 @@ interface QueryCtx {
|
|
|
1803
1872
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1804
1873
|
readonly log: LunoraLogger;
|
|
1805
1874
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
1875
|
+
/**
|
|
1876
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
1877
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
1878
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
1879
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
1880
|
+
*/
|
|
1881
|
+
readonly meta?: Record<string, unknown>;
|
|
1806
1882
|
readonly metrics: LunoraMetrics;
|
|
1807
1883
|
/**
|
|
1808
1884
|
* Wall-clock time (epoch ms) the function began, captured once so the whole
|
|
@@ -1820,7 +1896,7 @@ interface QueryCtx {
|
|
|
1820
1896
|
* `runMutation` on a `QueryCtx` (writes are not allowed from a query).
|
|
1821
1897
|
* Mirrors Convex's `ctx.runQuery`.
|
|
1822
1898
|
*/
|
|
1823
|
-
readonly runQuery:
|
|
1899
|
+
readonly runQuery: RunQuery;
|
|
1824
1900
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1825
1901
|
readonly secrets: Secrets;
|
|
1826
1902
|
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
@@ -1851,6 +1927,13 @@ interface MutationCtx {
|
|
|
1851
1927
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1852
1928
|
readonly log: LunoraLogger;
|
|
1853
1929
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
1930
|
+
/**
|
|
1931
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
1932
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
1933
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
1934
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
1935
|
+
*/
|
|
1936
|
+
readonly meta?: Record<string, unknown>;
|
|
1854
1937
|
readonly metrics: LunoraMetrics;
|
|
1855
1938
|
/**
|
|
1856
1939
|
* Wall-clock time (epoch ms) the function began, captured once so the whole
|
|
@@ -1868,14 +1951,14 @@ interface MutationCtx {
|
|
|
1868
1951
|
* failure does not roll back earlier writes (the same as a top-level
|
|
1869
1952
|
* mutation). Mirrors Convex's `ctx.runMutation`.
|
|
1870
1953
|
*/
|
|
1871
|
-
readonly runMutation:
|
|
1954
|
+
readonly runMutation: RunMutation;
|
|
1872
1955
|
/**
|
|
1873
1956
|
* Compose a read-only subquery in-process, reusing this mutation's `db`.
|
|
1874
1957
|
* Executes the referenced query's handler directly — no fresh DO RPC — so
|
|
1875
1958
|
* it observes this mutation's in-flight writes. Mirrors Convex's
|
|
1876
1959
|
* `ctx.runQuery`.
|
|
1877
1960
|
*/
|
|
1878
|
-
readonly runQuery:
|
|
1961
|
+
readonly runQuery: RunQuery;
|
|
1879
1962
|
readonly scheduler: Scheduler;
|
|
1880
1963
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1881
1964
|
readonly secrets: Secrets;
|
|
@@ -1917,6 +2000,13 @@ interface ActionCtx {
|
|
|
1917
2000
|
/** Structured, function-attributed logger; see {@link LunoraLogger}. */
|
|
1918
2001
|
readonly log: LunoraLogger;
|
|
1919
2002
|
/** Application counters, gauges, and histograms; see {@link LunoraMetrics}. */
|
|
2003
|
+
/**
|
|
2004
|
+
* Static metadata declared on this procedure with `.meta(...)`, merged
|
|
2005
|
+
* across calls. Present so middleware can read the policy it is meant to
|
|
2006
|
+
* enforce (`ctx.meta.rateLimit`, …) instead of having it hard-wired at each
|
|
2007
|
+
* `.use()` site; absent when the procedure never called `.meta()`.
|
|
2008
|
+
*/
|
|
2009
|
+
readonly meta?: Record<string, unknown>;
|
|
1920
2010
|
readonly metrics: LunoraMetrics;
|
|
1921
2011
|
/**
|
|
1922
2012
|
* Wall-clock time (epoch ms) the action began, captured once for convenience
|
|
@@ -1924,9 +2014,9 @@ interface ActionCtx {
|
|
|
1924
2014
|
* may also use ambient `Date.now()` freely.
|
|
1925
2015
|
*/
|
|
1926
2016
|
readonly now: number;
|
|
1927
|
-
readonly runAction:
|
|
1928
|
-
readonly runMutation:
|
|
1929
|
-
readonly runQuery:
|
|
2017
|
+
readonly runAction: RunAction;
|
|
2018
|
+
readonly runMutation: RunMutation;
|
|
2019
|
+
readonly runQuery: RunQuery;
|
|
1930
2020
|
readonly scheduler: Scheduler;
|
|
1931
2021
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1932
2022
|
readonly secrets: Secrets;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.54",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@lunora/errors": "1.0.0-alpha.9",
|
|
70
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
70
|
+
"@lunora/scheduler": "1.0.0-alpha.15",
|
|
71
71
|
"@lunora/values": "1.0.0-alpha.12",
|
|
72
72
|
"drizzle-orm": "^0.45.2",
|
|
73
73
|
"hono": "^4.12.32"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as c}from"./functions-CDC08CWY.mjs";import{l as g}from"./policy-tag-Dprt9JWo.mjs";import{l as p}from"./run-middleware-BeEEqmdE.mjs";const x=(r,e)=>p(r,e,a=>a),w=(r,e,a,t)=>async(i,o)=>{const d=c(r,o),n=await x(e,i),l=await a({args:d,ctx:n});return t?t.parse(l):l},y=(r,e,a)=>(t,i,o)=>{const d=c(r,i);return(async function*(){const n=await x(e,t),l=a({args:d,ctx:n,signal:o})[Symbol.asyncIterator]();try{for(;;){if(o.aborted)return;const u=await l.next();if(u.done||o.aborted)return;yield u.value}}finally{await l.return?.()}})()},m=r=>{const e=[];for(const a of r){const t=g(a);t&&e.push(t)}return e.length>0?{tags:e}:void 0},s=(r,e,a)=>({__lunoraProcedure:r,...a?{__lunoraVisibility:a}:{},input:t=>s(r,{...e,args:{...e.args,...t}},a),[r]:t=>{const i=m(e.middlewares);return{args:e.args,...e.expose?{expose:e.expose}:{},handler:w(e.args,e.middlewares,t,e.output),kind:r,...i?{rls:i}:{},...a?{visibility:a}:{},...e.x402?{x402:e.x402}:{}}},output:t=>s(r,{...e,output:t},a),...r==="query"?{stream:t=>{const i=m(e.middlewares);return{args:e.args,...e.expose?{expose:e.expose}:{},handler:y(e.args,e.middlewares,t),kind:"stream",...i?{rls:i}:{},...a?{visibility:a}:{},...e.x402?{x402:e.x402}:{}}}}:{},use:t=>s(r,{...e,middlewares:[...e.middlewares,t]},a),...a?{}:{expose:t=>s(r,{...e,expose:t},a)},...a?{}:{x402:t=>s(r,{...e,x402:t},a)}}),q={dataModel:()=>({create:r=>({action:s("action",{args:{},middlewares:[]}),internalAction:s("action",{args:{},middlewares:[]},"internal"),internalMutation:s("mutation",{args:{},middlewares:[]},"internal"),internalQuery:s("query",{args:{},middlewares:[]},"internal"),mutation:s("mutation",{args:{},middlewares:[]}),query:s("query",{args:{},middlewares:[]})})})};export{q as initLunora};
|