@toa.io/storages.mongodb 1.0.0-alpha.287 → 1.0.0-alpha.289
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/CHANGELOG.md +19 -0
- package/package.json +6 -6
- package/src/client.js +6 -7
- package/src/outbox.js +2 -1
- package/src/storage.js +9 -8
- package/test/storage.test.js +9 -12
- package/src/system.js +0 -44
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.0.0-alpha.289](https://github.com/toa-io/toa/compare/v1.0.0-alpha.288...v1.0.0-alpha.289) (2026-09-07)
|
|
7
|
+
|
|
8
|
+
* A deploy moves only what changed, and a component sees none of the runtime's environment (#1073) ([f38e3db](https://github.com/toa-io/toa/commit/f38e3db533f24db866c57bfa1ef294eff1eaf499)), closes [#1073](https://github.com/toa-io/toa/issues/1073) [#1064](https://github.com/toa-io/toa/issues/1064) [#1066](https://github.com/toa-io/toa/issues/1066) [#1067](https://github.com/toa-io/toa/issues/1067) [#1068](https://github.com/toa-io/toa/issues/1068) [#1069](https://github.com/toa-io/toa/issues/1069) [#1071](https://github.com/toa-io/toa/issues/1071) [#1070](https://github.com/toa-io/toa/issues/1070) [#1072](https://github.com/toa-io/toa/issues/1072)
|
|
9
|
+
|
|
10
|
+
### BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* a component that read `process.env.TOA_*` reads `context` instead;
|
|
13
|
+
`echo(input)` no longer substitutes from the environment; a bash operation sees no
|
|
14
|
+
`TOA_*`; images no longer set `USER node` — see migrations/289.md.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [1.0.0-alpha.288](https://github.com/toa-io/toa/compare/v1.0.0-alpha.287...v1.0.0-alpha.288) (2026-09-06)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @toa.io/storages.mongodb
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# [1.0.0-alpha.287](https://github.com/toa-io/toa/compare/v1.0.0-alpha.286...v1.0.0-alpha.287) (2026-09-06)
|
|
7
26
|
|
|
8
27
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/storages.mongodb",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.289",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Toa MongoDB Storage Connector",
|
|
6
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@toa.io/conveyor": "1.0.0-alpha.
|
|
24
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
25
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
26
|
-
"@toa.io/pointer": "1.0.0-alpha.
|
|
23
|
+
"@toa.io/conveyor": "1.0.0-alpha.289",
|
|
24
|
+
"@toa.io/core": "1.0.0-alpha.289",
|
|
25
|
+
"@toa.io/generic": "1.0.0-alpha.289",
|
|
26
|
+
"@toa.io/pointer": "1.0.0-alpha.289",
|
|
27
27
|
"mongodb": "7.6.0",
|
|
28
28
|
"openspan": "1.0.0-alpha.286",
|
|
29
29
|
"saslprep": "1.0.3"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "4fcb482beac5896305d8084cdbc1d5fcf372d108"
|
|
32
32
|
}
|
package/src/client.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { console } from 'openspan'
|
|
8
|
+
import { environment } from '@toa.io/generic'
|
|
8
9
|
import { Connector } from '@toa.io/core'
|
|
9
10
|
import { resolve } from '@toa.io/pointer'
|
|
10
11
|
import { ID } from './deployment.js'
|
|
@@ -182,7 +183,7 @@ export class Client extends Connector {
|
|
|
182
183
|
async resolveURLs() {
|
|
183
184
|
// Toa's own development stack is not on the conventional ports: the applications built on
|
|
184
185
|
// Toa are, and they share the machine. See CONTRIBUTING.md.
|
|
185
|
-
if (
|
|
186
|
+
if (environment.get('TOA_DEV') === '1') {
|
|
186
187
|
return ['mongodb://developer:secret@localhost:31020']
|
|
187
188
|
} else {
|
|
188
189
|
return await resolve(ID, this.locator.id)
|
|
@@ -194,13 +195,11 @@ export class Client extends Connector {
|
|
|
194
195
|
* @return {string}
|
|
195
196
|
*/
|
|
196
197
|
resolveDB() {
|
|
197
|
-
|
|
198
|
-
return process.env.TOA_CONTEXT
|
|
199
|
-
}
|
|
198
|
+
const context = environment.get('TOA_CONTEXT')
|
|
200
199
|
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
if (context !== undefined) return context
|
|
201
|
+
|
|
202
|
+
if (environment.get('TOA_DEV') === '1') return 'toa-dev'
|
|
204
203
|
|
|
205
204
|
throw new Error('Environment variable TOA_CONTEXT is not defined')
|
|
206
205
|
}
|
package/src/outbox.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { console } from 'openspan'
|
|
2
|
+
import { environment } from '@toa.io/generic'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* The outbox rows of one component. Its lifecycle is the Client's, so it is not a Connector.
|
|
@@ -160,7 +161,7 @@ const to = ({ id, ...rest }) => ({ _id: id, ...rest })
|
|
|
160
161
|
const from = ({ _id, ...rest }) => ({ id: _id, ...rest })
|
|
161
162
|
|
|
162
163
|
function retention() {
|
|
163
|
-
const value = Number(
|
|
164
|
+
const value = Number(environment.get('TOA_OUTBOX_RETENTION'))
|
|
164
165
|
|
|
165
166
|
return Number.isNaN(value) || value < 0 ? RETENTION : value
|
|
166
167
|
}
|
package/src/storage.js
CHANGED
|
@@ -4,7 +4,6 @@ import { translate } from './translate.js'
|
|
|
4
4
|
import { codec } from './record.js'
|
|
5
5
|
import { Outbox } from './outbox.js'
|
|
6
6
|
import { Migrations } from './migrations.js'
|
|
7
|
-
import { SYSTEM } from './system.js'
|
|
8
7
|
import { ReturnDocument } from 'mongodb'
|
|
9
8
|
|
|
10
9
|
export class Storage extends Connector {
|
|
@@ -73,14 +72,16 @@ export class Storage extends Connector {
|
|
|
73
72
|
|
|
74
73
|
this.#spans.clear()
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
if (this.#entity.migrations?.length > 0) {
|
|
76
|
+
this.#migrations = new Migrations(
|
|
77
|
+
this.#client.db,
|
|
78
|
+
this.#collection,
|
|
79
|
+
this.#entity.migrations
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
await this.#migrations.run()
|
|
83
|
+
}
|
|
82
84
|
|
|
83
|
-
await this.#migrations.run()
|
|
84
85
|
await this.#outbox?.index()
|
|
85
86
|
}
|
|
86
87
|
|
package/test/storage.test.js
CHANGED
|
@@ -5,6 +5,7 @@ import { isDeepStrictEqual } from 'node:util'
|
|
|
5
5
|
import { Storage } from '../src/storage.js'
|
|
6
6
|
|
|
7
7
|
let collection
|
|
8
|
+
let db
|
|
8
9
|
let storage
|
|
9
10
|
|
|
10
11
|
beforeEach(async () => {
|
|
@@ -15,25 +16,21 @@ beforeEach(async () => {
|
|
|
15
16
|
updateMany: mock.fn(async () => ({ modifiedCount: 0 }))
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
// database its record of them lives in
|
|
20
|
-
const state = {
|
|
21
|
-
insertOne: mock.fn(async () => ({})),
|
|
22
|
-
findOne: mock.fn(async () => null),
|
|
23
|
-
updateOne: mock.fn(async () => ({ modifiedCount: 1 }))
|
|
24
|
-
}
|
|
19
|
+
db = { collection: mock.fn(() => null) }
|
|
25
20
|
|
|
26
|
-
const client = {
|
|
27
|
-
collection,
|
|
28
|
-
db: { collection: () => state },
|
|
29
|
-
link: () => null
|
|
30
|
-
}
|
|
21
|
+
const client = { collection, db, link: () => null }
|
|
31
22
|
|
|
32
23
|
storage = new Storage(client, { schema: { properties: {} } })
|
|
33
24
|
|
|
34
25
|
await storage.open()
|
|
35
26
|
})
|
|
36
27
|
|
|
28
|
+
describe('open', () => {
|
|
29
|
+
it('should not touch the migrations record where the entity declares none', () => {
|
|
30
|
+
assert.equal(db.collection.mock.callCount(), 0)
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
37
34
|
describe('get', () => {
|
|
38
35
|
it('should filter deleted', async () => {
|
|
39
36
|
await storage.get({})
|
package/src/system.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migrations the runtime owns, applied to every collection ahead of whatever the component
|
|
3
|
-
* declares.
|
|
4
|
-
*
|
|
5
|
-
* These convert what the runtime itself writes, so they are declared here rather than in a
|
|
6
|
-
* migration every component would have to write — the same reason the outbox keeps its own
|
|
7
|
-
* indexes. A component cannot write them: it does not own the system properties, and a
|
|
8
|
-
* prototype's migrations are not inherited.
|
|
9
|
-
*
|
|
10
|
-
* They are applied once for the database, recorded beside the component's own, and named so
|
|
11
|
-
* that the two can never collide.
|
|
12
|
-
*/
|
|
13
|
-
export const SYSTEM = [
|
|
14
|
-
{
|
|
15
|
-
id: 'system:0001-epoch-millis',
|
|
16
|
-
steps: [
|
|
17
|
-
{
|
|
18
|
-
/*
|
|
19
|
-
* The system timestamps became dates: what sorts, compares and expires as a moment
|
|
20
|
-
* rather than as a number that happens to be one. A record written before this holds
|
|
21
|
-
* them as milliseconds, and a collection holding both would sort every number ahead of
|
|
22
|
-
* every date — so the release that brings this stops the deployment first.
|
|
23
|
-
*
|
|
24
|
-
* `CREATED` says whether a record has been converted, because every record has one.
|
|
25
|
-
* Null passes through both conversions, which is what an undeleted record's `DELETED`
|
|
26
|
-
* is; and the widening is not decoration — MongoDB makes a date from a long and
|
|
27
|
-
* refuses one from an int, and a small enough millisecond is stored as an int.
|
|
28
|
-
*/
|
|
29
|
-
update: {
|
|
30
|
-
filter: { CREATED: { $type: 'number' } },
|
|
31
|
-
update: [
|
|
32
|
-
{
|
|
33
|
-
$set: {
|
|
34
|
-
CREATED: { $toDate: { $toLong: '$CREATED' } },
|
|
35
|
-
UPDATED: { $toDate: { $toLong: '$UPDATED' } },
|
|
36
|
-
DELETED: { $toDate: { $toLong: '$DELETED' } }
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
}
|
|
44
|
-
]
|