@dxos/migrations 0.8.3 → 0.8.4-main.1068cf700f
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 +2 -2
- package/dist/lib/browser/index.mjs +88 -50
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +88 -50
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/migration-builder.d.ts +4 -4
- package/dist/types/src/migration-builder.d.ts.map +1 -1
- package/dist/types/src/migrations.d.ts +2 -1
- package/dist/types/src/migrations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -13
- package/src/migration-builder.ts +33 -32
- package/src/migrations.test.ts +25 -17
- package/src/migrations.ts +14 -6
- package/dist/lib/node/index.cjs +0 -290
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
package/README.md
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
//
|
|
2
|
-
import { next as
|
|
1
|
+
// src/migration-builder.ts
|
|
2
|
+
import { next as A } from "@automerge/automerge";
|
|
3
3
|
import { CreateEpochRequest } from "@dxos/client/halo";
|
|
4
|
+
import { getSchemaDXN } from "@dxos/echo/internal";
|
|
4
5
|
import { ObjectCore, migrateDocument } from "@dxos/echo-db";
|
|
5
|
-
import {
|
|
6
|
-
import { requireTypeReference } from "@dxos/echo-schema";
|
|
6
|
+
import { EncodedReference, SpaceDocVersion } from "@dxos/echo-protocol";
|
|
7
7
|
import { invariant } from "@dxos/invariant";
|
|
8
|
-
|
|
8
|
+
import { DXN } from "@dxos/keys";
|
|
9
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/migrations/src/migration-builder.ts";
|
|
9
10
|
var MigrationBuilder = class {
|
|
11
|
+
_space;
|
|
12
|
+
_repo;
|
|
13
|
+
_rootDoc;
|
|
14
|
+
// echoId -> automergeUrl
|
|
15
|
+
_newLinks = {};
|
|
16
|
+
_flushIds = [];
|
|
17
|
+
_deleteObjects = [];
|
|
18
|
+
_newRoot = void 0;
|
|
10
19
|
constructor(_space) {
|
|
11
20
|
this._space = _space;
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
14
|
-
this._deleteObjects = [];
|
|
15
|
-
this._newRoot = void 0;
|
|
16
|
-
this._repo = this._space.db.coreDatabase._repo;
|
|
17
|
-
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
21
|
+
this._repo = this._space.internal.db.coreDatabase._repo;
|
|
22
|
+
this._rootDoc = this._space.internal.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
18
23
|
}
|
|
19
24
|
async findObject(id) {
|
|
20
25
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString();
|
|
@@ -35,7 +40,7 @@ var MigrationBuilder = class {
|
|
|
35
40
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
36
41
|
invariant(oldHandle, void 0, {
|
|
37
42
|
F: __dxlog_file,
|
|
38
|
-
L:
|
|
43
|
+
L: 79,
|
|
39
44
|
S: this,
|
|
40
45
|
A: [
|
|
41
46
|
"oldHandle",
|
|
@@ -50,7 +55,7 @@ var MigrationBuilder = class {
|
|
|
50
55
|
objects: {
|
|
51
56
|
[id]: {
|
|
52
57
|
system: {
|
|
53
|
-
type:
|
|
58
|
+
type: EncodedReference.fromDXN(getSchemaDXN(schema))
|
|
54
59
|
},
|
|
55
60
|
data: props,
|
|
56
61
|
meta: {
|
|
@@ -60,30 +65,40 @@ var MigrationBuilder = class {
|
|
|
60
65
|
}
|
|
61
66
|
};
|
|
62
67
|
const migratedDoc = migrateDocument(oldHandle.doc(), newState);
|
|
63
|
-
const newHandle = this._repo.import(
|
|
68
|
+
const newHandle = this._repo.import(A.save(migratedDoc));
|
|
69
|
+
await newHandle.whenReady();
|
|
70
|
+
invariant(newHandle.url, "Migrated document URL not available after whenReady", {
|
|
71
|
+
F: __dxlog_file,
|
|
72
|
+
L: 101,
|
|
73
|
+
S: this,
|
|
74
|
+
A: [
|
|
75
|
+
"newHandle.url",
|
|
76
|
+
"'Migrated document URL not available after whenReady'"
|
|
77
|
+
]
|
|
78
|
+
});
|
|
64
79
|
this._newLinks[id] = newHandle.url;
|
|
65
|
-
this._addHandleToFlushList(newHandle);
|
|
80
|
+
this._addHandleToFlushList(newHandle.documentId);
|
|
66
81
|
}
|
|
67
82
|
async addObject(schema, props) {
|
|
68
|
-
const core = this._createObject({
|
|
83
|
+
const core = await this._createObject({
|
|
69
84
|
schema,
|
|
70
85
|
props
|
|
71
86
|
});
|
|
72
87
|
return core.id;
|
|
73
88
|
}
|
|
74
89
|
createReference(id) {
|
|
75
|
-
return
|
|
90
|
+
return EncodedReference.fromDXN(DXN.fromLocalObjectId(id));
|
|
76
91
|
}
|
|
77
92
|
deleteObject(id) {
|
|
78
93
|
this._deleteObjects.push(id);
|
|
79
94
|
}
|
|
80
|
-
changeProperties(changeFn) {
|
|
95
|
+
async changeProperties(changeFn) {
|
|
81
96
|
if (!this._newRoot) {
|
|
82
|
-
this._buildNewRoot();
|
|
97
|
+
await this._buildNewRoot();
|
|
83
98
|
}
|
|
84
99
|
invariant(this._newRoot, "New root not created", {
|
|
85
100
|
F: __dxlog_file,
|
|
86
|
-
L:
|
|
101
|
+
L: 123,
|
|
87
102
|
S: this,
|
|
88
103
|
A: [
|
|
89
104
|
"this._newRoot",
|
|
@@ -94,18 +109,19 @@ var MigrationBuilder = class {
|
|
|
94
109
|
const propertiesStructure = doc.objects?.[this._space.properties.id];
|
|
95
110
|
propertiesStructure && changeFn(propertiesStructure);
|
|
96
111
|
});
|
|
97
|
-
this.
|
|
112
|
+
await this._newRoot.whenReady();
|
|
113
|
+
this._addHandleToFlushList(this._newRoot.documentId);
|
|
98
114
|
}
|
|
99
115
|
/**
|
|
100
116
|
* @internal
|
|
101
117
|
*/
|
|
102
118
|
async _commit() {
|
|
103
119
|
if (!this._newRoot) {
|
|
104
|
-
this._buildNewRoot();
|
|
120
|
+
await this._buildNewRoot();
|
|
105
121
|
}
|
|
106
122
|
invariant(this._newRoot, "New root not created", {
|
|
107
123
|
F: __dxlog_file,
|
|
108
|
-
L:
|
|
124
|
+
L: 140,
|
|
109
125
|
S: this,
|
|
110
126
|
A: [
|
|
111
127
|
"this._newRoot",
|
|
@@ -113,6 +129,15 @@ var MigrationBuilder = class {
|
|
|
113
129
|
]
|
|
114
130
|
});
|
|
115
131
|
await this._space.db.flush();
|
|
132
|
+
invariant(this._newRoot.url, "New root URL not available", {
|
|
133
|
+
F: __dxlog_file,
|
|
134
|
+
L: 145,
|
|
135
|
+
S: this,
|
|
136
|
+
A: [
|
|
137
|
+
"this._newRoot.url",
|
|
138
|
+
"'New root URL not available'"
|
|
139
|
+
]
|
|
140
|
+
});
|
|
116
141
|
await this._space.internal.createEpoch({
|
|
117
142
|
migration: CreateEpochRequest.Migration.REPLACE_AUTOMERGE_ROOT,
|
|
118
143
|
automergeRootUrl: this._newRoot.url
|
|
@@ -127,7 +152,7 @@ var MigrationBuilder = class {
|
|
|
127
152
|
await docHandle.whenReady();
|
|
128
153
|
return docHandle;
|
|
129
154
|
}
|
|
130
|
-
_buildNewRoot() {
|
|
155
|
+
async _buildNewRoot() {
|
|
131
156
|
const links = {
|
|
132
157
|
...this._rootDoc.links ?? {}
|
|
133
158
|
};
|
|
@@ -135,7 +160,7 @@ var MigrationBuilder = class {
|
|
|
135
160
|
delete links[id];
|
|
136
161
|
}
|
|
137
162
|
for (const [id, url] of Object.entries(this._newLinks)) {
|
|
138
|
-
links[id] = new
|
|
163
|
+
links[id] = new A.RawString(url);
|
|
139
164
|
}
|
|
140
165
|
this._newRoot = this._repo.create({
|
|
141
166
|
version: SpaceDocVersion.CURRENT,
|
|
@@ -145,15 +170,16 @@ var MigrationBuilder = class {
|
|
|
145
170
|
objects: this._rootDoc.objects,
|
|
146
171
|
links
|
|
147
172
|
});
|
|
148
|
-
this.
|
|
173
|
+
await this._newRoot.whenReady();
|
|
174
|
+
this._addHandleToFlushList(this._newRoot.documentId);
|
|
149
175
|
}
|
|
150
|
-
_createObject({ id, schema, props }) {
|
|
176
|
+
async _createObject({ id, schema, props }) {
|
|
151
177
|
const core = new ObjectCore();
|
|
152
178
|
if (id) {
|
|
153
179
|
core.id = id;
|
|
154
180
|
}
|
|
155
181
|
core.initNewObject(props);
|
|
156
|
-
core.setType(
|
|
182
|
+
core.setType(EncodedReference.fromDXN(getSchemaDXN(schema)));
|
|
157
183
|
const newHandle = this._repo.create({
|
|
158
184
|
version: SpaceDocVersion.CURRENT,
|
|
159
185
|
access: {
|
|
@@ -163,28 +189,29 @@ var MigrationBuilder = class {
|
|
|
163
189
|
[core.id]: core.getDoc()
|
|
164
190
|
}
|
|
165
191
|
});
|
|
192
|
+
await newHandle.whenReady();
|
|
166
193
|
this._newLinks[core.id] = newHandle.url;
|
|
167
|
-
this._addHandleToFlushList(newHandle);
|
|
194
|
+
this._addHandleToFlushList(newHandle.documentId);
|
|
168
195
|
return core;
|
|
169
196
|
}
|
|
170
|
-
_addHandleToFlushList(
|
|
171
|
-
this._flushIds.push(
|
|
197
|
+
_addHandleToFlushList(id) {
|
|
198
|
+
this._flushIds.push(id);
|
|
172
199
|
}
|
|
173
200
|
};
|
|
174
201
|
|
|
175
|
-
//
|
|
176
|
-
import {
|
|
202
|
+
// src/migrations.ts
|
|
203
|
+
import { Atom } from "@effect-atom/atom";
|
|
204
|
+
import * as Registry from "@effect-atom/atom/Registry";
|
|
205
|
+
import { SpaceState } from "@dxos/client/echo";
|
|
177
206
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
178
|
-
var __dxlog_file2 = "/
|
|
207
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/migrations/src/migrations.ts";
|
|
179
208
|
var Migrations = class {
|
|
180
|
-
static
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
static {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
187
|
-
}
|
|
209
|
+
static namespace;
|
|
210
|
+
static migrations = [];
|
|
211
|
+
static _registry = Registry.make();
|
|
212
|
+
static _stateAtom = Atom.make({
|
|
213
|
+
running: []
|
|
214
|
+
}).pipe(Atom.keepAlive);
|
|
188
215
|
static get versionProperty() {
|
|
189
216
|
return this.namespace && `${this.namespace}.version`;
|
|
190
217
|
}
|
|
@@ -192,7 +219,8 @@ var Migrations = class {
|
|
|
192
219
|
return this.migrations[this.migrations.length - 1]?.version;
|
|
193
220
|
}
|
|
194
221
|
static running(space) {
|
|
195
|
-
|
|
222
|
+
const state = this._registry.get(this._stateAtom);
|
|
223
|
+
return state.running.includes(space.key.toHex());
|
|
196
224
|
}
|
|
197
225
|
static define(namespace, migrations) {
|
|
198
226
|
this.namespace = namespace;
|
|
@@ -201,7 +229,7 @@ var Migrations = class {
|
|
|
201
229
|
static async migrate(space, targetVersion) {
|
|
202
230
|
invariant2(!this.running(space), "Migration already running", {
|
|
203
231
|
F: __dxlog_file2,
|
|
204
|
-
L:
|
|
232
|
+
L: 49,
|
|
205
233
|
S: this,
|
|
206
234
|
A: [
|
|
207
235
|
"!this.running(space)",
|
|
@@ -210,7 +238,7 @@ var Migrations = class {
|
|
|
210
238
|
});
|
|
211
239
|
invariant2(this.versionProperty, "Migrations namespace not set", {
|
|
212
240
|
F: __dxlog_file2,
|
|
213
|
-
L:
|
|
241
|
+
L: 50,
|
|
214
242
|
S: this,
|
|
215
243
|
A: [
|
|
216
244
|
"this.versionProperty",
|
|
@@ -219,7 +247,7 @@ var Migrations = class {
|
|
|
219
247
|
});
|
|
220
248
|
invariant2(space.state.get() === SpaceState.SPACE_READY, "Space not ready", {
|
|
221
249
|
F: __dxlog_file2,
|
|
222
|
-
L:
|
|
250
|
+
L: 51,
|
|
223
251
|
S: this,
|
|
224
252
|
A: [
|
|
225
253
|
"space.state.get() === SpaceState.SPACE_READY",
|
|
@@ -233,7 +261,14 @@ var Migrations = class {
|
|
|
233
261
|
if (currentIndex === targetIndex) {
|
|
234
262
|
return false;
|
|
235
263
|
}
|
|
236
|
-
|
|
264
|
+
const spaceKey = space.key.toHex();
|
|
265
|
+
const currentState = this._registry.get(this._stateAtom);
|
|
266
|
+
this._registry.set(this._stateAtom, {
|
|
267
|
+
running: [
|
|
268
|
+
...currentState.running,
|
|
269
|
+
spaceKey
|
|
270
|
+
]
|
|
271
|
+
});
|
|
237
272
|
if (targetIndex > currentIndex) {
|
|
238
273
|
const migrations = this.migrations.slice(currentIndex, targetIndex);
|
|
239
274
|
for (const migration of migrations) {
|
|
@@ -242,10 +277,10 @@ var Migrations = class {
|
|
|
242
277
|
space,
|
|
243
278
|
builder
|
|
244
279
|
});
|
|
245
|
-
builder.changeProperties((propertiesStructure) => {
|
|
280
|
+
await builder.changeProperties((propertiesStructure) => {
|
|
246
281
|
invariant2(this.versionProperty, "Migrations namespace not set", {
|
|
247
282
|
F: __dxlog_file2,
|
|
248
|
-
L:
|
|
283
|
+
L: 69,
|
|
249
284
|
S: this,
|
|
250
285
|
A: [
|
|
251
286
|
"this.versionProperty",
|
|
@@ -257,7 +292,10 @@ var Migrations = class {
|
|
|
257
292
|
await builder._commit();
|
|
258
293
|
}
|
|
259
294
|
}
|
|
260
|
-
this.
|
|
295
|
+
const finalState = this._registry.get(this._stateAtom);
|
|
296
|
+
this._registry.set(this._stateAtom, {
|
|
297
|
+
running: finalState.running.filter((key) => key !== spaceKey)
|
|
298
|
+
});
|
|
261
299
|
return true;
|
|
262
300
|
}
|
|
263
301
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/migration-builder.ts", "../../../src/migrations.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { next as
|
|
5
|
-
"mappings": ";AAIA,SAASA,QAAQC,
|
|
6
|
-
"names": ["next", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { next as A, type Doc } from '@automerge/automerge';\nimport { type AnyDocumentId, type DocumentId } from '@automerge/automerge-repo';\nimport type * as Schema from 'effect/Schema';\n\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { getSchemaDXN } from '@dxos/echo/internal';\nimport { type DocHandleProxy, ObjectCore, type RepoProxy, migrateDocument } from '@dxos/echo-db';\nimport { type DatabaseDirectory, EncodedReference, type ObjectStructure, SpaceDocVersion } from '@dxos/echo-protocol';\nimport { invariant } from '@dxos/invariant';\nimport { DXN } from '@dxos/keys';\nimport { type MaybePromise } from '@dxos/util';\n\n/*\n\nConsidering a better API for this:\n\n```ts\nconst migration = space.db.beginMigration(); // all actions are not visible to queries and are only applied once you call `apply`\n\nmigration.applyObjectMigration(defineMigration(From, To, { ... }));\n\nmigration.delete(id);\nmigration.add(obj);\n\nawait migration.apply(); // Will create new epoch.\n```\n\n*/\n\n// TODO(dmaretskyi): We no longer need to hook into ECHO internals, with the changes to echo APIs.\nexport class MigrationBuilder {\n private readonly _repo: RepoProxy;\n private readonly _rootDoc: Doc<DatabaseDirectory>;\n\n // echoId -> automergeUrl\n private readonly _newLinks: Record<string, string> = {};\n private readonly _flushIds: DocumentId[] = [];\n private readonly _deleteObjects: string[] = [];\n\n private _newRoot?: DocHandleProxy<DatabaseDirectory> = undefined;\n\n constructor(private readonly _space: Space) {\n this._repo = this._space.internal.db.coreDatabase._repo;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.internal.db.coreDatabase as any)._automergeDocLoader\n .getSpaceRootDocHandle()\n .doc() as Doc<DatabaseDirectory>;\n }\n\n async findObject(id: string): Promise<ObjectStructure | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString() as AnyDocumentId | undefined;\n const docHandle = documentId && this._repo.find(documentId);\n if (!docHandle) {\n return undefined;\n }\n\n await docHandle.whenReady();\n const doc = docHandle.doc() as Doc<DatabaseDirectory>;\n return doc.objects?.[id];\n }\n\n async migrateObject(\n id: string,\n migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema: Schema.Schema.AnyNoContext; props: any }>,\n ): Promise<void> {\n const objectStructure = await this.findObject(id);\n if (!objectStructure) {\n return;\n }\n\n const { schema, props } = await migrate(objectStructure);\n\n const oldHandle = await this._findObjectContainingHandle(id);\n invariant(oldHandle);\n\n const newState: DatabaseDirectory = {\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [id]: {\n system: {\n type: EncodedReference.fromDXN(getSchemaDXN(schema)!),\n },\n data: props,\n meta: {\n keys: [],\n },\n },\n },\n };\n const migratedDoc = migrateDocument(oldHandle.doc() as Doc<DatabaseDirectory>, newState);\n const newHandle = this._repo.import<DatabaseDirectory>(A.save(migratedDoc));\n await newHandle.whenReady();\n invariant(newHandle.url, 'Migrated document URL not available after whenReady');\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle.documentId!);\n }\n\n async addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string> {\n const core = await this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return EncodedReference.fromDXN(DXN.fromLocalObjectId(id));\n }\n\n deleteObject(id: string): void {\n this._deleteObjects.push(id);\n }\n\n async changeProperties(changeFn: (properties: ObjectStructure) => void): Promise<void> {\n if (!this._newRoot) {\n await this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n this._newRoot.change((doc: DatabaseDirectory) => {\n const propertiesStructure = doc.objects?.[this._space.properties.id];\n propertiesStructure && changeFn(propertiesStructure);\n });\n await this._newRoot.whenReady();\n this._addHandleToFlushList(this._newRoot.documentId!);\n }\n\n /**\n * @internal\n */\n async _commit(): Promise<void> {\n if (!this._newRoot) {\n await this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._space.db.flush();\n\n // Create new epoch.\n invariant(this._newRoot.url, 'New root URL not available');\n await this._space.internal.createEpoch({\n migration: CreateEpochRequest.Migration.REPLACE_AUTOMERGE_ROOT,\n automergeRootUrl: this._newRoot.url,\n });\n }\n\n private async _findObjectContainingHandle(id: string): Promise<DocHandleProxy<DatabaseDirectory> | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString() as AnyDocumentId | undefined;\n const docHandle = documentId && this._repo.find(documentId);\n if (!docHandle) {\n return undefined;\n }\n\n await docHandle.whenReady();\n return docHandle;\n }\n\n private async _buildNewRoot(): Promise<void> {\n const links = { ...(this._rootDoc.links ?? {}) };\n for (const id of this._deleteObjects) {\n delete links[id];\n }\n\n for (const [id, url] of Object.entries(this._newLinks)) {\n links[id] = new A.RawString(url);\n }\n\n this._newRoot = this._repo.create<DatabaseDirectory>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: this._rootDoc.objects,\n links,\n });\n await this._newRoot.whenReady();\n this._addHandleToFlushList(this._newRoot.documentId!);\n }\n\n private async _createObject({\n id,\n schema,\n props,\n }: {\n id?: string;\n schema: Schema.Schema.AnyNoContext;\n props: any;\n }): Promise<ObjectCore> {\n const core = new ObjectCore();\n if (id) {\n core.id = id;\n }\n\n core.initNewObject(props);\n core.setType(EncodedReference.fromDXN(getSchemaDXN(schema)!));\n const newHandle = this._repo.create<DatabaseDirectory>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [core.id]: core.getDoc() as ObjectStructure,\n },\n });\n await newHandle.whenReady();\n this._newLinks[core.id] = newHandle.url!;\n this._addHandleToFlushList(newHandle.documentId!);\n\n return core;\n }\n\n private _addHandleToFlushList(id: DocumentId): void {\n this._flushIds.push(id);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { Atom } from '@effect-atom/atom';\nimport * as Registry from '@effect-atom/atom/Registry';\n\nimport { type Space, SpaceState } from '@dxos/client/echo';\nimport { invariant } from '@dxos/invariant';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { MigrationBuilder } from './migration-builder';\n\nexport type MigrationContext = {\n space: Space;\n builder: MigrationBuilder;\n};\n\nexport type Migration = {\n version: string;\n next: (context: MigrationContext) => MaybePromise<void>;\n};\n\nexport class Migrations {\n static namespace?: string;\n static migrations: Migration[] = [];\n private static _registry = Registry.make();\n private static _stateAtom = Atom.make<{ running: string[] }>({ running: [] }).pipe(Atom.keepAlive);\n\n static get versionProperty() {\n return this.namespace && `${this.namespace}.version`;\n }\n\n static get targetVersion() {\n return this.migrations[this.migrations.length - 1]?.version;\n }\n\n static running(space: Space): boolean {\n const state = this._registry.get(this._stateAtom);\n return state.running.includes(space.key.toHex());\n }\n\n static define(namespace: string, migrations: Migration[]): void {\n this.namespace = namespace;\n this.migrations = migrations;\n }\n\n static async migrate(space: Space, targetVersion?: string | number): Promise<boolean> {\n invariant(!this.running(space), 'Migration already running');\n invariant(this.versionProperty, 'Migrations namespace not set');\n invariant(space.state.get() === SpaceState.SPACE_READY, 'Space not ready');\n const currentVersion = space.properties[this.versionProperty];\n const currentIndex = this.migrations.findIndex((m) => m.version === currentVersion) + 1;\n const i = this.migrations.findIndex((m) => m.version === targetVersion);\n const targetIndex = i === -1 ? this.migrations.length : i + 1;\n if (currentIndex === targetIndex) {\n return false;\n }\n\n const spaceKey = space.key.toHex();\n const currentState = this._registry.get(this._stateAtom);\n this._registry.set(this._stateAtom, { running: [...currentState.running, spaceKey] });\n if (targetIndex > currentIndex) {\n const migrations = this.migrations.slice(currentIndex, targetIndex);\n for (const migration of migrations) {\n const builder = new MigrationBuilder(space);\n await migration.next({ space, builder });\n await builder.changeProperties((propertiesStructure) => {\n invariant(this.versionProperty, 'Migrations namespace not set');\n propertiesStructure.data[this.versionProperty] = migration.version;\n });\n await builder._commit();\n }\n }\n const finalState = this._registry.get(this._stateAtom);\n this._registry.set(this._stateAtom, { running: finalState.running.filter((key) => key !== spaceKey) });\n\n return true;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["next", "A", "CreateEpochRequest", "getSchemaDXN", "ObjectCore", "migrateDocument", "EncodedReference", "SpaceDocVersion", "invariant", "DXN", "MigrationBuilder", "_repo", "_rootDoc", "_newLinks", "_flushIds", "_deleteObjects", "_newRoot", "undefined", "_space", "internal", "db", "coreDatabase", "_automergeDocLoader", "getSpaceRootDocHandle", "doc", "findObject", "id", "documentId", "links", "toString", "docHandle", "find", "whenReady", "objects", "migrateObject", "migrate", "objectStructure", "schema", "props", "oldHandle", "_findObjectContainingHandle", "newState", "version", "CURRENT", "access", "spaceKey", "key", "toHex", "system", "type", "fromDXN", "data", "meta", "keys", "migratedDoc", "newHandle", "import", "save", "url", "_addHandleToFlushList", "addObject", "core", "_createObject", "createReference", "fromLocalObjectId", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "createEpoch", "migration", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "Object", "entries", "RawString", "create", "initNewObject", "setType", "getDoc", "Atom", "Registry", "SpaceState", "invariant", "Migrations", "namespace", "migrations", "_registry", "make", "_stateAtom", "Atom", "running", "pipe", "keepAlive", "versionProperty", "targetVersion", "length", "version", "space", "state", "get", "includes", "key", "toHex", "define", "migrate", "invariant", "SpaceState", "SPACE_READY", "currentVersion", "properties", "currentIndex", "findIndex", "m", "i", "targetIndex", "spaceKey", "currentState", "set", "slice", "migration", "builder", "MigrationBuilder", "next", "changeProperties", "propertiesStructure", "data", "_commit", "finalState", "filter"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"
|
|
1
|
+
{"inputs":{"src/migration-builder.ts":{"bytes":23919,"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","kind":"import-statement","external":true},{"path":"@dxos/echo/internal","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/echo-protocol","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true}],"format":"esm"},"src/migrations.ts":{"bytes":11487,"imports":[{"path":"@effect-atom/atom","kind":"import-statement","external":true},{"path":"@effect-atom/atom/Registry","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"}],"format":"esm"},"src/index.ts":{"bytes":653,"imports":[{"path":"src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"},{"path":"src/migrations.ts","kind":"import-statement","original":"./migrations"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17169},"dist/lib/browser/index.mjs":{"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","kind":"import-statement","external":true},{"path":"@dxos/echo/internal","kind":"import-statement","external":true},{"path":"@dxos/echo-db","kind":"import-statement","external":true},{"path":"@dxos/echo-protocol","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/keys","kind":"import-statement","external":true},{"path":"@effect-atom/atom","kind":"import-statement","external":true},{"path":"@effect-atom/atom/Registry","kind":"import-statement","external":true},{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"exports":["MigrationBuilder","Migrations"],"entryPoint":"src/index.ts","inputs":{"src/migration-builder.ts":{"bytesInOutput":5571},"src/index.ts":{"bytesInOutput":0},"src/migrations.ts":{"bytesInOutput":3215}},"bytes":8916}}}
|