hypercore-storage 1.0.1 → 1.0.3
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/README.md +192 -1
- package/index.js +19 -19
- package/package.json +1 -1
- package/spec/hyperschema/index.js +10 -6
package/README.md
CHANGED
|
@@ -10,7 +10,198 @@ npm install hypercore-storage
|
|
|
10
10
|
|
|
11
11
|
The following API is what Hypercore 11 binds to to do I/O.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```js
|
|
14
|
+
const Storage = require('hypercore-storage')
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
#### `store = new Storage(dbOrPath)`
|
|
18
|
+
|
|
19
|
+
Make a new storage engine.
|
|
20
|
+
|
|
21
|
+
#### `core = await store.create({ key, discoveyKey, manifest?, keyPair?, encryptionKey?, userData? })`
|
|
22
|
+
|
|
23
|
+
Create a new core, returns a storage instance for that core.
|
|
24
|
+
|
|
25
|
+
#### `core = await store.resume(discoveryKey)`
|
|
26
|
+
|
|
27
|
+
Resume a previously make core. If it doesn't exist it returns `null`.
|
|
28
|
+
|
|
29
|
+
#### `atom = store.createAtom()`
|
|
30
|
+
|
|
31
|
+
Primitive for making atomic batches across ops. See below for `core.atomize` on how to use it.
|
|
32
|
+
When you wanna flush your changes to the underlying storage, use `await atom.flush()`.
|
|
33
|
+
|
|
34
|
+
Internally to "listen" for when that happens you can add an sync hook with `atom.onflush(fn)`
|
|
35
|
+
|
|
36
|
+
#### `bool = await store.has(discoveryKey)`
|
|
37
|
+
|
|
38
|
+
Check if a core exists.
|
|
39
|
+
|
|
40
|
+
#### `stream = store.createCoreStream()`
|
|
41
|
+
|
|
42
|
+
List all cores. Stream data looks like this `{ discoveryKey, core }` where core contains the core header.
|
|
43
|
+
|
|
44
|
+
#### `await store.close()`
|
|
45
|
+
|
|
46
|
+
Close the storage instance.
|
|
47
|
+
|
|
48
|
+
#### `rx = core.read()`
|
|
49
|
+
|
|
50
|
+
Make a read batch on a core storage.
|
|
51
|
+
|
|
52
|
+
**NOTE:** a read batch DOES NOT flush until you call `rx.tryFlush()`.
|
|
53
|
+
|
|
54
|
+
#### `await rx.getAuth()`
|
|
55
|
+
|
|
56
|
+
Returns the auth data around a core.
|
|
57
|
+
|
|
58
|
+
#### `await rx.getHead()`
|
|
59
|
+
|
|
60
|
+
Returns the head of the merkle tree.
|
|
61
|
+
|
|
62
|
+
#### `await rx.getSessions()`
|
|
63
|
+
|
|
64
|
+
Returns an array of all named sessions.
|
|
65
|
+
|
|
66
|
+
#### `await rx.getDependency()`
|
|
67
|
+
|
|
68
|
+
Returns the core this has a dependency on.
|
|
69
|
+
|
|
70
|
+
#### `await rx.getHints()`
|
|
71
|
+
|
|
72
|
+
Returns the various storage/replication hints.
|
|
73
|
+
|
|
74
|
+
#### `await rx.getBlock(index)`
|
|
75
|
+
|
|
76
|
+
Returns a block stored.
|
|
77
|
+
|
|
78
|
+
#### `await rx.getTreeNode(index)`
|
|
79
|
+
|
|
80
|
+
Returns a tree node stored.
|
|
81
|
+
|
|
82
|
+
#### `await rx.getBitfieldPage(index)`
|
|
83
|
+
|
|
84
|
+
Return a bitfield page.
|
|
85
|
+
|
|
86
|
+
#### `await rx.getUserData(key)`
|
|
87
|
+
|
|
88
|
+
Return a user stored buffer.
|
|
89
|
+
|
|
90
|
+
#### `rx.tryFlush()`
|
|
91
|
+
|
|
92
|
+
Flushes the read batch, non of the above promises will resolve until you call this.
|
|
93
|
+
|
|
94
|
+
#### `tx = core.write()`
|
|
95
|
+
|
|
96
|
+
Make a write batch on a core storage.
|
|
97
|
+
|
|
98
|
+
**NOTE:** all the apis below are sync as they just buffer mutations until you flush them.
|
|
99
|
+
|
|
100
|
+
#### `tx.setAuth(auth)`
|
|
101
|
+
|
|
102
|
+
Set the auth data around a core.
|
|
103
|
+
|
|
104
|
+
#### `tx.setHead(auth)`
|
|
105
|
+
|
|
106
|
+
Set the head of the merkle tree.
|
|
107
|
+
|
|
108
|
+
#### `tx.setSessions(sessions)`
|
|
109
|
+
|
|
110
|
+
Set an array of all named sessions.
|
|
111
|
+
|
|
112
|
+
#### `tx.setDependency(dep)`
|
|
113
|
+
|
|
114
|
+
Set the core this has a dependency on.
|
|
115
|
+
|
|
116
|
+
#### `tx.setHints(hints)`
|
|
117
|
+
|
|
118
|
+
Set the various storage/replication hints.
|
|
119
|
+
|
|
120
|
+
#### `tx.putBlock(index, buffer)`
|
|
121
|
+
|
|
122
|
+
Put a block at a specific index.
|
|
123
|
+
|
|
124
|
+
#### `tx.deleteBlock(index)`
|
|
125
|
+
|
|
126
|
+
Delete a block at a specific index.
|
|
127
|
+
|
|
128
|
+
#### `tx.deleteBlockRange(start, index)`
|
|
129
|
+
|
|
130
|
+
Delete blocks between two indexes.
|
|
131
|
+
|
|
132
|
+
#### `tx.putTreeNode(node)`
|
|
133
|
+
|
|
134
|
+
Put a tree node (at its described index).
|
|
135
|
+
|
|
136
|
+
#### `tx.deleteTreeNode(index)`
|
|
137
|
+
|
|
138
|
+
Delete a tree node at a specific index.
|
|
139
|
+
|
|
140
|
+
#### `tx.deleteTreeNodeRange(start, index)`
|
|
141
|
+
|
|
142
|
+
Delete blocks between two tree indexes.
|
|
143
|
+
|
|
144
|
+
#### `tx.putBitfieldPage(index, page)`
|
|
145
|
+
|
|
146
|
+
Put a bitfield page at its described index.
|
|
147
|
+
|
|
148
|
+
#### `tx.deleteBitfieldPage(index)`
|
|
149
|
+
|
|
150
|
+
Delete a bitfield page.
|
|
151
|
+
|
|
152
|
+
#### `tx.deleteBitfieldPageRange(start, end)`
|
|
153
|
+
|
|
154
|
+
Delete bitfield pages between two indexes.
|
|
155
|
+
|
|
156
|
+
#### `tx.putUserData(key, value)`
|
|
157
|
+
|
|
158
|
+
Put a user provided buffer at a user provided key.
|
|
159
|
+
|
|
160
|
+
#### `tx.deleteUserData(key)`
|
|
161
|
+
|
|
162
|
+
Delete a user provided key.
|
|
163
|
+
|
|
164
|
+
#### `await tx.flush()`
|
|
165
|
+
|
|
166
|
+
Flushes the write batch.
|
|
167
|
+
|
|
168
|
+
#### `stream = core.createBlockStream(opts)`
|
|
169
|
+
|
|
170
|
+
Create a stream of all blocks.
|
|
171
|
+
|
|
172
|
+
#### `stream = core.createTreeNodeStream(opts)`
|
|
173
|
+
|
|
174
|
+
Create a stream of all tree nodes.
|
|
175
|
+
|
|
176
|
+
#### `stream = core.createBitfieldStream(opts)`
|
|
177
|
+
|
|
178
|
+
Create a stream of all bitfield pages.
|
|
179
|
+
|
|
180
|
+
#### `stream = core.createUserDataStream(opts)`
|
|
181
|
+
|
|
182
|
+
Create a stream of all user data.
|
|
183
|
+
|
|
184
|
+
#### `await core.close()`
|
|
185
|
+
|
|
186
|
+
Close the core storage engine.
|
|
187
|
+
|
|
188
|
+
#### `atom = core.createAtom()`
|
|
189
|
+
|
|
190
|
+
Same as `store.createAtom()` but here again for conveinience.
|
|
191
|
+
|
|
192
|
+
#### `core = core.atomize(atom)`
|
|
193
|
+
|
|
194
|
+
Atomize a core. Allows you to build up cross core atomic batches and operations.
|
|
195
|
+
An atomized core will not flush its changes until you call `atom.flush()`, but you can still read your writes.
|
|
196
|
+
|
|
197
|
+
#### `core = core.createSession(name, head)`
|
|
198
|
+
|
|
199
|
+
Create a named session on top of a core. A named session points back to the previous storage,
|
|
200
|
+
but is otherwise independent and stored on disk, like a branch in git if you will.
|
|
201
|
+
|
|
202
|
+
#### `core.dependencies`
|
|
203
|
+
|
|
204
|
+
Array containing the full list of dependencies for this core (ie tree of named sessions).
|
|
14
205
|
|
|
15
206
|
## License
|
|
16
207
|
|
package/index.js
CHANGED
|
@@ -40,19 +40,19 @@ class Atom {
|
|
|
40
40
|
this.view.reset()
|
|
41
41
|
|
|
42
42
|
const promises = []
|
|
43
|
-
|
|
43
|
+
for (let i = 0; i < this.flushes.length; i++) promises.push(this.flushes[i]())
|
|
44
44
|
|
|
45
45
|
await Promise.all(promises)
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
class HypercoreStorage {
|
|
50
|
-
constructor (store, db, core, view,
|
|
50
|
+
constructor (store, db, core, view, atom) {
|
|
51
51
|
this.store = store
|
|
52
52
|
this.db = db
|
|
53
53
|
this.core = core
|
|
54
54
|
this.view = view
|
|
55
|
-
this.
|
|
55
|
+
this.atom = atom
|
|
56
56
|
|
|
57
57
|
this.view.readStart()
|
|
58
58
|
}
|
|
@@ -95,15 +95,15 @@ class HypercoreStorage {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
snapshot () {
|
|
98
|
-
return new HypercoreStorage(this.store, this.db.snapshot(), this.core, this.view.snapshot(), this.
|
|
98
|
+
return new HypercoreStorage(this.store, this.db.snapshot(), this.core, this.view.snapshot(), this.atom)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
atomize (atom) {
|
|
102
|
-
return new HypercoreStorage(this.store, this.db.session(), this.core, atom.view,
|
|
102
|
+
return new HypercoreStorage(this.store, this.db.session(), this.core, atom.view, atom)
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
return this.store.
|
|
105
|
+
createAtom () {
|
|
106
|
+
return this.store.createAtom()
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
createBlockStream (opts) {
|
|
@@ -149,11 +149,11 @@ class HypercoreStorage {
|
|
|
149
149
|
const dependency = await dependencyPromise
|
|
150
150
|
if (dependency) core.dependencies = this._addDependency(dependency)
|
|
151
151
|
|
|
152
|
-
return new HypercoreStorage(this.store, this.db.session(), core, this.
|
|
152
|
+
return new HypercoreStorage(this.store, this.db.session(), core, this.atom ? this.view : new View(), this.atom)
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
async createSession (name, head
|
|
156
|
-
const rx = this.read(
|
|
155
|
+
async createSession (name, head) {
|
|
156
|
+
const rx = this.read()
|
|
157
157
|
|
|
158
158
|
const existingSessionsPromise = rx.getSessions()
|
|
159
159
|
const existingHeadPromise = rx.getHead()
|
|
@@ -174,7 +174,7 @@ class HypercoreStorage {
|
|
|
174
174
|
session.dataPointer = await this.store._allocData()
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
const tx = this.write(
|
|
177
|
+
const tx = this.write()
|
|
178
178
|
|
|
179
179
|
tx.setSessions(sessions)
|
|
180
180
|
|
|
@@ -193,7 +193,7 @@ class HypercoreStorage {
|
|
|
193
193
|
|
|
194
194
|
await tx.flush()
|
|
195
195
|
|
|
196
|
-
return new HypercoreStorage(this.store, this.db.session(), core,
|
|
196
|
+
return new HypercoreStorage(this.store, this.db.session(), core, this.atom ? this.view : new View(), this.atom)
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
async createAtomicSession (atom, head) {
|
|
@@ -233,12 +233,12 @@ class HypercoreStorage {
|
|
|
233
233
|
return deps
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
read (
|
|
237
|
-
return new CoreRX(this.core, this.db,
|
|
236
|
+
read () {
|
|
237
|
+
return new CoreRX(this.core, this.db, this.view)
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
write (
|
|
241
|
-
return new CoreTX(this.core, this.db,
|
|
240
|
+
write () {
|
|
241
|
+
return new CoreTX(this.core, this.db, this.atom ? this.view : null, [])
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
close () {
|
|
@@ -429,7 +429,7 @@ class CorestoreStorage {
|
|
|
429
429
|
return head === null ? initStoreHead() : head
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
|
|
432
|
+
createAtom () {
|
|
433
433
|
return new Atom(this.db)
|
|
434
434
|
}
|
|
435
435
|
|
|
@@ -585,7 +585,7 @@ class CorestoreStorage {
|
|
|
585
585
|
dataPointer = dependency.dataPointer
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
-
const result = new HypercoreStorage(this, this.db.session(), core, EMPTY,
|
|
588
|
+
const result = new HypercoreStorage(this, this.db.session(), core, EMPTY, null)
|
|
589
589
|
|
|
590
590
|
if (result.core.version === 0) await this._migrateCore(result, discoveryKey, create)
|
|
591
591
|
return result
|
|
@@ -635,7 +635,7 @@ class CorestoreStorage {
|
|
|
635
635
|
|
|
636
636
|
tx.apply()
|
|
637
637
|
|
|
638
|
-
return new HypercoreStorage(this, this.db.session(), ptr, EMPTY,
|
|
638
|
+
return new HypercoreStorage(this, this.db.session(), ptr, EMPTY, null)
|
|
639
639
|
}
|
|
640
640
|
|
|
641
641
|
async create (data) {
|
package/package.json
CHANGED
|
@@ -401,8 +401,8 @@ const encoding13 = {
|
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
// @core/
|
|
405
|
-
const encoding14 =
|
|
404
|
+
// @core/session
|
|
405
|
+
const encoding14 = {
|
|
406
406
|
preencode (state, m) {
|
|
407
407
|
c.string.preencode(state, m.name)
|
|
408
408
|
c.uint.preencode(state, m.dataPointer)
|
|
@@ -420,10 +420,13 @@ const encoding14 = c.array({
|
|
|
420
420
|
dataPointer: r1
|
|
421
421
|
}
|
|
422
422
|
}
|
|
423
|
-
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// @core/sessions
|
|
426
|
+
const encoding15 = c.array(encoding14)
|
|
424
427
|
|
|
425
428
|
// @core/dependency
|
|
426
|
-
const
|
|
429
|
+
const encoding16 = {
|
|
427
430
|
preencode (state, m) {
|
|
428
431
|
c.uint.preencode(state, m.dataPointer)
|
|
429
432
|
c.uint.preencode(state, m.length)
|
|
@@ -481,8 +484,9 @@ function getEncoding (name) {
|
|
|
481
484
|
case '@core/auth': return encoding11
|
|
482
485
|
case '@core/head': return encoding12
|
|
483
486
|
case '@core/hints': return encoding13
|
|
484
|
-
case '@core/
|
|
485
|
-
case '@core/
|
|
487
|
+
case '@core/session': return encoding14
|
|
488
|
+
case '@core/sessions': return encoding15
|
|
489
|
+
case '@core/dependency': return encoding16
|
|
486
490
|
default: throw new Error('Encoder not found ' + name)
|
|
487
491
|
}
|
|
488
492
|
}
|