@comapeo/core 2.0.1 → 2.1.0
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/blob-store/index.d.ts +5 -8
- package/dist/blob-store/index.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/core-manager/index.d.ts +10 -0
- package/dist/core-manager/index.d.ts.map +1 -1
- package/dist/datastore/index.d.ts +5 -4
- package/dist/datastore/index.d.ts.map +1 -1
- package/dist/generated/extensions.d.ts +31 -0
- package/dist/generated/extensions.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/drizzle-helpers.d.ts +6 -0
- package/dist/lib/drizzle-helpers.d.ts.map +1 -0
- package/dist/lib/error.d.ts +37 -0
- package/dist/lib/error.d.ts.map +1 -0
- package/dist/lib/get-own.d.ts +9 -0
- package/dist/lib/get-own.d.ts.map +1 -0
- package/dist/lib/is-hostname-ip-address.d.ts +17 -0
- package/dist/lib/is-hostname-ip-address.d.ts.map +1 -0
- package/dist/lib/ws-core-replicator.d.ts +11 -0
- package/dist/lib/ws-core-replicator.d.ts.map +1 -0
- package/dist/mapeo-manager.d.ts +18 -22
- package/dist/mapeo-manager.d.ts.map +1 -1
- package/dist/mapeo-project.d.ts +448 -15
- package/dist/mapeo-project.d.ts.map +1 -1
- package/dist/member-api.d.ts +40 -1
- package/dist/member-api.d.ts.map +1 -1
- package/dist/schema/client.d.ts +17 -5
- package/dist/schema/client.d.ts.map +1 -1
- package/dist/schema/project.d.ts +210 -0
- package/dist/schema/project.d.ts.map +1 -1
- package/dist/sync/peer-sync-controller.d.ts.map +1 -1
- package/dist/sync/sync-api.d.ts +28 -2
- package/dist/sync/sync-api.d.ts.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/drizzle/client/0001_chubby_cargill.sql +12 -0
- package/drizzle/client/meta/0001_snapshot.json +208 -0
- package/drizzle/client/meta/_journal.json +7 -0
- package/drizzle/project/0001_medical_wendell_rand.sql +22 -0
- package/drizzle/project/meta/0001_snapshot.json +1267 -0
- package/drizzle/project/meta/_journal.json +7 -0
- package/package.json +9 -5
- package/src/blob-store/index.js +3 -2
- package/src/constants.js +4 -1
- package/src/core-manager/index.js +58 -2
- package/src/datastore/README.md +1 -2
- package/src/datastore/index.js +4 -5
- package/src/fastify-plugins/blobs.js +1 -0
- package/src/generated/extensions.d.ts +31 -0
- package/src/generated/extensions.js +150 -0
- package/src/generated/extensions.ts +181 -0
- package/src/index.js +10 -0
- package/src/invite-api.js +1 -1
- package/src/lib/drizzle-helpers.js +79 -0
- package/src/lib/error.js +47 -0
- package/src/lib/get-own.js +10 -0
- package/src/lib/is-hostname-ip-address.js +26 -0
- package/src/lib/ws-core-replicator.js +47 -0
- package/src/mapeo-manager.js +71 -43
- package/src/mapeo-project.js +153 -43
- package/src/member-api.js +253 -2
- package/src/schema/client.js +4 -3
- package/src/schema/project.js +7 -0
- package/src/sync/peer-sync-controller.js +1 -0
- package/src/sync/sync-api.js +171 -3
- package/src/types.ts +4 -3
- package/dist/lib/timing-safe-equal.d.ts +0 -15
- package/dist/lib/timing-safe-equal.d.ts.map +0 -1
- package/src/lib/timing-safe-equal.js +0 -34
package/src/mapeo-project.js
CHANGED
|
@@ -2,7 +2,6 @@ import path from 'path'
|
|
|
2
2
|
import Database from 'better-sqlite3'
|
|
3
3
|
import { decodeBlockPrefix, decode, parseVersionId } from '@comapeo/schema'
|
|
4
4
|
import { drizzle } from 'drizzle-orm/better-sqlite3'
|
|
5
|
-
import { migrate } from 'drizzle-orm/better-sqlite3/migrator'
|
|
6
5
|
import { discoveryKey } from 'hypercore-crypto'
|
|
7
6
|
import { TypedEmitter } from 'tiny-typed-emitter'
|
|
8
7
|
|
|
@@ -24,6 +23,7 @@ import {
|
|
|
24
23
|
roleTable,
|
|
25
24
|
iconTable,
|
|
26
25
|
translationTable,
|
|
26
|
+
remoteDetectionAlertTable,
|
|
27
27
|
} from './schema/project.js'
|
|
28
28
|
import {
|
|
29
29
|
CoreOwnership,
|
|
@@ -38,20 +38,26 @@ import {
|
|
|
38
38
|
} from './roles.js'
|
|
39
39
|
import {
|
|
40
40
|
assert,
|
|
41
|
+
ExhaustivenessError,
|
|
41
42
|
getDeviceId,
|
|
42
43
|
projectKeyToId,
|
|
43
44
|
projectKeyToPublicId,
|
|
44
45
|
valueOf,
|
|
45
46
|
} from './utils.js'
|
|
47
|
+
import { migrate } from './lib/drizzle-helpers.js'
|
|
46
48
|
import { omit } from './lib/omit.js'
|
|
47
49
|
import { MemberApi } from './member-api.js'
|
|
48
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
SyncApi,
|
|
52
|
+
kHandleDiscoveryKey,
|
|
53
|
+
kWaitForInitialSyncWithPeer,
|
|
54
|
+
} from './sync/sync-api.js'
|
|
49
55
|
import { Logger } from './logger.js'
|
|
50
56
|
import { IconApi } from './icon-api.js'
|
|
51
57
|
import { readConfig } from './config-import.js'
|
|
52
58
|
import TranslationApi from './translation-api.js'
|
|
53
59
|
/** @import { ProjectSettingsValue } from '@comapeo/schema' */
|
|
54
|
-
/** @import { CoreStorage, KeyPair, Namespace } from './types.js' */
|
|
60
|
+
/** @import { CoreStorage, KeyPair, Namespace, ReplicationStream } from './types.js' */
|
|
55
61
|
|
|
56
62
|
/** @typedef {Omit<ProjectSettingsValue, 'schemaName'>} EditableProjectSettings */
|
|
57
63
|
/** @typedef {ProjectSettingsValue['configMetadata']} ConfigMetadata */
|
|
@@ -66,6 +72,8 @@ export const kProjectReplicate = Symbol('replicate project')
|
|
|
66
72
|
export const kDataTypes = Symbol('dataTypes')
|
|
67
73
|
export const kProjectLeave = Symbol('leave project')
|
|
68
74
|
export const kClearDataIfLeft = Symbol('clear data if left project')
|
|
75
|
+
export const kSetIsArchiveDevice = Symbol('set isArchiveDevice')
|
|
76
|
+
export const kIsArchiveDevice = Symbol('isArchiveDevice (temp - test only)')
|
|
69
77
|
|
|
70
78
|
const EMPTY_PROJECT_SETTINGS = Object.freeze({})
|
|
71
79
|
|
|
@@ -73,8 +81,9 @@ const EMPTY_PROJECT_SETTINGS = Object.freeze({})
|
|
|
73
81
|
* @extends {TypedEmitter<{ close: () => void }>}
|
|
74
82
|
*/
|
|
75
83
|
export class MapeoProject extends TypedEmitter {
|
|
76
|
-
#
|
|
84
|
+
#projectKey
|
|
77
85
|
#deviceId
|
|
86
|
+
#identityKeypair
|
|
78
87
|
#coreManager
|
|
79
88
|
#indexWriter
|
|
80
89
|
#dataStores
|
|
@@ -91,6 +100,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
91
100
|
#l
|
|
92
101
|
/** @type {Boolean} this avoids loading multiple configs in parallel */
|
|
93
102
|
#loadingConfig
|
|
103
|
+
#isArchiveDevice
|
|
94
104
|
|
|
95
105
|
static EMPTY_PROJECT_SETTINGS = EMPTY_PROJECT_SETTINGS
|
|
96
106
|
|
|
@@ -107,6 +117,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
107
117
|
* @param {CoreStorage} opts.coreStorage Folder to store all hypercore data
|
|
108
118
|
* @param {(mediaType: 'blobs' | 'icons') => Promise<string>} opts.getMediaBaseUrl
|
|
109
119
|
* @param {import('./local-peers.js').LocalPeers} opts.localPeers
|
|
120
|
+
* @param {boolean} opts.isArchiveDevice Whether this device is an archive device
|
|
110
121
|
* @param {Logger} [opts.logger]
|
|
111
122
|
*
|
|
112
123
|
*/
|
|
@@ -123,20 +134,58 @@ export class MapeoProject extends TypedEmitter {
|
|
|
123
134
|
getMediaBaseUrl,
|
|
124
135
|
localPeers,
|
|
125
136
|
logger,
|
|
137
|
+
isArchiveDevice,
|
|
126
138
|
}) {
|
|
127
139
|
super()
|
|
128
140
|
|
|
129
141
|
this.#l = Logger.create('project', logger)
|
|
130
142
|
this.#deviceId = getDeviceId(keyManager)
|
|
131
|
-
this.#
|
|
143
|
+
this.#projectKey = projectKey
|
|
132
144
|
this.#loadingConfig = false
|
|
145
|
+
this.#isArchiveDevice = isArchiveDevice
|
|
146
|
+
|
|
147
|
+
const getReplicationStream = this[kProjectReplicate].bind(this, true)
|
|
133
148
|
|
|
134
149
|
///////// 1. Setup database
|
|
150
|
+
|
|
135
151
|
this.#sqlite = new Database(dbPath)
|
|
136
152
|
const db = drizzle(this.#sqlite)
|
|
137
|
-
migrate(db, {
|
|
153
|
+
const migrationResult = migrate(db, {
|
|
154
|
+
migrationsFolder: projectMigrationsFolder,
|
|
155
|
+
})
|
|
156
|
+
let reindex
|
|
157
|
+
switch (migrationResult) {
|
|
158
|
+
case 'initialized database':
|
|
159
|
+
case 'no migration':
|
|
160
|
+
reindex = false
|
|
161
|
+
break
|
|
162
|
+
case 'migrated':
|
|
163
|
+
reindex = true
|
|
164
|
+
break
|
|
165
|
+
default:
|
|
166
|
+
throw new ExhaustivenessError(migrationResult)
|
|
167
|
+
}
|
|
138
168
|
|
|
139
|
-
|
|
169
|
+
const indexedTables = [
|
|
170
|
+
observationTable,
|
|
171
|
+
trackTable,
|
|
172
|
+
presetTable,
|
|
173
|
+
fieldTable,
|
|
174
|
+
coreOwnershipTable,
|
|
175
|
+
roleTable,
|
|
176
|
+
deviceInfoTable,
|
|
177
|
+
iconTable,
|
|
178
|
+
translationTable,
|
|
179
|
+
remoteDetectionAlertTable,
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
///////// 2. Wipe data if we need to re-index
|
|
183
|
+
|
|
184
|
+
if (reindex) {
|
|
185
|
+
for (const table of indexedTables) db.delete(table).run()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
///////// 3. Setup random-access-storage functions
|
|
140
189
|
|
|
141
190
|
/** @type {ConstructorParameters<typeof CoreManager>[0]['storage']} */
|
|
142
191
|
const coreManagerStorage = (name) =>
|
|
@@ -146,7 +195,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
146
195
|
const indexerStorage = (name) =>
|
|
147
196
|
coreStorage(path.join(INDEXER_STORAGE_FOLDER_NAME, name))
|
|
148
197
|
|
|
149
|
-
/////////
|
|
198
|
+
///////// 4. Create instances
|
|
150
199
|
|
|
151
200
|
this.#coreManager = new CoreManager({
|
|
152
201
|
projectSecretKey,
|
|
@@ -159,17 +208,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
159
208
|
})
|
|
160
209
|
|
|
161
210
|
this.#indexWriter = new IndexWriter({
|
|
162
|
-
tables:
|
|
163
|
-
observationTable,
|
|
164
|
-
trackTable,
|
|
165
|
-
presetTable,
|
|
166
|
-
fieldTable,
|
|
167
|
-
coreOwnershipTable,
|
|
168
|
-
roleTable,
|
|
169
|
-
deviceInfoTable,
|
|
170
|
-
iconTable,
|
|
171
|
-
translationTable,
|
|
172
|
-
],
|
|
211
|
+
tables: indexedTables,
|
|
173
212
|
sqlite: this.#sqlite,
|
|
174
213
|
getWinner,
|
|
175
214
|
mapDoc: (doc, version) => {
|
|
@@ -191,6 +230,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
191
230
|
namespace: 'auth',
|
|
192
231
|
batch: (entries) => this.#indexWriter.batch(entries),
|
|
193
232
|
storage: indexerStorage,
|
|
233
|
+
reindex,
|
|
194
234
|
}),
|
|
195
235
|
config: new DataStore({
|
|
196
236
|
coreManager: this.#coreManager,
|
|
@@ -201,12 +241,14 @@ export class MapeoProject extends TypedEmitter {
|
|
|
201
241
|
sharedIndexWriter,
|
|
202
242
|
}),
|
|
203
243
|
storage: indexerStorage,
|
|
244
|
+
reindex,
|
|
204
245
|
}),
|
|
205
246
|
data: new DataStore({
|
|
206
247
|
coreManager: this.#coreManager,
|
|
207
248
|
namespace: 'data',
|
|
208
249
|
batch: (entries) => this.#indexWriter.batch(entries),
|
|
209
250
|
storage: indexerStorage,
|
|
251
|
+
reindex,
|
|
210
252
|
}),
|
|
211
253
|
}
|
|
212
254
|
|
|
@@ -225,6 +267,12 @@ export class MapeoProject extends TypedEmitter {
|
|
|
225
267
|
db,
|
|
226
268
|
getTranslations,
|
|
227
269
|
}),
|
|
270
|
+
remoteDetectionAlert: new DataType({
|
|
271
|
+
dataStore: this.#dataStores.data,
|
|
272
|
+
table: remoteDetectionAlertTable,
|
|
273
|
+
db,
|
|
274
|
+
getTranslations,
|
|
275
|
+
}),
|
|
228
276
|
preset: new DataType({
|
|
229
277
|
dataStore: this.#dataStores.config,
|
|
230
278
|
table: presetTable,
|
|
@@ -276,7 +324,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
276
324
|
},
|
|
277
325
|
}),
|
|
278
326
|
}
|
|
279
|
-
|
|
327
|
+
this.#identityKeypair = keyManager.getIdentityKeypair()
|
|
280
328
|
const coreKeypairs = getCoreKeypairs({
|
|
281
329
|
projectKey,
|
|
282
330
|
projectSecretKey,
|
|
@@ -285,14 +333,14 @@ export class MapeoProject extends TypedEmitter {
|
|
|
285
333
|
this.#coreOwnership = new CoreOwnership({
|
|
286
334
|
dataType: this.#dataTypes.coreOwnership,
|
|
287
335
|
coreKeypairs,
|
|
288
|
-
identityKeypair,
|
|
336
|
+
identityKeypair: this.#identityKeypair,
|
|
289
337
|
})
|
|
290
338
|
this.#roles = new Roles({
|
|
291
339
|
dataType: this.#dataTypes.role,
|
|
292
340
|
coreOwnership: this.#coreOwnership,
|
|
293
341
|
coreManager: this.#coreManager,
|
|
294
342
|
projectKey: projectKey,
|
|
295
|
-
deviceKey:
|
|
343
|
+
deviceKey: this.#identityKeypair.publicKey,
|
|
296
344
|
})
|
|
297
345
|
|
|
298
346
|
this.#memberApi = new MemberApi({
|
|
@@ -300,16 +348,18 @@ export class MapeoProject extends TypedEmitter {
|
|
|
300
348
|
roles: this.#roles,
|
|
301
349
|
coreOwnership: this.#coreOwnership,
|
|
302
350
|
encryptionKeys,
|
|
351
|
+
getProjectName: this.#getProjectName.bind(this),
|
|
303
352
|
projectKey,
|
|
304
353
|
rpc: localPeers,
|
|
354
|
+
getReplicationStream,
|
|
355
|
+
waitForInitialSyncWithPeer: (deviceId, abortSignal) =>
|
|
356
|
+
this.$sync[kWaitForInitialSyncWithPeer](deviceId, abortSignal),
|
|
305
357
|
dataTypes: {
|
|
306
358
|
deviceInfo: this.#dataTypes.deviceInfo,
|
|
307
359
|
project: this.#dataTypes.projectSettings,
|
|
308
360
|
},
|
|
309
361
|
})
|
|
310
362
|
|
|
311
|
-
const projectPublicId = projectKeyToPublicId(projectKey)
|
|
312
|
-
|
|
313
363
|
this.#blobStore = new BlobStore({
|
|
314
364
|
coreManager: this.#coreManager,
|
|
315
365
|
})
|
|
@@ -321,7 +371,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
321
371
|
if (!base.endsWith('/')) {
|
|
322
372
|
base += '/'
|
|
323
373
|
}
|
|
324
|
-
return base + projectPublicId
|
|
374
|
+
return base + this.#projectPublicId
|
|
325
375
|
},
|
|
326
376
|
})
|
|
327
377
|
|
|
@@ -333,7 +383,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
333
383
|
if (!base.endsWith('/')) {
|
|
334
384
|
base += '/'
|
|
335
385
|
}
|
|
336
|
-
return base + projectPublicId
|
|
386
|
+
return base + this.#projectPublicId
|
|
337
387
|
},
|
|
338
388
|
})
|
|
339
389
|
|
|
@@ -341,14 +391,33 @@ export class MapeoProject extends TypedEmitter {
|
|
|
341
391
|
coreManager: this.#coreManager,
|
|
342
392
|
coreOwnership: this.#coreOwnership,
|
|
343
393
|
roles: this.#roles,
|
|
394
|
+
blobDownloadFilter: null,
|
|
344
395
|
logger: this.#l,
|
|
396
|
+
getServerWebsocketUrls: async () => {
|
|
397
|
+
const members = await this.#memberApi.getMany()
|
|
398
|
+
/** @type {string[]} */
|
|
399
|
+
const serverWebsocketUrls = []
|
|
400
|
+
for (const member of members) {
|
|
401
|
+
if (
|
|
402
|
+
member.deviceType === 'selfHostedServer' &&
|
|
403
|
+
member.selfHostedServerDetails
|
|
404
|
+
) {
|
|
405
|
+
const { baseUrl } = member.selfHostedServerDetails
|
|
406
|
+
const wsUrl = new URL(`/sync/${this.#projectPublicId}`, baseUrl)
|
|
407
|
+
wsUrl.protocol = wsUrl.protocol === 'http:' ? 'ws:' : 'wss:'
|
|
408
|
+
serverWebsocketUrls.push(wsUrl.href)
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return serverWebsocketUrls
|
|
412
|
+
},
|
|
413
|
+
getReplicationStream,
|
|
345
414
|
})
|
|
346
415
|
|
|
347
416
|
this.#translationApi = new TranslationApi({
|
|
348
417
|
dataType: this.#dataTypes.translation,
|
|
349
418
|
})
|
|
350
419
|
|
|
351
|
-
/////////
|
|
420
|
+
///////// 5. Replicate local peers automatically
|
|
352
421
|
|
|
353
422
|
// Replicate already connected local peers
|
|
354
423
|
for (const peer of localPeers.peers) {
|
|
@@ -416,6 +485,14 @@ export class MapeoProject extends TypedEmitter {
|
|
|
416
485
|
return this.#deviceId
|
|
417
486
|
}
|
|
418
487
|
|
|
488
|
+
get #projectId() {
|
|
489
|
+
return projectKeyToId(this.#projectKey)
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
get #projectPublicId() {
|
|
493
|
+
return projectKeyToPublicId(this.#projectKey)
|
|
494
|
+
}
|
|
495
|
+
|
|
419
496
|
/**
|
|
420
497
|
* Resolves when hypercores have all loaded
|
|
421
498
|
*
|
|
@@ -499,6 +576,10 @@ export class MapeoProject extends TypedEmitter {
|
|
|
499
576
|
return this.#dataTypes.field
|
|
500
577
|
}
|
|
501
578
|
|
|
579
|
+
get remoteDetectionAlert() {
|
|
580
|
+
return this.#dataTypes.remoteDetectionAlert
|
|
581
|
+
}
|
|
582
|
+
|
|
502
583
|
get $member() {
|
|
503
584
|
return this.#memberApi
|
|
504
585
|
}
|
|
@@ -557,6 +638,13 @@ export class MapeoProject extends TypedEmitter {
|
|
|
557
638
|
}
|
|
558
639
|
}
|
|
559
640
|
|
|
641
|
+
/**
|
|
642
|
+
* @returns {Promise<undefined | string>}
|
|
643
|
+
*/
|
|
644
|
+
async #getProjectName() {
|
|
645
|
+
return (await this.$getProjectSettings()).name
|
|
646
|
+
}
|
|
647
|
+
|
|
560
648
|
async $getOwnRole() {
|
|
561
649
|
return this.#roles.getRole(this.#deviceId)
|
|
562
650
|
}
|
|
@@ -578,28 +666,38 @@ export class MapeoProject extends TypedEmitter {
|
|
|
578
666
|
/**
|
|
579
667
|
* Replicate a project to a @hyperswarm/secret-stream. Invites will not
|
|
580
668
|
* function because the RPC channel is not connected for project replication,
|
|
581
|
-
* and only this project will replicate
|
|
582
|
-
* need to replicate the manager instance via manager[kManagerReplicate])
|
|
669
|
+
* and only this project will replicate.
|
|
583
670
|
*
|
|
584
|
-
* @param {
|
|
671
|
+
* @param {(
|
|
672
|
+
* boolean |
|
|
673
|
+
* import('stream').Duplex |
|
|
674
|
+
* import('streamx').Duplex
|
|
675
|
+
* )} isInitiatorOrStream
|
|
676
|
+
* @returns {ReplicationStream}
|
|
585
677
|
*/
|
|
586
|
-
[kProjectReplicate](
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
678
|
+
[kProjectReplicate](isInitiatorOrStream) {
|
|
679
|
+
const replicationStream = this.#coreManager.creatorCore.replicate(
|
|
680
|
+
isInitiatorOrStream,
|
|
681
|
+
/**
|
|
682
|
+
* Hypercore types need updating.
|
|
683
|
+
* @type {any}
|
|
684
|
+
*/ ({
|
|
685
|
+
keyPair: this.#identityKeypair,
|
|
686
|
+
/** @param {Buffer} discoveryKey */
|
|
687
|
+
ondiscoverykey: async (discoveryKey) => {
|
|
688
|
+
const protomux =
|
|
689
|
+
/** @type {import('protomux')<import('@hyperswarm/secret-stream')>} */ (
|
|
690
|
+
replicationStream.noiseStream.userData
|
|
691
|
+
)
|
|
692
|
+
this.#syncApi[kHandleDiscoveryKey](discoveryKey, protomux)
|
|
693
|
+
},
|
|
694
|
+
})
|
|
695
|
+
)
|
|
598
696
|
return replicationStream
|
|
599
697
|
}
|
|
600
698
|
|
|
601
699
|
/**
|
|
602
|
-
* @param {Pick<import('@comapeo/schema').DeviceInfoValue, 'name' | 'deviceType'>} value
|
|
700
|
+
* @param {Pick<import('@comapeo/schema').DeviceInfoValue, 'name' | 'deviceType' | 'selfHostedServerDetails'>} value
|
|
603
701
|
* @returns {Promise<import('@comapeo/schema').DeviceInfo>}
|
|
604
702
|
*/
|
|
605
703
|
async [kSetOwnDeviceInfo](value) {
|
|
@@ -612,6 +710,7 @@ export class MapeoProject extends TypedEmitter {
|
|
|
612
710
|
const doc = {
|
|
613
711
|
name: value.name,
|
|
614
712
|
deviceType: value.deviceType,
|
|
713
|
+
selfHostedServerDetails: value.selfHostedServerDetails,
|
|
615
714
|
schemaName: /** @type {const} */ ('deviceInfo'),
|
|
616
715
|
}
|
|
617
716
|
|
|
@@ -625,6 +724,17 @@ export class MapeoProject extends TypedEmitter {
|
|
|
625
724
|
return deviceInfo.update(existingDoc.versionId, doc)
|
|
626
725
|
}
|
|
627
726
|
|
|
727
|
+
/** @param {boolean} isArchiveDevice */
|
|
728
|
+
async [kSetIsArchiveDevice](isArchiveDevice) {
|
|
729
|
+
this.#isArchiveDevice = isArchiveDevice
|
|
730
|
+
// TODO: call this.#syncApi[kSetBlobDownloadFilter]()
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/** @returns {boolean} */
|
|
734
|
+
get [kIsArchiveDevice]() {
|
|
735
|
+
return this.#isArchiveDevice
|
|
736
|
+
}
|
|
737
|
+
|
|
628
738
|
/**
|
|
629
739
|
* @returns {import('./icon-api.js').IconApi}
|
|
630
740
|
*/
|