distributed-drive 0.0.1 → 0.0.2

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/index.js CHANGED
@@ -10,6 +10,7 @@ const { getEncoding } = require('./schema')
10
10
  const EntryResponse = getEncoding('@distributeddrive/entry-response')
11
11
  const ListResponse = getEncoding('@distributeddrive/list-response')
12
12
  const ReadRequest = getEncoding('@distributeddrive/read-request')
13
+ const ReaddirResponse = getEncoding('@distributeddrive/readdir-response')
13
14
 
14
15
  const EMPTY = Buffer.alloc(0)
15
16
  const NOT_FOUND = { exists: false, entry: null }
@@ -18,6 +19,7 @@ const entryOpts = { requestEncoding: c.string, responseEncoding: EntryResponse }
18
19
  const getOpts = { requestEncoding: c.string }
19
20
  const readOpts = { requestEncoding: ReadRequest }
20
21
  const listOpts = { requestEncoding: c.string, responseEncoding: ListResponse }
22
+ const readdirOpts = { requestEncoding: c.string, responseEncoding: ReaddirResponse }
21
23
  const invalidateOpts = { valueEncoding: c.string }
22
24
 
23
25
  class DistributedDrive extends ReadyResource {
@@ -188,6 +190,13 @@ class DistributedDrive extends ReadyResource {
188
190
  return null
189
191
  }
190
192
 
193
+ readdir(prefix) {
194
+ prefix = normalize(prefix || '/')
195
+ const rs = new Readable()
196
+ this._readdirInto(rs, prefix).catch((err) => rs.destroy(err))
197
+ return rs
198
+ }
199
+
191
200
  list(prefix, opts = {}) {
192
201
  prefix = normalize(prefix || '/')
193
202
  const rs = new Readable()
@@ -262,6 +271,42 @@ class DistributedDrive extends ReadyResource {
262
271
  rs.push(null)
263
272
  }
264
273
 
274
+ async _readdirInto(rs, prefix) {
275
+ const seen = new Set()
276
+
277
+ for (const drive of this.drives) {
278
+ try {
279
+ for await (const name of drive.readdir(prefix)) {
280
+ if (seen.has(name)) continue
281
+ seen.add(name)
282
+ rs.push(name)
283
+ }
284
+ } catch (err) {
285
+ safetyCatch(err)
286
+ }
287
+ }
288
+
289
+ const promises = [...this._peers].map((peer) =>
290
+ peer.rpcReaddir(prefix).catch((err) => {
291
+ safetyCatch(err)
292
+ return []
293
+ })
294
+ )
295
+
296
+ const results = await Promise.all(promises)
297
+
298
+ for (const names of results) {
299
+ if (!names) continue
300
+ for (const name of names) {
301
+ if (seen.has(name)) continue
302
+ seen.add(name)
303
+ rs.push(name)
304
+ }
305
+ }
306
+
307
+ rs.push(null)
308
+ }
309
+
265
310
  async _fanout(method, path) {
266
311
  const results = []
267
312
 
@@ -294,6 +339,7 @@ class Peer {
294
339
  this.rpc.respond('get', getOpts, (path) => this._onGet(path))
295
340
  this.rpc.respond('read', readOpts, (req) => this._onRead(req))
296
341
  this.rpc.respond('list', listOpts, (prefix) => this._onList(prefix))
342
+ this.rpc.respond('readdir', readdirOpts, (prefix) => this._onReaddir(prefix))
297
343
  this.rpc.respond('invalidate', invalidateOpts, (path) => this._onInvalidate(path))
298
344
  }
299
345
 
@@ -357,6 +403,25 @@ class Peer {
357
403
  return { entries }
358
404
  }
359
405
 
406
+ async _onReaddir(prefix) {
407
+ const names = []
408
+ const seen = new Set()
409
+
410
+ for (const drive of this.drive.drives) {
411
+ try {
412
+ for await (const name of drive.readdir(prefix)) {
413
+ if (seen.has(name)) continue
414
+ seen.add(name)
415
+ names.push(name)
416
+ }
417
+ } catch (err) {
418
+ safetyCatch(err)
419
+ }
420
+ }
421
+
422
+ return { names }
423
+ }
424
+
360
425
  async _onInvalidate(path) {
361
426
  this.drive._stale.add(path)
362
427
  }
@@ -386,6 +451,11 @@ class Peer {
386
451
  return response.entries
387
452
  }
388
453
 
454
+ async rpcReaddir(prefix) {
455
+ const response = await this.rpc.request('readdir', prefix, readdirOpts)
456
+ return response.names
457
+ }
458
+
389
459
  invalidate(path) {
390
460
  this.rpc.event('invalidate', path, invalidateOpts)
391
461
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "distributed-drive",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Drive-compatible unified view across multiple peers and drives over RPC",
5
5
  "main": "index.js",
6
6
  "imports": {
package/schema/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // This file is autogenerated by the hyperschema compiler
2
- // Schema Version: 2
2
+ // Schema Version: 3
3
3
  /* eslint-disable camelcase */
4
4
  /* eslint-disable quotes */
5
5
  /* eslint-disable space-before-function-paren */
6
6
 
7
7
  const { c } = require('hyperschema/runtime')
8
8
 
9
- const VERSION = 2
9
+ const VERSION = 3
10
10
 
11
11
  // eslint-disable-next-line no-unused-vars
12
12
  let version = VERSION
@@ -170,6 +170,26 @@ const encoding5 = {
170
170
  }
171
171
  }
172
172
 
173
+ // @distributeddrive/readdir-response.names
174
+ const encoding6_0 = c.array(c.string)
175
+
176
+ // @distributeddrive/readdir-response
177
+ const encoding6 = {
178
+ preencode(state, m) {
179
+ encoding6_0.preencode(state, m.names)
180
+ },
181
+ encode(state, m) {
182
+ encoding6_0.encode(state, m.names)
183
+ },
184
+ decode(state) {
185
+ const r0 = encoding6_0.decode(state)
186
+
187
+ return {
188
+ names: r0
189
+ }
190
+ }
191
+ }
192
+
173
193
  function setVersion(v) {
174
194
  version = v
175
195
  }
@@ -205,6 +225,8 @@ function getEncoding(name) {
205
225
  return encoding4
206
226
  case '@distributeddrive/read-request':
207
227
  return encoding5
228
+ case '@distributeddrive/readdir-response':
229
+ return encoding6
208
230
  default:
209
231
  throw new Error('Encoder not found ' + name)
210
232
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": 2,
2
+ "version": 3,
3
3
  "schema": [
4
4
  {
5
5
  "name": "blob",
@@ -141,6 +141,21 @@
141
141
  "version": 2
142
142
  }
143
143
  ]
144
+ },
145
+ {
146
+ "name": "readdir-response",
147
+ "namespace": "distributeddrive",
148
+ "compact": false,
149
+ "flagsPosition": -1,
150
+ "fields": [
151
+ {
152
+ "name": "names",
153
+ "required": true,
154
+ "array": true,
155
+ "type": "string",
156
+ "version": 3
157
+ }
158
+ ]
144
159
  }
145
160
  ]
146
161
  }