@nxgt/mongo-kit 0.1.4 → 0.2.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.
@@ -0,0 +1,108 @@
1
+ # Syncing
2
+
3
+ `kit.sync()` brings the server in line with the definitions the kit wires:
4
+ the collections, their `$jsonSchema` validators, their collection options and
5
+ their indexes, database by database.
6
+
7
+ ```ts
8
+ import { createKit, defineConfig } from '@nxgt/mongo-kit';
9
+ import * as collections from './models'; // every `defineCollection` of the app
10
+
11
+ await using kit = await createKit(
12
+ defineConfig({ uri: process.env.MONGO_URI!, collections }),
13
+ );
14
+
15
+ const reports = await kit.sync();
16
+ // { default: [ { name: 'posts', created: true, … }, { name: 'users', … } ] }
17
+ ```
18
+
19
+ It reports one `SyncReport[]` per database, under the name the config gave it
20
+ — `default` when it named none. Run it twice and the second run sends
21
+ nothing.
22
+
23
+ ## Options
24
+
25
+ They are `@nxgt/mongo`'s `SyncOptions`, passed through as they are.
26
+
27
+ | Option | Type | Default | Effect |
28
+ | --- | --- | --- | --- |
29
+ | `dryRun` | `boolean` | `false` | Compare and report, send nothing. An option MongoDB cannot change is reported instead of thrown, so one run lists everything that is wrong |
30
+ | `dropUnknownIndexes` | `boolean` | `false` | Drop the indexes the server has and no definition names. `_id_` is never dropped |
31
+ | `session` | `ClientSession` | — | A session for the reads. Never one in a transaction: MongoDB allows neither `collMod` nor an index build inside one |
32
+
33
+ ```ts
34
+ const reports = await kit.sync({ dryRun: true });
35
+ reports.default[0]?.created; // what it would create
36
+ reports.default[0]?.indexes.created; // the indexes it would build
37
+ ```
38
+
39
+ The first database that throws stops the rest, which is what `dryRun` is
40
+ for: it reports everything at once.
41
+
42
+ ## It is a deployment step
43
+
44
+ `collMod` needs the `dbAdmin` role, and an index build runs outside any
45
+ transaction — neither belongs in a request. A script of its own, run before
46
+ the new version serves traffic:
47
+
48
+ ```ts
49
+ // src/sync.ts — `bun run src/sync.ts [--dry-run]`
50
+ import { createKit } from '@nxgt/mongo-kit';
51
+ import { config } from './db';
52
+
53
+ await using kit = await createKit(config);
54
+
55
+ const reports = await kit.sync({ dryRun: process.argv.includes('--dry-run') });
56
+ for (const [database, collections] of Object.entries(reports)) {
57
+ for (const report of collections) {
58
+ console.log(
59
+ `${database}.${report.name}: ${report.created ? 'created' : 'in place'}, ` +
60
+ `${report.indexes.created.length} index(es) created`,
61
+ );
62
+ }
63
+ }
64
+ ```
65
+
66
+ For tests and local development, `autoSync: true` in the
67
+ [configuration](configuration.md) syncs each collection before its first
68
+ operation instead, and no script is needed.
69
+
70
+ ## Why not `syncAll`
71
+
72
+ `@nxgt/mongo`'s `syncAll` works from a global registry, which knows no
73
+ database: it cannot tell the collections of one from those of another.
74
+ `kit.sync()` syncs exactly what the kit wires, on the database each one is
75
+ wired to. For a repository that has no kit — a migration script, a one-off —
76
+ [`discoverCollections`](discover-collections.md) with `syncCollections` is
77
+ the other way round.
78
+
79
+ ## Signatures
80
+
81
+ ```ts
82
+ interface MongoKit<C> {
83
+ sync(options?: SyncOptions): Promise<Record<DbName<C>, SyncReport[]>>;
84
+ }
85
+
86
+ // both from @nxgt/mongo
87
+ interface SyncOptions {
88
+ dryRun?: boolean;
89
+ dropUnknownIndexes?: boolean;
90
+ session?: ClientSession;
91
+ }
92
+
93
+ interface SyncReport {
94
+ name: string;
95
+ created: boolean;
96
+ validator: 'unchanged' | 'created' | 'updated' | 'removed';
97
+ options: { changed: string[]; immutable: OptionMismatch[] };
98
+ indexes: { created: string[]; recreated: string[]; dropped: string[]; unchanged: string[] };
99
+ dryRun: boolean;
100
+ }
101
+ ```
102
+
103
+ ## Next
104
+
105
+ - [`discoverCollections`](discover-collections.md) — syncing from a glob,
106
+ without a kit.
107
+ - [Configuration](configuration.md) — `autoSync`, and the options a
108
+ collection is built with.
@@ -0,0 +1,68 @@
1
+ # Roadmap
2
+
3
+ Where `@nxgt/mongo-kit` is going. A direction, not a commitment: the version
4
+ an item shipped in is the only number on this page.
5
+
6
+ ## Now
7
+
8
+ - **`ping()`** — one call that says whether the databases the kit wires
9
+ answer, and how long they took, for a health endpoint that does not reach
10
+ for the driver itself.
11
+
12
+ ## Next
13
+
14
+ - **Files beside the collections** — a bucket declared in the configuration
15
+ and reached off the kit the way a collection is today, in the kit's session
16
+ and under its actor, so a file write joins a transaction with the documents
17
+ around it.
18
+
19
+ ## Later
20
+
21
+ _Nothing queued._
22
+
23
+ ## Not planned
24
+
25
+ - **A typed `discoverCollections`** — it reads the file system under Bun, has
26
+ no types and does not survive bundling. It is for scripts; an application
27
+ wires its collections in the configuration, as `import * as collections`,
28
+ where they stay typed.
29
+ - **Closing a client the configuration handed over** — the kit gives back only
30
+ the clients it opened, `await using` included. A client you opened is closed
31
+ where it was opened.
32
+ - **A transaction across two clients** — MongoDB refuses a session a client
33
+ does not own, so a transaction reaches one client's databases and `{ on }`
34
+ names which. Two databases on one URI share a client and need no `{ on }`.
35
+ - **`autoSync` as a production setting** — it is for tests and development.
36
+ In production `sync()` is a deployment step: it needs `dbAdmin`, and an
37
+ index build does not run in a transaction.
38
+ - **Wiring a collection under a name the driver's `Db` already answers to** —
39
+ refused by the types where the configuration is written, and again by
40
+ `createKit` against the object itself, so `kit.db.command(…)` is always the
41
+ driver's.
42
+
43
+ ## Shipped
44
+
45
+ - **Every refusal is a `KitError`, with a code** — `CONFIG`, `COLLISION`,
46
+ `NO_DATABASE`, `SEVERAL_DATABASES`, `TRANSACTION`, `DERIVED` or `DISCOVERY`,
47
+ beside the database and the key it is about, so a caller switches on the
48
+ code instead of matching the sentence; it extends `TypeError`, which these
49
+ were before, so a `catch` written against the old ones still catches them —
50
+ 0.2.0.
51
+ - **Documentation that travels with the package** — a guide page for the
52
+ configuration, the `db` scope, actor and transactions, and `sync()`, a
53
+ troubleshooting page whose headings are the exact error text, and this
54
+ roadmap, installed in `docs/` rather than left on GitHub — 0.1.5.
55
+ - **`@nxgt/mongo` 0.15.0** — a deduplicated file write two callers cannot
56
+ both win — 0.1.4.
57
+ - **`@nxgt/mongo` 0.14.0** — files under its `./gridfs` subpath — 0.1.3.
58
+ - **`@nxgt/mongo` 0.13.0** — `upsert` in one round trip — 0.1.2.
59
+ - **`@nxgt/mongo` 0.12.0** — strings from outside read from the schema —
60
+ 0.1.1.
61
+ - **First release** — `defineConfig` checking a configuration of one or
62
+ several databases and freezing it, and `createKit` giving a `db` that is the
63
+ driver's own with every collection typed on it, plus `as(actor)`,
64
+ `withSession`, `transaction`, `sync()` and `close()`; `discoverCollections`
65
+ for scripts — 0.1.0.
66
+
67
+ Everything released is in [`CHANGELOG.md`](https://github.com/softistx/nxgt-data/blob/develop/packages/mongo-kit/CHANGELOG.md) — it is not in
68
+ the published package, only in the repository.