@voltro/runtime 0.83.1 → 0.84.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/dist/index.d.ts CHANGED
@@ -18,6 +18,8 @@ import { ConstraintFacts } from '@voltro/database';
18
18
  import { ConstraintKind } from '@voltro/database';
19
19
  import { ConstraintViolation } from '@voltro/protocol';
20
20
  import { Context } from 'effect';
21
+ import { CrdtBackend } from '@voltro/local-first';
22
+ import { CrdtMigration } from '@voltro/local-first';
21
23
  import { createServer } from 'node:http';
22
24
  import { Cron } from 'effect';
23
25
  import { DataStore } from '@voltro/database';
@@ -3011,8 +3013,98 @@ export declare const counter: (name: string, description?: string) => Metric.Met
3011
3013
  */
3012
3014
  export declare const countRunningWorkflows: (store: DataStore) => Promise<number>;
3013
3015
 
3016
+ export declare const CRDT_VERSIONS_TABLE = "_voltro_crdt_versions";
3017
+
3018
+ export declare interface CrdtAdmission {
3019
+ readonly maxUpdateBytes?: number | null;
3020
+ readonly maxDocumentBytes?: number | null;
3021
+ readonly rebaseMaxBytes?: number | null;
3022
+ /** Content migrations per table and column — see `crdt.migrations`. */
3023
+ readonly migrations?: Readonly<Record<string, Readonly<Record<string, ReadonlyArray<CrdtMigration>>>>> | null;
3024
+ readonly validate?: CrdtValidator | null;
3025
+ }
3026
+
3027
+ /** A CRDT backend the server can be configured with (`crdt.backend`). */
3028
+ export declare type CrdtBackendChoice = CrdtBackend;
3029
+
3030
+ /** A CRDT cell: table + row id + column. */
3031
+ export declare interface CrdtCellRef {
3032
+ readonly table: string;
3033
+ readonly id: string;
3034
+ readonly column: string;
3035
+ }
3036
+
3037
+ /** What a CRDT cell looks like from the inside — the data an inspector panel
3038
+ * or an alert reads to see a document approaching its limits. */
3039
+ export declare interface CrdtCellStats {
3040
+ /** Stored bytes of the encoded state. */
3041
+ readonly bytes: number;
3042
+ /** The epoch it was last rebased into (`null`: never). */
3043
+ readonly epoch: string | null;
3044
+ /** How many writer sessions its history holds — what grows it. */
3045
+ readonly authors: number;
3046
+ /** Archived versions (snapshots, restores, rebases). */
3047
+ readonly versions: number;
3048
+ /** The limits the write path applies to it. */
3049
+ readonly limits: {
3050
+ readonly compactMaxBytes: number;
3051
+ readonly rebaseMaxBytes: number;
3052
+ readonly maxDocumentBytes: number;
3053
+ readonly maxUpdateBytes: number;
3054
+ };
3055
+ }
3056
+
3057
+ /** The cell's size, epoch, author count and history length, through the
3058
+ * caller's scope. `undefined` when the row is not visible. */
3059
+ export declare const crdtCellStats: (store: CrdtHistoryStore, cell: CrdtCellRef) => Promise<CrdtCellStats | undefined>;
3060
+
3014
3061
  export declare const crdtCompactMaxBytes: () => number;
3015
3062
 
3063
+ /** The slice of a store these functions use — `ctx.store` satisfies it. */
3064
+ export declare interface CrdtHistoryStore {
3065
+ readonly query: (descriptor: never) => Promise<ReadonlyArray<unknown>>;
3066
+ readonly insert: (table: never, row: never) => Promise<unknown>;
3067
+ readonly update: (table: never, id: never, patch: never) => Promise<unknown>;
3068
+ }
3069
+
3070
+ /** The effective per-document limit in bytes (`0` = unlimited). */
3071
+ export declare const crdtMaxDocumentBytes: () => number;
3072
+
3073
+ /** The effective per-update limit in bytes (`0` = unlimited). */
3074
+ export declare const crdtMaxUpdateBytes: () => number;
3075
+
3076
+ /** The content migrations declared for a CRDT column (`crdt.migrations`). */
3077
+ export declare const crdtMigrationsFor: (table: string, column: string) => ReadonlyArray<CrdtMigration>;
3078
+
3079
+ /** The effective hard-compaction threshold in bytes (`0` = never). */
3080
+ export declare const crdtRebaseMaxBytes: () => number;
3081
+
3082
+ /** Refuse a write by returning a message key (`'doc.tooLong'`); accept with
3083
+ * `undefined`. Runs on the server, synchronously, on the write path. */
3084
+ export declare type CrdtValidator = (write: CrdtWriteToValidate) => string | undefined;
3085
+
3086
+ /** One version as a history list shows it — never the bytes. */
3087
+ export declare interface CrdtVersion {
3088
+ readonly id: string;
3089
+ readonly reason: 'snapshot' | 'restore' | 'rebase';
3090
+ readonly label: string | null;
3091
+ readonly epoch: string | null;
3092
+ readonly createdBy: string | null;
3093
+ readonly createdAt: Date;
3094
+ }
3095
+
3096
+ /** What `crdt.validate` is handed for every merged CRDT write. */
3097
+ export declare interface CrdtWriteToValidate {
3098
+ readonly table: string;
3099
+ readonly column: string;
3100
+ /** The merged state about to be stored. */
3101
+ readonly state: Uint8Array;
3102
+ /** The stored state before this write, `undefined` on the first. */
3103
+ readonly previous: Uint8Array | undefined;
3104
+ /** The client's incoming update. */
3105
+ readonly update: Uint8Array;
3106
+ }
3107
+
3016
3108
  /**
3017
3109
  * The cron expression that fires `intervalMs` apart, or `undefined` when no
3018
3110
  * five-field expression does.
@@ -3332,6 +3424,15 @@ export declare const DEFAULT_COMPRESSION_MIN_BYTES = 1024;
3332
3424
 
3333
3425
  export declare const DEFAULT_CRDT_COMPACT_MAX_BYTES: number;
3334
3426
 
3427
+ export declare const DEFAULT_CRDT_MAX_DOCUMENT_BYTES: number;
3428
+
3429
+ export declare const DEFAULT_CRDT_MAX_UPDATE_BYTES: number;
3430
+
3431
+ /** Above this, a merged document is HARD-compacted into a new epoch (its old
3432
+ * lineage archived first). Soft compaction keeps every struct of a document
3433
+ * edited by many sessions; this is what bounds it. */
3434
+ export declare const DEFAULT_CRDT_REBASE_MAX_BYTES: number;
3435
+
3335
3436
  /**
3336
3437
  * How many subscribers one change event is delivered to CONCURRENTLY.
3337
3438
  *
@@ -3684,6 +3785,14 @@ export declare const deliveredRowCount: (value: unknown) => number;
3684
3785
  */
3685
3786
  export declare const deriveKey: (passphrase: string) => Buffer;
3686
3787
 
3788
+ /** Size-only facts about a stored CRDT state — its epoch and how many writer
3789
+ * sessions its history carries. For inspection; `undefined` when the bytes
3790
+ * do not decode (an `.encrypted()` column stores ciphertext). */
3791
+ export declare const describeCrdtState: (state: Uint8Array) => {
3792
+ readonly epoch: string | null;
3793
+ readonly authors: number;
3794
+ } | undefined;
3795
+
3687
3796
  export declare const describeOtelReasons: (why: OtelNeededBecause) => ReadonlyArray<string>;
3688
3797
 
3689
3798
  /**
@@ -6417,6 +6526,10 @@ export declare class LinearScanMatcher implements Matcher {
6417
6526
  /** Every connection the app declares, projected for ONE subject. */
6418
6527
  export declare const listConnectionStates: (store: VaultStore, registry: ConnectionRegistry, subjectId: string) => Promise<ReadonlyArray<ConnectionState_2>>;
6419
6528
 
6529
+ /** The cell's versions, newest first — without their bytes. Empty when the
6530
+ * row is not visible to the caller. */
6531
+ export declare const listCrdtVersions: (store: CrdtHistoryStore, cell: CrdtCellRef) => Promise<ReadonlyArray<CrdtVersion>>;
6532
+
6420
6533
  export declare const listResourcePolicies: () => ReadonlyArray<ResourcePolicy>;
6421
6534
 
6422
6535
  export { listRetentionConflicts }
@@ -7245,6 +7358,25 @@ export declare type MetricSampleType = 'counter' | 'gauge' | 'histogram' | 'summ
7245
7358
  * into the OTel MeterProvider when a `metricReader` is configured. */
7246
7359
  export declare type MetricsMode = 'off' | 'console' | 'otlp' | 'memory';
7247
7360
 
7361
+ /**
7362
+ * Bring every stored document of a CRDT column to the latest content schema
7363
+ * (`crdt.migrations`) — the batch half of a migration. Documents are migrated
7364
+ * on their next write anyway; this does it now, so readers that never write
7365
+ * see the new shape too. Each row is touched with an EMPTY update, which runs
7366
+ * the write path's fold — and with it the migrations, under the same
7367
+ * compare-and-swap, so running this from two replicas at once migrates each
7368
+ * document once. Rows are read through the store it is given, so tenant scope
7369
+ * applies; run it with a system store to cover every tenant.
7370
+ */
7371
+ export declare const migrateCrdtColumn: (store: CrdtHistoryStore, options: {
7372
+ readonly table: string;
7373
+ readonly column: string;
7374
+ readonly batchSize?: number;
7375
+ }) => Promise<{
7376
+ readonly scanned: number;
7377
+ readonly migrated: number;
7378
+ }>;
7379
+
7248
7380
  /** The lowest cadence any platform scheduler can express. */
7249
7381
  export declare const MIN_EXTERNALIZABLE_INTERVAL_MS = 60000;
7250
7382
 
@@ -8128,6 +8260,24 @@ export declare type PluginScheduleCoordinated = (name: string, intervalMs: numbe
8128
8260
 
8129
8261
  export declare const powerOfTwoSelector: (options?: P2COptions) => ReplicaSelector;
8130
8262
 
8263
+ /**
8264
+ * The server's half of restoring a SEALED (`crdtSealed()`) cell. The server
8265
+ * cannot read the content, so it cannot compute the restore — it archives the
8266
+ * current log as a `restore` version (the restore stays undoable) and hands
8267
+ * out the version's ciphertext. The client opens it with `openSealedLog` and
8268
+ * calls the hook's `restore(target)`, which writes the change as an ordinary
8269
+ * sealed edit. The cell's row is read through the caller's store first, as
8270
+ * for every history read. An open column is refused — `restoreCrdtVersion`
8271
+ * restores it on the server, and its history bytes stay `serverOnly()`.
8272
+ */
8273
+ export declare const prepareSealedCrdtRestore: (store: CrdtHistoryStore, input: {
8274
+ readonly versionId: string;
8275
+ readonly createdBy?: string;
8276
+ }) => Promise<{
8277
+ readonly undoPoint: CrdtVersion;
8278
+ readonly versionLog: Uint8Array;
8279
+ } | undefined>;
8280
+
8131
8281
  /**
8132
8282
  * Whether a `Referrer-Policy` value leaves the `Origin` header intact on a
8133
8283
  * same-origin state-changing request.
@@ -9133,6 +9283,8 @@ export declare interface RegistryTableLike {
9133
9283
  };
9134
9284
  /** `crdtText()` column — server-merged on write (see crdtColumns above). */
9135
9285
  readonly crdtManaged?: boolean;
9286
+ /** `crdtSealed()` column — an append-only log of encrypted frames. */
9287
+ readonly crdtSealed?: boolean;
9136
9288
  }>;
9137
9289
  readonly appliedMixins?: ReadonlyArray<{
9138
9290
  readonly id?: string;
@@ -9760,6 +9912,17 @@ export declare interface ResourcePolicy {
9760
9912
  readonly implies?: Readonly<Record<string, ReadonlyArray<string>>>;
9761
9913
  }
9762
9914
 
9915
+ /**
9916
+ * Bring a version back: the cell's content becomes the version's, written as
9917
+ * an ordinary CRDT edit (concurrent edits still merge), after archiving the
9918
+ * state it replaces as a `restore` version. `undefined` when the version or
9919
+ * its row is not visible to the caller.
9920
+ */
9921
+ export declare const restoreCrdtVersion: (store: CrdtHistoryStore, input: {
9922
+ readonly versionId: string;
9923
+ readonly createdBy?: string;
9924
+ }) => Promise<CrdtVersion | undefined>;
9925
+
9763
9926
  /**
9764
9927
  * Mark everything read inside `fn` as RESTRICTING.
9765
9928
  *
@@ -11050,6 +11213,8 @@ export declare interface SchemaInfo {
11050
11213
  * so concurrent clients converge. Empty set for the common non-CRDT table.
11051
11214
  */
11052
11215
  readonly crdtColumns: ReadonlySet<string>;
11216
+ /** End-to-end-sealed CRDT columns (`crdtSealed()`): appended, never merged. */
11217
+ readonly sealedColumns: ReadonlySet<string>;
11053
11218
  /**
11054
11219
  * Columns that a query predicate can hit and benefit from an index:
11055
11220
  * - column-level `.index()`-flagged columns
@@ -11167,6 +11332,8 @@ export declare interface SchemaRegistry {
11167
11332
  * CRDT merge (`mergeCrdtStates`) before an INSERT/UPDATE persists.
11168
11333
  */
11169
11334
  crdtColumns(table: string): ReadonlySet<string>;
11335
+ /** `crdtSealed()` columns of a table — see `SchemaInfo.sealedColumns`. */
11336
+ sealedColumns(table: string): ReadonlySet<string>;
11170
11337
  /**
11171
11338
  * Optional pre-INSERT schema decoder for a table. `undefined` when
11172
11339
  * the table didn't ship `.validate(schema)`. The MutationStore runs
@@ -11477,6 +11644,14 @@ export declare const setBufferedBytes: (label: string, bytes: number) => void;
11477
11644
  * Called by the CLI at boot; tests call it directly. */
11478
11645
  export declare const setConnectionResolver: (resolver: ConnectionResolver | undefined) => void;
11479
11646
 
11647
+ /** Boot/test override — the slot `wireCrdtTunables` writes. Fields left out
11648
+ * keep env/default resolution. */
11649
+ export declare const setCrdtAdmission: (admission: CrdtAdmission | null) => void;
11650
+
11651
+ /** Boot wiring for `crdt.backend` — every default call site (the merge, the
11652
+ * history, the inspection) follows it. `null` restores Yjs. */
11653
+ export declare const setCrdtBackend: (backend: CrdtBackendChoice | null) => void;
11654
+
11480
11655
  /** Boot/test override — the slot `wireCrdtTunables` writes. `null` restores
11481
11656
  * env/default resolution. */
11482
11657
  export declare const setCrdtCompactMaxBytes: (maxBytes: number | null) => void;
@@ -11623,6 +11798,15 @@ export declare interface SnapshotCacheBinding {
11623
11798
  readonly swrMs: number | undefined;
11624
11799
  }
11625
11800
 
11801
+ /**
11802
+ * Archive the cell's current state as a named version. `undefined` when the
11803
+ * row is not visible to the caller.
11804
+ */
11805
+ export declare const snapshotCrdt: (store: CrdtHistoryStore, cell: CrdtCellRef & {
11806
+ readonly label?: string;
11807
+ readonly createdBy?: string;
11808
+ }) => Promise<CrdtVersion | undefined>;
11809
+
11626
11810
  /** Snapshot the whole registry, normalized to `MetricSample[]` — plus the
11627
11811
  * socket-backpressure counters (`subscriptionSocketMetrics.ts`), appended
11628
11812
  * HERE so every reader (Prometheus exporter, inspect Metrics panel) sees
@@ -12984,6 +13168,8 @@ export declare const _voltroConnectionGrantsTable: TableLike;
12984
13168
  */
12985
13169
  export declare const _voltroConnectionsTable: TableLike;
12986
13170
 
13171
+ export declare const _voltroCrdtVersionsTable: TableLike;
13172
+
12987
13173
  /** `_voltro_rebac_tuples` — the relationship tuples `can()` reads. One row =
12988
13174
  * "`subjectId` has `relation` on `<resourceType>:<resourceId>`". Grant by
12989
13175
  * inserting; revoke by deleting (a delete is the live-revocation trigger). */