@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.
Files changed (71) hide show
  1. package/dist/blob-store/index.d.ts +5 -8
  2. package/dist/blob-store/index.d.ts.map +1 -1
  3. package/dist/constants.d.ts +2 -1
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/core-manager/index.d.ts +10 -0
  6. package/dist/core-manager/index.d.ts.map +1 -1
  7. package/dist/datastore/index.d.ts +5 -4
  8. package/dist/datastore/index.d.ts.map +1 -1
  9. package/dist/generated/extensions.d.ts +31 -0
  10. package/dist/generated/extensions.d.ts.map +1 -1
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/lib/drizzle-helpers.d.ts +6 -0
  14. package/dist/lib/drizzle-helpers.d.ts.map +1 -0
  15. package/dist/lib/error.d.ts +37 -0
  16. package/dist/lib/error.d.ts.map +1 -0
  17. package/dist/lib/get-own.d.ts +9 -0
  18. package/dist/lib/get-own.d.ts.map +1 -0
  19. package/dist/lib/is-hostname-ip-address.d.ts +17 -0
  20. package/dist/lib/is-hostname-ip-address.d.ts.map +1 -0
  21. package/dist/lib/ws-core-replicator.d.ts +11 -0
  22. package/dist/lib/ws-core-replicator.d.ts.map +1 -0
  23. package/dist/mapeo-manager.d.ts +18 -22
  24. package/dist/mapeo-manager.d.ts.map +1 -1
  25. package/dist/mapeo-project.d.ts +448 -15
  26. package/dist/mapeo-project.d.ts.map +1 -1
  27. package/dist/member-api.d.ts +40 -1
  28. package/dist/member-api.d.ts.map +1 -1
  29. package/dist/schema/client.d.ts +17 -5
  30. package/dist/schema/client.d.ts.map +1 -1
  31. package/dist/schema/project.d.ts +210 -0
  32. package/dist/schema/project.d.ts.map +1 -1
  33. package/dist/sync/peer-sync-controller.d.ts.map +1 -1
  34. package/dist/sync/sync-api.d.ts +28 -2
  35. package/dist/sync/sync-api.d.ts.map +1 -1
  36. package/dist/types.d.ts +3 -2
  37. package/dist/types.d.ts.map +1 -1
  38. package/drizzle/client/0001_chubby_cargill.sql +12 -0
  39. package/drizzle/client/meta/0001_snapshot.json +208 -0
  40. package/drizzle/client/meta/_journal.json +7 -0
  41. package/drizzle/project/0001_medical_wendell_rand.sql +22 -0
  42. package/drizzle/project/meta/0001_snapshot.json +1267 -0
  43. package/drizzle/project/meta/_journal.json +7 -0
  44. package/package.json +9 -5
  45. package/src/blob-store/index.js +3 -2
  46. package/src/constants.js +4 -1
  47. package/src/core-manager/index.js +58 -2
  48. package/src/datastore/README.md +1 -2
  49. package/src/datastore/index.js +4 -5
  50. package/src/fastify-plugins/blobs.js +1 -0
  51. package/src/generated/extensions.d.ts +31 -0
  52. package/src/generated/extensions.js +150 -0
  53. package/src/generated/extensions.ts +181 -0
  54. package/src/index.js +10 -0
  55. package/src/invite-api.js +1 -1
  56. package/src/lib/drizzle-helpers.js +79 -0
  57. package/src/lib/error.js +47 -0
  58. package/src/lib/get-own.js +10 -0
  59. package/src/lib/is-hostname-ip-address.js +26 -0
  60. package/src/lib/ws-core-replicator.js +47 -0
  61. package/src/mapeo-manager.js +71 -43
  62. package/src/mapeo-project.js +153 -43
  63. package/src/member-api.js +253 -2
  64. package/src/schema/client.js +4 -3
  65. package/src/schema/project.js +7 -0
  66. package/src/sync/peer-sync-controller.js +1 -0
  67. package/src/sync/sync-api.js +171 -3
  68. package/src/types.ts +4 -3
  69. package/dist/lib/timing-safe-equal.d.ts +0 -15
  70. package/dist/lib/timing-safe-equal.d.ts.map +0 -1
  71. package/src/lib/timing-safe-equal.js +0 -34
@@ -8,6 +8,13 @@
8
8
  "when": 1726514275142,
9
9
  "tag": "0000_spooky_lady_ursula",
10
10
  "breakpoints": true
11
+ },
12
+ {
13
+ "idx": 1,
14
+ "version": "5",
15
+ "when": 1729783892753,
16
+ "tag": "0001_medical_wendell_rand",
17
+ "breakpoints": true
11
18
  }
12
19
  ]
13
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comapeo/core",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "Offline p2p mapping library",
5
5
  "main": "src/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -108,8 +108,9 @@
108
108
  "homepage": "https://github.com/digidem/comapeo-core#readme",
109
109
  "devDependencies": {
110
110
  "@bufbuild/buf": "^1.26.1",
111
+ "@comapeo/core2.0.1": "npm:@comapeo/core@2.0.1",
111
112
  "@mapeo/default-config": "5.0.0",
112
- "@mapeo/mock-data": "2.0.0",
113
+ "@mapeo/mock-data": "^2.1.1",
113
114
  "@sinonjs/fake-timers": "^10.0.2",
114
115
  "@types/b4a": "^1.6.0",
115
116
  "@types/bogon": "^1.0.2",
@@ -124,6 +125,7 @@
124
125
  "@types/sub-encoder": "^2.1.0",
125
126
  "@types/throttle-debounce": "^5.0.0",
126
127
  "@types/varint": "^6.0.1",
128
+ "@types/ws": "^8.5.12",
127
129
  "@types/yauzl-promise": "^4.0.0",
128
130
  "@types/yazl": "^2.4.5",
129
131
  "bitfield": "^4.2.0",
@@ -153,7 +155,7 @@
153
155
  },
154
156
  "dependencies": {
155
157
  "@comapeo/fallback-smp": "^1.0.0",
156
- "@comapeo/schema": "1.0.0",
158
+ "@comapeo/schema": "1.2.0",
157
159
  "@digidem/types": "^2.3.0",
158
160
  "@fastify/error": "^3.4.1",
159
161
  "@fastify/type-provider-typebox": "^4.1.0",
@@ -171,7 +173,7 @@
171
173
  "debug": "^4.3.4",
172
174
  "dot-prop": "^9.0.0",
173
175
  "drizzle-orm": "^0.30.8",
174
- "fastify": ">= 4",
176
+ "fastify": "^4.0.0",
175
177
  "fastify-plugin": "^4.5.1",
176
178
  "hyperblobs": "2.3.0",
177
179
  "hypercore": "10.17.0",
@@ -181,7 +183,7 @@
181
183
  "magic-bytes.js": "^1.10.0",
182
184
  "map-obj": "^5.0.2",
183
185
  "mime": "^4.0.3",
184
- "multi-core-indexer": "^1.0.0-alpha.10",
186
+ "multi-core-indexer": "^1.0.0",
185
187
  "p-defer": "^4.0.0",
186
188
  "p-event": "^6.0.1",
187
189
  "p-timeout": "^6.1.2",
@@ -191,6 +193,7 @@
191
193
  "sodium-universal": "^4.0.0",
192
194
  "start-stop-state-machine": "^1.2.0",
193
195
  "streamx": "^2.19.0",
196
+ "string-timing-safe-equal": "^0.1.0",
194
197
  "styled-map-package": "^2.0.0",
195
198
  "sub-encoder": "^2.1.1",
196
199
  "throttle-debounce": "^5.0.0",
@@ -198,6 +201,7 @@
198
201
  "type-fest": "^4.5.0",
199
202
  "undici": "^6.13.0",
200
203
  "varint": "^6.0.0",
204
+ "ws": "^8.18.0",
201
205
  "yauzl-promise": "^4.0.0"
202
206
  }
203
207
  }
@@ -4,6 +4,7 @@ import util from 'node:util'
4
4
  import { discoveryKey } from 'hypercore-crypto'
5
5
  import { TypedEmitter } from 'tiny-typed-emitter'
6
6
  import { LiveDownload } from './live-download.js'
7
+ /** @import { JsonObject } from 'type-fest' */
7
8
  /** @import { Readable as NodeReadable } from 'node:stream' */
8
9
  /** @import { Readable as StreamxReadable, Writable } from 'streamx' */
9
10
  /** @import { BlobId } from '../types.js' */
@@ -200,7 +201,7 @@ export class BlobStore {
200
201
  * @param {Omit<BlobId, 'driveId'>} blobId
201
202
  * @param {Buffer} blob
202
203
  * @param {object} [options]
203
- * @param {{mimeType: string}} [options.metadata] Metadata to store with the blob
204
+ * @param {JsonObject} [options.metadata] Metadata to store with the blob
204
205
  * @returns {Promise<string>} discovery key as hex string of hyperdrive where blob is stored
205
206
  */
206
207
  async put({ type, variant, name }, blob, options) {
@@ -212,7 +213,7 @@ export class BlobStore {
212
213
  /**
213
214
  * @param {Omit<BlobId, 'driveId'>} blobId
214
215
  * @param {object} [options]
215
- * @param {{mimeType: string}} [options.metadata] Metadata to store with the blob
216
+ * @param {JsonObject} [options.metadata] Metadata to store with the blob
216
217
  * @returns {Writable & { driveId: string }}
217
218
  */
218
219
  createWriteStream({ type, variant, name }, options) {
package/src/constants.js CHANGED
@@ -19,7 +19,7 @@ export const DATA_NAMESPACES = NAMESPACES.filter(
19
19
  )
20
20
 
21
21
  export const NAMESPACE_SCHEMAS = /** @type {const} */ ({
22
- data: ['observation', 'track'],
22
+ data: ['observation', 'track', 'remoteDetectionAlert'],
23
23
  config: [
24
24
  'translation',
25
25
  'preset',
@@ -32,3 +32,6 @@ export const NAMESPACE_SCHEMAS = /** @type {const} */ ({
32
32
  })
33
33
 
34
34
  export const SUPPORTED_CONFIG_VERSION = 1
35
+
36
+ // WARNING: This value is persisted. Be careful when changing it.
37
+ export const DRIZZLE_MIGRATIONS_TABLE = '__drizzle_migrations'
@@ -4,16 +4,21 @@ import { debounce } from 'throttle-debounce'
4
4
  import assert from 'node:assert/strict'
5
5
  import { sql, eq } from 'drizzle-orm'
6
6
 
7
- import { HaveExtension, ProjectExtension } from '../generated/extensions.js'
7
+ import {
8
+ HaveExtension,
9
+ ProjectExtension,
10
+ DownloadIntentExtension,
11
+ } from '../generated/extensions.js'
8
12
  import { Logger } from '../logger.js'
9
13
  import { NAMESPACES } from '../constants.js'
10
14
  import { noop } from '../utils.js'
11
15
  import { coresTable } from '../schema/project.js'
12
16
  import * as rle from './bitfield-rle.js'
13
17
  import { CoreIndex } from './core-index.js'
18
+ import mapObject from 'map-obj'
14
19
 
15
20
  /** @import Hypercore from 'hypercore' */
16
- /** @import { HypercorePeer, Namespace } from '../types.js' */
21
+ /** @import { BlobFilter, GenericBlobFilter, HypercorePeer, Namespace } from '../types.js' */
17
22
 
18
23
  const WRITER_CORE_PREHAVES_DEBOUNCE_DELAY = 1000
19
24
 
@@ -25,6 +30,7 @@ export const kCoreManagerReplicate = Symbol('replicate core manager')
25
30
  * @typedef {Object} Events
26
31
  * @property {(coreRecord: CoreRecord) => void} add-core
27
32
  * @property {(namespace: Namespace, msg: { coreDiscoveryId: string, peerId: string, start: number, bitfield: Uint32Array }) => void} peer-have
33
+ * @property {(blobFilter: GenericBlobFilter, peerId: string) => void} peer-download-intent
28
34
  */
29
35
 
30
36
  /**
@@ -46,6 +52,7 @@ export class CoreManager extends TypedEmitter {
46
52
  #deviceId
47
53
  #l
48
54
  #autoDownload
55
+ #downloadIntentExtension
49
56
 
50
57
  static get namespaces() {
51
58
  return NAMESPACES
@@ -158,6 +165,16 @@ export class CoreManager extends TypedEmitter {
158
165
  },
159
166
  })
160
167
 
168
+ this.#downloadIntentExtension = this.creatorCore.registerExtension(
169
+ 'mapeo/download-intent',
170
+ {
171
+ encoding: DownloadIntentCodec,
172
+ onmessage: (msg, peer) => {
173
+ this.#handleDownloadIntentMessage(msg, peer)
174
+ },
175
+ }
176
+ )
177
+
161
178
  this.creatorCore.on('peer-add', (peer) => {
162
179
  this.#sendHaves(peer, this.#coreIndex).catch(() => {
163
180
  this.#l.log('Failed to send pre-haves to newly-connected peer')
@@ -395,6 +412,23 @@ export class CoreManager extends TypedEmitter {
395
412
  })
396
413
  }
397
414
 
415
+ /**
416
+ * @param {GenericBlobFilter} blobFilter
417
+ * @param {HypercorePeer} peer
418
+ */
419
+ #handleDownloadIntentMessage(blobFilter, peer) {
420
+ const peerId = peer.remotePublicKey.toString('hex')
421
+ this.emit('peer-download-intent', blobFilter, peerId)
422
+ }
423
+
424
+ /**
425
+ * @param {BlobFilter} blobFilter
426
+ * @param {HypercorePeer} peer
427
+ */
428
+ sendDownloadIntents(blobFilter, peer) {
429
+ this.#downloadIntentExtension.send(blobFilter, peer)
430
+ }
431
+
398
432
  /**
399
433
  *
400
434
  * @param {HypercorePeer} peer
@@ -505,3 +539,25 @@ const HaveExtensionCodec = {
505
539
  }
506
540
  },
507
541
  }
542
+
543
+ const DownloadIntentCodec = {
544
+ /** @param {BlobFilter} filter */
545
+ encode(filter) {
546
+ const downloadIntents = mapObject(filter, (key, value) => [
547
+ key,
548
+ { variants: value || [] },
549
+ ])
550
+ return DownloadIntentExtension.encode({ downloadIntents }).finish()
551
+ },
552
+ /**
553
+ * @param {Buffer | Uint8Array} buf
554
+ * @returns {GenericBlobFilter}
555
+ */
556
+ decode(buf) {
557
+ const msg = DownloadIntentExtension.decode(buf)
558
+ return mapObject(msg.downloadIntents, (key, value) => [
559
+ key + '', // keep TS happy
560
+ value.variants,
561
+ ])
562
+ },
563
+ }
@@ -19,6 +19,7 @@ const datastore = new DataStore({
19
19
  // Process entries here using an indexer...
20
20
  },
21
21
  namespace: 'data',
22
+ reindex: false,
22
23
  })
23
24
 
24
25
  /** @type {MapeoDoc} */
@@ -33,8 +34,6 @@ datastore.on('index-state', ({ current, remaining, entriesPerSecond }) => {
33
34
  // show state to user that indexing is happening
34
35
  }
35
36
  })
36
-
37
- const { current, remaining, entriesPerSecond } = datastore.getIndexState()
38
37
  ```
39
38
 
40
39
  ## API docs
@@ -51,8 +51,9 @@ export class DataStore extends TypedEmitter {
51
51
  * @param {TNamespace} opts.namespace
52
52
  * @param {(entries: MultiCoreIndexer.Entry<'binary'>[]) => Promise<import('../index-writer/index.js').IndexedDocIds>} opts.batch
53
53
  * @param {MultiCoreIndexer.StorageParam} opts.storage
54
+ * @param {boolean} opts.reindex
54
55
  */
55
- constructor({ coreManager, namespace, batch, storage }) {
56
+ constructor({ coreManager, namespace, batch, storage, reindex }) {
56
57
  super()
57
58
  this.#coreManager = coreManager
58
59
  this.#namespace = namespace
@@ -66,6 +67,7 @@ export class DataStore extends TypedEmitter {
66
67
  this.#coreIndexer = new MultiCoreIndexer(cores, {
67
68
  storage,
68
69
  batch: (entries) => this.#handleEntries(entries),
70
+ reindex,
69
71
  })
70
72
  coreManager.on('add-core', (coreRecord) => {
71
73
  if (coreRecord.namespace !== namespace) return
@@ -91,10 +93,6 @@ export class DataStore extends TypedEmitter {
91
93
  return this.#writerCore
92
94
  }
93
95
 
94
- getIndexState() {
95
- return this.#coreIndexer.state
96
- }
97
-
98
96
  /**
99
97
  *
100
98
  * @param {MultiCoreIndexer.Entry<'binary'>[]} entries
@@ -167,6 +165,7 @@ export class DataStore extends TypedEmitter {
167
165
  const deferred = pDefer()
168
166
  this.#pendingIndex.set(versionId, deferred)
169
167
  await deferred.promise
168
+ this.#pendingIndex.delete(versionId)
170
169
 
171
170
  return /** @type {Extract<MapeoDoc, TDoc>} */ (
172
171
  decode(block, { coreDiscoveryKey, index })
@@ -102,6 +102,7 @@ async function routes(fastify, options) {
102
102
  // Extract the 'mimeType' property of the metadata and use it for the response header if found
103
103
  if (
104
104
  metadata &&
105
+ typeof metadata === 'object' &&
105
106
  'mimeType' in metadata &&
106
107
  typeof metadata.mimeType === 'string'
107
108
  ) {
@@ -19,6 +19,19 @@ export declare const HaveExtension_Namespace: {
19
19
  export type HaveExtension_Namespace = typeof HaveExtension_Namespace[keyof typeof HaveExtension_Namespace];
20
20
  export declare function haveExtension_NamespaceFromJSON(object: any): HaveExtension_Namespace;
21
21
  export declare function haveExtension_NamespaceToNumber(object: HaveExtension_Namespace): number;
22
+ /** A map of blob types and variants that a peer intends to download */
23
+ export interface DownloadIntentExtension {
24
+ downloadIntents: {
25
+ [key: string]: DownloadIntentExtension_DownloadIntent;
26
+ };
27
+ }
28
+ export interface DownloadIntentExtension_DownloadIntent {
29
+ variants: string[];
30
+ }
31
+ export interface DownloadIntentExtension_DownloadIntentsEntry {
32
+ key: string;
33
+ value: DownloadIntentExtension_DownloadIntent | undefined;
34
+ }
22
35
  export declare const ProjectExtension: {
23
36
  encode(message: ProjectExtension, writer?: _m0.Writer): _m0.Writer;
24
37
  decode(input: _m0.Reader | Uint8Array, length?: number): ProjectExtension;
@@ -31,6 +44,24 @@ export declare const HaveExtension: {
31
44
  create<I extends Exact<DeepPartial<HaveExtension>, I>>(base?: I): HaveExtension;
32
45
  fromPartial<I extends Exact<DeepPartial<HaveExtension>, I>>(object: I): HaveExtension;
33
46
  };
47
+ export declare const DownloadIntentExtension: {
48
+ encode(message: DownloadIntentExtension, writer?: _m0.Writer): _m0.Writer;
49
+ decode(input: _m0.Reader | Uint8Array, length?: number): DownloadIntentExtension;
50
+ create<I extends Exact<DeepPartial<DownloadIntentExtension>, I>>(base?: I): DownloadIntentExtension;
51
+ fromPartial<I extends Exact<DeepPartial<DownloadIntentExtension>, I>>(object: I): DownloadIntentExtension;
52
+ };
53
+ export declare const DownloadIntentExtension_DownloadIntent: {
54
+ encode(message: DownloadIntentExtension_DownloadIntent, writer?: _m0.Writer): _m0.Writer;
55
+ decode(input: _m0.Reader | Uint8Array, length?: number): DownloadIntentExtension_DownloadIntent;
56
+ create<I extends Exact<DeepPartial<DownloadIntentExtension_DownloadIntent>, I>>(base?: I): DownloadIntentExtension_DownloadIntent;
57
+ fromPartial<I extends Exact<DeepPartial<DownloadIntentExtension_DownloadIntent>, I>>(object: I): DownloadIntentExtension_DownloadIntent;
58
+ };
59
+ export declare const DownloadIntentExtension_DownloadIntentsEntry: {
60
+ encode(message: DownloadIntentExtension_DownloadIntentsEntry, writer?: _m0.Writer): _m0.Writer;
61
+ decode(input: _m0.Reader | Uint8Array, length?: number): DownloadIntentExtension_DownloadIntentsEntry;
62
+ create<I extends Exact<DeepPartial<DownloadIntentExtension_DownloadIntentsEntry>, I>>(base?: I): DownloadIntentExtension_DownloadIntentsEntry;
63
+ fromPartial<I extends Exact<DeepPartial<DownloadIntentExtension_DownloadIntentsEntry>, I>>(object: I): DownloadIntentExtension_DownloadIntentsEntry;
64
+ };
34
65
  type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
35
66
  type DeepPartial<T> = T extends Builtin ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : T extends {} ? {
36
67
  [K in keyof T]?: DeepPartial<T[K]>;
@@ -169,6 +169,156 @@ export var HaveExtension = {
169
169
  return message;
170
170
  },
171
171
  };
172
+ function createBaseDownloadIntentExtension() {
173
+ return { downloadIntents: {} };
174
+ }
175
+ export var DownloadIntentExtension = {
176
+ encode: function (message, writer) {
177
+ if (writer === void 0) { writer = _m0.Writer.create(); }
178
+ Object.entries(message.downloadIntents).forEach(function (_a) {
179
+ var key = _a[0], value = _a[1];
180
+ DownloadIntentExtension_DownloadIntentsEntry.encode({ key: key, value: value }, writer.uint32(10).fork())
181
+ .ldelim();
182
+ });
183
+ return writer;
184
+ },
185
+ decode: function (input, length) {
186
+ var reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
187
+ var end = length === undefined ? reader.len : reader.pos + length;
188
+ var message = createBaseDownloadIntentExtension();
189
+ while (reader.pos < end) {
190
+ var tag = reader.uint32();
191
+ switch (tag >>> 3) {
192
+ case 1:
193
+ if (tag !== 10) {
194
+ break;
195
+ }
196
+ var entry1 = DownloadIntentExtension_DownloadIntentsEntry.decode(reader, reader.uint32());
197
+ if (entry1.value !== undefined) {
198
+ message.downloadIntents[entry1.key] = entry1.value;
199
+ }
200
+ continue;
201
+ }
202
+ if ((tag & 7) === 4 || tag === 0) {
203
+ break;
204
+ }
205
+ reader.skipType(tag & 7);
206
+ }
207
+ return message;
208
+ },
209
+ create: function (base) {
210
+ return DownloadIntentExtension.fromPartial(base !== null && base !== void 0 ? base : {});
211
+ },
212
+ fromPartial: function (object) {
213
+ var _a;
214
+ var message = createBaseDownloadIntentExtension();
215
+ message.downloadIntents = Object.entries((_a = object.downloadIntents) !== null && _a !== void 0 ? _a : {}).reduce(function (acc, _a) {
216
+ var key = _a[0], value = _a[1];
217
+ if (value !== undefined) {
218
+ acc[key] = DownloadIntentExtension_DownloadIntent.fromPartial(value);
219
+ }
220
+ return acc;
221
+ }, {});
222
+ return message;
223
+ },
224
+ };
225
+ function createBaseDownloadIntentExtension_DownloadIntent() {
226
+ return { variants: [] };
227
+ }
228
+ export var DownloadIntentExtension_DownloadIntent = {
229
+ encode: function (message, writer) {
230
+ if (writer === void 0) { writer = _m0.Writer.create(); }
231
+ for (var _i = 0, _a = message.variants; _i < _a.length; _i++) {
232
+ var v = _a[_i];
233
+ writer.uint32(10).string(v);
234
+ }
235
+ return writer;
236
+ },
237
+ decode: function (input, length) {
238
+ var reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
239
+ var end = length === undefined ? reader.len : reader.pos + length;
240
+ var message = createBaseDownloadIntentExtension_DownloadIntent();
241
+ while (reader.pos < end) {
242
+ var tag = reader.uint32();
243
+ switch (tag >>> 3) {
244
+ case 1:
245
+ if (tag !== 10) {
246
+ break;
247
+ }
248
+ message.variants.push(reader.string());
249
+ continue;
250
+ }
251
+ if ((tag & 7) === 4 || tag === 0) {
252
+ break;
253
+ }
254
+ reader.skipType(tag & 7);
255
+ }
256
+ return message;
257
+ },
258
+ create: function (base) {
259
+ return DownloadIntentExtension_DownloadIntent.fromPartial(base !== null && base !== void 0 ? base : {});
260
+ },
261
+ fromPartial: function (object) {
262
+ var _a;
263
+ var message = createBaseDownloadIntentExtension_DownloadIntent();
264
+ message.variants = ((_a = object.variants) === null || _a === void 0 ? void 0 : _a.map(function (e) { return e; })) || [];
265
+ return message;
266
+ },
267
+ };
268
+ function createBaseDownloadIntentExtension_DownloadIntentsEntry() {
269
+ return { key: "", value: undefined };
270
+ }
271
+ export var DownloadIntentExtension_DownloadIntentsEntry = {
272
+ encode: function (message, writer) {
273
+ if (writer === void 0) { writer = _m0.Writer.create(); }
274
+ if (message.key !== "") {
275
+ writer.uint32(10).string(message.key);
276
+ }
277
+ if (message.value !== undefined) {
278
+ DownloadIntentExtension_DownloadIntent.encode(message.value, writer.uint32(18).fork()).ldelim();
279
+ }
280
+ return writer;
281
+ },
282
+ decode: function (input, length) {
283
+ var reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
284
+ var end = length === undefined ? reader.len : reader.pos + length;
285
+ var message = createBaseDownloadIntentExtension_DownloadIntentsEntry();
286
+ while (reader.pos < end) {
287
+ var tag = reader.uint32();
288
+ switch (tag >>> 3) {
289
+ case 1:
290
+ if (tag !== 10) {
291
+ break;
292
+ }
293
+ message.key = reader.string();
294
+ continue;
295
+ case 2:
296
+ if (tag !== 18) {
297
+ break;
298
+ }
299
+ message.value = DownloadIntentExtension_DownloadIntent.decode(reader, reader.uint32());
300
+ continue;
301
+ }
302
+ if ((tag & 7) === 4 || tag === 0) {
303
+ break;
304
+ }
305
+ reader.skipType(tag & 7);
306
+ }
307
+ return message;
308
+ },
309
+ create: function (base) {
310
+ return DownloadIntentExtension_DownloadIntentsEntry.fromPartial(base !== null && base !== void 0 ? base : {});
311
+ },
312
+ fromPartial: function (object) {
313
+ var _a;
314
+ var message = createBaseDownloadIntentExtension_DownloadIntentsEntry();
315
+ message.key = (_a = object.key) !== null && _a !== void 0 ? _a : "";
316
+ message.value = (object.value !== undefined && object.value !== null)
317
+ ? DownloadIntentExtension_DownloadIntent.fromPartial(object.value)
318
+ : undefined;
319
+ return message;
320
+ },
321
+ };
172
322
  var tsProtoGlobalThis = (function () {
173
323
  if (typeof globalThis !== "undefined") {
174
324
  return globalThis;