@dxos/migrations 0.8.4-main.ead640a → 0.8.4-main.ef1bc66f44
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 +84 -76
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +84 -76
- 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 +3 -3
- 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 +18 -13
- package/src/migration-builder.ts +28 -27
- package/src/migrations.test.ts +24 -17
- package/src/migrations.ts +14 -6
package/README.md
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
// src/migration-builder.ts
|
|
2
2
|
import { next as A } from "@automerge/automerge";
|
|
3
3
|
import { CreateEpochRequest } from "@dxos/client/halo";
|
|
4
|
-
import {
|
|
4
|
+
import { getSchemaDXN } from "@dxos/echo/internal";
|
|
5
5
|
import { ObjectCore, migrateDocument } from "@dxos/echo-db";
|
|
6
|
-
import {
|
|
6
|
+
import { EncodedReference, SpaceDocVersion } from "@dxos/echo-protocol";
|
|
7
7
|
import { invariant } from "@dxos/invariant";
|
|
8
|
-
|
|
9
|
-
if (key in obj) {
|
|
10
|
-
Object.defineProperty(obj, key, {
|
|
11
|
-
value,
|
|
12
|
-
enumerable: true,
|
|
13
|
-
configurable: true,
|
|
14
|
-
writable: true
|
|
15
|
-
});
|
|
16
|
-
} else {
|
|
17
|
-
obj[key] = value;
|
|
18
|
-
}
|
|
19
|
-
return obj;
|
|
20
|
-
}
|
|
8
|
+
import { DXN } from "@dxos/keys";
|
|
21
9
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/migrations/src/migration-builder.ts";
|
|
22
10
|
var MigrationBuilder = class {
|
|
11
|
+
_space;
|
|
12
|
+
_repo;
|
|
13
|
+
_rootDoc;
|
|
14
|
+
// echoId -> automergeUrl
|
|
15
|
+
_newLinks = {};
|
|
16
|
+
_flushIds = [];
|
|
17
|
+
_deleteObjects = [];
|
|
18
|
+
_newRoot = void 0;
|
|
19
|
+
constructor(_space) {
|
|
20
|
+
this._space = _space;
|
|
21
|
+
this._repo = this._space.internal.db.coreDatabase._repo;
|
|
22
|
+
this._rootDoc = this._space.internal.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
23
|
+
}
|
|
23
24
|
async findObject(id) {
|
|
24
25
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString();
|
|
25
26
|
const docHandle = documentId && this._repo.find(documentId);
|
|
@@ -39,7 +40,7 @@ var MigrationBuilder = class {
|
|
|
39
40
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
40
41
|
invariant(oldHandle, void 0, {
|
|
41
42
|
F: __dxlog_file,
|
|
42
|
-
L:
|
|
43
|
+
L: 79,
|
|
43
44
|
S: this,
|
|
44
45
|
A: [
|
|
45
46
|
"oldHandle",
|
|
@@ -54,7 +55,7 @@ var MigrationBuilder = class {
|
|
|
54
55
|
objects: {
|
|
55
56
|
[id]: {
|
|
56
57
|
system: {
|
|
57
|
-
type:
|
|
58
|
+
type: EncodedReference.fromDXN(getSchemaDXN(schema))
|
|
58
59
|
},
|
|
59
60
|
data: props,
|
|
60
61
|
meta: {
|
|
@@ -65,29 +66,39 @@ var MigrationBuilder = class {
|
|
|
65
66
|
};
|
|
66
67
|
const migratedDoc = migrateDocument(oldHandle.doc(), newState);
|
|
67
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
|
+
});
|
|
68
79
|
this._newLinks[id] = newHandle.url;
|
|
69
|
-
this._addHandleToFlushList(newHandle);
|
|
80
|
+
this._addHandleToFlushList(newHandle.documentId);
|
|
70
81
|
}
|
|
71
82
|
async addObject(schema, props) {
|
|
72
|
-
const core = this._createObject({
|
|
83
|
+
const core = await this._createObject({
|
|
73
84
|
schema,
|
|
74
85
|
props
|
|
75
86
|
});
|
|
76
87
|
return core.id;
|
|
77
88
|
}
|
|
78
89
|
createReference(id) {
|
|
79
|
-
return
|
|
90
|
+
return EncodedReference.fromDXN(DXN.fromLocalObjectId(id));
|
|
80
91
|
}
|
|
81
92
|
deleteObject(id) {
|
|
82
93
|
this._deleteObjects.push(id);
|
|
83
94
|
}
|
|
84
|
-
changeProperties(changeFn) {
|
|
95
|
+
async changeProperties(changeFn) {
|
|
85
96
|
if (!this._newRoot) {
|
|
86
|
-
this._buildNewRoot();
|
|
97
|
+
await this._buildNewRoot();
|
|
87
98
|
}
|
|
88
99
|
invariant(this._newRoot, "New root not created", {
|
|
89
100
|
F: __dxlog_file,
|
|
90
|
-
L:
|
|
101
|
+
L: 123,
|
|
91
102
|
S: this,
|
|
92
103
|
A: [
|
|
93
104
|
"this._newRoot",
|
|
@@ -98,18 +109,19 @@ var MigrationBuilder = class {
|
|
|
98
109
|
const propertiesStructure = doc.objects?.[this._space.properties.id];
|
|
99
110
|
propertiesStructure && changeFn(propertiesStructure);
|
|
100
111
|
});
|
|
101
|
-
this.
|
|
112
|
+
await this._newRoot.whenReady();
|
|
113
|
+
this._addHandleToFlushList(this._newRoot.documentId);
|
|
102
114
|
}
|
|
103
115
|
/**
|
|
104
116
|
* @internal
|
|
105
117
|
*/
|
|
106
118
|
async _commit() {
|
|
107
119
|
if (!this._newRoot) {
|
|
108
|
-
this._buildNewRoot();
|
|
120
|
+
await this._buildNewRoot();
|
|
109
121
|
}
|
|
110
122
|
invariant(this._newRoot, "New root not created", {
|
|
111
123
|
F: __dxlog_file,
|
|
112
|
-
L:
|
|
124
|
+
L: 140,
|
|
113
125
|
S: this,
|
|
114
126
|
A: [
|
|
115
127
|
"this._newRoot",
|
|
@@ -117,6 +129,15 @@ var MigrationBuilder = class {
|
|
|
117
129
|
]
|
|
118
130
|
});
|
|
119
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
|
+
});
|
|
120
141
|
await this._space.internal.createEpoch({
|
|
121
142
|
migration: CreateEpochRequest.Migration.REPLACE_AUTOMERGE_ROOT,
|
|
122
143
|
automergeRootUrl: this._newRoot.url
|
|
@@ -131,7 +152,7 @@ var MigrationBuilder = class {
|
|
|
131
152
|
await docHandle.whenReady();
|
|
132
153
|
return docHandle;
|
|
133
154
|
}
|
|
134
|
-
_buildNewRoot() {
|
|
155
|
+
async _buildNewRoot() {
|
|
135
156
|
const links = {
|
|
136
157
|
...this._rootDoc.links ?? {}
|
|
137
158
|
};
|
|
@@ -149,15 +170,16 @@ var MigrationBuilder = class {
|
|
|
149
170
|
objects: this._rootDoc.objects,
|
|
150
171
|
links
|
|
151
172
|
});
|
|
152
|
-
this.
|
|
173
|
+
await this._newRoot.whenReady();
|
|
174
|
+
this._addHandleToFlushList(this._newRoot.documentId);
|
|
153
175
|
}
|
|
154
|
-
_createObject({ id, schema, props }) {
|
|
176
|
+
async _createObject({ id, schema, props }) {
|
|
155
177
|
const core = new ObjectCore();
|
|
156
178
|
if (id) {
|
|
157
179
|
core.id = id;
|
|
158
180
|
}
|
|
159
181
|
core.initNewObject(props);
|
|
160
|
-
core.setType(
|
|
182
|
+
core.setType(EncodedReference.fromDXN(getSchemaDXN(schema)));
|
|
161
183
|
const newHandle = this._repo.create({
|
|
162
184
|
version: SpaceDocVersion.CURRENT,
|
|
163
185
|
access: {
|
|
@@ -167,49 +189,29 @@ var MigrationBuilder = class {
|
|
|
167
189
|
[core.id]: core.getDoc()
|
|
168
190
|
}
|
|
169
191
|
});
|
|
192
|
+
await newHandle.whenReady();
|
|
170
193
|
this._newLinks[core.id] = newHandle.url;
|
|
171
|
-
this._addHandleToFlushList(newHandle);
|
|
194
|
+
this._addHandleToFlushList(newHandle.documentId);
|
|
172
195
|
return core;
|
|
173
196
|
}
|
|
174
|
-
_addHandleToFlushList(
|
|
175
|
-
this._flushIds.push(
|
|
176
|
-
}
|
|
177
|
-
constructor(_space) {
|
|
178
|
-
_define_property(this, "_space", void 0);
|
|
179
|
-
_define_property(this, "_repo", void 0);
|
|
180
|
-
_define_property(this, "_rootDoc", void 0);
|
|
181
|
-
_define_property(this, "_newLinks", void 0);
|
|
182
|
-
_define_property(this, "_flushIds", void 0);
|
|
183
|
-
_define_property(this, "_deleteObjects", void 0);
|
|
184
|
-
_define_property(this, "_newRoot", void 0);
|
|
185
|
-
this._space = _space;
|
|
186
|
-
this._newLinks = {};
|
|
187
|
-
this._flushIds = [];
|
|
188
|
-
this._deleteObjects = [];
|
|
189
|
-
this._newRoot = void 0;
|
|
190
|
-
this._repo = this._space.db.coreDatabase._repo;
|
|
191
|
-
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
197
|
+
_addHandleToFlushList(id) {
|
|
198
|
+
this._flushIds.push(id);
|
|
192
199
|
}
|
|
193
200
|
};
|
|
194
201
|
|
|
195
202
|
// src/migrations.ts
|
|
196
|
-
import {
|
|
203
|
+
import { Atom } from "@effect-atom/atom";
|
|
204
|
+
import * as Registry from "@effect-atom/atom/Registry";
|
|
205
|
+
import { SpaceState } from "@dxos/client/echo";
|
|
197
206
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
198
|
-
function _define_property2(obj, key, value) {
|
|
199
|
-
if (key in obj) {
|
|
200
|
-
Object.defineProperty(obj, key, {
|
|
201
|
-
value,
|
|
202
|
-
enumerable: true,
|
|
203
|
-
configurable: true,
|
|
204
|
-
writable: true
|
|
205
|
-
});
|
|
206
|
-
} else {
|
|
207
|
-
obj[key] = value;
|
|
208
|
-
}
|
|
209
|
-
return obj;
|
|
210
|
-
}
|
|
211
207
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/migrations/src/migrations.ts";
|
|
212
208
|
var Migrations = class {
|
|
209
|
+
static namespace;
|
|
210
|
+
static migrations = [];
|
|
211
|
+
static _registry = Registry.make();
|
|
212
|
+
static _stateAtom = Atom.make({
|
|
213
|
+
running: []
|
|
214
|
+
}).pipe(Atom.keepAlive);
|
|
213
215
|
static get versionProperty() {
|
|
214
216
|
return this.namespace && `${this.namespace}.version`;
|
|
215
217
|
}
|
|
@@ -217,7 +219,8 @@ var Migrations = class {
|
|
|
217
219
|
return this.migrations[this.migrations.length - 1]?.version;
|
|
218
220
|
}
|
|
219
221
|
static running(space) {
|
|
220
|
-
|
|
222
|
+
const state = this._registry.get(this._stateAtom);
|
|
223
|
+
return state.running.includes(space.key.toHex());
|
|
221
224
|
}
|
|
222
225
|
static define(namespace, migrations) {
|
|
223
226
|
this.namespace = namespace;
|
|
@@ -226,7 +229,7 @@ var Migrations = class {
|
|
|
226
229
|
static async migrate(space, targetVersion) {
|
|
227
230
|
invariant2(!this.running(space), "Migration already running", {
|
|
228
231
|
F: __dxlog_file2,
|
|
229
|
-
L:
|
|
232
|
+
L: 49,
|
|
230
233
|
S: this,
|
|
231
234
|
A: [
|
|
232
235
|
"!this.running(space)",
|
|
@@ -235,7 +238,7 @@ var Migrations = class {
|
|
|
235
238
|
});
|
|
236
239
|
invariant2(this.versionProperty, "Migrations namespace not set", {
|
|
237
240
|
F: __dxlog_file2,
|
|
238
|
-
L:
|
|
241
|
+
L: 50,
|
|
239
242
|
S: this,
|
|
240
243
|
A: [
|
|
241
244
|
"this.versionProperty",
|
|
@@ -244,7 +247,7 @@ var Migrations = class {
|
|
|
244
247
|
});
|
|
245
248
|
invariant2(space.state.get() === SpaceState.SPACE_READY, "Space not ready", {
|
|
246
249
|
F: __dxlog_file2,
|
|
247
|
-
L:
|
|
250
|
+
L: 51,
|
|
248
251
|
S: this,
|
|
249
252
|
A: [
|
|
250
253
|
"space.state.get() === SpaceState.SPACE_READY",
|
|
@@ -258,7 +261,14 @@ var Migrations = class {
|
|
|
258
261
|
if (currentIndex === targetIndex) {
|
|
259
262
|
return false;
|
|
260
263
|
}
|
|
261
|
-
|
|
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
|
+
});
|
|
262
272
|
if (targetIndex > currentIndex) {
|
|
263
273
|
const migrations = this.migrations.slice(currentIndex, targetIndex);
|
|
264
274
|
for (const migration of migrations) {
|
|
@@ -267,10 +277,10 @@ var Migrations = class {
|
|
|
267
277
|
space,
|
|
268
278
|
builder
|
|
269
279
|
});
|
|
270
|
-
builder.changeProperties((propertiesStructure) => {
|
|
280
|
+
await builder.changeProperties((propertiesStructure) => {
|
|
271
281
|
invariant2(this.versionProperty, "Migrations namespace not set", {
|
|
272
282
|
F: __dxlog_file2,
|
|
273
|
-
L:
|
|
283
|
+
L: 69,
|
|
274
284
|
S: this,
|
|
275
285
|
A: [
|
|
276
286
|
"this.versionProperty",
|
|
@@ -282,15 +292,13 @@ var Migrations = class {
|
|
|
282
292
|
await builder._commit();
|
|
283
293
|
}
|
|
284
294
|
}
|
|
285
|
-
this.
|
|
295
|
+
const finalState = this._registry.get(this._stateAtom);
|
|
296
|
+
this._registry.set(this._stateAtom, {
|
|
297
|
+
running: finalState.running.filter((key) => key !== spaceKey)
|
|
298
|
+
});
|
|
286
299
|
return true;
|
|
287
300
|
}
|
|
288
301
|
};
|
|
289
|
-
_define_property2(Migrations, "namespace", void 0);
|
|
290
|
-
_define_property2(Migrations, "migrations", []);
|
|
291
|
-
_define_property2(Migrations, "_state", live({
|
|
292
|
-
running: []
|
|
293
|
-
}));
|
|
294
302
|
export {
|
|
295
303
|
MigrationBuilder,
|
|
296
304
|
Migrations
|
|
@@ -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 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 {
|
|
5
|
-
"mappings": ";AAIA,SAASA,QAAQC,SAAmB;AAKpC,SAASC,0BAA0B;AACnC,SAASC,
|
|
6
|
-
"names": ["next", "A", "CreateEpochRequest", "
|
|
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":{"src/migration-builder.ts":{"bytes":
|
|
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}}}
|