@dxos/migrations 0.8.2-staging.7ac8446 → 0.8.3-main.672df60
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/dist/lib/browser/index.mjs +11 -11
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +9 -9
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +11 -11
- 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.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -10
- package/src/migration-builder.ts +59 -25
- package/src/migrations.test.ts +10 -8
- package/src/migrations.ts +6 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// packages/sdk/migrations/src/migration-builder.ts
|
|
2
|
-
import { next as am } from "@
|
|
2
|
+
import { next as am } from "@automerge/automerge";
|
|
3
3
|
import { CreateEpochRequest } from "@dxos/client/halo";
|
|
4
4
|
import { ObjectCore, migrateDocument } from "@dxos/echo-db";
|
|
5
|
-
import { SpaceDocVersion, encodeReference
|
|
5
|
+
import { Reference, SpaceDocVersion, encodeReference } from "@dxos/echo-protocol";
|
|
6
6
|
import { requireTypeReference } from "@dxos/echo-schema";
|
|
7
7
|
import { invariant } from "@dxos/invariant";
|
|
8
8
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migration-builder.ts";
|
|
@@ -14,7 +14,7 @@ var MigrationBuilder = class {
|
|
|
14
14
|
this._deleteObjects = [];
|
|
15
15
|
this._newRoot = void 0;
|
|
16
16
|
this._repo = this._space.db.coreDatabase._repo;
|
|
17
|
-
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().
|
|
17
|
+
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
18
18
|
}
|
|
19
19
|
async findObject(id) {
|
|
20
20
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString();
|
|
@@ -23,7 +23,7 @@ var MigrationBuilder = class {
|
|
|
23
23
|
return void 0;
|
|
24
24
|
}
|
|
25
25
|
await docHandle.whenReady();
|
|
26
|
-
const doc = docHandle.
|
|
26
|
+
const doc = docHandle.doc();
|
|
27
27
|
return doc.objects?.[id];
|
|
28
28
|
}
|
|
29
29
|
async migrateObject(id, migrate) {
|
|
@@ -35,7 +35,7 @@ var MigrationBuilder = class {
|
|
|
35
35
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
36
36
|
invariant(oldHandle, void 0, {
|
|
37
37
|
F: __dxlog_file,
|
|
38
|
-
L:
|
|
38
|
+
L: 84,
|
|
39
39
|
S: this,
|
|
40
40
|
A: [
|
|
41
41
|
"oldHandle",
|
|
@@ -59,7 +59,7 @@ var MigrationBuilder = class {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
const migratedDoc = migrateDocument(oldHandle.
|
|
62
|
+
const migratedDoc = migrateDocument(oldHandle.doc(), newState);
|
|
63
63
|
const newHandle = this._repo.import(am.save(migratedDoc));
|
|
64
64
|
this._newLinks[id] = newHandle.url;
|
|
65
65
|
this._addHandleToFlushList(newHandle);
|
|
@@ -83,7 +83,7 @@ var MigrationBuilder = class {
|
|
|
83
83
|
}
|
|
84
84
|
invariant(this._newRoot, "New root not created", {
|
|
85
85
|
F: __dxlog_file,
|
|
86
|
-
L:
|
|
86
|
+
L: 126,
|
|
87
87
|
S: this,
|
|
88
88
|
A: [
|
|
89
89
|
"this._newRoot",
|
|
@@ -105,7 +105,7 @@ var MigrationBuilder = class {
|
|
|
105
105
|
}
|
|
106
106
|
invariant(this._newRoot, "New root not created", {
|
|
107
107
|
F: __dxlog_file,
|
|
108
|
-
L:
|
|
108
|
+
L: 142,
|
|
109
109
|
S: this,
|
|
110
110
|
A: [
|
|
111
111
|
"this._newRoot",
|
|
@@ -173,7 +173,7 @@ var MigrationBuilder = class {
|
|
|
173
173
|
};
|
|
174
174
|
|
|
175
175
|
// packages/sdk/migrations/src/migrations.ts
|
|
176
|
-
import {
|
|
176
|
+
import { live, SpaceState } from "@dxos/client/echo";
|
|
177
177
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
178
178
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migrations.ts";
|
|
179
179
|
var Migrations = class {
|
|
@@ -181,7 +181,7 @@ var Migrations = class {
|
|
|
181
181
|
this.migrations = [];
|
|
182
182
|
}
|
|
183
183
|
static {
|
|
184
|
-
this._state =
|
|
184
|
+
this._state = live({
|
|
185
185
|
running: []
|
|
186
186
|
});
|
|
187
187
|
}
|
|
@@ -189,7 +189,7 @@ var Migrations = class {
|
|
|
189
189
|
return this.namespace && `${this.namespace}.version`;
|
|
190
190
|
}
|
|
191
191
|
static get targetVersion() {
|
|
192
|
-
return this.migrations[this.migrations.length - 1]
|
|
192
|
+
return this.migrations[this.migrations.length - 1]?.version;
|
|
193
193
|
}
|
|
194
194
|
static running(space) {
|
|
195
195
|
return this._state.running.includes(space.key.toHex());
|
|
@@ -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 {
|
|
5
|
-
"mappings": ";AAIA,
|
|
6
|
-
"names": ["next", "am", "CreateEpochRequest", "ObjectCore", "migrateDocument", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { next as am, type Doc } from '@automerge/automerge';\nimport { type AnyDocumentId, type DocumentId } from '@automerge/automerge-repo';\nimport { type Schema } from 'effect';\n\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { ObjectCore, migrateDocument, type DocHandleProxy, type RepoProxy } from '@dxos/echo-db';\nimport {\n Reference,\n SpaceDocVersion,\n encodeReference,\n type DatabaseDirectory,\n type ObjectStructure,\n} from '@dxos/echo-protocol';\nimport { requireTypeReference } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\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.db.coreDatabase._repo;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.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: encodeReference(requireTypeReference(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>(am.save(migratedDoc));\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n }\n\n async addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string> {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return encodeReference(Reference.localObjectReference(id));\n }\n\n deleteObject(id: string): void {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void): void {\n if (!this._newRoot) {\n 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 this._addHandleToFlushList(this._newRoot);\n }\n\n /**\n * @internal\n */\n async _commit(): Promise<void> {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._space.db.flush();\n\n // Create new epoch.\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 _buildNewRoot(): 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 am.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 this._addHandleToFlushList(this._newRoot);\n }\n\n private _createObject({\n id,\n schema,\n props,\n }: {\n id?: string;\n schema: Schema.Schema.AnyNoContext;\n props: any;\n }): ObjectCore {\n const core = new ObjectCore();\n if (id) {\n core.id = id;\n }\n\n core.initNewObject(props);\n core.setType(requireTypeReference(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 this._newLinks[core.id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n\n return core;\n }\n\n private _addHandleToFlushList(handle: DocHandleProxy<any>): void {\n this._flushIds.push(handle.documentId);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, live, 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 _state = live<{ running: string[] }>({ running: [] });\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 return this._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 this._state.running.push(space.key.toHex());\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 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 this._state.running.splice(this._state.running.indexOf(space.key.toHex()), 1);\n\n return true;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["next", "am", "CreateEpochRequest", "ObjectCore", "migrateDocument", "Reference", "SpaceDocVersion", "encodeReference", "requireTypeReference", "invariant", "MigrationBuilder", "_space", "_newLinks", "_flushIds", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "_rootDoc", "_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", "data", "meta", "keys", "migratedDoc", "newHandle", "import", "save", "url", "_addHandleToFlushList", "addObject", "core", "_createObject", "createReference", "localObjectReference", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "internal", "createEpoch", "migration", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "Object", "entries", "RawString", "create", "initNewObject", "setType", "getDoc", "handle", "live", "SpaceState", "invariant", "Migrations", "migrations", "_state", "live", "running", "versionProperty", "namespace", "targetVersion", "length", "version", "space", "includes", "key", "toHex", "define", "migrate", "invariant", "state", "get", "SpaceState", "SPACE_READY", "currentVersion", "properties", "currentIndex", "findIndex", "m", "i", "targetIndex", "push", "slice", "migration", "builder", "MigrationBuilder", "next", "changeProperties", "propertiesStructure", "data", "_commit", "splice", "indexOf"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":22181,"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","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/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/migrations/src/migrations.ts":{"bytes":9722,"imports":[{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"}],"format":"esm"},"packages/sdk/migrations/src/index.ts":{"bytes":666,"imports":[{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"},{"path":"packages/sdk/migrations/src/migrations.ts","kind":"import-statement","original":"./migrations"}],"format":"esm"}},"outputs":{"packages/sdk/migrations/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15579},"packages/sdk/migrations/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-db","kind":"import-statement","external":true},{"path":"@dxos/echo-protocol","kind":"import-statement","external":true},{"path":"@dxos/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","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":"packages/sdk/migrations/src/index.ts","inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytesInOutput":4834},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2754}},"bytes":7766}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -22,7 +22,7 @@ __export(node_exports, {
|
|
|
22
22
|
Migrations: () => Migrations
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(node_exports);
|
|
25
|
-
var import_automerge = require("@
|
|
25
|
+
var import_automerge = require("@automerge/automerge");
|
|
26
26
|
var import_halo = require("@dxos/client/halo");
|
|
27
27
|
var import_echo_db = require("@dxos/echo-db");
|
|
28
28
|
var import_echo_protocol = require("@dxos/echo-protocol");
|
|
@@ -39,7 +39,7 @@ var MigrationBuilder = class {
|
|
|
39
39
|
this._deleteObjects = [];
|
|
40
40
|
this._newRoot = void 0;
|
|
41
41
|
this._repo = this._space.db.coreDatabase._repo;
|
|
42
|
-
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().
|
|
42
|
+
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
43
43
|
}
|
|
44
44
|
async findObject(id) {
|
|
45
45
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString();
|
|
@@ -48,7 +48,7 @@ var MigrationBuilder = class {
|
|
|
48
48
|
return void 0;
|
|
49
49
|
}
|
|
50
50
|
await docHandle.whenReady();
|
|
51
|
-
const doc = docHandle.
|
|
51
|
+
const doc = docHandle.doc();
|
|
52
52
|
return doc.objects?.[id];
|
|
53
53
|
}
|
|
54
54
|
async migrateObject(id, migrate) {
|
|
@@ -60,7 +60,7 @@ var MigrationBuilder = class {
|
|
|
60
60
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
61
61
|
(0, import_invariant.invariant)(oldHandle, void 0, {
|
|
62
62
|
F: __dxlog_file,
|
|
63
|
-
L:
|
|
63
|
+
L: 84,
|
|
64
64
|
S: this,
|
|
65
65
|
A: [
|
|
66
66
|
"oldHandle",
|
|
@@ -84,7 +84,7 @@ var MigrationBuilder = class {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
|
-
const migratedDoc = (0, import_echo_db.migrateDocument)(oldHandle.
|
|
87
|
+
const migratedDoc = (0, import_echo_db.migrateDocument)(oldHandle.doc(), newState);
|
|
88
88
|
const newHandle = this._repo.import(import_automerge.next.save(migratedDoc));
|
|
89
89
|
this._newLinks[id] = newHandle.url;
|
|
90
90
|
this._addHandleToFlushList(newHandle);
|
|
@@ -108,7 +108,7 @@ var MigrationBuilder = class {
|
|
|
108
108
|
}
|
|
109
109
|
(0, import_invariant.invariant)(this._newRoot, "New root not created", {
|
|
110
110
|
F: __dxlog_file,
|
|
111
|
-
L:
|
|
111
|
+
L: 126,
|
|
112
112
|
S: this,
|
|
113
113
|
A: [
|
|
114
114
|
"this._newRoot",
|
|
@@ -130,7 +130,7 @@ var MigrationBuilder = class {
|
|
|
130
130
|
}
|
|
131
131
|
(0, import_invariant.invariant)(this._newRoot, "New root not created", {
|
|
132
132
|
F: __dxlog_file,
|
|
133
|
-
L:
|
|
133
|
+
L: 142,
|
|
134
134
|
S: this,
|
|
135
135
|
A: [
|
|
136
136
|
"this._newRoot",
|
|
@@ -202,7 +202,7 @@ var Migrations = class {
|
|
|
202
202
|
this.migrations = [];
|
|
203
203
|
}
|
|
204
204
|
static {
|
|
205
|
-
this._state = (0, import_echo.
|
|
205
|
+
this._state = (0, import_echo.live)({
|
|
206
206
|
running: []
|
|
207
207
|
});
|
|
208
208
|
}
|
|
@@ -210,7 +210,7 @@ var Migrations = class {
|
|
|
210
210
|
return this.namespace && `${this.namespace}.version`;
|
|
211
211
|
}
|
|
212
212
|
static get targetVersion() {
|
|
213
|
-
return this.migrations[this.migrations.length - 1]
|
|
213
|
+
return this.migrations[this.migrations.length - 1]?.version;
|
|
214
214
|
}
|
|
215
215
|
static running(space) {
|
|
216
216
|
return this._state.running.includes(space.key.toHex());
|
|
@@ -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 {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAIA,uBAAqC;
|
|
6
|
-
"names": ["import_invariant", "MigrationBuilder", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { next as am, type Doc } from '@automerge/automerge';\nimport { type AnyDocumentId, type DocumentId } from '@automerge/automerge-repo';\nimport { type Schema } from 'effect';\n\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { ObjectCore, migrateDocument, type DocHandleProxy, type RepoProxy } from '@dxos/echo-db';\nimport {\n Reference,\n SpaceDocVersion,\n encodeReference,\n type DatabaseDirectory,\n type ObjectStructure,\n} from '@dxos/echo-protocol';\nimport { requireTypeReference } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\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.db.coreDatabase._repo;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.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: encodeReference(requireTypeReference(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>(am.save(migratedDoc));\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n }\n\n async addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string> {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return encodeReference(Reference.localObjectReference(id));\n }\n\n deleteObject(id: string): void {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void): void {\n if (!this._newRoot) {\n 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 this._addHandleToFlushList(this._newRoot);\n }\n\n /**\n * @internal\n */\n async _commit(): Promise<void> {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._space.db.flush();\n\n // Create new epoch.\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 _buildNewRoot(): 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 am.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 this._addHandleToFlushList(this._newRoot);\n }\n\n private _createObject({\n id,\n schema,\n props,\n }: {\n id?: string;\n schema: Schema.Schema.AnyNoContext;\n props: any;\n }): ObjectCore {\n const core = new ObjectCore();\n if (id) {\n core.id = id;\n }\n\n core.initNewObject(props);\n core.setType(requireTypeReference(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 this._newLinks[core.id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n\n return core;\n }\n\n private _addHandleToFlushList(handle: DocHandleProxy<any>): void {\n this._flushIds.push(handle.documentId);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, live, 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 _state = live<{ running: string[] }>({ running: [] });\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 return this._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 this._state.running.push(space.key.toHex());\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 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 this._state.running.splice(this._state.running.indexOf(space.key.toHex()), 1);\n\n return true;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_invariant", "MigrationBuilder", "_space", "_newLinks", "_flushIds", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "_rootDoc", "_automergeDocLoader", "getSpaceRootDocHandle", "doc", "findObject", "id", "documentId", "links", "toString", "docHandle", "find", "whenReady", "objects", "migrateObject", "migrate", "objectStructure", "schema", "props", "oldHandle", "_findObjectContainingHandle", "invariant", "newState", "version", "SpaceDocVersion", "CURRENT", "access", "spaceKey", "key", "toHex", "system", "type", "encodeReference", "requireTypeReference", "data", "meta", "keys", "migratedDoc", "migrateDocument", "newHandle", "import", "am", "save", "url", "_addHandleToFlushList", "addObject", "core", "_createObject", "createReference", "Reference", "localObjectReference", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "internal", "createEpoch", "migration", "CreateEpochRequest", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "Object", "entries", "RawString", "create", "ObjectCore", "initNewObject", "setType", "getDoc", "handle", "Migrations", "migrations", "_state", "live", "running", "versionProperty", "namespace", "targetVersion", "length", "space", "includes", "define", "state", "get", "SpaceState", "SPACE_READY", "currentVersion", "currentIndex", "findIndex", "m", "i", "targetIndex", "slice", "builder", "next", "splice", "indexOf"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":22181,"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","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/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/migrations/src/migrations.ts":{"bytes":9722,"imports":[{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"}],"format":"esm"},"packages/sdk/migrations/src/index.ts":{"bytes":666,"imports":[{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"},{"path":"packages/sdk/migrations/src/migrations.ts","kind":"import-statement","original":"./migrations"}],"format":"esm"}},"outputs":{"packages/sdk/migrations/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15579},"packages/sdk/migrations/dist/lib/node/index.cjs":{"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","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/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","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":"packages/sdk/migrations/src/index.ts","inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytesInOutput":4834},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2754}},"bytes":7766}}}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
3
|
// packages/sdk/migrations/src/migration-builder.ts
|
|
4
|
-
import { next as am } from "@
|
|
4
|
+
import { next as am } from "@automerge/automerge";
|
|
5
5
|
import { CreateEpochRequest } from "@dxos/client/halo";
|
|
6
6
|
import { ObjectCore, migrateDocument } from "@dxos/echo-db";
|
|
7
|
-
import { SpaceDocVersion, encodeReference
|
|
7
|
+
import { Reference, SpaceDocVersion, encodeReference } from "@dxos/echo-protocol";
|
|
8
8
|
import { requireTypeReference } from "@dxos/echo-schema";
|
|
9
9
|
import { invariant } from "@dxos/invariant";
|
|
10
10
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migration-builder.ts";
|
|
@@ -16,7 +16,7 @@ var MigrationBuilder = class {
|
|
|
16
16
|
this._deleteObjects = [];
|
|
17
17
|
this._newRoot = void 0;
|
|
18
18
|
this._repo = this._space.db.coreDatabase._repo;
|
|
19
|
-
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().
|
|
19
|
+
this._rootDoc = this._space.db.coreDatabase._automergeDocLoader.getSpaceRootDocHandle().doc();
|
|
20
20
|
}
|
|
21
21
|
async findObject(id) {
|
|
22
22
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString();
|
|
@@ -25,7 +25,7 @@ var MigrationBuilder = class {
|
|
|
25
25
|
return void 0;
|
|
26
26
|
}
|
|
27
27
|
await docHandle.whenReady();
|
|
28
|
-
const doc = docHandle.
|
|
28
|
+
const doc = docHandle.doc();
|
|
29
29
|
return doc.objects?.[id];
|
|
30
30
|
}
|
|
31
31
|
async migrateObject(id, migrate) {
|
|
@@ -37,7 +37,7 @@ var MigrationBuilder = class {
|
|
|
37
37
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
38
38
|
invariant(oldHandle, void 0, {
|
|
39
39
|
F: __dxlog_file,
|
|
40
|
-
L:
|
|
40
|
+
L: 84,
|
|
41
41
|
S: this,
|
|
42
42
|
A: [
|
|
43
43
|
"oldHandle",
|
|
@@ -61,7 +61,7 @@ var MigrationBuilder = class {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
-
const migratedDoc = migrateDocument(oldHandle.
|
|
64
|
+
const migratedDoc = migrateDocument(oldHandle.doc(), newState);
|
|
65
65
|
const newHandle = this._repo.import(am.save(migratedDoc));
|
|
66
66
|
this._newLinks[id] = newHandle.url;
|
|
67
67
|
this._addHandleToFlushList(newHandle);
|
|
@@ -85,7 +85,7 @@ var MigrationBuilder = class {
|
|
|
85
85
|
}
|
|
86
86
|
invariant(this._newRoot, "New root not created", {
|
|
87
87
|
F: __dxlog_file,
|
|
88
|
-
L:
|
|
88
|
+
L: 126,
|
|
89
89
|
S: this,
|
|
90
90
|
A: [
|
|
91
91
|
"this._newRoot",
|
|
@@ -107,7 +107,7 @@ var MigrationBuilder = class {
|
|
|
107
107
|
}
|
|
108
108
|
invariant(this._newRoot, "New root not created", {
|
|
109
109
|
F: __dxlog_file,
|
|
110
|
-
L:
|
|
110
|
+
L: 142,
|
|
111
111
|
S: this,
|
|
112
112
|
A: [
|
|
113
113
|
"this._newRoot",
|
|
@@ -175,7 +175,7 @@ var MigrationBuilder = class {
|
|
|
175
175
|
};
|
|
176
176
|
|
|
177
177
|
// packages/sdk/migrations/src/migrations.ts
|
|
178
|
-
import {
|
|
178
|
+
import { live, SpaceState } from "@dxos/client/echo";
|
|
179
179
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
180
180
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migrations.ts";
|
|
181
181
|
var Migrations = class {
|
|
@@ -183,7 +183,7 @@ var Migrations = class {
|
|
|
183
183
|
this.migrations = [];
|
|
184
184
|
}
|
|
185
185
|
static {
|
|
186
|
-
this._state =
|
|
186
|
+
this._state = live({
|
|
187
187
|
running: []
|
|
188
188
|
});
|
|
189
189
|
}
|
|
@@ -191,7 +191,7 @@ var Migrations = class {
|
|
|
191
191
|
return this.namespace && `${this.namespace}.version`;
|
|
192
192
|
}
|
|
193
193
|
static get targetVersion() {
|
|
194
|
-
return this.migrations[this.migrations.length - 1]
|
|
194
|
+
return this.migrations[this.migrations.length - 1]?.version;
|
|
195
195
|
}
|
|
196
196
|
static running(space) {
|
|
197
197
|
return this._state.running.includes(space.key.toHex());
|
|
@@ -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 {
|
|
5
|
-
"mappings": ";;;AAIA,
|
|
6
|
-
"names": ["next", "am", "CreateEpochRequest", "ObjectCore", "migrateDocument", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { next as am, type Doc } from '@automerge/automerge';\nimport { type AnyDocumentId, type DocumentId } from '@automerge/automerge-repo';\nimport { type Schema } from 'effect';\n\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { ObjectCore, migrateDocument, type DocHandleProxy, type RepoProxy } from '@dxos/echo-db';\nimport {\n Reference,\n SpaceDocVersion,\n encodeReference,\n type DatabaseDirectory,\n type ObjectStructure,\n} from '@dxos/echo-protocol';\nimport { requireTypeReference } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\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.db.coreDatabase._repo;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.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: encodeReference(requireTypeReference(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>(am.save(migratedDoc));\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n }\n\n async addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string> {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return encodeReference(Reference.localObjectReference(id));\n }\n\n deleteObject(id: string): void {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void): void {\n if (!this._newRoot) {\n 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 this._addHandleToFlushList(this._newRoot);\n }\n\n /**\n * @internal\n */\n async _commit(): Promise<void> {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._space.db.flush();\n\n // Create new epoch.\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 _buildNewRoot(): 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 am.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 this._addHandleToFlushList(this._newRoot);\n }\n\n private _createObject({\n id,\n schema,\n props,\n }: {\n id?: string;\n schema: Schema.Schema.AnyNoContext;\n props: any;\n }): ObjectCore {\n const core = new ObjectCore();\n if (id) {\n core.id = id;\n }\n\n core.initNewObject(props);\n core.setType(requireTypeReference(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 this._newLinks[core.id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n\n return core;\n }\n\n private _addHandleToFlushList(handle: DocHandleProxy<any>): void {\n this._flushIds.push(handle.documentId);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, live, 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 _state = live<{ running: string[] }>({ running: [] });\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 return this._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 this._state.running.push(space.key.toHex());\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 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 this._state.running.splice(this._state.running.indexOf(space.key.toHex()), 1);\n\n return true;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["next", "am", "CreateEpochRequest", "ObjectCore", "migrateDocument", "Reference", "SpaceDocVersion", "encodeReference", "requireTypeReference", "invariant", "MigrationBuilder", "_space", "_newLinks", "_flushIds", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "_rootDoc", "_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", "data", "meta", "keys", "migratedDoc", "newHandle", "import", "save", "url", "_addHandleToFlushList", "addObject", "core", "_createObject", "createReference", "localObjectReference", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "internal", "createEpoch", "migration", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "Object", "entries", "RawString", "create", "initNewObject", "setType", "getDoc", "handle", "live", "SpaceState", "invariant", "Migrations", "migrations", "_state", "live", "running", "versionProperty", "namespace", "targetVersion", "length", "version", "space", "includes", "key", "toHex", "define", "migrate", "invariant", "state", "get", "SpaceState", "SPACE_READY", "currentVersion", "properties", "currentIndex", "findIndex", "m", "i", "targetIndex", "push", "slice", "migration", "builder", "MigrationBuilder", "next", "changeProperties", "propertiesStructure", "data", "_commit", "splice", "indexOf"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":22181,"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","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/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/migrations/src/migrations.ts":{"bytes":9722,"imports":[{"path":"@dxos/client/echo","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"}],"format":"esm"},"packages/sdk/migrations/src/index.ts":{"bytes":666,"imports":[{"path":"packages/sdk/migrations/src/migration-builder.ts","kind":"import-statement","original":"./migration-builder"},{"path":"packages/sdk/migrations/src/migrations.ts","kind":"import-statement","original":"./migrations"}],"format":"esm"}},"outputs":{"packages/sdk/migrations/dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15581},"packages/sdk/migrations/dist/lib/node-esm/index.mjs":{"imports":[{"path":"@automerge/automerge","kind":"import-statement","external":true},{"path":"@dxos/client/halo","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/echo-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","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":"packages/sdk/migrations/src/index.ts","inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytesInOutput":4834},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2754}},"bytes":7859}}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { type Schema } from 'effect';
|
|
1
2
|
import { type Space } from '@dxos/client/echo';
|
|
2
3
|
import { type ObjectStructure } from '@dxos/echo-protocol';
|
|
3
|
-
import { type S } from '@dxos/echo-schema';
|
|
4
4
|
import { type MaybePromise } from '@dxos/util';
|
|
5
5
|
export declare class MigrationBuilder {
|
|
6
6
|
private readonly _space;
|
|
@@ -13,10 +13,10 @@ export declare class MigrationBuilder {
|
|
|
13
13
|
constructor(_space: Space);
|
|
14
14
|
findObject(id: string): Promise<ObjectStructure | undefined>;
|
|
15
15
|
migrateObject(id: string, migrate: (objectStructure: ObjectStructure) => MaybePromise<{
|
|
16
|
-
schema:
|
|
16
|
+
schema: Schema.Schema.AnyNoContext;
|
|
17
17
|
props: any;
|
|
18
18
|
}>): Promise<void>;
|
|
19
|
-
addObject(schema:
|
|
19
|
+
addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string>;
|
|
20
20
|
createReference(id: string): import("@dxos/echo-protocol").EncodedReference;
|
|
21
21
|
deleteObject(id: string): void;
|
|
22
22
|
changeProperties(changeFn: (properties: ObjectStructure) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-builder.d.ts","sourceRoot":"","sources":["../../../src/migration-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"migration-builder.d.ts","sourceRoot":"","sources":["../../../src/migration-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAoB/C,qBAAa,gBAAgB;IAWf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAGlD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,OAAO,CAAC,QAAQ,CAAC,CAAgD;gBAEpC,MAAM,EAAE,KAAK;IAQpC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAY5D,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,CAAC,eAAe,EAAE,eAAe,KAAK,YAAY,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,GAC9G,OAAO,CAAC,IAAI,CAAC;IAkCV,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAKhF,eAAe,CAAC,EAAE,EAAE,MAAM;IAI1B,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI9B,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;YA+BzD,2BAA2B;IAWzC,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,qBAAqB;CAG9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/migrations.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/migrations.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAoB,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CACzD,CAAC;AAEF,qBAAa,UAAU;IACrB,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,CAAM;IACpC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAgD;IAErE,MAAM,KAAK,eAAe,uBAEzB;IAED,MAAM,KAAK,aAAa,WAEvB;IAED,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAIrC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI;WAKlD,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA6BtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.
|
|
1
|
+
{"version":"5.8.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/migrations",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3-main.672df60",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -24,15 +24,16 @@
|
|
|
24
24
|
"src"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/echo-schema": "0.8.
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
27
|
+
"@automerge/automerge": "3.0.0-beta.4",
|
|
28
|
+
"@automerge/automerge-repo": "2.0.1",
|
|
29
|
+
"@dxos/echo-db": "0.8.3-main.672df60",
|
|
30
|
+
"@dxos/client": "0.8.3-main.672df60",
|
|
31
|
+
"@dxos/echo-protocol": "0.8.3-main.672df60",
|
|
32
|
+
"@dxos/echo-schema": "0.8.3-main.672df60",
|
|
33
|
+
"@dxos/log": "0.8.3-main.672df60",
|
|
34
|
+
"@dxos/invariant": "0.8.3-main.672df60",
|
|
35
|
+
"@dxos/util": "0.8.3-main.672df60",
|
|
36
|
+
"@dxos/protocols": "0.8.3-main.672df60"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {},
|
|
38
39
|
"publishConfig": {
|
package/src/migration-builder.ts
CHANGED
|
@@ -2,33 +2,59 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import { type AnyDocumentId, type DocumentId } from '@
|
|
5
|
+
import { next as am, type Doc } from '@automerge/automerge';
|
|
6
|
+
import { type AnyDocumentId, type DocumentId } from '@automerge/automerge-repo';
|
|
7
|
+
import { type Schema } from 'effect';
|
|
8
|
+
|
|
7
9
|
import { type Space } from '@dxos/client/echo';
|
|
8
10
|
import { CreateEpochRequest } from '@dxos/client/halo';
|
|
9
|
-
import { ObjectCore, migrateDocument, type
|
|
10
|
-
import {
|
|
11
|
-
|
|
11
|
+
import { ObjectCore, migrateDocument, type DocHandleProxy, type RepoProxy } from '@dxos/echo-db';
|
|
12
|
+
import {
|
|
13
|
+
Reference,
|
|
14
|
+
SpaceDocVersion,
|
|
15
|
+
encodeReference,
|
|
16
|
+
type DatabaseDirectory,
|
|
17
|
+
type ObjectStructure,
|
|
18
|
+
} from '@dxos/echo-protocol';
|
|
19
|
+
import { requireTypeReference } from '@dxos/echo-schema';
|
|
12
20
|
import { invariant } from '@dxos/invariant';
|
|
13
21
|
import { type MaybePromise } from '@dxos/util';
|
|
14
22
|
|
|
23
|
+
/*
|
|
24
|
+
|
|
25
|
+
Considering a better API for this:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const migration = space.db.beginMigration(); // all actions are not visible to queries and are only applied once you call `apply`
|
|
29
|
+
|
|
30
|
+
migration.applyObjectMigration(defineMigration(From, To, { ... }));
|
|
31
|
+
|
|
32
|
+
migration.delete(id);
|
|
33
|
+
migration.add(obj);
|
|
34
|
+
|
|
35
|
+
await migration.apply(); // Will create new epoch.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
// TODO(dmaretskyi): We no longer need to hook into ECHO internals, with the changes to echo APIs.
|
|
15
41
|
export class MigrationBuilder {
|
|
16
42
|
private readonly _repo: RepoProxy;
|
|
17
|
-
private readonly _rootDoc: Doc<
|
|
43
|
+
private readonly _rootDoc: Doc<DatabaseDirectory>;
|
|
18
44
|
|
|
19
45
|
// echoId -> automergeUrl
|
|
20
46
|
private readonly _newLinks: Record<string, string> = {};
|
|
21
47
|
private readonly _flushIds: DocumentId[] = [];
|
|
22
48
|
private readonly _deleteObjects: string[] = [];
|
|
23
49
|
|
|
24
|
-
private _newRoot?: DocHandleProxy<
|
|
50
|
+
private _newRoot?: DocHandleProxy<DatabaseDirectory> = undefined;
|
|
25
51
|
|
|
26
52
|
constructor(private readonly _space: Space) {
|
|
27
53
|
this._repo = this._space.db.coreDatabase._repo;
|
|
28
54
|
// TODO(wittjosiah): Accessing private API.
|
|
29
55
|
this._rootDoc = (this._space.db.coreDatabase as any)._automergeDocLoader
|
|
30
56
|
.getSpaceRootDocHandle()
|
|
31
|
-
.
|
|
57
|
+
.doc() as Doc<DatabaseDirectory>;
|
|
32
58
|
}
|
|
33
59
|
|
|
34
60
|
async findObject(id: string): Promise<ObjectStructure | undefined> {
|
|
@@ -39,14 +65,14 @@ export class MigrationBuilder {
|
|
|
39
65
|
}
|
|
40
66
|
|
|
41
67
|
await docHandle.whenReady();
|
|
42
|
-
const doc = docHandle.
|
|
68
|
+
const doc = docHandle.doc() as Doc<DatabaseDirectory>;
|
|
43
69
|
return doc.objects?.[id];
|
|
44
70
|
}
|
|
45
71
|
|
|
46
72
|
async migrateObject(
|
|
47
73
|
id: string,
|
|
48
|
-
migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema:
|
|
49
|
-
) {
|
|
74
|
+
migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema: Schema.Schema.AnyNoContext; props: any }>,
|
|
75
|
+
): Promise<void> {
|
|
50
76
|
const objectStructure = await this.findObject(id);
|
|
51
77
|
if (!objectStructure) {
|
|
52
78
|
return;
|
|
@@ -57,7 +83,7 @@ export class MigrationBuilder {
|
|
|
57
83
|
const oldHandle = await this._findObjectContainingHandle(id);
|
|
58
84
|
invariant(oldHandle);
|
|
59
85
|
|
|
60
|
-
const newState:
|
|
86
|
+
const newState: DatabaseDirectory = {
|
|
61
87
|
version: SpaceDocVersion.CURRENT,
|
|
62
88
|
access: {
|
|
63
89
|
spaceKey: this._space.key.toHex(),
|
|
@@ -74,13 +100,13 @@ export class MigrationBuilder {
|
|
|
74
100
|
},
|
|
75
101
|
},
|
|
76
102
|
};
|
|
77
|
-
const migratedDoc = migrateDocument(oldHandle.
|
|
78
|
-
const newHandle = this._repo.import<
|
|
103
|
+
const migratedDoc = migrateDocument(oldHandle.doc() as Doc<DatabaseDirectory>, newState);
|
|
104
|
+
const newHandle = this._repo.import<DatabaseDirectory>(am.save(migratedDoc));
|
|
79
105
|
this._newLinks[id] = newHandle.url;
|
|
80
106
|
this._addHandleToFlushList(newHandle);
|
|
81
107
|
}
|
|
82
108
|
|
|
83
|
-
async addObject(schema:
|
|
109
|
+
async addObject(schema: Schema.Schema.AnyNoContext, props: any): Promise<string> {
|
|
84
110
|
const core = this._createObject({ schema, props });
|
|
85
111
|
return core.id;
|
|
86
112
|
}
|
|
@@ -89,17 +115,17 @@ export class MigrationBuilder {
|
|
|
89
115
|
return encodeReference(Reference.localObjectReference(id));
|
|
90
116
|
}
|
|
91
117
|
|
|
92
|
-
deleteObject(id: string) {
|
|
118
|
+
deleteObject(id: string): void {
|
|
93
119
|
this._deleteObjects.push(id);
|
|
94
120
|
}
|
|
95
121
|
|
|
96
|
-
changeProperties(changeFn: (properties: ObjectStructure) => void) {
|
|
122
|
+
changeProperties(changeFn: (properties: ObjectStructure) => void): void {
|
|
97
123
|
if (!this._newRoot) {
|
|
98
124
|
this._buildNewRoot();
|
|
99
125
|
}
|
|
100
126
|
invariant(this._newRoot, 'New root not created');
|
|
101
127
|
|
|
102
|
-
this._newRoot.change((doc:
|
|
128
|
+
this._newRoot.change((doc: DatabaseDirectory) => {
|
|
103
129
|
const propertiesStructure = doc.objects?.[this._space.properties.id];
|
|
104
130
|
propertiesStructure && changeFn(propertiesStructure);
|
|
105
131
|
});
|
|
@@ -109,7 +135,7 @@ export class MigrationBuilder {
|
|
|
109
135
|
/**
|
|
110
136
|
* @internal
|
|
111
137
|
*/
|
|
112
|
-
async _commit() {
|
|
138
|
+
async _commit(): Promise<void> {
|
|
113
139
|
if (!this._newRoot) {
|
|
114
140
|
this._buildNewRoot();
|
|
115
141
|
}
|
|
@@ -124,7 +150,7 @@ export class MigrationBuilder {
|
|
|
124
150
|
});
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
private async _findObjectContainingHandle(id: string): Promise<DocHandleProxy<
|
|
153
|
+
private async _findObjectContainingHandle(id: string): Promise<DocHandleProxy<DatabaseDirectory> | undefined> {
|
|
128
154
|
const documentId = (this._rootDoc.links?.[id] || this._newLinks[id])?.toString() as AnyDocumentId | undefined;
|
|
129
155
|
const docHandle = documentId && this._repo.find(documentId);
|
|
130
156
|
if (!docHandle) {
|
|
@@ -135,7 +161,7 @@ export class MigrationBuilder {
|
|
|
135
161
|
return docHandle;
|
|
136
162
|
}
|
|
137
163
|
|
|
138
|
-
private _buildNewRoot() {
|
|
164
|
+
private _buildNewRoot(): void {
|
|
139
165
|
const links = { ...(this._rootDoc.links ?? {}) };
|
|
140
166
|
for (const id of this._deleteObjects) {
|
|
141
167
|
delete links[id];
|
|
@@ -145,7 +171,7 @@ export class MigrationBuilder {
|
|
|
145
171
|
links[id] = new am.RawString(url);
|
|
146
172
|
}
|
|
147
173
|
|
|
148
|
-
this._newRoot = this._repo.create<
|
|
174
|
+
this._newRoot = this._repo.create<DatabaseDirectory>({
|
|
149
175
|
version: SpaceDocVersion.CURRENT,
|
|
150
176
|
access: {
|
|
151
177
|
spaceKey: this._space.key.toHex(),
|
|
@@ -156,7 +182,15 @@ export class MigrationBuilder {
|
|
|
156
182
|
this._addHandleToFlushList(this._newRoot);
|
|
157
183
|
}
|
|
158
184
|
|
|
159
|
-
private _createObject({
|
|
185
|
+
private _createObject({
|
|
186
|
+
id,
|
|
187
|
+
schema,
|
|
188
|
+
props,
|
|
189
|
+
}: {
|
|
190
|
+
id?: string;
|
|
191
|
+
schema: Schema.Schema.AnyNoContext;
|
|
192
|
+
props: any;
|
|
193
|
+
}): ObjectCore {
|
|
160
194
|
const core = new ObjectCore();
|
|
161
195
|
if (id) {
|
|
162
196
|
core.id = id;
|
|
@@ -164,7 +198,7 @@ export class MigrationBuilder {
|
|
|
164
198
|
|
|
165
199
|
core.initNewObject(props);
|
|
166
200
|
core.setType(requireTypeReference(schema));
|
|
167
|
-
const newHandle = this._repo.create<
|
|
201
|
+
const newHandle = this._repo.create<DatabaseDirectory>({
|
|
168
202
|
version: SpaceDocVersion.CURRENT,
|
|
169
203
|
access: {
|
|
170
204
|
spaceKey: this._space.key.toHex(),
|
|
@@ -179,7 +213,7 @@ export class MigrationBuilder {
|
|
|
179
213
|
return core;
|
|
180
214
|
}
|
|
181
215
|
|
|
182
|
-
private _addHandleToFlushList(handle: DocHandleProxy<any>) {
|
|
216
|
+
private _addHandleToFlushList(handle: DocHandleProxy<any>): void {
|
|
183
217
|
this._flushIds.push(handle.documentId);
|
|
184
218
|
}
|
|
185
219
|
}
|
package/src/migrations.test.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { Client } from '@dxos/client';
|
|
8
|
-
import {
|
|
8
|
+
import { live, Filter, type Space } from '@dxos/client/echo';
|
|
9
9
|
import { TestBuilder } from '@dxos/client/testing';
|
|
10
10
|
import { Expando } from '@dxos/echo-schema';
|
|
11
11
|
|
|
@@ -21,7 +21,8 @@ Migrations.define('test', [
|
|
|
21
21
|
{
|
|
22
22
|
version: '1970-01-02',
|
|
23
23
|
next: async ({ space, builder }) => {
|
|
24
|
-
|
|
24
|
+
// TODO(dmaretskyi): Is this intended to query only expando objects? Change to `Filter.type(Expando, { namespace: 'test' })`
|
|
25
|
+
const { objects } = await space.db.query(Filter._props<any>({ namespace: 'test' })).run();
|
|
25
26
|
for (const object of objects) {
|
|
26
27
|
await builder.migrateObject(object.id, ({ data }) => ({
|
|
27
28
|
schema: Expando,
|
|
@@ -33,7 +34,8 @@ Migrations.define('test', [
|
|
|
33
34
|
{
|
|
34
35
|
version: '1970-01-03',
|
|
35
36
|
next: async ({ space, builder }) => {
|
|
36
|
-
|
|
37
|
+
// TODO(dmaretskyi): Is this intended to query only expando objects? Change to `Filter.type(Expando, { namespace: 'test' })`
|
|
38
|
+
const { objects } = await space.db.query(Filter._props<any>({ namespace: 'test' })).run();
|
|
37
39
|
for (const object of objects) {
|
|
38
40
|
await builder.migrateObject(object.id, ({ data }) => ({
|
|
39
41
|
schema: Expando,
|
|
@@ -65,7 +67,7 @@ describe('Migrations', () => {
|
|
|
65
67
|
|
|
66
68
|
test('if no migrations have been run before, runs all migrations', async () => {
|
|
67
69
|
await Migrations.migrate(space);
|
|
68
|
-
const { objects } = await space.db.query(Filter.
|
|
70
|
+
const { objects } = await space.db.query(Filter.type(Expando, { namespace: 'test' })).run();
|
|
69
71
|
expect(objects).to.have.length(1);
|
|
70
72
|
expect(objects[0].count).to.equal(6);
|
|
71
73
|
expect(space.properties['test.version']).to.equal('1970-01-03');
|
|
@@ -73,9 +75,9 @@ describe('Migrations', () => {
|
|
|
73
75
|
|
|
74
76
|
test('if some migrations have been run before, runs only the remaining migrations', async () => {
|
|
75
77
|
space.properties['test.version'] = '1970-01-02';
|
|
76
|
-
space.db.add(
|
|
78
|
+
space.db.add(live(Expando, { namespace: 'test', count: 5 }));
|
|
77
79
|
await Migrations.migrate(space);
|
|
78
|
-
const { objects } = await space.db.query(Filter.
|
|
80
|
+
const { objects } = await space.db.query(Filter.type(Expando, { namespace: 'test' })).run();
|
|
79
81
|
expect(objects).to.have.length(1);
|
|
80
82
|
expect(objects[0].count).to.equal(15);
|
|
81
83
|
expect(space.properties['test.version']).to.equal('1970-01-03');
|
|
@@ -84,13 +86,13 @@ describe('Migrations', () => {
|
|
|
84
86
|
test('if all migrations have been run before, does nothing', async () => {
|
|
85
87
|
space.properties['test.version'] = '1970-01-03';
|
|
86
88
|
await Migrations.migrate(space);
|
|
87
|
-
const { objects } = await space.db.query(Filter.
|
|
89
|
+
const { objects } = await space.db.query(Filter.type(Expando, { namespace: 'test' })).run();
|
|
88
90
|
expect(objects).to.have.length(0);
|
|
89
91
|
});
|
|
90
92
|
|
|
91
93
|
test('if target version is specified, runs only the migrations up to that version', async () => {
|
|
92
94
|
await Migrations.migrate(space, '1970-01-02');
|
|
93
|
-
const { objects } = await space.db.query(Filter.
|
|
95
|
+
const { objects } = await space.db.query(Filter.type(Expando, { namespace: 'test' })).run();
|
|
94
96
|
expect(objects).to.have.length(1);
|
|
95
97
|
expect(objects[0].count).to.equal(2);
|
|
96
98
|
expect(space.properties['test.version']).to.equal('1970-01-02');
|
package/src/migrations.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type Space,
|
|
5
|
+
import { type Space, live, SpaceState } from '@dxos/client/echo';
|
|
6
6
|
import { invariant } from '@dxos/invariant';
|
|
7
7
|
import { type MaybePromise } from '@dxos/util';
|
|
8
8
|
|
|
@@ -21,26 +21,26 @@ export type Migration = {
|
|
|
21
21
|
export class Migrations {
|
|
22
22
|
static namespace?: string;
|
|
23
23
|
static migrations: Migration[] = [];
|
|
24
|
-
private static _state =
|
|
24
|
+
private static _state = live<{ running: string[] }>({ running: [] });
|
|
25
25
|
|
|
26
26
|
static get versionProperty() {
|
|
27
27
|
return this.namespace && `${this.namespace}.version`;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
static get targetVersion() {
|
|
31
|
-
return this.migrations[this.migrations.length - 1]
|
|
31
|
+
return this.migrations[this.migrations.length - 1]?.version;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
static running(space: Space) {
|
|
34
|
+
static running(space: Space): boolean {
|
|
35
35
|
return this._state.running.includes(space.key.toHex());
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
static define(namespace: string, migrations: Migration[]) {
|
|
38
|
+
static define(namespace: string, migrations: Migration[]): void {
|
|
39
39
|
this.namespace = namespace;
|
|
40
40
|
this.migrations = migrations;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
static async migrate(space: Space, targetVersion?: string | number) {
|
|
43
|
+
static async migrate(space: Space, targetVersion?: string | number): Promise<boolean> {
|
|
44
44
|
invariant(!this.running(space), 'Migration already running');
|
|
45
45
|
invariant(this.versionProperty, 'Migrations namespace not set');
|
|
46
46
|
invariant(space.state.get() === SpaceState.SPACE_READY, 'Space not ready');
|