@mblaney/holster 1.0.6 → 1.0.8
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/README.md +3 -1
- package/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/package.json +1 -1
- package/src/array.js +21 -10
- package/src/buffer.js +388 -55
- package/src/dup.js +2 -0
- package/src/get.js +11 -0
- package/src/ham.js +31 -5
- package/src/radisk.js +8 -5
- package/src/store.js +21 -7
- package/src/utils.js +23 -14
- package/src/wire.js +7 -1
package/src/store.js
CHANGED
|
@@ -49,6 +49,12 @@ const fileSystem = opt => {
|
|
|
49
49
|
},
|
|
50
50
|
list: cb => {
|
|
51
51
|
fs.readdir(dir, (err, files) => {
|
|
52
|
+
if (err) {
|
|
53
|
+
console.log("fs.readdir error:", err)
|
|
54
|
+
cb()
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
52
58
|
files.forEach(cb)
|
|
53
59
|
cb()
|
|
54
60
|
})
|
|
@@ -206,10 +212,14 @@ const Store = opt => {
|
|
|
206
212
|
|
|
207
213
|
return {
|
|
208
214
|
get: (lex, cb) => {
|
|
209
|
-
if (!lex) {
|
|
215
|
+
if (!lex || !utils.obj.is(lex)) {
|
|
210
216
|
cb("lex required")
|
|
211
217
|
return
|
|
212
218
|
}
|
|
219
|
+
if (!lex["#"]) {
|
|
220
|
+
cb("soul required in lex")
|
|
221
|
+
return
|
|
222
|
+
}
|
|
213
223
|
|
|
214
224
|
var soul = lex["#"]
|
|
215
225
|
var key = typeof lex["."] === "string" ? lex["."] : ""
|
|
@@ -241,18 +251,22 @@ const Store = opt => {
|
|
|
241
251
|
return
|
|
242
252
|
}
|
|
243
253
|
|
|
244
|
-
|
|
254
|
+
let count = 0
|
|
255
|
+
let finished = false
|
|
245
256
|
const ack = err => {
|
|
246
257
|
count--
|
|
247
|
-
if (
|
|
258
|
+
if (finished) return
|
|
248
259
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
cb(
|
|
260
|
+
if (err) {
|
|
261
|
+
finished = true
|
|
262
|
+
cb(err)
|
|
252
263
|
return
|
|
253
264
|
}
|
|
254
265
|
|
|
255
|
-
if (count === 0)
|
|
266
|
+
if (count === 0) {
|
|
267
|
+
finished = true
|
|
268
|
+
cb(null)
|
|
269
|
+
}
|
|
256
270
|
}
|
|
257
271
|
|
|
258
272
|
Object.keys(graph).forEach(soul => {
|
package/src/utils.js
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
export const num = {
|
|
2
|
-
is: n =>
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
is: n => {
|
|
3
|
+
if (n instanceof Array) return false
|
|
4
|
+
|
|
5
|
+
if (typeof n === "number") return !isNaN(n)
|
|
6
|
+
|
|
7
|
+
if (typeof n === "string") {
|
|
8
|
+
const parsed = parseFloat(n)
|
|
9
|
+
return !isNaN(parsed) && isFinite(parsed)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return false
|
|
13
|
+
},
|
|
5
14
|
}
|
|
6
15
|
|
|
7
16
|
export const obj = {
|
|
8
17
|
is: o => {
|
|
9
|
-
if (!o) return false
|
|
18
|
+
if (!o || typeof o !== "object") return false
|
|
10
19
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"Object"
|
|
15
|
-
)
|
|
20
|
+
const toString = Object.prototype.toString.call(o)
|
|
21
|
+
const match = toString.match(/^\[object (\w+)\]$/)
|
|
22
|
+
return o.constructor === Object || (match && match[1] === "Object")
|
|
16
23
|
},
|
|
17
24
|
map: (list, cb, o) => {
|
|
18
25
|
var keys = Object.keys(list)
|
|
@@ -74,11 +81,13 @@ export const userPublicKey = "_holster_user_public_key"
|
|
|
74
81
|
// graph converts objects to graph format with updated states,
|
|
75
82
|
// with optional meta data to verify signed data.
|
|
76
83
|
export const graph = (soul, data, sig, pub) => {
|
|
84
|
+
const timestamp = Date.now()
|
|
77
85
|
const g = {[soul]: {_: {"#": soul, ">": {}}}}
|
|
86
|
+
|
|
78
87
|
for (const [key, value] of Object.entries(data)) {
|
|
79
|
-
if (key !== "_" && key
|
|
88
|
+
if (key !== "_" && key !== userPublicKey && key !== userSignature) {
|
|
80
89
|
g[soul][key] = value
|
|
81
|
-
g[soul]._[">"][key] =
|
|
90
|
+
g[soul]._[">"][key] = timestamp
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
// If a signature and public key are provided they also need to be stored on
|
|
@@ -87,9 +96,9 @@ export const graph = (soul, data, sig, pub) => {
|
|
|
87
96
|
// broadcast the data as a put, which other devices will need to verify.
|
|
88
97
|
if (sig && pub) {
|
|
89
98
|
g[soul][userSignature] = sig
|
|
90
|
-
g[soul]._[">"][userSignature] =
|
|
99
|
+
g[soul]._[">"][userSignature] = timestamp
|
|
91
100
|
g[soul][userPublicKey] = pub
|
|
92
|
-
g[soul]._[">"][userPublicKey] =
|
|
101
|
+
g[soul]._[">"][userPublicKey] = timestamp
|
|
93
102
|
}
|
|
94
103
|
return g
|
|
95
104
|
}
|
|
@@ -121,7 +130,7 @@ export const match = (lex, key) => {
|
|
|
121
130
|
export const text = {
|
|
122
131
|
random: length => {
|
|
123
132
|
var s = ""
|
|
124
|
-
const c = "
|
|
133
|
+
const c = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
125
134
|
if (!length) length = 24
|
|
126
135
|
for (let i = 0; i < length; i++) {
|
|
127
136
|
s += c.charAt(Math.floor(Math.random() * c.length))
|
package/src/wire.js
CHANGED
|
@@ -164,7 +164,13 @@ const Wire = opt => {
|
|
|
164
164
|
// across the network.
|
|
165
165
|
const update = await Ham.mix(data, graph, opt.secure, listen)
|
|
166
166
|
const none = Object.keys(update.now).length === 0
|
|
167
|
-
if (none
|
|
167
|
+
if (none) {
|
|
168
|
+
// Nothing to do.
|
|
169
|
+
cb(null)
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!(await check(update.now, send, cb))) return
|
|
168
174
|
|
|
169
175
|
store.put(update.now, cb)
|
|
170
176
|
// Also put data on the wire spec.
|