helia 6.1.4 → 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.
Files changed (92) hide show
  1. package/dist/index.min.js +65 -55
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/block-storage.d.ts +62 -0
  4. package/dist/src/block-storage.d.ts.map +1 -0
  5. package/dist/src/block-storage.js +159 -0
  6. package/dist/src/block-storage.js.map +1 -0
  7. package/dist/src/datastore-version.d.ts +3 -0
  8. package/dist/src/datastore-version.d.ts.map +1 -0
  9. package/dist/src/datastore-version.js +20 -0
  10. package/dist/src/datastore-version.js.map +1 -0
  11. package/dist/src/get-codec.d.ts +4 -0
  12. package/dist/src/get-codec.d.ts.map +1 -0
  13. package/dist/src/get-codec.js +31 -0
  14. package/dist/src/get-codec.js.map +1 -0
  15. package/dist/src/get-crypto.d.ts +4 -0
  16. package/dist/src/get-crypto.d.ts.map +1 -0
  17. package/dist/src/get-crypto.js +35 -0
  18. package/dist/src/get-crypto.js.map +1 -0
  19. package/dist/src/get-hasher.d.ts +4 -0
  20. package/dist/src/get-hasher.d.ts.map +1 -0
  21. package/dist/src/get-hasher.js +31 -0
  22. package/dist/src/get-hasher.js.map +1 -0
  23. package/dist/src/helia.d.ts +165 -0
  24. package/dist/src/helia.d.ts.map +1 -0
  25. package/dist/src/helia.js +165 -0
  26. package/dist/src/helia.js.map +1 -0
  27. package/dist/src/index.d.ts +30 -19
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +78 -12
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/networked-storage.d.ts +28 -0
  32. package/dist/src/networked-storage.d.ts.map +1 -0
  33. package/dist/src/networked-storage.js +52 -0
  34. package/dist/src/networked-storage.js.map +1 -0
  35. package/dist/src/pins.d.ts +21 -0
  36. package/dist/src/pins.d.ts.map +1 -0
  37. package/dist/src/pins.js +140 -0
  38. package/dist/src/pins.js.map +1 -0
  39. package/dist/src/routing.d.ts +51 -0
  40. package/dist/src/routing.d.ts.map +1 -0
  41. package/dist/src/routing.js +311 -0
  42. package/dist/src/routing.js.map +1 -0
  43. package/dist/src/session-storage.d.ts +47 -0
  44. package/dist/src/session-storage.d.ts.map +1 -0
  45. package/dist/src/session-storage.js +148 -0
  46. package/dist/src/session-storage.js.map +1 -0
  47. package/dist/src/storage.d.ts +55 -0
  48. package/dist/src/storage.d.ts.map +1 -0
  49. package/dist/src/storage.js +225 -0
  50. package/dist/src/storage.js.map +1 -0
  51. package/dist/src/version.d.ts +1 -1
  52. package/dist/src/version.js +1 -1
  53. package/dist/typedoc-urls.json +3 -6
  54. package/package.json +38 -41
  55. package/src/block-storage.ts +194 -0
  56. package/src/datastore-version.ts +25 -0
  57. package/src/get-codec.ts +39 -0
  58. package/src/get-crypto.ts +44 -0
  59. package/src/get-hasher.ts +39 -0
  60. package/src/helia.ts +364 -0
  61. package/src/index.ts +58 -30
  62. package/src/networked-storage.ts +74 -0
  63. package/src/pins.ts +208 -0
  64. package/src/routing.ts +389 -0
  65. package/src/session-storage.ts +174 -0
  66. package/src/storage.ts +294 -0
  67. package/src/version.ts +1 -1
  68. package/dist/src/utils/bootstrappers.d.ts +0 -4
  69. package/dist/src/utils/bootstrappers.d.ts.map +0 -1
  70. package/dist/src/utils/bootstrappers.js +0 -13
  71. package/dist/src/utils/bootstrappers.js.map +0 -1
  72. package/dist/src/utils/helia-defaults.d.ts +0 -48
  73. package/dist/src/utils/helia-defaults.d.ts.map +0 -1
  74. package/dist/src/utils/helia-defaults.js +0 -85
  75. package/dist/src/utils/helia-defaults.js.map +0 -1
  76. package/dist/src/utils/libp2p-defaults.browser.d.ts +0 -19
  77. package/dist/src/utils/libp2p-defaults.browser.d.ts.map +0 -1
  78. package/dist/src/utils/libp2p-defaults.browser.js +0 -73
  79. package/dist/src/utils/libp2p-defaults.browser.js.map +0 -1
  80. package/dist/src/utils/libp2p-defaults.d.ts +0 -49
  81. package/dist/src/utils/libp2p-defaults.d.ts.map +0 -1
  82. package/dist/src/utils/libp2p-defaults.js +0 -113
  83. package/dist/src/utils/libp2p-defaults.js.map +0 -1
  84. package/dist/src/utils/libp2p.d.ts +0 -19
  85. package/dist/src/utils/libp2p.d.ts.map +0 -1
  86. package/dist/src/utils/libp2p.js +0 -19
  87. package/dist/src/utils/libp2p.js.map +0 -1
  88. package/src/utils/bootstrappers.ts +0 -12
  89. package/src/utils/helia-defaults.ts +0 -92
  90. package/src/utils/libp2p-defaults.browser.ts +0 -92
  91. package/src/utils/libp2p-defaults.ts +0 -137
  92. package/src/utils/libp2p.ts +0 -42
@@ -0,0 +1,225 @@
1
+ import { BlockNotFoundWhileOfflineError, InvalidConfigurationError, LoadBlockFailedError } from '@helia/utils';
2
+ import { isPromise } from '@helia/utils';
3
+ import { InvalidMultihashError, InvalidParametersError, setMaxListeners } from '@libp2p/interface';
4
+ import { anySignal } from 'any-signal';
5
+ import { IdentityBlockstore } from 'blockstore-core/identity';
6
+ import filter from 'it-filter';
7
+ import forEach from 'it-foreach';
8
+ import { CustomProgressEvent } from 'progress-events';
9
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
10
+ const DEFAULT_MAX_IDENTITY_HASH_DIGEST_LENGTH = 128;
11
+ export class Storage {
12
+ child;
13
+ getHasher;
14
+ log;
15
+ logger;
16
+ blockBrokers;
17
+ /**
18
+ * Create a new BlockStorage
19
+ */
20
+ constructor(components, init = {}) {
21
+ this.log = components.logger.forComponent('helia:networked-storage');
22
+ this.logger = components.logger;
23
+ this.blockBrokers = components.blockBrokers;
24
+ this.child = new IdentityBlockstore(components.blockstore, {
25
+ maxDigestLength: init.maxIdentityHashDigestLength ?? DEFAULT_MAX_IDENTITY_HASH_DIGEST_LENGTH
26
+ });
27
+ this.getHasher = components.getHasher;
28
+ }
29
+ /**
30
+ * Put a block to the underlying datastore
31
+ */
32
+ async put(cid, block, options = {}) {
33
+ if (await this.child.has(cid, options)) {
34
+ options.onProgress?.(new CustomProgressEvent('blocks:put:duplicate', cid));
35
+ return cid;
36
+ }
37
+ options.onProgress?.(new CustomProgressEvent('blocks:put:providers:notify', cid));
38
+ await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
39
+ options.onProgress?.(new CustomProgressEvent('blocks:put:blockstore:put', cid));
40
+ return this.child.put(cid, block, options);
41
+ }
42
+ /**
43
+ * Put a multiple blocks to the underlying datastore
44
+ */
45
+ async *putMany(blocks, options = {}) {
46
+ const missingBlocks = filter(blocks, async ({ cid }) => {
47
+ const has = await this.child.has(cid, options);
48
+ if (has) {
49
+ options.onProgress?.(new CustomProgressEvent('blocks:put-many:duplicate', cid));
50
+ }
51
+ return !has;
52
+ });
53
+ const notifyEach = forEach(missingBlocks, async ({ cid }) => {
54
+ options.onProgress?.(new CustomProgressEvent('blocks:put-many:providers:notify', cid));
55
+ await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
56
+ });
57
+ options.onProgress?.(new CustomProgressEvent('blocks:put-many:blockstore:put-many'));
58
+ yield* this.child.putMany(notifyEach, options);
59
+ }
60
+ /**
61
+ * Get a block by cid
62
+ */
63
+ async *get(cid, options = {}) {
64
+ const has = await this.child.has(cid, options);
65
+ const offline = options.offline === true;
66
+ if (!has) {
67
+ if (offline) {
68
+ throw new BlockNotFoundWhileOfflineError('The block was present in the blockstore and the node is running offline so cannot fetch it');
69
+ }
70
+ const hasher = await this.getHasher(cid.multihash.code);
71
+ options?.signal?.throwIfAborted();
72
+ // we do not have the block locally, get it from a block provider
73
+ options.onProgress?.(new CustomProgressEvent('blocks:get:providers:get', cid));
74
+ const block = await raceBlockRetrievers(cid, this.blockBrokers, hasher, {
75
+ ...options,
76
+ log: this.log
77
+ });
78
+ options.onProgress?.(new CustomProgressEvent('blocks:get:blockstore:put', cid));
79
+ await this.child.put(cid, block, options);
80
+ // notify other block providers of the new block
81
+ options.onProgress?.(new CustomProgressEvent('blocks:get:providers:notify', cid));
82
+ await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
83
+ yield block;
84
+ return;
85
+ }
86
+ options.onProgress?.(new CustomProgressEvent('blocks:get:blockstore:get', cid));
87
+ yield* this.child.get(cid, options);
88
+ }
89
+ /**
90
+ * Get multiple blocks back from an (async) iterable of cids
91
+ */
92
+ async *getMany(cids, options = {}) {
93
+ options.onProgress?.(new CustomProgressEvent('blocks:get-many:blockstore:get-many'));
94
+ yield* this.child.getMany(forEach(cids, async (cid) => {
95
+ const has = await this.child.has(cid, options);
96
+ const offline = options.offline === true;
97
+ if (!has) {
98
+ if (offline) {
99
+ throw new BlockNotFoundWhileOfflineError('The block was present in the blockstore and the node is running offline so cannot fetch it');
100
+ }
101
+ const hasher = await this.getHasher(cid.multihash.code);
102
+ options?.signal?.throwIfAborted();
103
+ // we do not have the block locally, get it from a block provider
104
+ options.onProgress?.(new CustomProgressEvent('blocks:get-many:providers:get', cid));
105
+ const block = await raceBlockRetrievers(cid, this.blockBrokers, hasher, {
106
+ ...options,
107
+ log: this.log
108
+ });
109
+ options.onProgress?.(new CustomProgressEvent('blocks:get-many:blockstore:put', cid));
110
+ await this.child.put(cid, block, options);
111
+ // notify other block providers of the new block
112
+ options.onProgress?.(new CustomProgressEvent('blocks:get-many:providers:notify', cid));
113
+ await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
114
+ }
115
+ }));
116
+ }
117
+ /**
118
+ * Delete a block from the blockstore
119
+ */
120
+ async delete(cid, options = {}) {
121
+ options.onProgress?.(new CustomProgressEvent('blocks:delete:blockstore:delete', cid));
122
+ await this.child.delete(cid, options);
123
+ }
124
+ /**
125
+ * Delete multiple blocks from the blockstore
126
+ */
127
+ async *deleteMany(cids, options = {}) {
128
+ options.onProgress?.(new CustomProgressEvent('blocks:delete-many:blockstore:delete-many'));
129
+ yield* this.child.deleteMany((async function* () {
130
+ for await (const cid of cids) {
131
+ yield cid;
132
+ }
133
+ }()), options);
134
+ }
135
+ async has(cid, options = {}) {
136
+ return this.child.has(cid, options);
137
+ }
138
+ async *getAll(options = {}) {
139
+ options.onProgress?.(new CustomProgressEvent('blocks:get-all:blockstore:get-many'));
140
+ yield* this.child.getAll(options);
141
+ }
142
+ }
143
+ /**
144
+ * Race block providers cancelling any pending requests once the block has been
145
+ * found.
146
+ */
147
+ async function raceBlockRetrievers(cid, blockBrokers, hasher, options) {
148
+ const validateFn = getCidBlockVerifierFunction(cid, hasher);
149
+ const controller = new AbortController();
150
+ const signal = anySignal([controller.signal, options.signal]);
151
+ setMaxListeners(Infinity, controller.signal, signal);
152
+ const retrievers = [];
153
+ for (const broker of blockBrokers) {
154
+ if (isRetrievingBlockBroker(broker)) {
155
+ retrievers.push(broker);
156
+ }
157
+ }
158
+ if (retrievers.length === 0) {
159
+ throw new InvalidConfigurationError(`No block brokers capable of retrieving blocks are configured, the CID ${cid} cannot be fetched from the network`);
160
+ }
161
+ try {
162
+ return await Promise.any(retrievers
163
+ .map(async (retriever) => {
164
+ try {
165
+ let blocksWereValidated = false;
166
+ const block = await retriever.retrieve(cid, {
167
+ ...options,
168
+ signal,
169
+ validateFn: async (block) => {
170
+ await validateFn(block);
171
+ options.signal?.throwIfAborted();
172
+ blocksWereValidated = true;
173
+ }
174
+ });
175
+ if (!blocksWereValidated) {
176
+ // the blockBroker either did not throw an error when attempting to validate the block
177
+ // or did not call the validateFn at all. We should validate the block ourselves
178
+ await validateFn(block);
179
+ options.signal?.throwIfAborted();
180
+ }
181
+ return block;
182
+ }
183
+ catch (err) {
184
+ options.log.error('could not retrieve verified block for %c from %s - %e', cid, retriever.name, err);
185
+ throw err;
186
+ }
187
+ }));
188
+ }
189
+ catch (err) {
190
+ throw new LoadBlockFailedError(err.errors, `Failed to load block for ${cid}`);
191
+ }
192
+ finally {
193
+ // we have the block from the fastest block retriever, abort any still
194
+ // in-flight retrieve attempts
195
+ controller.abort();
196
+ signal.clear();
197
+ }
198
+ }
199
+ function isRetrievingBlockBroker(broker) {
200
+ return typeof broker.retrieve === 'function';
201
+ }
202
+ export const getCidBlockVerifierFunction = (cid, hasher) => {
203
+ if (hasher == null) {
204
+ throw new InvalidParametersError(`No hasher configured for multihash code 0x${cid.multihash.code.toString(16)}, please configure one. You can look up which hash this is at https://github.com/multiformats/multicodec/blob/master/table.csv`);
205
+ }
206
+ return async (block) => {
207
+ // verify block
208
+ let hash;
209
+ const res = hasher.digest(block, {
210
+ // support truncated hashes where they are truncated
211
+ truncate: cid.multihash.digest.byteLength
212
+ });
213
+ if (isPromise(res)) {
214
+ hash = await res;
215
+ }
216
+ else {
217
+ hash = res;
218
+ }
219
+ if (!uint8ArrayEquals(hash.digest, cid.multihash.digest)) {
220
+ // if a hash mismatch occurs for a TrustlessGatewayBlockBroker, we should try another gateway
221
+ throw new InvalidMultihashError('Hash of downloaded block did not match multihash from passed CID');
222
+ }
223
+ };
224
+ };
225
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/storage.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- export declare const version = "6.1.4";
1
+ export declare const version = "7.0.0";
2
2
  export declare const name = "helia";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
- export const version = '6.1.4';
1
+ export const version = '7.0.0';
2
2
  export const name = 'helia';
3
3
  //# sourceMappingURL=version.js.map
@@ -1,10 +1,7 @@
1
1
  {
2
- "DAGWalker": "https://ipfs.github.io/helia/interfaces/helia.DAGWalker.html",
3
- ".:DAGWalker": "https://ipfs.github.io/helia/interfaces/helia.DAGWalker.html",
4
- "DefaultLibp2pServices": "https://ipfs.github.io/helia/interfaces/helia.DefaultLibp2pServices.html",
5
- "Libp2pDefaultsOptions": "https://ipfs.github.io/helia/interfaces/helia.Libp2pDefaultsOptions.html",
2
+ "HeliaInit": "https://ipfs.github.io/helia/interfaces/helia.HeliaInit.html",
6
3
  "createHelia": "https://ipfs.github.io/helia/functions/helia.createHelia.html",
7
4
  ".:createHelia": "https://ipfs.github.io/helia/functions/helia.createHelia.html",
8
- "heliaDefaults": "https://ipfs.github.io/helia/functions/helia.heliaDefaults.html",
9
- "libp2pDefaults": "https://ipfs.github.io/helia/functions/helia.libp2pDefaults.html"
5
+ "createHeliaLight": "https://ipfs.github.io/helia/functions/helia.createHeliaLight.html",
6
+ ".:createHeliaLight": "https://ipfs.github.io/helia/functions/helia.createHeliaLight.html"
10
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helia",
3
- "version": "6.1.4",
3
+ "version": "7.0.0",
4
4
  "description": "An implementation of IPFS in JavaScript",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/ipfs/helia/tree/main/packages/helia#readme",
@@ -49,49 +49,46 @@
49
49
  "prepublishOnly": "node scripts/update-version.js && npm run build"
50
50
  },
51
51
  "dependencies": {
52
- "@chainsafe/libp2p-noise": "^17.0.0",
53
- "@chainsafe/libp2p-yamux": "^8.0.1",
54
- "@helia/block-brokers": "^5.2.4",
55
- "@helia/delegated-routing-v1-http-api-client": "^6.0.1",
56
- "@helia/interface": "^6.2.1",
57
- "@helia/routers": "^5.1.1",
58
- "@helia/utils": "^2.5.2",
59
- "@ipshipyard/libp2p-auto-tls": "^2.0.1",
60
- "@libp2p/autonat": "^3.0.15",
61
- "@libp2p/bootstrap": "^12.0.16",
62
- "@libp2p/circuit-relay-v2": "^4.2.0",
63
- "@libp2p/config": "^1.1.27",
64
- "@libp2p/dcutr": "^3.0.15",
65
- "@libp2p/http": "^2.0.1",
66
- "@libp2p/identify": "^4.1.0",
67
- "@libp2p/interface": "^3.2.0",
68
- "@libp2p/kad-dht": "^16.2.0",
69
- "@libp2p/keychain": "^6.0.12",
70
- "@libp2p/mdns": "^12.0.16",
71
- "@libp2p/mplex": "^12.0.16",
72
- "@libp2p/ping": "^3.1.0",
73
- "@libp2p/tcp": "^11.0.15",
74
- "@libp2p/tls": "^3.0.15",
75
- "@libp2p/upnp-nat": "^4.0.15",
76
- "@libp2p/webrtc": "^6.0.16",
77
- "@libp2p/websockets": "^10.1.8",
78
- "@multiformats/dns": "^1.0.13",
79
- "blockstore-core": "^6.1.3",
80
- "datastore-core": "^11.0.3",
81
- "interface-datastore": "^9.0.3",
82
- "ipns": "^10.1.3",
83
- "libp2p": "^3.2.0",
84
- "multiformats": "^13.4.2"
52
+ "@helia/bitswap": "^4.0.0",
53
+ "@helia/http": "^4.0.0",
54
+ "@helia/interface": "^7.0.0",
55
+ "@helia/libp2p": "^1.0.0",
56
+ "@helia/utils": "^3.0.0",
57
+ "@ipld/dag-cbor": "^10.0.1",
58
+ "@ipld/dag-json": "^11.0.0",
59
+ "@ipld/dag-pb": "^4.1.7",
60
+ "@ipshipyard/crypto": "^1.1.0",
61
+ "@ipshipyard/keychain": "^1.0.2",
62
+ "@libp2p/interface": "^3.2.4",
63
+ "@libp2p/utils": "^7.2.3",
64
+ "@multiformats/dns": "^1.0.15",
65
+ "@multiformats/multiaddr": "^13.0.3",
66
+ "abort-error": "^1.0.2",
67
+ "any-signal": "^4.2.0",
68
+ "birnam": "^1.0.0",
69
+ "blockstore-core": "^7.0.1",
70
+ "cborg": "^5.1.4",
71
+ "datastore-core": "^12.0.1",
72
+ "interface-blockstore": "^7.0.1",
73
+ "interface-datastore": "^10.0.1",
74
+ "it-drain": "^3.0.12",
75
+ "it-filter": "^3.1.6",
76
+ "it-foreach": "^2.1.7",
77
+ "it-merge": "^3.0.14",
78
+ "main-event": "^1.0.4",
79
+ "mortice": "^3.3.1",
80
+ "multiformats": "^14.0.0",
81
+ "progress-events": "^1.1.0",
82
+ "uint8arrays": "^6.1.1"
85
83
  },
86
84
  "devDependencies": {
87
- "@multiformats/mafmt": "^12.1.6",
88
- "@multiformats/multiaddr": "^13.0.1",
89
- "aegir": "^47.1.5",
85
+ "aegir": "^48.0.11",
86
+ "delay": "^7.0.0",
90
87
  "it-all": "^3.0.11",
91
- "it-drain": "^3.0.12"
92
- },
93
- "browser": {
94
- "./dist/src/utils/libp2p-defaults.js": "./dist/src/utils/libp2p-defaults.browser.js"
88
+ "it-map": "^3.1.6",
89
+ "it-to-buffer": "^5.0.0",
90
+ "sinon": "^22.0.0",
91
+ "sinon-ts": "^2.0.0"
95
92
  },
96
93
  "sideEffects": false
97
94
  }
@@ -0,0 +1,194 @@
1
+ import { BlockPinnedError } from '@helia/utils'
2
+ import { start, stop } from '@libp2p/interface'
3
+ import createMortice from 'mortice'
4
+ import type { Routing } from '@helia/interface'
5
+ import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions, SessionBlockstore } from '@helia/interface'
6
+ import type { Pins } from '@helia/interface'
7
+ import type { AbortOptions, Startable } from '@libp2p/interface'
8
+ import type { Blockstore, InputPair } from 'interface-blockstore'
9
+ import type { Mortice } from 'mortice'
10
+ import type { CID } from 'multiformats/cid'
11
+ import type { ProgressOptions } from 'progress-events'
12
+
13
+ export interface BlockStorageInit {
14
+ holdGcLock?: boolean
15
+ }
16
+
17
+ export interface GetOptions extends AbortOptions {
18
+ progress?(evt: Event): void
19
+ }
20
+
21
+ /**
22
+ * BlockStorage is a hybrid blockstore that puts/gets blocks from a configured
23
+ * blockstore (that may be on disk, s3, or something else). If the blocks are
24
+ * not present Bitswap will be used to fetch them from network peers.
25
+ */
26
+ export class BlockStorage implements Blocks, Startable {
27
+ public lock: Mortice
28
+ private readonly child: Blocks
29
+ private readonly pins: Pins
30
+ private readonly routing: Routing
31
+ private started: boolean
32
+
33
+ /**
34
+ * Create a new BlockStorage
35
+ */
36
+ constructor (blockstore: Blocks, pins: Pins, routing: Routing, options: BlockStorageInit = {}) {
37
+ this.child = blockstore
38
+ this.pins = pins
39
+ this.routing = routing
40
+ this.lock = createMortice({
41
+ singleProcess: options.holdGcLock
42
+ })
43
+ this.started = false
44
+ }
45
+
46
+ isStarted (): boolean {
47
+ return this.started
48
+ }
49
+
50
+ async start (): Promise<void> {
51
+ await start(this.child)
52
+ this.started = true
53
+ }
54
+
55
+ async stop (): Promise<void> {
56
+ await stop(this.child)
57
+ this.started = false
58
+ }
59
+
60
+ unwrap (): Blockstore {
61
+ return this.child
62
+ }
63
+
64
+ /**
65
+ * Put a block to the underlying datastore
66
+ */
67
+ async put (cid: CID, block: Uint8Array, options: AbortOptions & ProgressOptions<PutBlockProgressEvents> = {}): Promise<CID> {
68
+ options?.signal?.throwIfAborted()
69
+ const releaseLock = await this.lock.readLock()
70
+
71
+ try {
72
+ return await this.child.put(cid, block, options)
73
+ } finally {
74
+ releaseLock()
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Put a multiple blocks to the underlying datastore
80
+ */
81
+ async * putMany (blocks: Iterable<InputPair> | AsyncIterable<InputPair>, options: AbortOptions & ProgressOptions<PutManyBlocksProgressEvents> = {}): AsyncGenerator<CID> {
82
+ options?.signal?.throwIfAborted()
83
+ const releaseLock = await this.lock.readLock()
84
+
85
+ try {
86
+ yield * this.child.putMany(blocks, options)
87
+ } finally {
88
+ releaseLock()
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Get a block by cid
94
+ */
95
+ async * get (cid: CID, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetBlockProgressEvents> = {}): AsyncGenerator<Uint8Array> {
96
+ options?.signal?.throwIfAborted()
97
+ const releaseLock = await this.lock.readLock()
98
+
99
+ try {
100
+ yield * this.child.get(cid, options)
101
+ } finally {
102
+ releaseLock()
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Get multiple blocks back from an (async) iterable of cids
108
+ */
109
+ async * getMany (cids: Iterable<CID> | AsyncIterable<CID>, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetManyBlocksProgressEvents> = {}): AsyncGenerator<Pair> {
110
+ options?.signal?.throwIfAborted()
111
+ const releaseLock = await this.lock.readLock()
112
+
113
+ try {
114
+ yield * this.child.getMany(cids, options)
115
+ } finally {
116
+ releaseLock()
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Delete a block from the blockstore
122
+ */
123
+ async delete (cid: CID, options: AbortOptions & ProgressOptions<DeleteBlockProgressEvents> = {}): Promise<void> {
124
+ options?.signal?.throwIfAborted()
125
+ const releaseLock = await this.lock.writeLock()
126
+
127
+ try {
128
+ if (await this.pins.isPinned(cid)) {
129
+ throw new BlockPinnedError('Block was pinned - please unpin and try again')
130
+ }
131
+
132
+ // stop re-providing this CID if necessary
133
+ await this.routing.cancelReprovide(cid, options)
134
+
135
+ await this.child.delete(cid, options)
136
+ } finally {
137
+ releaseLock()
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Delete multiple blocks from the blockstore
143
+ */
144
+ async * deleteMany (cids: Iterable<CID> | AsyncIterable<CID>, options: AbortOptions & ProgressOptions<DeleteManyBlocksProgressEvents> = {}): AsyncGenerator<CID> {
145
+ options?.signal?.throwIfAborted()
146
+ const releaseLock = await this.lock.writeLock()
147
+
148
+ try {
149
+ const storage = this
150
+
151
+ yield * this.child.deleteMany((async function * (): AsyncGenerator<CID> {
152
+ for await (const cid of cids) {
153
+ if (await storage.pins.isPinned(cid)) {
154
+ throw new BlockPinnedError('Block was pinned - please unpin and try again')
155
+ }
156
+
157
+ // stop re-providing this CID if necessary
158
+ await storage.routing.cancelReprovide(cid, options)
159
+
160
+ yield cid
161
+ }
162
+ }()), options)
163
+ } finally {
164
+ releaseLock()
165
+ }
166
+ }
167
+
168
+ async has (cid: CID, options: AbortOptions = {}): Promise<boolean> {
169
+ options?.signal?.throwIfAborted()
170
+ const releaseLock = await this.lock.readLock()
171
+
172
+ try {
173
+ return await this.child.has(cid, options)
174
+ } finally {
175
+ releaseLock()
176
+ }
177
+ }
178
+
179
+ async * getAll (options: AbortOptions & ProgressOptions<GetAllBlocksProgressEvents> = {}): AsyncGenerator<Pair> {
180
+ options?.signal?.throwIfAborted()
181
+ const releaseLock = await this.lock.readLock()
182
+
183
+ try {
184
+ yield * this.child.getAll(options)
185
+ } finally {
186
+ releaseLock()
187
+ }
188
+ }
189
+
190
+ createSession (root: CID, options?: AbortOptions): SessionBlockstore {
191
+ options?.signal?.throwIfAborted()
192
+ return this.child.createSession(root, options)
193
+ }
194
+ }
@@ -0,0 +1,25 @@
1
+ import { InvalidDatastoreVersionError } from '@helia/utils'
2
+ import { Key } from 'interface-datastore'
3
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
4
+ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
5
+ import type { Datastore } from 'interface-datastore'
6
+
7
+ const DS_VERSION_KEY = new Key('/version')
8
+ const CURRENT_VERSION = 1
9
+
10
+ export async function assertDatastoreVersionIsCurrent (datastore: Datastore): Promise<void> {
11
+ if (!(await datastore.has(DS_VERSION_KEY))) {
12
+ await datastore.put(DS_VERSION_KEY, uint8ArrayFromString(`${CURRENT_VERSION}`))
13
+
14
+ return
15
+ }
16
+
17
+ const buf = await datastore.get(DS_VERSION_KEY)
18
+ const str = uint8ArrayToString(buf)
19
+ const version = parseInt(str, 10)
20
+
21
+ if (version !== CURRENT_VERSION) {
22
+ // TODO: write migrations when we break compatibility - for an example, see https://github.com/ipfs/js-ipfs-repo/tree/master/packages/ipfs-repo-migrations
23
+ throw new InvalidDatastoreVersionError('Invalid datastore version, a datastore migration may be required')
24
+ }
25
+ }
@@ -0,0 +1,39 @@
1
+ import { UnknownCodecError } from '@helia/interface'
2
+ import { isPromise } from '@helia/utils'
3
+ import * as dagPb from '@ipld/dag-pb'
4
+ import * as raw from 'multiformats/codecs/raw'
5
+ import type { CodecLoader } from '@helia/interface'
6
+ import type { BlockCodec } from 'multiformats/codecs/interface'
7
+
8
+ export function getCodec (initialCodecs: Array<BlockCodec<any, any>> = [], loadCodec?: CodecLoader): CodecLoader {
9
+ const codecs: Record<number, BlockCodec<any, any>> = {
10
+ [dagPb.code]: dagPb,
11
+ [raw.code]: raw
12
+ }
13
+
14
+ initialCodecs.forEach(codec => {
15
+ codecs[codec.code] = codec
16
+ })
17
+
18
+ return async (code) => {
19
+ let codec = codecs[code]
20
+
21
+ if (codec == null && loadCodec != null) {
22
+ const res = loadCodec(code)
23
+
24
+ if (isPromise(res)) {
25
+ codec = await res
26
+ } else {
27
+ codec = res
28
+ }
29
+
30
+ codecs[codec.code] = codec
31
+ }
32
+
33
+ if (codec != null) {
34
+ return codec
35
+ }
36
+
37
+ throw new UnknownCodecError(`Could not load codec for ${code}`)
38
+ }
39
+ }