@dxos/migrations 0.5.9-main.1c1903d → 0.5.9-main.1ea2105

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.
@@ -1,7 +1,8 @@
1
1
  // packages/sdk/migrations/src/migration-builder.ts
2
- import { getHeads } from "@dxos/automerge/automerge";
2
+ import { next as am } from "@dxos/automerge/automerge";
3
3
  import { CreateEpochRequest } from "@dxos/client/halo";
4
- import { ObjectCore } from "@dxos/echo-db";
4
+ import { ObjectCore, migrateDocument } from "@dxos/echo-db";
5
+ import { SpaceDocVersion, encodeReference, Reference } from "@dxos/echo-protocol";
5
6
  import { requireTypeReference } from "@dxos/echo-schema";
6
7
  import { invariant } from "@dxos/invariant";
7
8
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migration-builder.ts";
@@ -31,20 +32,49 @@ var MigrationBuilder = class {
31
32
  if (!objectStructure) {
32
33
  return;
33
34
  }
34
- const { schema, props } = migrate(objectStructure);
35
- this._createObject({
36
- id,
37
- schema,
38
- props
35
+ const { schema, props } = await migrate(objectStructure);
36
+ const oldHandle = await this._findObjectContainingHandle(id);
37
+ invariant(oldHandle, void 0, {
38
+ F: __dxlog_file,
39
+ L: 61,
40
+ S: this,
41
+ A: [
42
+ "oldHandle",
43
+ ""
44
+ ]
39
45
  });
46
+ const newState = {
47
+ version: SpaceDocVersion.CURRENT,
48
+ access: {
49
+ spaceKey: this._space.key.toHex()
50
+ },
51
+ objects: {
52
+ [id]: {
53
+ system: {
54
+ type: encodeReference(requireTypeReference(schema))
55
+ },
56
+ data: props,
57
+ meta: {
58
+ keys: []
59
+ }
60
+ }
61
+ }
62
+ };
63
+ const migratedDoc = migrateDocument(oldHandle.docSync(), newState);
64
+ const newHandle = this._repo.import(am.save(migratedDoc));
65
+ this._newLinks[id] = newHandle.url;
66
+ this._addHandleToFlushList(newHandle);
40
67
  }
41
- addObject(schema, props) {
68
+ async addObject(schema, props) {
42
69
  const core = this._createObject({
43
70
  schema,
44
71
  props
45
72
  });
46
73
  return core.id;
47
74
  }
75
+ createReference(id) {
76
+ return encodeReference(new Reference(id));
77
+ }
48
78
  deleteObject(id) {
49
79
  this._deleteObjects.push(id);
50
80
  }
@@ -54,7 +84,7 @@ var MigrationBuilder = class {
54
84
  }
55
85
  invariant(this._newRoot, "New root not created", {
56
86
  F: __dxlog_file,
57
- L: 74,
87
+ L: 103,
58
88
  S: this,
59
89
  A: [
60
90
  "this._newRoot",
@@ -65,10 +95,7 @@ var MigrationBuilder = class {
65
95
  const propertiesStructure = doc.objects?.[this._space.properties.id];
66
96
  propertiesStructure && changeFn(propertiesStructure);
67
97
  });
68
- this._flushStates.push({
69
- documentId: this._newRoot.documentId,
70
- heads: getHeads(this._newRoot.docSync())
71
- });
98
+ this._addHandleToFlushList(this._newRoot);
72
99
  }
73
100
  /**
74
101
  * @internal
@@ -79,7 +106,7 @@ var MigrationBuilder = class {
79
106
  }
80
107
  invariant(this._newRoot, "New root not created", {
81
108
  F: __dxlog_file,
82
- L: 93,
109
+ L: 119,
83
110
  S: this,
84
111
  A: [
85
112
  "this._newRoot",
@@ -94,6 +121,15 @@ var MigrationBuilder = class {
94
121
  automergeRootUrl: this._newRoot.url
95
122
  });
96
123
  }
124
+ async _findObjectContainingHandle(id) {
125
+ const documentId = this._rootDoc.links?.[id] || this._newLinks[id];
126
+ const docHandle = documentId && this._repo.find(documentId);
127
+ if (!docHandle) {
128
+ return void 0;
129
+ }
130
+ await docHandle.whenReady();
131
+ return docHandle;
132
+ }
97
133
  _buildNewRoot() {
98
134
  const previousLinks = {
99
135
  ...this._rootDoc.links ?? {}
@@ -102,6 +138,7 @@ var MigrationBuilder = class {
102
138
  delete previousLinks[id];
103
139
  }
104
140
  this._newRoot = this._repo.create({
141
+ version: SpaceDocVersion.CURRENT,
105
142
  access: {
106
143
  spaceKey: this._space.key.toHex()
107
144
  },
@@ -111,10 +148,7 @@ var MigrationBuilder = class {
111
148
  ...this._newLinks
112
149
  }
113
150
  });
114
- this._flushStates.push({
115
- documentId: this._newRoot.documentId,
116
- heads: getHeads(this._newRoot.docSync())
117
- });
151
+ this._addHandleToFlushList(this._newRoot);
118
152
  }
119
153
  _createObject({ id, schema, props }) {
120
154
  const core = new ObjectCore();
@@ -124,6 +158,7 @@ var MigrationBuilder = class {
124
158
  core.initNewObject(props);
125
159
  core.setType(requireTypeReference(schema));
126
160
  const newHandle = this._repo.create({
161
+ version: SpaceDocVersion.CURRENT,
127
162
  access: {
128
163
  spaceKey: this._space.key.toHex()
129
164
  },
@@ -132,11 +167,14 @@ var MigrationBuilder = class {
132
167
  }
133
168
  });
134
169
  this._newLinks[core.id] = newHandle.url;
170
+ this._addHandleToFlushList(newHandle);
171
+ return core;
172
+ }
173
+ _addHandleToFlushList(handle) {
135
174
  this._flushStates.push({
136
- documentId: newHandle.documentId,
137
- heads: getHeads(newHandle.docSync())
175
+ documentId: handle.documentId,
176
+ heads: am.getHeads(handle.docSync())
138
177
  });
139
- return core;
140
178
  }
141
179
  };
142
180
 
@@ -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 { getHeads, type Doc } from '@dxos/automerge/automerge';\nimport { type AnyDocumentId, type DocHandle, type Repo } from '@dxos/automerge/automerge-repo';\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { type AutomergeContext, ObjectCore } from '@dxos/echo-db';\nimport { type ObjectStructure, type SpaceDoc } from '@dxos/echo-protocol';\nimport { requireTypeReference, type S } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';\n\nexport class MigrationBuilder {\n private readonly _repo: Repo;\n private readonly _automergeContext: AutomergeContext;\n private readonly _rootDoc: Doc<SpaceDoc>;\n\n // echoId -> automergeUrl\n private readonly _newLinks: Record<string, string> = {};\n private readonly _flushStates: FlushRequest.DocState[] = [];\n private readonly _deleteObjects: string[] = [];\n\n private _newRoot?: DocHandle<SpaceDoc> = undefined;\n\n constructor(private readonly _space: Space) {\n this._repo = this._space.db.coreDatabase.automerge.repo;\n this._automergeContext = this._space.db.coreDatabase.automerge;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.db.coreDatabase as any)._automergeDocLoader\n .getSpaceRootDocHandle()\n .docSync() as Doc<SpaceDoc>;\n }\n\n async findObject(id: string): Promise<ObjectStructure | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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.docSync() as Doc<SpaceDoc>;\n return doc.objects?.[id];\n }\n\n async migrateObject(\n id: string,\n migrate: (objectStructure: ObjectStructure) => { schema: S.Schema<any>; props: any },\n ) {\n const objectStructure = await this.findObject(id);\n if (!objectStructure) {\n return;\n }\n\n const { schema, props } = migrate(objectStructure);\n this._createObject({ id, schema, props });\n }\n\n addObject(schema: S.Schema<any>, props: any) {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n deleteObject(id: string) {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void) {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n this._newRoot.change((doc: SpaceDoc) => {\n const propertiesStructure = doc.objects?.[this._space.properties.id];\n propertiesStructure && changeFn(propertiesStructure);\n });\n this._flushStates.push({\n documentId: this._newRoot.documentId,\n heads: getHeads(this._newRoot.docSync()),\n });\n }\n\n /**\n * @internal\n */\n async _commit() {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._automergeContext.flush({\n states: this._flushStates,\n });\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 _buildNewRoot() {\n const previousLinks = { ...(this._rootDoc.links ?? {}) };\n for (const id of this._deleteObjects) {\n delete previousLinks[id];\n }\n\n this._newRoot = this._repo.create<SpaceDoc>({\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: this._rootDoc.objects,\n links: {\n ...previousLinks,\n ...this._newLinks,\n },\n });\n this._flushStates.push({\n documentId: this._newRoot.documentId,\n heads: getHeads(this._newRoot.docSync()),\n });\n }\n\n private _createObject({ id, schema, props }: { id?: string; schema: S.Schema<any>; props: any }) {\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<SpaceDoc>({\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [core.id]: core.getDoc(),\n },\n });\n this._newLinks[core.id] = newHandle.url;\n this._flushStates.push({\n documentId: newHandle.documentId,\n heads: getHeads(newHandle.docSync()),\n });\n\n return core;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, create, 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 = create<{ 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) {\n return this._state.running.includes(space.key.toHex());\n }\n\n static define(namespace: string, migrations: Migration[]) {\n this.namespace = namespace;\n this.migrations = migrations;\n }\n\n static async migrate(space: Space, targetVersion?: string | number) {\n invariant(!this.running(space), 'Migration already running');\n invariant(this.versionProperty, 'Migrations namespace not set');\n invariant(space.state.get() === SpaceState.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": ["getHeads", "CreateEpochRequest", "ObjectCore", "requireTypeReference", "invariant", "MigrationBuilder", "constructor", "_space", "_newLinks", "_flushStates", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "automerge", "repo", "_automergeContext", "_rootDoc", "_automergeDocLoader", "getSpaceRootDocHandle", "docSync", "findObject", "id", "documentId", "links", "docHandle", "find", "whenReady", "doc", "objects", "migrateObject", "migrate", "objectStructure", "schema", "props", "_createObject", "addObject", "core", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "heads", "_commit", "flush", "states", "internal", "createEpoch", "migration", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "url", "previousLinks", "create", "access", "spaceKey", "key", "toHex", "initNewObject", "setType", "newHandle", "getDoc", "create", "SpaceState", "invariant", "Migrations", "migrations", "_state", "create", "running", "versionProperty", "namespace", "targetVersion", "length", "version", "space", "includes", "key", "toHex", "define", "migrate", "invariant", "state", "get", "SpaceState", "READY", "currentVersion", "properties", "currentIndex", "findIndex", "m", "i", "targetIndex", "push", "slice", "migration", "builder", "MigrationBuilder", "next", "changeProperties", "propertiesStructure", "data", "_commit", "splice", "indexOf"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Doc, next as am } from '@dxos/automerge/automerge';\nimport { type AnyDocumentId, type DocHandle, type Repo } from '@dxos/automerge/automerge-repo';\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { type AutomergeContext, ObjectCore, migrateDocument } from '@dxos/echo-db';\nimport { SpaceDocVersion, encodeReference, type ObjectStructure, type SpaceDoc, Reference } from '@dxos/echo-protocol';\nimport { requireTypeReference, type S } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';\nimport { type MaybePromise } from '@dxos/util';\n\nexport class MigrationBuilder {\n private readonly _repo: Repo;\n private readonly _automergeContext: AutomergeContext;\n private readonly _rootDoc: Doc<SpaceDoc>;\n\n // echoId -> automergeUrl\n private readonly _newLinks: Record<string, string> = {};\n private readonly _flushStates: FlushRequest.DocState[] = [];\n private readonly _deleteObjects: string[] = [];\n\n private _newRoot?: DocHandle<SpaceDoc> = undefined;\n\n constructor(private readonly _space: Space) {\n this._repo = this._space.db.coreDatabase.automerge.repo;\n this._automergeContext = this._space.db.coreDatabase.automerge;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.db.coreDatabase as any)._automergeDocLoader\n .getSpaceRootDocHandle()\n .docSync() as Doc<SpaceDoc>;\n }\n\n async findObject(id: string): Promise<ObjectStructure | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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.docSync() as Doc<SpaceDoc>;\n return doc.objects?.[id];\n }\n\n async migrateObject(\n id: string,\n migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema: S.Schema<any>; props: any }>,\n ) {\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: SpaceDoc = {\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.docSync() as Doc<SpaceDoc>, newState);\n const newHandle = this._repo.import<SpaceDoc>(am.save(migratedDoc));\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n }\n\n async addObject(schema: S.Schema<any>, props: any) {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return encodeReference(new Reference(id));\n }\n\n deleteObject(id: string) {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void) {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n this._newRoot.change((doc: SpaceDoc) => {\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() {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._automergeContext.flush({\n states: this._flushStates,\n });\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<DocHandle<SpaceDoc> | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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() {\n const previousLinks = { ...(this._rootDoc.links ?? {}) };\n for (const id of this._deleteObjects) {\n delete previousLinks[id];\n }\n\n this._newRoot = this._repo.create<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: this._rootDoc.objects,\n links: {\n ...previousLinks,\n ...this._newLinks,\n },\n });\n this._addHandleToFlushList(this._newRoot);\n }\n\n private _createObject({ id, schema, props }: { id?: string; schema: S.Schema<any>; props: any }) {\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<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [core.id]: core.getDoc(),\n },\n });\n this._newLinks[core.id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n\n return core;\n }\n\n private _addHandleToFlushList(handle: DocHandle<any>) {\n this._flushStates.push({\n documentId: handle.documentId,\n heads: am.getHeads(handle.docSync()),\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, create, 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 = create<{ 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) {\n return this._state.running.includes(space.key.toHex());\n }\n\n static define(namespace: string, migrations: Migration[]) {\n this.namespace = namespace;\n this.migrations = migrations;\n }\n\n static async migrate(space: Space, targetVersion?: string | number) {\n invariant(!this.running(space), 'Migration already running');\n invariant(this.versionProperty, 'Migrations namespace not set');\n invariant(space.state.get() === SpaceState.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", "SpaceDocVersion", "encodeReference", "Reference", "requireTypeReference", "invariant", "MigrationBuilder", "constructor", "_space", "_newLinks", "_flushStates", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "automerge", "repo", "_automergeContext", "_rootDoc", "_automergeDocLoader", "getSpaceRootDocHandle", "docSync", "findObject", "id", "documentId", "links", "docHandle", "find", "whenReady", "doc", "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", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "states", "internal", "createEpoch", "migration", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "previousLinks", "create", "initNewObject", "setType", "getDoc", "handle", "heads", "getHeads", "create", "SpaceState", "invariant", "Migrations", "migrations", "_state", "create", "running", "versionProperty", "namespace", "targetVersion", "length", "version", "space", "includes", "key", "toHex", "define", "migrate", "invariant", "state", "get", "SpaceState", "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":16903,"imports":[{"path":"@dxos/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-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/migrations/src/migrations.ts":{"bytes":9817,"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":698,"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":12698},"packages/sdk/migrations/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/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-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":3783},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2745}},"bytes":6706}}}
1
+ {"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":21641,"imports":[{"path":"@dxos/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":9817,"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":698,"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":15103},"packages/sdk/migrations/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/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":4976},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2745}},"bytes":7899}}}
@@ -25,6 +25,7 @@ module.exports = __toCommonJS(node_exports);
25
25
  var import_automerge = require("@dxos/automerge/automerge");
26
26
  var import_halo = require("@dxos/client/halo");
27
27
  var import_echo_db = require("@dxos/echo-db");
28
+ var import_echo_protocol = require("@dxos/echo-protocol");
28
29
  var import_echo_schema = require("@dxos/echo-schema");
29
30
  var import_invariant = require("@dxos/invariant");
30
31
  var import_echo = require("@dxos/client/echo");
@@ -56,20 +57,49 @@ var MigrationBuilder = class {
56
57
  if (!objectStructure) {
57
58
  return;
58
59
  }
59
- const { schema, props } = migrate(objectStructure);
60
- this._createObject({
61
- id,
62
- schema,
63
- props
60
+ const { schema, props } = await migrate(objectStructure);
61
+ const oldHandle = await this._findObjectContainingHandle(id);
62
+ (0, import_invariant.invariant)(oldHandle, void 0, {
63
+ F: __dxlog_file,
64
+ L: 61,
65
+ S: this,
66
+ A: [
67
+ "oldHandle",
68
+ ""
69
+ ]
64
70
  });
71
+ const newState = {
72
+ version: import_echo_protocol.SpaceDocVersion.CURRENT,
73
+ access: {
74
+ spaceKey: this._space.key.toHex()
75
+ },
76
+ objects: {
77
+ [id]: {
78
+ system: {
79
+ type: (0, import_echo_protocol.encodeReference)((0, import_echo_schema.requireTypeReference)(schema))
80
+ },
81
+ data: props,
82
+ meta: {
83
+ keys: []
84
+ }
85
+ }
86
+ }
87
+ };
88
+ const migratedDoc = (0, import_echo_db.migrateDocument)(oldHandle.docSync(), newState);
89
+ const newHandle = this._repo.import(import_automerge.next.save(migratedDoc));
90
+ this._newLinks[id] = newHandle.url;
91
+ this._addHandleToFlushList(newHandle);
65
92
  }
66
- addObject(schema, props) {
93
+ async addObject(schema, props) {
67
94
  const core = this._createObject({
68
95
  schema,
69
96
  props
70
97
  });
71
98
  return core.id;
72
99
  }
100
+ createReference(id) {
101
+ return (0, import_echo_protocol.encodeReference)(new import_echo_protocol.Reference(id));
102
+ }
73
103
  deleteObject(id) {
74
104
  this._deleteObjects.push(id);
75
105
  }
@@ -79,7 +109,7 @@ var MigrationBuilder = class {
79
109
  }
80
110
  (0, import_invariant.invariant)(this._newRoot, "New root not created", {
81
111
  F: __dxlog_file,
82
- L: 74,
112
+ L: 103,
83
113
  S: this,
84
114
  A: [
85
115
  "this._newRoot",
@@ -90,10 +120,7 @@ var MigrationBuilder = class {
90
120
  const propertiesStructure = doc.objects?.[this._space.properties.id];
91
121
  propertiesStructure && changeFn(propertiesStructure);
92
122
  });
93
- this._flushStates.push({
94
- documentId: this._newRoot.documentId,
95
- heads: (0, import_automerge.getHeads)(this._newRoot.docSync())
96
- });
123
+ this._addHandleToFlushList(this._newRoot);
97
124
  }
98
125
  /**
99
126
  * @internal
@@ -104,7 +131,7 @@ var MigrationBuilder = class {
104
131
  }
105
132
  (0, import_invariant.invariant)(this._newRoot, "New root not created", {
106
133
  F: __dxlog_file,
107
- L: 93,
134
+ L: 119,
108
135
  S: this,
109
136
  A: [
110
137
  "this._newRoot",
@@ -119,6 +146,15 @@ var MigrationBuilder = class {
119
146
  automergeRootUrl: this._newRoot.url
120
147
  });
121
148
  }
149
+ async _findObjectContainingHandle(id) {
150
+ const documentId = this._rootDoc.links?.[id] || this._newLinks[id];
151
+ const docHandle = documentId && this._repo.find(documentId);
152
+ if (!docHandle) {
153
+ return void 0;
154
+ }
155
+ await docHandle.whenReady();
156
+ return docHandle;
157
+ }
122
158
  _buildNewRoot() {
123
159
  const previousLinks = {
124
160
  ...this._rootDoc.links ?? {}
@@ -127,6 +163,7 @@ var MigrationBuilder = class {
127
163
  delete previousLinks[id];
128
164
  }
129
165
  this._newRoot = this._repo.create({
166
+ version: import_echo_protocol.SpaceDocVersion.CURRENT,
130
167
  access: {
131
168
  spaceKey: this._space.key.toHex()
132
169
  },
@@ -136,10 +173,7 @@ var MigrationBuilder = class {
136
173
  ...this._newLinks
137
174
  }
138
175
  });
139
- this._flushStates.push({
140
- documentId: this._newRoot.documentId,
141
- heads: (0, import_automerge.getHeads)(this._newRoot.docSync())
142
- });
176
+ this._addHandleToFlushList(this._newRoot);
143
177
  }
144
178
  _createObject({ id, schema, props }) {
145
179
  const core = new import_echo_db.ObjectCore();
@@ -149,6 +183,7 @@ var MigrationBuilder = class {
149
183
  core.initNewObject(props);
150
184
  core.setType((0, import_echo_schema.requireTypeReference)(schema));
151
185
  const newHandle = this._repo.create({
186
+ version: import_echo_protocol.SpaceDocVersion.CURRENT,
152
187
  access: {
153
188
  spaceKey: this._space.key.toHex()
154
189
  },
@@ -157,11 +192,14 @@ var MigrationBuilder = class {
157
192
  }
158
193
  });
159
194
  this._newLinks[core.id] = newHandle.url;
195
+ this._addHandleToFlushList(newHandle);
196
+ return core;
197
+ }
198
+ _addHandleToFlushList(handle) {
160
199
  this._flushStates.push({
161
- documentId: newHandle.documentId,
162
- heads: (0, import_automerge.getHeads)(newHandle.docSync())
200
+ documentId: handle.documentId,
201
+ heads: import_automerge.next.getHeads(handle.docSync())
163
202
  });
164
- return core;
165
203
  }
166
204
  };
167
205
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/migrations/src/migrations.ts";
@@ -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 { getHeads, type Doc } from '@dxos/automerge/automerge';\nimport { type AnyDocumentId, type DocHandle, type Repo } from '@dxos/automerge/automerge-repo';\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { type AutomergeContext, ObjectCore } from '@dxos/echo-db';\nimport { type ObjectStructure, type SpaceDoc } from '@dxos/echo-protocol';\nimport { requireTypeReference, type S } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';\n\nexport class MigrationBuilder {\n private readonly _repo: Repo;\n private readonly _automergeContext: AutomergeContext;\n private readonly _rootDoc: Doc<SpaceDoc>;\n\n // echoId -> automergeUrl\n private readonly _newLinks: Record<string, string> = {};\n private readonly _flushStates: FlushRequest.DocState[] = [];\n private readonly _deleteObjects: string[] = [];\n\n private _newRoot?: DocHandle<SpaceDoc> = undefined;\n\n constructor(private readonly _space: Space) {\n this._repo = this._space.db.coreDatabase.automerge.repo;\n this._automergeContext = this._space.db.coreDatabase.automerge;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.db.coreDatabase as any)._automergeDocLoader\n .getSpaceRootDocHandle()\n .docSync() as Doc<SpaceDoc>;\n }\n\n async findObject(id: string): Promise<ObjectStructure | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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.docSync() as Doc<SpaceDoc>;\n return doc.objects?.[id];\n }\n\n async migrateObject(\n id: string,\n migrate: (objectStructure: ObjectStructure) => { schema: S.Schema<any>; props: any },\n ) {\n const objectStructure = await this.findObject(id);\n if (!objectStructure) {\n return;\n }\n\n const { schema, props } = migrate(objectStructure);\n this._createObject({ id, schema, props });\n }\n\n addObject(schema: S.Schema<any>, props: any) {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n deleteObject(id: string) {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void) {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n this._newRoot.change((doc: SpaceDoc) => {\n const propertiesStructure = doc.objects?.[this._space.properties.id];\n propertiesStructure && changeFn(propertiesStructure);\n });\n this._flushStates.push({\n documentId: this._newRoot.documentId,\n heads: getHeads(this._newRoot.docSync()),\n });\n }\n\n /**\n * @internal\n */\n async _commit() {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._automergeContext.flush({\n states: this._flushStates,\n });\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 _buildNewRoot() {\n const previousLinks = { ...(this._rootDoc.links ?? {}) };\n for (const id of this._deleteObjects) {\n delete previousLinks[id];\n }\n\n this._newRoot = this._repo.create<SpaceDoc>({\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: this._rootDoc.objects,\n links: {\n ...previousLinks,\n ...this._newLinks,\n },\n });\n this._flushStates.push({\n documentId: this._newRoot.documentId,\n heads: getHeads(this._newRoot.docSync()),\n });\n }\n\n private _createObject({ id, schema, props }: { id?: string; schema: S.Schema<any>; props: any }) {\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<SpaceDoc>({\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [core.id]: core.getDoc(),\n },\n });\n this._newLinks[core.id] = newHandle.url;\n this._flushStates.push({\n documentId: newHandle.documentId,\n heads: getHeads(newHandle.docSync()),\n });\n\n return core;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, create, 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 = create<{ 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) {\n return this._state.running.includes(space.key.toHex());\n }\n\n static define(namespace: string, migrations: Migration[]) {\n this.namespace = namespace;\n this.migrations = migrations;\n }\n\n static async migrate(space: Space, targetVersion?: string | number) {\n invariant(!this.running(space), 'Migration already running');\n invariant(this.versionProperty, 'Migrations namespace not set');\n invariant(space.state.get() === SpaceState.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", "constructor", "_space", "_newLinks", "_flushStates", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "automerge", "repo", "_automergeContext", "_rootDoc", "_automergeDocLoader", "getSpaceRootDocHandle", "docSync", "findObject", "id", "documentId", "links", "docHandle", "find", "whenReady", "doc", "objects", "migrateObject", "migrate", "objectStructure", "schema", "props", "_createObject", "addObject", "core", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "invariant", "change", "propertiesStructure", "properties", "heads", "getHeads", "_commit", "flush", "states", "internal", "createEpoch", "migration", "CreateEpochRequest", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "url", "previousLinks", "create", "access", "spaceKey", "key", "toHex", "ObjectCore", "initNewObject", "setType", "requireTypeReference", "newHandle", "getDoc", "Migrations", "migrations", "_state", "running", "versionProperty", "namespace", "targetVersion", "length", "version", "space", "includes", "define", "state", "get", "SpaceState", "READY", "currentVersion", "currentIndex", "findIndex", "m", "i", "targetIndex", "slice", "builder", "next", "data", "splice", "indexOf"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Doc, next as am } from '@dxos/automerge/automerge';\nimport { type AnyDocumentId, type DocHandle, type Repo } from '@dxos/automerge/automerge-repo';\nimport { type Space } from '@dxos/client/echo';\nimport { CreateEpochRequest } from '@dxos/client/halo';\nimport { type AutomergeContext, ObjectCore, migrateDocument } from '@dxos/echo-db';\nimport { SpaceDocVersion, encodeReference, type ObjectStructure, type SpaceDoc, Reference } from '@dxos/echo-protocol';\nimport { requireTypeReference, type S } from '@dxos/echo-schema';\nimport { invariant } from '@dxos/invariant';\nimport { type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';\nimport { type MaybePromise } from '@dxos/util';\n\nexport class MigrationBuilder {\n private readonly _repo: Repo;\n private readonly _automergeContext: AutomergeContext;\n private readonly _rootDoc: Doc<SpaceDoc>;\n\n // echoId -> automergeUrl\n private readonly _newLinks: Record<string, string> = {};\n private readonly _flushStates: FlushRequest.DocState[] = [];\n private readonly _deleteObjects: string[] = [];\n\n private _newRoot?: DocHandle<SpaceDoc> = undefined;\n\n constructor(private readonly _space: Space) {\n this._repo = this._space.db.coreDatabase.automerge.repo;\n this._automergeContext = this._space.db.coreDatabase.automerge;\n // TODO(wittjosiah): Accessing private API.\n this._rootDoc = (this._space.db.coreDatabase as any)._automergeDocLoader\n .getSpaceRootDocHandle()\n .docSync() as Doc<SpaceDoc>;\n }\n\n async findObject(id: string): Promise<ObjectStructure | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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.docSync() as Doc<SpaceDoc>;\n return doc.objects?.[id];\n }\n\n async migrateObject(\n id: string,\n migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema: S.Schema<any>; props: any }>,\n ) {\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: SpaceDoc = {\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.docSync() as Doc<SpaceDoc>, newState);\n const newHandle = this._repo.import<SpaceDoc>(am.save(migratedDoc));\n this._newLinks[id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n }\n\n async addObject(schema: S.Schema<any>, props: any) {\n const core = this._createObject({ schema, props });\n return core.id;\n }\n\n createReference(id: string) {\n return encodeReference(new Reference(id));\n }\n\n deleteObject(id: string) {\n this._deleteObjects.push(id);\n }\n\n changeProperties(changeFn: (properties: ObjectStructure) => void) {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n this._newRoot.change((doc: SpaceDoc) => {\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() {\n if (!this._newRoot) {\n this._buildNewRoot();\n }\n invariant(this._newRoot, 'New root not created');\n\n await this._automergeContext.flush({\n states: this._flushStates,\n });\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<DocHandle<SpaceDoc> | undefined> {\n const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) 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() {\n const previousLinks = { ...(this._rootDoc.links ?? {}) };\n for (const id of this._deleteObjects) {\n delete previousLinks[id];\n }\n\n this._newRoot = this._repo.create<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: this._rootDoc.objects,\n links: {\n ...previousLinks,\n ...this._newLinks,\n },\n });\n this._addHandleToFlushList(this._newRoot);\n }\n\n private _createObject({ id, schema, props }: { id?: string; schema: S.Schema<any>; props: any }) {\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<SpaceDoc>({\n version: SpaceDocVersion.CURRENT,\n access: {\n spaceKey: this._space.key.toHex(),\n },\n objects: {\n [core.id]: core.getDoc(),\n },\n });\n this._newLinks[core.id] = newHandle.url;\n this._addHandleToFlushList(newHandle);\n\n return core;\n }\n\n private _addHandleToFlushList(handle: DocHandle<any>) {\n this._flushStates.push({\n documentId: handle.documentId,\n heads: am.getHeads(handle.docSync()),\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Space, create, 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 = create<{ 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) {\n return this._state.running.includes(space.key.toHex());\n }\n\n static define(namespace: string, migrations: Migration[]) {\n this.namespace = namespace;\n this.migrations = migrations;\n }\n\n static async migrate(space: Space, targetVersion?: string | number) {\n invariant(!this.running(space), 'Migration already running');\n invariant(this.versionProperty, 'Migrations namespace not set');\n invariant(space.state.get() === SpaceState.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", "constructor", "_space", "_newLinks", "_flushStates", "_deleteObjects", "_newRoot", "undefined", "_repo", "db", "coreDatabase", "automerge", "repo", "_automergeContext", "_rootDoc", "_automergeDocLoader", "getSpaceRootDocHandle", "docSync", "findObject", "id", "documentId", "links", "docHandle", "find", "whenReady", "doc", "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", "deleteObject", "push", "changeProperties", "changeFn", "_buildNewRoot", "change", "propertiesStructure", "properties", "_commit", "flush", "states", "internal", "createEpoch", "migration", "CreateEpochRequest", "Migration", "REPLACE_AUTOMERGE_ROOT", "automergeRootUrl", "previousLinks", "create", "ObjectCore", "initNewObject", "setType", "getDoc", "handle", "heads", "getHeads", "Migrations", "migrations", "_state", "running", "versionProperty", "namespace", "targetVersion", "length", "space", "includes", "define", "state", "get", "SpaceState", "READY", "currentVersion", "currentIndex", "findIndex", "m", "i", "targetIndex", "slice", "builder", "next", "splice", "indexOf"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":16903,"imports":[{"path":"@dxos/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-schema","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/migrations/src/migrations.ts":{"bytes":9817,"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":698,"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":12698},"packages/sdk/migrations/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/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-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":3783},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2745}},"bytes":6706}}}
1
+ {"inputs":{"packages/sdk/migrations/src/migration-builder.ts":{"bytes":21641,"imports":[{"path":"@dxos/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":9817,"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":698,"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":15103},"packages/sdk/migrations/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/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":4976},"packages/sdk/migrations/src/index.ts":{"bytesInOutput":0},"packages/sdk/migrations/src/migrations.ts":{"bytesInOutput":2745}},"bytes":7899}}}
@@ -1,6 +1,7 @@
1
1
  import { type Space } from '@dxos/client/echo';
2
2
  import { type ObjectStructure } from '@dxos/echo-protocol';
3
3
  import { type S } from '@dxos/echo-schema';
4
+ import { type MaybePromise } from '@dxos/util';
4
5
  export declare class MigrationBuilder {
5
6
  private readonly _space;
6
7
  private readonly _repo;
@@ -12,14 +13,17 @@ export declare class MigrationBuilder {
12
13
  private _newRoot?;
13
14
  constructor(_space: Space);
14
15
  findObject(id: string): Promise<ObjectStructure | undefined>;
15
- migrateObject(id: string, migrate: (objectStructure: ObjectStructure) => {
16
+ migrateObject(id: string, migrate: (objectStructure: ObjectStructure) => MaybePromise<{
16
17
  schema: S.Schema<any>;
17
18
  props: any;
18
- }): Promise<void>;
19
- addObject(schema: S.Schema<any>, props: any): string;
19
+ }>): Promise<void>;
20
+ addObject(schema: S.Schema<any>, props: any): Promise<string>;
21
+ createReference(id: string): import("@dxos/echo-protocol").EncodedReference;
20
22
  deleteObject(id: string): void;
21
23
  changeProperties(changeFn: (properties: ObjectStructure) => void): void;
24
+ private _findObjectContainingHandle;
22
25
  private _buildNewRoot;
23
26
  private _createObject;
27
+ private _addHandleToFlushList;
24
28
  }
25
29
  //# sourceMappingURL=migration-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-builder.d.ts","sourceRoot":"","sources":["../../../src/migration-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAE,KAAK,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAwB,KAAK,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAIjE,qBAAa,gBAAgB;IAYf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAGzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,OAAO,CAAC,QAAQ,CAAC,CAAkC;gBAEtB,MAAM,EAAE,KAAK;IASpC,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;QAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE;IAWtF,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG;IAK3C,YAAY,CAAC,EAAE,EAAE,MAAM;IAIvB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI;IAoChE,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,aAAa;CAwBtB"}
1
+ {"version":3,"file":"migration-builder.d.ts","sourceRoot":"","sources":["../../../src/migration-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EAAoC,KAAK,eAAe,EAA4B,MAAM,qBAAqB,CAAC;AACvH,OAAO,EAAwB,KAAK,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAGjE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,qBAAa,gBAAgB;IAYf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAGzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,OAAO,CAAC,QAAQ,CAAC,CAAkC;gBAEtB,MAAM,EAAE,KAAK;IASpC,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,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IAmC9F,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG;IAKjD,eAAe,CAAC,EAAE,EAAE,MAAM;IAI1B,YAAY,CAAC,EAAE,EAAE,MAAM;IAIvB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI;YAiClD,2BAA2B;IAWzC,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,qBAAqB;CAM9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/migrations",
3
- "version": "0.5.9-main.1c1903d",
3
+ "version": "0.5.9-main.1ea2105",
4
4
  "description": "",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -20,15 +20,15 @@
20
20
  "src"
21
21
  ],
22
22
  "dependencies": {
23
- "@dxos/automerge": "0.5.9-main.1c1903d",
24
- "@dxos/client": "0.5.9-main.1c1903d",
25
- "@dxos/echo-db": "0.5.9-main.1c1903d",
26
- "@dxos/echo-schema": "0.5.9-main.1c1903d",
27
- "@dxos/echo-protocol": "0.5.9-main.1c1903d",
28
- "@dxos/invariant": "0.5.9-main.1c1903d",
29
- "@dxos/log": "0.5.9-main.1c1903d",
30
- "@dxos/protocols": "0.5.9-main.1c1903d",
31
- "@dxos/util": "0.5.9-main.1c1903d"
23
+ "@dxos/automerge": "0.5.9-main.1ea2105",
24
+ "@dxos/echo-db": "0.5.9-main.1ea2105",
25
+ "@dxos/echo-protocol": "0.5.9-main.1ea2105",
26
+ "@dxos/echo-schema": "0.5.9-main.1ea2105",
27
+ "@dxos/invariant": "0.5.9-main.1ea2105",
28
+ "@dxos/client": "0.5.9-main.1ea2105",
29
+ "@dxos/log": "0.5.9-main.1ea2105",
30
+ "@dxos/protocols": "0.5.9-main.1ea2105",
31
+ "@dxos/util": "0.5.9-main.1ea2105"
32
32
  },
33
33
  "devDependencies": {},
34
34
  "publishConfig": {
@@ -2,15 +2,16 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { getHeads, type Doc } from '@dxos/automerge/automerge';
5
+ import { type Doc, next as am } from '@dxos/automerge/automerge';
6
6
  import { type AnyDocumentId, type DocHandle, type Repo } from '@dxos/automerge/automerge-repo';
7
7
  import { type Space } from '@dxos/client/echo';
8
8
  import { CreateEpochRequest } from '@dxos/client/halo';
9
- import { type AutomergeContext, ObjectCore } from '@dxos/echo-db';
10
- import { type ObjectStructure, type SpaceDoc } from '@dxos/echo-protocol';
9
+ import { type AutomergeContext, ObjectCore, migrateDocument } from '@dxos/echo-db';
10
+ import { SpaceDocVersion, encodeReference, type ObjectStructure, type SpaceDoc, Reference } from '@dxos/echo-protocol';
11
11
  import { requireTypeReference, type S } from '@dxos/echo-schema';
12
12
  import { invariant } from '@dxos/invariant';
13
13
  import { type FlushRequest } from '@dxos/protocols/proto/dxos/echo/service';
14
+ import { type MaybePromise } from '@dxos/util';
14
15
 
15
16
  export class MigrationBuilder {
16
17
  private readonly _repo: Repo;
@@ -47,22 +48,50 @@ export class MigrationBuilder {
47
48
 
48
49
  async migrateObject(
49
50
  id: string,
50
- migrate: (objectStructure: ObjectStructure) => { schema: S.Schema<any>; props: any },
51
+ migrate: (objectStructure: ObjectStructure) => MaybePromise<{ schema: S.Schema<any>; props: any }>,
51
52
  ) {
52
53
  const objectStructure = await this.findObject(id);
53
54
  if (!objectStructure) {
54
55
  return;
55
56
  }
56
57
 
57
- const { schema, props } = migrate(objectStructure);
58
- this._createObject({ id, schema, props });
58
+ const { schema, props } = await migrate(objectStructure);
59
+
60
+ const oldHandle = await this._findObjectContainingHandle(id);
61
+ invariant(oldHandle);
62
+
63
+ const newState: SpaceDoc = {
64
+ version: SpaceDocVersion.CURRENT,
65
+ access: {
66
+ spaceKey: this._space.key.toHex(),
67
+ },
68
+ objects: {
69
+ [id]: {
70
+ system: {
71
+ type: encodeReference(requireTypeReference(schema)),
72
+ },
73
+ data: props,
74
+ meta: {
75
+ keys: [],
76
+ },
77
+ },
78
+ },
79
+ };
80
+ const migratedDoc = migrateDocument(oldHandle.docSync() as Doc<SpaceDoc>, newState);
81
+ const newHandle = this._repo.import<SpaceDoc>(am.save(migratedDoc));
82
+ this._newLinks[id] = newHandle.url;
83
+ this._addHandleToFlushList(newHandle);
59
84
  }
60
85
 
61
- addObject(schema: S.Schema<any>, props: any) {
86
+ async addObject(schema: S.Schema<any>, props: any) {
62
87
  const core = this._createObject({ schema, props });
63
88
  return core.id;
64
89
  }
65
90
 
91
+ createReference(id: string) {
92
+ return encodeReference(new Reference(id));
93
+ }
94
+
66
95
  deleteObject(id: string) {
67
96
  this._deleteObjects.push(id);
68
97
  }
@@ -77,10 +106,7 @@ export class MigrationBuilder {
77
106
  const propertiesStructure = doc.objects?.[this._space.properties.id];
78
107
  propertiesStructure && changeFn(propertiesStructure);
79
108
  });
80
- this._flushStates.push({
81
- documentId: this._newRoot.documentId,
82
- heads: getHeads(this._newRoot.docSync()),
83
- });
109
+ this._addHandleToFlushList(this._newRoot);
84
110
  }
85
111
 
86
112
  /**
@@ -103,6 +129,17 @@ export class MigrationBuilder {
103
129
  });
104
130
  }
105
131
 
132
+ private async _findObjectContainingHandle(id: string): Promise<DocHandle<SpaceDoc> | undefined> {
133
+ const documentId = (this._rootDoc.links?.[id] || this._newLinks[id]) as AnyDocumentId | undefined;
134
+ const docHandle = documentId && this._repo.find(documentId);
135
+ if (!docHandle) {
136
+ return undefined;
137
+ }
138
+
139
+ await docHandle.whenReady();
140
+ return docHandle;
141
+ }
142
+
106
143
  private _buildNewRoot() {
107
144
  const previousLinks = { ...(this._rootDoc.links ?? {}) };
108
145
  for (const id of this._deleteObjects) {
@@ -110,6 +147,7 @@ export class MigrationBuilder {
110
147
  }
111
148
 
112
149
  this._newRoot = this._repo.create<SpaceDoc>({
150
+ version: SpaceDocVersion.CURRENT,
113
151
  access: {
114
152
  spaceKey: this._space.key.toHex(),
115
153
  },
@@ -119,10 +157,7 @@ export class MigrationBuilder {
119
157
  ...this._newLinks,
120
158
  },
121
159
  });
122
- this._flushStates.push({
123
- documentId: this._newRoot.documentId,
124
- heads: getHeads(this._newRoot.docSync()),
125
- });
160
+ this._addHandleToFlushList(this._newRoot);
126
161
  }
127
162
 
128
163
  private _createObject({ id, schema, props }: { id?: string; schema: S.Schema<any>; props: any }) {
@@ -134,6 +169,7 @@ export class MigrationBuilder {
134
169
  core.initNewObject(props);
135
170
  core.setType(requireTypeReference(schema));
136
171
  const newHandle = this._repo.create<SpaceDoc>({
172
+ version: SpaceDocVersion.CURRENT,
137
173
  access: {
138
174
  spaceKey: this._space.key.toHex(),
139
175
  },
@@ -142,11 +178,15 @@ export class MigrationBuilder {
142
178
  },
143
179
  });
144
180
  this._newLinks[core.id] = newHandle.url;
145
- this._flushStates.push({
146
- documentId: newHandle.documentId,
147
- heads: getHeads(newHandle.docSync()),
148
- });
181
+ this._addHandleToFlushList(newHandle);
149
182
 
150
183
  return core;
151
184
  }
185
+
186
+ private _addHandleToFlushList(handle: DocHandle<any>) {
187
+ this._flushStates.push({
188
+ documentId: handle.documentId,
189
+ heads: am.getHeads(handle.docSync()),
190
+ });
191
+ }
152
192
  }
@@ -16,7 +16,7 @@ Migrations.define('test', [
16
16
  {
17
17
  version: '1970-01-01',
18
18
  next: async ({ builder }) => {
19
- builder.addObject(Expando, { namespace: 'test', count: 1 });
19
+ await builder.addObject(Expando, { namespace: 'test', count: 1 });
20
20
  },
21
21
  },
22
22
  {