@mblaney/holster 2.0.1 → 2.1.0

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.
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import SafeBuffer from "./buffer.ts"
7
- import type { JWK } from "./schemas.ts"
7
+ import type {JWK} from "./schemas.ts"
8
8
 
9
9
  const isNode = typeof process !== "undefined" && process.versions?.node != null
10
10
 
@@ -64,23 +64,20 @@ export const jwk = (pub: string, priv?: string): JWK => {
64
64
  */
65
65
  export const sha256 = async (data: unknown): Promise<SeaArray> => {
66
66
  const hash = await subtle.digest(
67
- { name: "SHA-256" },
68
- new TextEncoder().encode(stringify(data))
67
+ {name: "SHA-256"},
68
+ new TextEncoder().encode(stringify(data)),
69
69
  )
70
70
  return SafeBuffer.from(new Uint8Array(hash))
71
71
  }
72
72
 
73
73
  /**
74
- * Derive AES key from password and salt
74
+ * Derive AES key from password and salt
75
75
  */
76
- export const aeskey = async (
77
- key: string,
78
- salt: SeaArray
79
- ) => {
76
+ export const aeskey = async (key: string, salt: SeaArray) => {
80
77
  const combined = key + salt.toString("utf8")
81
78
  const hashResult = await sha256(combined)
82
79
  const jwkKey = keyToJwk(hashResult)
83
- return await subtle.importKey("jwk", jwkKey, { name: "AES-GCM" }, false, [
80
+ return await subtle.importKey("jwk", jwkKey, {name: "AES-GCM"}, false, [
84
81
  "encrypt",
85
82
  "decrypt",
86
83
  ])
@@ -95,9 +92,8 @@ const keyToJwk = (key: SeaArray): JWK => {
95
92
  .replace(/\+/g, "-")
96
93
  .replace(/\//g, "_")
97
94
  .replace(/=/g, "")
98
- return { kty: "oct", k: k, ext: false, alg: "A256GCM" }
95
+ return {kty: "oct", k: k, ext: false, alg: "A256GCM"}
99
96
  }
100
97
 
101
98
  // Re-export SeaArray type for convenience
102
99
  import type SeaArray from "./array.ts"
103
-
package/ts/src/sea.ts CHANGED
@@ -3,14 +3,10 @@
3
3
  * Cryptographic functions for signing, verification, encryption, and decryption
4
4
  */
5
5
 
6
- import { userPublicKey, userSignature } from "./utils.ts"
6
+ import {userPublicKey, userSignature} from "./utils.ts"
7
7
  import * as utils from "./sea-utils.ts"
8
8
  import SafeBuffer from "./buffer.ts"
9
- import type {
10
- UserPair,
11
- EncryptedData,
12
- SignedData,
13
- } from "./schemas.ts"
9
+ import type {UserPair, EncryptedData, SignedData} from "./schemas.ts"
14
10
 
15
11
  type Callback<T> = (result: T) => void
16
12
 
@@ -24,7 +20,7 @@ const SEA = {
24
20
  pair: async (cb?: Callback<UserPair>): Promise<UserPair> => {
25
21
  // ECDSA keys for signing/verifying
26
22
  const ecdsa = await utils.subtle
27
- .generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, [
23
+ .generateKey({name: "ECDSA", namedCurve: "P-256"}, true, [
28
24
  "sign",
29
25
  "verify",
30
26
  ])
@@ -38,7 +34,7 @@ const SEA = {
38
34
 
39
35
  // ECDH keys for encryption/decryption
40
36
  const ecdh = await utils.subtle
41
- .generateKey({ name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey"])
37
+ .generateKey({name: "ECDH", namedCurve: "P-256"}, true, ["deriveKey"])
42
38
  .then(async keys => {
43
39
  const pub = await utils.subtle.exportKey("jwk", keys.publicKey)
44
40
  return {
@@ -63,14 +59,14 @@ const SEA = {
63
59
  encrypt: async (
64
60
  data: unknown,
65
61
  pair: Partial<UserPair> | null,
66
- cb?: Callback<EncryptedData | null>
62
+ cb?: Callback<EncryptedData | null>,
67
63
  ): Promise<EncryptedData | null> => {
68
64
  if (!pair || !pair.epriv) {
69
65
  if (cb) cb(null)
70
66
  return null
71
67
  }
72
68
 
73
- const rand = { s: utils.random(9), iv: utils.random(15) }
69
+ const rand = {s: utils.random(9), iv: utils.random(15)}
74
70
  const ct = await utils.aeskey(pair.epriv, rand.s).then(aes => {
75
71
  return utils.subtle.encrypt(
76
72
  {
@@ -78,7 +74,7 @@ const SEA = {
78
74
  iv: new Uint8Array(rand.iv),
79
75
  },
80
76
  aes,
81
- new TextEncoder().encode(utils.stringify(data))
77
+ new TextEncoder().encode(utils.stringify(data)),
82
78
  )
83
79
  })
84
80
  const enc: EncryptedData = {
@@ -96,7 +92,7 @@ const SEA = {
96
92
  decrypt: async (
97
93
  enc: Partial<EncryptedData> | null,
98
94
  pair: Partial<UserPair> | null,
99
- cb?: Callback<unknown | null>
95
+ cb?: Callback<unknown | null>,
100
96
  ): Promise<unknown | null> => {
101
97
  if (!enc || !enc.ct || !enc.iv || !enc.s || !pair || !pair.epriv) {
102
98
  if (cb) cb(null)
@@ -117,7 +113,7 @@ const SEA = {
117
113
  tagLength: 128,
118
114
  },
119
115
  aes,
120
- new Uint8Array(data.ct)
116
+ new Uint8Array(data.ct),
121
117
  )
122
118
  })
123
119
  const dec = utils.parse(new TextDecoder("utf8").decode(ct))
@@ -136,7 +132,7 @@ const SEA = {
136
132
  verify: async (
137
133
  data: string | SignedData,
138
134
  pair: Partial<UserPair> | null,
139
- cb?: Callback<unknown | null>
135
+ cb?: Callback<unknown | null>,
140
136
  ): Promise<unknown | null> => {
141
137
  if (!pair || !pair.pub) {
142
138
  if (cb) cb(null)
@@ -149,9 +145,9 @@ const SEA = {
149
145
  const key = await utils.subtle.importKey(
150
146
  "jwk",
151
147
  utils.jwk(pair.pub),
152
- { name: "ECDSA", namedCurve: "P-256" },
148
+ {name: "ECDSA", namedCurve: "P-256"},
153
149
  false,
154
- ["verify"]
150
+ ["verify"],
155
151
  )
156
152
 
157
153
  let msg: string | Record<string, unknown> = {}
@@ -162,13 +158,13 @@ const SEA = {
162
158
  // (which should not be part of signature, so not verified)
163
159
  for (const k of Object.keys(signed.m).sort()) {
164
160
  if (k !== "_" && k !== userPublicKey && k !== userSignature) {
165
- (msg as Record<string, unknown>)[k] = signed.m[k]
161
+ ;(msg as Record<string, unknown>)[k] = signed.m[k]
166
162
  }
167
163
  }
168
164
  }
169
165
  const hash = await utils.sha256(msg)
170
166
  const sig = new Uint8Array(SafeBuffer.from(signed.s, "base64"))
171
- const alg = { name: "ECDSA", hash: { name: "SHA-256" } }
167
+ const alg = {name: "ECDSA", hash: {name: "SHA-256"}}
172
168
  if (await utils.subtle.verify(alg, key, sig, new Uint8Array(hash))) {
173
169
  const verified = utils.parse(signed.m as string)
174
170
  if (cb) cb(verified)
@@ -185,7 +181,7 @@ const SEA = {
185
181
  sign: async (
186
182
  data: string | Record<string, unknown>,
187
183
  pair: Partial<UserPair> | null,
188
- cb?: Callback<SignedData | null>
184
+ cb?: Callback<SignedData | null>,
189
185
  ): Promise<SignedData | null> => {
190
186
  if (!pair || !pair.pub || !pair.priv) {
191
187
  if (cb) cb(null)
@@ -199,21 +195,21 @@ const SEA = {
199
195
  const check = utils.parse(data as never) as Record<string, unknown>
200
196
  for (const k of Object.keys(check).sort()) {
201
197
  if (k !== "_" && k !== userPublicKey && k !== userSignature) {
202
- (msg as Record<string, unknown>)[k] = check[k]
198
+ ;(msg as Record<string, unknown>)[k] = check[k]
203
199
  }
204
200
  }
205
201
  }
206
202
  const hash = await utils.sha256(msg)
207
203
  const jwk = utils.jwk(pair.pub, pair.priv)
208
- const alg = { name: "ECDSA", namedCurve: "P-256" }
204
+ const alg = {name: "ECDSA", namedCurve: "P-256"}
209
205
  const sig = await utils.subtle
210
206
  .importKey("jwk", jwk, alg, false, ["sign"])
211
207
  .then(key =>
212
208
  utils.subtle.sign(
213
- { name: "ECDSA", hash: { name: "SHA-256" } },
209
+ {name: "ECDSA", hash: {name: "SHA-256"}},
214
210
  key,
215
- new Uint8Array(hash)
216
- )
211
+ new Uint8Array(hash),
212
+ ),
217
213
  )
218
214
  const signed: SignedData = {
219
215
  m: msg,
@@ -230,7 +226,7 @@ const SEA = {
230
226
  signTimestamp: async (
231
227
  timestamp: number,
232
228
  pair: Partial<UserPair> | null,
233
- cb?: Callback<string | null>
229
+ cb?: Callback<string | null>,
234
230
  ): Promise<string | null> => {
235
231
  if (!pair || !pair.pub || !pair.priv) {
236
232
  if (cb) cb(null)
@@ -241,16 +237,16 @@ const SEA = {
241
237
  const timestampStr = timestamp.toString()
242
238
  const hash = await utils.sha256(timestampStr)
243
239
  const jwk = utils.jwk(pair.pub, pair.priv)
244
- const alg = { name: "ECDSA", namedCurve: "P-256" }
240
+ const alg = {name: "ECDSA", namedCurve: "P-256"}
245
241
 
246
242
  const sig = await utils.subtle
247
243
  .importKey("jwk", jwk, alg, false, ["sign"])
248
244
  .then(key =>
249
245
  utils.subtle.sign(
250
- { name: "ECDSA", hash: { name: "SHA-256" } },
246
+ {name: "ECDSA", hash: {name: "SHA-256"}},
251
247
  key,
252
- new Uint8Array(hash)
253
- )
248
+ new Uint8Array(hash),
249
+ ),
254
250
  )
255
251
 
256
252
  const signature = SafeBuffer.from(sig, "binary").toString("base64")
@@ -266,7 +262,7 @@ const SEA = {
266
262
  timestamp: number,
267
263
  signature: string,
268
264
  publicKey: string,
269
- cb?: Callback<boolean>
265
+ cb?: Callback<boolean>,
270
266
  ): Promise<boolean> => {
271
267
  if (!publicKey || !timestamp || !signature) {
272
268
  if (cb) cb(false)
@@ -281,25 +277,27 @@ const SEA = {
281
277
  const key = await utils.subtle.importKey(
282
278
  "jwk",
283
279
  utils.jwk(publicKey),
284
- { name: "ECDSA", namedCurve: "P-256" },
280
+ {name: "ECDSA", namedCurve: "P-256"},
285
281
  false,
286
- ["verify"]
282
+ ["verify"],
287
283
  )
288
284
 
289
285
  const sig = new Uint8Array(SafeBuffer.from(signature, "base64"))
290
- const alg = { name: "ECDSA", hash: { name: "SHA-256" } }
286
+ const alg = {name: "ECDSA", hash: {name: "SHA-256"}}
291
287
 
292
288
  const isValid = await utils.subtle.verify(
293
289
  alg,
294
290
  key,
295
291
  sig,
296
- new Uint8Array(hash)
292
+ new Uint8Array(hash),
297
293
  )
298
294
 
299
295
  if (cb) cb(isValid)
300
296
  return isValid
301
297
  } catch (err) {
302
- console.log(`error verifying timestamp signature: ${(err as Error).message}`)
298
+ console.log(
299
+ `error verifying timestamp signature: ${(err as Error).message}`,
300
+ )
303
301
  if (cb) cb(false)
304
302
  return false
305
303
  }
@@ -311,13 +309,13 @@ const SEA = {
311
309
  work: async (
312
310
  data: unknown,
313
311
  salt?: unknown,
314
- cb?: Callback<{ epriv: string }>
315
- ): Promise<{ epriv: string }> => {
312
+ cb?: Callback<{epriv: string}>,
313
+ ): Promise<{epriv: string}> => {
316
314
  let _cb = cb
317
315
  let _salt = salt
318
316
 
319
317
  if (typeof salt === "function") {
320
- _cb = salt as Callback<{ epriv: string }>
318
+ _cb = salt as Callback<{epriv: string}>
321
319
  _salt = undefined
322
320
  }
323
321
  if (typeof _salt === "undefined") _salt = utils.random(9)
@@ -325,19 +323,19 @@ const SEA = {
325
323
  const key = await utils.subtle.importKey(
326
324
  "raw",
327
325
  new TextEncoder().encode(utils.stringify(data)),
328
- { name: "PBKDF2" },
326
+ {name: "PBKDF2"},
329
327
  false,
330
- ["deriveBits"]
328
+ ["deriveBits"],
331
329
  )
332
330
  const alg = {
333
331
  name: "PBKDF2",
334
332
  iterations: 100000,
335
333
  salt: new TextEncoder().encode(_salt as string),
336
- hash: { name: "SHA-256" },
334
+ hash: {name: "SHA-256"},
337
335
  }
338
336
  const work = await utils.subtle.deriveBits(alg, key, 512)
339
337
  // Use "pair" format so that work can be used as epriv by decrypt
340
- const pair = { epriv: SafeBuffer.from(work, "binary").toString("base64") }
338
+ const pair = {epriv: SafeBuffer.from(work, "binary").toString("base64")}
341
339
  if (_cb) _cb(pair)
342
340
  return pair
343
341
  },
@@ -348,41 +346,40 @@ const SEA = {
348
346
  secret: async (
349
347
  to: Partial<UserPair> | null,
350
348
  from: Partial<UserPair> | null,
351
- cb?: Callback<{ epriv: string } | null>
352
- ): Promise<{ epriv: string } | null> => {
349
+ cb?: Callback<{epriv: string} | null>,
350
+ ): Promise<{epriv: string} | null> => {
353
351
  if (!to || !to.epub || !from || !from.epub || !from.epriv) {
354
352
  if (cb) cb(null)
355
353
  return null
356
354
  }
357
355
 
358
- const alg = { name: "ECDH", namedCurve: "P-256" }
356
+ const alg = {name: "ECDH", namedCurve: "P-256"}
359
357
  const pub = utils.jwk(to.epub)
360
358
  const pubKey = await utils.subtle.importKey("jwk", pub, alg, true, [])
361
359
  const priv = utils.jwk(from.epub, from.epriv)
362
360
  // utils.jwk provides default key_ops but it shouldn't be used here
363
- delete (priv as { key_ops?: unknown }).key_ops
361
+ delete (priv as {key_ops?: unknown}).key_ops
364
362
  const derived = await utils.subtle
365
363
  .importKey("jwk", priv, alg, false, ["deriveBits"])
366
364
  .then(async key => {
367
365
  const derivedBits = await utils.subtle.deriveBits(
368
- { public: pubKey, name: "ECDH", namedCurve: "P-256" } as never,
366
+ {public: pubKey, name: "ECDH", namedCurve: "P-256"} as never,
369
367
  key,
370
- 256
368
+ 256,
371
369
  )
372
370
  const derivedKey = await utils.subtle.importKey(
373
371
  "raw",
374
372
  new Uint8Array(derivedBits),
375
- { name: "AES-GCM", length: 256 },
373
+ {name: "AES-GCM", length: 256},
376
374
  true,
377
- ["encrypt", "decrypt"]
375
+ ["encrypt", "decrypt"],
378
376
  )
379
- return utils.subtle.exportKey("jwk", derivedKey).then(({ k }) => k!)
377
+ return utils.subtle.exportKey("jwk", derivedKey).then(({k}) => k!)
380
378
  })
381
379
  // Use "pair" format so that secret can be used as epriv by encrypt
382
- if (cb) cb({ epriv: derived })
383
- return { epriv: derived }
380
+ if (cb) cb({epriv: derived})
381
+ return {epriv: derived}
384
382
  },
385
383
  }
386
384
 
387
385
  export default SEA
388
-
package/ts/src/store.ts CHANGED
@@ -18,9 +18,7 @@ import type {
18
18
  const isNode = typeof process !== "undefined" && process.versions?.node != null
19
19
 
20
20
  // Dynamic import for Node.js fs module - won't execute in browser/service worker
21
- const fs = isNode
22
- ? await import(/*webpackIgnore: true*/ "node:fs")
23
- : undefined
21
+ const fs = isNode ? await import(/*webpackIgnore: true*/ "node:fs") : undefined
24
22
 
25
23
  // ASCII character for enquiry
26
24
  const enq = String.fromCharCode(5)
@@ -41,39 +39,49 @@ const fileSystem = (opt: StoreOptions): FileSystemInterface => {
41
39
 
42
40
  return {
43
41
  get: (file, cb) => {
44
- fs!.readFile(dir + "/" + file, (err: NodeJS.ErrnoException | null, data?: Buffer) => {
45
- if (err) {
46
- if ((err as { code?: string }).code === "ENOENT") {
47
- cb()
48
- return
42
+ fs!.readFile(
43
+ dir + "/" + file,
44
+ (err: NodeJS.ErrnoException | null, data?: Buffer) => {
45
+ if (err) {
46
+ if ((err as {code?: string}).code === "ENOENT") {
47
+ cb()
48
+ return
49
+ }
50
+ console.log("fs.readFile error:", err)
49
51
  }
50
- console.log("fs.readFile error:", err)
51
- }
52
- const dataStr = data ? data.toString() : undefined
53
- cb(err as never, dataStr)
54
- })
52
+ const dataStr = data ? data.toString() : undefined
53
+ cb(err as never, dataStr)
54
+ },
55
+ )
55
56
  },
56
57
  put: (file, data, cb) => {
57
58
  const tmp = file + "." + utils.text.random(9) + ".tmp"
58
- fs!.writeFile(tmp, data as string, (err: NodeJS.ErrnoException | null) => {
59
- if (err) {
60
- console.log("fs.writeFile error:", err)
61
- cb(err as never)
62
- return
63
- }
64
- fs!.rename(tmp, dir + "/" + file, cb as never)
65
- })
59
+ fs!.writeFile(
60
+ tmp,
61
+ data as string,
62
+ (err: NodeJS.ErrnoException | null) => {
63
+ if (err) {
64
+ console.log("fs.writeFile error:", err)
65
+ cb(err as never)
66
+ return
67
+ }
68
+ fs!.rename(tmp, dir + "/" + file, cb as never)
69
+ },
70
+ )
66
71
  },
67
72
  list: cb => {
68
- fs!.readdir(dir, (err: NodeJS.ErrnoException | null, files?: string[]) => {
69
- if (err) {
70
- console.log("fs.readdir error:", err)
73
+ fs!.readdir(
74
+ dir,
75
+ (err: NodeJS.ErrnoException | null, files?: string[]) => {
76
+ if (err) {
77
+ console.log("fs.readdir error:", err)
78
+ cb()
79
+ return
80
+ }
81
+ if (files) files.forEach(cb)
71
82
  cb()
72
- return
73
- }
74
- if (files) files.forEach(cb)
75
- cb()
76
- })
83
+ },
84
+ )
77
85
  },
78
86
  }
79
87
  }
@@ -122,7 +130,10 @@ const fileSystem = (opt: StoreOptions): FileSystemInterface => {
122
130
 
123
131
  return {
124
132
  get: (file, cb) => {
125
- const _get = (file: string, cb: (err?: string | null, data?: string) => void) => {
133
+ const _get = (
134
+ file: string,
135
+ cb: (err?: string | null, data?: string) => void,
136
+ ) => {
126
137
  const tx = db.transaction([dir], "readonly")
127
138
  const req = tx.objectStore(dir).get(file)
128
139
  req.onerror = () => {
@@ -146,7 +157,7 @@ const fileSystem = (opt: StoreOptions): FileSystemInterface => {
146
157
  const _put = (
147
158
  file: string,
148
159
  data: string,
149
- cb: (err?: string | null) => void
160
+ cb: (err?: string | null) => void,
150
161
  ) => {
151
162
  const tx = db.transaction([dir], "readwrite")
152
163
  const req = tx.objectStore(dir).put(data, file)
@@ -209,11 +220,7 @@ const fileSystem = (opt: StoreOptions): FileSystemInterface => {
209
220
  }
210
221
 
211
222
  export interface StoreInterface {
212
- get: (
213
- lex: Lex,
214
- cb: (err?: string | null, graph?: Graph) => void,
215
- _opt?: { secure?: boolean }
216
- ) => void
223
+ get: (lex: Lex, cb: (err?: string | null, graph?: Graph) => void) => void
217
224
  put: (graph: Graph, cb: (err?: string | null) => void) => void
218
225
  }
219
226
 
@@ -227,7 +234,7 @@ const Store = (opt?: StoreOptions): StoreInterface => {
227
234
  const radisk = Radisk(options as never)
228
235
 
229
236
  return {
230
- get: (lex, cb, _opt) => {
237
+ get: (lex, cb) => {
231
238
  if (!lex || !utils.obj.is(lex)) {
232
239
  cb("lex required")
233
240
  return
@@ -237,42 +244,56 @@ const Store = (opt?: StoreOptions): StoreInterface => {
237
244
  return
238
245
  }
239
246
 
240
- const opts = _opt || {}
241
247
  const soul = lex["#"]
242
- const key =
243
- !opts.secure && typeof lex["."] === "string" ? lex["."] : ""
248
+ const key = typeof lex["."] === "string" ? lex["."] : ""
244
249
  let node: GraphNode | undefined
245
250
  const signatures: Record<string, string> = {}
246
251
 
247
- const each = (value: EncodedValue, key: string): void => {
248
- // Always include userPublicKey for verification, regardless of filter
249
- if (key !== utils.userPublicKey && !utils.match(lex["."], key)) return
252
+ const each = (value: EncodedValue, k: string): void => {
253
+ if (k !== utils.userPublicKey && !utils.match(lex["."], k)) return
250
254
 
251
- if (!node) node = { _: { "#": soul, ">": {} } }
252
- node[key] = value[0]
253
- node._[">"][key] = value[1]
255
+ if (!node) node = {_: {"#": soul, ">": {}}}
256
+ node[k] = value[0]
257
+ node._[">"][k] = value[1]
254
258
  // If signature is present, store it in _["s"]
255
259
  if (value.length === 3 && value[2]) {
256
260
  signatures[value[1].toString()] = value[2]
257
261
  }
258
262
  }
259
263
 
264
+ // When doing a targeted property lookup, also fetch userPublicKey in
265
+ // parallel so ham.js can verify signatures regardless of secure mode.
266
+ // Full-soul scans (key="") already surface it via Radix.map.
267
+ const needsPubKey = key !== "" && key !== utils.userPublicKey
268
+ let pending = needsPubKey ? 2 : 1
269
+ let cbErr: string | null = null
270
+ const finish = (err: string | null | undefined): void => {
271
+ if (err && !cbErr) cbErr = err
272
+ if (--pending > 0) return
273
+ const graph: Graph = {[soul]: node!}
274
+ if (node && Object.keys(signatures).length > 0) {
275
+ node._["s"] = signatures
276
+ }
277
+ cb(cbErr, graph)
278
+ }
279
+
260
280
  radisk(soul + enq + key, (err, value) => {
261
- let graph: Graph | undefined
262
281
  if (utils.obj.is(value)) {
263
282
  Radix.map(value as never, each)
264
283
  if (!node) each(value as never, key)
265
- graph = { [soul]: node! }
266
284
  } else if (value) {
267
285
  each(value as EncodedValue, key)
268
- graph = { [soul]: node! }
269
- }
270
- // Only add _["s"] if we found any signatures
271
- if (graph && graph[soul] && Object.keys(signatures).length > 0) {
272
- graph[soul]._["s"] = signatures
273
286
  }
274
- cb(err, graph)
287
+ finish(err)
275
288
  })
289
+
290
+ if (needsPubKey) {
291
+ radisk(soul + enq + utils.userPublicKey, (err, value) => {
292
+ if (value && !utils.obj.is(value))
293
+ each(value as EncodedValue, utils.userPublicKey)
294
+ finish(err)
295
+ })
296
+ }
276
297
  },
277
298
  put: (graph, cb) => {
278
299
  if (!graph) {
@@ -307,9 +328,7 @@ const Store = (opt?: StoreOptions): StoreInterface => {
307
328
  const value = node[key]!
308
329
  const state = node._[">"][key]!
309
330
  const sig = node._["s"] && node._["s"][state]
310
- const data: EncodedValue = sig
311
- ? [value, state, sig]
312
- : [value, state]
331
+ const data: EncodedValue = sig ? [value, state, sig] : [value, state]
313
332
  radisk(soul + enq + key, data, ack)
314
333
  })
315
334
  })
@@ -318,4 +337,3 @@ const Store = (opt?: StoreOptions): StoreInterface => {
318
337
  }
319
338
 
320
339
  export default Store
321
-