@voltro/runtime 0.79.1 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +169 -0
- package/dist/index.d.ts +273 -29
- package/dist/index.js +2861 -2666
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -909,6 +909,12 @@ export declare const API_CSP = "default-src 'none'; frame-ancestors 'none'; base
|
|
|
909
909
|
|
|
910
910
|
export declare const API_KEYS_TABLE = "_voltro_api_keys";
|
|
911
911
|
|
|
912
|
+
/** Caller side: the token this app presents to the api it binds as `name`. */
|
|
913
|
+
export declare const apiBindingTokenEnv: (name: string) => string;
|
|
914
|
+
|
|
915
|
+
/** Caller side: where the api it binds as `name` listens (production). */
|
|
916
|
+
export declare const apiBindingUrlEnv: (name: string) => string;
|
|
917
|
+
|
|
912
918
|
/** What `ApiKeyStore.ensureActor` is handed for the row it plants. */
|
|
913
919
|
export declare interface ApiKeyActor {
|
|
914
920
|
readonly id: string;
|
|
@@ -1107,6 +1113,19 @@ export declare interface AppAccess {
|
|
|
1107
1113
|
readonly scopes: ReadonlyArray<string>;
|
|
1108
1114
|
}
|
|
1109
1115
|
|
|
1116
|
+
/**
|
|
1117
|
+
* The typed clients of the apps this app calls — augmented per app by the
|
|
1118
|
+
* codegen'd `apis.generated.ts`:
|
|
1119
|
+
*
|
|
1120
|
+
* declare module '@voltro/runtime' {
|
|
1121
|
+
* interface AppApis { readonly cloud: ServiceApi<CloudServiceProcedures> }
|
|
1122
|
+
* }
|
|
1123
|
+
*
|
|
1124
|
+
* Empty until an app declares `apis:`.
|
|
1125
|
+
*/
|
|
1126
|
+
export declare interface AppApis {
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1110
1129
|
export declare interface AppContext {
|
|
1111
1130
|
/** Run database work with a freshly transaction-bound context. Reuses an
|
|
1112
1131
|
* existing mutation transaction (no savepoint). The callback may be retried;
|
|
@@ -1204,6 +1223,19 @@ export declare interface AppContext {
|
|
|
1204
1223
|
* subject", by construction.
|
|
1205
1224
|
*/
|
|
1206
1225
|
readonly connections?: ConnectionsFacade;
|
|
1226
|
+
/**
|
|
1227
|
+
* The other apps of the project this app calls (`ctx.apis.<name>`) — one
|
|
1228
|
+
* typed client per `apis:` binding in `app.config.ts`, typed from the
|
|
1229
|
+
* callee's `service:` procedures by the codegen'd `apis.generated.ts`.
|
|
1230
|
+
*
|
|
1231
|
+
* await ctx.apis.cloud.deployments.activate({ deploymentId, tenantId })
|
|
1232
|
+
* yield* ctx.apis.cloud.deployments.activate.effect(input) // in a workflow step
|
|
1233
|
+
*
|
|
1234
|
+
* Always present — an app with no bindings gets an empty object, so the field
|
|
1235
|
+
* never reads as "maybe wired". A call without an answer fails with
|
|
1236
|
+
* `ApiUnavailable`; every answer the callee gives arrives as itself.
|
|
1237
|
+
*/
|
|
1238
|
+
readonly apis: AppApis;
|
|
1207
1239
|
/**
|
|
1208
1240
|
* Request-scoped batching (`ctx.load` / `ctx.loadMany`). Coalesces
|
|
1209
1241
|
* same-tick reads of one table into a single `WHERE id IN (...)`.
|
|
@@ -1460,6 +1492,9 @@ export declare const assertCan: (subject: RebacSubject, action: string, resource
|
|
|
1460
1492
|
*/
|
|
1461
1493
|
export declare const assertConnectionCipherConfigured: (definitions: ReadonlyArray<ConnectionDefinition>) => void;
|
|
1462
1494
|
|
|
1495
|
+
/** Refuse a caller map that could not be what the author meant. */
|
|
1496
|
+
export declare const assertServiceCallersConfig: (callers: ServiceCallersConfig) => void;
|
|
1497
|
+
|
|
1463
1498
|
/**
|
|
1464
1499
|
* Boot gate: every mounted incoming-webhook route must carry a verification
|
|
1465
1500
|
* declaration. Throws `UnverifiedWebhookRoute` for the first that does not.
|
|
@@ -1640,6 +1675,19 @@ export declare interface AuditableQuery {
|
|
|
1640
1675
|
|
|
1641
1676
|
export declare interface AuthMiddlewareLayerOptions {
|
|
1642
1677
|
readonly resolveSubject: ResolveSubjectFn;
|
|
1678
|
+
/**
|
|
1679
|
+
* The apps allowed to call one rpc tag, or `undefined` when the tag is not a
|
|
1680
|
+
* `service:` procedure. Both boot paths pass the same lookup over the
|
|
1681
|
+
* procedures they registered.
|
|
1682
|
+
*
|
|
1683
|
+
* This is the OUTER wall for a service credential: the guard check refuses a
|
|
1684
|
+
* service subject at every procedure that does not name it, but framework
|
|
1685
|
+
* built-ins (`__voltro.*`) and plugin routes reach their handlers without a
|
|
1686
|
+
* descriptor guard. Here, before any handler, a service subject reaches only
|
|
1687
|
+
* the tags that name it — so a leaked service token opens exactly the doors
|
|
1688
|
+
* the callee declared and nothing the framework adds.
|
|
1689
|
+
*/
|
|
1690
|
+
readonly serviceCallersFor?: (tag: string) => ReadonlyArray<string> | undefined;
|
|
1643
1691
|
}
|
|
1644
1692
|
|
|
1645
1693
|
/**
|
|
@@ -2245,6 +2293,8 @@ export declare interface ClientAddressInput {
|
|
|
2245
2293
|
readonly socketAddress: string | undefined;
|
|
2246
2294
|
/** Raw `x-forwarded-for` header, if present. */
|
|
2247
2295
|
readonly xForwardedFor: string | undefined;
|
|
2296
|
+
/** Raw value of `config.clientAddressHeader`, if the request carried it. */
|
|
2297
|
+
readonly clientAddressHeader?: string | undefined;
|
|
2248
2298
|
readonly config: TrustedProxyConfig;
|
|
2249
2299
|
}
|
|
2250
2300
|
|
|
@@ -3301,6 +3351,10 @@ export declare const DEFAULT_HSTS = "max-age=15552000; includeSubDomains";
|
|
|
3301
3351
|
*/
|
|
3302
3352
|
export declare const DEFAULT_KEEP_ALIVE_MS = 72000;
|
|
3303
3353
|
|
|
3354
|
+
export declare const DEFAULT_LEVEL_RESYNC_MS: number;
|
|
3355
|
+
|
|
3356
|
+
export declare const DEFAULT_LEVEL_STUCK_MS: number;
|
|
3357
|
+
|
|
3304
3358
|
/** Ceiling the idle backoff climbs to. Deliberately short enough to be a
|
|
3305
3359
|
* FLOOR under a missed wake rather than a substitute for one. */
|
|
3306
3360
|
export declare const DEFAULT_MAX_IDLE_INTERVAL_MS = 30000;
|
|
@@ -3539,7 +3593,12 @@ export declare const defineOutboxHandler: <R = never>(definition: OutboxHandlerD
|
|
|
3539
3593
|
|
|
3540
3594
|
/** Declare a reaction. Validates that the MANDATORY guard is present — an
|
|
3541
3595
|
* ungated reaction is a spend-storm footgun, so this fails LOUD at boot. */
|
|
3542
|
-
export declare
|
|
3596
|
+
export declare function defineReaction(def: LevelReactionDefinition): LevelReactionDefinition;
|
|
3597
|
+
|
|
3598
|
+
export declare function defineReaction(def: EdgeReactionDefinition): EdgeReactionDefinition;
|
|
3599
|
+
|
|
3600
|
+
/** A value already typed as either form — narrowed at runtime by its `watch`. */
|
|
3601
|
+
export declare function defineReaction(def: ReactionDefinition): ReactionDefinition;
|
|
3543
3602
|
|
|
3544
3603
|
/** Register a resource policy (the static, discoverable relationship registry
|
|
3545
3604
|
* the capability map exposes). Validates + fails LOUD on a malformed or
|
|
@@ -4062,6 +4121,15 @@ export declare interface DrainResult {
|
|
|
4062
4121
|
*/
|
|
4063
4122
|
export declare const dueWakeups: (store: DataStore, now: Date, limit?: number) => Promise<ReadonlyArray<Wakeup>>;
|
|
4064
4123
|
|
|
4124
|
+
/** A reaction to each CHANGE of a table (edge-triggered). */
|
|
4125
|
+
export declare interface EdgeReactionDefinition extends ReactionBase {
|
|
4126
|
+
/** The table whose changes trigger the reaction (+ optional op filter). */
|
|
4127
|
+
readonly watch: ReactionEdgeWatch;
|
|
4128
|
+
/** Optional predicate over the change — skip when it returns false. */
|
|
4129
|
+
readonly when?: (event: ReactionEvent) => boolean;
|
|
4130
|
+
readonly guards: ReactionGuards;
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4065
4133
|
/** The minimal Effect-store surface `insertIgnoreRowOutcomeEffect` needs. */
|
|
4066
4134
|
export declare interface EffectInsertIgnoreOutcomeStore {
|
|
4067
4135
|
readonly insertIgnoreWithOutcome: (table: string, row: Row, options: {
|
|
@@ -5453,13 +5521,12 @@ export declare const forbiddenColumnsForSubject: (tableName: string, subject: Su
|
|
|
5453
5521
|
export declare const forgetCredential: (store: VaultStore, connectionId: string, subjectId: string) => Promise<boolean>;
|
|
5454
5522
|
|
|
5455
5523
|
/**
|
|
5456
|
-
* Drop rows
|
|
5524
|
+
* Drop this replica's rows on a graceful shutdown.
|
|
5457
5525
|
*
|
|
5458
|
-
*
|
|
5459
|
-
*
|
|
5460
|
-
*
|
|
5461
|
-
*
|
|
5462
|
-
* (a scale-down), whose row would otherwise be counted forever.
|
|
5526
|
+
* A restart under the same replica ID overwrites its row anyway; this handles
|
|
5527
|
+
* a replica that goes away for good (a scale-down). It cannot run for a process
|
|
5528
|
+
* that crashed or was killed — those rows are aged out by the retention sweep
|
|
5529
|
+
* on `writtenAt`, which every live replica refreshes each publish interval.
|
|
5463
5530
|
*/
|
|
5464
5531
|
export declare const forgetReplicaObservations: (store: DataStore, replicaId: string) => Promise<void>;
|
|
5465
5532
|
|
|
@@ -5576,6 +5643,8 @@ export declare interface GroupState {
|
|
|
5576
5643
|
readonly extreme?: number;
|
|
5577
5644
|
}
|
|
5578
5645
|
|
|
5646
|
+
export declare const guardUndeclaredTables: (underlying: DataStore, isKnownTable: (table: string) => boolean) => DataStore;
|
|
5647
|
+
|
|
5579
5648
|
/** What a user handler may return. */
|
|
5580
5649
|
export declare type HandlerBody<R = never> = void | Promise<unknown> | Effect.Effect<unknown, unknown, R>;
|
|
5581
5650
|
|
|
@@ -5862,7 +5931,10 @@ export { InspectStore }
|
|
|
5862
5931
|
*/
|
|
5863
5932
|
export declare interface InspectStream {
|
|
5864
5933
|
readonly replicaId?: string;
|
|
5865
|
-
|
|
5934
|
+
/** Undefined serves this process's own feed. Decided before the response
|
|
5935
|
+
* starts: an event stream is a 200 from its first byte, so a refusal found
|
|
5936
|
+
* inside the body could only reach the client as a feed that closes. */
|
|
5937
|
+
readonly select?: (url: string, headers: Readonly<Record<string, string>>) => Effect.Effect<InspectStreamSelection | undefined>;
|
|
5866
5938
|
/** Same shape as the inspect auth resolver — returns ok or reason. */
|
|
5867
5939
|
readonly authorize: (headers: Readonly<Record<string, string>>) => {
|
|
5868
5940
|
readonly ok: true;
|
|
@@ -5884,6 +5956,16 @@ export declare interface InspectStream {
|
|
|
5884
5956
|
readonly keepAliveMs?: number;
|
|
5885
5957
|
}
|
|
5886
5958
|
|
|
5959
|
+
/** A named process's feed, or the reasoned refusal to open it. */
|
|
5960
|
+
export declare type InspectStreamSelection = {
|
|
5961
|
+
readonly kind: 'stream';
|
|
5962
|
+
readonly stream: Stream.Stream<Uint8Array>;
|
|
5963
|
+
} | {
|
|
5964
|
+
readonly kind: 'refused';
|
|
5965
|
+
readonly status: number;
|
|
5966
|
+
readonly body: unknown;
|
|
5967
|
+
};
|
|
5968
|
+
|
|
5887
5969
|
export { inspectWorkflow }
|
|
5888
5970
|
|
|
5889
5971
|
export declare const installApprovalGate: (gate: ApprovalGateApi) => void;
|
|
@@ -6002,6 +6084,12 @@ export declare const isIdleNow: (opts: IdleCheckOptions) => Promise<boolean>;
|
|
|
6002
6084
|
|
|
6003
6085
|
export declare const isInfraError: (e: unknown) => boolean;
|
|
6004
6086
|
|
|
6087
|
+
/** Narrow a reaction definition to the level form. */
|
|
6088
|
+
export declare const isLevelReaction: (def: ReactionDefinition) => def is LevelReactionDefinition;
|
|
6089
|
+
|
|
6090
|
+
/** Narrow a reaction to the level form. */
|
|
6091
|
+
export declare const isLevelWatch: (watch: ReactionWatch) => watch is ReactionLevelWatch;
|
|
6092
|
+
|
|
6005
6093
|
export declare const isObservingGraph: () => boolean;
|
|
6006
6094
|
|
|
6007
6095
|
/**
|
|
@@ -6109,6 +6197,8 @@ export declare const isTransactionReadConflict: (err: unknown) => err is Transac
|
|
|
6109
6197
|
/** Is `address` one of the peers we are willing to take a forwarded chain from? */
|
|
6110
6198
|
export declare const isTrustedProxy: (address: string | undefined, config: TrustedProxyConfig) => boolean;
|
|
6111
6199
|
|
|
6200
|
+
export declare const isWellFormedServiceToken: (value: string) => boolean;
|
|
6201
|
+
|
|
6112
6202
|
export declare const isWorkflowEventTriggerDefinition: (value: unknown) => value is WorkflowEventTriggerDefinition;
|
|
6113
6203
|
|
|
6114
6204
|
/** A maintainable aggregate op. (countDistinct / window funcs are NOT here —
|
|
@@ -6232,6 +6322,34 @@ export declare const lastWriteProvenance: (row: Record<string, unknown> | null |
|
|
|
6232
6322
|
readonly traceId?: string | null;
|
|
6233
6323
|
}) => ProvenanceResult;
|
|
6234
6324
|
|
|
6325
|
+
/**
|
|
6326
|
+
* A reaction to every ROW of a live query's current result (level-triggered).
|
|
6327
|
+
*
|
|
6328
|
+
* The act is a workflow, and the workflow's `idempotencyKey` is what makes it
|
|
6329
|
+
* exactly-once across the fleet: every replica that sees the row may try to
|
|
6330
|
+
* start it, and the engine collapses them into one execution. So there is no
|
|
6331
|
+
* `dedupeKey` here, and the workflow's key must identify the unit of work — a
|
|
6332
|
+
* row that can come BACK into the set (an org suspended, unsuspended, suspended
|
|
6333
|
+
* again) needs a key carrying that generation (`suspend:${orgId}:${suspendedAt}`).
|
|
6334
|
+
*
|
|
6335
|
+
* The workflow must move the row OUT of the set (its first step flips a status,
|
|
6336
|
+
* its failure path records a terminal one). A row still in the set long after
|
|
6337
|
+
* it was started is reported as `stuck`, never silently restarted.
|
|
6338
|
+
*/
|
|
6339
|
+
export declare interface LevelReactionDefinition extends ReactionBase {
|
|
6340
|
+
readonly watch: ReactionLevelWatch;
|
|
6341
|
+
/** The identity of a row in the set — what `stuck` reports and the runner tracks. */
|
|
6342
|
+
readonly key: (row: never) => string;
|
|
6343
|
+
/** Only rows it returns true for act. */
|
|
6344
|
+
readonly when?: (row: never) => boolean;
|
|
6345
|
+
/** Re-read the whole set this often even when nothing changed, so a start that
|
|
6346
|
+
* failed is retried. Default 5 minutes, minimum 30 seconds. */
|
|
6347
|
+
readonly resync?: number | string;
|
|
6348
|
+
/** Report a row still in the set this long after it was started. Default 15 minutes. */
|
|
6349
|
+
readonly stuckAfter?: number | string;
|
|
6350
|
+
readonly guards?: Omit<ReactionGuards, 'dedupeKey'>;
|
|
6351
|
+
}
|
|
6352
|
+
|
|
6235
6353
|
export declare class LinearScanMatcher implements Matcher {
|
|
6236
6354
|
private readonly byTable;
|
|
6237
6355
|
register(sub: SubscriptionRecord): void;
|
|
@@ -7055,6 +7173,11 @@ export declare type MetricsMode = 'off' | 'console' | 'otlp' | 'memory';
|
|
|
7055
7173
|
/** The lowest cadence any platform scheduler can express. */
|
|
7056
7174
|
export declare const MIN_EXTERNALIZABLE_INTERVAL_MS = 60000;
|
|
7057
7175
|
|
|
7176
|
+
export declare const MIN_LEVEL_RESYNC_MS = 30000;
|
|
7177
|
+
|
|
7178
|
+
/** Mint a fresh service token. `voltro dev` and `voltro secret generate` call this. */
|
|
7179
|
+
export declare const mintServiceToken: () => string;
|
|
7180
|
+
|
|
7058
7181
|
/**
|
|
7059
7182
|
* Ordering token for one mirrored write.
|
|
7060
7183
|
*
|
|
@@ -8268,17 +8391,23 @@ export declare type ReactionAct = {
|
|
|
8268
8391
|
readonly payload?: (event: ReactionEvent) => unknown;
|
|
8269
8392
|
};
|
|
8270
8393
|
|
|
8271
|
-
|
|
8394
|
+
declare interface ReactionBase {
|
|
8272
8395
|
readonly name: string;
|
|
8273
|
-
/** The table whose changes trigger the reaction (+ optional op filter). */
|
|
8274
|
-
readonly watch: {
|
|
8275
|
-
readonly table: string;
|
|
8276
|
-
readonly on?: ReactionOp | ReadonlyArray<ReactionOp>;
|
|
8277
|
-
};
|
|
8278
|
-
/** Optional predicate over the change — skip when it returns false. */
|
|
8279
|
-
readonly when?: (event: ReactionEvent) => boolean;
|
|
8280
8396
|
readonly act: ReactionAct;
|
|
8281
|
-
|
|
8397
|
+
}
|
|
8398
|
+
|
|
8399
|
+
export declare type ReactionDefinition = EdgeReactionDefinition | LevelReactionDefinition;
|
|
8400
|
+
|
|
8401
|
+
/** `'5 minutes'` / `'30s'` / `'8 days'` / `300000` → milliseconds. */
|
|
8402
|
+
export declare const reactionDurationMs: (value: number | string, field: string, reaction: string) => number;
|
|
8403
|
+
|
|
8404
|
+
/**
|
|
8405
|
+
* The EDGE form: react to each change of one table, as it happens.
|
|
8406
|
+
* Best-effort — a change made while the reacting process is down is not seen.
|
|
8407
|
+
*/
|
|
8408
|
+
export declare interface ReactionEdgeWatch {
|
|
8409
|
+
readonly table: string;
|
|
8410
|
+
readonly on?: ReactionOp | ReadonlyArray<ReactionOp>;
|
|
8282
8411
|
}
|
|
8283
8412
|
|
|
8284
8413
|
/** The change a reaction reacts to (the framework's CDC shape). */
|
|
@@ -8324,6 +8453,23 @@ export declare interface ReactionGuards {
|
|
|
8324
8453
|
};
|
|
8325
8454
|
}
|
|
8326
8455
|
|
|
8456
|
+
/**
|
|
8457
|
+
* The LEVEL form: react to every ROW of a live query's current result — the set
|
|
8458
|
+
* of open work — for as long as it is in the set.
|
|
8459
|
+
*
|
|
8460
|
+
* Each delivery of the query is the whole current set, so work that appeared
|
|
8461
|
+
* while the reacting process was down, restarting or deploying is seen on the
|
|
8462
|
+
* first delivery after it comes back: nothing is lost. `api` names a binding in
|
|
8463
|
+
* `apis:` (the query is another app's `service:` query); omit it to watch one
|
|
8464
|
+
* of this app's own queries.
|
|
8465
|
+
*/
|
|
8466
|
+
export declare interface ReactionLevelWatch {
|
|
8467
|
+
readonly query: string;
|
|
8468
|
+
readonly api?: string;
|
|
8469
|
+
/** The query's input. Default `{}`. */
|
|
8470
|
+
readonly input?: unknown;
|
|
8471
|
+
}
|
|
8472
|
+
|
|
8327
8473
|
export declare type ReactionOp = 'insert' | 'update' | 'delete';
|
|
8328
8474
|
|
|
8329
8475
|
export declare type ReactionOutcome = 'acted' | 'skipped-op' | 'skipped-when' | 'skipped-dedupe' | 'skipped-ratelimit' | 'skipped-budget';
|
|
@@ -8382,6 +8528,8 @@ export declare interface ReactionRunDeps {
|
|
|
8382
8528
|
readonly now?: () => number;
|
|
8383
8529
|
}
|
|
8384
8530
|
|
|
8531
|
+
export declare type ReactionWatch = ReactionEdgeWatch | ReactionLevelWatch;
|
|
8532
|
+
|
|
8385
8533
|
/** The reactive tunables a caller may declare. Every field optional; every
|
|
8386
8534
|
* default above. */
|
|
8387
8535
|
export declare interface ReactiveConfigInput {
|
|
@@ -9425,6 +9573,14 @@ export declare const resolveReactiveConfig: (config?: ReactiveConfigInput | unde
|
|
|
9425
9573
|
|
|
9426
9574
|
export declare const resolveRedirectUri: (definition: OAuth2ConnectionDefinition, publicUrl: string) => string;
|
|
9427
9575
|
|
|
9576
|
+
/** The client address of a request, read from its headers per `config`. The
|
|
9577
|
+
* one call every listener makes — which headers matter is decided here. */
|
|
9578
|
+
export declare const resolveRequestClientAddress: (input: {
|
|
9579
|
+
readonly socketAddress: string | undefined;
|
|
9580
|
+
readonly headers: Readonly<Record<string, string | undefined>>;
|
|
9581
|
+
readonly config: TrustedProxyConfig;
|
|
9582
|
+
}) => string | undefined;
|
|
9583
|
+
|
|
9428
9584
|
/**
|
|
9429
9585
|
* Whether the request reached the app over TLS.
|
|
9430
9586
|
*
|
|
@@ -9500,7 +9656,8 @@ export declare type ResolveSubjectFn = (input: {
|
|
|
9500
9656
|
export declare const resolveTimelineMode: (env?: Record<string, string | undefined>) => TimelineMode;
|
|
9501
9657
|
|
|
9502
9658
|
/** Select identity before opening a transaction, never while one owns writes.
|
|
9503
|
-
* Only the framework's system subject
|
|
9659
|
+
* Only a cross-tenant machine subject — the framework's system subject, or a
|
|
9660
|
+
* service calling a `service:` procedure — may select a different tenant. */
|
|
9504
9661
|
export declare const resolveTransactionSubject: (subject: Subject, tenantId: string | undefined, transactionActive: boolean) => Subject;
|
|
9505
9662
|
|
|
9506
9663
|
/**
|
|
@@ -9513,7 +9670,7 @@ export declare const resolveTransactionSubject: (subject: Subject, tenantId: str
|
|
|
9513
9670
|
* rebuild; the config field exists because it is a tunable and tunables belong
|
|
9514
9671
|
* in `app.config.ts`.
|
|
9515
9672
|
*/
|
|
9516
|
-
export declare const resolveTrustedProxies: (configured?: ReadonlyArray<string> | undefined, env?: Readonly<Record<string, string | undefined
|
|
9673
|
+
export declare const resolveTrustedProxies: (configured?: ReadonlyArray<string> | undefined, env?: Readonly<Record<string, string | undefined>>, configuredHeader?: string | undefined) => TrustedProxyConfig;
|
|
9517
9674
|
|
|
9518
9675
|
/** Per-resource-type policy. `actions` maps an action to the relations that
|
|
9519
9676
|
* grant it (ANY-of). `implies` is relation implication (owner ⇒ editor ⇒
|
|
@@ -9944,6 +10101,9 @@ export declare interface RowHistoryEntry {
|
|
|
9944
10101
|
readonly traceId?: string | null;
|
|
9945
10102
|
}
|
|
9946
10103
|
|
|
10104
|
+
/** Internal header name. Its value is meaningless without the process mark. */
|
|
10105
|
+
export declare const RPC_CLIENT_ADDRESS_HEADER = "x-voltro-client-address";
|
|
10106
|
+
|
|
9947
10107
|
/** Server-owned lifetime, not a user identity or a client-supplied claim.
|
|
9948
10108
|
* WebSockets retain it across calls; HTTP retains it only within one request.
|
|
9949
10109
|
* Reconnects and server restarts receive a new id. */
|
|
@@ -9951,6 +10111,11 @@ export declare interface RpcConnection {
|
|
|
9951
10111
|
readonly id: string;
|
|
9952
10112
|
readonly transport: 'websocket' | 'http';
|
|
9953
10113
|
readonly signal: AbortSignal;
|
|
10114
|
+
/** The caller's address, resolved by the rpc listener through
|
|
10115
|
+
* `security.trustedProxies` / `clientAddressHeader` — the same value its
|
|
10116
|
+
* per-IP shield counts. Absent when the call did not arrive through that
|
|
10117
|
+
* listener (an internal invocation, an embedder's own transport). */
|
|
10118
|
+
readonly remoteAddr?: string;
|
|
9954
10119
|
}
|
|
9955
10120
|
|
|
9956
10121
|
export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
@@ -10005,6 +10170,9 @@ export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
|
10005
10170
|
* boot-path parity rule asks for.
|
|
10006
10171
|
*/
|
|
10007
10172
|
readonly publishSurfaceDigest?: boolean;
|
|
10173
|
+
/** The bound tags that are `service:` procedures — published as
|
|
10174
|
+
* `serviceSurface`, kept out of the client `surface`. */
|
|
10175
|
+
readonly serviceSurfaceTags?: ReadonlySet<string>;
|
|
10008
10176
|
/** Non-sensitive fleet identity written on the rpc WebSocket open/close
|
|
10009
10177
|
* records. Defaults to the process identity resolver (POD_NAME/HOSTNAME).
|
|
10010
10178
|
* Embedders may state it explicitly when they own process identity. */
|
|
@@ -10218,7 +10386,7 @@ export declare const runProvidedEffect: <A>(effect: Effect.Effect<A, unknown, ne
|
|
|
10218
10386
|
* `agentActor(via:'agent')` scoped to the row's tenant. Idempotent: the same
|
|
10219
10387
|
* dedupe key never acts twice.
|
|
10220
10388
|
*/
|
|
10221
|
-
export declare const runReaction: (reaction:
|
|
10389
|
+
export declare const runReaction: (reaction: EdgeReactionDefinition, event: ReactionEvent, deps: ReactionRunDeps) => Promise<ReactionOutcome>;
|
|
10222
10390
|
|
|
10223
10391
|
/**
|
|
10224
10392
|
* Start the full single-node orchestrator: bind the router on the public
|
|
@@ -10250,6 +10418,9 @@ export declare interface RuntimeContext {
|
|
|
10250
10418
|
/** Server-owned transport identity and close signal. Not authentication;
|
|
10251
10419
|
* session membership remains an application's explicit access decision. */
|
|
10252
10420
|
readonly connection?: RpcConnection;
|
|
10421
|
+
/** `connection.remoteAddr`, lifted so the serve pipeline — which also serves
|
|
10422
|
+
* REST calls that have no connection — reads one field for both. */
|
|
10423
|
+
readonly remoteAddr?: string;
|
|
10253
10424
|
}
|
|
10254
10425
|
|
|
10255
10426
|
/**
|
|
@@ -11099,6 +11270,11 @@ export declare interface ServeRequestContext {
|
|
|
11099
11270
|
readonly surface?: 'rest';
|
|
11100
11271
|
/** The descriptor's `publicApi` spec, on a projected call. */
|
|
11101
11272
|
readonly publicApi?: PublicApiSpec;
|
|
11273
|
+
/** The caller's address as the listener resolved it through
|
|
11274
|
+
* `security.trustedProxies` — carried to the plugin interceptor so a
|
|
11275
|
+
* per-endpoint limit can count per client. Absent for calls that did not
|
|
11276
|
+
* arrive over the network. */
|
|
11277
|
+
readonly remoteAddr?: string;
|
|
11102
11278
|
/**
|
|
11103
11279
|
* Caller-side cancellation (the gRPC deadline / client-cancel path).
|
|
11104
11280
|
* Honoured at the ONE place the executor effect runs to a promise, so an
|
|
@@ -11163,11 +11339,56 @@ export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown,
|
|
|
11163
11339
|
/** See `ServeRequestContext.surface` — present on a REST-projected call. */
|
|
11164
11340
|
readonly surface?: 'rest';
|
|
11165
11341
|
readonly publicApi?: PublicApiSpec;
|
|
11342
|
+
/** See `ServeRequestContext.remoteAddr`. */
|
|
11343
|
+
readonly remoteAddr?: string;
|
|
11166
11344
|
}) => Effect.Effect<unknown, unknown, never>;
|
|
11167
11345
|
|
|
11168
11346
|
/** The published tracer, or `undefined` when tracing is off / no server booted. */
|
|
11169
11347
|
export declare const serverTracer: () => Tracer.Tracer | undefined;
|
|
11170
11348
|
|
|
11349
|
+
/** The bearer prefix every service credential carries. */
|
|
11350
|
+
export declare const SERVICE_TOKEN_PREFIX = "vsvc_";
|
|
11351
|
+
|
|
11352
|
+
/**
|
|
11353
|
+
* One accepted caller. Declared in the callee's `app.config.ts`:
|
|
11354
|
+
*
|
|
11355
|
+
* serviceCallers: { worker: {} }
|
|
11356
|
+
*
|
|
11357
|
+
* The object is the per-caller configuration slot; today it carries nothing,
|
|
11358
|
+
* because the token comes from the environment by convention and the grant
|
|
11359
|
+
* comes from the procedures. It is an object rather than `true` so a later
|
|
11360
|
+
* per-caller option (a rate limit, an mTLS identity) is an addition, not a
|
|
11361
|
+
* change of shape.
|
|
11362
|
+
*/
|
|
11363
|
+
export declare type ServiceCallerConfig = Readonly<Record<string, never>>;
|
|
11364
|
+
|
|
11365
|
+
/** Callee side: the second accepted value during a rotation. */
|
|
11366
|
+
export declare const serviceCallerNextTokenEnv: (caller: string) => string;
|
|
11367
|
+
|
|
11368
|
+
export declare type ServiceCallersConfig = Readonly<Record<string, ServiceCallerConfig>>;
|
|
11369
|
+
|
|
11370
|
+
/**
|
|
11371
|
+
* The strategy an app with `serviceCallers` puts FIRST in its chain.
|
|
11372
|
+
*
|
|
11373
|
+
* It claims only `Bearer vsvc_…`. Every other request is a `skip`, so an app's
|
|
11374
|
+
* users never pay more than a prefix check.
|
|
11375
|
+
*/
|
|
11376
|
+
export declare const serviceCallerStrategy: (options: ServiceCallerStrategyOptions) => AuthStrategy;
|
|
11377
|
+
|
|
11378
|
+
export declare interface ServiceCallerStrategyOptions {
|
|
11379
|
+
readonly callers: ServiceCallersConfig;
|
|
11380
|
+
/** Read lazily — at request time and in `verifyConfig` — never while the
|
|
11381
|
+
* config is imported, so `voltro build` needs no production secret. */
|
|
11382
|
+
readonly env?: () => Readonly<Record<string, string | undefined>>;
|
|
11383
|
+
}
|
|
11384
|
+
|
|
11385
|
+
/** Callee side: the env var holding the token a caller presents. */
|
|
11386
|
+
export declare const serviceCallerTokenEnv: (caller: string) => string;
|
|
11387
|
+
|
|
11388
|
+
/** `worker` → `WORKER`, `build-runner` → `BUILD_RUNNER`, `voltroCloudWorker` →
|
|
11389
|
+
* `VOLTRO_CLOUD_WORKER`. The env-var spelling of an app name. */
|
|
11390
|
+
export declare const serviceEnvSegment: (name: string) => string;
|
|
11391
|
+
|
|
11171
11392
|
export declare const setBufferedBytes: (label: string, bytes: number) => void;
|
|
11172
11393
|
|
|
11173
11394
|
/** Register the process-wide connection resolver (or clear with `undefined`).
|
|
@@ -12182,6 +12403,12 @@ export declare interface TransportSecurityOptions {
|
|
|
12182
12403
|
* CIDRs, the presets `loopback` / `private`, a hop count (`['2']`), or
|
|
12183
12404
|
* `['*']` to trust any peer. Env override: `VOLTRO_TRUSTED_PROXIES`. */
|
|
12184
12405
|
readonly trustedProxies?: ReadonlyArray<string>;
|
|
12406
|
+
/** A header a trusted proxy SETS to the client's single address
|
|
12407
|
+
* (`'cf-connecting-ip'`, `'x-real-ip'`). Believed only from a peer
|
|
12408
|
+
* `trustedProxies` covers, and only when it holds one valid IP; otherwise
|
|
12409
|
+
* the `x-forwarded-for` chain applies. Env override:
|
|
12410
|
+
* `VOLTRO_CLIENT_ADDRESS_HEADER`. */
|
|
12411
|
+
readonly clientAddressHeader?: string;
|
|
12185
12412
|
/** Security response headers. Env override: `VOLTRO_SECURITY_HEADERS`
|
|
12186
12413
|
* (`off|default|strict`), plus `VOLTRO_CSP` / `VOLTRO_CSP_HTML` /
|
|
12187
12414
|
* `VOLTRO_HSTS`. */
|
|
@@ -12227,6 +12454,10 @@ export declare interface TrustedProxyConfig {
|
|
|
12227
12454
|
readonly trustAll: boolean;
|
|
12228
12455
|
/** Hop count (express's numeric `trust proxy`). `undefined` → not hop mode. */
|
|
12229
12456
|
readonly hops?: number;
|
|
12457
|
+
/** Lower-cased name of a single-address header a trusted proxy SETS
|
|
12458
|
+
* (`cf-connecting-ip`, `x-real-ip`). Preferred over the forwarded chain when
|
|
12459
|
+
* it holds one valid IP; `x-forwarded-for` remains the fallback. */
|
|
12460
|
+
readonly clientAddressHeader?: string;
|
|
12230
12461
|
}
|
|
12231
12462
|
|
|
12232
12463
|
/**
|
|
@@ -12315,6 +12546,13 @@ declare interface TypedUpsertOptions<T extends AnyWritableTable> {
|
|
|
12315
12546
|
*/
|
|
12316
12547
|
export declare const unbindConnection: (clientId: number) => void;
|
|
12317
12548
|
|
|
12549
|
+
export declare class UndeclaredTableAccess extends Error {
|
|
12550
|
+
readonly table: string;
|
|
12551
|
+
readonly operation: string;
|
|
12552
|
+
readonly _tag = "UndeclaredTableAccess";
|
|
12553
|
+
constructor(table: string, operation: string);
|
|
12554
|
+
}
|
|
12555
|
+
|
|
12318
12556
|
/** The store surface an inverse op needs (a subset of the framework DataStore). */
|
|
12319
12557
|
export declare interface UndoApplyStore {
|
|
12320
12558
|
insert(table: string, row: Record<string, unknown>): Promise<unknown> | unknown;
|
|
@@ -12806,15 +13044,12 @@ export declare type WorkflowAdmissionOutcome = {
|
|
|
12806
13044
|
* that filled up on this arrival. */
|
|
12807
13045
|
readonly payload: unknown;
|
|
12808
13046
|
/** Dispatch the resident submission and return its durably acknowledged
|
|
12809
|
-
* execution ID
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
readonly
|
|
12814
|
-
|
|
12815
|
-
readonly mode: string;
|
|
12816
|
-
readonly dueAt: number;
|
|
12817
|
-
} | {
|
|
13047
|
+
* execution ID — or, when the dispatch went unacknowledged, the receipt
|
|
13048
|
+
* recovery completes it under (`mode: 'unacknowledged'`). That start may
|
|
13049
|
+
* still run, so it is neither an execution ID nor a failure. Recovery owns
|
|
13050
|
+
* retries; callers must not execute separately. */
|
|
13051
|
+
readonly accept: () => Promise<string | WorkflowQueuedAdmission>;
|
|
13052
|
+
} | WorkflowQueuedAdmission | {
|
|
12818
13053
|
readonly kind: 'dropped';
|
|
12819
13054
|
readonly retryAfterMs: number;
|
|
12820
13055
|
} | {
|
|
@@ -13118,6 +13353,15 @@ export declare class WorkflowPayloadError extends Error {
|
|
|
13118
13353
|
missingFields: ReadonlyArray<string>, detail: string);
|
|
13119
13354
|
}
|
|
13120
13355
|
|
|
13356
|
+
/** A start the caller follows through its receipt instead of an execution ID. */
|
|
13357
|
+
export declare interface WorkflowQueuedAdmission {
|
|
13358
|
+
readonly kind: 'queued';
|
|
13359
|
+
readonly receiptId: string;
|
|
13360
|
+
readonly intentId: string;
|
|
13361
|
+
readonly mode: string;
|
|
13362
|
+
readonly dueAt: number;
|
|
13363
|
+
}
|
|
13364
|
+
|
|
13121
13365
|
export declare interface WorkflowQueuedControlOptions {
|
|
13122
13366
|
readonly callerContext?: WorkflowCallerContext;
|
|
13123
13367
|
readonly cause?: NonNullable<WorkflowControlRequest['cause']>;
|