hypercore 11.0.20 → 11.0.22
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 +12 -14
- package/lib/session-state.js +89 -37
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -247,19 +247,6 @@ class Hypercore extends EventEmitter {
|
|
|
247
247
|
this.core.replicator.updateActivity(this._active ? 1 : -1)
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
_setupSession (parent) {
|
|
251
|
-
if (!this.keyPair) this.keyPair = parent.keyPair
|
|
252
|
-
|
|
253
|
-
const s = parent.state
|
|
254
|
-
|
|
255
|
-
if (s) {
|
|
256
|
-
const shouldSnapshot = this.snapshotted && !s.isSnapshot()
|
|
257
|
-
this.state = shouldSnapshot ? s.snapshot() : s.ref()
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (this.snapshotted && this.core && !this._snapshot) this._updateSnapshot()
|
|
261
|
-
}
|
|
262
|
-
|
|
263
250
|
async _open (storage, key, opts) {
|
|
264
251
|
const preload = opts.preload || (opts.parent && opts.parent.preload)
|
|
265
252
|
|
|
@@ -339,7 +326,18 @@ class Hypercore extends EventEmitter {
|
|
|
339
326
|
|
|
340
327
|
if (parent) {
|
|
341
328
|
if (parent._stateIndex === -1) await parent.ready()
|
|
342
|
-
this.
|
|
329
|
+
if (!this.keyPair) this.keyPair = parent.keyPair
|
|
330
|
+
|
|
331
|
+
const ps = parent.state
|
|
332
|
+
|
|
333
|
+
if (ps) {
|
|
334
|
+
const shouldSnapshot = this.snapshotted && !ps.isSnapshot()
|
|
335
|
+
this.state = shouldSnapshot ? await ps.snapshot() : ps.ref()
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (this.snapshotted && this.core && !this._snapshot) {
|
|
339
|
+
this._updateSnapshot()
|
|
340
|
+
}
|
|
343
341
|
}
|
|
344
342
|
|
|
345
343
|
if (opts.exclusive && opts.writable !== false) {
|
package/lib/session-state.js
CHANGED
|
@@ -24,6 +24,7 @@ module.exports = class SessionState {
|
|
|
24
24
|
this.lingers = null
|
|
25
25
|
|
|
26
26
|
this.parent = parent
|
|
27
|
+
this.atomized = null
|
|
27
28
|
this.mutex = new Mutex()
|
|
28
29
|
|
|
29
30
|
this.blocks = blocks
|
|
@@ -122,6 +123,33 @@ module.exports = class SessionState {
|
|
|
122
123
|
return MerkleTree.size(this.roots)
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
async getFlushedTreeInfo (storage) {
|
|
127
|
+
if (!this.atomized || !this.atomized.flushing) return this.treeInfo()
|
|
128
|
+
await this.atomized.flushed()
|
|
129
|
+
|
|
130
|
+
let rx = storage.read()
|
|
131
|
+
const headPromise = rx.getHead()
|
|
132
|
+
const authPromise = rx.getAuth()
|
|
133
|
+
|
|
134
|
+
rx.tryFlush()
|
|
135
|
+
const [head, auth] = await Promise.all([headPromise, authPromise])
|
|
136
|
+
|
|
137
|
+
rx = storage.read()
|
|
138
|
+
const rootPromises = []
|
|
139
|
+
for (const r of flat.fullRoots(head.length * 2)) {
|
|
140
|
+
rootPromises.push(rx.getTreeNode(r))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
rx.tryFlush()
|
|
144
|
+
return {
|
|
145
|
+
fork: head.fork,
|
|
146
|
+
roots: await Promise.all(rootPromises),
|
|
147
|
+
length: head.length,
|
|
148
|
+
prologue: auth.manifest && auth.manifest.prologue,
|
|
149
|
+
signature: head.signature
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
125
153
|
treeInfo () {
|
|
126
154
|
return {
|
|
127
155
|
fork: this.fork,
|
|
@@ -137,6 +165,7 @@ module.exports = class SessionState {
|
|
|
137
165
|
|
|
138
166
|
this.active = 0
|
|
139
167
|
this.mutex.destroy(new Error('Closed')).catch(noop)
|
|
168
|
+
if (this.parent && this.parent.atomized) this.parent.atomized = null
|
|
140
169
|
|
|
141
170
|
const closing = this.storage.close()
|
|
142
171
|
|
|
@@ -153,14 +182,16 @@ module.exports = class SessionState {
|
|
|
153
182
|
return closing
|
|
154
183
|
}
|
|
155
184
|
|
|
156
|
-
snapshot () {
|
|
185
|
+
async snapshot () {
|
|
186
|
+
const storage = this.storage.snapshot()
|
|
187
|
+
|
|
157
188
|
const s = new SessionState(
|
|
158
189
|
this.core,
|
|
159
190
|
null,
|
|
160
|
-
|
|
191
|
+
storage,
|
|
161
192
|
this.blocks,
|
|
162
|
-
this.tree.clone(),
|
|
163
|
-
this.
|
|
193
|
+
this.tree.clone(storage),
|
|
194
|
+
await this.getFlushedTreeInfo(storage),
|
|
164
195
|
this.name
|
|
165
196
|
)
|
|
166
197
|
|
|
@@ -214,46 +245,62 @@ module.exports = class SessionState {
|
|
|
214
245
|
}
|
|
215
246
|
}
|
|
216
247
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
248
|
+
_precommit () {
|
|
249
|
+
this.commiting = true
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async _commit () {
|
|
253
|
+
await this.mutex.lock()
|
|
220
254
|
|
|
221
|
-
|
|
255
|
+
try {
|
|
256
|
+
const bitfield = this._pendingBitfield
|
|
257
|
+
this._pendingBitfield = null
|
|
258
|
+
await this.parent._oncommit(this, bitfield)
|
|
259
|
+
} finally {
|
|
260
|
+
this.commiting = false
|
|
261
|
+
this.mutex.unlock()
|
|
262
|
+
}
|
|
222
263
|
}
|
|
223
264
|
|
|
224
265
|
async _oncommit (src, bitfield) {
|
|
225
|
-
|
|
266
|
+
await this.mutex.lock()
|
|
226
267
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this.roots = src.roots.slice()
|
|
230
|
-
this.signature = src.signature
|
|
268
|
+
try {
|
|
269
|
+
const currLength = this.length
|
|
231
270
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
signature: this.signature
|
|
237
|
-
}
|
|
271
|
+
this.fork = src.fork
|
|
272
|
+
this.length = src.length
|
|
273
|
+
this.roots = src.roots.slice()
|
|
274
|
+
this.signature = src.signature
|
|
238
275
|
|
|
239
|
-
|
|
240
|
-
|
|
276
|
+
const tree = {
|
|
277
|
+
fork: this.fork,
|
|
278
|
+
length: this.length,
|
|
279
|
+
rootHash: this.hash(),
|
|
280
|
+
signature: this.signature
|
|
281
|
+
}
|
|
241
282
|
|
|
242
|
-
|
|
283
|
+
const rx = src.storage.read()
|
|
284
|
+
const dependencyPromise = rx.getDependency()
|
|
243
285
|
|
|
244
|
-
|
|
245
|
-
if (dependency && dependency.length > this.flushedLength()) {
|
|
246
|
-
this.storage.updateDependencyLength(dependency.length, false, true)
|
|
247
|
-
}
|
|
286
|
+
rx.tryFlush()
|
|
248
287
|
|
|
249
|
-
|
|
288
|
+
const dependency = await dependencyPromise
|
|
289
|
+
if (dependency && dependency.length > this.flushedLength()) {
|
|
290
|
+
this.storage.updateDependencyLength(dependency.length, false, true)
|
|
291
|
+
}
|
|
250
292
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (
|
|
254
|
-
|
|
293
|
+
const truncated = bitfield ? bitfield.truncated : -1
|
|
294
|
+
|
|
295
|
+
if (truncated !== -1 && truncated < currLength) {
|
|
296
|
+
this.ontruncate(tree, truncated, currLength, true)
|
|
297
|
+
if (!bitfield || bitfield.length === 0) return
|
|
298
|
+
}
|
|
255
299
|
|
|
256
|
-
|
|
300
|
+
this.onappend(tree, bitfield, true)
|
|
301
|
+
} finally {
|
|
302
|
+
this.mutex.unlock()
|
|
303
|
+
}
|
|
257
304
|
}
|
|
258
305
|
|
|
259
306
|
flushed () {
|
|
@@ -587,7 +634,6 @@ module.exports = class SessionState {
|
|
|
587
634
|
|
|
588
635
|
try {
|
|
589
636
|
if (length < this.length) throw INVALID_OPERATION('Can not catchup back in time')
|
|
590
|
-
if (length === this.length) return
|
|
591
637
|
|
|
592
638
|
const origLength = this.length
|
|
593
639
|
|
|
@@ -641,14 +687,12 @@ module.exports = class SessionState {
|
|
|
641
687
|
this.storage.updateDependencyLength(sharedLength, true)
|
|
642
688
|
this.storage.updateDependencyLength(length, false)
|
|
643
689
|
|
|
644
|
-
const bitfield = { start: sharedLength, length: tree.length - sharedLength, drop: false }
|
|
645
|
-
|
|
646
690
|
this.fork = tree.fork
|
|
647
691
|
this.roots = roots
|
|
648
692
|
this.length = tree.length
|
|
649
693
|
|
|
650
694
|
if (truncating) this.ontruncate(tree, sharedLength, origLength, flushed)
|
|
651
|
-
if (sharedLength < length) this.onappend(tree,
|
|
695
|
+
if (sharedLength < length) this.onappend(tree, null, flushed)
|
|
652
696
|
} finally {
|
|
653
697
|
this.mutex.unlock()
|
|
654
698
|
}
|
|
@@ -803,6 +847,7 @@ module.exports = class SessionState {
|
|
|
803
847
|
srcLocked = true
|
|
804
848
|
|
|
805
849
|
if (!(await this.core._validateCommit(state, treeLength))) return null
|
|
850
|
+
if (this.length > length) return null
|
|
806
851
|
|
|
807
852
|
if (this.length < length && !signature) {
|
|
808
853
|
if (!keyPair) keyPair = this.core.header.keyPair
|
|
@@ -968,6 +1013,10 @@ module.exports = class SessionState {
|
|
|
968
1013
|
}
|
|
969
1014
|
}
|
|
970
1015
|
|
|
1016
|
+
if (this.atomized && atom) {
|
|
1017
|
+
throw new Error('Session already atomized')
|
|
1018
|
+
}
|
|
1019
|
+
|
|
971
1020
|
const tree = new MerkleTree(storage)
|
|
972
1021
|
|
|
973
1022
|
const head = {
|
|
@@ -988,7 +1037,10 @@ module.exports = class SessionState {
|
|
|
988
1037
|
atom ? this.name : name
|
|
989
1038
|
)
|
|
990
1039
|
|
|
991
|
-
if (atom)
|
|
1040
|
+
if (atom) {
|
|
1041
|
+
this.atomized = atom
|
|
1042
|
+
atom.onflush(state._commit.bind(state))
|
|
1043
|
+
}
|
|
992
1044
|
|
|
993
1045
|
return state
|
|
994
1046
|
}
|