hypercore-storage 2.9.0 → 3.0.1

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.
@@ -0,0 +1,481 @@
1
+ {
2
+ "version": 2,
3
+ "schema": [
4
+ {
5
+ "name": "allocated",
6
+ "namespace": "corestore",
7
+ "compact": true,
8
+ "flagsPosition": -1,
9
+ "fields": [
10
+ {
11
+ "name": "cores",
12
+ "required": true,
13
+ "type": "uint",
14
+ "version": 1
15
+ },
16
+ {
17
+ "name": "datas",
18
+ "required": true,
19
+ "type": "uint",
20
+ "version": 1
21
+ }
22
+ ]
23
+ },
24
+ {
25
+ "name": "head-v1",
26
+ "namespace": "corestore",
27
+ "compact": false,
28
+ "flagsPosition": 0,
29
+ "fields": [
30
+ {
31
+ "name": "allocated",
32
+ "type": "@corestore/allocated",
33
+ "version": 1
34
+ },
35
+ {
36
+ "name": "seed",
37
+ "type": "fixed32",
38
+ "version": 1
39
+ },
40
+ {
41
+ "name": "defaultDiscoveryKey",
42
+ "type": "fixed32",
43
+ "version": 1
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "name": "head-v2",
49
+ "namespace": "corestore",
50
+ "compact": false,
51
+ "flagsPosition": 3,
52
+ "fields": [
53
+ {
54
+ "name": "cores",
55
+ "required": true,
56
+ "type": "uint",
57
+ "version": 1
58
+ },
59
+ {
60
+ "name": "datas",
61
+ "required": true,
62
+ "type": "uint",
63
+ "version": 1
64
+ },
65
+ {
66
+ "name": "groups",
67
+ "required": true,
68
+ "type": "uint",
69
+ "version": 1
70
+ },
71
+ {
72
+ "name": "seed",
73
+ "type": "fixed32",
74
+ "version": 1
75
+ },
76
+ {
77
+ "name": "defaultDiscoveryKey",
78
+ "type": "fixed32",
79
+ "version": 1
80
+ }
81
+ ]
82
+ },
83
+ {
84
+ "name": "head",
85
+ "namespace": "corestore",
86
+ "versions": [
87
+ {
88
+ "type": "@corestore/head-v1",
89
+ "map": "headLegacyMap",
90
+ "version": 1
91
+ },
92
+ {
93
+ "type": "@corestore/head-v2",
94
+ "map": null,
95
+ "version": 2
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ "name": "alias",
101
+ "namespace": "corestore",
102
+ "compact": true,
103
+ "flagsPosition": -1,
104
+ "fields": [
105
+ {
106
+ "name": "name",
107
+ "required": true,
108
+ "type": "string",
109
+ "version": 1
110
+ },
111
+ {
112
+ "name": "namespace",
113
+ "required": true,
114
+ "type": "fixed32",
115
+ "version": 1
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "name": "core",
121
+ "namespace": "corestore",
122
+ "compact": false,
123
+ "flagsPosition": 3,
124
+ "fields": [
125
+ {
126
+ "name": "version",
127
+ "required": true,
128
+ "type": "uint",
129
+ "version": 1
130
+ },
131
+ {
132
+ "name": "corePointer",
133
+ "required": true,
134
+ "type": "uint",
135
+ "version": 1
136
+ },
137
+ {
138
+ "name": "dataPointer",
139
+ "required": true,
140
+ "type": "uint",
141
+ "version": 1
142
+ },
143
+ {
144
+ "name": "alias",
145
+ "type": "@corestore/alias",
146
+ "version": 1
147
+ }
148
+ ]
149
+ },
150
+ {
151
+ "name": "hashes",
152
+ "namespace": "core",
153
+ "offset": 0,
154
+ "enum": [
155
+ {
156
+ "key": "blake2b",
157
+ "version": 1
158
+ }
159
+ ],
160
+ "strings": true
161
+ },
162
+ {
163
+ "name": "signatures",
164
+ "namespace": "core",
165
+ "offset": 0,
166
+ "enum": [
167
+ {
168
+ "key": "ed25519",
169
+ "version": 1
170
+ }
171
+ ],
172
+ "strings": true
173
+ },
174
+ {
175
+ "name": "tree-node",
176
+ "namespace": "core",
177
+ "compact": true,
178
+ "flagsPosition": -1,
179
+ "fields": [
180
+ {
181
+ "name": "index",
182
+ "required": true,
183
+ "type": "uint",
184
+ "version": 1
185
+ },
186
+ {
187
+ "name": "size",
188
+ "required": true,
189
+ "type": "uint",
190
+ "version": 1
191
+ },
192
+ {
193
+ "name": "hash",
194
+ "required": true,
195
+ "type": "fixed32",
196
+ "version": 1
197
+ }
198
+ ]
199
+ },
200
+ {
201
+ "name": "signer",
202
+ "namespace": "core",
203
+ "compact": true,
204
+ "flagsPosition": -1,
205
+ "fields": [
206
+ {
207
+ "name": "signature",
208
+ "required": true,
209
+ "type": "@core/signatures",
210
+ "version": 1
211
+ },
212
+ {
213
+ "name": "namespace",
214
+ "required": true,
215
+ "type": "fixed32",
216
+ "version": 1
217
+ },
218
+ {
219
+ "name": "publicKey",
220
+ "required": true,
221
+ "type": "fixed32",
222
+ "version": 1
223
+ }
224
+ ]
225
+ },
226
+ {
227
+ "name": "prologue",
228
+ "namespace": "core",
229
+ "compact": true,
230
+ "flagsPosition": -1,
231
+ "fields": [
232
+ {
233
+ "name": "hash",
234
+ "required": true,
235
+ "type": "fixed32",
236
+ "version": 1
237
+ },
238
+ {
239
+ "name": "length",
240
+ "required": true,
241
+ "type": "uint",
242
+ "version": 1
243
+ }
244
+ ]
245
+ },
246
+ {
247
+ "name": "manifest",
248
+ "namespace": "core",
249
+ "compact": false,
250
+ "flagsPosition": 1,
251
+ "fields": [
252
+ {
253
+ "name": "version",
254
+ "required": true,
255
+ "type": "uint",
256
+ "version": 1
257
+ },
258
+ {
259
+ "name": "hash",
260
+ "required": true,
261
+ "type": "@core/hashes",
262
+ "version": 1
263
+ },
264
+ {
265
+ "name": "quorum",
266
+ "required": true,
267
+ "type": "uint",
268
+ "version": 1
269
+ },
270
+ {
271
+ "name": "allowPatch",
272
+ "type": "bool",
273
+ "version": 1
274
+ },
275
+ {
276
+ "name": "signers",
277
+ "required": true,
278
+ "array": true,
279
+ "type": "@core/signer",
280
+ "version": 1
281
+ },
282
+ {
283
+ "name": "prologue",
284
+ "type": "@core/prologue",
285
+ "version": 1
286
+ },
287
+ {
288
+ "name": "linked",
289
+ "array": true,
290
+ "type": "fixed32",
291
+ "version": 1
292
+ },
293
+ {
294
+ "name": "userData",
295
+ "type": "buffer",
296
+ "version": 1
297
+ }
298
+ ]
299
+ },
300
+ {
301
+ "name": "keyPair",
302
+ "namespace": "core",
303
+ "compact": true,
304
+ "flagsPosition": -1,
305
+ "fields": [
306
+ {
307
+ "name": "publicKey",
308
+ "required": true,
309
+ "type": "buffer",
310
+ "version": 1
311
+ },
312
+ {
313
+ "name": "secretKey",
314
+ "required": true,
315
+ "type": "optionalBuffer",
316
+ "version": 1
317
+ }
318
+ ]
319
+ },
320
+ {
321
+ "name": "group",
322
+ "namespace": "core",
323
+ "compact": false,
324
+ "flagsPosition": 0,
325
+ "fields": [
326
+ {
327
+ "name": "key",
328
+ "type": "fixed32",
329
+ "version": 1
330
+ },
331
+ {
332
+ "name": "pointer",
333
+ "type": "uint",
334
+ "version": 1
335
+ }
336
+ ]
337
+ },
338
+ {
339
+ "name": "auth",
340
+ "namespace": "core",
341
+ "compact": false,
342
+ "flagsPosition": 2,
343
+ "fields": [
344
+ {
345
+ "name": "key",
346
+ "required": true,
347
+ "type": "fixed32",
348
+ "version": 1
349
+ },
350
+ {
351
+ "name": "discoveryKey",
352
+ "required": true,
353
+ "type": "fixed32",
354
+ "version": 1
355
+ },
356
+ {
357
+ "name": "manifest",
358
+ "type": "@core/manifest",
359
+ "version": 1
360
+ },
361
+ {
362
+ "name": "keyPair",
363
+ "type": "@core/keyPair",
364
+ "version": 1
365
+ },
366
+ {
367
+ "name": "encryptionKey",
368
+ "type": "buffer",
369
+ "version": 1
370
+ }
371
+ ]
372
+ },
373
+ {
374
+ "name": "head",
375
+ "namespace": "core",
376
+ "compact": false,
377
+ "flagsPosition": 4,
378
+ "fields": [
379
+ {
380
+ "name": "fork",
381
+ "required": true,
382
+ "type": "uint",
383
+ "version": 1
384
+ },
385
+ {
386
+ "name": "length",
387
+ "required": true,
388
+ "type": "uint",
389
+ "version": 1
390
+ },
391
+ {
392
+ "name": "rootHash",
393
+ "required": true,
394
+ "type": "fixed32",
395
+ "version": 1
396
+ },
397
+ {
398
+ "name": "signature",
399
+ "required": true,
400
+ "type": "optionalBuffer",
401
+ "version": 1
402
+ },
403
+ {
404
+ "name": "timestamp",
405
+ "required": false,
406
+ "type": "uint64",
407
+ "version": 2
408
+ }
409
+ ]
410
+ },
411
+ {
412
+ "name": "hints",
413
+ "namespace": "core",
414
+ "compact": false,
415
+ "flagsPosition": 0,
416
+ "fields": [
417
+ {
418
+ "name": "contiguousLength",
419
+ "type": "uint",
420
+ "version": 1
421
+ },
422
+ {
423
+ "name": "remoteContiguousLength",
424
+ "type": "uint",
425
+ "version": 1
426
+ },
427
+ {
428
+ "name": "recovering",
429
+ "type": "uint",
430
+ "version": 1
431
+ }
432
+ ]
433
+ },
434
+ {
435
+ "name": "session",
436
+ "namespace": "core",
437
+ "compact": true,
438
+ "flagsPosition": -1,
439
+ "fields": [
440
+ {
441
+ "name": "name",
442
+ "required": true,
443
+ "type": "string",
444
+ "version": 1
445
+ },
446
+ {
447
+ "name": "dataPointer",
448
+ "required": true,
449
+ "type": "uint",
450
+ "version": 1
451
+ }
452
+ ]
453
+ },
454
+ {
455
+ "name": "sessions",
456
+ "namespace": "core",
457
+ "array": true,
458
+ "type": "@core/session"
459
+ },
460
+ {
461
+ "name": "dependency",
462
+ "namespace": "core",
463
+ "compact": true,
464
+ "flagsPosition": -1,
465
+ "fields": [
466
+ {
467
+ "name": "dataPointer",
468
+ "required": true,
469
+ "type": "uint",
470
+ "version": 1
471
+ },
472
+ {
473
+ "name": "length",
474
+ "required": true,
475
+ "type": "uint",
476
+ "version": 1
477
+ }
478
+ ]
479
+ }
480
+ ]
481
+ }
package/index.js CHANGED
@@ -4,9 +4,10 @@ const ScopeLock = require('scope-lock')
4
4
  const DeviceFile = require('device-file')
5
5
  const path = require('path')
6
6
  const fs = require('fs')
7
+
7
8
  const View = require('./lib/view.js')
8
9
 
9
- const VERSION = 1
10
+ const VERSION = 2
10
11
  const COLUMN_FAMILY = 'corestore'
11
12
 
12
13
  const { store, core } = require('./lib/keys.js')
@@ -22,7 +23,8 @@ const {
22
23
  createUserDataStream,
23
24
  createTreeNodeStream,
24
25
  createMarkStream,
25
- createLocalStream
26
+ createLocalStream,
27
+ createGroupUpdateStream
26
28
  } = require('./lib/streams.js')
27
29
 
28
30
  const EMPTY = new View()
@@ -647,6 +649,10 @@ class CorestoreStorage {
647
649
  await require('./migrations/0').store(this, target)
648
650
  break
649
651
  }
652
+ case 1: {
653
+ // implicit migration on write
654
+ break
655
+ }
650
656
  default: {
651
657
  throw new Error(
652
658
  'Unsupported version: ' + version + ' - you should probably upgrade your dependencies'
@@ -673,6 +679,10 @@ class CorestoreStorage {
673
679
  await require('./migrations/0').core(core, target)
674
680
  break
675
681
  }
682
+ case 1: {
683
+ await require('./migrations/1').core(core, target)
684
+ break
685
+ }
676
686
  default: {
677
687
  throw new Error(
678
688
  'Unsupported version: ' + version + ' - you should probably upgrade your dependencies'
@@ -738,7 +748,7 @@ class CorestoreStorage {
738
748
  try {
739
749
  const head = await this._getHead(view)
740
750
 
741
- dataPointer = head.allocated.datas++
751
+ dataPointer = head.datas++
742
752
 
743
753
  tx.setHead(head)
744
754
  tx.apply()
@@ -801,6 +811,10 @@ class CorestoreStorage {
801
811
  return createDiscoveryKeyStream(this.db, EMPTY, namespace)
802
812
  }
803
813
 
814
+ createGroupUpdateStream(group, { since, reverse } = {}) {
815
+ return createGroupUpdateStream(this.db, EMPTY, group, { gte: since, reverse })
816
+ }
817
+
804
818
  async getAlias(alias) {
805
819
  if (this.version === 0) await this._migrateStore()
806
820
 
@@ -822,6 +836,15 @@ class CorestoreStorage {
822
836
  return head === null ? null : head.seed
823
837
  }
824
838
 
839
+ async getGroup(topic) {
840
+ if (this.version === 0) await this._migrateStore()
841
+
842
+ const rx = new CorestoreRX(this.db, EMPTY)
843
+ const groupPromise = rx.getGroup(topic)
844
+ rx.tryFlush()
845
+ return groupPromise
846
+ }
847
+
825
848
  async setSeed(seed, { overwrite = true } = {}) {
826
849
  if (this.version === 0) await this._migrateStore()
827
850
 
@@ -1079,8 +1102,8 @@ class CorestoreStorage {
1079
1102
  if (head === null) head = initStoreHead()
1080
1103
  if (head.defaultDiscoveryKey === null) head.defaultDiscoveryKey = discoveryKey
1081
1104
 
1082
- const corePointer = ptrs ? ptrs.corePointer : head.allocated.cores++
1083
- const dataPointer = ptrs ? ptrs.dataPointer : head.allocated.datas++
1105
+ const corePointer = ptrs ? ptrs.corePointer : head.cores++
1106
+ const dataPointer = ptrs ? ptrs.dataPointer : head.datas++
1084
1107
 
1085
1108
  core = { version: VERSION, corePointer, dataPointer, alias }
1086
1109
 
@@ -1122,6 +1145,51 @@ class CorestoreStorage {
1122
1145
  }
1123
1146
  }
1124
1147
 
1148
+ // not allowed to throw validation errors as its a shared tx!
1149
+ async _createGroup(view, topic) {
1150
+ const rx = new CorestoreRX(this.db, view)
1151
+ const tx = new CorestoreTX(view)
1152
+
1153
+ const groupPromise = rx.getGroup(topic)
1154
+ const headPromise = rx.getHead()
1155
+
1156
+ rx.tryFlush()
1157
+
1158
+ let group = await groupPromise
1159
+ if (group !== null) {
1160
+ return {
1161
+ key: topic,
1162
+ pointer: group
1163
+ }
1164
+ }
1165
+
1166
+ let head = await headPromise
1167
+ if (head === null) head = initStoreHead()
1168
+
1169
+ group = head.groups++
1170
+
1171
+ tx.putGroup(topic, group)
1172
+ tx.setHead(head)
1173
+ tx.apply()
1174
+
1175
+ return {
1176
+ key: topic,
1177
+ pointer: group
1178
+ }
1179
+ }
1180
+
1181
+ async createGroup(topic) {
1182
+ if (this.version === 0) await this._migrateStore()
1183
+
1184
+ const view = await this._enter()
1185
+
1186
+ try {
1187
+ return await this._createGroup(view, topic)
1188
+ } finally {
1189
+ await this._exit()
1190
+ }
1191
+ }
1192
+
1125
1193
  static isParentStorage(storage, parent) {
1126
1194
  return HypercoreStorage.isParentStorage(storage, parent)
1127
1195
  }
@@ -1132,10 +1200,9 @@ module.exports = CorestoreStorage
1132
1200
  function initStoreHead() {
1133
1201
  return {
1134
1202
  version: 0, // cause we wanna run the migration
1135
- allocated: {
1136
- datas: 0,
1137
- cores: 0
1138
- },
1203
+ datas: 0,
1204
+ cores: 0,
1205
+ groups: 0,
1139
1206
  seed: null,
1140
1207
  defaultDiscoveryKey: null
1141
1208
  }
package/lib/keys.js CHANGED
@@ -7,11 +7,14 @@ const TL_CORE_BY_DKEY = 1
7
7
  const TL_CORE_BY_ALIAS = 2
8
8
  const TL_CORE = 3
9
9
  const TL_DATA = 4
10
+ const TL_GROUP_BY_TOPIC = 5
11
+ const TL_GROUP = 6
10
12
 
11
- const TL_END = TL_DATA + 1
13
+ const TL_END = TL_GROUP + 1
12
14
 
13
15
  const CORE_AUTH = 0
14
16
  const CORE_SESSIONS = 1
17
+ const CORE_GROUP = 2
15
18
 
16
19
  const DATA_HEAD = 0
17
20
  const DATA_DEPENDENCY = 1
@@ -27,6 +30,7 @@ const slab = { buffer: b4a.allocUnsafe(65536), start: 0, end: 0 }
27
30
 
28
31
  const store = {}
29
32
  const core = {}
33
+ const group = {}
30
34
 
31
35
  store.clear = function () {
32
36
  const state = alloc()
@@ -139,6 +143,15 @@ core.auth = function (ptr) {
139
143
  return state.buffer.subarray(start, state.start)
140
144
  }
141
145
 
146
+ core.group = function (ptr) {
147
+ const state = alloc()
148
+ const start = state.start
149
+ UINT.encode(state, TL_CORE)
150
+ UINT.encode(state, ptr)
151
+ UINT.encode(state, CORE_GROUP)
152
+ return state.buffer.subarray(start, state.start)
153
+ }
154
+
142
155
  core.sessions = function (ptr) {
143
156
  const state = alloc()
144
157
  const start = state.start
@@ -300,7 +313,25 @@ core.localKey = function (buffer) {
300
313
  return state.buffer.subarray(state.start, state.end)
301
314
  }
302
315
 
303
- module.exports = { store, core }
316
+ group.topic = function (topic) {
317
+ const state = alloc()
318
+ const start = state.start
319
+ UINT.encode(state, TL_GROUP_BY_TOPIC)
320
+ c.fixed32.encode(state, topic)
321
+ return state.buffer.subarray(start, state.start)
322
+ }
323
+
324
+ group.entry = function (group, timestamp, ptr) {
325
+ const state = alloc()
326
+ const start = state.start
327
+ UINT.encode(state, TL_GROUP)
328
+ UINT.encode(state, group)
329
+ c.uint64be.encode(state, timestamp)
330
+ UINT.encode(state, ptr)
331
+ return state.buffer.subarray(start, state.start)
332
+ }
333
+
334
+ module.exports = { store, core, group }
304
335
 
305
336
  function alloc() {
306
337
  if (slab.buffer.byteLength - slab.start < 4096) {