@tinycloud/replica 0.2.4-beta.3 → 0.3.0-beta.4

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/sqlite.d.cts CHANGED
@@ -1,4 +1,5 @@
1
- import { R as ReplicaStore, j as ReplicaState, b as ReplicaStatus, h as ReplicaConfig, G as GrantRecord, i as ReplicaLastError, f as LeaseToken, l as VerifiedPage, g as LocalEntry, L as ListOpts } from './types-f3-kYLQZ.cjs';
1
+ import { ReplicaConsentAnchor } from '@tinycloud/sdk-services/kv/replication';
2
+ import { R as ReplicaStore, j as ReplicaState, b as ReplicaStatus, h as ReplicaConfig, G as GrantRecord, i as ReplicaLastError, c as LeaseToken, l as VerifiedPage, g as LocalEntry, L as ListOpts } from './types-CQ61VnsP.cjs';
2
3
 
3
4
  type SqlValue = string | number | null | Uint8Array;
4
5
  /** The synchronous SQLite surface shared by `node:sqlite` and `bun:sqlite`. */
@@ -22,7 +23,52 @@ declare function nodeSqliteSupported(version: string): boolean;
22
23
  */
23
24
  declare function loadSqlite(): Promise<SqliteOpener>;
24
25
 
26
+ interface SqliteLayoutEntry {
27
+ path: string;
28
+ kind: "file" | "directory" | "symlink";
29
+ dev: string;
30
+ ino: string;
31
+ }
32
+ type SqliteLayoutIdentity = {
33
+ dev: string;
34
+ ino: string;
35
+ };
36
+ /** JSON-safe exact inventory of non-mirror entries for durable approval. */
37
+ declare function inspectSqliteReplicaLayout(dir: string, options?: {
38
+ allowAdapterFence?: boolean;
39
+ }): Promise<{
40
+ knownEntries: SqliteLayoutEntry[];
41
+ unknownPaths: string[];
42
+ unknownEntries: SqliteLayoutEntry[];
43
+ rootIdentity: SqliteLayoutIdentity;
44
+ }>;
45
+ /** Test-only interleaving seam for replacement races between enumerated unlinks. */
46
+ declare const LAYOUT_FAULTS: unique symbol;
47
+ /** Lease holder only: delete enumerated files, never recurse into an unapproved child. */
48
+ declare function removeSqliteReplicaLayout(dir: string, options?: {
49
+ approvedUnknown?: readonly SqliteLayoutEntry[];
50
+ expectedKnown?: readonly SqliteLayoutEntry[];
51
+ allowMissingDatabase?: boolean;
52
+ expectedRoot?: SqliteLayoutIdentity;
53
+ allowAdapterFence?: boolean;
54
+ [LAYOUT_FAULTS]?: {
55
+ beforeUnlink?(path: string): void | Promise<void>;
56
+ };
57
+ }): Promise<void>;
58
+
25
59
  declare const DURABILITY = "sqlite-wal-synchronous-full+fsynced-blobs";
60
+ type SqliteGrantInstall = {
61
+ installedAt: number;
62
+ effectiveExpiresAt: number;
63
+ consentDeadline: number;
64
+ consentAnchor: ReplicaConsentAnchor;
65
+ };
66
+ type SqliteGrantPolicy = {
67
+ at: number;
68
+ ttlMs: number;
69
+ consentDeadline: number;
70
+ consentAnchor: ReplicaConsentAnchor;
71
+ };
26
72
  /**
27
73
  * Runs a mutation section (every database write and every filesystem
28
74
  * change). The CLI passes one that holds the profile lock briefly and
@@ -63,16 +109,33 @@ declare class SqliteReplicaStore implements ReplicaStore {
63
109
  }): Promise<{
64
110
  state: ReplicaState;
65
111
  status: ReplicaStatus;
112
+ grantInstall: SqliteGrantInstall | null;
113
+ activeGrantInstall: SqliteGrantInstall | null;
66
114
  } | null>;
67
115
  /**
68
116
  * Open the replica store in `dir`. With `create: false` a missing replica is
69
117
  * REPLICA_NOT_FOUND and nothing is written to disk.
70
118
  */
71
119
  static open(dir: string, options: SqliteReplicaStoreOptions): Promise<SqliteReplicaStore>;
120
+ /**
121
+ * A gated read borrows this controller's already-verified writable handle.
122
+ * Borrow before the first await: the parent may close in the callback, but
123
+ * its pin and native handle remain live until the snapshot releases them.
124
+ * Serialize BEGIN through COMMIT/ROLLBACK with writes on the shared handle.
125
+ */
126
+ readTransaction<T>(generation: number, checkGate: () => Promise<void>, section: (store: SqliteReplicaStore) => Promise<T>): Promise<T>;
72
127
  open(): Promise<ReplicaState | null>;
73
128
  init(c: ReplicaConfig): Promise<void>;
74
129
  /** Update the retention opt-in; it takes effect at the next sync. */
75
130
  setRetentionGrant(cid: string | null): Promise<void>;
131
+ getGrantInstall(cid: string): Promise<SqliteGrantInstall | null>;
132
+ /** Every installed CID, including superseded ones, for an origin-wide purge floor. */
133
+ grantInstallTimes(): Promise<Array<{
134
+ cid: string;
135
+ installedAt: number;
136
+ }>>;
137
+ installGatedGrant(g: GrantRecord, policy: SqliteGrantPolicy): Promise<SqliteGrantInstall>;
138
+ recomputeGrantInstall(g: GrantRecord, policy: SqliteGrantPolicy): Promise<SqliteGrantInstall | null>;
76
139
  installGrant(g: GrantRecord): Promise<void>;
77
140
  discardPendingGrant(cid: string, detail: string): Promise<void>;
78
141
  recordPendingGrantError(cid: string, e: ReplicaLastError): Promise<void>;
@@ -87,13 +150,19 @@ declare class SqliteReplicaStore implements ReplicaStore {
87
150
  keepSource?: boolean;
88
151
  }): Promise<void>;
89
152
  /**
90
- * Remove this replica's directory for good (`tc replica reset --purge`).
91
- * Fenced like a commit: `t` must still be a live lease on the database this
92
- * store opened, checked under the write lock, so a paused process can
93
- * never remove a replica another process took over or recreated. Allowed
94
- * on a revoked replica. The store is unusable afterwards; close it.
153
+ * Remove the source-created mirror layout under a live lease. Unknown files
154
+ * are removed only when their exact preflight identities were approved.
95
155
  */
96
- destroy(t: LeaseToken): Promise<void>;
156
+ destroy(t: LeaseToken, options?: {
157
+ approvedUnknown?: readonly SqliteLayoutEntry[];
158
+ expectedKnown?: readonly SqliteLayoutEntry[];
159
+ expectedRoot?: {
160
+ dev: string;
161
+ ino: string;
162
+ };
163
+ allowMissingDatabase?: boolean;
164
+ allowAdapterFence?: boolean;
165
+ }): Promise<void>;
97
166
  /**
98
167
  * Record the revocation (durable before this returns: reads are blocked
99
168
  * from here on, also after a restart), then purge. A purge that fails
@@ -111,4 +180,4 @@ declare class SqliteReplicaStore implements ReplicaStore {
111
180
  close(): Promise<void>;
112
181
  }
113
182
 
114
- export { DURABILITY, type MutationGuard, type SqlValue, type SqliteDatabase, type SqliteOpener, SqliteReplicaStore, type SqliteReplicaStoreOptions, loadSqlite, nodeSqliteSupported };
183
+ export { DURABILITY, type MutationGuard, type SqlValue, type SqliteDatabase, type SqliteLayoutEntry, type SqliteOpener, SqliteReplicaStore, type SqliteReplicaStoreOptions, inspectSqliteReplicaLayout, loadSqlite, nodeSqliteSupported, removeSqliteReplicaLayout };
package/dist/sqlite.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { R as ReplicaStore, j as ReplicaState, b as ReplicaStatus, h as ReplicaConfig, G as GrantRecord, i as ReplicaLastError, f as LeaseToken, l as VerifiedPage, g as LocalEntry, L as ListOpts } from './types-f3-kYLQZ.js';
1
+ import { ReplicaConsentAnchor } from '@tinycloud/sdk-services/kv/replication';
2
+ import { R as ReplicaStore, j as ReplicaState, b as ReplicaStatus, h as ReplicaConfig, G as GrantRecord, i as ReplicaLastError, c as LeaseToken, l as VerifiedPage, g as LocalEntry, L as ListOpts } from './types-CQ61VnsP.js';
2
3
 
3
4
  type SqlValue = string | number | null | Uint8Array;
4
5
  /** The synchronous SQLite surface shared by `node:sqlite` and `bun:sqlite`. */
@@ -22,7 +23,52 @@ declare function nodeSqliteSupported(version: string): boolean;
22
23
  */
23
24
  declare function loadSqlite(): Promise<SqliteOpener>;
24
25
 
26
+ interface SqliteLayoutEntry {
27
+ path: string;
28
+ kind: "file" | "directory" | "symlink";
29
+ dev: string;
30
+ ino: string;
31
+ }
32
+ type SqliteLayoutIdentity = {
33
+ dev: string;
34
+ ino: string;
35
+ };
36
+ /** JSON-safe exact inventory of non-mirror entries for durable approval. */
37
+ declare function inspectSqliteReplicaLayout(dir: string, options?: {
38
+ allowAdapterFence?: boolean;
39
+ }): Promise<{
40
+ knownEntries: SqliteLayoutEntry[];
41
+ unknownPaths: string[];
42
+ unknownEntries: SqliteLayoutEntry[];
43
+ rootIdentity: SqliteLayoutIdentity;
44
+ }>;
45
+ /** Test-only interleaving seam for replacement races between enumerated unlinks. */
46
+ declare const LAYOUT_FAULTS: unique symbol;
47
+ /** Lease holder only: delete enumerated files, never recurse into an unapproved child. */
48
+ declare function removeSqliteReplicaLayout(dir: string, options?: {
49
+ approvedUnknown?: readonly SqliteLayoutEntry[];
50
+ expectedKnown?: readonly SqliteLayoutEntry[];
51
+ allowMissingDatabase?: boolean;
52
+ expectedRoot?: SqliteLayoutIdentity;
53
+ allowAdapterFence?: boolean;
54
+ [LAYOUT_FAULTS]?: {
55
+ beforeUnlink?(path: string): void | Promise<void>;
56
+ };
57
+ }): Promise<void>;
58
+
25
59
  declare const DURABILITY = "sqlite-wal-synchronous-full+fsynced-blobs";
60
+ type SqliteGrantInstall = {
61
+ installedAt: number;
62
+ effectiveExpiresAt: number;
63
+ consentDeadline: number;
64
+ consentAnchor: ReplicaConsentAnchor;
65
+ };
66
+ type SqliteGrantPolicy = {
67
+ at: number;
68
+ ttlMs: number;
69
+ consentDeadline: number;
70
+ consentAnchor: ReplicaConsentAnchor;
71
+ };
26
72
  /**
27
73
  * Runs a mutation section (every database write and every filesystem
28
74
  * change). The CLI passes one that holds the profile lock briefly and
@@ -63,16 +109,33 @@ declare class SqliteReplicaStore implements ReplicaStore {
63
109
  }): Promise<{
64
110
  state: ReplicaState;
65
111
  status: ReplicaStatus;
112
+ grantInstall: SqliteGrantInstall | null;
113
+ activeGrantInstall: SqliteGrantInstall | null;
66
114
  } | null>;
67
115
  /**
68
116
  * Open the replica store in `dir`. With `create: false` a missing replica is
69
117
  * REPLICA_NOT_FOUND and nothing is written to disk.
70
118
  */
71
119
  static open(dir: string, options: SqliteReplicaStoreOptions): Promise<SqliteReplicaStore>;
120
+ /**
121
+ * A gated read borrows this controller's already-verified writable handle.
122
+ * Borrow before the first await: the parent may close in the callback, but
123
+ * its pin and native handle remain live until the snapshot releases them.
124
+ * Serialize BEGIN through COMMIT/ROLLBACK with writes on the shared handle.
125
+ */
126
+ readTransaction<T>(generation: number, checkGate: () => Promise<void>, section: (store: SqliteReplicaStore) => Promise<T>): Promise<T>;
72
127
  open(): Promise<ReplicaState | null>;
73
128
  init(c: ReplicaConfig): Promise<void>;
74
129
  /** Update the retention opt-in; it takes effect at the next sync. */
75
130
  setRetentionGrant(cid: string | null): Promise<void>;
131
+ getGrantInstall(cid: string): Promise<SqliteGrantInstall | null>;
132
+ /** Every installed CID, including superseded ones, for an origin-wide purge floor. */
133
+ grantInstallTimes(): Promise<Array<{
134
+ cid: string;
135
+ installedAt: number;
136
+ }>>;
137
+ installGatedGrant(g: GrantRecord, policy: SqliteGrantPolicy): Promise<SqliteGrantInstall>;
138
+ recomputeGrantInstall(g: GrantRecord, policy: SqliteGrantPolicy): Promise<SqliteGrantInstall | null>;
76
139
  installGrant(g: GrantRecord): Promise<void>;
77
140
  discardPendingGrant(cid: string, detail: string): Promise<void>;
78
141
  recordPendingGrantError(cid: string, e: ReplicaLastError): Promise<void>;
@@ -87,13 +150,19 @@ declare class SqliteReplicaStore implements ReplicaStore {
87
150
  keepSource?: boolean;
88
151
  }): Promise<void>;
89
152
  /**
90
- * Remove this replica's directory for good (`tc replica reset --purge`).
91
- * Fenced like a commit: `t` must still be a live lease on the database this
92
- * store opened, checked under the write lock, so a paused process can
93
- * never remove a replica another process took over or recreated. Allowed
94
- * on a revoked replica. The store is unusable afterwards; close it.
153
+ * Remove the source-created mirror layout under a live lease. Unknown files
154
+ * are removed only when their exact preflight identities were approved.
95
155
  */
96
- destroy(t: LeaseToken): Promise<void>;
156
+ destroy(t: LeaseToken, options?: {
157
+ approvedUnknown?: readonly SqliteLayoutEntry[];
158
+ expectedKnown?: readonly SqliteLayoutEntry[];
159
+ expectedRoot?: {
160
+ dev: string;
161
+ ino: string;
162
+ };
163
+ allowMissingDatabase?: boolean;
164
+ allowAdapterFence?: boolean;
165
+ }): Promise<void>;
97
166
  /**
98
167
  * Record the revocation (durable before this returns: reads are blocked
99
168
  * from here on, also after a restart), then purge. A purge that fails
@@ -111,4 +180,4 @@ declare class SqliteReplicaStore implements ReplicaStore {
111
180
  close(): Promise<void>;
112
181
  }
113
182
 
114
- export { DURABILITY, type MutationGuard, type SqlValue, type SqliteDatabase, type SqliteOpener, SqliteReplicaStore, type SqliteReplicaStoreOptions, loadSqlite, nodeSqliteSupported };
183
+ export { DURABILITY, type MutationGuard, type SqlValue, type SqliteDatabase, type SqliteLayoutEntry, type SqliteOpener, SqliteReplicaStore, type SqliteReplicaStoreOptions, inspectSqliteReplicaLayout, loadSqlite, nodeSqliteSupported, removeSqliteReplicaLayout };