@comapeo/core 6.0.1 → 7.0.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/downloader.d.ts +4 -4
- package/dist/blob-store/downloader.d.ts.map +1 -1
- package/dist/blob-store/hyperdrive-index.d.ts +5 -3
- package/dist/blob-store/hyperdrive-index.d.ts.map +1 -1
- package/dist/blob-store/index.d.ts +6 -5
- package/dist/blob-store/index.d.ts.map +1 -1
- package/dist/core-manager/index.d.ts +6 -19
- package/dist/core-manager/index.d.ts.map +1 -1
- package/dist/datastore/index.d.ts +1 -1
- package/dist/generated/extensions.d.ts +0 -30
- package/dist/generated/extensions.d.ts.map +1 -1
- package/dist/generated/rpc.d.ts +30 -0
- package/dist/generated/rpc.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/local-peers.d.ts +12 -0
- package/dist/local-peers.d.ts.map +1 -1
- package/dist/mapeo-manager.d.ts +41 -3
- package/dist/mapeo-manager.d.ts.map +1 -1
- package/dist/mapeo-project.d.ts +5 -70
- package/dist/mapeo-project.d.ts.map +1 -1
- package/dist/schema/project.d.ts +1 -1
- package/dist/sync/namespace-sync-state.d.ts +1 -1
- package/dist/sync/peer-sync-controller.d.ts +1 -1
- package/dist/sync/sync-api.d.ts.map +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/blob-store/downloader.js +11 -4
- package/src/blob-store/hyperdrive-index.js +20 -3
- package/src/blob-store/index.js +17 -7
- package/src/core-manager/index.js +15 -70
- package/src/generated/extensions.d.ts +0 -30
- package/src/generated/extensions.js +0 -165
- package/src/generated/extensions.ts +0 -204
- package/src/generated/rpc.d.ts +30 -0
- package/src/generated/rpc.js +191 -0
- package/src/generated/rpc.ts +236 -0
- package/src/index.js +4 -1
- package/src/local-peers.js +33 -0
- package/src/mapeo-manager.js +93 -35
- package/src/mapeo-project.js +16 -106
- package/src/utils.js +2 -2
package/src/mapeo-project.js
CHANGED
|
@@ -3,7 +3,6 @@ import Database from 'better-sqlite3'
|
|
|
3
3
|
import { decodeBlockPrefix, decode, parseVersionId } from '@comapeo/schema'
|
|
4
4
|
import { drizzle } from 'drizzle-orm/better-sqlite3'
|
|
5
5
|
import { sql, count, eq } from 'drizzle-orm'
|
|
6
|
-
import { TypedEmitter } from 'tiny-typed-emitter'
|
|
7
6
|
import ZipArchive from 'zip-stream-promise'
|
|
8
7
|
import * as b4a from 'b4a'
|
|
9
8
|
import mime from 'mime/lite'
|
|
@@ -39,18 +38,13 @@ import {
|
|
|
39
38
|
getWinner,
|
|
40
39
|
mapAndValidateCoreOwnership,
|
|
41
40
|
} from './core-ownership.js'
|
|
42
|
-
import {
|
|
43
|
-
BLOCKED_ROLE_ID,
|
|
44
|
-
Roles,
|
|
45
|
-
LEFT_ROLE_ID,
|
|
46
|
-
INACTIVE_MEMBER_ROLE_IDS,
|
|
47
|
-
} from './roles.js'
|
|
41
|
+
import { BLOCKED_ROLE_ID, Roles, LEFT_ROLE_ID } from './roles.js'
|
|
48
42
|
import {
|
|
49
43
|
buildBlobId,
|
|
50
44
|
getDeviceId,
|
|
45
|
+
noop,
|
|
51
46
|
projectKeyToId,
|
|
52
47
|
projectKeyToPublicId,
|
|
53
|
-
validateMapShareExtension,
|
|
54
48
|
valueOf,
|
|
55
49
|
} from './utils.js'
|
|
56
50
|
import { migrate } from './lib/drizzle-helpers.js'
|
|
@@ -73,7 +67,6 @@ import {
|
|
|
73
67
|
ExhaustivenessError,
|
|
74
68
|
nullIfNotFound,
|
|
75
69
|
GeoJSONExportError,
|
|
76
|
-
InvalidMapShareError,
|
|
77
70
|
MultipleCategoryImportsError,
|
|
78
71
|
UnexpectedDocSchemaError,
|
|
79
72
|
} from './errors.js'
|
|
@@ -81,6 +74,8 @@ import { WebSocket } from 'ws'
|
|
|
81
74
|
import fs from 'node:fs'
|
|
82
75
|
|
|
83
76
|
import ensureError from 'ensure-error'
|
|
77
|
+
import ReadyResource from 'ready-resource'
|
|
78
|
+
|
|
84
79
|
/** @import { MapShareExtension } from './generated/extensions.js' */
|
|
85
80
|
/** @import { ProjectSettingsValue, Observation, Track } from '@comapeo/schema' */
|
|
86
81
|
/** @import { Attachment, CoreStorage, BlobFilter, BlobId, BlobStoreEntriesStream, KeyPair, Namespace, ReplicationStream, GenericBlobFilter, MapeoValueMap, MapeoDocMap } from './types.js' */
|
|
@@ -129,36 +124,16 @@ const VARIANT_EXPORT_ORDER = ['original', 'preview', 'thumbnail']
|
|
|
129
124
|
* @property {Role & {reason: string | undefined}} role
|
|
130
125
|
*/
|
|
131
126
|
|
|
132
|
-
/**
|
|
133
|
-
* @typedef {object} AugmentedMapShareProperties
|
|
134
|
-
* @property {readonly [number, number, number, number]} bounds - Bounding box of the shared map [W, S, E, N].
|
|
135
|
-
* @property {readonly [string, ...string[]]} mapShareUrls - URLs associated with the map share.
|
|
136
|
-
* @property {number} mapShareReceivedAt - Timestamp when the map share was received.
|
|
137
|
-
* @property {string} senderDeviceId - The ID of the device that sent the map share.
|
|
138
|
-
* @property {string} [senderDeviceName] - The name of the device that sent the map share.
|
|
139
|
-
* @property {string} receiverDeviceId - The deviceId of the peer the map share was sent to
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* @typedef {Omit<MapShareExtension, 'bounds' | 'mapShareUrls' | 'receiverDeviceKey'> & AugmentedMapShareProperties} MapShare
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* @typedef {Omit<MapShare, 'mapShareReceivedAt' | 'senderDeviceId' | 'senderDeviceName'>} MapShareSend
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
127
|
/**
|
|
151
128
|
* @typedef {object} ProjectEvents
|
|
152
129
|
* @property {() => void} close Project resources have been cleared up
|
|
153
130
|
* @property {(changeEvent: RoleChangeEvent) => void} own-role-change
|
|
154
|
-
* @property {(e: Error, mapShare: MapShareExtension) => void} map-share-error - Emitted when an incoming map share fails to be recieved due to formatting issues
|
|
155
|
-
* @property {(mapShare: MapShare) => void} map-share - Emitted when a map share is recieved from someone on the project
|
|
156
131
|
*/
|
|
157
132
|
|
|
158
133
|
/**
|
|
159
|
-
* @extends {
|
|
134
|
+
* @extends {ReadyResource<ProjectEvents>}
|
|
160
135
|
*/
|
|
161
|
-
export class MapeoProject extends
|
|
136
|
+
export class MapeoProject extends ReadyResource {
|
|
162
137
|
#projectKey
|
|
163
138
|
#deviceId
|
|
164
139
|
#identityKeypair
|
|
@@ -563,22 +538,17 @@ export class MapeoProject extends TypedEmitter {
|
|
|
563
538
|
}
|
|
564
539
|
})
|
|
565
540
|
|
|
566
|
-
this.#coreManager.on('map-share', (mapShareBase, senderDeviceId) =>
|
|
567
|
-
this.#handleMapShare(mapShareBase, senderDeviceId).catch((e) => {
|
|
568
|
-
this.emit('map-share-error', e, mapShareBase)
|
|
569
|
-
this.#l.log(
|
|
570
|
-
'Error: Unable to handle incoming Map Share',
|
|
571
|
-
ensureError(e)
|
|
572
|
-
)
|
|
573
|
-
})
|
|
574
|
-
)
|
|
575
|
-
|
|
576
541
|
this.once('close', () => {
|
|
577
542
|
localPeers.off('peer-add', onPeerAdd)
|
|
578
543
|
localPeers.off('discovery-key', onDiscoverykey)
|
|
579
544
|
})
|
|
580
545
|
|
|
581
546
|
this.#l.log('Created project instance %h, %s', projectKey, isArchiveDevice)
|
|
547
|
+
|
|
548
|
+
// Not necessary, because coreManager and blobStore "auto-open", but leaving
|
|
549
|
+
// this here defensively in case we add additional resources to _open() in
|
|
550
|
+
// the future
|
|
551
|
+
this.ready().catch(noop)
|
|
582
552
|
}
|
|
583
553
|
|
|
584
554
|
/**
|
|
@@ -620,23 +590,23 @@ export class MapeoProject extends TypedEmitter {
|
|
|
620
590
|
|
|
621
591
|
/**
|
|
622
592
|
* Resolves when hypercores have all loaded
|
|
623
|
-
*
|
|
624
593
|
* @returns {Promise<void>}
|
|
625
594
|
*/
|
|
626
|
-
|
|
627
|
-
|
|
595
|
+
async _open() {
|
|
596
|
+
await this.#coreManager.ready()
|
|
597
|
+
await this.#blobStore.ready()
|
|
628
598
|
}
|
|
629
599
|
|
|
630
600
|
/**
|
|
631
601
|
*/
|
|
632
|
-
async
|
|
602
|
+
async _close() {
|
|
633
603
|
this.#l.log('closing project %h', this.#projectId)
|
|
634
|
-
this.#blobStore.close()
|
|
635
604
|
const dataStorePromises = []
|
|
636
605
|
for (const dataStore of Object.values(this.#dataStores)) {
|
|
637
606
|
dataStorePromises.push(dataStore.close())
|
|
638
607
|
}
|
|
639
608
|
await Promise.all(dataStorePromises)
|
|
609
|
+
await this.#blobStore.close()
|
|
640
610
|
await this.#coreManager.close()
|
|
641
611
|
|
|
642
612
|
this.#sqlite.close()
|
|
@@ -805,43 +775,6 @@ export class MapeoProject extends TypedEmitter {
|
|
|
805
775
|
this.emit('own-role-change', { role })
|
|
806
776
|
}
|
|
807
777
|
|
|
808
|
-
/**
|
|
809
|
-
* @param {MapShareExtension} mapShareBase
|
|
810
|
-
* @param {string} senderDeviceId
|
|
811
|
-
*/
|
|
812
|
-
async #handleMapShare(mapShareBase, senderDeviceId) {
|
|
813
|
-
const mapShareReceivedAt = Date.now()
|
|
814
|
-
|
|
815
|
-
validateMapShareExtension(mapShareBase)
|
|
816
|
-
|
|
817
|
-
const sender = await this.$member.getById(senderDeviceId)
|
|
818
|
-
|
|
819
|
-
if (INACTIVE_MEMBER_ROLE_IDS.includes(sender.role.roleId)) {
|
|
820
|
-
throw new InvalidMapShareError(
|
|
821
|
-
`Map Share Sender is not an active member of the project (role: ${sender.role.name})`
|
|
822
|
-
)
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
const { receiverDeviceKey, ...mapShareData } = mapShareBase
|
|
826
|
-
|
|
827
|
-
const receiverDeviceId = receiverDeviceKey.toString('hex')
|
|
828
|
-
|
|
829
|
-
if (receiverDeviceId !== this.#deviceId) {
|
|
830
|
-
throw new Error('Got map share intended for a different peer')
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
/** @type {MapShare} */
|
|
834
|
-
const mapShare = {
|
|
835
|
-
...mapShareData,
|
|
836
|
-
senderDeviceId,
|
|
837
|
-
senderDeviceName: sender.name,
|
|
838
|
-
mapShareReceivedAt,
|
|
839
|
-
receiverDeviceId,
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
this.emit('map-share', mapShare)
|
|
843
|
-
}
|
|
844
|
-
|
|
845
778
|
/**
|
|
846
779
|
* @deprecated
|
|
847
780
|
* @param {string} originalVersionId The `originalVersionId` from a document.
|
|
@@ -1490,29 +1423,6 @@ export class MapeoProject extends TypedEmitter {
|
|
|
1490
1423
|
this.#importingCategories = false
|
|
1491
1424
|
}
|
|
1492
1425
|
}
|
|
1493
|
-
|
|
1494
|
-
/**
|
|
1495
|
-
* Send a map share offer to the peer with device ID `mapShare.receiverDeviceId`
|
|
1496
|
-
*
|
|
1497
|
-
* @param {MapShareSend} mapShare
|
|
1498
|
-
* @param {object} [options]
|
|
1499
|
-
* @param {boolean} [options.__testOnlyBypassValidation=false] Warning: Do not use!
|
|
1500
|
-
*/
|
|
1501
|
-
async $sendMapShare(mapShare, { __testOnlyBypassValidation = false } = {}) {
|
|
1502
|
-
const { receiverDeviceId, ...mapShareData } = mapShare
|
|
1503
|
-
const receiverDeviceKey = Buffer.from(receiverDeviceId, 'hex')
|
|
1504
|
-
|
|
1505
|
-
/** @type {MapShareExtension} */
|
|
1506
|
-
// @ts-expect-error readonly fields being assigned as mutable
|
|
1507
|
-
const shareExtension = {
|
|
1508
|
-
...mapShareData,
|
|
1509
|
-
receiverDeviceKey,
|
|
1510
|
-
}
|
|
1511
|
-
if (!__testOnlyBypassValidation) {
|
|
1512
|
-
validateMapShareExtension(shareExtension)
|
|
1513
|
-
}
|
|
1514
|
-
await this.#coreManager.sendMapShare(shareExtension)
|
|
1515
|
-
}
|
|
1516
1426
|
}
|
|
1517
1427
|
|
|
1518
1428
|
/**
|
package/src/utils.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from './errors.js'
|
|
12
12
|
import pTimeout, { TimeoutError as pTimeoutError } from 'p-timeout'
|
|
13
13
|
|
|
14
|
-
/** @import { MapShareExtension } from './generated/
|
|
14
|
+
/** @import { MapShareExtension } from './generated/rpc.js' */
|
|
15
15
|
/** @import {Attachment, BlobId} from "./types.js" */
|
|
16
16
|
|
|
17
17
|
const PROJECT_INVITE_ID_SALT = Buffer.from('mapeo project invite id', 'ascii')
|
|
@@ -267,7 +267,7 @@ export async function timeoutPromise(promise, opts) {
|
|
|
267
267
|
* Does not validate device ID or device name
|
|
268
268
|
*
|
|
269
269
|
* @param {MapShareExtension} mapShare
|
|
270
|
-
* @returns {asserts mapShare is { [K in keyof MapShareExtension]: import('./mapeo-
|
|
270
|
+
* @returns {asserts mapShare is { [K in keyof MapShareExtension]: import('./mapeo-manager.js').MapShare[K] }} - this validates the properties that MapShareExtension and MapShare have in common - bounds tuple and mapShareUrls
|
|
271
271
|
*/
|
|
272
272
|
export function validateMapShareExtension(mapShare) {
|
|
273
273
|
const {
|