hypercore-storage 1.4.4 → 1.5.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.
package/index.js CHANGED
@@ -19,7 +19,8 @@ const {
19
19
  createBlockStream,
20
20
  createBitfieldStream,
21
21
  createUserDataStream,
22
- createTreeNodeStream
22
+ createTreeNodeStream,
23
+ createLocalStream
23
24
  } = require('./lib/streams.js')
24
25
 
25
26
  const EMPTY = new View()
@@ -172,6 +173,10 @@ class HypercoreStorage {
172
173
  return createUserDataStream(this.core, this.db, this.view, opts)
173
174
  }
174
175
 
176
+ createLocalStream (opts) {
177
+ return createLocalStream(this.core, this.db, this.view, opts)
178
+ }
179
+
175
180
  async resumeSession (name) {
176
181
  const rx = this.read()
177
182
  const existingSessionsPromise = rx.getSessions()
package/lib/keys.js CHANGED
@@ -20,6 +20,7 @@ const DATA_BLOCK = 3
20
20
  const DATA_TREE = 4
21
21
  const DATA_BITFIELD = 5
22
22
  const DATA_USER_DATA = 6
23
+ const DATA_LOCAL = 7
23
24
 
24
25
  const slab = { buffer: b4a.allocUnsafe(65536), start: 0, end: 0 }
25
26
 
@@ -207,6 +208,31 @@ core.userDataEnd = function (ptr) {
207
208
  return state.buffer.subarray(start, state.start)
208
209
  }
209
210
 
211
+ core.local = function (ptr, key) {
212
+ if (key.byteLength > 2048) {
213
+ throw new Error('local keys has an upper limit of 2048 bytes atm')
214
+ }
215
+
216
+ const state = alloc()
217
+ const start = state.start
218
+ UINT.encode(state, TL_DATA)
219
+ UINT.encode(state, ptr)
220
+ UINT.encode(state, DATA_LOCAL)
221
+
222
+ state.buffer.set(key, state.start)
223
+ state.start += key.byteLength
224
+ return state.buffer.subarray(start, state.start)
225
+ }
226
+
227
+ core.localEnd = function (ptr) {
228
+ const state = alloc()
229
+ const start = state.start
230
+ UINT.encode(state, TL_DATA)
231
+ UINT.encode(state, ptr)
232
+ UINT.encode(state, DATA_LOCAL + 1)
233
+ return state.buffer.subarray(start, state.start)
234
+ }
235
+
210
236
  core.blockIndex = function (buffer) {
211
237
  const state = { buffer, start: 0, end: buffer.byteLength }
212
238
  UINT.decode(state) // ns
@@ -231,6 +257,14 @@ core.userDataKey = function (buffer) {
231
257
  return STRING.decode(state)
232
258
  }
233
259
 
260
+ core.localKey = function (buffer) {
261
+ const state = { buffer, start: 0, end: buffer.byteLength }
262
+ UINT.decode(state) // ns
263
+ UINT.decode(state) // ptr
264
+ UINT.decode(state) // type
265
+ return state.buffer.subarray(state.start, state.end)
266
+ }
267
+
234
268
  module.exports = { store, core }
235
269
 
236
270
  function alloc () {
package/lib/streams.js CHANGED
@@ -1,9 +1,11 @@
1
+ const b4a = require('b4a')
1
2
  const BlockDependencyStream = require('./block-dependency-stream.js')
2
3
  const { core, store } = require('./keys.js')
3
4
  const schema = require('../spec/hyperschema')
4
5
 
5
6
  const CORESTORE_CORE = schema.getEncoding('@corestore/core')
6
7
  const CORE_TREE_NODE = schema.getEncoding('@core/tree-node')
8
+ const EMPTY = b4a.alloc(0)
7
9
 
8
10
  module.exports = {
9
11
  createBlockStream,
@@ -11,7 +13,8 @@ module.exports = {
11
13
  createUserDataStream,
12
14
  createCoreStream,
13
15
  createAliasStream,
14
- createTreeNodeStream
16
+ createTreeNodeStream,
17
+ createLocalStream
15
18
  }
16
19
 
17
20
  function createCoreStream (db, view) {
@@ -81,12 +84,28 @@ function createUserDataStream (ptr, db, view, { gt = null, gte = '', lte = null,
81
84
  return ite
82
85
  }
83
86
 
87
+ function createLocalStream (ptr, db, view, { gt = null, gte = EMPTY, lte = null, lt = null, reverse = false } = {}) {
88
+ if (gt !== null || lte !== null) throw new Error('gt and lte not yet supported for local streams')
89
+
90
+ const s = core.local(ptr.dataPointer, gte)
91
+ const e = lt === null ? core.localEnd(ptr.dataPointer) : core.local(ptr.dataPointer, lt)
92
+ const ite = view.iterator(db, s, e, false)
93
+
94
+ ite._readableState.map = mapLocal
95
+ return ite
96
+ }
97
+
84
98
  function mapBitfield (data) {
85
99
  const [index, type] = core.bitfieldIndexAndType(data.key)
86
100
  if (type !== 0) return null // ignore for now
87
101
  return { index, page: data.value }
88
102
  }
89
103
 
104
+ function mapLocal (data) {
105
+ const key = core.localKey(data.key)
106
+ return { key, value: data.value }
107
+ }
108
+
90
109
  function mapUserData (data) {
91
110
  const key = core.userDataKey(data.key)
92
111
  return { key, value: data.value }
package/lib/tx.js CHANGED
@@ -100,6 +100,22 @@ class CoreTX {
100
100
  this.changes.push([core.userData(this.core.dataPointer, key), null, null])
101
101
  }
102
102
 
103
+ putLocal (key, value) {
104
+ this.changes.push([core.local(this.core.dataPointer, key), value, null])
105
+ }
106
+
107
+ deleteLocal (key) {
108
+ this.changes.push([core.local(this.core.dataPointer, key), null, null])
109
+ }
110
+
111
+ deleteLocalRange (start, end) {
112
+ this.changes.push([
113
+ core.local(this.core.dataPointer, start),
114
+ null,
115
+ end === null ? core.localEnd(this.core.dataPointer) : core.local(this.core.dataPointer, end)
116
+ ])
117
+ }
118
+
103
119
  flush () {
104
120
  const changes = this.changes
105
121
  if (changes === null) return Promise.resolve(!this.view)
@@ -168,6 +184,10 @@ class CoreRX {
168
184
  return this.view.get(this.read, core.userData(this.core.dataPointer, key))
169
185
  }
170
186
 
187
+ getLocal (key) {
188
+ return this.view.get(this.read, core.local(this.core.dataPointer, key))
189
+ }
190
+
171
191
  tryFlush () {
172
192
  this.read.tryFlush()
173
193
  this._free()
package/lib/view.js CHANGED
@@ -51,15 +51,16 @@ class OverlayStream extends Readable {
51
51
 
52
52
  _onreadable () {
53
53
  let data = this._stream.read()
54
-
55
54
  if (data === null) return false
56
55
 
56
+ let drained = false
57
+
57
58
  do {
58
- this._push(data)
59
+ if (this._push(data) === true) drained = true
59
60
  data = this._stream.read()
60
61
  } while (data !== null)
61
62
 
62
- return true
63
+ return drained
63
64
  }
64
65
 
65
66
  _read (cb) {
@@ -85,12 +86,14 @@ class OverlayStream extends Readable {
85
86
 
86
87
  // we didnt move past and are in, drop
87
88
  if (b4a.compare(c[0], key) <= 0 && b4a.compare(key, c[2]) < 0) {
88
- return true
89
+ return false
89
90
  }
90
91
 
91
92
  break
92
93
  }
93
94
 
95
+ let updated = false
96
+
94
97
  while (this.change < this.changes.length) {
95
98
  const c = this.changes[this.change]
96
99
  const key = c[0]
@@ -100,20 +103,26 @@ class OverlayStream extends Readable {
100
103
  // same value, if not deleted, return new one
101
104
  if (cmp === 0) {
102
105
  this.change++
103
- return value === null || this._inRange(key) === false ? true : this.push({ key, value })
106
+ if (value === null || this._inRange(key) === false) return updated
107
+ this.push({ key, value })
108
+ return true
104
109
  }
105
110
 
106
111
  // we moved past the change, push it
107
112
  if (this.reverse ? cmp > 0 : cmp < 0) {
108
113
  this.change++
109
- if (value !== null && this._inRange(key) === true) this.push({ key, value })
114
+ if (value === null || this._inRange(key) === false) continue
115
+ this.push({ key, value })
116
+ updated = true
110
117
  continue
111
118
  }
112
119
 
113
- return this.push(entry)
120
+ this.push(entry)
121
+ return true
114
122
  }
115
123
 
116
- return this.push(entry)
124
+ this.push(entry)
125
+ return true
117
126
  }
118
127
 
119
128
  _inRange (key) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore-storage",
3
- "version": "1.4.4",
3
+ "version": "1.5.1",
4
4
  "main": "index.js",
5
5
  "files": [
6
6
  "index.js",