hypercore 10.0.0-alpha.12 → 10.0.0-alpha.13

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
@@ -66,7 +66,7 @@ module.exports = class Hypercore extends EventEmitter {
66
66
  this.autoClose = !!opts.autoClose
67
67
 
68
68
  this.closing = null
69
- this.opening = opts._opening || this._open(key, storage, opts)
69
+ this.opening = this._openSession(key, storage, opts)
70
70
  this.opening.catch(noop)
71
71
 
72
72
  this._preappend = preappend.bind(this)
@@ -115,28 +115,20 @@ module.exports = class Hypercore extends EventEmitter {
115
115
  }
116
116
 
117
117
  const Clz = opts.class || Hypercore
118
- const keyPair = opts.keyPair && opts.keyPair.secretKey && { ...opts.keyPair }
119
-
120
- // This only works if the hypercore was fully loaded,
121
- // but we only do this to validate the keypair to help catch bugs so yolo
122
- if (this.key && keyPair) keyPair.publicKey = this.key
123
-
124
118
  const s = new Clz(this.storage, this.key, {
125
119
  ...opts,
126
- sign: opts.sign || (keyPair && keyPair.secretKey && Core.createSigner(this.crypto, keyPair)) || this.sign,
127
- valueEncoding: this.valueEncoding,
128
120
  extensions: this.extensions,
129
121
  _opening: this.opening,
130
122
  _sessions: this.sessions
131
123
  })
132
124
 
133
- s._initSession(this)
125
+ s._passCapabilities(this)
134
126
  this.sessions.push(s)
135
127
 
136
128
  return s
137
129
  }
138
130
 
139
- _initSession (o) {
131
+ _passCapabilities (o) {
140
132
  if (!this.sign) this.sign = o.sign
141
133
  this.crypto = o.crypto
142
134
  this.opened = o.opened
@@ -149,6 +141,98 @@ module.exports = class Hypercore extends EventEmitter {
149
141
  this.autoClose = o.autoClose
150
142
  }
151
143
 
144
+ async _openFromExisting (from, opts) {
145
+ await from.opening
146
+
147
+ for (const [name, ext] of this.extensions) {
148
+ from.extensions.register(name, null, ext)
149
+ }
150
+
151
+ this._passCapabilities(from)
152
+ this.extensions = from.extensions
153
+ this.sessions = from.sessions
154
+ this.storage = from.storage
155
+
156
+ this.sessions.push(this)
157
+ }
158
+
159
+ async _openSession (key, storage, opts) {
160
+ const isFirst = !opts._opening
161
+
162
+ if (!isFirst) await opts._opening
163
+ if (opts.preload) opts = { ...opts, ...(await opts.preload()) }
164
+
165
+ const keyPair = (key && opts.keyPair)
166
+ ? { ...opts.keyPair, publicKey: key }
167
+ : key
168
+ ? { publicKey: key, secretKey: null }
169
+ : opts.keyPair
170
+
171
+ // This only works if the hypercore was fully loaded,
172
+ // but we only do this to validate the keypair to help catch bugs so yolo
173
+ if (this.key && keyPair) keyPair.publicKey = this.key
174
+
175
+ if (opts.sign) {
176
+ this.sign = opts.sign
177
+ } else if (keyPair && keyPair.secretKey) {
178
+ this.sign = Core.createSigner(this.crypto, keyPair)
179
+ }
180
+
181
+ if (isFirst) {
182
+ await this._openCapabilities(keyPair, storage, opts)
183
+ // Only the root session should pass capabilities to other sessions.
184
+ for (let i = 0; i < this.sessions.length; i++) {
185
+ const s = this.sessions[i]
186
+ if (s !== this) s._passCapabilities(this)
187
+ }
188
+ }
189
+
190
+ if (!this.sign) this.sign = this.core.defaultSign
191
+ this.writable = !!this.sign
192
+
193
+ if (opts.valueEncoding) {
194
+ this.valueEncoding = c.from(codecs(opts.valueEncoding))
195
+ }
196
+
197
+ // This is a hidden option that's only used by Corestore.
198
+ // It's required so that corestore can load a name from userData before 'ready' is emitted.
199
+ if (opts._preready) await opts._preready(this)
200
+
201
+ this.opened = true
202
+ this.emit('ready')
203
+ }
204
+
205
+ async _openCapabilities (keyPair, storage, opts) {
206
+ if (opts.from) return this._openFromExisting(opts.from, opts)
207
+
208
+ if (!this.storage) this.storage = Hypercore.defaultStorage(opts.storage || storage)
209
+
210
+ this.core = await Core.open(this.storage, {
211
+ keyPair,
212
+ crypto: this.crypto,
213
+ onupdate: this._oncoreupdate.bind(this)
214
+ })
215
+
216
+ if (opts.userData) {
217
+ for (const [key, value] of Object.entries(opts.userData)) {
218
+ await this.core.userData(key, value)
219
+ }
220
+ }
221
+
222
+ this.replicator = new Replicator(this.core, {
223
+ onupdate: this._onpeerupdate.bind(this)
224
+ })
225
+
226
+ this.discoveryKey = this.crypto.discoveryKey(this.core.header.signer.publicKey)
227
+ this.key = this.core.header.signer.publicKey
228
+
229
+ if (!this.encryption && opts.encryptionKey) {
230
+ this.encryption = new BlockEncryption(opts.encryptionKey, this.key)
231
+ }
232
+
233
+ this.extensions.attach(this.replicator)
234
+ }
235
+
152
236
  close () {
153
237
  if (this.closing) return this.closing
154
238
  this.closing = this._close()
@@ -237,71 +321,6 @@ module.exports = class Hypercore extends EventEmitter {
237
321
  return this.opening
238
322
  }
239
323
 
240
- async _open (key, storage, opts) {
241
- if (opts.preload) opts = { ...opts, ...(await opts.preload()) }
242
-
243
- this.valueEncoding = opts.valueEncoding ? c.from(codecs(opts.valueEncoding)) : null
244
-
245
- const keyPair = (key && opts.keyPair)
246
- ? { ...opts.keyPair, publicKey: key }
247
- : key
248
- ? { publicKey: key, secretKey: null }
249
- : opts.keyPair
250
-
251
- if (opts.from) {
252
- const from = opts.from
253
- await from.opening
254
- for (const [name, ext] of this.extensions) from.extensions.register(name, null, ext)
255
- this._initSession(from)
256
- this.extensions = from.extensions
257
- this.sessions = from.sessions
258
- this.storage = from.storage
259
- if (!this.sign) this.sign = opts.sign || ((keyPair && keyPair.secretKey) ? Core.createSigner(this.crypto, keyPair) : null)
260
- this.writable = !!this.sign
261
- this.sessions.push(this)
262
- return
263
- }
264
-
265
- if (!this.storage) this.storage = Hypercore.defaultStorage(opts.storage || storage)
266
-
267
- this.core = await Core.open(this.storage, {
268
- keyPair,
269
- crypto: this.crypto,
270
- onupdate: this._oncoreupdate.bind(this)
271
- })
272
-
273
- if (opts.userData) {
274
- for (const [key, value] of Object.entries(opts.userData)) {
275
- await this.core.userData(key, value)
276
- }
277
- }
278
-
279
- this.replicator = new Replicator(this.core, {
280
- onupdate: this._onpeerupdate.bind(this)
281
- })
282
-
283
- if (!this.sign) this.sign = opts.sign || this.core.defaultSign
284
-
285
- this.discoveryKey = this.crypto.discoveryKey(this.core.header.signer.publicKey)
286
- this.key = this.core.header.signer.publicKey
287
- this.writable = !!this.sign
288
-
289
- if (!this.encryption && opts.encryptionKey) {
290
- this.encryption = new BlockEncryption(opts.encryptionKey, this.key)
291
- }
292
-
293
- this.extensions.attach(this.replicator)
294
- this.opened = true
295
-
296
- if (opts.postload) await opts.postload(this)
297
-
298
- for (let i = 0; i < this.sessions.length; i++) {
299
- const s = this.sessions[i]
300
- if (s !== this) s._initSession(this)
301
- s.emit('ready')
302
- }
303
- }
304
-
305
324
  _oncoreupdate (status, bitfield, value, from) {
306
325
  if (status !== 0) {
307
326
  for (let i = 0; i < this.sessions.length; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.12",
3
+ "version": "10.0.0-alpha.13",
4
4
  "description": "Hypercore 10",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -35,7 +35,7 @@
35
35
  "compact-encoding": "^2.5.0",
36
36
  "crc32-universal": "^1.0.1",
37
37
  "flat-tree": "^1.9.0",
38
- "hypercore-crypto": "^3.0.0",
38
+ "hypercore-crypto": "^3.1.0",
39
39
  "is-options": "^1.0.1",
40
40
  "random-access-file": "^2.1.4",
41
41
  "random-array-iterator": "^1.0.0",
package/test/sessions.js CHANGED
@@ -15,6 +15,7 @@ test('sessions - can create writable sessions from a read-only core', async func
15
15
  t.absent(core.writable)
16
16
 
17
17
  const session = core.session({ keyPair: { secretKey: keyPair.secretKey } })
18
+ await session.ready()
18
19
  t.ok(session.writable)
19
20
 
20
21
  try {
@@ -74,7 +75,8 @@ test('sessions - writable session with invalid keypair throws', async function (
74
75
 
75
76
  try {
76
77
  const core = new Hypercore(ram, keyPair2.publicKey) // Create a new core in read-only mode.
77
- core.session({ keyPair: keyPair1 })
78
+ const session = core.session({ keyPair: keyPair1 })
79
+ await session.ready()
78
80
  t.fail('invalid keypair did not throw')
79
81
  } catch {
80
82
  t.pass('invalid keypair threw')
@@ -171,3 +173,11 @@ test('sessions - close with from option', async function (t) {
171
173
  t.absent(core1.closed)
172
174
  t.alike(await core1.get(0), Buffer.from('hello world'))
173
175
  })
176
+
177
+ test('sessions - custom valueEncoding on session', async function (t) {
178
+ const core1 = new Hypercore(ram)
179
+ const core2 = core1.session({ valueEncoding: 'utf-8' })
180
+
181
+ await core1.append(Buffer.from('hello world'))
182
+ t.is(await core2.get(0), 'hello world')
183
+ })