@voltro/runtime 0.67.0 → 0.69.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 +437 -0
- package/dist/index.d.ts +106 -3
- package/dist/index.js +1820 -1771
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -163,6 +163,11 @@ export declare interface ActivitySignals {
|
|
|
163
163
|
readonly activeWorkflowExecutions: () => number;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/** The framework's universal audit-subject table (`@voltro/database`'s core
|
|
167
|
+
* `actors`). An issued key gets a row here so `audit()`'s `createdBy` foreign
|
|
168
|
+
* key resolves for a key-authenticated caller. */
|
|
169
|
+
export declare const ACTORS_TABLE = "actors";
|
|
170
|
+
|
|
166
171
|
/**
|
|
167
172
|
* Adopt a detached subscription for a resuming client at `fromRevision`.
|
|
168
173
|
* Undefined — identity unknown, entry dead (an error/revocation while
|
|
@@ -949,6 +954,28 @@ export declare interface ApiKeyStore {
|
|
|
949
954
|
readonly findById: (id: string) => Promise<ApiKeyRow | null>;
|
|
950
955
|
readonly listByTenant: (tenantId: string | null) => Promise<ReadonlyArray<ApiKeyRow>>;
|
|
951
956
|
readonly patch: (id: string, fields: Partial<ApiKeyRow>) => Promise<void>;
|
|
957
|
+
/**
|
|
958
|
+
* Plant the key's row in `actors` — the audit subject every `createdBy` /
|
|
959
|
+
* `updatedBy` / `deletedBy` points at.
|
|
960
|
+
*
|
|
961
|
+
* REQUIRED, not optional, and that is the whole point. `actors.kind` is
|
|
962
|
+
* declared by the framework as `'user' | 'serviceAccount' | 'apiKey' |
|
|
963
|
+
* 'system'`, so an API key is explicitly an audit subject — and issuing wrote
|
|
964
|
+
* only `_voltro_api_keys`, so the row never existed. Measured in a consumer's
|
|
965
|
+
* database: `actors with kind='apiKey': 0`. The first audit-stamped insert by
|
|
966
|
+
* a key-authenticated caller then died on the foreign key, which means
|
|
967
|
+
* `apiKeys:` and `audit()` were not combinable and both are on by default.
|
|
968
|
+
*
|
|
969
|
+
* An optional hook would have been the same defect with a nicer name — the
|
|
970
|
+
* mistake was omission, and an optional field is omissible. Same reasoning as
|
|
971
|
+
* `startOutboxRunner`'s required `onShutdown`.
|
|
972
|
+
*
|
|
973
|
+
* Idempotent by contract: it is called on every issue, including a rotation.
|
|
974
|
+
*/
|
|
975
|
+
readonly ensureActor: (actor: {
|
|
976
|
+
readonly id: string;
|
|
977
|
+
readonly displayName: string | null;
|
|
978
|
+
}) => Promise<void>;
|
|
952
979
|
}
|
|
953
980
|
|
|
954
981
|
export declare interface ApiKeyUsageBuffer {
|
|
@@ -4758,6 +4785,12 @@ export declare interface FleetMergeResult<T> {
|
|
|
4758
4785
|
*
|
|
4759
4786
|
* Empty when no membership is wired: with no roster there is no evidence of
|
|
4760
4787
|
* departure, and assuming it would empty a single-process answer.
|
|
4788
|
+
*
|
|
4789
|
+
* A row is departed only when it is BOTH unrostered AND older than the
|
|
4790
|
+
* freshness window. Roster-absence alone is not evidence — a membership view
|
|
4791
|
+
* is per-process, so replicas sharing a database but no bus each hold a roster
|
|
4792
|
+
* of one, and the earlier rule had two live replicas calling each other gone
|
|
4793
|
+
* while reporting an age of under two seconds.
|
|
4761
4794
|
*/
|
|
4762
4795
|
readonly departed: ReadonlyArray<{
|
|
4763
4796
|
readonly replicaId: string;
|
|
@@ -6280,8 +6313,18 @@ export declare interface MemberSnapshot {
|
|
|
6280
6313
|
readonly self: boolean;
|
|
6281
6314
|
}
|
|
6282
6315
|
|
|
6283
|
-
/**
|
|
6284
|
-
export declare
|
|
6316
|
+
/** The planted audit-subject row, as the memory store records it. */
|
|
6317
|
+
export declare interface MemoryActorRow {
|
|
6318
|
+
readonly id: string;
|
|
6319
|
+
readonly kind: 'apiKey';
|
|
6320
|
+
readonly displayName: string | null;
|
|
6321
|
+
}
|
|
6322
|
+
|
|
6323
|
+
/** In-memory store (tests + single-process dev). The `actors` map is EXPOSED so
|
|
6324
|
+
* a test can assert the row was planted — see `ApiKeyStore.ensureActor`. */
|
|
6325
|
+
export declare const memoryApiKeyStore: () => ApiKeyStore & {
|
|
6326
|
+
readonly actors: ReadonlyMap<string, MemoryActorRow>;
|
|
6327
|
+
};
|
|
6285
6328
|
|
|
6286
6329
|
/**
|
|
6287
6330
|
* Adapter for in-memory testing. The "position" is a monotonically-
|
|
@@ -6814,6 +6857,43 @@ export declare interface OrchestratorTickDeps {
|
|
|
6814
6857
|
readonly log?: WakeOrchestratorLogger;
|
|
6815
6858
|
}
|
|
6816
6859
|
|
|
6860
|
+
/**
|
|
6861
|
+
* Referrer policies that make a browser send `Origin: null` on a SAME-ORIGIN
|
|
6862
|
+
* state-changing request — which `classifyRequestOrigin` refuses as opaque.
|
|
6863
|
+
*
|
|
6864
|
+
* This is not a lint about tidiness. `no-referrer` was the default here, and
|
|
6865
|
+
* under it every no-JS `<form method="post">` in every Voltro app answered 403,
|
|
6866
|
+
* on both boot paths, for every user. Two security defaults, each defensible
|
|
6867
|
+
* alone, cancelling each other: we asked the browser to withhold provenance and
|
|
6868
|
+
* then refused the request for lacking it.
|
|
6869
|
+
*
|
|
6870
|
+
* Measured in a real headless chromium against a bare `node:http` server —
|
|
6871
|
+
* ONE header changed between the rows, nothing else:
|
|
6872
|
+
*
|
|
6873
|
+
* Referrer-Policy: (none) → Origin: http://127.0.0.1:45412
|
|
6874
|
+
* Referrer-Policy: no-referrer → Origin: null ← and no Referer
|
|
6875
|
+
* Referrer-Policy: strict-origin-when-cross-origin → Origin: http://127.0.0.1:45412
|
|
6876
|
+
* Referrer-Policy: same-origin → Origin: http://127.0.0.1:45412
|
|
6877
|
+
*
|
|
6878
|
+
* It is the Fetch spec's behaviour, not a chromium quirk: when appending the
|
|
6879
|
+
* `Origin` header, a request whose referrer policy is `no-referrer` serialises
|
|
6880
|
+
* its origin as `null`. `origin-when-cross-origin`'s sibling `unsafe-url` does
|
|
6881
|
+
* not, so the set below is exactly the two that null it unconditionally.
|
|
6882
|
+
*
|
|
6883
|
+
* `same-origin` is NOT in the set — it preserves the Origin for same-origin
|
|
6884
|
+
* requests — but it is also not the default, because it nulls the Origin for a
|
|
6885
|
+
* legitimate CROSS-origin post to an allowlisted api, which is precisely the
|
|
6886
|
+
* split-deployment `VOLTRO_ALLOWED_ORIGINS` exists to permit.
|
|
6887
|
+
* `strict-origin-when-cross-origin` nulls it only on an https→http downgrade,
|
|
6888
|
+
* which is the one case where withholding it is the point. It is also what every
|
|
6889
|
+
* current browser does with no header at all, so it surprises nobody.
|
|
6890
|
+
*
|
|
6891
|
+
* The second casualty of `no-referrer` is in the same request: the Referer is
|
|
6892
|
+
* gone too, and `/form/*` reads it to decide where the PRG redirect and the 422
|
|
6893
|
+
* re-render go back to.
|
|
6894
|
+
*/
|
|
6895
|
+
export declare const ORIGIN_NULLING_REFERRER_POLICIES: ReadonlySet<string>;
|
|
6896
|
+
|
|
6817
6897
|
export declare type OriginDecision = {
|
|
6818
6898
|
readonly allowed: true;
|
|
6819
6899
|
readonly reason: 'guard-off' | 'same-origin' | 'loopback' | 'allowlisted' | 'no-browser-origin';
|
|
@@ -6945,7 +7025,7 @@ export declare interface OutboxFacade {
|
|
|
6945
7025
|
export declare interface OutboxFacadeDeps {
|
|
6946
7026
|
/** The REQUEST's store. Inside a mutation this is the transactional view —
|
|
6947
7027
|
* which is what makes the enqueue atomic with the domain write. */
|
|
6948
|
-
readonly store: Pick<DataStore, 'insert' | 'query' | '
|
|
7028
|
+
readonly store: Pick<DataStore, 'insert' | 'query' | 'updateMany'>;
|
|
6949
7029
|
readonly subject: Subject;
|
|
6950
7030
|
readonly traceId: string | null;
|
|
6951
7031
|
/** Nudge the drain worker once the transaction commits. Optional: without
|
|
@@ -7108,6 +7188,15 @@ export declare type PluginScheduleCoordinated = (name: string, intervalMs: numbe
|
|
|
7108
7188
|
|
|
7109
7189
|
export declare const powerOfTwoSelector: (options?: P2COptions) => ReplicaSelector;
|
|
7110
7190
|
|
|
7191
|
+
/**
|
|
7192
|
+
* Whether a `Referrer-Policy` value leaves the `Origin` header intact on a
|
|
7193
|
+
* same-origin state-changing request.
|
|
7194
|
+
*
|
|
7195
|
+
* Reads the LAST supported token, which is what a browser honours: the header
|
|
7196
|
+
* is a fallback list, and every token after a supported one still overrides it.
|
|
7197
|
+
*/
|
|
7198
|
+
export declare const preservesSameOriginHeader: (value: string | false) => boolean;
|
|
7199
|
+
|
|
7111
7200
|
export declare interface PreviewDiff {
|
|
7112
7201
|
readonly rows: ReadonlyArray<RowDiff>;
|
|
7113
7202
|
readonly summary: {
|
|
@@ -9042,6 +9131,20 @@ export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
|
9042
9131
|
* runtime capability so clients replay only when the deployed server proves
|
|
9043
9132
|
* the same key will be deduplicated. */
|
|
9044
9133
|
readonly mutationReplay?: boolean;
|
|
9134
|
+
/**
|
|
9135
|
+
* Publish per-rpc-tag SCHEMA SHAPE digests alongside the capabilities, so a
|
|
9136
|
+
* connecting client can tell whether the copy of the api client it loaded is
|
|
9137
|
+
* the one this server binds.
|
|
9138
|
+
*
|
|
9139
|
+
* Dev only, and set by `voltro dev` alone. The staleness it detects is a
|
|
9140
|
+
* pre-bundled browser chunk that Vite did not re-optimize; `voltro serve`
|
|
9141
|
+
* ships a built bundle where that cannot arise, and there a rolling deploy
|
|
9142
|
+
* would make a transient mismatch NORMAL — reporting it would be noise on
|
|
9143
|
+
* exactly the path where noise is expensive. So this is a deliberate
|
|
9144
|
+
* dev/serve asymmetry rather than an oversight, which is the distinction the
|
|
9145
|
+
* boot-path parity rule asks for.
|
|
9146
|
+
*/
|
|
9147
|
+
readonly publishSurfaceDigest?: boolean;
|
|
9045
9148
|
/** Non-sensitive fleet identity written on the rpc WebSocket open/close
|
|
9046
9149
|
* records. Defaults to the process identity resolver (POD_NAME/HOSTNAME).
|
|
9047
9150
|
* Embedders may state it explicitly when they own process identity. */
|