diff --git a/lib/session-state.js b/lib/session-state.js index 9c0a4154..9c4c11c0 100644 --- a/lib/session-state.js +++ b/lib/session-state.js @@ -541,7 +541,24 @@ module.exports = class SessionState { if (end - start === 1) tx.deleteBlock(start) else tx.deleteBlockRange(start, end) - const dependency = start < this.flushedLength() ? updateDependency(this, start, true) : null + const flushedLength = this.flushedLength() + const dependency = start < flushedLength ? updateDependency(this, start, true) : null + + // Dependency was reset but the end doesn't include all blocks + if (dependency && end < flushedLength - 1) { + const blocksPromises = [] + const rx = this.storage.read() + for (let i = end + 1; i < flushedLength; i++) { + blocksPromises.push(rx.getBlock(i)) + } + rx.tryFlush() + const blocks = await Promise.all(blocksPromises) + let j = 0 + for (let i = end + 1; i < flushedLength; i++) { + tx.putBlock(i, blocks[j]) + j++ + } + } const flushed = await this.flush() diff --git a/test/sessions.js b/test/sessions.js index cf4f0aa1..a061a0c1 100644 --- a/test/sessions.js +++ b/test/sessions.js @@ -175,4 +175,47 @@ test('sessions - checkout breaks prologue', async function (t) { uncaughts.off(noop) }) +test('named session doesnt clear wrong blocks', async (t) => { + const core = await create(t) + + const num = 10 + for (let i = 0; i < num; i++) { + await core.append('block' + i) + } + + t.ok(await core.has(num - 1), 'parent has block') + const named = core.session({ name: 'batch' }) + await named.ready() + + const clearEnd = num - 2 + + t.ok(await named.has(num - 1), 'named starts w/ block') + await t.execution(() => named.clear(1, clearEnd), 'clear runs') + t.absent(await named.has(1), 'named cleared start of range') + t.absent(await named.has(clearEnd), 'named cleared end of range') + t.ok(await named.has(clearEnd + 1), 'named didnt clear beyond end') + t.ok(await named.has(num - 1), 'named ends w/ block') + + t.ok(await core.has(1), 'core has start of cleared range') + t.ok(await core.has(clearEnd), 'core has end of cleared range') + t.ok(await core.has(num - 1), 'core ends w/ block') + + t.comment('clearing to end') + const namedToEnd = core.session({ name: 'batch-to-end' }) + await namedToEnd.ready() + + t.ok(await namedToEnd.has(num - 1), 'starts w/ end block') + await t.execution(() => namedToEnd.clear(1, num - 1), 'clear runs') + + { + const rx = namedToEnd.state.storage.read() + const b = rx.getBlock(num - 1) + rx.tryFlush() + t.absent(await b, 'didnt put blocks beyond end in storage only') + } + + await named.close() + await namedToEnd.close() +}) + function noop() {}