@classytic/mongokit 3.43.1 → 3.45.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/README.md +18 -3
- package/dist/{PaginationEngine-DZnkbSrr.mjs → PaginationEngine-BRlLTQQz.mjs} +13 -27
- package/dist/{PaginationEngine-CRHyuUtw.d.mts → PaginationEngine-BWb-c47a.d.mts} +1 -3
- package/dist/{Repository-DnL4xk5w.d.mts → Repository-DJuRmBNx.d.mts} +44 -13
- package/dist/{Repository-Dj6xqPxJ.mjs → Repository-DheA7oW-.mjs} +330 -112
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +2 -2
- package/dist/{actions-ChYfkPYP.mjs → actions-DKQx9ToJ.mjs} +3 -4
- package/dist/adapter/index.d.mts +6 -10
- package/dist/adapter/index.mjs +1 -1
- package/dist/{adapter-CkMoMF83.mjs → adapter-Qzgc3ZD_.mjs} +4 -6
- package/dist/ai/index.d.mts +21 -8
- package/dist/ai/index.mjs +15 -9
- package/dist/better-auth/index.d.mts +21 -20
- package/dist/better-auth/index.mjs +12 -23
- package/dist/{coercion-BjdPX3YF.d.mts → coercion-COp9DRNw.d.mts} +0 -2
- package/dist/{create-repository-UjwPWR1z.mjs → create-repository-C9DHHcl7.mjs} +4 -5
- package/dist/{create-repository-CJtVdwig.d.mts → create-repository-DG-gwOf0.d.mts} +5 -7
- package/dist/{derive-DRBiegRH.mjs → derive-Dxsc31fV.mjs} +3 -6
- package/dist/{error-BuByZwKU.mjs → error-DjdmPLWO.mjs} +1 -2
- package/dist/{field-selection-FSQFLpsU.mjs → field-selection-DPFaFw9Y.mjs} +1 -2
- package/dist/{id-chunks-BmAwsqNk.mjs → id-chunks-DH-RAZWG.mjs} +13 -8
- package/dist/{id-resolution-BqDrk0S2.mjs → id-resolution-Cqh49d9J.mjs} +1 -2
- package/dist/idempotency/index.d.mts +4 -7
- package/dist/idempotency/index.mjs +1 -2
- package/dist/{index-SYF8N28D.d.mts → index-5mhQ63_B.d.mts} +3 -4
- package/dist/{index-C0AjVqX3.d.mts → index-ehGZLbrd.d.mts} +2 -8
- package/dist/index.d.mts +70 -102
- package/dist/index.mjs +36 -52
- package/dist/indexes/verify-indexes.d.mts +8 -11
- package/dist/indexes/verify-indexes.mjs +1 -2
- package/dist/{indexes-DIjMpYES.d.mts → indexes-FfyOuhDK.d.mts} +0 -2
- package/dist/{join-scope-DSAznE8E.mjs → join-scope-C1gOtZ59.mjs} +2 -3
- package/dist/kernel-conformance/index.d.mts +39 -13
- package/dist/kernel-conformance/index.mjs +4 -7
- package/dist/lock/index.d.mts +134 -7
- package/dist/lock/index.mjs +349 -14
- package/dist/{logger-K7dPmu2U.mjs → logger-hbWOlj_X.mjs} +1 -2
- package/dist/{method-registry.plugin-C63pGn1d.mjs → method-registry.plugin-BeJfQBJV.mjs} +5 -7
- package/dist/{model-registry-ClKtWiHa.mjs → model-registry-DrVfJ3Nt.mjs} +1 -2
- package/dist/{mongooseToJsonSchema-C3k4ide0.mjs → mongooseToJsonSchema-DMDotz4_.mjs} +2 -3
- package/dist/{multi-tenant.plugin-B_q9NUHc.d.mts → multi-tenant.plugin-BTPtCLNK.d.mts} +143 -11
- package/dist/{operations-XiFgG5US.d.mts → operations-D6XsHx4e.d.mts} +19 -11
- package/dist/outbox/index.d.mts +24 -9
- package/dist/outbox/index.mjs +17 -6
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/pagination/utils/limits.d.mts +6 -9
- package/dist/pagination/utils/limits.mjs +2 -3
- package/dist/{pagination-D6psses0.d.mts → pagination-BAM9cA4N.d.mts} +6 -16
- package/dist/{plugin-options-Cirmb4Kp.d.mts → plugin-options-DrNGWV5b.d.mts} +2 -4
- package/dist/plugins/index.d.mts +6 -7
- package/dist/plugins/index.mjs +6 -7
- package/dist/query/primitives/coercion.d.mts +1 -1
- package/dist/query/primitives/coercion.mjs +2 -3
- package/dist/query/primitives/geo.d.mts +11 -14
- package/dist/query/primitives/geo.mjs +1 -2
- package/dist/query/primitives/indexes.d.mts +1 -1
- package/dist/query/primitives/indexes.mjs +1 -2
- package/dist/{query-defaults-BxUcSOoF.mjs → query-defaults-DwvWUjZU.mjs} +18 -54
- package/dist/read-model/index.d.mts +18 -21
- package/dist/read-model/index.mjs +3 -4
- package/dist/{repository-MqAP409e.d.mts → repository-B0aFVgP2.d.mts} +25 -29
- package/dist/retention-purge-CCd_VXUf.d.mts +38 -0
- package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-D8jQpDG7.mjs} +1 -2
- package/dist/search/index.d.mts +1 -1
- package/dist/search/index.mjs +1 -1
- package/dist/sync/index.d.mts +113 -17
- package/dist/sync/index.mjs +421 -65
- package/dist/tenant/index.d.mts +8 -11
- package/dist/tenant/index.mjs +1 -2
- package/dist/testkit/index.d.mts +179 -23
- package/dist/testkit/index.mjs +421 -23
- package/dist/{timestamp.plugin-DpOWavVI.mjs → timestamp.plugin-B-IJrlYb.mjs} +192 -49
- package/dist/{to-plain-vksRrLtc.mjs → to-plain-CEKv_ylg.mjs} +2 -4
- package/dist/{to-plain-o5tUY2nV.d.mts → to-plain-Do-8jTKC.d.mts} +2 -16
- package/dist/{transaction-DmiB4k2P.mjs → transaction-C6Oj941P.mjs} +18 -19
- package/dist/{type-utils-CLzRFtIA.d.mts → type-utils-CKvuewAL.d.mts} +0 -2
- package/dist/{update-WgeAUJ_I.mjs → update-CYaJMu6j.mjs} +13 -23
- package/dist/usage/index.d.mts +2 -5
- package/dist/usage/index.mjs +8 -6
- package/dist/utils/index.d.mts +8 -10
- package/dist/utils/index.mjs +7 -7
- package/dist/{validation-chain.plugin-BAeC5eVT.d.mts → validation-chain.plugin-COYrUdd8.d.mts} +150 -48
- package/dist/{validation-chain.plugin-DRApTmkN.mjs → validation-chain.plugin-DJplVJ12.mjs} +210 -55
- package/llms.txt +33 -0
- package/package.json +29 -25
- package/skills/mongokit/SKILL.md +112 -0
- package/skills/mongokit/references/pagination-search.md +87 -0
- package/skills/mongokit/references/plugins-tenancy.md +103 -0
- package/skills/mongokit/references/repository-api.md +83 -0
- package/skills/mongokit/references/transactions-outbox.md +103 -0
package/dist/sync/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ClientSession, Connection, Model } from "mongoose";
|
|
2
|
-
import { ChangeLogAppendOptions, ChangeLogStore, CommandStreamStore, CommandStreamTx } from "@classytic/repo-core/sync";
|
|
3
|
-
|
|
4
|
-
interface ChangeLogModelOptions {
|
|
2
|
+
import { ChangeEntry, ChangeLogAppendOptions, ChangeLogStore, ChangesPage, ChangesSinceOptions, CommandStreamStore, CommandStreamTx } from "@classytic/repo-core/sync";
|
|
3
|
+
export interface ChangeLogModelOptions {
|
|
5
4
|
/** Entries collection. Default `sync_changes`; its counter lives in `<collection>_counter`. */
|
|
6
5
|
collection?: string;
|
|
7
6
|
/** Mongoose model name prefix. Default `SyncChange`. Must be unique per connection. */
|
|
@@ -14,29 +13,87 @@ interface ChangeLogModelOptions {
|
|
|
14
13
|
* before, so no reader can checkpoint past an entry that appears later.
|
|
15
14
|
*/
|
|
16
15
|
sequencing?: 'in-transaction' | 'deferred';
|
|
16
|
+
/**
|
|
17
|
+
* Deferred sequencing: how long the sequencer lease lasts, in ms (default {@link DEFAULT_SEQUENCER_LEASE_MS}).
|
|
18
|
+
* The holder renews it with every batch it commits, so this bounds one batch, not one pass, and it is the longest
|
|
19
|
+
* a sequencer that dies mid-pass can delay numbering. Expiry is judged on the database clock (`$$NOW`), so
|
|
20
|
+
* process clock skew does not stretch it. A holder whose lease was taken over cannot write: each batch commits
|
|
21
|
+
* in one transaction gated on the lease token. Integer, at least 100.
|
|
22
|
+
*/
|
|
23
|
+
sequencerLeaseMs?: number;
|
|
17
24
|
}
|
|
18
|
-
|
|
25
|
+
/** Default deferred-sequencer lease: a crashed holder delays numbering at most this long. */
|
|
26
|
+
export declare const DEFAULT_SEQUENCER_LEASE_MS = 5000;
|
|
27
|
+
export interface ChangeLogModels {
|
|
19
28
|
entries: Model<Record<string, unknown>>;
|
|
20
29
|
counter: Model<Record<string, unknown>>;
|
|
30
|
+
/**
|
|
31
|
+
* `prune`'s horizons per `(tenantId, scope)` (`<collection>_horizon`, `tenantId: null` for untenanted entries):
|
|
32
|
+
* the highest seq it deleted there. A filtered reader is expired only by the horizons of what it can see.
|
|
33
|
+
* Always set by `createChangeLogModels`; a hand-built models object without it falls back to the feed-wide
|
|
34
|
+
* horizon for every reader.
|
|
35
|
+
*/
|
|
36
|
+
horizons?: Model<Record<string, unknown>>;
|
|
21
37
|
/** Staged, not-yet-numbered entries — present only under `sequencing: 'deferred'`. */
|
|
22
38
|
pending?: Model<Record<string, unknown>>;
|
|
23
39
|
sequencing: 'in-transaction' | 'deferred';
|
|
40
|
+
/** Deferred sequencer lease in ms; {@link DEFAULT_SEQUENCER_LEASE_MS} when absent (a hand-built models object). */
|
|
41
|
+
sequencerLeaseMs?: number;
|
|
24
42
|
/** The counter document's id (one feed per entries collection). */
|
|
25
43
|
feed: string;
|
|
26
44
|
}
|
|
27
|
-
declare function createChangeLogModels(connection: Connection, options?: ChangeLogModelOptions): ChangeLogModels;
|
|
45
|
+
export declare function createChangeLogModels(connection: Connection, options?: ChangeLogModelOptions): ChangeLogModels;
|
|
46
|
+
/** {@link MongoChangeLogStore.snapshot}'s options: the reader's view, plus the bound after the first page. */
|
|
47
|
+
export interface ChangesSnapshotOptions extends ChangesSinceOptions {
|
|
48
|
+
/** The `upTo` the first page returned; omit it on the first page. */
|
|
49
|
+
readonly upTo?: string;
|
|
50
|
+
}
|
|
51
|
+
/** One snapshot page. `cursor` pages the snapshot; `upTo` is where `since()` resumes once `hasMore` is false. */
|
|
52
|
+
export interface ChangesSnapshotPage extends ChangesPage {
|
|
53
|
+
readonly upTo: string;
|
|
54
|
+
}
|
|
28
55
|
/** The mongo change feed: the `ChangeLogStore` contract plus superseded-entry compaction. */
|
|
29
|
-
interface MongoChangeLogStore extends ChangeLogStore {
|
|
56
|
+
export interface MongoChangeLogStore extends ChangeLogStore {
|
|
30
57
|
/**
|
|
31
|
-
* Delete every entry
|
|
32
|
-
*
|
|
33
|
-
*
|
|
58
|
+
* Delete every entry of a `(tenantId, scope, docId)` but the one a reader ends on (the last
|
|
59
|
+
* tombstone, or the highest-version upsert after it). Safe for any client cursor: entries carry
|
|
60
|
+
* whole documents, and a reader would have skipped every deleted one. Idempotent; run it on a schedule.
|
|
34
61
|
*/
|
|
35
62
|
compactSuperseded(options?: {
|
|
36
63
|
batchSize?: number;
|
|
37
64
|
}): Promise<{
|
|
38
65
|
removed: number;
|
|
39
66
|
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Retention with a horizon (the `ChangeLogStore.prune` contract). Deletes every entry older than
|
|
69
|
+
* `before` (`at < before`) except, per `(tenantId, scope, docId)`, the one a reader ends on (as
|
|
70
|
+
* `compactSuperseded` keeps), so a snapshot still sees every document. Records a HORIZON (the highest deleted cursor, never lowered) per `(tenantId, scope)`
|
|
71
|
+
* and feed-wide, BEFORE deleting, and returns the feed-wide one, `''` while nothing was ever
|
|
72
|
+
* pruned. `since(cursor, options)` with a cursor below the horizon of what that reader can see
|
|
73
|
+
* (its tenant, shared scopes and `scopes`; the feed-wide horizon when unfiltered; `''` included)
|
|
74
|
+
* throws repo-core's `CursorExpiredError(cursor, horizon)`: that reader missed deleted
|
|
75
|
+
* intermediate entries and must resync from `latestCursor(options)`, which never answers below
|
|
76
|
+
* that horizon. Pruning one tenant never expires another tenant's cursor. Unlike
|
|
77
|
+
* `compactSuperseded`, which is safe for any cursor but silently drops intermediate entries a
|
|
78
|
+
* resuming reader has not seen, a reader never gets a silent gap here. Idempotent; schedule it
|
|
79
|
+
* (e.g. hourly with `before = now - 24h`).
|
|
80
|
+
*/
|
|
81
|
+
prune(before: Date, options?: {
|
|
82
|
+
batchSize?: number;
|
|
83
|
+
}): Promise<string>;
|
|
84
|
+
/**
|
|
85
|
+
* The resync bootstrap for a reader `since()` expired: each document's latest entry at or below
|
|
86
|
+
* `upTo` (the reader's horizon, fixed by the first page), tombstones left out, in feed order. Then
|
|
87
|
+
* `since(upTo)` carries on, delivering every change above it, deletes included. Complete because
|
|
88
|
+
* `prune` and `compactSuperseded` never delete a document's latest entry. If that `since(upTo)`
|
|
89
|
+
* expires again, a prune raised the horizon in between: bootstrap again.
|
|
90
|
+
*/
|
|
91
|
+
snapshot(cursor: string, options?: ChangesSnapshotOptions): Promise<ChangesSnapshotPage>;
|
|
92
|
+
/**
|
|
93
|
+
* The compaction horizon cursor a reader with these options is held to (`''` while nothing it
|
|
94
|
+
* can see was pruned); feed-wide without options.
|
|
95
|
+
*/
|
|
96
|
+
horizon(options?: Pick<ChangesSinceOptions, 'tenantId' | 'scopes' | 'sharedScopes'>): Promise<string>;
|
|
40
97
|
/**
|
|
41
98
|
* Number every staged entry (deferred sequencing; a no-op otherwise). Reads call it first; a scheduler may too.
|
|
42
99
|
* Returns how many it numbered, or `null` when another sequencer holds the lease.
|
|
@@ -47,21 +104,62 @@ interface MongoChangeLogStore extends ChangeLogStore {
|
|
|
47
104
|
* never use the cursor (`changeLogPlugin`). Under in-transaction sequencing it is `append`.
|
|
48
105
|
*/
|
|
49
106
|
stage(entry: Parameters<ChangeLogStore['append']>[0], options?: ChangeLogAppendOptions): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Point read of ONE document's latest recorded change: its last staged entry when one waits for a cursor
|
|
109
|
+
* (deferred sequencing; `cursor: ''`, as `append` answers inside a transaction), else its highest numbered
|
|
110
|
+
* entry; `null` when the feed holds none. Reads only (it never runs the sequencer), so it is cheap on a hot
|
|
111
|
+
* path, e.g. a writer that needs the last recorded state of a record before it appends the next change.
|
|
112
|
+
* A document is `(tenantId, scope, docId)`: `tenantId` omitted or `null` reads the untenanted document.
|
|
113
|
+
* Pass `session` to see what the caller staged or appended in its own transaction. Pruning and
|
|
114
|
+
* compaction keep the entry a reader ends on, which may not be the last one recorded.
|
|
115
|
+
*/
|
|
116
|
+
latestOf(scope: string, docId: string, options?: {
|
|
117
|
+
tenantId?: string | null;
|
|
118
|
+
session?: unknown;
|
|
119
|
+
}): Promise<ChangeEntry | null>;
|
|
120
|
+
}
|
|
121
|
+
/** What {@link ChangeLogStoreOptions.onSequenced} is told: new entries now have cursors up to `cursor`. */
|
|
122
|
+
export interface ChangeLogSequencedEvent {
|
|
123
|
+
/** The highest numbered cursor of the feed after the pass (readers reading past their cursor see the new entries). */
|
|
124
|
+
cursor: string;
|
|
125
|
+
/** How many entries were numbered since this store last looked (by this store, or by another holder). */
|
|
126
|
+
numbered: number;
|
|
127
|
+
/** `'self'`: this store's pass numbered them. `'other'`: another holder did, while a read of this store waited. */
|
|
128
|
+
by: 'self' | 'other';
|
|
129
|
+
}
|
|
130
|
+
/** Runtime options of {@link createChangeLogStore} (the models carry the storage options). */
|
|
131
|
+
export interface ChangeLogStoreOptions {
|
|
132
|
+
/**
|
|
133
|
+
* Clock for every entry's `at` (staged and in-transaction appends). Default `() => new Date()`. Inject the host's
|
|
134
|
+
* clock so `at` and `prune(before)` cutoffs agree with a driven test clock. The deferred sequencer's LEASE stays on
|
|
135
|
+
* the database clock (`$$NOW`): it is shared by every process, so it must not depend on any one process's clock.
|
|
136
|
+
*/
|
|
137
|
+
now?: () => Date;
|
|
138
|
+
/**
|
|
139
|
+
* Deferred sequencing: called after new entries got cursors, so a host's replay hub can `notify()` its tails at
|
|
140
|
+
* once. Fires when this store's pass numbered entries (`by: 'self'`), and when a read of this store found the
|
|
141
|
+
* sequencer lease held by another holder: the store then retries in the background (short backoff, unref'd
|
|
142
|
+
* timers, for at most three leases) until that holder is done, and reports what it numbered meanwhile
|
|
143
|
+
* (`by: 'other'`), or takes over a lease left by a holder that died and numbers the entries itself
|
|
144
|
+
* (`by: 'self'`). Without this hook nothing is retried in the background. A throwing hook is ignored. Never
|
|
145
|
+
* called under in-transaction sequencing (every append already has its cursor).
|
|
146
|
+
*/
|
|
147
|
+
onSequenced?: (event: ChangeLogSequencedEvent) => void;
|
|
50
148
|
}
|
|
51
|
-
declare function createChangeLogStore(models: ChangeLogModels): MongoChangeLogStore;
|
|
52
|
-
interface CommandStreamModelOptions {
|
|
149
|
+
export declare function createChangeLogStore(models: ChangeLogModels, storeOptions?: ChangeLogStoreOptions): MongoChangeLogStore;
|
|
150
|
+
export interface CommandStreamModelOptions {
|
|
53
151
|
/** Collection prefix: `<prefix>_streams`, `<prefix>_verdicts`, `<prefix>_aliases`. Default `sync`. */
|
|
54
152
|
prefix?: string;
|
|
55
153
|
/** Mongoose model name prefix. Default `SyncStream`. Must be unique per connection. */
|
|
56
154
|
modelName?: string;
|
|
57
155
|
}
|
|
58
|
-
interface CommandStreamModels {
|
|
156
|
+
export interface CommandStreamModels {
|
|
59
157
|
streams: Model<Record<string, unknown>>;
|
|
60
158
|
verdicts: Model<Record<string, unknown>>;
|
|
61
159
|
aliases: Model<Record<string, unknown>>;
|
|
62
160
|
}
|
|
63
|
-
declare function createCommandStreamModels(connection: Connection, options?: CommandStreamModelOptions): CommandStreamModels;
|
|
64
|
-
interface MongoCommandStreamTx extends CommandStreamTx {
|
|
161
|
+
export declare function createCommandStreamModels(connection: Connection, options?: CommandStreamModelOptions): CommandStreamModels;
|
|
162
|
+
export interface MongoCommandStreamTx extends CommandStreamTx {
|
|
65
163
|
readonly session: ClientSession;
|
|
66
164
|
}
|
|
67
165
|
/**
|
|
@@ -69,6 +167,4 @@ interface MongoCommandStreamTx extends CommandStreamTx {
|
|
|
69
167
|
* Concurrent transactions on one stream write-conflict on its document and `withTransaction`
|
|
70
168
|
* retries the loser, which then reads the winner's watermark.
|
|
71
169
|
*/
|
|
72
|
-
declare function createCommandStreamStore(connection: Pick<Connection, 'startSession'>, models: CommandStreamModels, changes: ChangeLogStore): CommandStreamStore<MongoCommandStreamTx>;
|
|
73
|
-
//#endregion
|
|
74
|
-
export { ChangeLogModelOptions, ChangeLogModels, CommandStreamModelOptions, CommandStreamModels, MongoChangeLogStore, MongoCommandStreamTx, createChangeLogModels, createChangeLogStore, createCommandStreamModels, createCommandStreamStore };
|
|
170
|
+
export declare function createCommandStreamStore(connection: Pick<Connection, 'startSession'>, models: CommandStreamModels, changes: ChangeLogStore): CommandStreamStore<MongoCommandStreamTx>;
|