@dxos/echo-pipeline 0.4.9 → 0.4.10-main.068c3d8
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-RTEEJ723.mjs → chunk-SYE4EK33.mjs} +30 -35
- package/dist/lib/browser/chunk-SYE4EK33.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +593 -217
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +8 -2
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node/{chunk-7VZVCCNF.cjs → chunk-WCTX6RNS.cjs} +35 -40
- package/dist/lib/node/chunk-WCTX6RNS.cjs.map +7 -0
- package/dist/lib/node/index.cjs +611 -237
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +18 -13
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/types/src/automerge/automerge-doc-loader.d.ts +66 -0
- package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -0
- package/dist/types/src/automerge/automerge-doc-loader.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-doc-loader.test.d.ts.map +1 -0
- package/dist/types/src/automerge/automerge-host.d.ts +21 -18
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-repo.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -0
- package/dist/types/src/automerge/index.d.ts +4 -0
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/automerge/level.test.d.ts +2 -0
- package/dist/types/src/automerge/level.test.d.ts.map +1 -0
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +30 -0
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -0
- package/dist/types/src/automerge/local-host-network-adapter.d.ts +8 -1
- package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/migrations.d.ts +7 -0
- package/dist/types/src/automerge/migrations.d.ts.map +1 -0
- package/dist/types/src/automerge/reference.d.ts +15 -0
- package/dist/types/src/automerge/reference.d.ts.map +1 -0
- package/dist/types/src/automerge/storage-adapter.test.d.ts +2 -0
- package/dist/types/src/automerge/storage-adapter.test.d.ts.map +1 -0
- package/dist/types/src/automerge/types.d.ts +73 -0
- package/dist/types/src/automerge/types.d.ts.map +1 -0
- package/dist/types/src/metadata/metadata-store.d.ts +2 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +4 -8
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/level.d.ts +3 -0
- package/dist/types/src/testing/level.d.ts.map +1 -0
- package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
- package/package.json +33 -30
- package/src/automerge/automerge-doc-loader.test.ts +97 -0
- package/src/automerge/automerge-doc-loader.ts +241 -0
- package/src/automerge/automerge-host.test.ts +22 -8
- package/src/automerge/automerge-host.ts +65 -118
- package/src/automerge/automerge-repo.test.ts +29 -0
- package/src/automerge/index.ts +4 -0
- package/src/automerge/level.test.ts +64 -0
- package/src/automerge/leveldb-storage-adapter.ts +117 -0
- package/src/automerge/local-host-network-adapter.ts +19 -13
- package/src/automerge/migrations.ts +41 -0
- package/src/automerge/reference.ts +31 -0
- package/src/automerge/storage-adapter.test.ts +90 -0
- package/src/automerge/types.ts +86 -0
- package/src/db-host/data-service.ts +1 -1
- package/src/metadata/metadata-store.ts +17 -8
- package/src/space/space.test.ts +7 -7
- package/src/space/space.ts +6 -21
- package/src/testing/index.ts +1 -0
- package/src/testing/level.ts +11 -0
- package/dist/lib/browser/chunk-RTEEJ723.mjs.map +0 -7
- package/dist/lib/node/chunk-7VZVCCNF.cjs.map +0 -7
package/dist/lib/node/index.cjs
CHANGED
|
@@ -18,162 +18,169 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var node_exports = {};
|
|
20
20
|
__export(node_exports, {
|
|
21
|
-
AuthExtension: () =>
|
|
22
|
-
AuthStatus: () =>
|
|
21
|
+
AuthExtension: () => import_chunk_WCTX6RNS.AuthExtension,
|
|
22
|
+
AuthStatus: () => import_chunk_WCTX6RNS.AuthStatus,
|
|
23
|
+
AutomergeDocumentLoaderImpl: () => AutomergeDocumentLoaderImpl,
|
|
23
24
|
AutomergeHost: () => AutomergeHost,
|
|
24
25
|
AutomergeStorageAdapter: () => AutomergeStorageAdapter,
|
|
25
|
-
DataServiceImpl: () =>
|
|
26
|
+
DataServiceImpl: () => import_chunk_WCTX6RNS.DataServiceImpl,
|
|
27
|
+
LevelDBStorageAdapter: () => LevelDBStorageAdapter,
|
|
26
28
|
LocalHostNetworkAdapter: () => LocalHostNetworkAdapter,
|
|
27
|
-
MOCK_AUTH_PROVIDER: () =>
|
|
28
|
-
MOCK_AUTH_VERIFIER: () =>
|
|
29
|
+
MOCK_AUTH_PROVIDER: () => import_chunk_WCTX6RNS.MOCK_AUTH_PROVIDER,
|
|
30
|
+
MOCK_AUTH_VERIFIER: () => import_chunk_WCTX6RNS.MOCK_AUTH_VERIFIER,
|
|
29
31
|
MeshNetworkAdapter: () => MeshNetworkAdapter,
|
|
30
|
-
MetadataStore: () =>
|
|
31
|
-
Pipeline: () =>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
MetadataStore: () => import_chunk_WCTX6RNS.MetadataStore,
|
|
33
|
+
Pipeline: () => import_chunk_WCTX6RNS.Pipeline,
|
|
34
|
+
REFERENCE_TYPE_TAG: () => REFERENCE_TYPE_TAG,
|
|
35
|
+
SnapshotManager: () => import_chunk_WCTX6RNS.SnapshotManager,
|
|
36
|
+
SnapshotStore: () => import_chunk_WCTX6RNS.SnapshotStore,
|
|
37
|
+
Space: () => import_chunk_WCTX6RNS.Space,
|
|
38
|
+
SpaceManager: () => import_chunk_WCTX6RNS.SpaceManager,
|
|
39
|
+
SpaceProtocol: () => import_chunk_WCTX6RNS.SpaceProtocol,
|
|
40
|
+
SpaceProtocolSession: () => import_chunk_WCTX6RNS.SpaceProtocolSession,
|
|
41
|
+
TimeframeClock: () => import_chunk_WCTX6RNS.TimeframeClock,
|
|
42
|
+
codec: () => import_chunk_WCTX6RNS.codec,
|
|
43
|
+
createMappedFeedWriter: () => import_chunk_WCTX6RNS.createMappedFeedWriter,
|
|
44
|
+
decodeReference: () => decodeReference,
|
|
45
|
+
encodeReference: () => encodeReference,
|
|
46
|
+
encodingOptions: () => encodingOptions,
|
|
41
47
|
getSpaceKeyFromDoc: () => getSpaceKeyFromDoc,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
hasInvitationExpired: () => import_chunk_WCTX6RNS.hasInvitationExpired,
|
|
49
|
+
isEncodedReferenceObject: () => isEncodedReferenceObject,
|
|
50
|
+
mapFeedIndexesToTimeframe: () => import_chunk_WCTX6RNS.mapFeedIndexesToTimeframe,
|
|
51
|
+
mapTimeframeToFeedIndexes: () => import_chunk_WCTX6RNS.mapTimeframeToFeedIndexes,
|
|
52
|
+
startAfter: () => import_chunk_WCTX6RNS.startAfter,
|
|
53
|
+
valueEncoding: () => import_chunk_WCTX6RNS.valueEncoding
|
|
46
54
|
});
|
|
47
55
|
module.exports = __toCommonJS(node_exports);
|
|
48
|
-
var
|
|
56
|
+
var import_chunk_WCTX6RNS = require("./chunk-WCTX6RNS.cjs");
|
|
57
|
+
var import_async = require("@dxos/async");
|
|
49
58
|
var import_automerge = require("@dxos/automerge/automerge");
|
|
50
59
|
var import_automerge_repo = require("@dxos/automerge/automerge-repo");
|
|
51
|
-
var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
|
|
52
60
|
var import_context = require("@dxos/context");
|
|
53
61
|
var import_keys = require("@dxos/keys");
|
|
54
62
|
var import_log = require("@dxos/log");
|
|
55
|
-
var import_protocols = require("@dxos/protocols");
|
|
56
|
-
var import_random_access_storage = require("@dxos/random-access-storage");
|
|
57
63
|
var import_tracing = require("@dxos/tracing");
|
|
58
64
|
var import_util = require("@dxos/util");
|
|
59
|
-
var
|
|
60
|
-
var
|
|
65
|
+
var import_context2 = require("@dxos/context");
|
|
66
|
+
var import_async2 = require("@dxos/async");
|
|
61
67
|
var import_automerge_repo2 = require("@dxos/automerge/automerge-repo");
|
|
62
68
|
var import_codec_protobuf = require("@dxos/codec-protobuf");
|
|
63
69
|
var import_invariant = require("@dxos/invariant");
|
|
64
|
-
var
|
|
65
|
-
var import_async2 = require("@dxos/async");
|
|
70
|
+
var import_async3 = require("@dxos/async");
|
|
66
71
|
var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
|
|
67
72
|
var import_invariant2 = require("@dxos/invariant");
|
|
68
|
-
var
|
|
73
|
+
var import_log2 = require("@dxos/log");
|
|
69
74
|
var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
|
|
76
|
+
var import_log3 = require("@dxos/log");
|
|
77
|
+
var import_random_access_storage = require("@dxos/random-access-storage");
|
|
78
|
+
var import_util2 = require("@dxos/util");
|
|
79
|
+
var import_async4 = require("@dxos/async");
|
|
80
|
+
var import_context3 = require("@dxos/context");
|
|
81
|
+
var import_debug = require("@dxos/debug");
|
|
82
|
+
var import_invariant3 = require("@dxos/invariant");
|
|
83
|
+
var import_log4 = require("@dxos/log");
|
|
84
|
+
var import_echo_db = require("@dxos/echo-db");
|
|
85
|
+
var LevelDBStorageAdapter = class extends import_context2.Resource {
|
|
86
|
+
constructor(_params) {
|
|
87
|
+
super();
|
|
88
|
+
this._params = _params;
|
|
74
89
|
}
|
|
75
|
-
async load(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
async load(keyArray) {
|
|
91
|
+
try {
|
|
92
|
+
if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
return await this._params.db.get(keyArray, {
|
|
96
|
+
...encodingOptions
|
|
97
|
+
});
|
|
98
|
+
} catch (err) {
|
|
99
|
+
if (isLevelDbNotFoundError(err)) {
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
84
103
|
}
|
|
85
|
-
const buffer = await file.read(0, size);
|
|
86
|
-
return (0, import_util2.bufferToArray)(buffer);
|
|
87
104
|
}
|
|
88
|
-
async save(
|
|
89
|
-
if (this.
|
|
105
|
+
async save(keyArray, binary) {
|
|
106
|
+
if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
|
|
90
107
|
return void 0;
|
|
91
108
|
}
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
const batch = this._params.db.batch();
|
|
110
|
+
await this._params.callbacks?.beforeSave?.({
|
|
111
|
+
path: keyArray,
|
|
112
|
+
batch
|
|
113
|
+
});
|
|
114
|
+
batch.put(keyArray, Buffer.from(binary), {
|
|
115
|
+
...encodingOptions
|
|
116
|
+
});
|
|
117
|
+
await batch.write();
|
|
118
|
+
await this._params.callbacks?.afterSave?.(keyArray);
|
|
97
119
|
}
|
|
98
|
-
async remove(
|
|
99
|
-
if (this.
|
|
120
|
+
async remove(keyArray) {
|
|
121
|
+
if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
|
|
100
122
|
return void 0;
|
|
101
123
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
124
|
+
await this._params.db.del(keyArray, {
|
|
125
|
+
...encodingOptions
|
|
126
|
+
});
|
|
105
127
|
}
|
|
106
128
|
async loadRange(keyPrefix) {
|
|
107
|
-
if (this.
|
|
129
|
+
if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
|
|
108
130
|
return [];
|
|
109
131
|
}
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
132
|
+
const result = [];
|
|
133
|
+
for await (const [key, value] of this._params.db.iterator({
|
|
134
|
+
gte: keyPrefix,
|
|
135
|
+
lte: [
|
|
136
|
+
...keyPrefix,
|
|
137
|
+
"\uFFFF"
|
|
138
|
+
],
|
|
139
|
+
...encodingOptions
|
|
140
|
+
})) {
|
|
141
|
+
result.push({
|
|
142
|
+
key,
|
|
143
|
+
data: value
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
121
147
|
}
|
|
122
148
|
async removeRange(keyPrefix) {
|
|
123
|
-
if (this.
|
|
149
|
+
if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
|
|
124
150
|
return void 0;
|
|
125
151
|
}
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
_getKeyFromFilename(filename) {
|
|
140
|
-
return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
var AutomergeStorageWrapper = class {
|
|
144
|
-
constructor({ storage, callbacks }) {
|
|
145
|
-
this._storage = storage;
|
|
146
|
-
this._callbacks = callbacks;
|
|
147
|
-
}
|
|
148
|
-
async load(key) {
|
|
149
|
-
return this._storage.load(key);
|
|
150
|
-
}
|
|
151
|
-
async save(key, value) {
|
|
152
|
-
await this._callbacks.beforeSave?.(key);
|
|
153
|
-
await this._storage.save(key, value);
|
|
154
|
-
await this._callbacks.afterSave?.(key);
|
|
155
|
-
}
|
|
156
|
-
async remove(key) {
|
|
157
|
-
return this._storage.remove(key);
|
|
158
|
-
}
|
|
159
|
-
async loadRange(keyPrefix) {
|
|
160
|
-
return this._storage.loadRange(keyPrefix);
|
|
161
|
-
}
|
|
162
|
-
async removeRange(keyPrefix) {
|
|
163
|
-
return this._storage.removeRange(keyPrefix);
|
|
164
|
-
}
|
|
165
|
-
async close() {
|
|
166
|
-
if (this._storage instanceof AutomergeStorageAdapter) {
|
|
167
|
-
return this._storage.close();
|
|
152
|
+
const batch = this._params.db.batch();
|
|
153
|
+
for await (const [key] of this._params.db.iterator({
|
|
154
|
+
gte: keyPrefix,
|
|
155
|
+
lte: [
|
|
156
|
+
...keyPrefix,
|
|
157
|
+
"\uFFFF"
|
|
158
|
+
],
|
|
159
|
+
...encodingOptions
|
|
160
|
+
})) {
|
|
161
|
+
batch.del(key, {
|
|
162
|
+
...encodingOptions
|
|
163
|
+
});
|
|
168
164
|
}
|
|
165
|
+
await batch.write();
|
|
169
166
|
}
|
|
170
167
|
};
|
|
168
|
+
var keyEncoder = {
|
|
169
|
+
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
170
|
+
decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"))
|
|
171
|
+
};
|
|
172
|
+
var encodingOptions = {
|
|
173
|
+
keyEncoding: keyEncoder,
|
|
174
|
+
valueEncoding: "buffer"
|
|
175
|
+
};
|
|
176
|
+
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
171
177
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
|
|
172
178
|
var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
|
|
173
179
|
constructor() {
|
|
174
180
|
super(...arguments);
|
|
175
181
|
this._peers = /* @__PURE__ */ new Map();
|
|
176
|
-
this._connected = new
|
|
182
|
+
this._connected = new import_async2.Trigger();
|
|
183
|
+
this._isConnected = false;
|
|
177
184
|
}
|
|
178
185
|
/**
|
|
179
186
|
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
@@ -183,15 +190,21 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
|
|
|
183
190
|
network: this
|
|
184
191
|
});
|
|
185
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Called by `Repo` to connect to the network.
|
|
195
|
+
*
|
|
196
|
+
* @param peerId Our peer Id.
|
|
197
|
+
*/
|
|
186
198
|
connect(peerId) {
|
|
187
199
|
this.peerId = peerId;
|
|
200
|
+
this._isConnected = true;
|
|
188
201
|
this._connected.wake();
|
|
189
202
|
}
|
|
190
203
|
send(message) {
|
|
191
204
|
const peer = this._peers.get(message.targetId);
|
|
192
205
|
(0, import_invariant.invariant)(peer, "Peer not found.", {
|
|
193
206
|
F: __dxlog_file,
|
|
194
|
-
L:
|
|
207
|
+
L: 51,
|
|
195
208
|
S: this,
|
|
196
209
|
A: [
|
|
197
210
|
"peer",
|
|
@@ -206,12 +219,17 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
|
|
|
206
219
|
}
|
|
207
220
|
disconnect() {
|
|
208
221
|
}
|
|
222
|
+
async whenConnected() {
|
|
223
|
+
await this._connected.wait({
|
|
224
|
+
timeout: 1e4
|
|
225
|
+
});
|
|
226
|
+
}
|
|
209
227
|
syncRepo({ id, syncMessage }) {
|
|
210
228
|
const peerId = this._getPeerId(id);
|
|
211
229
|
return new import_codec_protobuf.Stream(({ next, close }) => {
|
|
212
230
|
(0, import_invariant.invariant)(!this._peers.has(peerId), "Peer already connected.", {
|
|
213
231
|
F: __dxlog_file,
|
|
214
|
-
L:
|
|
232
|
+
L: 73,
|
|
215
233
|
S: this,
|
|
216
234
|
A: [
|
|
217
235
|
"!this._peers.has(peerId)",
|
|
@@ -233,35 +251,47 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
|
|
|
233
251
|
});
|
|
234
252
|
}
|
|
235
253
|
});
|
|
236
|
-
this.
|
|
237
|
-
timeout: 1e3
|
|
238
|
-
}).then(() => {
|
|
239
|
-
this.emit("peer-candidate", {
|
|
240
|
-
peerMetadata: {},
|
|
241
|
-
peerId
|
|
242
|
-
});
|
|
243
|
-
}).catch((err) => import_log2.log.catch(err, void 0, {
|
|
254
|
+
(0, import_invariant.invariant)(this._isConnected, void 0, {
|
|
244
255
|
F: __dxlog_file,
|
|
245
|
-
L:
|
|
256
|
+
L: 90,
|
|
246
257
|
S: this,
|
|
247
|
-
|
|
248
|
-
|
|
258
|
+
A: [
|
|
259
|
+
"this._isConnected",
|
|
260
|
+
""
|
|
261
|
+
]
|
|
262
|
+
});
|
|
263
|
+
this.emit("peer-candidate", {
|
|
264
|
+
peerMetadata: {},
|
|
265
|
+
peerId
|
|
266
|
+
});
|
|
249
267
|
});
|
|
250
268
|
}
|
|
251
269
|
async sendSyncMessage({ id, syncMessage }) {
|
|
252
|
-
|
|
253
|
-
|
|
270
|
+
(0, import_invariant.invariant)(this._isConnected, void 0, {
|
|
271
|
+
F: __dxlog_file,
|
|
272
|
+
L: 99,
|
|
273
|
+
S: this,
|
|
274
|
+
A: [
|
|
275
|
+
"this._isConnected",
|
|
276
|
+
""
|
|
277
|
+
]
|
|
254
278
|
});
|
|
255
279
|
const message = import_automerge_repo2.cbor.decode(syncMessage);
|
|
256
280
|
this.emit("message", message);
|
|
257
281
|
}
|
|
258
282
|
async getHostInfo() {
|
|
259
|
-
|
|
260
|
-
|
|
283
|
+
(0, import_invariant.invariant)(this._isConnected, void 0, {
|
|
284
|
+
F: __dxlog_file,
|
|
285
|
+
L: 105,
|
|
286
|
+
S: this,
|
|
287
|
+
A: [
|
|
288
|
+
"this._isConnected",
|
|
289
|
+
""
|
|
290
|
+
]
|
|
261
291
|
});
|
|
262
292
|
(0, import_invariant.invariant)(this.peerId, "Peer id not set.", {
|
|
263
293
|
F: __dxlog_file,
|
|
264
|
-
L:
|
|
294
|
+
L: 106,
|
|
265
295
|
S: this,
|
|
266
296
|
A: [
|
|
267
297
|
"this.peerId",
|
|
@@ -281,7 +311,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
|
|
|
281
311
|
constructor() {
|
|
282
312
|
super(...arguments);
|
|
283
313
|
this._extensions = /* @__PURE__ */ new Map();
|
|
284
|
-
this._connected = new
|
|
314
|
+
this._connected = new import_async3.Trigger();
|
|
285
315
|
}
|
|
286
316
|
/**
|
|
287
317
|
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
@@ -309,7 +339,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
|
|
|
309
339
|
});
|
|
310
340
|
extension.sendSyncMessage({
|
|
311
341
|
payload: import_automerge_repo3.cbor.encode(message)
|
|
312
|
-
}).catch((err) =>
|
|
342
|
+
}).catch((err) => import_log2.log.catch(err, void 0, {
|
|
313
343
|
F: __dxlog_file2,
|
|
314
344
|
L: 39,
|
|
315
345
|
S: this,
|
|
@@ -334,7 +364,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
|
|
|
334
364
|
}, {
|
|
335
365
|
onStartReplication: async (info, remotePeerId) => {
|
|
336
366
|
await this._connected.wait();
|
|
337
|
-
(0,
|
|
367
|
+
(0, import_log2.log)("onStartReplication", {
|
|
338
368
|
id: info.id,
|
|
339
369
|
thisPeerId: this.peerId,
|
|
340
370
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -347,7 +377,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
|
|
|
347
377
|
if (!this._extensions.has(info.id)) {
|
|
348
378
|
peerInfo = info;
|
|
349
379
|
this._extensions.set(info.id, extension);
|
|
350
|
-
(0,
|
|
380
|
+
(0, import_log2.log)("peer-candidate", {
|
|
351
381
|
id: info.id,
|
|
352
382
|
thisPeerId: this.peerId,
|
|
353
383
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -386,6 +416,108 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
|
|
|
386
416
|
return extension;
|
|
387
417
|
}
|
|
388
418
|
};
|
|
419
|
+
var AutomergeStorageAdapter = class {
|
|
420
|
+
constructor(_directory) {
|
|
421
|
+
this._directory = _directory;
|
|
422
|
+
this._state = "opened";
|
|
423
|
+
}
|
|
424
|
+
async load(key) {
|
|
425
|
+
if (this._state !== "opened") {
|
|
426
|
+
return void 0;
|
|
427
|
+
}
|
|
428
|
+
const filename = this._getFilename(key);
|
|
429
|
+
const file = this._directory.getOrCreateFile(filename);
|
|
430
|
+
const { size } = await file.stat();
|
|
431
|
+
if (!size || size === 0) {
|
|
432
|
+
return void 0;
|
|
433
|
+
}
|
|
434
|
+
const buffer = await file.read(0, size);
|
|
435
|
+
return (0, import_util2.bufferToArray)(buffer);
|
|
436
|
+
}
|
|
437
|
+
async save(key, data) {
|
|
438
|
+
if (this._state !== "opened") {
|
|
439
|
+
return void 0;
|
|
440
|
+
}
|
|
441
|
+
const filename = this._getFilename(key);
|
|
442
|
+
const file = this._directory.getOrCreateFile(filename);
|
|
443
|
+
await file.write(0, (0, import_util2.arrayToBuffer)(data));
|
|
444
|
+
await file.truncate?.(data.length);
|
|
445
|
+
await file.flush?.();
|
|
446
|
+
}
|
|
447
|
+
async remove(key) {
|
|
448
|
+
if (this._state !== "opened") {
|
|
449
|
+
return void 0;
|
|
450
|
+
}
|
|
451
|
+
const filename = this._getFilename(key);
|
|
452
|
+
const file = this._directory.getOrCreateFile(filename);
|
|
453
|
+
await file.destroy();
|
|
454
|
+
}
|
|
455
|
+
async loadRange(keyPrefix) {
|
|
456
|
+
if (this._state !== "opened") {
|
|
457
|
+
return [];
|
|
458
|
+
}
|
|
459
|
+
const filename = this._getFilename(keyPrefix);
|
|
460
|
+
const entries = await this._directory.list();
|
|
461
|
+
return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
462
|
+
const file = this._directory.getOrCreateFile(entry);
|
|
463
|
+
const { size } = await file.stat();
|
|
464
|
+
const buffer = await file.read(0, size);
|
|
465
|
+
return {
|
|
466
|
+
key: this._getKeyFromFilename(entry),
|
|
467
|
+
data: (0, import_util2.bufferToArray)(buffer)
|
|
468
|
+
};
|
|
469
|
+
}));
|
|
470
|
+
}
|
|
471
|
+
async removeRange(keyPrefix) {
|
|
472
|
+
if (this._state !== "opened") {
|
|
473
|
+
return void 0;
|
|
474
|
+
}
|
|
475
|
+
const filename = this._getFilename(keyPrefix);
|
|
476
|
+
const entries = await this._directory.list();
|
|
477
|
+
await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
|
|
478
|
+
const file = this._directory.getOrCreateFile(entry);
|
|
479
|
+
await file.destroy();
|
|
480
|
+
}));
|
|
481
|
+
}
|
|
482
|
+
async close() {
|
|
483
|
+
this._state = "closed";
|
|
484
|
+
}
|
|
485
|
+
_getFilename(key) {
|
|
486
|
+
return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
|
|
487
|
+
}
|
|
488
|
+
_getKeyFromFilename(filename) {
|
|
489
|
+
return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
|
|
493
|
+
var levelMigration = async ({ db, directory }) => {
|
|
494
|
+
const isNewLevel = !await db.iterator({
|
|
495
|
+
...encodingOptions
|
|
496
|
+
}).next();
|
|
497
|
+
if (!isNewLevel) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const oldStorageAdapter = directory.type === import_random_access_storage.StorageType.IDB ? new import_automerge_repo_storage_indexeddb.IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory);
|
|
501
|
+
const chunks = await oldStorageAdapter.loadRange([]);
|
|
502
|
+
if (chunks.length === 0) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const batch = db.batch();
|
|
506
|
+
import_log3.log.info("found chunks on old storage adapter", {
|
|
507
|
+
chunks: chunks.length
|
|
508
|
+
}, {
|
|
509
|
+
F: __dxlog_file3,
|
|
510
|
+
L: 36,
|
|
511
|
+
S: void 0,
|
|
512
|
+
C: (f, a) => f(...a)
|
|
513
|
+
});
|
|
514
|
+
for (const { key, data } of await oldStorageAdapter.loadRange([])) {
|
|
515
|
+
data && batch.put(key, data, {
|
|
516
|
+
...encodingOptions
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
await batch.write();
|
|
520
|
+
};
|
|
389
521
|
function _ts_decorate(decorators, target, key, desc) {
|
|
390
522
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
391
523
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
@@ -396,26 +528,29 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
396
528
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
397
529
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
398
530
|
}
|
|
399
|
-
var
|
|
531
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
400
532
|
var AutomergeHost = class {
|
|
401
|
-
constructor({ directory,
|
|
533
|
+
constructor({ directory, db, storageCallbacks }) {
|
|
402
534
|
this._ctx = new import_context.Context();
|
|
403
535
|
this._authorizedDevices = new import_util.ComplexMap(import_keys.PublicKey.hash);
|
|
404
|
-
this._updatingMetadata = /* @__PURE__ */ new Map();
|
|
405
536
|
this._requestedDocs = /* @__PURE__ */ new Set();
|
|
406
|
-
this.
|
|
407
|
-
this.
|
|
408
|
-
this.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
callbacks: {
|
|
415
|
-
beforeSave: (params) => this._beforeSave(params)
|
|
416
|
-
}
|
|
537
|
+
this._directory = directory;
|
|
538
|
+
this._db = db;
|
|
539
|
+
this._storageCallbacks = storageCallbacks;
|
|
540
|
+
}
|
|
541
|
+
async open() {
|
|
542
|
+
this._directory && await levelMigration({
|
|
543
|
+
db: this._db,
|
|
544
|
+
directory: this._directory
|
|
417
545
|
});
|
|
546
|
+
this._storage = new LevelDBStorageAdapter({
|
|
547
|
+
db: this._db,
|
|
548
|
+
callbacks: this._storageCallbacks
|
|
549
|
+
});
|
|
550
|
+
await this._storage.open?.();
|
|
418
551
|
this._peerId = `host-${import_keys.PublicKey.random().toHex()}`;
|
|
552
|
+
this._meshNetwork = new MeshNetworkAdapter();
|
|
553
|
+
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
419
554
|
this._repo = new import_automerge_repo.Repo({
|
|
420
555
|
peerId: this._peerId,
|
|
421
556
|
network: [
|
|
@@ -440,8 +575,8 @@ var AutomergeHost = class {
|
|
|
440
575
|
documentId,
|
|
441
576
|
isRequested
|
|
442
577
|
}, {
|
|
443
|
-
F:
|
|
444
|
-
L:
|
|
578
|
+
F: __dxlog_file4,
|
|
579
|
+
L: 99,
|
|
445
580
|
S: this,
|
|
446
581
|
C: (f, a) => f(...a)
|
|
447
582
|
});
|
|
@@ -454,8 +589,8 @@ var AutomergeHost = class {
|
|
|
454
589
|
peerId,
|
|
455
590
|
documentId
|
|
456
591
|
}, {
|
|
457
|
-
F:
|
|
458
|
-
L:
|
|
592
|
+
F: __dxlog_file4,
|
|
593
|
+
L: 106,
|
|
459
594
|
S: this,
|
|
460
595
|
C: (f, a) => f(...a)
|
|
461
596
|
});
|
|
@@ -468,8 +603,8 @@ var AutomergeHost = class {
|
|
|
468
603
|
peerId,
|
|
469
604
|
documentId
|
|
470
605
|
}, {
|
|
471
|
-
F:
|
|
472
|
-
L:
|
|
606
|
+
F: __dxlog_file4,
|
|
607
|
+
L: 115,
|
|
473
608
|
S: this,
|
|
474
609
|
C: (f, a) => f(...a)
|
|
475
610
|
});
|
|
@@ -485,16 +620,16 @@ var AutomergeHost = class {
|
|
|
485
620
|
spaceKey,
|
|
486
621
|
isAuthorized
|
|
487
622
|
}, {
|
|
488
|
-
F:
|
|
489
|
-
L:
|
|
623
|
+
F: __dxlog_file4,
|
|
624
|
+
L: 121,
|
|
490
625
|
S: this,
|
|
491
626
|
C: (f, a) => f(...a)
|
|
492
627
|
});
|
|
493
628
|
return isAuthorized;
|
|
494
629
|
} catch (err) {
|
|
495
630
|
import_log.log.catch(err, void 0, {
|
|
496
|
-
F:
|
|
497
|
-
L:
|
|
631
|
+
F: __dxlog_file4,
|
|
632
|
+
L: 131,
|
|
498
633
|
S: this,
|
|
499
634
|
C: (f, a) => f(...a)
|
|
500
635
|
});
|
|
@@ -504,69 +639,22 @@ var AutomergeHost = class {
|
|
|
504
639
|
});
|
|
505
640
|
this._clientNetwork.ready();
|
|
506
641
|
this._meshNetwork.ready();
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
642
|
+
await this._clientNetwork.whenConnected();
|
|
643
|
+
}
|
|
644
|
+
async close() {
|
|
645
|
+
await this._storage.close?.();
|
|
646
|
+
await this._clientNetwork.close();
|
|
647
|
+
await this._ctx.dispose();
|
|
514
648
|
}
|
|
515
649
|
get repo() {
|
|
516
650
|
return this._repo;
|
|
517
651
|
}
|
|
518
|
-
async _beforeSave(path) {
|
|
519
|
-
const id = path[0];
|
|
520
|
-
if (this._updatingMetadata.has(id)) {
|
|
521
|
-
return this._updatingMetadata.get(id);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
_onDocument(handle) {
|
|
525
|
-
const listener = (event) => this._onUpdate(event);
|
|
526
|
-
handle.on("change", listener);
|
|
527
|
-
this._ctx.onDispose(() => {
|
|
528
|
-
handle.off("change", listener);
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
_onUpdate(event) {
|
|
532
|
-
if (this._metadata == null) {
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
const objectIds = getInlineChanges(event);
|
|
536
|
-
if (objectIds.length === 0) {
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
const heads = (0, import_automerge.getHeads)(event.doc);
|
|
540
|
-
const lastAvailableHash = heads.join("");
|
|
541
|
-
if (!lastAvailableHash) {
|
|
542
|
-
return;
|
|
543
|
-
}
|
|
544
|
-
const encodedIds = objectIds.map((objectId) => import_protocols.idCodec.encode({
|
|
545
|
-
documentId: event.handle.documentId,
|
|
546
|
-
objectId
|
|
547
|
-
}));
|
|
548
|
-
const idToLastHash = new Map(encodedIds.map((id) => [
|
|
549
|
-
id,
|
|
550
|
-
lastAvailableHash
|
|
551
|
-
]));
|
|
552
|
-
const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
|
|
553
|
-
this._updatingMetadata.delete(event.handle.documentId);
|
|
554
|
-
}).catch((err) => {
|
|
555
|
-
this._ctx.disposed && import_log.log.catch(err, void 0, {
|
|
556
|
-
F: __dxlog_file3,
|
|
557
|
-
L: 188,
|
|
558
|
-
S: this,
|
|
559
|
-
C: (f, a) => f(...a)
|
|
560
|
-
});
|
|
561
|
-
});
|
|
562
|
-
this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
|
|
563
|
-
}
|
|
564
652
|
_automergeDocs() {
|
|
565
653
|
return (0, import_util.mapValues)(this._repo.handles, (handle) => ({
|
|
566
654
|
state: handle.state,
|
|
567
655
|
hasDoc: !!handle.docSync(),
|
|
568
656
|
heads: handle.docSync() ? import_automerge.next.getHeads(handle.docSync()) : null,
|
|
569
|
-
data: handle.docSync()
|
|
657
|
+
data: handle.docSync() && (0, import_util.mapValues)(handle.docSync(), (value, key) => {
|
|
570
658
|
try {
|
|
571
659
|
switch (key) {
|
|
572
660
|
case "access":
|
|
@@ -586,14 +674,25 @@ var AutomergeHost = class {
|
|
|
586
674
|
_automergePeers() {
|
|
587
675
|
return this._repo.peers;
|
|
588
676
|
}
|
|
589
|
-
async close() {
|
|
590
|
-
await this._storage.close();
|
|
591
|
-
await this._clientNetwork.close();
|
|
592
|
-
await this._ctx.dispose();
|
|
593
|
-
}
|
|
594
677
|
//
|
|
595
678
|
// Methods for client-services.
|
|
596
679
|
//
|
|
680
|
+
async flush({ documentIds }) {
|
|
681
|
+
await Promise.all(documentIds?.map((id) => this._repo.find(id).whenReady()) ?? []);
|
|
682
|
+
try {
|
|
683
|
+
await (0, import_async.asyncTimeout)(this._repo.flush(documentIds), 500);
|
|
684
|
+
} catch (err) {
|
|
685
|
+
import_log.log.warn("flush error", {
|
|
686
|
+
documentIds,
|
|
687
|
+
err
|
|
688
|
+
}, {
|
|
689
|
+
F: __dxlog_file4,
|
|
690
|
+
L: 195,
|
|
691
|
+
S: this,
|
|
692
|
+
C: (f, a) => f(...a)
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
}
|
|
597
696
|
syncRepo(request) {
|
|
598
697
|
return this._clientNetwork.syncRepo(request);
|
|
599
698
|
}
|
|
@@ -614,8 +713,8 @@ var AutomergeHost = class {
|
|
|
614
713
|
spaceKey,
|
|
615
714
|
deviceKey
|
|
616
715
|
}, {
|
|
617
|
-
F:
|
|
618
|
-
L:
|
|
716
|
+
F: __dxlog_file4,
|
|
717
|
+
L: 220,
|
|
619
718
|
S: this,
|
|
620
719
|
C: (f, a) => f(...a)
|
|
621
720
|
});
|
|
@@ -638,24 +737,6 @@ _ts_decorate([
|
|
|
638
737
|
AutomergeHost = _ts_decorate([
|
|
639
738
|
import_tracing.trace.resource()
|
|
640
739
|
], AutomergeHost);
|
|
641
|
-
var getInlineChanges = (event) => {
|
|
642
|
-
const inlineChangedObjectIds = /* @__PURE__ */ new Set();
|
|
643
|
-
for (const { path } of event.patches) {
|
|
644
|
-
if (path.length < 2) {
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
switch (path[0]) {
|
|
648
|
-
case "objects":
|
|
649
|
-
if (path.length >= 2) {
|
|
650
|
-
inlineChangedObjectIds.add(path[1]);
|
|
651
|
-
}
|
|
652
|
-
break;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
return [
|
|
656
|
-
...inlineChangedObjectIds
|
|
657
|
-
];
|
|
658
|
-
};
|
|
659
740
|
var getSpaceKeyFromDoc = (doc) => {
|
|
660
741
|
const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
|
|
661
742
|
if (rawSpaceKey == null) {
|
|
@@ -663,19 +744,307 @@ var getSpaceKeyFromDoc = (doc) => {
|
|
|
663
744
|
}
|
|
664
745
|
return String(rawSpaceKey);
|
|
665
746
|
};
|
|
747
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
|
|
748
|
+
var AutomergeDocumentLoaderImpl = class {
|
|
749
|
+
constructor(_spaceKey, _repo) {
|
|
750
|
+
this._spaceKey = _spaceKey;
|
|
751
|
+
this._repo = _repo;
|
|
752
|
+
this._spaceRootDocHandle = null;
|
|
753
|
+
this._objectDocumentHandles = /* @__PURE__ */ new Map();
|
|
754
|
+
this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
|
|
755
|
+
this.onObjectDocumentLoaded = new import_async4.Event();
|
|
756
|
+
}
|
|
757
|
+
getAllHandles() {
|
|
758
|
+
return [
|
|
759
|
+
...new Set(this._objectDocumentHandles.values())
|
|
760
|
+
];
|
|
761
|
+
}
|
|
762
|
+
async loadSpaceRootDocHandle(ctx, spaceState) {
|
|
763
|
+
if (this._spaceRootDocHandle != null) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
if (!spaceState.rootUrl) {
|
|
767
|
+
import_log4.log.error("Database opened with no rootUrl", {
|
|
768
|
+
spaceKey: this._spaceKey
|
|
769
|
+
}, {
|
|
770
|
+
F: __dxlog_file5,
|
|
771
|
+
L: 66,
|
|
772
|
+
S: this,
|
|
773
|
+
C: (f, a) => f(...a)
|
|
774
|
+
});
|
|
775
|
+
this._createContextBoundSpaceRootDocument(ctx);
|
|
776
|
+
} else {
|
|
777
|
+
const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
|
|
778
|
+
const doc = existingDocHandle.docSync();
|
|
779
|
+
(0, import_invariant3.invariant)(doc, void 0, {
|
|
780
|
+
F: __dxlog_file5,
|
|
781
|
+
L: 71,
|
|
782
|
+
S: this,
|
|
783
|
+
A: [
|
|
784
|
+
"doc",
|
|
785
|
+
""
|
|
786
|
+
]
|
|
787
|
+
});
|
|
788
|
+
if (doc.access == null) {
|
|
789
|
+
this._initDocAccess(existingDocHandle);
|
|
790
|
+
}
|
|
791
|
+
this._spaceRootDocHandle = existingDocHandle;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
loadObjectDocument(objectId) {
|
|
795
|
+
(0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
|
|
796
|
+
F: __dxlog_file5,
|
|
797
|
+
L: 80,
|
|
798
|
+
S: this,
|
|
799
|
+
A: [
|
|
800
|
+
"this._spaceRootDocHandle",
|
|
801
|
+
""
|
|
802
|
+
]
|
|
803
|
+
});
|
|
804
|
+
if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
const spaceRootDoc = this._spaceRootDocHandle.docSync();
|
|
808
|
+
(0, import_invariant3.invariant)(spaceRootDoc, void 0, {
|
|
809
|
+
F: __dxlog_file5,
|
|
810
|
+
L: 85,
|
|
811
|
+
S: this,
|
|
812
|
+
A: [
|
|
813
|
+
"spaceRootDoc",
|
|
814
|
+
""
|
|
815
|
+
]
|
|
816
|
+
});
|
|
817
|
+
const documentUrl = (spaceRootDoc.links ?? {})[objectId];
|
|
818
|
+
if (documentUrl == null) {
|
|
819
|
+
this._objectsPendingDocumentLoad.add(objectId);
|
|
820
|
+
import_log4.log.info("loading delayed until object links are initialized", {
|
|
821
|
+
objectId
|
|
822
|
+
}, {
|
|
823
|
+
F: __dxlog_file5,
|
|
824
|
+
L: 89,
|
|
825
|
+
S: this,
|
|
826
|
+
C: (f, a) => f(...a)
|
|
827
|
+
});
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
this._loadLinkedObjects({
|
|
831
|
+
[objectId]: documentUrl
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
onObjectLinksUpdated(links) {
|
|
835
|
+
if (!links) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
const linksAwaitingLoad = Object.entries(links).filter(([objectId]) => this._objectsPendingDocumentLoad.has(objectId));
|
|
839
|
+
this._loadLinkedObjects(Object.fromEntries(linksAwaitingLoad));
|
|
840
|
+
linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
|
|
841
|
+
}
|
|
842
|
+
getSpaceRootDocHandle() {
|
|
843
|
+
(0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
|
|
844
|
+
F: __dxlog_file5,
|
|
845
|
+
L: 107,
|
|
846
|
+
S: this,
|
|
847
|
+
A: [
|
|
848
|
+
"this._spaceRootDocHandle",
|
|
849
|
+
""
|
|
850
|
+
]
|
|
851
|
+
});
|
|
852
|
+
return this._spaceRootDocHandle;
|
|
853
|
+
}
|
|
854
|
+
createDocumentForObject(objectId) {
|
|
855
|
+
(0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
|
|
856
|
+
F: __dxlog_file5,
|
|
857
|
+
L: 112,
|
|
858
|
+
S: this,
|
|
859
|
+
A: [
|
|
860
|
+
"this._spaceRootDocHandle",
|
|
861
|
+
""
|
|
862
|
+
]
|
|
863
|
+
});
|
|
864
|
+
const spaceDocHandle = this._repo.create();
|
|
865
|
+
this._initDocAccess(spaceDocHandle);
|
|
866
|
+
this.onObjectBoundToDocument(spaceDocHandle, objectId);
|
|
867
|
+
this._spaceRootDocHandle.change((newDoc) => {
|
|
868
|
+
newDoc.links ??= {};
|
|
869
|
+
newDoc.links[objectId] = spaceDocHandle.url;
|
|
870
|
+
});
|
|
871
|
+
return spaceDocHandle;
|
|
872
|
+
}
|
|
873
|
+
onObjectBoundToDocument(handle, objectId) {
|
|
874
|
+
this._objectDocumentHandles.set(objectId, handle);
|
|
875
|
+
}
|
|
876
|
+
clearHandleReferences() {
|
|
877
|
+
const objectsWithHandles = [
|
|
878
|
+
...this._objectDocumentHandles.keys()
|
|
879
|
+
];
|
|
880
|
+
this._objectDocumentHandles.clear();
|
|
881
|
+
this._spaceRootDocHandle = null;
|
|
882
|
+
return objectsWithHandles;
|
|
883
|
+
}
|
|
884
|
+
_loadLinkedObjects(links) {
|
|
885
|
+
if (!links) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
for (const [objectId, automergeUrl] of Object.entries(links)) {
|
|
889
|
+
const logMeta = {
|
|
890
|
+
objectId,
|
|
891
|
+
automergeUrl
|
|
892
|
+
};
|
|
893
|
+
const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
|
|
894
|
+
if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
|
|
895
|
+
import_log4.log.warn("object already inlined in a different document, ignoring the link", {
|
|
896
|
+
...logMeta,
|
|
897
|
+
actualDocumentUrl: objectDocumentHandle.url
|
|
898
|
+
}, {
|
|
899
|
+
F: __dxlog_file5,
|
|
900
|
+
L: 142,
|
|
901
|
+
S: this,
|
|
902
|
+
C: (f, a) => f(...a)
|
|
903
|
+
});
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
if (objectDocumentHandle?.url === automergeUrl) {
|
|
907
|
+
import_log4.log.warn("object document was already loaded", logMeta, {
|
|
908
|
+
F: __dxlog_file5,
|
|
909
|
+
L: 149,
|
|
910
|
+
S: this,
|
|
911
|
+
C: (f, a) => f(...a)
|
|
912
|
+
});
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
const handle = this._repo.find(automergeUrl);
|
|
916
|
+
import_log4.log.debug("document loading triggered", logMeta, {
|
|
917
|
+
F: __dxlog_file5,
|
|
918
|
+
L: 153,
|
|
919
|
+
S: this,
|
|
920
|
+
C: (f, a) => f(...a)
|
|
921
|
+
});
|
|
922
|
+
this._objectDocumentHandles.set(objectId, handle);
|
|
923
|
+
void this._createObjectOnDocumentLoad(handle, objectId);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
async _initDocHandle(ctx, url) {
|
|
927
|
+
const docHandle = this._repo.find(url);
|
|
928
|
+
while (true) {
|
|
929
|
+
try {
|
|
930
|
+
await (0, import_debug.warnAfterTimeout)(5e3, "Automerge root doc load timeout (AutomergeDb)", async () => {
|
|
931
|
+
await (0, import_context3.cancelWithContext)(ctx, docHandle.whenReady());
|
|
932
|
+
});
|
|
933
|
+
break;
|
|
934
|
+
} catch (err) {
|
|
935
|
+
if (`${err}`.includes("Timeout")) {
|
|
936
|
+
import_log4.log.info("wraparound", {
|
|
937
|
+
id: docHandle.documentId,
|
|
938
|
+
state: docHandle.state
|
|
939
|
+
}, {
|
|
940
|
+
F: __dxlog_file5,
|
|
941
|
+
L: 169,
|
|
942
|
+
S: this,
|
|
943
|
+
C: (f, a) => f(...a)
|
|
944
|
+
});
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
throw err;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
if (docHandle.state === "unavailable") {
|
|
951
|
+
throw new Error("Automerge document is unavailable");
|
|
952
|
+
}
|
|
953
|
+
return docHandle;
|
|
954
|
+
}
|
|
955
|
+
_createContextBoundSpaceRootDocument(ctx) {
|
|
956
|
+
const docHandle = this._repo.create();
|
|
957
|
+
this._spaceRootDocHandle = docHandle;
|
|
958
|
+
ctx.onDispose(() => {
|
|
959
|
+
docHandle.delete();
|
|
960
|
+
this._spaceRootDocHandle = null;
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
_initDocAccess(handle) {
|
|
964
|
+
handle.change((newDoc) => {
|
|
965
|
+
newDoc.access ??= {
|
|
966
|
+
spaceKey: this._spaceKey.toHex()
|
|
967
|
+
};
|
|
968
|
+
newDoc.access.spaceKey = this._spaceKey.toHex();
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
async _createObjectOnDocumentLoad(handle, objectId) {
|
|
972
|
+
try {
|
|
973
|
+
await handle.doc([
|
|
974
|
+
"ready"
|
|
975
|
+
]);
|
|
976
|
+
const logMeta = {
|
|
977
|
+
objectId,
|
|
978
|
+
docUrl: handle.url
|
|
979
|
+
};
|
|
980
|
+
if (this.onObjectDocumentLoaded.listenerCount() === 0) {
|
|
981
|
+
import_log4.log.info("document loaded after all listeners were removed", logMeta, {
|
|
982
|
+
F: __dxlog_file5,
|
|
983
|
+
L: 205,
|
|
984
|
+
S: this,
|
|
985
|
+
C: (f, a) => f(...a)
|
|
986
|
+
});
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
const objectDocHandle = this._objectDocumentHandles.get(objectId);
|
|
990
|
+
if (objectDocHandle?.url !== handle.url) {
|
|
991
|
+
import_log4.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
|
|
992
|
+
F: __dxlog_file5,
|
|
993
|
+
L: 210,
|
|
994
|
+
S: this,
|
|
995
|
+
C: (f, a) => f(...a)
|
|
996
|
+
});
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
this.onObjectDocumentLoaded.emit({
|
|
1000
|
+
handle,
|
|
1001
|
+
objectId
|
|
1002
|
+
});
|
|
1003
|
+
} catch (err) {
|
|
1004
|
+
const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
|
|
1005
|
+
import_log4.log.warn("failed to load a document", {
|
|
1006
|
+
objectId,
|
|
1007
|
+
automergeUrl: handle.url,
|
|
1008
|
+
retryLoading: shouldRetryLoading,
|
|
1009
|
+
err
|
|
1010
|
+
}, {
|
|
1011
|
+
F: __dxlog_file5,
|
|
1012
|
+
L: 216,
|
|
1013
|
+
S: this,
|
|
1014
|
+
C: (f, a) => f(...a)
|
|
1015
|
+
});
|
|
1016
|
+
if (shouldRetryLoading) {
|
|
1017
|
+
await this._createObjectOnDocumentLoad(handle, objectId);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
|
|
1023
|
+
var encodeReference = (reference) => ({
|
|
1024
|
+
"@type": REFERENCE_TYPE_TAG,
|
|
1025
|
+
// NOTE: Automerge do not support undefined values, so we need to use null instead.
|
|
1026
|
+
itemId: reference.itemId ?? null,
|
|
1027
|
+
protocol: reference.protocol ?? null,
|
|
1028
|
+
host: reference.host ?? null
|
|
1029
|
+
});
|
|
1030
|
+
var decodeReference = (value) => new import_echo_db.Reference(value.itemId, value.protocol ?? void 0, value.host ?? void 0);
|
|
1031
|
+
var isEncodedReferenceObject = (value) => typeof value === "object" && value !== null && value["@type"] === REFERENCE_TYPE_TAG;
|
|
666
1032
|
// Annotate the CommonJS export names for ESM import in node:
|
|
667
1033
|
0 && (module.exports = {
|
|
668
1034
|
AuthExtension,
|
|
669
1035
|
AuthStatus,
|
|
1036
|
+
AutomergeDocumentLoaderImpl,
|
|
670
1037
|
AutomergeHost,
|
|
671
1038
|
AutomergeStorageAdapter,
|
|
672
1039
|
DataServiceImpl,
|
|
1040
|
+
LevelDBStorageAdapter,
|
|
673
1041
|
LocalHostNetworkAdapter,
|
|
674
1042
|
MOCK_AUTH_PROVIDER,
|
|
675
1043
|
MOCK_AUTH_VERIFIER,
|
|
676
1044
|
MeshNetworkAdapter,
|
|
677
1045
|
MetadataStore,
|
|
678
1046
|
Pipeline,
|
|
1047
|
+
REFERENCE_TYPE_TAG,
|
|
679
1048
|
SnapshotManager,
|
|
680
1049
|
SnapshotStore,
|
|
681
1050
|
Space,
|
|
@@ -685,7 +1054,12 @@ var getSpaceKeyFromDoc = (doc) => {
|
|
|
685
1054
|
TimeframeClock,
|
|
686
1055
|
codec,
|
|
687
1056
|
createMappedFeedWriter,
|
|
1057
|
+
decodeReference,
|
|
1058
|
+
encodeReference,
|
|
1059
|
+
encodingOptions,
|
|
688
1060
|
getSpaceKeyFromDoc,
|
|
1061
|
+
hasInvitationExpired,
|
|
1062
|
+
isEncodedReferenceObject,
|
|
689
1063
|
mapFeedIndexesToTimeframe,
|
|
690
1064
|
mapTimeframeToFeedIndexes,
|
|
691
1065
|
startAfter,
|