@mblaney/holster 1.0.26 → 1.0.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblaney/holster",
3
- "version": "1.0.26",
3
+ "version": "1.0.27",
4
4
  "description": "Holster is a service that allows synchronising data between devices using Node, Deno, Bun or the browser.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/get.js CHANGED
@@ -1,4 +1,4 @@
1
- import {match} from "./utils.js"
1
+ import {match, userPublicKey} from "./utils.js"
2
2
 
3
3
  const Get = (lex, graph) => {
4
4
  if (!lex || typeof lex !== "object") {
@@ -34,7 +34,8 @@ const Get = (lex, graph) => {
34
34
  }
35
35
  } else {
36
36
  for (const key of Object.keys(graph[soul])) {
37
- if (match(lex["."], key)) {
37
+ // Always include userPublicKey for verification, regardless of filter
38
+ if (key === userPublicKey || match(lex["."], key)) {
38
39
  node[key] = graph[soul][key]
39
40
  node._[">"][key] = graph[soul]._[">"][key]
40
41
  const state = graph[soul]._[">"][key]
package/src/radisk.js CHANGED
@@ -34,6 +34,7 @@ const Radisk = opt => {
34
34
  if (!opt.write) opt.write = 1 // Wait time before write in milliseconds
35
35
  if (!opt.size) opt.size = 1024 * 1024 // File size on disk, default 1MB
36
36
  if (!opt.memoryLimit) opt.memoryLimit = 500 // Memory limit in MB
37
+ if (!opt.readTimeout) opt.readTimeout = 1000 // Read timeout in milliseconds
37
38
  if (typeof opt.cache === "undefined") opt.cache = true
38
39
 
39
40
  if (!opt.store) {
@@ -126,20 +127,34 @@ const Radisk = opt => {
126
127
  // Check if there's already a pending read for this key
127
128
  if (pendingReads.has(key)) {
128
129
  // Add callback to existing pending read
129
- pendingReads.get(key).push(cb)
130
+ pendingReads.get(key).callbacks.push(cb)
130
131
  return
131
132
  }
132
133
 
133
- // Start new read and create callback queue
134
- pendingReads.set(key, [cb])
134
+ // Start new read and create callback queue with fired flag
135
+ const pending = {callbacks: [cb], fired: false, timeoutId: null}
136
+ pendingReads.set(key, pending)
137
+
138
+ // Set a timeout to fire callbacks if read takes too long
139
+ pending.timeoutId = setTimeout(() => {
140
+ if (!pending.fired) {
141
+ pending.fired = true
142
+ pendingReads.delete(key)
143
+ const err = new Error("radisk read timeout")
144
+ pending.callbacks.forEach(callback => callback(err, undefined))
145
+ }
146
+ }, opt.readTimeout)
135
147
 
136
148
  const readStart = Date.now()
137
149
  return radisk.read(key, (err, result) => {
150
+ clearTimeout(pending.timeoutId)
138
151
  perfLog("read", readStart, key)
139
- // Execute all pending callbacks for this key
140
- const callbacks = pendingReads.get(key) || []
141
- pendingReads.delete(key)
142
- callbacks.forEach(callback => callback(err, result))
152
+ // Execute all pending callbacks for this key if timeout hasn't fired
153
+ if (!pending.fired) {
154
+ pending.fired = true
155
+ pendingReads.delete(key)
156
+ pending.callbacks.forEach(callback => callback(err, result))
157
+ }
143
158
  })
144
159
  }
145
160
 
package/src/store.js CHANGED
@@ -226,7 +226,8 @@ const Store = opt => {
226
226
  var node
227
227
  var signatures = {}
228
228
  const each = (value, key) => {
229
- if (!utils.match(lex["."], key)) return
229
+ // Always include userPublicKey for verification, regardless of filter
230
+ if (key !== utils.userPublicKey && !utils.match(lex["."], key)) return
230
231
 
231
232
  if (!node) node = {_: {"#": soul, ">": {}}}
232
233
  node[key] = value[0]