hypercore 11.0.19 → 11.0.21
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 +102 -35
- 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
|
|
@@ -40,7 +41,7 @@ module.exports = class SessionState {
|
|
|
40
41
|
|
|
41
42
|
if (treeInfo.roots.length) this.setRoots(treeInfo.roots)
|
|
42
43
|
|
|
43
|
-
this.snapshotCompatLength = this.isSnapshot() ? this.length : -1
|
|
44
|
+
this.snapshotCompatLength = this.isSnapshot() ? Math.min(this.length, this.core.state.length) : -1
|
|
44
45
|
|
|
45
46
|
this.active = 0
|
|
46
47
|
|
|
@@ -91,7 +92,8 @@ module.exports = class SessionState {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
signedLength () {
|
|
94
|
-
|
|
95
|
+
const l = Math.min(this.flushedLength(), this.core.state.length)
|
|
96
|
+
return this.isSnapshot() && l > this.snapshotCompatLength ? this.snapshotCompatLength : l
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
unref () {
|
|
@@ -121,6 +123,33 @@ module.exports = class SessionState {
|
|
|
121
123
|
return MerkleTree.size(this.roots)
|
|
122
124
|
}
|
|
123
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
|
+
|
|
124
153
|
treeInfo () {
|
|
125
154
|
return {
|
|
126
155
|
fork: this.fork,
|
|
@@ -136,6 +165,7 @@ module.exports = class SessionState {
|
|
|
136
165
|
|
|
137
166
|
this.active = 0
|
|
138
167
|
this.mutex.destroy(new Error('Closed')).catch(noop)
|
|
168
|
+
if (this.parent && this.parent.atomized) this.parent.atomized = null
|
|
139
169
|
|
|
140
170
|
const closing = this.storage.close()
|
|
141
171
|
|
|
@@ -152,14 +182,16 @@ module.exports = class SessionState {
|
|
|
152
182
|
return closing
|
|
153
183
|
}
|
|
154
184
|
|
|
155
|
-
snapshot () {
|
|
185
|
+
async snapshot () {
|
|
186
|
+
const storage = this.storage.snapshot()
|
|
187
|
+
|
|
156
188
|
const s = new SessionState(
|
|
157
189
|
this.core,
|
|
158
190
|
null,
|
|
159
|
-
|
|
191
|
+
storage,
|
|
160
192
|
this.blocks,
|
|
161
|
-
this.tree.clone(),
|
|
162
|
-
this.
|
|
193
|
+
this.tree.clone(storage),
|
|
194
|
+
await this.getFlushedTreeInfo(storage),
|
|
163
195
|
this.name
|
|
164
196
|
)
|
|
165
197
|
|
|
@@ -213,46 +245,62 @@ module.exports = class SessionState {
|
|
|
213
245
|
}
|
|
214
246
|
}
|
|
215
247
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
248
|
+
_precommit () {
|
|
249
|
+
this.commiting = true
|
|
250
|
+
}
|
|
219
251
|
|
|
220
|
-
|
|
252
|
+
async _commit () {
|
|
253
|
+
await this.mutex.lock()
|
|
254
|
+
|
|
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
|
+
}
|
|
221
263
|
}
|
|
222
264
|
|
|
223
265
|
async _oncommit (src, bitfield) {
|
|
224
|
-
|
|
266
|
+
await this.mutex.lock()
|
|
225
267
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
this.roots = src.roots.slice()
|
|
229
|
-
this.signature = src.signature
|
|
268
|
+
try {
|
|
269
|
+
const currLength = this.length
|
|
230
270
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
signature: this.signature
|
|
236
|
-
}
|
|
271
|
+
this.fork = src.fork
|
|
272
|
+
this.length = src.length
|
|
273
|
+
this.roots = src.roots.slice()
|
|
274
|
+
this.signature = src.signature
|
|
237
275
|
|
|
238
|
-
|
|
239
|
-
|
|
276
|
+
const tree = {
|
|
277
|
+
fork: this.fork,
|
|
278
|
+
length: this.length,
|
|
279
|
+
rootHash: this.hash(),
|
|
280
|
+
signature: this.signature
|
|
281
|
+
}
|
|
240
282
|
|
|
241
|
-
|
|
283
|
+
const rx = src.storage.read()
|
|
284
|
+
const dependencyPromise = rx.getDependency()
|
|
242
285
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
286
|
+
rx.tryFlush()
|
|
287
|
+
|
|
288
|
+
const dependency = await dependencyPromise
|
|
289
|
+
if (dependency && dependency.length > this.flushedLength()) {
|
|
290
|
+
this.storage.updateDependencyLength(dependency.length, false, true)
|
|
291
|
+
}
|
|
247
292
|
|
|
248
|
-
|
|
293
|
+
const truncated = bitfield ? bitfield.truncated : -1
|
|
249
294
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
295
|
+
if (truncated !== -1 && truncated < currLength) {
|
|
296
|
+
this.ontruncate(tree, truncated, currLength, true)
|
|
297
|
+
if (!bitfield || bitfield.length === 0) return
|
|
298
|
+
}
|
|
254
299
|
|
|
255
|
-
|
|
300
|
+
this.onappend(tree, bitfield, true)
|
|
301
|
+
} finally {
|
|
302
|
+
this.mutex.unlock()
|
|
303
|
+
}
|
|
256
304
|
}
|
|
257
305
|
|
|
258
306
|
flushed () {
|
|
@@ -350,6 +398,12 @@ module.exports = class SessionState {
|
|
|
350
398
|
|
|
351
399
|
const { dependency, tree, roots } = await this._truncate(tx, batch)
|
|
352
400
|
|
|
401
|
+
for (const sessionState of this.core.sessionStates) {
|
|
402
|
+
if (sessionState.isSnapshot() && sessionState.name === this.name && length < sessionState.snapshotCompatLength) {
|
|
403
|
+
sessionState.snapshotCompatLength = length
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
353
407
|
const flushed = await this.flush()
|
|
354
408
|
|
|
355
409
|
this.fork = tree.fork
|
|
@@ -524,6 +578,12 @@ module.exports = class SessionState {
|
|
|
524
578
|
if (!flushed) this._updateBitfield(bitfield)
|
|
525
579
|
else if (this.isDefault()) this.core.ontruncate(tree, bitfield)
|
|
526
580
|
|
|
581
|
+
for (const sessionState of this.core.sessionStates) {
|
|
582
|
+
if (sessionState.isSnapshot() && sessionState.name === this.name && to < sessionState.snapshotCompatLength) {
|
|
583
|
+
sessionState.snapshotCompatLength = to
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
527
587
|
for (let i = this.sessions.length - 1; i >= 0; i--) {
|
|
528
588
|
this.sessions[i].emit('truncate', to, tree.fork)
|
|
529
589
|
}
|
|
@@ -955,6 +1015,10 @@ module.exports = class SessionState {
|
|
|
955
1015
|
}
|
|
956
1016
|
}
|
|
957
1017
|
|
|
1018
|
+
if (this.atomized && atom) {
|
|
1019
|
+
throw new Error('Session already atomized')
|
|
1020
|
+
}
|
|
1021
|
+
|
|
958
1022
|
const tree = new MerkleTree(storage)
|
|
959
1023
|
|
|
960
1024
|
const head = {
|
|
@@ -975,7 +1039,10 @@ module.exports = class SessionState {
|
|
|
975
1039
|
atom ? this.name : name
|
|
976
1040
|
)
|
|
977
1041
|
|
|
978
|
-
if (atom)
|
|
1042
|
+
if (atom) {
|
|
1043
|
+
this.atomized = atom
|
|
1044
|
+
atom.onflush(state._commit.bind(state))
|
|
1045
|
+
}
|
|
979
1046
|
|
|
980
1047
|
return state
|
|
981
1048
|
}
|