@dxos/echo-pipeline 0.7.2 → 0.7.3-staging.0905f03
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/{chunk-RRKGEIVZ.mjs → chunk-LZK5YFYE.mjs} +13 -13
- package/dist/lib/browser/{chunk-RRKGEIVZ.mjs.map → chunk-LZK5YFYE.mjs.map} +2 -2
- package/dist/lib/browser/index.mjs +56 -62
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +1 -1
- package/dist/lib/node/{chunk-6KAVD3GU.cjs → chunk-MACQJ2EP.cjs} +16 -16
- package/dist/lib/node/{chunk-6KAVD3GU.cjs.map → chunk-MACQJ2EP.cjs.map} +2 -2
- package/dist/lib/node/index.cjs +80 -88
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +10 -10
- package/dist/lib/node-esm/{chunk-4QES5F4H.mjs → chunk-JIZPSASG.mjs} +13 -13
- package/dist/lib/node-esm/{chunk-4QES5F4H.mjs.map → chunk-JIZPSASG.mjs.map} +2 -2
- package/dist/lib/node-esm/index.mjs +56 -62
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +1 -1
- package/dist/types/src/automerge/automerge-host.d.ts +7 -1
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/db-host/echo-host.d.ts +3 -2
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
- package/dist/types/src/db-host/index.d.ts +0 -1
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/{db-host/migration.d.ts → util.d.ts} +1 -3
- package/dist/types/src/util.d.ts.map +1 -0
- package/package.json +35 -34
- package/src/automerge/automerge-host.ts +12 -3
- package/src/db-host/echo-host.ts +4 -1
- package/src/db-host/index.ts +0 -1
- package/src/edge/echo-edge-replicator.test.ts +74 -31
- package/src/edge/echo-edge-replicator.ts +17 -3
- package/src/index.ts +1 -0
- package/src/space/space.ts +1 -0
- package/src/util.ts +19 -0
- package/dist/types/src/db-host/migration.d.ts.map +0 -1
- package/src/db-host/migration.ts +0 -57
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo-pipeline",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-staging.0905f03",
|
|
4
4
|
"description": "ECHO database.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -37,43 +37,44 @@
|
|
|
37
37
|
"crc-32": "^1.2.2",
|
|
38
38
|
"level-transcoder": "^1.0.1",
|
|
39
39
|
"lodash.isequal": "^4.5.0",
|
|
40
|
-
"@dxos/async": "0.7.
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/credentials": "0.7.
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/echo-protocol": "0.7.
|
|
48
|
-
"@dxos/echo-schema": "0.7.
|
|
49
|
-
"@dxos/edge-client": "0.7.
|
|
50
|
-
"@dxos/feed-store": "0.7.
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/kv-store": "0.7.
|
|
56
|
-
"@dxos/log": "0.7.
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/
|
|
60
|
-
"@dxos/node-std": "0.7.
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/teleport
|
|
64
|
-
"@dxos/teleport": "0.7.
|
|
65
|
-
"@dxos/teleport-extension-gossip": "0.7.
|
|
66
|
-
"@dxos/teleport-extension-object-sync": "0.7.
|
|
67
|
-
"@dxos/
|
|
68
|
-
"@dxos/timeframe": "0.7.
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/typings": "0.7.
|
|
71
|
-
"@dxos/util": "0.7.
|
|
40
|
+
"@dxos/async": "0.7.3-staging.0905f03",
|
|
41
|
+
"@dxos/codec-protobuf": "0.7.3-staging.0905f03",
|
|
42
|
+
"@dxos/automerge": "0.7.3-staging.0905f03",
|
|
43
|
+
"@dxos/context": "0.7.3-staging.0905f03",
|
|
44
|
+
"@dxos/credentials": "0.7.3-staging.0905f03",
|
|
45
|
+
"@dxos/crypto": "0.7.3-staging.0905f03",
|
|
46
|
+
"@dxos/debug": "0.7.3-staging.0905f03",
|
|
47
|
+
"@dxos/echo-protocol": "0.7.3-staging.0905f03",
|
|
48
|
+
"@dxos/echo-schema": "0.7.3-staging.0905f03",
|
|
49
|
+
"@dxos/edge-client": "0.7.3-staging.0905f03",
|
|
50
|
+
"@dxos/feed-store": "0.7.3-staging.0905f03",
|
|
51
|
+
"@dxos/indexing": "0.7.3-staging.0905f03",
|
|
52
|
+
"@dxos/hypercore": "0.7.3-staging.0905f03",
|
|
53
|
+
"@dxos/keyring": "0.7.3-staging.0905f03",
|
|
54
|
+
"@dxos/invariant": "0.7.3-staging.0905f03",
|
|
55
|
+
"@dxos/kv-store": "0.7.3-staging.0905f03",
|
|
56
|
+
"@dxos/log": "0.7.3-staging.0905f03",
|
|
57
|
+
"@dxos/messaging": "0.7.3-staging.0905f03",
|
|
58
|
+
"@dxos/keys": "0.7.3-staging.0905f03",
|
|
59
|
+
"@dxos/network-manager": "0.7.3-staging.0905f03",
|
|
60
|
+
"@dxos/node-std": "0.7.3-staging.0905f03",
|
|
61
|
+
"@dxos/random-access-storage": "0.7.3-staging.0905f03",
|
|
62
|
+
"@dxos/protocols": "0.7.3-staging.0905f03",
|
|
63
|
+
"@dxos/teleport": "0.7.3-staging.0905f03",
|
|
64
|
+
"@dxos/teleport-extension-automerge-replicator": "0.7.3-staging.0905f03",
|
|
65
|
+
"@dxos/teleport-extension-gossip": "0.7.3-staging.0905f03",
|
|
66
|
+
"@dxos/teleport-extension-object-sync": "0.7.3-staging.0905f03",
|
|
67
|
+
"@dxos/tracing": "0.7.3-staging.0905f03",
|
|
68
|
+
"@dxos/timeframe": "0.7.3-staging.0905f03",
|
|
69
|
+
"@dxos/teleport-extension-replicator": "0.7.3-staging.0905f03",
|
|
70
|
+
"@dxos/typings": "0.7.3-staging.0905f03",
|
|
71
|
+
"@dxos/util": "0.7.3-staging.0905f03"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@types/lodash.isequal": "^4.5.0",
|
|
75
75
|
"fast-check": "^3.19.0",
|
|
76
|
-
"
|
|
76
|
+
"get-port-please": "^3.1.1",
|
|
77
|
+
"@dxos/test-utils": "0.7.3-staging.0905f03"
|
|
77
78
|
},
|
|
78
79
|
"publishConfig": {
|
|
79
80
|
"access": "public"
|
|
@@ -42,11 +42,18 @@ import { type EchoReplicator, type RemoteDocumentExistenceCheckParams } from './
|
|
|
42
42
|
import { HeadsStore } from './heads-store';
|
|
43
43
|
import { LevelDBStorageAdapter, type BeforeSaveParams } from './leveldb-storage-adapter';
|
|
44
44
|
|
|
45
|
+
export type PeerIdProvider = () => string | undefined;
|
|
46
|
+
|
|
45
47
|
export type AutomergeHostParams = {
|
|
46
48
|
db: LevelDB;
|
|
47
49
|
|
|
48
50
|
indexMetadataStore: IndexMetadataStore;
|
|
49
51
|
dataMonitor?: EchoDataMonitor;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Used for creating stable ids. A random key is generated on open, if no value is provided.
|
|
55
|
+
*/
|
|
56
|
+
peerIdProvider?: PeerIdProvider;
|
|
50
57
|
};
|
|
51
58
|
|
|
52
59
|
export type LoadDocOptions = {
|
|
@@ -82,9 +89,11 @@ export class AutomergeHost extends Resource {
|
|
|
82
89
|
@trace.info()
|
|
83
90
|
private _peerId!: PeerId;
|
|
84
91
|
|
|
92
|
+
private readonly _peerIdProvider?: PeerIdProvider;
|
|
93
|
+
|
|
85
94
|
public readonly collectionStateUpdated = new Event<{ collectionId: CollectionId }>();
|
|
86
95
|
|
|
87
|
-
constructor({ db, indexMetadataStore, dataMonitor }: AutomergeHostParams) {
|
|
96
|
+
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider }: AutomergeHostParams) {
|
|
88
97
|
super();
|
|
89
98
|
this._db = db;
|
|
90
99
|
this._storage = new LevelDBStorageAdapter({
|
|
@@ -104,11 +113,11 @@ export class AutomergeHost extends Resource {
|
|
|
104
113
|
});
|
|
105
114
|
this._headsStore = new HeadsStore({ db: db.sublevel('heads') });
|
|
106
115
|
this._indexMetadataStore = indexMetadataStore;
|
|
116
|
+
this._peerIdProvider = peerIdProvider;
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
protected override async _open() {
|
|
110
|
-
|
|
111
|
-
this._peerId = `host-${PublicKey.random().toHex()}` as PeerId;
|
|
120
|
+
this._peerId = `host-${this._peerIdProvider?.() ?? PublicKey.random().toHex()}` as PeerId;
|
|
112
121
|
|
|
113
122
|
await this._storage.open?.();
|
|
114
123
|
|
package/src/db-host/echo-host.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
type EchoReplicator,
|
|
34
34
|
type CollectionSyncState,
|
|
35
35
|
type EchoDataStats,
|
|
36
|
+
type PeerIdProvider,
|
|
36
37
|
} from '../automerge';
|
|
37
38
|
|
|
38
39
|
const INDEXER_CONFIG: IndexConfig = {
|
|
@@ -42,6 +43,7 @@ const INDEXER_CONFIG: IndexConfig = {
|
|
|
42
43
|
|
|
43
44
|
export type EchoHostParams = {
|
|
44
45
|
kv: LevelDB;
|
|
46
|
+
peerIdProvider?: PeerIdProvider;
|
|
45
47
|
};
|
|
46
48
|
|
|
47
49
|
/**
|
|
@@ -59,7 +61,7 @@ export class EchoHost extends Resource {
|
|
|
59
61
|
private readonly _spaceStateManager = new SpaceStateManager();
|
|
60
62
|
private readonly _echoDataMonitor: EchoDataMonitor;
|
|
61
63
|
|
|
62
|
-
constructor({ kv }: EchoHostParams) {
|
|
64
|
+
constructor({ kv, peerIdProvider }: EchoHostParams) {
|
|
63
65
|
super();
|
|
64
66
|
|
|
65
67
|
this._indexMetadataStore = new IndexMetadataStore({ db: kv.sublevel('index-metadata') });
|
|
@@ -70,6 +72,7 @@ export class EchoHost extends Resource {
|
|
|
70
72
|
db: kv,
|
|
71
73
|
dataMonitor: this._echoDataMonitor,
|
|
72
74
|
indexMetadataStore: this._indexMetadataStore,
|
|
75
|
+
peerIdProvider,
|
|
73
76
|
});
|
|
74
77
|
|
|
75
78
|
this._indexer = new Indexer({
|
package/src/db-host/index.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { getRandomPort } from 'get-port-please';
|
|
6
|
+
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
7
|
|
|
7
8
|
import { Event } from '@dxos/async';
|
|
8
9
|
import { cbor } from '@dxos/automerge/automerge-repo';
|
|
@@ -16,69 +17,111 @@ import type { Peer } from '@dxos/protocols/proto/dxos/edge/messenger';
|
|
|
16
17
|
import { openAndClose } from '@dxos/test-utils';
|
|
17
18
|
|
|
18
19
|
import { EchoEdgeReplicator } from './echo-edge-replicator';
|
|
19
|
-
import type { EchoReplicatorContext } from '../automerge';
|
|
20
|
+
import type { EchoReplicatorContext, ReplicatorConnection } from '../automerge';
|
|
20
21
|
|
|
21
22
|
describe('EchoEdgeReplicator', () => {
|
|
22
|
-
test('reconnects', async (
|
|
23
|
-
const {
|
|
24
|
-
onTestFinished(cleanup);
|
|
25
|
-
const client = new EdgeClient(await createEphemeralEdgeIdentity(), { socketEndpoint: endpoint });
|
|
26
|
-
await openAndClose(client);
|
|
23
|
+
test('reconnects', async () => {
|
|
24
|
+
const { client, server } = await createClientServer();
|
|
27
25
|
|
|
28
26
|
const spaceId = SpaceId.random();
|
|
29
27
|
|
|
30
|
-
const replicator = new EchoEdgeReplicator({ edgeConnection: client });
|
|
31
28
|
const { context, connectionOpen } = createMockContext();
|
|
32
|
-
await
|
|
29
|
+
const replicator = await connectReplicator(client, context);
|
|
33
30
|
await replicator.connectToSpace(spaceId);
|
|
34
31
|
|
|
35
32
|
client.setIdentity(await createEphemeralEdgeIdentity());
|
|
36
33
|
await connectionOpen.waitForCount(1);
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
-
identityKey: client.identityKey,
|
|
42
|
-
peerKey: client.peerKey,
|
|
43
|
-
},
|
|
44
|
-
spaceId,
|
|
45
|
-
),
|
|
46
|
-
);
|
|
35
|
+
const forbidden = createForbiddenMessage({ identityKey: client.identityKey, peerKey: client.peerKey }, spaceId);
|
|
36
|
+
server.sendMessage(forbidden);
|
|
47
37
|
await connectionOpen.waitForCount(1);
|
|
48
38
|
|
|
49
39
|
// Double restart to check for race conditions.
|
|
50
40
|
client.setIdentity(await createEphemeralEdgeIdentity());
|
|
51
|
-
sendMessage(
|
|
52
|
-
createForbiddenMessage(
|
|
53
|
-
{
|
|
54
|
-
identityKey: client.identityKey,
|
|
55
|
-
peerKey: client.peerKey,
|
|
56
|
-
},
|
|
57
|
-
spaceId,
|
|
58
|
-
),
|
|
59
|
-
);
|
|
41
|
+
server.sendMessage(forbidden);
|
|
60
42
|
await connectionOpen.waitForCount(1);
|
|
61
43
|
|
|
62
44
|
await replicator.disconnect();
|
|
63
45
|
});
|
|
46
|
+
|
|
47
|
+
describe('shouldAdvertise', () => {
|
|
48
|
+
test('true if space document belongs to connection space', async () => {
|
|
49
|
+
const { client } = await createClientServer();
|
|
50
|
+
|
|
51
|
+
const spaceId = SpaceId.random();
|
|
52
|
+
const documentId = PublicKey.random().toHex();
|
|
53
|
+
const { context, openConnections } = createMockContext({
|
|
54
|
+
documentSpaceId: { [documentId]: spaceId },
|
|
55
|
+
});
|
|
56
|
+
const replicator = await connectReplicator(client, context);
|
|
57
|
+
await replicator.connectToSpace(spaceId);
|
|
58
|
+
|
|
59
|
+
await expect.poll(() => openConnections.length === 1).toBeTruthy();
|
|
60
|
+
expect(openConnections[0].shouldAdvertise({ documentId })).toBeTruthy();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('checks remote collection if space id can not be resolved', async () => {
|
|
64
|
+
const { client } = await createClientServer();
|
|
65
|
+
|
|
66
|
+
const spaceId = SpaceId.random();
|
|
67
|
+
const documentId = PublicKey.random().toHex();
|
|
68
|
+
const remoteCollections: { [peerId: string]: { [documentId: string]: boolean } } = {};
|
|
69
|
+
const { context, openConnections } = createMockContext({ remoteCollections });
|
|
70
|
+
const replicator = await connectReplicator(client, context);
|
|
71
|
+
await replicator.connectToSpace(spaceId);
|
|
72
|
+
|
|
73
|
+
await expect.poll(() => openConnections.length === 1).toBeTruthy();
|
|
74
|
+
const connection = openConnections[0];
|
|
75
|
+
expect(await connection.shouldAdvertise({ documentId })).toBeFalsy();
|
|
76
|
+
remoteCollections[connection.peerId] = { [documentId]: true };
|
|
77
|
+
expect(await connection.shouldAdvertise({ documentId })).toBeTruthy();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const connectReplicator = async (client: EdgeClient, context: EchoReplicatorContext) => {
|
|
82
|
+
const replicator = new EchoEdgeReplicator({ edgeConnection: client });
|
|
83
|
+
await replicator.connect(context);
|
|
84
|
+
onTestFinished(() => replicator.disconnect());
|
|
85
|
+
return replicator;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const createClientServer = async () => {
|
|
89
|
+
const server = await createTestEdgeWsServer(await getRandomPort());
|
|
90
|
+
onTestFinished(server.cleanup);
|
|
91
|
+
const client = new EdgeClient(await createEphemeralEdgeIdentity(), { socketEndpoint: server.endpoint });
|
|
92
|
+
await openAndClose(client);
|
|
93
|
+
return { client, server };
|
|
94
|
+
};
|
|
64
95
|
});
|
|
65
96
|
|
|
66
|
-
const createMockContext = (
|
|
97
|
+
const createMockContext = (args?: {
|
|
98
|
+
remoteCollections?: { [peerId: string]: { [documentId: string]: boolean } };
|
|
99
|
+
documentSpaceId?: { [documentId: string]: SpaceId };
|
|
100
|
+
}) => {
|
|
67
101
|
const connectionOpen = new Event();
|
|
102
|
+
const openConnections: ReplicatorConnection[] = [];
|
|
68
103
|
return {
|
|
69
104
|
context: {
|
|
70
|
-
getContainingSpaceIdForDocument: async (documentId) => null,
|
|
105
|
+
getContainingSpaceIdForDocument: async (documentId) => args?.documentSpaceId?.[documentId] ?? null,
|
|
71
106
|
getContainingSpaceForDocument: async (documentId) => null,
|
|
72
107
|
onConnectionAuthScopeChanged: (connection) => {},
|
|
73
|
-
isDocumentInRemoteCollection: async (params) =>
|
|
74
|
-
|
|
108
|
+
isDocumentInRemoteCollection: async (params) =>
|
|
109
|
+
args?.remoteCollections?.[params.peerId]?.[params.documentId] ?? false,
|
|
110
|
+
onConnectionClosed: (connection) => {
|
|
111
|
+
const idx = openConnections.indexOf(connection);
|
|
112
|
+
if (idx >= 0) {
|
|
113
|
+
openConnections.splice(idx, 1);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
75
116
|
onConnectionOpen: (connection) => {
|
|
117
|
+
openConnections.push(connection);
|
|
76
118
|
connectionOpen.emit();
|
|
77
119
|
},
|
|
78
120
|
|
|
79
121
|
peerId: PublicKey.random().toHex(),
|
|
80
122
|
} satisfies EchoReplicatorContext,
|
|
81
123
|
|
|
124
|
+
openConnections,
|
|
82
125
|
connectionOpen,
|
|
83
126
|
};
|
|
84
127
|
};
|
|
@@ -97,6 +97,9 @@ export class EchoEdgeReplicator implements EchoReplicator {
|
|
|
97
97
|
async connectToSpace(spaceId: SpaceId) {
|
|
98
98
|
using _guard = await this._mutex.acquire();
|
|
99
99
|
|
|
100
|
+
if (this._connectedSpaces.has(spaceId)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
100
103
|
this._connectedSpaces.add(spaceId);
|
|
101
104
|
|
|
102
105
|
// Check if AM-repo requested that we connect to remote peers.
|
|
@@ -264,9 +267,20 @@ class EdgeReplicatorConnection extends Resource implements ReplicatorConnection
|
|
|
264
267
|
}
|
|
265
268
|
const spaceId = await this._context.getContainingSpaceIdForDocument(params.documentId);
|
|
266
269
|
if (!spaceId) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
const remoteDocumentExists = await this._context.isDocumentInRemoteCollection({
|
|
271
|
+
documentId: params.documentId,
|
|
272
|
+
peerId: this._remotePeerId as PeerId,
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
log.info('document not found locally for share policy check, accepting the remote document', {
|
|
276
|
+
documentId: params.documentId,
|
|
277
|
+
remoteDocumentExists,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// If a document is not present locally return true only if it already exists on edge.
|
|
281
|
+
// Simply returning true will add edge to "generous peers list" for this document which will
|
|
282
|
+
// start replication of the document after we receive it potentially pushing it to replicator of the wrong space.
|
|
283
|
+
return remoteDocumentExists;
|
|
270
284
|
}
|
|
271
285
|
return spaceId === this._spaceId;
|
|
272
286
|
}
|
package/src/index.ts
CHANGED
package/src/space/space.ts
CHANGED
|
@@ -48,6 +48,7 @@ export type CreatePipelineParams = {
|
|
|
48
48
|
* Spaces are globally addressable databases with access control.
|
|
49
49
|
*/
|
|
50
50
|
// TODO(dmaretskyi): Extract database stuff.
|
|
51
|
+
// TODO(dmaretskyi): Rename HaloGraph move to HALO.
|
|
51
52
|
@trackLeaks('open', 'close')
|
|
52
53
|
@trace.resource()
|
|
53
54
|
export class Space extends Resource {
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { decodeReference, type ObjectStructure, type SpaceDoc } from '@dxos/echo-protocol';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Assumes properties are at root.
|
|
9
|
+
*/
|
|
10
|
+
export const findInlineObjectOfType = (spaceDoc: SpaceDoc, typename: string): [string, ObjectStructure] | undefined => {
|
|
11
|
+
for (const id in spaceDoc.objects ?? {}) {
|
|
12
|
+
const obj = spaceDoc.objects![id];
|
|
13
|
+
if (obj.system.type && decodeReference(obj.system.type).objectId === typename) {
|
|
14
|
+
return [id, obj];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return undefined;
|
|
19
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../../../src/db-host/migration.ts"],"names":[],"mappings":"AAKA,OAAO,EAKL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EAEd,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,uBAAuB,QAAe,QAAQ,KAAG,OAAO,CAAC,QAAQ,CAU7E,CAAC;AAEF,eAAO,MAAM,yBAAyB,SAAgB,QAAQ,KAAG,OAAO,CAAC,QAAQ,CAYhF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,aAAc,QAAQ,YAAY,MAAM,KAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SASzG,CAAC"}
|
package/src/db-host/migration.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { convertLegacyReference } from '@dxos/echo-protocol';
|
|
6
|
-
import {
|
|
7
|
-
decodeReference,
|
|
8
|
-
encodeReference,
|
|
9
|
-
isLegacyReference,
|
|
10
|
-
LEGACY_TYPE_PROPERTIES,
|
|
11
|
-
type ObjectStructure,
|
|
12
|
-
Reference,
|
|
13
|
-
type SpaceDoc,
|
|
14
|
-
SpaceDocVersion,
|
|
15
|
-
} from '@dxos/echo-protocol';
|
|
16
|
-
import { TYPE_PROPERTIES } from '@dxos/echo-schema';
|
|
17
|
-
import { deepMapValuesAsync } from '@dxos/util';
|
|
18
|
-
|
|
19
|
-
export const convertLegacyReferences = async (doc: SpaceDoc): Promise<SpaceDoc> => {
|
|
20
|
-
const newDoc = await deepMapValuesAsync(doc, async (value, recurse) => {
|
|
21
|
-
if (isLegacyReference(value)) {
|
|
22
|
-
return convertLegacyReference(value);
|
|
23
|
-
}
|
|
24
|
-
return recurse(value);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
newDoc.version = SpaceDocVersion.CURRENT;
|
|
28
|
-
return newDoc;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const convertLegacySpaceRootDoc = async (root: SpaceDoc): Promise<SpaceDoc> => {
|
|
32
|
-
// Convert references.
|
|
33
|
-
const newDoc: SpaceDoc = await convertLegacyReferences(root);
|
|
34
|
-
|
|
35
|
-
// Update properties type.
|
|
36
|
-
const properties = findInlineObjectOfType(newDoc, LEGACY_TYPE_PROPERTIES);
|
|
37
|
-
if (properties) {
|
|
38
|
-
const [_, obj] = properties;
|
|
39
|
-
obj.system.type = encodeReference(Reference.fromLegacyTypename(TYPE_PROPERTIES));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return newDoc;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Assumes properties are at root.
|
|
47
|
-
*/
|
|
48
|
-
export const findInlineObjectOfType = (spaceDoc: SpaceDoc, typename: string): [string, ObjectStructure] | undefined => {
|
|
49
|
-
for (const id in spaceDoc.objects ?? {}) {
|
|
50
|
-
const obj = spaceDoc.objects![id];
|
|
51
|
-
if (obj.system.type && decodeReference(obj.system.type).objectId === typename) {
|
|
52
|
-
return [id, obj];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return undefined;
|
|
57
|
-
};
|