@lunora/codegen 1.0.0-alpha.329 → 1.0.0-alpha.330
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 +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{MUTATORS_FILENAME-Jkk8Zgkb.mjs → MUTATORS_FILENAME-B_I0kkvJ.mjs} +1 -1
- package/dist/packem_shared/{NOTIFY_FILENAME-DiYZjYts.mjs → NOTIFY_FILENAME-DOIxn0Qb.mjs} +1 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DdPW4JCi.mjs +31 -0
- package/dist/packem_shared/{SHAPES_FILENAME-DkBUN9dK.mjs → SHAPES_FILENAME-D7Ifi5Ce.mjs} +1 -1
- package/dist/packem_shared/chain-ZlTHdRo2.mjs +1 -0
- package/dist/packem_shared/classify-procedure-call-Bw5sia-K.mjs +1 -0
- package/dist/packem_shared/{context-property-calls-eO5eiVZG.mjs → context-property-calls-Co_G3ENU.mjs} +1 -1
- package/dist/packem_shared/{context-root-D-pTjHtx.mjs → context-root-BTW5XwVq.mjs} +1 -1
- package/dist/packem_shared/{database-calls-DJgmh0Kv.mjs → database-calls-D-GwIhWO.mjs} +1 -1
- package/dist/packem_shared/{discoverCrons-DBnCama4.mjs → discoverCrons-B2SdRjRO.mjs} +1 -1
- package/dist/packem_shared/{discoverFunctions-CIJja4zp.mjs → discoverFunctions-C9Ra5XXH.mjs} +1 -1
- package/dist/packem_shared/discoverHyperdriveCalls-DfCAjBgd.mjs +1 -0
- package/dist/packem_shared/{discoverInserts-CednbRCq.mjs → discoverInserts-T5ojinqL.mjs} +1 -1
- package/dist/packem_shared/discoverMaskProcedures-DKd9fVDa.mjs +1 -0
- package/dist/packem_shared/{discoverMigrations-C9mLIhGZ.mjs → discoverMigrations-ClgjUkaG.mjs} +1 -1
- package/dist/packem_shared/{discoverNondeterministicCalls-B6FUSWes.mjs → discoverNondeterministicCalls-UCUCyCox.mjs} +1 -1
- package/dist/packem_shared/{discoverQueries-BezURxvr.mjs → discoverQueries-u2XNpxsn.mjs} +1 -1
- package/dist/packem_shared/discoverR2sqlCalls-jz5KouxF.mjs +1 -0
- package/dist/packem_shared/{discoverRlsMetadata-DCgP2H39.mjs → discoverRlsMetadata-D2G3YAoe.mjs} +1 -1
- package/dist/packem_shared/{discoverRlsProcedures-Os1lrVX_.mjs → discoverRlsProcedures-BD8aG1BU.mjs} +1 -1
- package/dist/packem_shared/{discoverStorageRulesMetadata-BTD9Vs5X.mjs → discoverStorageRulesMetadata-C2ceH0ZO.mjs} +1 -1
- package/dist/packem_shared/{emitShard-Ba8hJ_G8.mjs → emitShard-DtfjUgjj.mjs} +1 -1
- package/dist/packem_shared/{exported-procedure-chains-DOFtzPZn.mjs → exported-procedure-chains-CVzkVdq4.mjs} +1 -1
- package/dist/packem_shared/{index-iWQbulvu.mjs → index-BPUxZYM5.mjs} +1 -1
- package/dist/packem_shared/{module-specifiers-WF8iAydP.mjs → module-specifiers-BctA0m_p.mjs} +1 -1
- package/dist/packem_shared/{shard-BtImwCVL.mjs → shard-CsfiXxV0.mjs} +130 -105
- package/package.json +9 -9
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-GV-_yNKe.mjs +0 -11
- package/dist/packem_shared/chain-DYBhMcDK.mjs +0 -1
- package/dist/packem_shared/classify-procedure-call-DUBO9bqm.mjs +0 -1
- package/dist/packem_shared/discoverHyperdriveCalls-DVIQ0i_e.mjs +0 -1
- package/dist/packem_shared/discoverMaskProcedures-B4k9BS0s.mjs +0 -1
- package/dist/packem_shared/discoverR2sqlCalls-B9Q6xfi6.mjs +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{LunoraError as
|
|
1
|
+
import{LunoraError as de}from"@lunora/errors";import{serializeSchemaSnapshot as Ht,hashSchemaSnapshot as Vt}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{isHyperdriveGlobalTable as Kt,isD1GlobalTable as Gt}from"./isD1GlobalTable-udvHAAzD.mjs";import{r as Qt}from"./json-data-Chfs2Cz5.mjs";import{r as E,e as Jt,a as zt,b as Yt,c as Xt,d as Zt,f as er,g as tr,h as rr,i as nr,j as ar,k as sr,l as or,m as ir,n as dr,o as cr,p as lr,q as ur}from"./shard-runtime-BpoCV-aM.mjs";import{u as Y,i as hr,a as pr,I as mr,c as gr,G as fr,d as br}from"./shared-DnCokNcE.mjs";import{p as wr}from"./platform-8oj7iXQy.mjs";import{i as yr}from"./schema-BgM8A3XV.mjs";const h=(n,e)=>`((): (() => ${e}) => { let cached: ${e} | undefined; return () => (cached ??= JSON.parse(${JSON.stringify(JSON.stringify(n))}) as ${e}); })()`,ce=["categories","description","facing","level","remediation","title"],vr=n=>{const e={};return{advisoryRows:n.map(a=>{let r=e[a.name];return r||(r=Object.fromEntries(ce.filter(o=>o in a).map(o=>[o,a[o]])),e[a.name]=r),Object.fromEntries(Object.entries(a).filter(([o,d])=>!ce.includes(o)||JSON.stringify(d)!==JSON.stringify(r[o])))}),advisoryRules:e}},kr=` /**
|
|
2
2
|
* The bare writer every admin/maintenance entry point writes through.
|
|
3
3
|
*
|
|
4
4
|
* Admin and maintenance writes go through the SAME reactive-cache hooks as a
|
|
@@ -30,7 +30,7 @@ import{LunoraError as $t}from"@lunora/errors";import{serializeSchemaSnapshot as
|
|
|
30
30
|
schema: schema as unknown as SchemaLike,
|
|
31
31
|
sql: this.sql as SqlExec,
|
|
32
32
|
});
|
|
33
|
-
}`,
|
|
33
|
+
}`,g=(n="")=>` const writer = this.adminWriter(${n});`,Sr=`${kr}
|
|
34
34
|
|
|
35
35
|
protected override async runShardDataMigration(args: RunShardMigrationArgs): Promise<MigrationRunResult> {
|
|
36
36
|
this.ensureMigrated();
|
|
@@ -47,7 +47,7 @@ import{LunoraError as $t}from"@lunora/errors";import{serializeSchemaSnapshot as
|
|
|
47
47
|
throw new LunoraError("MIGRATION_NOT_FOUND", \`data migration "\${args.id}" is not registered\`, { status: 404 });
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
${
|
|
50
|
+
${g()}
|
|
51
51
|
|
|
52
52
|
return runDataMigration({
|
|
53
53
|
...(args.batchSize === undefined ? {} : { batchSize: args.batchSize }),
|
|
@@ -80,7 +80,7 @@ ${m()}
|
|
|
80
80
|
|
|
81
81
|
this.ensureMigrated();
|
|
82
82
|
|
|
83
|
-
${
|
|
83
|
+
${g("headroom ?? this.transactionHeadroom()")}
|
|
84
84
|
|
|
85
85
|
if (args.op === "insert") {
|
|
86
86
|
const id = await writer.insert(args.table, args.doc ?? {});
|
|
@@ -135,7 +135,7 @@ ${m("headroom ?? this.transactionHeadroom()")}
|
|
|
135
135
|
protected override async runShardExport(args: RunShardExportArgs): Promise<ExportRow[]> {
|
|
136
136
|
this.ensureMigrated();
|
|
137
137
|
|
|
138
|
-
${
|
|
138
|
+
${g()}
|
|
139
139
|
|
|
140
140
|
const rows: ExportRow[] = [];
|
|
141
141
|
|
|
@@ -152,7 +152,7 @@ ${m()}
|
|
|
152
152
|
protected override async runShardImport(args: RunShardImportArgs): Promise<ImportShardResult> {
|
|
153
153
|
this.ensureMigrated();
|
|
154
154
|
|
|
155
|
-
${
|
|
155
|
+
${g()}
|
|
156
156
|
|
|
157
157
|
// \`importShardRows\` inserts with \`allowExplicitId\`, so a source
|
|
158
158
|
// database's \`_id\`s carry across verbatim and every foreign key
|
|
@@ -163,7 +163,7 @@ ${m()}
|
|
|
163
163
|
protected override async runShardRankBefore(args: RunShardRankBeforeArgs): Promise<{ before: number; total: number }> {
|
|
164
164
|
this.ensureMigrated();
|
|
165
165
|
|
|
166
|
-
${
|
|
166
|
+
${g()}
|
|
167
167
|
|
|
168
168
|
// \`rankBefore\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
|
|
169
169
|
// but the shard writer from \`createShardCtxDb\` always defines it.
|
|
@@ -181,7 +181,7 @@ ${m()}
|
|
|
181
181
|
protected override async runShardFindRelated(args: RunShardFindRelatedArgs): Promise<RelatedPage> {
|
|
182
182
|
this.ensureMigrated();
|
|
183
183
|
|
|
184
|
-
${
|
|
184
|
+
${g()}
|
|
185
185
|
|
|
186
186
|
// \`related\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
|
|
187
187
|
// but the shard writer from \`createShardCtxDb\` always defines it — it
|
|
@@ -199,7 +199,7 @@ ${m()}
|
|
|
199
199
|
protected override async runShardRankPage(args: RunShardRankPageArgs): Promise<ShardRankPageResult> {
|
|
200
200
|
this.ensureMigrated();
|
|
201
201
|
|
|
202
|
-
${
|
|
202
|
+
${g()}
|
|
203
203
|
|
|
204
204
|
// \`rankPageRows\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
|
|
205
205
|
// but the shard writer from \`createShardCtxDb\` always defines it. The sort
|
|
@@ -220,18 +220,18 @@ ${m()}
|
|
|
220
220
|
protected override async runShardApplyCdc(args: RunShardApplyCdcArgs): Promise<{ applied: number }> {
|
|
221
221
|
this.ensureMigrated();
|
|
222
222
|
|
|
223
|
-
${
|
|
223
|
+
${g()}
|
|
224
224
|
|
|
225
225
|
await applyCdcChanges(writer, args.changes);
|
|
226
226
|
|
|
227
227
|
return { applied: args.changes.length };
|
|
228
|
-
}`,
|
|
229
|
-
orm: databaseContext.orm,`,
|
|
230
|
-
orm: { configurable: true, enumerable: true, value: mutationDatabase.orm, writable: true },`,
|
|
228
|
+
}`,Rr=({actionOnlyBuild:n,actionOnlyFields:e,agentsBuild:t,agentsContextField:a,containersBuild:r,containersContextField:o,databaseOptions:d,everyContextBuild:f,everyContextField:v,facadeBlock:l,globalDatabaseLine:b,lazyFunctions:c=!1,notifyBuild:L,ormContextField:S,paymentsBuild:R,paymentsContextField:I,queuesBuild:P,queuesContextField:k,topicsBuild:N,topicsContextField:i,vectorsBuild:w,vectorsContextField:M,workflowsBuild:$,workflowsContextField:q})=>{const x=e.length>0,F=S===""?"{ db }":"{ db, orm: bindOrm(facade) }",U=S===""?"":`
|
|
229
|
+
orm: databaseContext.orm,`,O=S===""?"":`
|
|
230
|
+
orm: { configurable: true, enumerable: true, value: mutationDatabase.orm, writable: true },`,u=x?`
|
|
231
231
|
// ActionCtx-only helpers (external, non-deterministic I/O): constructed
|
|
232
232
|
// and attached only for an \`action\` so query/mutation ctx never carry them.
|
|
233
233
|
if (isAction) {
|
|
234
|
-
${n.replaceAll(/^(?=.)/gmu," ")}${e.map(
|
|
234
|
+
${n.replaceAll(/^(?=.)/gmu," ")}${e.map(p=>` ctx.${p} = ${p};`).join(`
|
|
235
235
|
`)}
|
|
236
236
|
}
|
|
237
237
|
`:"";return` private buildCtx(options: { bookmarks?: DispatchBookmark | undefined; functionPath?: string | undefined; headroom?: TransactionHeadroomTracker | undefined; identity?: SubscriptionIdentity | undefined; kind?: "query" | undefined; onRead?: ((table: string, idOrScan?: string) => void) | undefined; onReadRange?: ((range: KeyRange) => void) | undefined; scope?: QueryReadScope | undefined; trusted?: boolean | undefined } = {}): unknown {
|
|
@@ -261,7 +261,7 @@ ${n.replaceAll(/^(?=.)/gmu," ")}${e.map(R=>` ctx.${R} = ${R};`
|
|
|
261
261
|
};
|
|
262
262
|
})();
|
|
263
263
|
const { identity, ip, userId } = caller;
|
|
264
|
-
${
|
|
264
|
+
${w}${f}${r}${$}${P}${N}${t}
|
|
265
265
|
// Which dispatch this ctx belongs to. Drives the two deferral facades
|
|
266
266
|
// below and the \`ctx.run*\` caller guard; a ctx built for an
|
|
267
267
|
// admin/lifecycle path has no registered function, and so no kind. An
|
|
@@ -367,7 +367,7 @@ ${$}${g}${r}${F}${k}${i}${t}
|
|
|
367
367
|
// so both write to the same trace.
|
|
368
368
|
const span = this.makeDispatchSpan(traceAnchor, observability);
|
|
369
369
|
|
|
370
|
-
${
|
|
370
|
+
${b} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
|
|
371
371
|
// adds aggregate counters (call count, total time, per-operation
|
|
372
372
|
// breakdown) to the wide event rather than a span per call, so a
|
|
373
373
|
// handler making hundreds of queries stays readable. See
|
|
@@ -376,11 +376,11 @@ ${f} // \`ctx.db\`, wrapped in automatic instrumentation: by default
|
|
|
376
376
|
// mutation must rebuild its DB and table/ORM views with its own queue.
|
|
377
377
|
const makeDatabaseContext = (scheduler: SchedulerLike) => {
|
|
378
378
|
const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${d}), logFunctionPath, traceAnchor, observability);
|
|
379
|
-
${
|
|
379
|
+
${l} return ${F};
|
|
380
380
|
};
|
|
381
381
|
const databaseContext = makeDatabaseContext(scheduler);
|
|
382
382
|
const db = databaseContext.db;
|
|
383
|
-
${
|
|
383
|
+
${R}
|
|
384
384
|
|
|
385
385
|
// \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
|
|
386
386
|
// The trace anchor is threaded explicitly for the same reason \`identity\`
|
|
@@ -388,7 +388,7 @@ ${P}
|
|
|
388
388
|
// writing mutation's trace from the shared per-request field.
|
|
389
389
|
const trace = this.makeTracer(logFunctionPath, observability, traceAnchor);
|
|
390
390
|
const metrics = this.makeMetrics(logFunctionPath, observability);
|
|
391
|
-
${
|
|
391
|
+
${L}
|
|
392
392
|
// \`ctx.now\`: the wall-clock instant (epoch ms) this function began,
|
|
393
393
|
// captured ONCE so the whole handler body sees a single stable value.
|
|
394
394
|
// A \`query\` handler is re-run by every live subscription that reads it,
|
|
@@ -439,21 +439,21 @@ ${I}
|
|
|
439
439
|
// to the handler so code that signs its own URLs (a copy-in
|
|
440
440
|
// \`createStorage\`) can fall back to it too. \`undefined\` for a
|
|
441
441
|
// query and for a deferred dispatch, for the reasons given there.
|
|
442
|
-
origin: requestOrigin,${
|
|
442
|
+
origin: requestOrigin,${U}
|
|
443
443
|
scheduler,
|
|
444
444
|
span,
|
|
445
445
|
storage: contextStorage,
|
|
446
|
-
trace,${
|
|
446
|
+
trace,${M}${v}${I}${o}${q}${k}${i}${a}
|
|
447
447
|
};
|
|
448
|
-
${
|
|
449
|
-
`:""}${
|
|
450
|
-
${
|
|
448
|
+
${x?` const isAction = contextKind === "action";
|
|
449
|
+
`:""}${u}
|
|
450
|
+
${c?` const captureScope = (): (() => void) => {
|
|
451
451
|
const requestScope = this.captureRequestScope();
|
|
452
452
|
return () => this.restoreRequestScope(requestScope);
|
|
453
453
|
};
|
|
454
454
|
|
|
455
455
|
`:""} const installRun = (target: Record<string, unknown>, kind: typeof contextKind): void => {
|
|
456
|
-
target.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, target, kind${
|
|
456
|
+
target.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, target, kind${c?", undefined, captureScope":""});
|
|
457
457
|
// The composed mutation runs under the SAME wrapper the top-level RPC
|
|
458
458
|
// uses, so "do the transactional work in a mutation and call it from the
|
|
459
459
|
// action" — the recipe the docs give for atomicity — actually is atomic.
|
|
@@ -469,7 +469,7 @@ ${l?` const captureScope = (): (() => void) => {
|
|
|
469
469
|
|
|
470
470
|
return Object.defineProperties({}, {
|
|
471
471
|
...Object.getOwnPropertyDescriptors(target),
|
|
472
|
-
db: { configurable: true, enumerable: true, value: mutationDatabase.db, writable: true },${
|
|
472
|
+
db: { configurable: true, enumerable: true, value: mutationDatabase.db, writable: true },${O}
|
|
473
473
|
scheduler: { configurable: true, enumerable: true, value: mutationScheduler, writable: true },
|
|
474
474
|
storage: { configurable: true, enumerable: true, value: withDeferredDeletes(storage), writable: true },
|
|
475
475
|
});
|
|
@@ -479,7 +479,7 @@ ${l?` const captureScope = (): (() => void) => {
|
|
|
479
479
|
installRun(mutationCtx, kind);
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
-
return dispatchRun("mutation", reference.__lunoraRef, fnArgs, mutationCtx, kind, async (work) => this.runMutationTransaction(mutationCtx, work)${
|
|
482
|
+
return dispatchRun("mutation", reference.__lunoraRef, fnArgs, mutationCtx, kind, async (work) => this.runMutationTransaction(mutationCtx, work)${c?", captureScope":""});
|
|
483
483
|
};
|
|
484
484
|
// \`ctx.runQuery(ref, args, { untracked: true })\` runs the sub-query on
|
|
485
485
|
// its OWN query context, built without the subscription's read-footprint
|
|
@@ -502,7 +502,7 @@ ${l?` const captureScope = (): (() => void) => {
|
|
|
502
502
|
runOptions?.untracked === true
|
|
503
503
|
? this.buildCtx({ bookmarks: options.bookmarks, functionPath: options.functionPath, headroom: options.headroom, identity: caller, kind: "query", scope: options.scope })
|
|
504
504
|
: queryContext(),
|
|
505
|
-
kind,${
|
|
505
|
+
kind,${c?`
|
|
506
506
|
undefined,
|
|
507
507
|
captureScope,`:""}
|
|
508
508
|
);
|
|
@@ -526,7 +526,7 @@ ${l?` const captureScope = (): (() => void) => {
|
|
|
526
526
|
|
|
527
527
|
if (queryView === undefined) {
|
|
528
528
|
const descriptors: PropertyDescriptorMap = Object.getOwnPropertyDescriptors(ctx);
|
|
529
|
-
${e.map(
|
|
529
|
+
${e.map(p=>` delete descriptors.${p};
|
|
530
530
|
`).join("")} // Writable and configurable, like the plain fields they replace.
|
|
531
531
|
const field = (value: unknown): PropertyDescriptor => ({ configurable: true, enumerable: true, value, writable: true });
|
|
532
532
|
|
|
@@ -545,7 +545,7 @@ ${e.map(R=>` delete descriptors.${R};
|
|
|
545
545
|
installRun(ctx, contextKind);
|
|
546
546
|
|
|
547
547
|
return ctx;
|
|
548
|
-
}`},
|
|
548
|
+
}`},le=`// Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
|
|
549
549
|
// referencing call fails loudly with a clear error instead of overflowing the
|
|
550
550
|
// stack. Tracked across the awaited handler chain (one DO invocation is
|
|
551
551
|
// single-threaded), so the counter reflects true nesting depth.
|
|
@@ -611,7 +611,7 @@ const dispatchRun = async (
|
|
|
611
611
|
} finally {
|
|
612
612
|
runDepth -= 1;
|
|
613
613
|
}
|
|
614
|
-
};`,
|
|
614
|
+
};`,xr=n=>n?le.replace(" runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,",` runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,
|
|
615
615
|
captureScope?: () => () => void,`).replace(` try {
|
|
616
616
|
// A mutation composed from an action`,` try {
|
|
617
617
|
let loaded = getLoadedFunction(functionPath);
|
|
@@ -632,7 +632,7 @@ const dispatchRun = async (
|
|
|
632
632
|
|
|
633
633
|
const loadedFunction = loaded;
|
|
634
634
|
|
|
635
|
-
// A mutation composed from an action`).replaceAll("registered.handler","loadedFunction.handler"):
|
|
635
|
+
// A mutation composed from an action`).replaceAll("registered.handler","loadedFunction.handler"):le,Or=` public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker, scope?: QueryReadScope, bookmarks?: DispatchBookmark): Promise<unknown> {
|
|
636
636
|
__PREPARE_FUNCTION__ const registered = LUNORA_FUNCTIONS[functionPath];
|
|
637
637
|
|
|
638
638
|
// Internal functions are reachable server-side only: via \`ctx.run*\`
|
|
@@ -816,7 +816,7 @@ __COMMITTED_CATCH__ } finally {
|
|
|
816
816
|
// \`ctx.scheduler\` call that reached the buffer in the first place.
|
|
817
817
|
protected override scheduleOutboxScheduler(): SchedulerLike | undefined {
|
|
818
818
|
return config.scheduler?.((this.env ?? {}) as Record<string, unknown>) as SchedulerLike | undefined;
|
|
819
|
-
}`,
|
|
819
|
+
}`,Ar=` protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
|
|
820
820
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
821
821
|
|
|
822
822
|
if (!registered || registered.kind !== "query" || registered.visibility === "internal") {
|
|
@@ -857,7 +857,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
|
|
|
857
857
|
// \`ctx.auth\` stream as nobody — or as a concurrent RPC's caller.
|
|
858
858
|
iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath, identity }), args, signal),
|
|
859
859
|
};
|
|
860
|
-
}`,
|
|
860
|
+
}`,Dr=` } catch (error) {
|
|
861
861
|
// The write committed before this failed. Mark the error so the caller can tell
|
|
862
862
|
// a durable write from a rollback: the rethrow still reaches the caller unchanged.
|
|
863
863
|
if (typeof error === "object" && error !== null) {
|
|
@@ -865,7 +865,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
|
|
|
865
865
|
}
|
|
866
866
|
|
|
867
867
|
throw error;
|
|
868
|
-
`,
|
|
868
|
+
`,Tr=(n,e=!1)=>{const t=e?` const registeredBeforeLoad = LUNORA_FUNCTIONS[functionPath];
|
|
869
869
|
|
|
870
870
|
if (registeredBeforeLoad?.visibility === "internal" && !this.isSystemDispatch()) {
|
|
871
871
|
throw new LunoraError("FUNCTION_NOT_FOUND", "function not registered: " + functionPath);
|
|
@@ -882,7 +882,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
|
|
|
882
882
|
}
|
|
883
883
|
}
|
|
884
884
|
|
|
885
|
-
`:"";return
|
|
885
|
+
`:"";return Or.replace("__COMMITTED_CATCH__",n?Dr:"").replace("__PREPARE_FUNCTION__",`${t}${a}`)},Cr=n=>{const e={};for(const t of n.tables){const a={};for(const[r,o]of Object.entries(t.shape)){const d=Y(o);d.kind==="id"&&d.tableName!==void 0&&(a[r]=d.tableName)}Object.keys(a).length>0&&(e[t.name]=a)}return e},_r=n=>{const e={};for(const t of n.tables){const a=[];for(const[r,o]of Object.entries(t.shape))Y(o).kind==="storage"&&a.push(r);a.length>0&&(e[t.name]=a)}return e},Er=n=>{const e={};for(const t of n.tables){const a=[...t.indexes.map(r=>({fields:[...r.fields],name:r.name,type:"index",...r.unique===!0?{unique:!0}:{}})),...t.searchIndexes.map(r=>({fields:[r.field,...r.filterFields??[]],name:r.name,type:"search"})),...(t.geoIndexes??[]).map(r=>({fields:[r.field],name:r.name,type:"geo"})),...t.rankIndexes.map(r=>({fields:r.sortBy.map(o=>o.field),name:r.name,type:"rank"})),...t.vectorIndexes.map(r=>({fields:r.field===void 0?[]:[r.field],name:r.name,type:"vector"}))];a.length>0&&(e[t.name]=a)}return e},Lr=n=>{const e=[];for(const t of n.tables)!t.ttl||t.shardMode==="global"||e.push({...t.ttl.after===void 0?{}:{after:t.ttl.after},field:t.ttl.field,...t.softDelete?{softDeleteField:t.softDelete.field}:{},table:t.name});return e},Ir=n=>{if(n.kind!=="union"||n.members===void 0||n.members.length===0)return;const e=[];for(const t of n.members){if(t.kind!=="literal"||t.literalValue===void 0)return;try{const a=JSON.parse(t.literalValue);if(typeof a!="string")return;e.push(a)}catch{return}}return e},Pr=(n,e,t)=>{const a=Y(e),r={name:n,optional:hr(e),type:a.kind};if(a.kind==="id"&&a.tableName!==void 0){r.ref=a.tableName;const d=t.get(n);d!==void 0&&(r.onDelete=d)}a.kind==="storage"&&(r.isStorage=!0,a.bucket!==void 0&&(r.bucket=a.bucket));const o=Ir(a);return o!==void 0&&(r.enumValues=o),a.column?.notNull===!1&&(r.nullable=!0),r},Nr=n=>{const e={};for(const t of n.tables){const a=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"},...t.commitOrdered===!0?[{name:"_commitSeq",optional:!1,type:"number"}]:[]],r=new Map(t.relations.flatMap(o=>o.kind==="one"?[[o.field,o.onDelete]]:[]));for(const[o,d]of Object.entries(t.shape))a.push(Pr(o,d,r));e[t.name]=a}return e},Mr=({hasMutators:n,hasShapes:e,rlsData:t})=>{const a=e?`
|
|
886
886
|
protected override resolveShape(name: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined {
|
|
887
887
|
const shape = LUNORA_SHAPES[name];
|
|
888
888
|
|
|
@@ -945,14 +945,14 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
|
|
|
945
945
|
|
|
946
946
|
return { ...(shape.columns === undefined ? {} : { columns: shape.columns }), effectiveWhere, global: isGlobal, table: shape.table };
|
|
947
947
|
}
|
|
948
|
-
`:"",r=e?[...new Set(t.policies.filter(
|
|
948
|
+
`:"",r=e?[...new Set(t.policies.filter(l=>l.on==="read"&&l.table!=="").map(l=>l.table))].toSorted((l,b)=>l.localeCompare(b)):[],o=r.length>0?`
|
|
949
949
|
/** Refuses to boot a shape that would replicate around the read policies its table is governed by (\`defineShape({ use })\` is how a shape opts in; \`use: []\` acknowledges an ungoverned one). */
|
|
950
950
|
assertShapesDeclareReadPolicies(LUNORA_SHAPES, ${JSON.stringify(r)}, (schema as unknown as { rlsMode?: string }).rlsMode === "required");
|
|
951
951
|
`:"";return{customMutatorOverride:n?`
|
|
952
952
|
protected override isCustomMutator(functionPath: string): boolean {
|
|
953
953
|
return LUNORA_MUTATOR_PATHS.has(functionPath);
|
|
954
954
|
}
|
|
955
|
-
`:"",shapeGuardImport:e?"assertShapeShardable, ":"",shapeReadPolicyAssertion:
|
|
955
|
+
`:"",shapeGuardImport:e?"assertShapeShardable, ":"",shapeReadPolicyAssertion:o,shapeReadPolicyImport:o===""?"":"assertShapesDeclareReadPolicies, ",shapeResolveOverride:a}},$r=(n,e)=>n?`
|
|
956
956
|
protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?: SubscriptionIdentity): Promise<Array<{ doc: Record<string, unknown>; id: string }>> {
|
|
957
957
|
const env = this.env as Record<string, unknown>;
|
|
958
958
|
// A shape read performs no writes, so the widened request only needs
|
|
@@ -1018,7 +1018,7 @@ assertShapesDeclareReadPolicies(LUNORA_SHAPES, ${JSON.stringify(r)}, (schema as
|
|
|
1018
1018
|
|
|
1019
1019
|
return globalDb.cdcChangedTables?.(sinceSeq, cursorOnly === undefined ? {} : { cursorOnly });
|
|
1020
1020
|
}
|
|
1021
|
-
`:"",
|
|
1021
|
+
`:"",qr=n=>({externalSourceOverride:n?`
|
|
1022
1022
|
protected override async pollExternalSources(trace?: TraceRefLike): Promise<number | undefined> {
|
|
1023
1023
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
1024
1024
|
const sourced = Object.entries((schema as unknown as SchemaLike).tables)
|
|
@@ -1171,8 +1171,8 @@ assertShapesDeclareReadPolicies(LUNORA_SHAPES, ${JSON.stringify(r)}, (schema as
|
|
|
1171
1171
|
`:"",sourceClientCacheConst:n?`
|
|
1172
1172
|
const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
|
|
1173
1173
|
const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
1174
|
-
`:""}),
|
|
1175
|
-
`:"",d=t?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",
|
|
1174
|
+
`:""}),Fr=(n,e)=>{const t=e.length>0,r=n?E("vectorsStub: VectorSearchLike","ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().",["deleteByIds","getByIds","query","upsert","upsertMany","upsertNow"]):"",o=t?` const vectorShardKey = this.currentShardKey();
|
|
1175
|
+
`:"",d=t?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",v=`, { ${["deferAfterCommit: (work) => this.deferAfterCommit(work)",...t?["namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey",`shardedIndexNames: [${e.map(c=>JSON.stringify(c)).join(", ")}]`]:[]].join(", ")} }`,l=n?`
|
|
1176
1176
|
const vectorSync = this.vectorSync(env);
|
|
1177
1177
|
// Vectorize lives outside this shard's SQLite, so a query whose result
|
|
1178
1178
|
// depends on a similarity search cannot be proven current on reconnect —
|
|
@@ -1189,7 +1189,7 @@ const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
|
1189
1189
|
}
|
|
1190
1190
|
|
|
1191
1191
|
const lunora = createVectors({ indexes: config.vectors(env) });
|
|
1192
|
-
${
|
|
1192
|
+
${o} const vectors = createContextVectors(lunora${v});
|
|
1193
1193
|
|
|
1194
1194
|
return {
|
|
1195
1195
|
backfill: createVectorBackfillSync({ ${d}schema: schema as unknown as VectorSchemaLike, upsertMany: lunora.upsertMany, vectors }),
|
|
@@ -1215,14 +1215,39 @@ ${s} const vectors = createContextVectors(lunora${y});
|
|
|
1215
1215
|
ordered: async (read, work) => this.runOrderedAfterWrites(read, work),
|
|
1216
1216
|
});
|
|
1217
1217
|
}
|
|
1218
|
-
`:"",vectorsBuild:
|
|
1218
|
+
`:"",vectorsBuild:l,vectorsStub:r}},Xr=({advisories:n=[],advisorProcedures:e=[],agents:t=[],capabilities:a=new Set,containers:r=[],env:o,flagKeys:d=[],hasFlags:f=!1,hasNotify:v=!1,hasRooms:l=!1,hasSockets:b=!1,lazyFunctions:c=!1,hasVectors:L=!0,liveStreamDeclarations:S=[],liveStreams:R=!1,maskMetadata:I,mutators:P=[],queues:k=[],rlsMetadata:N,schema:i,schemaSnapshot:w,shapes:M=[],storageRules:$,studioFeatures:q,services:x=[],topics:F=[],useUmbrella:U=!1,workflows:O=[]})=>{const u=br(U),B=P.length>0,p=M.length>0,ue=w===void 0?"":Ht(w),he=w===void 0?"":`
|
|
1219
1219
|
/** Structural schema snapshot + its content hash, recorded in the shard's \`__lunora_schema_history\` ledger on cold start so the studio can show a schema-version timeline and diff any two versions. */
|
|
1220
|
-
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(
|
|
1221
|
-
`,
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1220
|
+
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(Vt(w))}, json: ${JSON.stringify(ue)} };
|
|
1221
|
+
`,pe=w===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",y=Jt(a),T=zt(f,u.flags),j=Yt(d,f,u.flags),W=ur(v),H=Xt(o),{build:me,contextField:ge,importLines:fe,specs:be}=Zt(wr(k)),{build:we,contextField:ye,importLines:ve,specs:ke}=er(F,k),V=tr(x,u.server),{build:Se,contextField:Re,importLines:xe,specs:Oe}=rr(r,i.jurisdiction),{build:Ae,contextField:De,importLines:Te,specs:Ce}=nr(O),{build:_e,contextField:Ee,importLines:Le,specs:Ie}=ar(t),{build:Pe,configField:Ne,contextField:Me,imports:$e,stub:qe}=sr(a.has("payments")),Fe=n,{advisoryRules:Ue,advisoryRows:Be}=vr(Fe),je=e,X=N??{policies:[],roles:[]},We=I??{columns:[]},He=$??{rules:[]},Ve=q??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,privacy:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Ke,override:Ge}=or(O),{constant:Qe,override:Je}=ir(k),m=L&&i.vectorIndexes.length>0,K=new Set(i.tables.filter(s=>yr(s)).map(s=>s.name)),Z=m&&i.vectorIndexes.some(s=>K.has(s.table)),A=i.tables.some(s=>s.shardMode==="global"),G=dr(K),Q=i.tables.some(s=>Kt(s)),ee=i.tables.some(s=>Gt(s)),C=i.tables.some(s=>s.externalSource!==void 0),te=i.tables.some(s=>s.memory===!0),J=i.tables.some(s=>s.shardMode!=="global"&&s.searchIndexes.length>0);if(ee&&Q)throw new de("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const z=i.tables.length>0,ze=Cr(i),Ye=Er(i),Xe=Nr(i),Ze=_r(i),re=Lr(i),ne=cr(m,O.length>0,k.length>0,f,J);p&&ne.push("WhereInput");const ae=lr(A),{customMutatorOverride:et,shapeGuardImport:tt,shapeReadPolicyAssertion:rt,shapeReadPolicyImport:nt,shapeResolveOverride:at}=Mr({hasMutators:B,hasShapes:p,rlsData:X}),D=R?S:[];for(const s of D)if(pr(s.exportName,"live stream export name"),!mr.test(s.filePath))throw new de("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe live stream file path: ${JSON.stringify(s.filePath)}`);const st=c?[]:D.map(s=>`import { ${s.exportName} as liveStream_${s.exportName} } from "../${s.filePath}.js";`),ot=` protected override liveStreams() {
|
|
1222
|
+
return { ${D.map(s=>`${gr(s.id)}: liveStream_${s.exportName}`).join(", ")} };
|
|
1223
|
+
}
|
|
1224
|
+
`,it=` private readonly liveStreamLoaders = new Map<string, () => Promise<{ validatePublish: (topic: string, payload: unknown) => unknown }>>([
|
|
1225
|
+
${D.map(s=>` [${JSON.stringify(s.id)}, () => import("../${s.filePath}.js").then((module) => module.${s.exportName})],`).join(`
|
|
1226
|
+
`)}
|
|
1227
|
+
]);
|
|
1228
|
+
|
|
1229
|
+
private readonly loadedLiveStreams = new Map<string, { validatePublish: (topic: string, payload: unknown) => unknown }>();
|
|
1230
|
+
|
|
1231
|
+
protected override loadLiveStream(stream: string): Promise<void> | undefined {
|
|
1232
|
+
const load = this.loadedLiveStreams.has(stream) ? undefined : this.liveStreamLoaders.get(stream);
|
|
1233
|
+
|
|
1234
|
+
return load === undefined
|
|
1235
|
+
? undefined
|
|
1236
|
+
: load().then((declaration) => {
|
|
1237
|
+
this.loadedLiveStreams.set(stream, declaration);
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
// Only the streams a publish has already loaded: a stream not yet loaded was either never published to or is
|
|
1242
|
+
// unknown, and either way \`declaredLivePayload\` refuses what this does not hold.
|
|
1243
|
+
protected override liveStreams() {
|
|
1244
|
+
return Object.fromEntries(this.loadedLiveStreams);
|
|
1245
|
+
}
|
|
1246
|
+
`;let se="";D.length>0&&(se=c?it:ot);const _=[`import type { ${ne.join(", ")} } from "${u.do}";`,`import { applyCdcChanges, createStableIdFactory, ${J?"backfillSearchIndexes, ":""}${m?"backfillVectorIndexes, ":""}buildReprojectionMigration, ${te?"clearMemoryTables, ":""}${tt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${C?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${Z?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${ae.importFragment}ShardDO as ShardDOBase } from "${u.do}";`,...C?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${u.do}";`]:[],p?`import { asBucketStorage, ${nt}beginDeferredDeletes, beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${u.server}";`:`import { asBucketStorage, beginDeferredDeletes, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${u.server}";`];z&&_.push(`import { bindOrm, bindTableFacade } from "${u.server}";`),m&&_.push('import type { SchemaLike as VectorSchemaLike, VectorBackfillSync, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectorBackfillSync, createVectors, createVectorSyncHook, vectorBackfillTargets } from "@lunora/bindings/vectors";'),_.push(...y.importLines,...T.importLines,...W.importLines,...H.importLines,...xe,...Te,...fe,...ve,...V.importLines,...Le,...$e,"",'import schema from "../schema.js";',...st,`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...c?["getLoadedFunction","loadFunction"]:[],...B?["LUNORA_MUTATOR_PATHS"]:[],...l?["LUNORA_ROOMS"]:[],...b?["LUNORA_SOCKETS"]:[],...p?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const dt=m?`
|
|
1247
|
+
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",ct=ee?`
|
|
1248
|
+
d1?: (env: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",lt=Q?`
|
|
1249
|
+
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",ut=C?`
|
|
1250
|
+
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",ht="ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().",pt="ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().",mt="ctx.storage: no storage configured. Pass `storage` to createShardDO().",gt=A?E("globalDbStub: DatabaseWriterLike",ht,["aggregate","count","delete","explain","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",{vectorSyncMethod:ft,vectorsBuild:bt,vectorsStub:wt}=Fr(m,Z?i.vectorIndexes.filter(s=>K.has(s.table)).map(s=>s.name):[]),yt=`{
|
|
1226
1251
|
...this.ctxDbTuning(),
|
|
1227
1252
|
auth: { identity: identity ?? null, userId: userId ?? null },
|
|
1228
1253
|
broadcast: (delta) => {
|
|
@@ -1262,7 +1287,7 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1262
1287
|
// fallback rather than reporting into a no-op.
|
|
1263
1288
|
...(options.onReadRange !== undefined
|
|
1264
1289
|
? { onReadRange: options.onReadRange }
|
|
1265
|
-
: options.scope === undefined ? {} : { onReadRange: this.getCtxDbReadRangeHook(options.scope) }),${
|
|
1290
|
+
: options.scope === undefined ? {} : { onReadRange: this.getCtxDbReadRangeHook(options.scope) }),${m?`
|
|
1266
1291
|
// Vectorize is outside this shard's SQLite and cannot roll back, so
|
|
1267
1292
|
// the sync is held until the mutation's transaction has COMMITTED
|
|
1268
1293
|
// (\`deferAfterCommit\`) instead of running inline. Inline, a write
|
|
@@ -1274,11 +1299,11 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1274
1299
|
scheduler,
|
|
1275
1300
|
schema: schema as unknown as SchemaLike,
|
|
1276
1301
|
sql: this.sql as SqlExec,
|
|
1277
|
-
storage,${
|
|
1302
|
+
storage,${A?`
|
|
1278
1303
|
globalDb,`:""}
|
|
1279
|
-
}`,
|
|
1280
|
-
vectors,`:"",
|
|
1281
|
-
orm: bindOrm(facade),`:"",
|
|
1304
|
+
}`,vt=m?`
|
|
1305
|
+
vectors,`:"",kt=z?`
|
|
1306
|
+
orm: bindOrm(facade),`:"",oe=Q?"config.hyperdriveGlobal":"config.d1",St=A?` const bookmark = this.getInboundBookmark();
|
|
1282
1307
|
const globalRequest = {
|
|
1283
1308
|
...this.globalCdcOptions(config.cdc ?? false),
|
|
1284
1309
|
...(bookmark === undefined ? {} : { bookmark }),
|
|
@@ -1286,26 +1311,26 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1286
1311
|
onBookmark: (bookmarkValue: string | undefined) => { if (options.bookmarks !== undefined) { options.bookmarks.value = bookmarkValue; } },
|
|
1287
1312
|
...(userId === undefined ? {} : { userId }),
|
|
1288
1313
|
};
|
|
1289
|
-
const globalDb: DatabaseWriterLike = ${
|
|
1290
|
-
`:"",
|
|
1314
|
+
const globalDb: DatabaseWriterLike = ${oe}?.(env, globalRequest) ?? globalDbStub;
|
|
1315
|
+
`:"",Rt=$r(p&&A,oe),xt=l?` protected override roomHandlerPath(topic: string): string | undefined {
|
|
1291
1316
|
// Own properties only: a plain object would resolve \`toString\` and the like to inherited functions.
|
|
1292
1317
|
return Object.hasOwn(LUNORA_ROOMS, topic) ? LUNORA_ROOMS[topic] : undefined;
|
|
1293
1318
|
}
|
|
1294
|
-
`:"",
|
|
1319
|
+
`:"",Ot=b?` protected override socketRoute(path: string): { auth: boolean; functionPath: string } | undefined {
|
|
1295
1320
|
return LUNORA_SOCKETS[path];
|
|
1296
1321
|
}
|
|
1297
|
-
`:"",{externalSourceOverride:
|
|
1322
|
+
`:"",{externalSourceOverride:At,sourceBootstrap:Dt,sourceClientCacheConst:Tt}=qr(C),Ct=`
|
|
1298
1323
|
protected override async runShardInit(): Promise<void> {
|
|
1299
1324
|
this.ensureMigrated();
|
|
1300
|
-
${
|
|
1325
|
+
${te?` clearMemoryTables(this.sql as SqlExec, schema as unknown as SchemaLike);
|
|
1301
1326
|
`:""}
|
|
1302
1327
|
await this.dispatchShardInit();
|
|
1303
1328
|
}
|
|
1304
|
-
`,
|
|
1329
|
+
`,_t=re.length>0?`
|
|
1305
1330
|
if (LUNORA_TTL_SWEEPS.length > 0) {
|
|
1306
1331
|
void this.scheduleTtlSweep();
|
|
1307
1332
|
}
|
|
1308
|
-
`:"",
|
|
1333
|
+
`:"",Et=`
|
|
1309
1334
|
public constructor(state: ShardDOState, env: unknown) {
|
|
1310
1335
|
super(state, env, {
|
|
1311
1336
|
// Every writer this file builds spreads the ctxDbTuning() slice —
|
|
@@ -1322,7 +1347,7 @@ ${ee?` clearMemoryTables(this.sql as SqlExec, schema as unknown as Sc
|
|
|
1322
1347
|
// exists — a trigger that fails first still flushes and fuses.
|
|
1323
1348
|
...(config.observability === undefined ? {} : { telemetrySink: () => config.observability?.((env ?? {}) as Record<string, unknown>) }),
|
|
1324
1349
|
});
|
|
1325
|
-
${
|
|
1350
|
+
${Dt}${_t} }
|
|
1326
1351
|
|
|
1327
1352
|
protected override isCacheableQuery(functionPath: string): boolean {
|
|
1328
1353
|
// NOT \`kind === "query"\` alone. A cache hit answers without running
|
|
@@ -1346,7 +1371,7 @@ ${vt}${Rt} }
|
|
|
1346
1371
|
protected override isPaidFunction(functionPath: string): boolean {
|
|
1347
1372
|
return LUNORA_FUNCTIONS[functionPath]?.x402 !== undefined;
|
|
1348
1373
|
}
|
|
1349
|
-
`,
|
|
1374
|
+
`,ie=c?`
|
|
1350
1375
|
protected override prepareFunction(functionPath: string, reason: "rpc" | "subscription" | "stream" | "reactor"): Promise<void> | undefined {
|
|
1351
1376
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
1352
1377
|
const allowsInternal = reason === "reactor" || (reason === "rpc" && this.isSystemDispatch());
|
|
@@ -1361,25 +1386,25 @@ ${vt}${Rt} }
|
|
|
1361
1386
|
|
|
1362
1387
|
return loadFunction(functionPath).then(() => undefined);
|
|
1363
1388
|
}
|
|
1364
|
-
`:"",
|
|
1389
|
+
`:"",Lt=ie===""?`
|
|
1365
1390
|
|
|
1366
|
-
`:`${
|
|
1367
|
-
`,
|
|
1391
|
+
`:`${ie}
|
|
1392
|
+
`,It=xr(c),Pt=c?` const preparation = this.prepareFunction(functionPath, "subscription");
|
|
1368
1393
|
if (preparation !== undefined) await preparation;
|
|
1369
|
-
`:"",
|
|
1394
|
+
`:"",Nt=Ar.replace("__PREPARE_FUNCTION__",Pt),Mt=Tr(l,c),$t=z?`
|
|
1370
1395
|
const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
|
|
1371
|
-
${i.tables.map(
|
|
1396
|
+
${i.tables.map(s=>` facade[${JSON.stringify(s.name)}] = bindTableFacade(db, ${JSON.stringify(s.name)});`).join(`
|
|
1372
1397
|
`)}
|
|
1373
|
-
`:"",
|
|
1398
|
+
`:"",qt=`${y.everyBuild}${T.build}${H.build}
|
|
1374
1399
|
const secrets = createSecrets(env);
|
|
1375
|
-
`,
|
|
1376
|
-
secrets,`,
|
|
1400
|
+
`,Ft=`${y.everyFields}${T.contextField}${W.contextField}${H.contextField}
|
|
1401
|
+
secrets,`,Ut=W.build,Bt=R?`
|
|
1377
1402
|
const live = {
|
|
1378
|
-
publish: async (topic: string, payload: unknown, publishOptions
|
|
1379
|
-
await this.publishLiveFromAction(topic, payload, publishOptions);
|
|
1403
|
+
publish: async (ref: { __lunoraLive: string; topic: string }, payload: unknown, publishOptions?: { shardKey?: string }): Promise<void> => {
|
|
1404
|
+
await this.publishLiveFromAction(ref.topic, payload, { ...publishOptions, stream: ref.__lunoraLive });
|
|
1380
1405
|
},
|
|
1381
1406
|
};
|
|
1382
|
-
`:"",
|
|
1407
|
+
`:"",jt=[...y.actionFields,...x.length>0?["services"]:[],...R?["live"]:[]],Wt=`${y.actionBuild}${V.build}${Bt}`;return`${fr}${_.join(`
|
|
1383
1408
|
`)}
|
|
1384
1409
|
|
|
1385
1410
|
type FunctionKind = "action" | "mutation" | "query";
|
|
@@ -1389,13 +1414,13 @@ interface FunctionReference {
|
|
|
1389
1414
|
}
|
|
1390
1415
|
|
|
1391
1416
|
/** Foreign-key columns per table (\`v.id("target")\` fields) for the data browser. */
|
|
1392
|
-
const LUNORA_TABLE_REFS = ${h(
|
|
1417
|
+
const LUNORA_TABLE_REFS = ${h(ze,"Record<string, Record<string, string>>")};
|
|
1393
1418
|
|
|
1394
1419
|
/** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
|
|
1395
|
-
const LUNORA_TABLE_INDEXES = ${h(
|
|
1420
|
+
const LUNORA_TABLE_INDEXES = ${h(Ye,'Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>>')};
|
|
1396
1421
|
|
|
1397
1422
|
/** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
|
|
1398
|
-
const LUNORA_TABLE_COLUMNS = ${h(
|
|
1423
|
+
const LUNORA_TABLE_COLUMNS = ${h(Xe,`Record<
|
|
1399
1424
|
string,
|
|
1400
1425
|
Array<{
|
|
1401
1426
|
bucket?: string;
|
|
@@ -1412,16 +1437,16 @@ const LUNORA_TABLE_COLUMNS = ${h(Qe,`Record<
|
|
|
1412
1437
|
>`)};
|
|
1413
1438
|
|
|
1414
1439
|
/** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
|
|
1415
|
-
const LUNORA_STORAGE_COLUMNS = ${h(
|
|
1440
|
+
const LUNORA_STORAGE_COLUMNS = ${h(Ze,"Record<string, string[]>")};
|
|
1416
1441
|
|
|
1417
1442
|
/** Declarative TTL policies (\`.ttl(field, { after? })\`) the DO alarm sweep auto-expires rows for. */
|
|
1418
|
-
const LUNORA_TTL_SWEEPS = ${
|
|
1443
|
+
const LUNORA_TTL_SWEEPS = ${Qt(re,"Array<{ after?: number; field: string; softDeleteField?: string; table: string }>")};
|
|
1419
1444
|
|
|
1420
1445
|
/** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
|
|
1421
|
-
const LUNORA_ADVISORY_RULES = ${h(
|
|
1446
|
+
const LUNORA_ADVISORY_RULES = ${h(Ue,"Record<string, Partial<AdvisoryFinding>>")};
|
|
1422
1447
|
|
|
1423
1448
|
/** Per-finding rows; rule-level text lives once in \`LUNORA_ADVISORY_RULES\` and is merged back on first read. */
|
|
1424
|
-
const LUNORA_ADVISORY_ROWS = ${h(
|
|
1449
|
+
const LUNORA_ADVISORY_ROWS = ${h(Be,"Array<Partial<AdvisoryFinding> & { name: string }>")};
|
|
1425
1450
|
|
|
1426
1451
|
const LUNORA_ADVISORIES = ((): (() => AdvisoryFinding[]) => {
|
|
1427
1452
|
let cached: AdvisoryFinding[] | undefined;
|
|
@@ -1429,20 +1454,20 @@ const LUNORA_ADVISORIES = ((): (() => AdvisoryFinding[]) => {
|
|
|
1429
1454
|
})();
|
|
1430
1455
|
|
|
1431
1456
|
/** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
|
|
1432
|
-
const LUNORA_ADVISOR_PROCEDURES = ${h(
|
|
1457
|
+
const LUNORA_ADVISOR_PROCEDURES = ${h(je,"AdvisorProcedure[]")};
|
|
1433
1458
|
|
|
1434
1459
|
/** Read-only RLS metadata (policies + roles discovered from \`.use(rls(...))\` chains) served via \`__lunora_admin__:rlsPolicies\` for the studio's RLS inspector. */
|
|
1435
|
-
const LUNORA_RLS_METADATA = ${h(
|
|
1436
|
-
${
|
|
1460
|
+
const LUNORA_RLS_METADATA = ${h(X,"RlsPoliciesResult")};
|
|
1461
|
+
${rt}
|
|
1437
1462
|
/** Read-only masking metadata (table + column + strategy discovered from \`.use(mask(...))\` chains) served via \`__lunora_admin__:maskPolicies\` for the studio's data-browser mask preview. */
|
|
1438
|
-
const LUNORA_MASK_METADATA = ${h(
|
|
1463
|
+
const LUNORA_MASK_METADATA = ${h(We,"MaskPoliciesResult")};
|
|
1439
1464
|
|
|
1440
1465
|
/** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
|
|
1441
|
-
const LUNORA_STORAGE_RULES = ${h(
|
|
1466
|
+
const LUNORA_STORAGE_RULES = ${h(He,"StorageRulesResult")};
|
|
1442
1467
|
|
|
1443
1468
|
/** Which optional package-backed features this app wires up (discovered from imports / \`ctx.*\` reads / schema signals) served via \`__lunora_admin__:studioFeatures\` so the studio hides nav pages whose package isn't enabled. */
|
|
1444
|
-
const LUNORA_STUDIO_FEATURES = ${h(
|
|
1445
|
-
${
|
|
1469
|
+
const LUNORA_STUDIO_FEATURES = ${h(Ve,"StudioFeaturesResult")};
|
|
1470
|
+
${he}${G.constant}${j.constant}${Ke}${Qe}${Oe}${Ce}${be}${ke}${V.specs}${Ie}
|
|
1446
1471
|
export interface ShardDOConfig {
|
|
1447
1472
|
/** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
|
|
1448
1473
|
cdc?: boolean;
|
|
@@ -1459,25 +1484,25 @@ export interface ShardDOConfig {
|
|
|
1459
1484
|
/** \`unknown\` because \`@lunora/scheduler\`'s \`Scheduler\` is not assignable to \`SchedulerLike\`; the shard casts it. */
|
|
1460
1485
|
scheduler?: (env: Record<string, unknown>) => unknown;
|
|
1461
1486
|
/** \`origin\` is the origin the current \`/rpc\` request reached the worker on — the fallback base for signed object URLs when no \`publicBaseUrl\` is configured. \`undefined\` off the synchronous dispatch path. */
|
|
1462
|
-
storage?: (env: Record<string, unknown>, origin?: string) => unknown;${
|
|
1487
|
+
storage?: (env: Record<string, unknown>, origin?: string) => unknown;${dt}${y.configFields}${T.configField}${Ne}${ct}${lt}${ut}${G.configField}
|
|
1463
1488
|
}
|
|
1464
|
-
${
|
|
1465
|
-
${
|
|
1489
|
+
${E("schedulerStub",pt,["cancel","runAfter","runAt"])}${E("storageStub",mt,["createMultipartUpload","delete","download","generateUploadUrl","getMetadata","getPresignedUrl","getSignedUrl","getUrl","head","list","resumeMultipartUpload","store","upload"],{sync:["getUrl","resumeMultipartUpload"]})}${gt}${Tt}${wt}${y.stubs}${qe}
|
|
1490
|
+
${It}
|
|
1466
1491
|
|
|
1467
1492
|
/**
|
|
1468
1493
|
* Build the project's shard Durable Object. Export the result as \`ShardDO\`
|
|
1469
1494
|
* from the worker entry so wrangler binds it by name.
|
|
1470
1495
|
*/
|
|
1471
1496
|
export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
|
|
1472
|
-
class extends ShardDOBase {${
|
|
1473
|
-
private migrated = false;${
|
|
1474
|
-
${
|
|
1475
|
-
${
|
|
1476
|
-
${
|
|
1497
|
+
class extends ShardDOBase {${Et}
|
|
1498
|
+
private migrated = false;${Lt}${Mt}
|
|
1499
|
+
${ae.override}
|
|
1500
|
+
${Nt}
|
|
1501
|
+
${et}${at}${Rt}${At}
|
|
1477
1502
|
protected override lifecycleHookPaths(event: "connect" | "disconnect" | "init" | "reactor" | "whisper"): readonly string[] {
|
|
1478
1503
|
return LUNORA_LIFECYCLE_HOOKS[event];
|
|
1479
1504
|
}
|
|
1480
|
-
${
|
|
1505
|
+
${xt}${Ot}${se}${G.override}${Ct}
|
|
1481
1506
|
// One \`onQueryChange\` dispatch. Mirrors \`executeSubscription\` — the
|
|
1482
1507
|
// socket-terminated half of the same reactivity — and differs only in who
|
|
1483
1508
|
// consumes the result: the base's \`dispatchReactors\` stores the digest as
|
|
@@ -1498,7 +1523,7 @@ ${bt}${wt}${K.override}${St}
|
|
|
1498
1523
|
// would instead run an app's reactor as whichever user happened to write
|
|
1499
1524
|
// last, which is worse than running it as nobody.
|
|
1500
1525
|
protected override async runReactor(functionPath: string, previousDigest?: string): Promise<{ digest: string; ran: boolean; tables: readonly string[] } | undefined> {
|
|
1501
|
-
${
|
|
1526
|
+
${c?` const requestScope = this.captureRequestScope();
|
|
1502
1527
|
const preparation = this.prepareFunction(functionPath, "reactor");
|
|
1503
1528
|
|
|
1504
1529
|
if (preparation !== undefined) {
|
|
@@ -1576,7 +1601,7 @@ ${l?` const requestScope = this.captureRequestScope();
|
|
|
1576
1601
|
protected override studioFeatures(): StudioFeaturesResult {
|
|
1577
1602
|
return LUNORA_STUDIO_FEATURES();
|
|
1578
1603
|
}
|
|
1579
|
-
${
|
|
1604
|
+
${j.evaluateOverride}${j.subscriptionOverride}${Ge}${Je}
|
|
1580
1605
|
protected override advisories(): AdvisoryFinding[] {
|
|
1581
1606
|
return LUNORA_ADVISORIES();
|
|
1582
1607
|
}
|
|
@@ -1585,17 +1610,17 @@ ${B.evaluateOverride}${B.subscriptionOverride}${We}${Ve}
|
|
|
1585
1610
|
return LUNORA_ADVISOR_PROCEDURES();
|
|
1586
1611
|
}
|
|
1587
1612
|
|
|
1588
|
-
${
|
|
1613
|
+
${Sr}
|
|
1589
1614
|
|
|
1590
1615
|
protected override ensureMigrated(): void {
|
|
1591
1616
|
if (this.migrated) {
|
|
1592
1617
|
return;
|
|
1593
1618
|
}
|
|
1594
1619
|
|
|
1595
|
-
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${
|
|
1620
|
+
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${pe} });
|
|
1596
1621
|
this.migrated = true;
|
|
1597
1622
|
}
|
|
1598
|
-
${
|
|
1623
|
+
${J?`
|
|
1599
1624
|
protected override runShardSearchBackfill(options: { maxPages?: number }): SearchBackfillProgress {
|
|
1600
1625
|
// Migrations create the fts5 companions; without them every backfill
|
|
1601
1626
|
// statement would raise "no such table" on a shard that has never
|
|
@@ -1604,7 +1629,7 @@ ${Q?`
|
|
|
1604
1629
|
|
|
1605
1630
|
return backfillSearchIndexes(this.sql as SqlExec, schema as unknown as SchemaLike, options);
|
|
1606
1631
|
}
|
|
1607
|
-
`:""}${
|
|
1608
|
-
${
|
|
1632
|
+
`:""}${ft}
|
|
1633
|
+
${Rr({lazyFunctions:c,actionOnlyFields:jt,agentsBuild:_e,agentsContextField:Ee,containersBuild:Se,containersContextField:Re,databaseOptions:yt,everyContextBuild:qt,everyContextField:Ft,facadeBlock:$t,globalDatabaseLine:St,notifyBuild:Ut,ormContextField:kt,paymentsBuild:Pe,paymentsContextField:Me,queuesBuild:me,queuesContextField:ge,topicsBuild:we,topicsContextField:ye,vectorsBuild:bt,vectorsContextField:vt,workflowsBuild:Ae,workflowsContextField:De,actionOnlyBuild:Wt})}
|
|
1609
1634
|
};
|
|
1610
|
-
`};export{
|
|
1635
|
+
`};export{_r as b,Xr as e};
|