mindoodb 0.0.53 → 0.0.55

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.
Files changed (99) hide show
  1. package/README-server.md +125 -69
  2. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +17 -0
  3. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  4. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +22 -0
  5. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  6. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +58 -0
  7. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  8. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +156 -3
  9. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
  10. package/dist/browser/index.mjs +2 -0
  11. package/dist/core/BaseMindooDB.d.ts +73 -74
  12. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  13. package/dist/core/BaseMindooDB.js +263 -509
  14. package/dist/core/BaseMindooDB.js.map +1 -1
  15. package/dist/core/MindooDBServerAdmin.d.ts +44 -22
  16. package/dist/core/MindooDBServerAdmin.d.ts.map +1 -1
  17. package/dist/core/MindooDBServerAdmin.js +45 -21
  18. package/dist/core/MindooDBServerAdmin.js.map +1 -1
  19. package/dist/core/appendonlystores/syncStores.d.ts +147 -0
  20. package/dist/core/appendonlystores/syncStores.d.ts.map +1 -0
  21. package/dist/core/appendonlystores/syncStores.js +612 -0
  22. package/dist/core/appendonlystores/syncStores.js.map +1 -0
  23. package/dist/core/builtinDbInvariants.d.ts +30 -0
  24. package/dist/core/builtinDbInvariants.d.ts.map +1 -1
  25. package/dist/core/builtinDbInvariants.js +97 -0
  26. package/dist/core/builtinDbInvariants.js.map +1 -1
  27. package/dist/core/index.d.ts +1 -1
  28. package/dist/core/index.d.ts.map +1 -1
  29. package/dist/core/index.js +7 -4
  30. package/dist/core/index.js.map +1 -1
  31. package/dist/core/types.d.ts +42 -0
  32. package/dist/core/types.d.ts.map +1 -1
  33. package/dist/node/server/CapabilityMatcher.d.ts +2 -2
  34. package/dist/node/server/CapabilityMatcher.js +2 -2
  35. package/dist/node/server/MindooDBServer.d.ts +14 -1
  36. package/dist/node/server/MindooDBServer.d.ts.map +1 -1
  37. package/dist/node/server/MindooDBServer.js +166 -159
  38. package/dist/node/server/MindooDBServer.js.map +1 -1
  39. package/dist/node/server/SyncEventBus.d.ts +10 -0
  40. package/dist/node/server/SyncEventBus.d.ts.map +1 -1
  41. package/dist/node/server/SyncEventBus.js.map +1 -1
  42. package/dist/node/server/TenantManager.d.ts +58 -6
  43. package/dist/node/server/TenantManager.d.ts.map +1 -1
  44. package/dist/node/server/TenantManager.js +90 -65
  45. package/dist/node/server/TenantManager.js.map +1 -1
  46. package/dist/node/server/add-to-network.d.ts.map +1 -1
  47. package/dist/node/server/add-to-network.js +33 -15
  48. package/dist/node/server/add-to-network.js.map +1 -1
  49. package/dist/node/server/canonicalSetupName.d.ts +22 -0
  50. package/dist/node/server/canonicalSetupName.d.ts.map +1 -0
  51. package/dist/node/server/canonicalSetupName.js +38 -0
  52. package/dist/node/server/canonicalSetupName.js.map +1 -0
  53. package/dist/node/server/config.d.ts.map +1 -1
  54. package/dist/node/server/config.js +33 -1
  55. package/dist/node/server/config.js.map +1 -1
  56. package/dist/node/server/peer/ClusterAuditLog.d.ts +64 -0
  57. package/dist/node/server/peer/ClusterAuditLog.d.ts.map +1 -0
  58. package/dist/node/server/peer/ClusterAuditLog.js +99 -0
  59. package/dist/node/server/peer/ClusterAuditLog.js.map +1 -0
  60. package/dist/node/server/peer/ClusterJobRunner.d.ts +43 -0
  61. package/dist/node/server/peer/ClusterJobRunner.d.ts.map +1 -0
  62. package/dist/node/server/peer/ClusterJobRunner.js +119 -0
  63. package/dist/node/server/peer/ClusterJobRunner.js.map +1 -0
  64. package/dist/node/server/peer/ClusterManager.d.ts +116 -0
  65. package/dist/node/server/peer/ClusterManager.d.ts.map +1 -0
  66. package/dist/node/server/peer/ClusterManager.js +274 -0
  67. package/dist/node/server/peer/ClusterManager.js.map +1 -0
  68. package/dist/node/server/peer/PeerAuthService.d.ts +69 -0
  69. package/dist/node/server/peer/PeerAuthService.d.ts.map +1 -0
  70. package/dist/node/server/peer/PeerAuthService.js +208 -0
  71. package/dist/node/server/peer/PeerAuthService.js.map +1 -0
  72. package/dist/node/server/peer/PeerReplicator.d.ts +232 -0
  73. package/dist/node/server/peer/PeerReplicator.d.ts.map +1 -0
  74. package/dist/node/server/peer/PeerReplicator.js +879 -0
  75. package/dist/node/server/peer/PeerReplicator.js.map +1 -0
  76. package/dist/node/server/peer/routes.d.ts +66 -0
  77. package/dist/node/server/peer/routes.d.ts.map +1 -0
  78. package/dist/node/server/peer/routes.js +322 -0
  79. package/dist/node/server/peer/routes.js.map +1 -0
  80. package/dist/node/server/peer/types.d.ts +244 -0
  81. package/dist/node/server/peer/types.d.ts.map +1 -0
  82. package/dist/node/server/peer/types.js +189 -0
  83. package/dist/node/server/peer/types.js.map +1 -0
  84. package/dist/node/server/server.d.ts +1 -1
  85. package/dist/node/server/server.js +18 -37
  86. package/dist/node/server/server.js.map +1 -1
  87. package/dist/node/server/serverinit.d.ts +2 -1
  88. package/dist/node/server/serverinit.d.ts.map +1 -1
  89. package/dist/node/server/serverinit.js +34 -12
  90. package/dist/node/server/serverinit.js.map +1 -1
  91. package/dist/node/server/types.d.ts +42 -30
  92. package/dist/node/server/types.d.ts.map +1 -1
  93. package/dist/node/server/types.js +1 -7
  94. package/dist/node/server/types.js.map +1 -1
  95. package/dist/node/server/validation.d.ts +0 -6
  96. package/dist/node/server/validation.d.ts.map +1 -1
  97. package/dist/node/server/validation.js +1 -7
  98. package/dist/node/server/validation.js.map +1 -1
  99. package/package.json +1 -1
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Server-to-server replication with one trusted peer.
3
+ *
4
+ * One replicator instance per entry in `trusted-servers.json` that carries a
5
+ * `url`. It owns everything about that link: the peer session, the set of
6
+ * tenants both sides hold, the mirror loop over every database, the live push
7
+ * out of {@link SyncEventBus}, and the SSE subscription that pulls the other
8
+ * direction.
9
+ *
10
+ * ## What it replicates
11
+ *
12
+ * Everything both servers already have in common, and nothing else. The tenant
13
+ * set is intersected via a Bloom summary (see {@link refreshIntersection}), so
14
+ * a server never learns which tenants it does *not* host on the other side. For
15
+ * each shared tenant it mirrors **all** databases — the union of the local and
16
+ * remote database lists — in both stores (`docs` and `attachments`).
17
+ *
18
+ * ## Convergence invariants
19
+ *
20
+ * 1. **Directory first.** Databases are ordered by
21
+ * {@link orderDatabasesForReplication}: `directory`, then `userdirectory`,
22
+ * then the rest. An application entry signed by a key the peer does not
23
+ * trust yet is rejected per entry, so the grants have to land first.
24
+ * 2. **Cursor holds on rejection.** Unlike a client, a peer must not skip past
25
+ * a rejected entry — that is permanent divergence between two servers that
26
+ * are supposed to be identical. The peer path passes
27
+ * `rejectionPolicy: "hold"`, which clamps the cursor so the next run
28
+ * re-offers the entry once the missing trust has replicated.
29
+ * 3. **Receipts are preserved, not re-stamped.** Enforced on the receiving side
30
+ * in `ServerNetworkContentAddressedStore`; this side just transports.
31
+ */
32
+ import { StoreKind, type ContentAddressedStore } from "../../../core/types";
33
+ import type { CryptoAdapter } from "../../../core/crypto/CryptoAdapter";
34
+ import { Logger } from "../../../core/logging";
35
+ import type { TrustedServer } from "../types";
36
+ import type { SyncEventBus } from "../SyncEventBus";
37
+ import { type ClusterHealth, type ClusterHealthReason, type ClusterPeerStatus, type ClusterTenantStatus, type ClusterTopologyPeer, type PeerRole } from "./types";
38
+ /** What a replicator needs from the surrounding server to do its job. */
39
+ export interface PeerReplicatorHost {
40
+ cryptoAdapter: CryptoAdapter;
41
+ /** This server's name, as the peer knows it in its own trusted-servers list. */
42
+ localServerName: string;
43
+ /** This server's Ed25519 public key (PEM) — how the peer looks us up. */
44
+ localSigningPublicKey: string;
45
+ /** This node's own mesh role, which decides whether spoke-to-spoke is suppressed. */
46
+ localRole: PeerRole;
47
+ /** Ed25519 signing key, for the peer challenge. */
48
+ getSigningKey(): Promise<CryptoKey | undefined>;
49
+ /** RSA private key, to unwrap entries the peer sends us. */
50
+ getEncryptionKey(): Promise<CryptoKey | undefined>;
51
+ /** Tenant ids hosted locally. */
52
+ listTenants(): string[];
53
+ /** Database ids held locally for a tenant. */
54
+ listDatabases(tenantId: string): string[];
55
+ /** Local store for a (tenant, db, kind) triple, created on demand. */
56
+ getLocalStore(tenantId: string, dbId: string, storeKind: StoreKind): Promise<ContentAddressedStore>;
57
+ eventBus: SyncEventBus;
58
+ logger?: Logger;
59
+ }
60
+ export interface PeerSyncScope {
61
+ tenantId?: string;
62
+ dbId?: string;
63
+ }
64
+ export interface PeerSyncRunResult {
65
+ peer: string;
66
+ tenants: number;
67
+ databases: number;
68
+ pushed: number;
69
+ pulled: number;
70
+ rejected: number;
71
+ /** Pairs whose cursor is clamped waiting for trust to replicate (invariant 2). */
72
+ held: number;
73
+ errors: string[];
74
+ }
75
+ export declare class PeerReplicator {
76
+ private peer;
77
+ private readonly host;
78
+ private readonly logger;
79
+ private direction;
80
+ private role;
81
+ private attachments;
82
+ private running;
83
+ private paused;
84
+ private sessionState;
85
+ private eventsConnected;
86
+ private token;
87
+ private tokenIssuedAt;
88
+ private tokenPromise;
89
+ private intersection;
90
+ private intersectionAt;
91
+ private tenants;
92
+ private transferredEntries;
93
+ private transferredBytes;
94
+ private syncInFlight;
95
+ private pendingScopes;
96
+ private pushTimer;
97
+ private idleTimer;
98
+ private reconnectTimer;
99
+ private reconnectAttempt;
100
+ private sseAbort;
101
+ private unsubscribeBus;
102
+ private lastError;
103
+ private lastErrorClass;
104
+ private lastErrorAt;
105
+ private lastSyncAt;
106
+ /**
107
+ * Scan cursors, per (source, target) store pair.
108
+ *
109
+ * In-process only, deliberately: a restarted server pays one metadata scan
110
+ * per pair and then re-establishes the fast path from the store head. Cheap
111
+ * enough, and it avoids a second on-disk format to keep consistent with the
112
+ * stores it describes.
113
+ */
114
+ private readonly cursors;
115
+ constructor(peer: TrustedServer, host: PeerReplicatorHost);
116
+ get name(): string;
117
+ get url(): string | undefined;
118
+ /** Replace the peer config in place (peer CRUD) without dropping cursors. */
119
+ updatePeer(peer: TrustedServer): void;
120
+ /** Roles and endpoint, for `GET /system/cluster/topology`. */
121
+ topologyEntry(): ClusterTopologyPeer;
122
+ start(): void;
123
+ stop(): Promise<void>;
124
+ pause(): void;
125
+ resume(): void;
126
+ private bootstrap;
127
+ private scheduleReconnect;
128
+ private ensureToken;
129
+ private authenticate;
130
+ private peerFetch;
131
+ /**
132
+ * Recompute the set of tenants both servers host.
133
+ *
134
+ * We send a Bloom summary of our tenant ids; the peer answers with the ids on
135
+ * *its* side that the filter might contain. Those are candidates only — a
136
+ * Bloom filter has false positives — so the result is intersected against the
137
+ * authoritative local list before anything is replicated. That second step is
138
+ * what makes the false-positive rate a performance question rather than a
139
+ * correctness one.
140
+ */
141
+ refreshIntersection(): Promise<string[]>;
142
+ /**
143
+ * Run one full replication pass, optionally narrowed to a tenant or database.
144
+ *
145
+ * Concurrent calls collapse onto the in-flight run: the caller that arrives
146
+ * second gets the same promise rather than a second parallel mirror of the
147
+ * same stores.
148
+ */
149
+ syncNow(scope?: PeerSyncScope): Promise<PeerSyncRunResult>;
150
+ /**
151
+ * Re-offer entries the peer rejected.
152
+ *
153
+ * Under the hold policy the cursor is already clamped, so a plain sync run is
154
+ * the retry — this exists as a named admin action so the UI has something to
155
+ * call that says what it does.
156
+ */
157
+ retryRejected(scope?: PeerSyncScope): Promise<PeerSyncRunResult>;
158
+ private runSync;
159
+ /**
160
+ * The (database, store) pairs to mirror for one tenant, in order.
161
+ *
162
+ * `eager` interleaves — each database's documents are immediately followed by
163
+ * its attachments, so a database is complete before the next one starts.
164
+ * `lazy` runs every document store first and only then the attachment stores:
165
+ * a run that is interrupted (or a link that is slow) has then spent its
166
+ * bandwidth on the text, which is what makes documents readable, rather than
167
+ * on blobs that can be fetched later. `never` skips attachments entirely.
168
+ *
169
+ * Database order comes from {@link orderDatabasesForReplication} either way —
170
+ * invariant 1 outranks the attachment policy.
171
+ */
172
+ private mirrorPlan;
173
+ /**
174
+ * Databases to mirror for a tenant: the union of both sides, in invariant
175
+ * order (invariant 1).
176
+ *
177
+ * Union rather than intersection, because a database that exists only on the
178
+ * peer is exactly the thing a fresh mirror needs to pull.
179
+ */
180
+ private databasesFor;
181
+ private syncStorePair;
182
+ /**
183
+ * One leg of a store pair, with a batch-wide denial folded into `held`.
184
+ *
185
+ * See {@link syncStorePair}: a denial means "not now", so the cursor must
186
+ * stay put and the pair is retried on the next run. Any other failure is a
187
+ * real error and propagates to the tenant loop.
188
+ */
189
+ private transfer;
190
+ private createRemoteStore;
191
+ private cursorStore;
192
+ private onLocalChange;
193
+ /**
194
+ * Round-robin over the pending (tenant, db) scopes.
195
+ *
196
+ * Sequential on purpose: a hub with many spokes should not open a hundred
197
+ * parallel sessions to one peer, and one busy tenant must not starve the
198
+ * others — each pending scope gets its turn in the order it was queued.
199
+ */
200
+ private flushScopes;
201
+ private startEventStream;
202
+ private consumeEventStream;
203
+ private handleEventFrame;
204
+ private recordError;
205
+ /**
206
+ * Status snapshot for `GET /system/cluster/status`.
207
+ *
208
+ * Read straight from in-memory replication state — no store scans — so the
209
+ * admin UI can poll it without competing with replication for I/O. Contains
210
+ * counts and classified reasons only: never a docId, never an author key.
211
+ */
212
+ snapshot(): ClusterPeerStatus;
213
+ tenantSnapshot(tenantId: string): ClusterTenantStatus | null;
214
+ private tenantStatus;
215
+ /** Reasons that come from the link itself rather than from any one tenant. */
216
+ private peerLevelReasons;
217
+ }
218
+ /**
219
+ * Collapse reasons into one health verdict, shared by the per-tenant, per-peer
220
+ * and per-node rollups so all three agree on the thresholds.
221
+ *
222
+ * `stalled` outranks `degraded` deliberately. A clamped cursor is the visible
223
+ * precursor of divergence: the link looks healthy, entries keep flowing, and
224
+ * yet one database is quietly stuck behind an entry the peer will not accept
225
+ * until the directory catches up. That is the state an operator most needs to
226
+ * see, so a transient error elsewhere must not mask it.
227
+ */
228
+ export declare function rollUpHealth(tenants: ClusterTenantStatus[], extraReasons?: ClusterHealthReason[]): {
229
+ health: ClusterHealth;
230
+ reasons: ClusterHealthReason[];
231
+ };
232
+ //# sourceMappingURL=PeerReplicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeerReplicator.d.ts","sourceRoot":"","sources":["../../../../src/node/server/peer/PeerReplicator.ts"],"names":[],"mappings":"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"}