@comapeo/core 3.1.2 → 3.2.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/index.d.ts.map +1 -1
- package/dist/mapeo-project.d.ts +78 -36
- package/dist/mapeo-project.d.ts.map +1 -1
- package/dist/schema/project.d.ts +1 -6
- package/dist/schema/project.d.ts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/mapeo-project.js +419 -3
- package/src/types.ts +9 -1
- package/src/utils.js +34 -0
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;;AAgBO,0CAJI,YAAY,gKAEV,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;;AAgBO,0CAJI,YAAY,gKAEV,UAAU,yCAUwvlB,QAAQ,kBAAyB,SAAS,qDAVvvlB,CAG7B;;;;;;kCARH,oBAAoB;gCAL/C,YAAY;oCAAZ,YAAY;+BAAZ,YAAY"}
|
package/dist/mapeo-project.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export const kProjectLeave: unique symbol;
|
|
|
15
15
|
export const kClearDataIfLeft: unique symbol;
|
|
16
16
|
export const kSetIsArchiveDevice: unique symbol;
|
|
17
17
|
export const kIsArchiveDevice: unique symbol;
|
|
18
|
+
export const kGeoJSONFileName: unique symbol;
|
|
19
|
+
export const kExportGeoJSONStream: unique symbol;
|
|
20
|
+
export const kExportZipStream: unique symbol;
|
|
18
21
|
/**
|
|
19
22
|
* @extends {TypedEmitter<{ close: () => void }>}
|
|
20
23
|
*/
|
|
@@ -196,12 +199,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
196
199
|
tableName: "observation";
|
|
197
200
|
dataType: "custom";
|
|
198
201
|
columnType: "SQLiteCustomColumn";
|
|
199
|
-
data:
|
|
200
|
-
driveDiscoveryId: string;
|
|
201
|
-
name: string;
|
|
202
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
203
|
-
hash: string;
|
|
204
|
-
}[];
|
|
202
|
+
data: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
205
203
|
driverParam: string;
|
|
206
204
|
notNull: true;
|
|
207
205
|
hasDefault: false;
|
|
@@ -277,12 +275,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
277
275
|
schemaName: "observation";
|
|
278
276
|
lat?: number | undefined;
|
|
279
277
|
lon?: number | undefined;
|
|
280
|
-
attachments:
|
|
281
|
-
driveDiscoveryId: string;
|
|
282
|
-
name: string;
|
|
283
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
284
|
-
hash: string;
|
|
285
|
-
}[];
|
|
278
|
+
attachments: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
286
279
|
tags: {
|
|
287
280
|
[k: string]: boolean | number | string | null | (boolean | number | string | null)[];
|
|
288
281
|
};
|
|
@@ -312,12 +305,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
312
305
|
schemaName: "observation";
|
|
313
306
|
lat?: number | undefined;
|
|
314
307
|
lon?: number | undefined;
|
|
315
|
-
attachments:
|
|
316
|
-
driveDiscoveryId: string;
|
|
317
|
-
name: string;
|
|
318
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
319
|
-
hash: string;
|
|
320
|
-
}[];
|
|
308
|
+
attachments: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
321
309
|
tags: {
|
|
322
310
|
[k: string]: boolean | number | string | null | (boolean | number | string | null)[];
|
|
323
311
|
};
|
|
@@ -1276,6 +1264,36 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
1276
1264
|
* @returns {import('./icon-api.js').IconApi}
|
|
1277
1265
|
*/
|
|
1278
1266
|
get $icons(): IconApi;
|
|
1267
|
+
/**
|
|
1268
|
+
* Export observations and or tracks as a GeoJSON file
|
|
1269
|
+
* @param {string} exportFolder Path to save the file. The file name is auto-generated
|
|
1270
|
+
* @param {Object} [options={}]
|
|
1271
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1272
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1273
|
+
* @param {string} [options.lang]
|
|
1274
|
+
* @returns {Promise<string>} The full path that the file was exported at
|
|
1275
|
+
*/
|
|
1276
|
+
exportGeoJSONFile(exportFolder: string, { observations, tracks, lang }?: {
|
|
1277
|
+
observations?: boolean | undefined;
|
|
1278
|
+
tracks?: boolean | undefined;
|
|
1279
|
+
lang?: string | undefined;
|
|
1280
|
+
} | undefined): Promise<string>;
|
|
1281
|
+
/**
|
|
1282
|
+
* Export observations, tracks, and or attachments as a zip file.
|
|
1283
|
+
* @param {string} exportFolder Path to save the file. The file name is auto-generated
|
|
1284
|
+
* @param {Object} [options={}]
|
|
1285
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1286
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1287
|
+
* @param {boolean} [options.attachments=true] Whether all attachments for observations should be exported
|
|
1288
|
+
* @param {string} [options.lang]
|
|
1289
|
+
* @returns {Promise<string>} The full path that the file was exported at
|
|
1290
|
+
*/
|
|
1291
|
+
exportZipFile(exportFolder: string, { observations, tracks, attachments, lang }?: {
|
|
1292
|
+
observations?: boolean | undefined;
|
|
1293
|
+
tracks?: boolean | undefined;
|
|
1294
|
+
attachments?: boolean | undefined;
|
|
1295
|
+
lang?: string | undefined;
|
|
1296
|
+
} | undefined): Promise<string>;
|
|
1279
1297
|
/** @param {Object} opts
|
|
1280
1298
|
* @param {string} opts.configPath
|
|
1281
1299
|
* @returns {Promise<Error[]>}
|
|
@@ -1424,12 +1442,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
1424
1442
|
tableName: "observation";
|
|
1425
1443
|
dataType: "custom";
|
|
1426
1444
|
columnType: "SQLiteCustomColumn";
|
|
1427
|
-
data:
|
|
1428
|
-
driveDiscoveryId: string;
|
|
1429
|
-
name: string;
|
|
1430
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
1431
|
-
hash: string;
|
|
1432
|
-
}[];
|
|
1445
|
+
data: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
1433
1446
|
driverParam: string;
|
|
1434
1447
|
notNull: true;
|
|
1435
1448
|
hasDefault: false;
|
|
@@ -1505,12 +1518,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
1505
1518
|
schemaName: "observation";
|
|
1506
1519
|
lat?: number | undefined;
|
|
1507
1520
|
lon?: number | undefined;
|
|
1508
|
-
attachments:
|
|
1509
|
-
driveDiscoveryId: string;
|
|
1510
|
-
name: string;
|
|
1511
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
1512
|
-
hash: string;
|
|
1513
|
-
}[];
|
|
1521
|
+
attachments: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
1514
1522
|
tags: {
|
|
1515
1523
|
[k: string]: boolean | number | string | null | (boolean | number | string | null)[];
|
|
1516
1524
|
};
|
|
@@ -1540,12 +1548,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
1540
1548
|
schemaName: "observation";
|
|
1541
1549
|
lat?: number | undefined;
|
|
1542
1550
|
lon?: number | undefined;
|
|
1543
|
-
attachments:
|
|
1544
|
-
driveDiscoveryId: string;
|
|
1545
|
-
name: string;
|
|
1546
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
1547
|
-
hash: string;
|
|
1548
|
-
}[];
|
|
1551
|
+
attachments: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
1549
1552
|
tags: {
|
|
1550
1553
|
[k: string]: boolean | number | string | null | (boolean | number | string | null)[];
|
|
1551
1554
|
};
|
|
@@ -3658,6 +3661,42 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
3658
3661
|
[kSetIsArchiveDevice](isArchiveDevice: boolean): Promise<void>;
|
|
3659
3662
|
/** @returns {boolean} */
|
|
3660
3663
|
get [kIsArchiveDevice](): boolean;
|
|
3664
|
+
/**
|
|
3665
|
+
* Export observations and or tracks as a stream of GeoJSON data
|
|
3666
|
+
* @param {Object} [options={}]
|
|
3667
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
3668
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
3669
|
+
* @param {SeenAttachments} [options.seenAttachments]
|
|
3670
|
+
* @param {string} [options.lang]
|
|
3671
|
+
* @returns {Readable<Buffer | Uint8Array>}
|
|
3672
|
+
*/
|
|
3673
|
+
[kExportGeoJSONStream]({ observations, tracks, lang, seenAttachments, }?: {
|
|
3674
|
+
observations?: boolean | undefined;
|
|
3675
|
+
tracks?: boolean | undefined;
|
|
3676
|
+
seenAttachments?: SeenAttachments | undefined;
|
|
3677
|
+
lang?: string | undefined;
|
|
3678
|
+
} | undefined): Readable<Buffer | Uint8Array>;
|
|
3679
|
+
/**
|
|
3680
|
+
* @param {boolean} observations
|
|
3681
|
+
* @param {boolean} tracks
|
|
3682
|
+
* @returns {Promise<string>}
|
|
3683
|
+
*/
|
|
3684
|
+
[kGeoJSONFileName](observations: boolean, tracks: boolean): Promise<string>;
|
|
3685
|
+
/**
|
|
3686
|
+
* Export observations, tracks, and or attachments as a zip file stream.
|
|
3687
|
+
* @param {Object} [options={}]
|
|
3688
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
3689
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
3690
|
+
* @param {boolean} [options.attachments=true] Whether all attachments for observations should be exported
|
|
3691
|
+
* @param {string} [options.lang]
|
|
3692
|
+
* @returns {Readable<Buffer | Uint8Array>}
|
|
3693
|
+
*/
|
|
3694
|
+
[kExportZipStream]({ observations, tracks, attachments, lang, }?: {
|
|
3695
|
+
observations?: boolean | undefined;
|
|
3696
|
+
tracks?: boolean | undefined;
|
|
3697
|
+
attachments?: boolean | undefined;
|
|
3698
|
+
lang?: string | undefined;
|
|
3699
|
+
} | undefined): Readable<Buffer | Uint8Array>;
|
|
3661
3700
|
[kProjectLeave](): Promise<void>;
|
|
3662
3701
|
/**
|
|
3663
3702
|
* Clear data if we've left the project. No-op if you're still in the project.
|
|
@@ -3668,6 +3707,7 @@ export class MapeoProject extends TypedEmitter<{
|
|
|
3668
3707
|
}
|
|
3669
3708
|
export type EditableProjectSettings = Omit<ProjectSettingsValue, "schemaName">;
|
|
3670
3709
|
export type ConfigMetadata = ProjectSettingsValue["configMetadata"];
|
|
3710
|
+
export type SeenAttachments = Map<string, Attachment>;
|
|
3671
3711
|
import { TypedEmitter } from 'tiny-typed-emitter';
|
|
3672
3712
|
import { BlobApi } from './blob-api.js';
|
|
3673
3713
|
import { DataStore } from './datastore/index.js';
|
|
@@ -3680,9 +3720,11 @@ import { CoreManager } from './core-manager/index.js';
|
|
|
3680
3720
|
import { CoreOwnership } from './core-ownership.js';
|
|
3681
3721
|
import { BlobStore } from './blob-store/index.js';
|
|
3682
3722
|
import type { ReplicationStream } from './types.js';
|
|
3723
|
+
import { Readable } from 'streamx';
|
|
3683
3724
|
import { IndexWriter } from './index-writer/index.js';
|
|
3684
3725
|
import type { CoreStorage } from './types.js';
|
|
3685
3726
|
import { WebSocket } from 'ws';
|
|
3686
3727
|
import { Logger } from './logger.js';
|
|
3687
3728
|
import type { ProjectSettingsValue } from '@comapeo/schema';
|
|
3729
|
+
import type { Attachment } from './types.js';
|
|
3688
3730
|
//# sourceMappingURL=mapeo-project.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapeo-project.d.ts","sourceRoot":"","sources":["../src/mapeo-project.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mapeo-project.d.ts","sourceRoot":"","sources":["../src/mapeo-project.js"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2YL;IAED,8BAEC;IAoLD;;;;;;;;;;;OAWG;IACH,yCAPW,CACV,OAAW,GACX,OAAW,QAAQ,EAAE,MAAM,GAC3B,OAAW,SAAS,EAAE,MAAM,CACzB,GACS,iBAAiB,CAqB7B;IAED;;;OAGG;IACH,2BAHW,IAAI,CAAC,OAAO,iBAAiB,EAAE,eAAe,EAAE,MAAM,GAAG,YAAY,GAAG,yBAAyB,CAAC,GAChG,OAAO,CAAC,OAAO,iBAAiB,EAAE,UAAU,CAAC,CAwBzD;IAED,uCAAuC;IACvC,uCADY,OAAO,iBAGlB;IAED,yBAAyB;IACzB,kCAEC;IAoLD;;;;;;;;OAQG;IACH;;;;;oBAFa,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,CAkBzC;IAqBD;;;;OAIG;IACH,iCAJW,OAAO,UACP,OAAO,GACL,OAAO,CAAC,MAAM,CAAC,CAY3B;IAoHD;;;;;;;;OAQG;IACH;;;;;oBAFa,QAAQ,CAAC,MAAM,GAAG,UAAU,CAAC,CAmBzC;IAkED,iCAMC;IAED;;;OAGG;IACH,sBAFa,OAAO,CAAC,IAAI,CAAC,CAoCzB;;CAuKF;sCAp0Ca,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC;6BACxC,oBAAoB,CAAC,gBAAgB,CAAC;8BACtC,GAAG,CAAC,MAAM,EAAC,UAAU,CAAC;6BAjEP,oBAAoB;wBAWzB,eAAe;0BAHb,sBAAsB;yBACL,qBAAqB;0BAuCtC,iBAAiB;wBAKpC,oBAAoB;2BAIA,sBAAsB;wBAFzB,eAAe;4BAhDX,yBAAyB;8BAuB9C,qBAAqB;0BApBF,uBAAuB;uCAoD8H,YAAY;yBA1DjJ,SAAS;4BAQvB,yBAAyB;iCAkD0H,YAAY;0BAHjK,IAAI;uBALP,aAAa;0CAO0B,iBAAiB;gCACgG,YAAY"}
|
package/dist/schema/project.d.ts
CHANGED
|
@@ -317,12 +317,7 @@ export const observationTable: import("drizzle-orm/sqlite-core").SQLiteTableWith
|
|
|
317
317
|
tableName: "observation";
|
|
318
318
|
dataType: "custom";
|
|
319
319
|
columnType: "SQLiteCustomColumn";
|
|
320
|
-
data:
|
|
321
|
-
driveDiscoveryId: string;
|
|
322
|
-
name: string;
|
|
323
|
-
type: "attachment_type_unspecified" | "photo" | "video" | "audio" | "UNRECOGNIZED";
|
|
324
|
-
hash: string;
|
|
325
|
-
}[];
|
|
320
|
+
data: import("@comapeo/schema/dist/schema/observation.js").Attachment[];
|
|
326
321
|
driverParam: string;
|
|
327
322
|
notNull: true;
|
|
328
323
|
hasDefault: false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/schema/project.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGC;AACD
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/schema/project.js"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Simplify, TupleToUnion, ValueOf, RequireAtLeastOne, SetOptional } from 'type-fest';
|
|
2
2
|
import { SUPPORTED_BLOB_VARIANTS } from './blob-store/index.js';
|
|
3
|
-
import { MapeoCommon, MapeoDoc, MapeoValue, decode } from '@comapeo/schema';
|
|
3
|
+
import { MapeoCommon, MapeoDoc, MapeoValue, Observation, decode } from '@comapeo/schema';
|
|
4
4
|
import type BigSparseArray from 'big-sparse-array';
|
|
5
5
|
import type Protomux from 'protomux';
|
|
6
6
|
import type NoiseStream from '@hyperswarm/secret-stream';
|
|
@@ -120,6 +120,7 @@ export type BlobStoreEntriesStream = Readable & {
|
|
|
120
120
|
blobCoreId: string;
|
|
121
121
|
}>;
|
|
122
122
|
};
|
|
123
|
+
export type Attachment = Observation['attachments'][0];
|
|
123
124
|
export type StringToTaggedUnion<T extends string> = {
|
|
124
125
|
[K in T]: {
|
|
125
126
|
type: K;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,iBAAiB,EACjB,WAAW,EACZ,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -95,8 +95,17 @@ export function createMap<K extends string, V extends unknown>(keys: ReadonlyArr
|
|
|
95
95
|
* @returns {String} hash of the object
|
|
96
96
|
*/
|
|
97
97
|
export function hashObject(obj: Object): string;
|
|
98
|
+
/**
|
|
99
|
+
* Convert attachments to BlobIds for use in the BlobStore, adapted from comapeo-mobile
|
|
100
|
+
* @param {Attachment} attachment
|
|
101
|
+
* @param {'original' | 'thumbnail' | 'preview'} requestedVariant
|
|
102
|
+
* @returns {BlobId}
|
|
103
|
+
*/
|
|
104
|
+
export function buildBlobId(attachment: Attachment, requestedVariant: "original" | "thumbnail" | "preview"): BlobId;
|
|
98
105
|
export class ExhaustivenessError extends Error {
|
|
99
106
|
/** @param {never} value */
|
|
100
107
|
constructor(value: never);
|
|
101
108
|
}
|
|
109
|
+
import type { Attachment } from "./types.js";
|
|
110
|
+
import type { BlobId } from "./types.js";
|
|
102
111
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,6BAHW,MAAM,SAAO,UASvB;AAUD;;GAEG;AACH,wBAFa,IAAI,CAEQ;AAEzB;;;;GAIG;AACH,kCAJW,OAAO,kBACP,MAAM,GAAG,KAAK,GACZ,QAAQ,SAAS,CAS7B;AAED;;;;;;;;;;;;;GAaG;AACH,uBATa,CAAC,OACH,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAUd,OAAO,KACL,KAAK,IAAI,CAAC,CAGxB;AAED;;;;GAIG;AACH,0BAJa,CAAC,SACH,SAAS,GAAG,CAAC,GACX,KAAK,IAAI,CAAC,CAItB;AAED;;;;;;;GAOG;AAEH,0BALkB,CAAC,SAAN,EAAI,OACN,CAAC,GACC,OAAO,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAUtD;AAED;;;;GAIG;AACH,wBAJyE,CAAC,SAA5D,OAAO,iBAAiB,EAAE,QAAQ,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CAAG,OAC7D,CAAC,GACC,IAAI,CAAC,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC,CAa5H;AAED;;;;GAIG;AACH,2CAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,iDAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,wDAHW,QAAQ,CAAC,MAAM,CAAC,GACd,MAAM,CAMlB;AAED;;;GAGG;AACH,4CAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;GAGG;AACH,wCAHW,2CAAkC,GAChC,MAAM,CAIlB;AAED;;;;;;;2DAO2D;AAC3D,0BALsB,CAAC,SAAV,MAAQ,EACF,CAAC,wBACT,aAAa,CAAC,CAAC,CAAC,SAChB,CAAC,GACC,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAOtD;AAED;;;;GAIG;AACH,gCAHW,MAAM,UAQhB;AAED;;;;;GAKG;AACH,wCAJW,UAAU,oBACV,UAAU,GAAG,WAAW,GAAG,SAAS,GAClC,MAAM,CA0BlB;AArMD;IACE,2BAA2B;IAC3B,mBADY,KAAK,EAIhB;CACF;gCAvBqC,YAAY;4BAAZ,YAAY"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comapeo/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Offline p2p mapping library",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"@comapeo/core2.0.1": "npm:@comapeo/core@2.0.1",
|
|
113
113
|
"@comapeo/ipc": "^2.1.0",
|
|
114
114
|
"@mapeo/default-config": "5.0.0",
|
|
115
|
-
"@mapeo/mock-data": "^
|
|
115
|
+
"@mapeo/mock-data": "^3.0.0",
|
|
116
116
|
"@sinonjs/fake-timers": "^10.0.2",
|
|
117
117
|
"@types/b4a": "^1.6.0",
|
|
118
118
|
"@types/bogon": "^1.0.2",
|
|
@@ -142,6 +142,7 @@
|
|
|
142
142
|
"mapeo-offline-map": "^2.0.0",
|
|
143
143
|
"math-random-seed": "^2.0.0",
|
|
144
144
|
"nanobench": "^3.0.0",
|
|
145
|
+
"node-stream-zip": "^1.15.0",
|
|
145
146
|
"npm-run-all": "^4.1.5",
|
|
146
147
|
"prettier": "^2.8.8",
|
|
147
148
|
"random-access-file": "^4.0.7",
|
|
@@ -159,7 +160,7 @@
|
|
|
159
160
|
},
|
|
160
161
|
"dependencies": {
|
|
161
162
|
"@comapeo/fallback-smp": "^1.0.0",
|
|
162
|
-
"@comapeo/schema": "1.
|
|
163
|
+
"@comapeo/schema": "1.6.0",
|
|
163
164
|
"@digidem/types": "^2.3.0",
|
|
164
165
|
"@fastify/error": "^3.4.1",
|
|
165
166
|
"@fastify/type-provider-typebox": "^4.1.0",
|
|
@@ -210,6 +211,7 @@
|
|
|
210
211
|
"varint": "^6.0.0",
|
|
211
212
|
"ws": "^8.18.0",
|
|
212
213
|
"xstate": "^5.19.2",
|
|
213
|
-
"yauzl-promise": "^4.0.0"
|
|
214
|
+
"yauzl-promise": "^4.0.0",
|
|
215
|
+
"zip-stream-promise": "^1.0.2"
|
|
214
216
|
}
|
|
215
217
|
}
|
package/src/mapeo-project.js
CHANGED
|
@@ -4,6 +4,10 @@ import { decodeBlockPrefix, decode, parseVersionId } from '@comapeo/schema'
|
|
|
4
4
|
import { drizzle } from 'drizzle-orm/better-sqlite3'
|
|
5
5
|
import { discoveryKey } from 'hypercore-crypto'
|
|
6
6
|
import { TypedEmitter } from 'tiny-typed-emitter'
|
|
7
|
+
import ZipArchive from 'zip-stream-promise'
|
|
8
|
+
import * as b4a from 'b4a'
|
|
9
|
+
// @ts-expect-error
|
|
10
|
+
import { Readable, pipelinePromise } from 'streamx'
|
|
7
11
|
|
|
8
12
|
import { NAMESPACES, NAMESPACE_SCHEMAS } from './constants.js'
|
|
9
13
|
import { CoreManager } from './core-manager/index.js'
|
|
@@ -38,6 +42,7 @@ import {
|
|
|
38
42
|
} from './roles.js'
|
|
39
43
|
import {
|
|
40
44
|
assert,
|
|
45
|
+
buildBlobId,
|
|
41
46
|
ExhaustivenessError,
|
|
42
47
|
getDeviceId,
|
|
43
48
|
projectKeyToId,
|
|
@@ -58,11 +63,12 @@ import { readConfig } from './config-import.js'
|
|
|
58
63
|
import TranslationApi from './translation-api.js'
|
|
59
64
|
import { NotFoundError, nullIfNotFound } from './errors.js'
|
|
60
65
|
import { WebSocket } from 'ws'
|
|
61
|
-
|
|
62
|
-
/** @import {
|
|
63
|
-
|
|
66
|
+
import { createWriteStream } from 'fs'
|
|
67
|
+
/** @import { ProjectSettingsValue, Observation, Track } from '@comapeo/schema' */
|
|
68
|
+
/** @import { Attachment, CoreStorage, BlobFilter, BlobId, BlobStoreEntriesStream, KeyPair, Namespace, ReplicationStream, GenericBlobFilter, MapeoValueMap, MapeoDocMap } from './types.js' */
|
|
64
69
|
/** @typedef {Omit<ProjectSettingsValue, 'schemaName'>} EditableProjectSettings */
|
|
65
70
|
/** @typedef {ProjectSettingsValue['configMetadata']} ConfigMetadata */
|
|
71
|
+
/** @typedef {Map<string,Attachment>} SeenAttachments*/
|
|
66
72
|
|
|
67
73
|
const CORESTORE_STORAGE_FOLDER_NAME = 'corestore'
|
|
68
74
|
const INDEXER_STORAGE_FOLDER_NAME = 'indexer'
|
|
@@ -76,9 +82,15 @@ export const kProjectLeave = Symbol('leave project')
|
|
|
76
82
|
export const kClearDataIfLeft = Symbol('clear data if left project')
|
|
77
83
|
export const kSetIsArchiveDevice = Symbol('set isArchiveDevice')
|
|
78
84
|
export const kIsArchiveDevice = Symbol('isArchiveDevice (temp - test only)')
|
|
85
|
+
export const kGeoJSONFileName = Symbol('geoJSONFileName')
|
|
86
|
+
export const kExportGeoJSONStream = Symbol('exportGeoJSONStream')
|
|
87
|
+
export const kExportZipStream = Symbol('exportZipStream')
|
|
79
88
|
|
|
80
89
|
const EMPTY_PROJECT_SETTINGS = Object.freeze({})
|
|
81
90
|
|
|
91
|
+
/** @type BlobId['variant'][]*/
|
|
92
|
+
const VARIANT_EXPORT_ORDER = ['original', 'preview', 'thumbnail']
|
|
93
|
+
|
|
82
94
|
/**
|
|
83
95
|
* @extends {TypedEmitter<{ close: () => void }>}
|
|
84
96
|
*/
|
|
@@ -749,6 +761,410 @@ export class MapeoProject extends TypedEmitter {
|
|
|
749
761
|
return this.#iconApi
|
|
750
762
|
}
|
|
751
763
|
|
|
764
|
+
/**
|
|
765
|
+
* @param {Iterable<Observation>} observations
|
|
766
|
+
* @param {Object} options
|
|
767
|
+
* @param {Set<string>} [options.seenObservations=new Set()]
|
|
768
|
+
* @param {SeenAttachments} [options.seenAttachments]
|
|
769
|
+
* @returns {AsyncIterable<Buffer | Uint8Array>}
|
|
770
|
+
*/
|
|
771
|
+
async *#exportObservations(
|
|
772
|
+
observations,
|
|
773
|
+
{ seenObservations = new Set(), seenAttachments = new Map() }
|
|
774
|
+
) {
|
|
775
|
+
let first = true
|
|
776
|
+
for (const observation of observations) {
|
|
777
|
+
const { lat, lon, docId } = observation
|
|
778
|
+
if (seenObservations.has(docId)) {
|
|
779
|
+
continue
|
|
780
|
+
}
|
|
781
|
+
seenObservations.add(docId)
|
|
782
|
+
for (const attachment of observation.attachments) {
|
|
783
|
+
const { hash } = attachment
|
|
784
|
+
if (!seenAttachments.has(hash)) {
|
|
785
|
+
seenAttachments.set(hash, attachment)
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
let latitude = lat
|
|
790
|
+
let longitude = lon
|
|
791
|
+
let altitude = null
|
|
792
|
+
const position = observation?.metadata?.position?.coords
|
|
793
|
+
if (position) {
|
|
794
|
+
latitude = position.latitude
|
|
795
|
+
longitude = position.longitude
|
|
796
|
+
if (position.altitude !== undefined) {
|
|
797
|
+
altitude = position.altitude
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
const coordinates = [longitude, latitude]
|
|
802
|
+
if (typeof altitude === 'number') {
|
|
803
|
+
coordinates.push(altitude)
|
|
804
|
+
}
|
|
805
|
+
const hasLatLon =
|
|
806
|
+
typeof longitude === 'number' && typeof latitude === 'number'
|
|
807
|
+
const geometry = hasLatLon
|
|
808
|
+
? {
|
|
809
|
+
type: 'Point',
|
|
810
|
+
coordinates,
|
|
811
|
+
}
|
|
812
|
+
: null
|
|
813
|
+
const comma = first ? '' : ','
|
|
814
|
+
first = false
|
|
815
|
+
yield b4a.from(
|
|
816
|
+
`${comma}\n ` +
|
|
817
|
+
JSON.stringify({
|
|
818
|
+
type: 'Feature',
|
|
819
|
+
properties: observation,
|
|
820
|
+
geometry,
|
|
821
|
+
})
|
|
822
|
+
)
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* @param {Iterable<Track>} tracks
|
|
828
|
+
* @param {Object} options
|
|
829
|
+
* @param {Set<string>} [options.seenObservations=new Set()]
|
|
830
|
+
* @param {SeenAttachments} [options.seenAttachments]
|
|
831
|
+
* @param {string} [options.lang]
|
|
832
|
+
* @returns {AsyncIterable<Buffer | Uint8Array>}
|
|
833
|
+
*/
|
|
834
|
+
async *#exportTracks(
|
|
835
|
+
tracks,
|
|
836
|
+
{ lang, seenObservations = new Set(), seenAttachments = new Map() } = {}
|
|
837
|
+
) {
|
|
838
|
+
let first = true
|
|
839
|
+
for (const track of tracks) {
|
|
840
|
+
const { observationRefs } = track
|
|
841
|
+
|
|
842
|
+
const observations = await Promise.all(
|
|
843
|
+
observationRefs.map(({ docId }) =>
|
|
844
|
+
this.#dataTypes.observation.getByDocId(docId, { lang })
|
|
845
|
+
)
|
|
846
|
+
)
|
|
847
|
+
|
|
848
|
+
const coordinates = track.locations.map(
|
|
849
|
+
({ coords: { longitude, latitude, altitude } }) => [
|
|
850
|
+
longitude,
|
|
851
|
+
latitude,
|
|
852
|
+
altitude,
|
|
853
|
+
]
|
|
854
|
+
)
|
|
855
|
+
const comma = first ? '' : ','
|
|
856
|
+
first = false
|
|
857
|
+
yield b4a.from(
|
|
858
|
+
`${comma}\n ` +
|
|
859
|
+
JSON.stringify({
|
|
860
|
+
type: 'Feature',
|
|
861
|
+
properties: track,
|
|
862
|
+
geometry: {
|
|
863
|
+
type: 'LineString',
|
|
864
|
+
coordinates,
|
|
865
|
+
},
|
|
866
|
+
}) +
|
|
867
|
+
'\n'
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
let firstObs = true
|
|
871
|
+
for await (const chunk of this.#exportObservations(observations, {
|
|
872
|
+
seenObservations,
|
|
873
|
+
seenAttachments,
|
|
874
|
+
})) {
|
|
875
|
+
if (firstObs) {
|
|
876
|
+
yield b4a.from(',')
|
|
877
|
+
firstObs = false
|
|
878
|
+
}
|
|
879
|
+
yield chunk
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* @param {Object} [options={}]
|
|
886
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
887
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
888
|
+
* @param {SeenAttachments} [options.seenAttachments]
|
|
889
|
+
* @param {string} [options.lang]
|
|
890
|
+
* @returns {AsyncIterable<Buffer | Uint8Array>}
|
|
891
|
+
*/
|
|
892
|
+
async *#exportGeoJSONIterator({
|
|
893
|
+
observations = true,
|
|
894
|
+
tracks = true,
|
|
895
|
+
lang,
|
|
896
|
+
seenAttachments = new Map(),
|
|
897
|
+
} = {}) {
|
|
898
|
+
yield b4a.from(`{
|
|
899
|
+
"type": "FeatureCollection",
|
|
900
|
+
"features": [
|
|
901
|
+
`)
|
|
902
|
+
|
|
903
|
+
const seenObservations = new Set()
|
|
904
|
+
|
|
905
|
+
let hadTracks = false
|
|
906
|
+
if (tracks) {
|
|
907
|
+
const rows = await this.#dataTypes.track.getMany({ lang })
|
|
908
|
+
for await (const chunk of this.#exportTracks(rows, {
|
|
909
|
+
lang,
|
|
910
|
+
seenObservations,
|
|
911
|
+
seenAttachments,
|
|
912
|
+
})) {
|
|
913
|
+
hadTracks = true
|
|
914
|
+
yield chunk
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
if (observations) {
|
|
919
|
+
if (hadTracks) {
|
|
920
|
+
yield b4a.from(',')
|
|
921
|
+
}
|
|
922
|
+
const rows = await this.#dataTypes.observation.getMany({ lang })
|
|
923
|
+
yield* this.#exportObservations(rows, {
|
|
924
|
+
seenObservations,
|
|
925
|
+
seenAttachments,
|
|
926
|
+
})
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
yield b4a.from(`
|
|
930
|
+
]
|
|
931
|
+
}
|
|
932
|
+
`)
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Export observations and or tracks as a stream of GeoJSON data
|
|
937
|
+
* @param {Object} [options={}]
|
|
938
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
939
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
940
|
+
* @param {SeenAttachments} [options.seenAttachments]
|
|
941
|
+
* @param {string} [options.lang]
|
|
942
|
+
* @returns {Readable<Buffer | Uint8Array>}
|
|
943
|
+
*/
|
|
944
|
+
[kExportGeoJSONStream]({
|
|
945
|
+
observations = true,
|
|
946
|
+
tracks = true,
|
|
947
|
+
lang,
|
|
948
|
+
seenAttachments = new Map(),
|
|
949
|
+
} = {}) {
|
|
950
|
+
// Format based on https://doc.arcgis.com/en/arcgis-online/reference/geojson.htm
|
|
951
|
+
|
|
952
|
+
return Readable.from(
|
|
953
|
+
this.#exportGeoJSONIterator({
|
|
954
|
+
observations,
|
|
955
|
+
tracks,
|
|
956
|
+
lang,
|
|
957
|
+
seenAttachments,
|
|
958
|
+
})
|
|
959
|
+
)
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
*
|
|
964
|
+
* @param {string} type Type of export this will be
|
|
965
|
+
* @returns {Promise<string>}
|
|
966
|
+
*/
|
|
967
|
+
async #exportPrefix(type = '') {
|
|
968
|
+
const name = await this.#getProjectName()
|
|
969
|
+
const date = new Date()
|
|
970
|
+
const dateSection = date
|
|
971
|
+
.toLocaleDateString('nu', {
|
|
972
|
+
year: 'numeric',
|
|
973
|
+
month: 'numeric',
|
|
974
|
+
day: 'numeric',
|
|
975
|
+
})
|
|
976
|
+
.replaceAll('/', '_')
|
|
977
|
+
.replaceAll('-', '_')
|
|
978
|
+
return `CoMapeo_${name}_${type}_${dateSection}`
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* @param {boolean} observations
|
|
983
|
+
* @param {boolean} tracks
|
|
984
|
+
* @returns {Promise<string>}
|
|
985
|
+
*/
|
|
986
|
+
async [kGeoJSONFileName](observations, tracks) {
|
|
987
|
+
let exportType = ''
|
|
988
|
+
if (observations) exportType += 'Obsvns'
|
|
989
|
+
if (tracks) {
|
|
990
|
+
if (observations) exportType += '_'
|
|
991
|
+
exportType += 'Tracks'
|
|
992
|
+
}
|
|
993
|
+
const prefix = await this.#exportPrefix(exportType)
|
|
994
|
+
|
|
995
|
+
return prefix + '.geojson'
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* @param {boolean} observations
|
|
1000
|
+
* @param {boolean} tracks
|
|
1001
|
+
* @returns {Promise<string>}
|
|
1002
|
+
*/
|
|
1003
|
+
async #zipFileName(observations, tracks) {
|
|
1004
|
+
let exportType = ''
|
|
1005
|
+
if (observations) exportType += 'Obsvns'
|
|
1006
|
+
if (tracks) {
|
|
1007
|
+
if (observations) exportType += '_'
|
|
1008
|
+
exportType += 'Tracks'
|
|
1009
|
+
}
|
|
1010
|
+
const prefix = await this.#exportPrefix(exportType)
|
|
1011
|
+
|
|
1012
|
+
return prefix + '.zip'
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* Export observations and or tracks as a GeoJSON file
|
|
1017
|
+
* @param {string} exportFolder Path to save the file. The file name is auto-generated
|
|
1018
|
+
* @param {Object} [options={}]
|
|
1019
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1020
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1021
|
+
* @param {string} [options.lang]
|
|
1022
|
+
* @returns {Promise<string>} The full path that the file was exported at
|
|
1023
|
+
*/
|
|
1024
|
+
async exportGeoJSONFile(
|
|
1025
|
+
exportFolder,
|
|
1026
|
+
{ observations = true, tracks = true, lang } = {}
|
|
1027
|
+
) {
|
|
1028
|
+
const fileName = await this[kGeoJSONFileName](observations, tracks)
|
|
1029
|
+
const filePath = path.join(exportFolder, fileName)
|
|
1030
|
+
const source = this[kExportGeoJSONStream]({ observations, tracks, lang })
|
|
1031
|
+
const sink = createWriteStream(filePath)
|
|
1032
|
+
await pipelinePromise(source, sink)
|
|
1033
|
+
|
|
1034
|
+
return filePath
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* @param {Attachment} attachment
|
|
1039
|
+
* @returns {Promise<null | BlobId>}
|
|
1040
|
+
*/
|
|
1041
|
+
async #tryGetBlobId(attachment) {
|
|
1042
|
+
// Audio must not have variants
|
|
1043
|
+
for (const variant of VARIANT_EXPORT_ORDER) {
|
|
1044
|
+
const blobId = buildBlobId(attachment, variant)
|
|
1045
|
+
const entry = await this.#blobStore.entry(blobId)
|
|
1046
|
+
if (!entry) continue
|
|
1047
|
+
return blobId
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
return null
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* @param {ZipArchive} archive
|
|
1055
|
+
* @param {Object} [options={}]
|
|
1056
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1057
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1058
|
+
* @param {boolean} [options.attachments=true] Whether all attachments for observations should be exported
|
|
1059
|
+
* @param {string} [options.lang]
|
|
1060
|
+
* @returns {Promise<void>}
|
|
1061
|
+
*/
|
|
1062
|
+
async #exportToArchive(
|
|
1063
|
+
archive,
|
|
1064
|
+
{ observations = true, tracks = true, attachments = true, lang } = {}
|
|
1065
|
+
) {
|
|
1066
|
+
// GeoJSON
|
|
1067
|
+
const geoJSONFileName = await this[kGeoJSONFileName](observations, tracks)
|
|
1068
|
+
const seenAttachments = new Map()
|
|
1069
|
+
const geoJSONStream = this[kExportGeoJSONStream]({
|
|
1070
|
+
observations,
|
|
1071
|
+
tracks,
|
|
1072
|
+
lang,
|
|
1073
|
+
seenAttachments,
|
|
1074
|
+
})
|
|
1075
|
+
|
|
1076
|
+
// @ts-expect-error
|
|
1077
|
+
await archive.entry(geoJSONStream, { name: geoJSONFileName })
|
|
1078
|
+
|
|
1079
|
+
const missingAttachments = []
|
|
1080
|
+
// Attachments
|
|
1081
|
+
if (attachments) {
|
|
1082
|
+
const mediaFolder = this.#exportPrefix('Media') + '/'
|
|
1083
|
+
for (const attachment of seenAttachments.values()) {
|
|
1084
|
+
const blobId = await this.#tryGetBlobId(attachment)
|
|
1085
|
+
if (blobId === null) {
|
|
1086
|
+
missingAttachments.push(attachment)
|
|
1087
|
+
continue
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
const stream = this.#blobStore.createReadStream(blobId)
|
|
1091
|
+
const name = mediaFolder + blobId.variant + '/' + attachment.name
|
|
1092
|
+
|
|
1093
|
+
// @ts-expect-error
|
|
1094
|
+
await archive.entry(stream, { name })
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
if (missingAttachments.length) {
|
|
1098
|
+
this.#l.log(`Found missing attachments during export`)
|
|
1099
|
+
const missingContent = missingAttachments
|
|
1100
|
+
.map((attachment) => JSON.stringify(attachment))
|
|
1101
|
+
.join('\n')
|
|
1102
|
+
|
|
1103
|
+
await archive.entry(missingContent, {
|
|
1104
|
+
name: mediaFolder + 'missing.ndjson',
|
|
1105
|
+
})
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
// Finalize
|
|
1109
|
+
archive.finalize()
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* Export observations, tracks, and or attachments as a zip file stream.
|
|
1114
|
+
* @param {Object} [options={}]
|
|
1115
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1116
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1117
|
+
* @param {boolean} [options.attachments=true] Whether all attachments for observations should be exported
|
|
1118
|
+
* @param {string} [options.lang]
|
|
1119
|
+
* @returns {Readable<Buffer | Uint8Array>}
|
|
1120
|
+
*/
|
|
1121
|
+
[kExportZipStream]({
|
|
1122
|
+
observations = true,
|
|
1123
|
+
tracks = true,
|
|
1124
|
+
attachments = true,
|
|
1125
|
+
lang,
|
|
1126
|
+
} = {}) {
|
|
1127
|
+
const archive = new ZipArchive()
|
|
1128
|
+
|
|
1129
|
+
this.#exportToArchive(archive, {
|
|
1130
|
+
observations,
|
|
1131
|
+
tracks,
|
|
1132
|
+
attachments,
|
|
1133
|
+
lang,
|
|
1134
|
+
}).catch((e) => archive.emit('error', e))
|
|
1135
|
+
|
|
1136
|
+
// @ts-expect-error
|
|
1137
|
+
return archive
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/**
|
|
1141
|
+
* Export observations, tracks, and or attachments as a zip file.
|
|
1142
|
+
* @param {string} exportFolder Path to save the file. The file name is auto-generated
|
|
1143
|
+
* @param {Object} [options={}]
|
|
1144
|
+
* @param {boolean} [options.observations=true] Whether observations should be exported
|
|
1145
|
+
* @param {boolean} [options.tracks=true] Whether all tracks and their observations should be exported
|
|
1146
|
+
* @param {boolean} [options.attachments=true] Whether all attachments for observations should be exported
|
|
1147
|
+
* @param {string} [options.lang]
|
|
1148
|
+
* @returns {Promise<string>} The full path that the file was exported at
|
|
1149
|
+
*/
|
|
1150
|
+
async exportZipFile(
|
|
1151
|
+
exportFolder,
|
|
1152
|
+
{ observations = true, tracks = true, attachments = true, lang } = {}
|
|
1153
|
+
) {
|
|
1154
|
+
const fileName = await this.#zipFileName(observations, tracks)
|
|
1155
|
+
const filePath = path.join(exportFolder, fileName)
|
|
1156
|
+
const source = this[kExportZipStream]({
|
|
1157
|
+
observations,
|
|
1158
|
+
tracks,
|
|
1159
|
+
attachments,
|
|
1160
|
+
lang,
|
|
1161
|
+
})
|
|
1162
|
+
const sink = createWriteStream(filePath)
|
|
1163
|
+
await pipelinePromise(source, sink)
|
|
1164
|
+
|
|
1165
|
+
return filePath
|
|
1166
|
+
}
|
|
1167
|
+
|
|
752
1168
|
/**
|
|
753
1169
|
* @returns {Promise<void>}
|
|
754
1170
|
*/
|
package/src/types.ts
CHANGED
|
@@ -6,7 +6,13 @@ import type {
|
|
|
6
6
|
SetOptional,
|
|
7
7
|
} from 'type-fest'
|
|
8
8
|
import { SUPPORTED_BLOB_VARIANTS } from './blob-store/index.js'
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
MapeoCommon,
|
|
11
|
+
MapeoDoc,
|
|
12
|
+
MapeoValue,
|
|
13
|
+
Observation,
|
|
14
|
+
decode,
|
|
15
|
+
} from '@comapeo/schema'
|
|
10
16
|
import type BigSparseArray from 'big-sparse-array'
|
|
11
17
|
import type Protomux from 'protomux'
|
|
12
18
|
import type NoiseStream from '@hyperswarm/secret-stream'
|
|
@@ -156,6 +162,8 @@ export type BlobStoreEntriesStream = Readable & {
|
|
|
156
162
|
>
|
|
157
163
|
}
|
|
158
164
|
|
|
165
|
+
export type Attachment = Observation['attachments'][0]
|
|
166
|
+
|
|
159
167
|
export type StringToTaggedUnion<T extends string> = {
|
|
160
168
|
[K in T]: {
|
|
161
169
|
type: K
|
package/src/utils.js
CHANGED
|
@@ -4,6 +4,8 @@ import { createHash } from 'node:crypto'
|
|
|
4
4
|
import stableStringify from 'json-stable-stringify'
|
|
5
5
|
import { omit } from './lib/omit.js'
|
|
6
6
|
|
|
7
|
+
/** @import {Attachment, BlobId} from "./types.js" */
|
|
8
|
+
|
|
7
9
|
const PROJECT_INVITE_ID_SALT = Buffer.from('mapeo project invite id', 'ascii')
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -185,3 +187,35 @@ export function hashObject(obj) {
|
|
|
185
187
|
.digest()
|
|
186
188
|
.toString('hex')
|
|
187
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Convert attachments to BlobIds for use in the BlobStore, adapted from comapeo-mobile
|
|
193
|
+
* @param {Attachment} attachment
|
|
194
|
+
* @param {'original' | 'thumbnail' | 'preview'} requestedVariant
|
|
195
|
+
* @returns {BlobId}
|
|
196
|
+
*/
|
|
197
|
+
export function buildBlobId(attachment, requestedVariant) {
|
|
198
|
+
if (
|
|
199
|
+
attachment.type !== 'photo' &&
|
|
200
|
+
attachment.type !== 'audio' &&
|
|
201
|
+
attachment.type !== 'video'
|
|
202
|
+
) {
|
|
203
|
+
throw new Error(`Cannot fetch URL for attachment type "${attachment.type}"`)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (attachment.type === 'photo') {
|
|
207
|
+
return {
|
|
208
|
+
type: 'photo',
|
|
209
|
+
variant: requestedVariant,
|
|
210
|
+
name: attachment.name,
|
|
211
|
+
driveId: attachment.driveDiscoveryId,
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
type: attachment.type,
|
|
217
|
+
variant: 'original',
|
|
218
|
+
name: attachment.name,
|
|
219
|
+
driveId: attachment.driveDiscoveryId,
|
|
220
|
+
}
|
|
221
|
+
}
|