@mblaney/holster 1.0.35 → 1.0.36
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/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/dist/holster.js +4 -0
- package/dist/holster.js.map +7 -0
- package/package.json +23 -5
- package/src/get.js +6 -18
- package/src/ham.js +17 -47
- package/src/holster.js +106 -28
- package/src/sea.js +0 -52
- package/src/store.js +7 -7
- package/src/wire.js +7 -1
- package/ts/src/array.ts +78 -0
- package/ts/src/buffer.ts +441 -0
- package/ts/src/dup.ts +49 -0
- package/ts/src/get.ts +83 -0
- package/ts/src/ham.ts +254 -0
- package/ts/src/holster.ts +931 -0
- package/ts/src/index.ts +35 -0
- package/ts/src/radisk.ts +585 -0
- package/ts/src/radix.ts +157 -0
- package/ts/src/schemas.ts +519 -0
- package/ts/src/sea-utils.ts +103 -0
- package/ts/src/sea.ts +388 -0
- package/ts/src/store.ts +321 -0
- package/ts/src/user.ts +381 -0
- package/ts/src/utils.ts +232 -0
- package/ts/src/wire.ts +829 -0
- package/.dockerignore +0 -9
- package/.github/workflows/node.js.yml +0 -31
- package/.github/workflows/npm-publish.yml +0 -33
- package/Dockerfile +0 -20
- package/examples/index.html +0 -33
- package/examples/index.js +0 -49
- package/examples/user.html +0 -31
- package/examples/user.js +0 -93
- package/examples/wire.html +0 -27
- package/examples/wire.js +0 -55
- package/test/holster.get.test.js +0 -94
- package/test/holster.lex.test.js +0 -196
- package/test/holster.off.test.js +0 -53
- package/test/holster.on.test.js +0 -264
- package/test/holster.put.test.js +0 -358
- package/test/holster.secure.test.js +0 -202
- package/test/holster.user.get.test.js +0 -114
- package/test/holster.user.lex.test.js +0 -149
- package/test/holster.user.off.test.js +0 -73
- package/test/holster.user.on.test.js +0 -300
- package/test/holster.user.put.test.js +0 -463
- package/test/kitty/! +0 -9
- package/test/names.js +0 -225
- package/test/radisk.cache.test.js +0 -213
- package/test/radisk.test.js +0 -331
- package/test/radix.test.js +0 -117
- package/test/sea.test.js +0 -284
- package/test/split.test.js +0 -317
- package/test/store.test.js +0 -316
- package/test/system/basic.test.js +0 -29
- package/test/system/chained-on.test.js +0 -41
- package/test/system/concurrent-listeners.test.js +0 -125
- package/test/system/immediate-read.test.js +0 -30
- package/test/system/listener-before-data.test.js +0 -51
- package/test/system/promise-wrapper.test.js +0 -47
- package/test/system/user-chained-on.test.js +0 -60
- package/test/system/user-concurrent-listeners.test.js +0 -142
- package/test/system/user-listener-before-data.test.js +0 -66
- package/test/user.test.js +0 -173
- package/test/wire.test.js +0 -158
package/build/holster.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/utils.js", "../src/dup.js", "../src/get.js", "../src/array.js", "../src/buffer.js", "../src/sea-utils.js", "../src/sea.js", "../src/ham.js", "../src/radix.js", "../src/radisk.js", "../src/store.js", "../src/wire.js", "../src/user.js", "../src/holster.js"],
|
|
4
|
-
"sourcesContent": ["export const num = {\n is: n => {\n if (n instanceof Array) return false\n\n if (typeof n === \"number\") return !isNaN(n)\n\n if (typeof n === \"string\") {\n const parsed = parseFloat(n)\n return !isNaN(parsed) && isFinite(parsed)\n }\n\n return false\n },\n}\n\nexport const obj = {\n is: o => {\n if (!o || typeof o !== \"object\") return false\n\n const toString = Object.prototype.toString.call(o)\n const match = toString.match(/^\\[object (\\w+)\\]$/)\n return o.constructor === Object || (match && match[1] === \"Object\")\n },\n map: (list, cb, o) => {\n var keys = Object.keys(list)\n for (let i = 0; i < keys.length; i++) {\n let result = cb(list[keys[i]], keys[i], o)\n if (typeof result !== \"undefined\") return result\n }\n },\n put: (o, key, value) => {\n if (!o) o = {}\n o[key] = value\n return o\n },\n del: (o, key) => {\n if (!o) return\n\n o[key] = null\n delete o[key]\n return o\n },\n}\n\nconst map_soul = (soul, key, o) => {\n // If id is already defined AND we're still looping through the object,\n // then it is considered invalid.\n if (o.id) {\n o.id = false\n return\n }\n\n if (key === \"#\" && typeof soul === \"string\") {\n o.id = soul\n return\n }\n\n // If there exists anything else on the object that isn't the soul,\n // then it is considered invalid.\n o.id = false\n}\n\n// Check if an object is a soul relation, ie {'#': 'UUID'}\nexport const rel = {\n is: value => {\n if (value && value[\"#\"] && !value._ && obj.is(value)) {\n let o = {}\n obj.map(value, map_soul, o)\n if (o.id) return o.id\n }\n\n return false\n },\n // Convert a soul into a relation and return it.\n ify: soul => obj.put({}, \"#\", soul),\n}\n\nexport const userSignature = \"_holster_user_signature\"\nexport const userPublicKey = \"_holster_user_public_key\"\n\n// graph converts objects to graph format with updated states,\n// with optional meta data to verify signed data.\nexport const graph = (soul, data, sig, pub, timestamp) => {\n const g = {[soul]: {_: {\"#\": soul, \">\": {}}}}\n\n for (const [key, value] of Object.entries(data)) {\n if (key !== \"_\" && key !== userPublicKey && key !== userSignature) {\n g[soul][key] = value\n g[soul]._[\">\"][key] = timestamp || Date.now()\n }\n }\n if (sig && pub && timestamp) {\n g[soul]._[\"s\"] = {[timestamp]: sig}\n g[soul][userPublicKey] = pub\n g[soul]._[\">\"][userPublicKey] = timestamp\n }\n return g\n}\n\nexport const match = (lex, key) => {\n // Null is used to match listeners on souls, which don't provide a key.\n if (typeof key === \"undefined\") return lex === null\n\n if (typeof lex === \"undefined\") return true\n\n if (typeof lex === \"string\") return lex === key\n\n // Array support: check if key is in the array\n if (Array.isArray(lex)) return lex.includes(key)\n\n if (!obj.is(lex) || !key) return false\n\n const prefix = lex[\"*\"]\n if (prefix) return key.slice(0, prefix.length) === prefix\n\n const gt = lex[\">\"]\n const lt = lex[\"<\"]\n if (gt && lt) return key >= gt && key <= lt\n\n if (gt) return key >= gt\n\n if (lt) return key <= lt\n\n return false\n}\n\nexport const text = {\n random: length => {\n var s = \"\"\n const c = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n if (!length) length = 24\n for (let i = 0; i < length; i++) {\n s += c.charAt(Math.floor(Math.random() * c.length))\n }\n return s\n },\n}\n", "const Dup = maxAge => {\n // Allow maxAge to be passed in as tests wait on the setTimeout.\n if (!maxAge) maxAge = 9000\n const dup = {store: {}}\n dup.check = id => (dup.store[id] ? dup.track(id) : false)\n dup.track = id => {\n // Keep the liveliness of the message up while it is being received.\n dup.store[id] = Date.now()\n if (!dup.expiry) {\n dup.expiry = setTimeout(() => {\n if (dup.expiry) return\n\n const now = Date.now()\n Object.keys(dup.store).forEach(id => {\n if (now - dup.store[id] > maxAge) delete dup.store[id]\n })\n dup.expiry = null\n }, maxAge)\n }\n return id\n }\n return dup\n}\n\nexport default Dup\n", "import {match, userPublicKey} from \"./utils.js\"\n\nconst Get = (lex, graph, fast) => {\n if (!lex || typeof lex !== \"object\") {\n throw new TypeError(\"lex must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n\n const soul = lex[\"#\"]\n if (!soul || typeof soul !== \"string\") {\n throw new TypeError(\"soul must be a string\")\n }\n\n if (!graph[soul]) return\n\n const node = {_: {\"#\": soul, \">\": {}}}\n let signatures = {}\n\n if (typeof lex[\".\"] === \"string\") {\n const key = lex[\".\"]\n if (typeof graph[soul][key] === \"undefined\") return\n\n node[key] = graph[soul][key]\n node._[\">\"][key] = graph[soul]._[\">\"][key]\n const state = graph[soul]._[\">\"][key]\n if (graph[soul]._[\"s\"]) {\n if (graph[soul]._[\"s\"][state]) {\n signatures[state] = graph[soul]._[\"s\"][state]\n } else if (graph[soul]._[\"s\"][key]) {\n signatures[key] = graph[soul]._[\"s\"][key]\n }\n }\n\n // Always include userPublicKey for verification, regardless of filter\n if (userPublicKey && typeof graph[soul][userPublicKey] !== \"undefined\") {\n node[userPublicKey] = graph[soul][userPublicKey]\n node._[\">\"][userPublicKey] = graph[soul]._[\">\"][userPublicKey]\n const pkState = graph[soul]._[\">\"][userPublicKey]\n if (graph[soul]._[\"s\"]) {\n if (graph[soul]._[\"s\"][pkState]) {\n signatures[pkState] = graph[soul]._[\"s\"][pkState]\n } else if (graph[soul]._[\"s\"][userPublicKey]) {\n signatures[userPublicKey] = graph[soul]._[\"s\"][userPublicKey]\n }\n }\n }\n } else {\n // For fast requests, return properties currently in the graph. Otherwise\n // return undefined to ensure we get all matching properties from store.\n if (!fast) return\n\n for (const key of Object.keys(graph[soul])) {\n // Always include userPublicKey for verification, regardless of filter\n if (key === userPublicKey || match(lex[\".\"], key)) {\n node[key] = graph[soul][key]\n node._[\">\"][key] = graph[soul]._[\">\"][key]\n const state = graph[soul]._[\">\"][key]\n if (graph[soul]._[\"s\"]) {\n if (graph[soul]._[\"s\"][state]) {\n signatures[state] = graph[soul]._[\"s\"][state]\n } else if (graph[soul]._[\"s\"][key]) {\n signatures[key] = graph[soul]._[\"s\"][key]\n }\n }\n }\n }\n }\n if (Object.keys(signatures).length > 0) {\n node._[\"s\"] = signatures\n }\n return {[soul]: node}\n}\n\nexport default Get\n", "if (typeof btoa === \"undefined\") {\n globalThis.btoa = data => Buffer.from(data, \"binary\").toString(\"base64\")\n globalThis.atob = data => Buffer.from(data, \"base64\").toString(\"binary\")\n}\n\n// This is Array extended to have .toString([\"utf8\"|\"hex\"|\"base64\"])\nfunction SeaArray() {}\nObject.assign(SeaArray, {from: Array.from})\nSeaArray.prototype = Object.create(Array.prototype)\n\nSeaArray.prototype.toString = function (enc, start, end) {\n if (!enc) enc = \"utf8\"\n if (!start) start = 0\n\n end = end ? Math.min(Math.max(end, start), this.length) : this.length\n\n if (enc === \"hex\") {\n const buf = new Uint8Array(this.slice(start, end))\n return Array.from(buf, byte => byte.toString(16).padStart(2, \"0\")).join(\"\")\n }\n\n if (enc === \"utf8\") {\n return Array.from({length: end - start}, (_, i) => {\n const charCode = this[i + start]\n // Use unicode replacement character for invalid character codes.\n if (charCode < 0 || charCode > 0x10ffff) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n }\n\n if (enc === \"base64\") {\n const utf8String = Array.from({length: end - start}, (_, i) => {\n const charCode = this[i + start]\n if (charCode < 0 || charCode > 255) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n return btoa(utf8String)\n }\n}\n\nexport default SeaArray\n", "import SeaArray from \"./array.js\"\n\n// Security constants\nconst SECURITY_LIMITS = {\n MAX_BUFFER_SIZE: 10 * 1024 * 1024, // 10MB limit\n MAX_STRING_LENGTH: 1024 * 1024, // 1MB string limit\n}\n\n// Secure Buffer implementation for SEA.js\n// Compatible with NodeJS safe-buffer but with enhanced security\nfunction SafeBuffer(...props) {\n console.warn(\"new SafeBuffer() is deprecated, please use SafeBuffer.from()\")\n return SafeBuffer.from(...props)\n}\n\nSafeBuffer.prototype = Object.create(Array.prototype)\n\n// Input validation helpers\nconst validateStringInput = (input, encoding) => {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string for encoding: \" + encoding)\n }\n\n if (input.length > SECURITY_LIMITS.MAX_STRING_LENGTH) {\n throw new RangeError(\n `String too large: ${input.length} > ${SECURITY_LIMITS.MAX_STRING_LENGTH}`,\n )\n }\n}\n\nconst validateBufferSize = (size, operation = \"buffer operation\") => {\n if (size > SECURITY_LIMITS.MAX_BUFFER_SIZE) {\n throw new RangeError(\n `Buffer size too large for ${operation}: ${size} > ${SECURITY_LIMITS.MAX_BUFFER_SIZE}`,\n )\n }\n}\n\n// Secure hex parsing\nconst parseHexString = hexString => {\n validateStringInput(hexString, \"hex\")\n\n // Remove any whitespace and convert to lowercase\n const cleanHex = hexString.replace(/\\s/g, \"\").toLowerCase()\n\n // Validate hex format: only 0-9, a-f characters\n if (!/^[0-9a-f]*$/.test(cleanHex)) {\n throw new TypeError(\"Invalid hex string: contains non-hex characters\")\n }\n\n // Must be even length\n if (cleanHex.length % 2 !== 0) {\n throw new TypeError(\"Invalid hex string: must have even length\")\n }\n\n if (cleanHex.length === 0) {\n return new Uint8Array(0)\n }\n\n validateBufferSize(cleanHex.length / 2, \"hex parsing\")\n\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n const hexByte = cleanHex.substr(i, 2)\n bytes[i / 2] = parseInt(hexByte, 16)\n }\n return bytes\n}\n\nconst encodeUtf8String = str => {\n validateStringInput(str, \"utf8\")\n\n try {\n // Use standard TextEncoder for proper UTF-8 encoding\n const encoder = new TextEncoder()\n const bytes = encoder.encode(str)\n\n validateBufferSize(bytes.length, \"UTF-8 encoding\")\n return bytes\n } catch (err) {\n throw new TypeError(\"Failed to encode UTF-8 string: \" + err.message)\n }\n}\n\nconst encodeBinaryString = str => {\n validateStringInput(str, \"binary\")\n\n validateBufferSize(str.length, \"binary encoding\")\n\n const bytes = new Uint8Array(str.length)\n for (let i = 0; i < str.length; i++) {\n const charCode = str.charCodeAt(i)\n\n // Binary strings should only contain bytes (0-255)\n if (charCode > 255) {\n throw new TypeError(\n `Invalid binary string: character at position ${i} exceeds byte range (${charCode} > 255)`,\n )\n }\n\n bytes[i] = charCode\n }\n return bytes\n}\n\n// Secure base64 decoding\nconst parseBase64String = base64String => {\n validateStringInput(base64String, \"base64\")\n\n // Remove any whitespace\n const cleanBase64 = base64String.replace(/\\s/g, \"\")\n\n // Validate base64 format\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\n throw new TypeError(\"Invalid base64 string: contains invalid characters\")\n }\n\n try {\n const decodedString = atob(cleanBase64)\n validateBufferSize(decodedString.length, \"base64 decoding\")\n\n const bytes = new Uint8Array(decodedString.length)\n for (let i = 0; i < decodedString.length; i++) {\n bytes[i] = decodedString.charCodeAt(i)\n }\n\n return bytes\n } catch (err) {\n throw new TypeError(\"Failed to decode base64 string: \" + err.message)\n }\n}\n\n// Secure array-like input processing\nconst processArrayLikeInput = input => {\n let bytes\n\n if (input instanceof ArrayBuffer) {\n validateBufferSize(input.byteLength, \"ArrayBuffer processing\")\n bytes = new Uint8Array(input)\n } else if (ArrayBuffer.isView(input)) {\n validateBufferSize(\n input.byteLength || input.length,\n \"TypedArray processing\",\n )\n bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength)\n } else if (Array.isArray(input)) {\n validateBufferSize(input.length, \"Array processing\")\n\n // Validate all array elements are valid byte values\n for (let i = 0; i < input.length; i++) {\n const val = input[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`,\n )\n }\n }\n\n bytes = new Uint8Array(input)\n } else if (\n typeof input === \"object\" &&\n input !== null &&\n typeof input.byteLength === \"number\"\n ) {\n // Handle ArrayBuffer from different contexts (e.g. jsdom)\n validateBufferSize(input.byteLength, \"ArrayBuffer-like processing\")\n bytes = new Uint8Array(input)\n } else if (\n typeof input === \"object\" &&\n input !== null &&\n typeof input.length === \"number\"\n ) {\n // Handle array-like objects\n validateBufferSize(input.length, \"array-like processing\")\n\n const arr = Array.from(input)\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`,\n )\n }\n }\n bytes = new Uint8Array(arr)\n } else {\n throw new TypeError(\"Unsupported input type: \" + typeof input)\n }\n\n return bytes\n}\n\nObject.assign(SafeBuffer, {\n from() {\n const argCount = arguments.length\n\n if (argCount === 0) {\n throw new TypeError(\"SafeBuffer.from() requires at least one argument\")\n }\n\n const input = arguments[0]\n\n if (input === null || input === undefined) {\n throw new TypeError(\"First argument must not be null or undefined\")\n }\n\n let bytes\n\n if (typeof input === \"string\") {\n const encoding = (arguments[1] || \"utf8\").toLowerCase()\n\n switch (encoding) {\n case \"hex\":\n bytes = parseHexString(input)\n break\n\n case \"utf8\":\n case \"utf-8\":\n bytes = encodeUtf8String(input)\n break\n\n case \"binary\":\n case \"latin1\":\n bytes = encodeBinaryString(input)\n break\n\n case \"base64\":\n bytes = parseBase64String(input)\n break\n\n case \"ascii\":\n // ASCII is subset of UTF-8, but validate range\n validateStringInput(input, \"ascii\")\n for (let i = 0; i < input.length; i++) {\n if (input.charCodeAt(i) > 127) {\n throw new TypeError(\n `Invalid ASCII character at position ${i}: ${input.charCodeAt(i)} > 127`,\n )\n }\n }\n bytes = encodeUtf8String(input) // Safe since ASCII is UTF-8 subset\n break\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n } else {\n bytes = processArrayLikeInput(input)\n }\n\n if (!bytes || bytes.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n try {\n return SeaArray.from(bytes)\n } catch (err) {\n throw new Error(\"Failed to create SafeBuffer: \" + err.message)\n }\n },\n\n alloc(length, fill = 0) {\n if (typeof length !== \"number\" || !Number.isInteger(length) || length < 0) {\n throw new TypeError(\"Length must be a non-negative integer\")\n }\n\n validateBufferSize(length, \"buffer allocation\")\n\n // Validate fill value\n if (typeof fill === \"number\") {\n if (fill < 0 || fill > 255 || !Number.isInteger(fill)) {\n throw new TypeError(\"Fill value must be an integer between 0 and 255\")\n }\n } else if (typeof fill === \"string\") {\n if (fill.length !== 1) {\n throw new TypeError(\"Fill string must be exactly one character\")\n }\n fill = fill.charCodeAt(0)\n if (fill > 255) {\n throw new TypeError(\"Fill character code must be <= 255\")\n }\n } else {\n throw new TypeError(\"Fill must be a number or single character string\")\n }\n\n try {\n const buffer = new Uint8Array(length)\n if (fill !== 0) {\n buffer.fill(fill)\n }\n return SeaArray.from(buffer)\n } catch (err) {\n throw new Error(\"Failed to allocate buffer: \" + err.message)\n }\n },\n\n concat(arr) {\n if (!Array.isArray(arr)) {\n throw new TypeError(\"First argument must be an array\")\n }\n\n if (arr.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n // Validate all array elements and calculate total size\n let totalLength = 0\n const validatedBuffers = []\n\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]\n\n if (!item) {\n throw new TypeError(`Array element at index ${i} is null or undefined`)\n }\n\n let bytes\n try {\n bytes = processArrayLikeInput(item)\n } catch (err) {\n throw new TypeError(\n `Invalid array element at index ${i}: ${err.message}`,\n )\n }\n\n totalLength += bytes.length\n validateBufferSize(totalLength, \"buffer concatenation\")\n\n validatedBuffers.push(bytes)\n }\n\n try {\n const result = new Uint8Array(totalLength)\n let offset = 0\n\n for (const buffer of validatedBuffers) {\n result.set(buffer, offset)\n offset += buffer.length\n }\n\n return SeaArray.from(result)\n } catch (err) {\n throw new Error(\"Failed to concatenate buffers: \" + err.message)\n }\n },\n\n // Helper method to check if object is SafeBuffer\n isBuffer(obj) {\n return (\n obj instanceof SeaArray ||\n (obj && typeof obj === \"object\" && obj.constructor === SafeBuffer)\n )\n },\n\n // Get byte length of string in specific encoding\n byteLength(string, encoding = \"utf8\") {\n if (typeof string !== \"string\") {\n throw new TypeError(\"First argument must be a string\")\n }\n\n switch (encoding.toLowerCase()) {\n case \"utf8\":\n case \"utf-8\":\n return new TextEncoder().encode(string).length\n\n case \"ascii\":\n case \"binary\":\n case \"latin1\":\n return string.length\n\n case \"base64\":\n const clean = string.replace(/\\s/g, \"\")\n return (\n Math.floor((clean.length * 3) / 4) - (clean.match(/=/g) || []).length\n )\n\n case \"hex\":\n return Math.floor(string.replace(/\\s/g, \"\").length / 2)\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n },\n})\n\nSafeBuffer.prototype.from = SafeBuffer.from\nSafeBuffer.prototype.toString = function (\n encoding = \"utf8\",\n start = 0,\n end = this.length,\n) {\n // Input validation\n if (typeof encoding !== \"string\") {\n throw new TypeError(\"Encoding must be a string\")\n }\n\n if (typeof start !== \"number\" || !Number.isInteger(start) || start < 0) {\n throw new TypeError(\"Start must be a non-negative integer\")\n }\n\n if (typeof end !== \"number\" || !Number.isInteger(end) || end < start) {\n throw new TypeError(\"End must be an integer >= start\")\n }\n\n // Delegate to SeaArray with validation\n try {\n return SeaArray.prototype.toString.call(this, encoding, start, end)\n } catch (err) {\n throw new Error(\"Failed to convert buffer to string: \" + err.message)\n }\n}\n\nexport default SafeBuffer\n", "import SafeBuffer from \"./buffer.js\"\n\nconst isNode = typeof document === \"undefined\"\nconst crypto = isNode\n ? (await import(/*webpackIgnore: true*/ \"node:crypto\")).webcrypto\n : globalThis.crypto\nexport const subtle = crypto.subtle\n\nexport const stringify = data => {\n return typeof data === \"string\" ? data : JSON.stringify(data)\n}\n\nexport const parse = text => {\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\nexport const random = length => {\n const array = new Uint8Array(SafeBuffer.alloc(length))\n return SafeBuffer.from(crypto.getRandomValues(array))\n}\n\nexport const jwk = (pub, priv) => {\n const [x, y] = pub.split(\".\")\n const ops = priv ? [\"sign\"] : [\"verify\"]\n return {\n kty: \"EC\",\n crv: \"P-256\",\n x: x,\n y: y,\n d: priv,\n ext: true,\n key_ops: ops,\n }\n}\n\nexport const sha256 = async data => {\n const hash = await subtle.digest(\n {name: \"SHA-256\"},\n new TextEncoder().encode(stringify(data)),\n )\n return SafeBuffer.from(hash)\n}\n\nexport const aeskey = async (key, salt) => {\n const combined = key + salt.toString(\"utf8\")\n const hash = SafeBuffer.from(await sha256(combined), \"binary\")\n const jwk = keyToJwk(hash)\n return await subtle.importKey(\"jwk\", jwk, {name: \"AES-GCM\"}, false, [\n \"encrypt\",\n \"decrypt\",\n ])\n}\n\nconst keyToJwk = key => {\n const k = key\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/\\=/g, \"\")\n return {kty: \"oct\", k: k, ext: false, alg: \"A256GCM\"}\n}\n", "import {userPublicKey, userSignature} from \"./utils.js\"\nimport * as utils from \"./sea-utils.js\"\nimport SafeBuffer from \"./buffer.js\"\n\n// Security, Encryption, and Authorization: SEA.js from GunDB.\nconst SEA = {\n pair: async cb => {\n // ECDSA keys for signing/verifying.\n const ecdsa = await utils.subtle\n .generateKey({name: \"ECDSA\", namedCurve: \"P-256\"}, true, [\n \"sign\",\n \"verify\",\n ])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n priv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d,\n pub: pub.x + \".\" + pub.y,\n }\n })\n\n // ECDH keys for encryption/decryption.\n const ecdh = await utils.subtle\n .generateKey({name: \"ECDH\", namedCurve: \"P-256\"}, true, [\"deriveKey\"])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n epriv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d,\n epub: pub.x + \".\" + pub.y,\n }\n })\n\n const pair = {\n pub: ecdsa.pub,\n priv: ecdsa.priv,\n epub: ecdh.epub,\n epriv: ecdh.epriv,\n }\n if (cb) cb(pair)\n return pair\n },\n encrypt: async (data, pair, cb) => {\n if (!pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const rand = {s: utils.random(9), iv: utils.random(15)}\n const ct = await utils.aeskey(pair.epriv, rand.s).then(aes => {\n return utils.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(rand.iv),\n },\n aes,\n new TextEncoder().encode(utils.stringify(data)),\n )\n })\n const enc = {\n ct: SafeBuffer.from(ct, \"binary\").toString(\"base64\"),\n iv: rand.iv.toString(\"base64\"),\n s: rand.s.toString(\"base64\"),\n }\n if (cb) cb(enc)\n return enc\n },\n decrypt: async (enc, pair, cb) => {\n if (!enc || !enc.ct || !enc.iv || !enc.s || !pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const data = {\n ct: SafeBuffer.from(enc.ct, \"base64\"),\n iv: SafeBuffer.from(enc.iv, \"base64\"),\n s: SafeBuffer.from(enc.s, \"base64\"),\n }\n try {\n const ct = await utils.aeskey(pair.epriv, data.s).then(aes => {\n return utils.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(data.iv),\n tagLength: 128,\n },\n aes,\n new Uint8Array(data.ct),\n )\n })\n const dec = utils.parse(new TextDecoder(\"utf8\").decode(ct))\n if (cb) cb(dec)\n return dec\n } catch (err) {\n // An error will be thrown if the wrong key is used.\n if (cb) cb(null)\n return null\n }\n },\n verify: async (data, pair, cb) => {\n if (!pair || !pair.pub) {\n if (cb) cb(null)\n return null\n }\n\n const signed = utils.parse(data)\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(pair.pub),\n {name: \"ECDSA\", namedCurve: \"P-256\"},\n false,\n [\"verify\"],\n )\n\n let msg = {}\n if (typeof signed.m === \"string\") {\n msg = signed.m\n } else {\n // Allow data to be passed in with graph meta data,\n // (which should not be part of signature, so not verified).\n for (const k of Object.keys(signed.m).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n msg[k] = signed.m[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const sig = new Uint8Array(SafeBuffer.from(signed.s, \"base64\"))\n const alg = {name: \"ECDSA\", hash: {name: \"SHA-256\"}}\n if (await utils.subtle.verify(alg, key, sig, new Uint8Array(hash))) {\n const verified = utils.parse(signed.m)\n if (cb) cb(verified)\n return verified\n }\n\n if (cb) cb(null)\n return null\n },\n sign: async (data, pair, cb) => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n let msg = {}\n if (typeof data === \"string\") {\n msg = data\n } else {\n const check = utils.parse(data)\n for (const k of Object.keys(check).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n msg[k] = check[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = {name: \"ECDSA\", namedCurve: \"P-256\"}\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n {name: \"ECDSA\", hash: {name: \"SHA-256\"}},\n key,\n new Uint8Array(hash),\n ),\n )\n const signed = {\n m: msg,\n s: SafeBuffer.from(sig, \"binary\").toString(\"base64\"),\n }\n\n if (cb) cb(signed)\n return signed\n },\n // Sign a timestamp to prove ownership of an update\n signTimestamp: async (timestamp, pair, cb) => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = {name: \"ECDSA\", namedCurve: \"P-256\"}\n\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n {name: \"ECDSA\", hash: {name: \"SHA-256\"}},\n key,\n new Uint8Array(hash),\n ),\n )\n\n const signature = SafeBuffer.from(sig, \"binary\").toString(\"base64\")\n\n if (cb) cb(signature)\n return signature\n },\n // Verify a timestamp signature to confirm ownership of update\n verifyTimestamp: async (timestamp, signature, publicKey, cb) => {\n if (!publicKey || !timestamp || !signature) {\n if (cb) cb(false)\n return false\n }\n\n try {\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(publicKey),\n {name: \"ECDSA\", namedCurve: \"P-256\"},\n false,\n [\"verify\"],\n )\n\n const sig = new Uint8Array(SafeBuffer.from(signature, \"base64\"))\n const alg = {name: \"ECDSA\", hash: {name: \"SHA-256\"}}\n\n const isValid = await utils.subtle.verify(\n alg,\n key,\n sig,\n new Uint8Array(hash),\n )\n\n if (cb) cb(isValid)\n return isValid\n } catch (err) {\n console.log(`error verifying timestamp signature: ${err.message}`)\n if (cb) cb(false)\n return false\n }\n },\n // Verify individual property signatures stored in node._[\"s\"]\n // Returns array of valid property names\n verifyProperties: async (node, pub, cb) => {\n if (!pub || !node) {\n if (cb) cb([])\n return []\n }\n\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(pub),\n {name: \"ECDSA\", namedCurve: \"P-256\"},\n false,\n [\"verify\"],\n )\n\n const alg = {name: \"ECDSA\", hash: {name: \"SHA-256\"}}\n const valid = []\n const propertySignatures = (node._ && node._[\"s\"]) || {}\n\n // Verify each property individually\n for (const k of Object.keys(node).sort()) {\n if (k === \"_\" || k == userPublicKey) continue\n\n const propSig = propertySignatures[k]\n if (!propSig) {\n continue\n }\n\n try {\n const hash = await utils.sha256(node[k])\n const sig = new Uint8Array(SafeBuffer.from(propSig, \"base64\"))\n\n const isValid = await utils.subtle.verify(\n alg,\n key,\n sig,\n new Uint8Array(hash),\n )\n if (isValid) {\n valid.push(k)\n } else {\n console.log(`warning: property '${k}' signature verification failed`)\n }\n } catch (err) {\n console.log(`warning: property '${k}' error verifying: ${err.message}`)\n }\n }\n\n if (cb) cb(valid)\n return valid\n },\n work: async (data, salt, cb) => {\n if (typeof salt === \"function\") {\n cb = salt\n salt = undefined\n }\n if (typeof salt === \"undefined\") salt = utils.random(9)\n\n const key = await utils.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(utils.stringify(data)),\n {name: \"PBKDF2\"},\n false,\n [\"deriveBits\"],\n )\n const alg = {\n name: \"PBKDF2\",\n iterations: 100000,\n salt: new TextEncoder().encode(salt),\n hash: {name: \"SHA-256\"},\n }\n const work = await utils.subtle.deriveBits(alg, key, 512)\n // Use \"pair\" format so that work can be used as epriv by decrypt.\n const pair = {epriv: SafeBuffer.from(work, \"binary\").toString(\"base64\")}\n if (cb) cb(pair)\n return pair\n },\n secret: async (to, from, cb) => {\n if (!to || !to.epub || !from || !from.epub || !from.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const alg = {name: \"ECDH\", namedCurve: \"P-256\"}\n const pub = utils.jwk(to.epub)\n const pubKey = await utils.subtle.importKey(\"jwk\", pub, alg, true, [])\n const priv = utils.jwk(from.epub, from.epriv, false)\n // utils.jwk provides default key_ops but it shouldn't be used here.\n delete priv.key_ops\n const derived = await utils.subtle\n .importKey(\"jwk\", priv, alg, false, [\"deriveBits\"])\n .then(async key => {\n const derivedBits = await utils.subtle.deriveBits(\n {public: pubKey, name: \"ECDH\", namedCurve: \"P-256\"},\n key,\n 256,\n )\n const derivedKey = await utils.subtle.importKey(\n \"raw\",\n new Uint8Array(derivedBits),\n {name: \"AES-GCM\", length: 256},\n true,\n [\"encrypt\", \"decrypt\"],\n )\n return utils.subtle.exportKey(\"jwk\", derivedKey).then(({k}) => k)\n })\n // Use \"pair\" format so that secret can be used as epriv by encrypt.\n if (cb) cb({epriv: derived})\n return {epriv: derived}\n },\n}\n\nexport default SEA\n", "import * as utils from \"./utils.js\"\nimport SEA from \"./sea.js\"\n\n// Maximum number of souls to keep in memory\nconst MAX_GRAPH_SIZE = 10000\n\n// state and value are the incoming changes.\n// currentState and currentValue are the current graph data.\nconst Ham = (state, currentState, value, currentValue, signed = false) => {\n if (state < currentState) return {historical: true}\n\n if (state > currentState) return {incoming: true}\n\n // state is equal to currentState. Old data is expected to propagate through\n // the network, but conflicting values with same signed timestamp are ignored\n // since the owner can only create one value per timestamp.\n if (signed && value !== currentValue) {\n return {historical: true}\n }\n\n // Lexically compare to resolve conflict (for unsigned or matching values)\n if (typeof value !== \"string\") {\n value = JSON.stringify(value) || \"\"\n }\n if (typeof currentValue !== \"string\") {\n currentValue = JSON.stringify(currentValue) || \"\"\n }\n // No update required.\n if (value === currentValue) return {state: true}\n\n // Keep the current value.\n if (value < currentValue) return {current: true}\n\n // Otherwise update using the incoming value.\n return {incoming: true}\n}\n\nHam.mix = async (change, graph, secure, listen) => {\n if (!change || typeof change !== \"object\") {\n throw new TypeError(\"change must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n if (!listen || typeof listen !== \"object\") {\n throw new TypeError(\"listen must be an object\")\n }\n\n const machine = Date.now()\n const now = {}\n const defer = {}\n const listeners = [] // Collect listeners to fire after store.put\n const validProperties = new Map() // Track valid properties per soul\n const validTimestamps = new Map() // Track valid timestamps per soul\n let wait = 0\n\n for (const soul of Object.keys(change)) {\n const node = change[soul]\n let updated = false\n let alias = false\n let nodeWait = 0\n let verify = secure\n\n if (!node || !node._) continue\n\n const pub = node[utils.userPublicKey]\n // If timestamp signatures and public key are provided then always verify\n if (node._[\"s\"] && pub) verify = true\n\n // Special case if soul starts with \"~\". Node must be system data ie,\n // ~@alias or ~publickey. For aliases, key and value must be a self\n // identifying rel. For public keys, data needs to be signed and verified.\n // (This is also true for any data when the secure flag is used.)\n if (soul.length > 1 && soul[0] === \"~\") {\n if (soul[1] === \"@\") {\n alias = true\n verify = false\n } else {\n if (pub && soul != \"~\" + pub) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n\n verify = true\n }\n }\n if (verify) {\n // Signature verification: check node._[\"s\"] which can contain:\n // 1. Per-property signatures (legacy): keys are property names\n // 2. Timestamp signatures (new): keys are numeric timestamps\n if (!pub || !node._) {\n continue\n }\n\n const signedTimestamps = new Set()\n const signedProperties = new Set()\n\n // Skip verification of timestamps that are older than what's in the graph\n // to prevent old signatures from distributed messages causing conflicts\n const incomingTimestamps = Object.entries(node._[\">\"] || {})\n\n for (const [key, sig] of Object.entries(node._[\"s\"] || {})) {\n const asNumber = Number(key)\n if (!isNaN(asNumber) && asNumber > 0) {\n // Check if this timestamp is for properties that already have newer\n // versions in graph.\n const hasNewerInGraph = incomingTimestamps.some(([prop, ts]) => {\n if (Number(ts) === asNumber) {\n const graphState =\n graph[soul] && graph[soul]._[\">\"] ? graph[soul]._[\">\"][prop] : 0\n // Skip verification if graph has a newer timestamp for property.\n if (graphState > asNumber) {\n return true\n }\n }\n return false\n })\n\n if (hasNewerInGraph) {\n continue\n }\n\n const isValid = await SEA.verifyTimestamp(asNumber, sig, pub)\n if (isValid) {\n signedTimestamps.add(asNumber)\n // Add all properties with this timestamp to signed set\n for (const [prop, ts] of incomingTimestamps) {\n if (Number(ts) === asNumber) {\n signedProperties.add(prop)\n }\n }\n }\n }\n }\n\n // TODO: Remove per-property signature verification after old data has\n // been cleared. Only check per-property signatures if there are\n // properties without timestamp signatures.\n const propertiesWithoutTimestampSigs = Object.keys(node).filter(k => {\n if (k === \"_\" || k === utils.userPublicKey) return false\n return !incomingTimestamps.some(\n ([prop, ts]) => prop === k && signedTimestamps.has(Number(ts)),\n )\n })\n\n if (propertiesWithoutTimestampSigs.length > 0) {\n const nodeToVerify = {_: node._}\n for (const prop of propertiesWithoutTimestampSigs) {\n nodeToVerify[prop] = node[prop]\n }\n const perPropertySignedProps = await SEA.verifyProperties(\n nodeToVerify,\n pub,\n )\n perPropertySignedProps.forEach(prop => signedProperties.add(prop))\n }\n\n // If no properties verified, skip this update\n if (signedProperties.size === 0) {\n continue\n }\n\n // Track signed properties and timestamps for this soul\n validProperties.set(soul, signedProperties)\n validTimestamps.set(soul, signedTimestamps)\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n // Properties without signatures in this update are left unchanged\n if (validProperties.has(soul) && !validProperties.get(soul).has(key)) {\n continue\n }\n\n const value = node[key]\n const state = node._ && node._[\">\"] ? node._[\">\"][key] : 0\n const currentValue = (graph[soul] || {})[key]\n const currentState = (graph[soul] || {_: {\">\": {}}})._[\">\"][key] || 0\n\n if (alias && key !== utils.rel.is(value)) {\n console.log(`error alias ${alias}: ${key} !== ${utils.rel.is(value)}`)\n continue\n }\n\n // Defer the update if ahead of machine time.\n const skew = state - machine\n if (skew > 0) {\n // Ignore update if ahead by more than 24 hours.\n if (skew > 86400000) continue\n\n // Wait the shortest difference before trying the updates again.\n if (wait === 0 || skew < wait) wait = nodeWait = skew\n if (!defer[soul]) {\n defer[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n defer[soul][key] = value\n defer[soul]._[\">\"][key] = state\n if (node._[\"s\"]) {\n if (node._[\"s\"][state]) {\n defer[soul]._[\"s\"][state] = node._[\"s\"][state]\n } else if (node._[\"s\"][key]) {\n defer[soul]._[\"s\"][key] = node._[\"s\"][key]\n }\n }\n } else {\n // Check if this property has a signed timestamp\n const isSigned =\n validTimestamps.has(soul) && validTimestamps.get(soul).has(state)\n const result = Ham(state, currentState, value, currentValue, isSigned)\n if (result.incoming) {\n if (!now[soul]) {\n now[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n if (!graph[soul]) {\n graph[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n graph[soul][key] = now[soul][key] = value\n graph[soul]._[\">\"][key] = now[soul]._[\">\"][key] = state\n if (node._[\"s\"]) {\n if (node._[\"s\"][state]) {\n graph[soul]._[\"s\"][state] = now[soul]._[\"s\"][state] =\n node._[\"s\"][state]\n } else if (node._[\"s\"][key]) {\n graph[soul]._[\"s\"][key] = now[soul]._[\"s\"][key] = node._[\"s\"][key]\n }\n }\n // Collect event listeners to fire after store.put completes.\n // This ensures listeners always fire with data that's been stored.\n if (listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => listeners.push(l.cb))\n }\n updated = true\n }\n }\n }\n\n // Collect event listeners for update on soul.\n if (updated && listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"]))\n .forEach(l => listeners.push(l.cb))\n }\n }\n\n const souls = Object.keys(graph)\n if (souls.length > MAX_GRAPH_SIZE) {\n // Sort by oldest state timestamp and remove oldest entries\n const soulsByAge = souls\n .map(soul => {\n const states = graph[soul]._ && graph[soul]._[\">\"]\n const maxState = states ? Math.max(...Object.values(states)) : 0\n return {soul, maxState}\n })\n .sort((a, b) => a.maxState - b.maxState)\n const remove = soulsByAge.slice(0, souls.length - MAX_GRAPH_SIZE)\n remove.forEach(({soul}) => delete graph[soul])\n }\n\n return {now: now, defer: defer, wait: wait, listeners: listeners}\n}\n\nexport default Ham\n", "import * as utils from \"./utils.js\"\n\n// ASCII character for group separator.\nconst group = String.fromCharCode(29)\n// ASCII character for record separator.\nconst record = String.fromCharCode(30)\n\nconst Radix = () => {\n const radix = (keys, value, tree) => {\n if (!tree) {\n if (!radix[group]) radix[group] = {}\n tree = radix[group]\n }\n if (!keys) return tree\n\n let i = 0\n let tmp = {}\n let key = keys[i]\n const max = keys.length - 1\n const noValue = typeof value === \"undefined\"\n // Find a matching value using the shortest string from keys.\n let found = tree[key]\n while (!found && i < max) {\n key += keys[++i]\n found = tree[key]\n }\n\n if (!found) {\n // If not found from the provided keys try matching with an existing key.\n const result = utils.obj.map(tree, (hasValue, hasKey) => {\n let j = 0\n let matchingKey = \"\"\n while (hasKey[j] === keys[j]) {\n matchingKey += hasKey[j++]\n }\n if (matchingKey) {\n if (noValue) {\n // matchingKey has to be as long as the original keys when reading.\n if (j <= max) return\n\n tmp[hasKey.slice(j)] = hasValue\n return hasValue\n }\n\n let replace = {\n [hasKey.slice(j)]: hasValue,\n [keys.slice(j)]: {[record]: value},\n }\n tree[matchingKey] = {[group]: replace}\n delete tree[hasKey]\n return true\n }\n })\n if (!result) {\n if (noValue) return\n\n if (!tree[key]) tree[key] = {}\n tree[key][record] = value\n } else if (noValue) {\n return tmp\n }\n } else if (i === max) {\n // If no value use the key provided to return a whole group or record.\n if (noValue) {\n // If an individual record isn't found then return the whole group.\n return typeof found[record] === \"undefined\"\n ? found[group]\n : found[record]\n }\n // Otherwise create a new record at the provided key for value.\n found[record] = value\n } else {\n // Found at a shorter key, try again.\n if (!found[group] && !noValue) found[group] = {}\n return radix(keys.slice(++i), value, found[group])\n }\n }\n return radix\n}\n\nRadix.map = function map(radix, cb, opt, pre) {\n if (!pre) pre = []\n var tree = radix[group] || radix\n var keys = Object.keys(tree).sort()\n var u\n\n for (let i = 0; i < keys.length; i++) {\n let key = keys[i]\n let found = tree[key]\n let tmp = found[record]\n if (typeof tmp !== \"undefined\") {\n tmp = cb(tmp, pre.join(\"\") + key, key, pre)\n if (typeof tmp !== \"undefined\") return tmp\n } else if (opt) {\n cb(u, pre.join(\"\"), key, pre)\n }\n if (found[group]) {\n pre.push(key)\n tmp = map(found[group], cb, opt, pre)\n if (typeof tmp !== \"undefined\") return tmp\n pre.pop()\n }\n }\n}\n\nexport default Radix\n", "import Radix from \"./radix.js\"\nimport * as utils from \"./utils.js\"\n\n// ASCII character for end of text\nconst etx = String.fromCharCode(3)\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n\n// Radisk provides access to a radix tree that is stored in the provided\n// opt.store interface\nconst Radisk = opt => {\n var u\n\n // Multi-file cache for all parsed radix trees\n const cache = new Map()\n // File listing cache to avoid repeated directory scans\n let fileListCache = null\n let fileListCacheTime = 0\n const FILE_LIST_CACHE_TTL = 10000 // 10 seconds\n // Pending reads queue to avoid duplicate reads for the same key\n const pendingReads = new Map()\n\n // Memory monitoring and cleanup\n let lastMemoryCheck = 0\n const MEMORY_CHECK_INTERVAL = 30000 // Check every 30 seconds\n const HEAP_WARNING_THRESHOLD = 0.8 // Warn at 80% of max heap size\n const HEAP_CLEANUP_THRESHOLD = 0.9 // Clean cache at 90% of max heap size\n\n if (!opt) opt = {}\n if (!opt.log) opt.log = console.log\n if (!opt.batch) opt.batch = 100 // Balanced batch size for performance\n if (!opt.write) opt.write = 1 // Wait time before write in milliseconds\n if (!opt.size) opt.size = 1024 * 1024 // File size on disk, default 1MB\n if (!opt.memoryLimit) opt.memoryLimit = 500 // Memory limit in MB\n if (!opt.readTimeout) opt.readTimeout = 1000 // Read timeout in milliseconds\n if (typeof opt.cache === \"undefined\") opt.cache = true\n\n if (!opt.store) {\n opt.log(\n \"Radisk needs `store` interface with `{get: fn, put: fn, list: fn}`\",\n )\n return\n }\n if (!opt.store.get) {\n opt.log(\"Radisk needs `store.get` interface with `(file, cb)`\")\n return\n }\n if (!opt.store.put) {\n opt.log(\"Radisk needs `store.put` interface with `(file, data, cb)`\")\n return\n }\n if (!opt.store.list) {\n opt.log(\"Radisk needs a streaming `store.list` interface with `(cb)`\")\n return\n }\n\n // Performance logging\n const perfLog = (operation, startTime, key, size) => {\n const duration = Date.now() - startTime\n if (duration > 2000) {\n console.log(\n `[RADISK-SLOW] ${operation}: ${duration}ms for ${key}${size ? ` (${size} bytes)` : \"\"}`,\n )\n }\n }\n\n // Memory monitoring and cache cleanup\n const checkMemoryUsage = () => {\n if (typeof process === \"undefined\" || !process.memoryUsage) return\n\n const now = Date.now()\n if (now - lastMemoryCheck < MEMORY_CHECK_INTERVAL) return\n lastMemoryCheck = now\n\n const memUsage = process.memoryUsage()\n const heapUsed = memUsage.heapUsed\n const heapTotal = memUsage.heapTotal\n const maxHeapSize = opt.memoryLimit * 1024 * 1024\n const heapUsageRatio = heapUsed / maxHeapSize\n\n if (heapUsageRatio > HEAP_CLEANUP_THRESHOLD) {\n const cacheSize = cache.size\n console.log(\n `[RADISK-MEMORY] High memory usage: ${Math.round(heapUsageRatio * 100)}% of heap limit. Clearing ${cacheSize} cached files.`,\n )\n cache.clear()\n // Force garbage collection if available\n if (global.gc) {\n global.gc()\n }\n // Reset timer to avoid immediate re-check until GC has time to work\n lastMemoryCheck = now + MEMORY_CHECK_INTERVAL\n } else if (heapUsageRatio > HEAP_WARNING_THRESHOLD) {\n console.log(\n `[RADISK-MEMORY] Memory warning: ${Math.round(heapUsageRatio * 100)}% of heap limit used. Cache size: ${cache.size} files.`,\n )\n }\n }\n\n // Any and all storage adapters should:\n // 1. Because writing to disk takes time, we should batch data to disk.\n // This improves performance, and reduces potential disk corruption.\n // 2. If a batch exceeds a certain number of writes, we should immediately\n // write to disk when physically possible. This caps total performance,\n // but reduces potential loss.\n const radisk = (key, value, cb) => {\n key = \"\" + key\n\n // If no value is provided then the second parameter is the callback\n // function. Read value from memory or disk and call callback with it.\n if (typeof value === \"function\") {\n cb = value\n value = radisk.batch(key)\n if (typeof value !== \"undefined\") {\n return cb(u, value)\n }\n\n if (radisk.thrash.at) {\n value = radisk.thrash.at(key)\n if (typeof value !== \"undefined\") {\n return cb(u, value)\n }\n }\n\n // Check if there's already a pending read for this key\n if (pendingReads.has(key)) {\n // Add callback to existing pending read\n pendingReads.get(key).callbacks.push(cb)\n return\n }\n\n // Start new read and create callback queue with fired flag\n const pending = {callbacks: [cb], fired: false, timeoutId: null}\n pendingReads.set(key, pending)\n\n // Set a timeout to fire callbacks if read takes too long\n pending.timeoutId = setTimeout(() => {\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n const err = new Error(\"radisk read timeout\")\n pending.callbacks.forEach(callback => callback(err, undefined))\n }\n }, opt.readTimeout)\n\n const readStart = Date.now()\n return radisk.read(key, (err, result) => {\n clearTimeout(pending.timeoutId)\n perfLog(\"read\", readStart, key)\n // Execute all pending callbacks for this key if timeout hasn't fired\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n pending.callbacks.forEach(callback => callback(err, result))\n }\n })\n }\n\n // Otherwise store the value provided.\n radisk.batch(key, value)\n // Check memory usage after writing to in-memory radix tree\n checkMemoryUsage()\n if (cb) {\n radisk.batch.acks.push(cb)\n }\n // Don't wait if we have batched too many.\n if (++radisk.batch.ed >= opt.batch) {\n return radisk.thrash()\n }\n\n // Otherwise wait for more updates before writing.\n clearTimeout(radisk.batch.timeout)\n radisk.batch.timeout = setTimeout(radisk.thrash, opt.write)\n }\n\n radisk.batch = Radix()\n radisk.batch.acks = []\n radisk.batch.ed = 0\n\n radisk.thrash = () => {\n if (radisk.thrash.ing) {\n return (radisk.thrash.more = true)\n }\n\n const thrashStart = Date.now()\n clearTimeout(radisk.batch.timeout)\n radisk.thrash.more = false\n radisk.thrash.ing = true\n var batch = (radisk.thrash.at = radisk.batch)\n radisk.batch = null\n radisk.batch = Radix()\n radisk.batch.acks = []\n radisk.batch.ed = 0\n let i = 0\n radisk.save(batch, err => {\n // This is to ignore multiple callbacks from radisk.save calling\n // radisk.write? It looks like multiple callbacks will be made if a\n // file needs to be split.\n if (++i > 1) return\n\n perfLog(\"thrash\", thrashStart, `batch-${batch.ed}`)\n if (err) opt.log(err)\n batch.acks.forEach(cb => cb(err))\n radisk.thrash.at = null\n radisk.thrash.ing = false\n if (radisk.thrash.more) radisk.thrash()\n })\n }\n\n // 1. Find the first radix item in memory\n // 2. Use that as the starting index in the directory of files\n // 3. Find the first file that is lexically larger than it\n // 4. Read the previous file into memory\n // 5. Scan through in memory radix for all values lexically less than limit\n // 6. Merge and write all of those to the in-memory file and back to disk\n radisk.save = (rad, cb) => {\n const save = {\n find: (tree, key) => {\n // This is false for any key until save.start is set to an initial key.\n if (key < save.start) return\n\n save.start = key\n opt.store.list(save.lex)\n return true\n },\n lex: file => {\n if (!file || file > save.start) {\n save.end = file\n // ! is used as the first file name as it's the first printable\n // character, so always matches as lexically less than any node.\n // Also save.start can be set to undefined by a previous call to\n // save.mix, so don't continue in this case.\n if (save.start) save.mix(save.file || \"!\", save.start, save.end)\n } else {\n save.file = file\n }\n },\n mix: (file, start, end) => {\n save.start = save.end = save.file = u\n // Use cache if available, otherwise parse from disk\n if (cache.has(file)) {\n const disk = cache.get(file)\n Radix.map(rad, (value, key) => {\n if (key < start) return\n\n if (end && end < key) {\n save.start = key\n return\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\n } else {\n radisk.parse(file, (err, disk) => {\n if (err) return cb(err)\n\n Radix.map(rad, (value, key) => {\n if (key < start) return\n\n if (end && end < key) {\n save.start = key\n return\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\n })\n }\n },\n next: err => {\n if (err) return cb(err)\n\n if (save.start) return Radix.map(rad, save.find)\n\n cb(err)\n },\n }\n Radix.map(rad, save.find)\n }\n\n radisk.write = (file, rad, cb) => {\n const write = {\n text: \"\",\n limit: \"\",\n done: false,\n count: 0,\n each: (value, key, k, pre) => {\n // each is called for all keys, but stop adding to write.text when\n // write.slice is called, then the current contents of write.text\n // will be written to file.\n if (write.done) return\n\n write.count++\n value = typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)\n const enc =\n Radisk.encode(pre.length) + \"#\" + Radisk.encode(k) + value + \"\\n\"\n // Cannot split the file if only have one entry to write. Also don't\n // start a split if in the middle of writing a node (pre > 0).\n if (\n write.count > 1 &&\n pre.length === 0 &&\n write.text.length + enc.length > opt.size\n ) {\n const end = k.indexOf(enq)\n write.limit = end === -1 ? k : k.substring(0, end)\n // Cannot split if they key is the same as the current file name.\n if (write.limit !== file) {\n write.done = true\n write.sub = Radix()\n Radix.map(rad, write.slice)\n radisk.write(write.limit, write.sub, cb)\n return\n }\n }\n\n write.text += enc\n },\n slice: (value, key) => {\n if (key < write.limit) return\n\n write.sub(key, value)\n },\n }\n Radix.map(rad, write.each, true)\n // There is always accumulated write.text to store once write.each has\n // finished.\n const writeStart = Date.now()\n opt.store.put(file, write.text, err => {\n perfLog(\"file-write\", writeStart, file, write.text.length)\n cb(err)\n })\n }\n\n radisk.read = (key, cb) => {\n // Only the soul of the key is compared to filenames (see radisk.write).\n const end = key.indexOf(enq)\n const soul = end === -1 ? key : key.substring(0, end)\n\n const read = {\n lex: file => {\n // store.list should call lex without a file last, which means all file\n // names were compared to soul, so the current read.file is ok to use.\n if (!file) {\n if (!read.file) {\n cb(\"no file found\", u)\n return\n }\n\n // Check multi-file cache first\n if (opt.cache && cache.has(read.file)) {\n const cachedRadix = cache.get(read.file)\n read.value = cachedRadix(key)\n // Return cached result (defined or undefined) since in-memory\n // radix tree is authoritative\n return cb(u, read.value)\n }\n\n radisk.parse(read.file, read.it)\n return\n }\n\n // Want the filename closest to soul.\n if (file > soul || file < read.file) return\n\n read.file = file\n },\n it: (err, disk) => {\n if (err) opt.log(err)\n if (disk) {\n if (opt.cache) {\n cache.set(read.file, disk)\n checkMemoryUsage() // Check memory usage after adding to cache\n }\n read.value = disk(key)\n }\n cb(err, read.value)\n },\n }\n const now = Date.now()\n if (\n opt.cache &&\n fileListCache &&\n now - fileListCacheTime < FILE_LIST_CACHE_TTL\n ) {\n // Use cached file list\n fileListCache.forEach(file => read.lex(file))\n read.lex() // Signal end of list\n } else {\n // Refresh cache\n const files = []\n const originalLex = read.lex\n read.lex = file => {\n if (file) files.push(file)\n return originalLex(file)\n }\n\n opt.store.list(file => {\n read.lex(file)\n if (!file && opt.cache) {\n // End of list - cache the results\n fileListCache = files\n fileListCacheTime = now\n }\n })\n }\n }\n\n // Let us start by assuming we are the only process that is\n // changing the directory or bucket. Not because we do not want\n // to be multi-process/machine, but because we want to experiment\n // with how much performance and scale we can get out of only one.\n // Then we can work on the harder problem of being multi-process.\n radisk.parse = (file, cb) => {\n const parse = {\n disk: Radix(),\n read: (err, data) => {\n if (err) return cb(err)\n\n if (!data) return cb(u, parse.disk)\n\n let pre = []\n let preString = \"\"\n // Work though data by splitting into 3 values. The first value says\n // if the second value is one of: the radix level for a key, the key\n // iteself, or a value. The third is the rest of the data to work with.\n let tmp = parse.split(data)\n while (tmp) {\n let key\n let value\n let i = tmp[1]\n tmp = parse.split(tmp[2]) || \"\"\n if (tmp[0] === \"#\") {\n key = tmp[1]\n // Optimize prefix building - avoid repeated joins\n if (i < pre.length) {\n pre.length = i\n }\n if (i <= pre.length) {\n pre[i] = key\n pre.length = i + 1\n }\n // Only rebuild preString when prefix changes\n preString = pre.join(\"\")\n }\n tmp = parse.split(tmp[2]) || \"\"\n if (tmp[0] === \"\\n\") continue\n\n if (tmp[0] === \"=\") value = tmp[1]\n if (typeof key !== \"undefined\" && typeof value !== \"undefined\") {\n parse.disk(preString, value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(u, parse.disk)\n },\n split: data => {\n if (!data) return\n\n const i = data.indexOf(unit)\n if (i === -1) return\n\n const a = data.slice(0, i)\n let o = {}\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i)]\n },\n }\n opt.store.get(file, parse.read)\n }\n\n return radisk\n}\n\nRadisk.encode = data => {\n // A key should be passed in as a string to encode, a value can optionally be\n // an array of 2-3 items: [value, state] or [value, state, signature].\n let state = \"\"\n let sig = \"\"\n if (data instanceof Array && (data.length === 2 || data.length === 3)) {\n state = etx + data[1]\n if (data.length === 3 && data[2]) {\n sig = etx + data[2]\n }\n data = data[0]\n }\n\n if (typeof data === \"string\") {\n let i = 0\n let current = null\n let text = unit\n while ((current = data[i++])) {\n if (current === unit) text += unit\n }\n return text + '\"' + data + state + sig + unit\n }\n\n const rel = utils.rel.is(data)\n if (rel) return unit + \"#\" + rel + state + sig + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + sig + unit\n\n if (data === true) return unit + \"+\" + state + sig + unit\n\n if (data === false) return unit + \"-\" + state + sig + unit\n\n if (data === null) return unit + \" \" + state + sig + unit\n}\n\nRadisk.decode = (data, obj) => {\n var i = -1\n var n = 0\n var current = null\n var previous = null\n var textStart = -1\n var textEnd = -1\n if (data[0] !== unit) return\n\n // Find a control character previous to the text we want, skipping\n // consecutive unit separator characters at the beginning of the data.\n while ((current = data[++i])) {\n if (previous) {\n if (textStart === -1) textStart = i\n if (current === unit) {\n if (--n <= 0) {\n textEnd = i\n break\n }\n }\n } else if (current === unit) {\n n++\n } else {\n previous = current || true\n }\n }\n\n const text =\n textStart !== -1 ? data.slice(textStart, textEnd !== -1 ? textEnd : i) : \"\"\n\n if (obj) obj.i = i + 1\n\n let parts = text.split(etx)\n let value = parts[0]\n let state = parts[1]\n let sig = parts[2]\n\n if (!state) {\n if (previous === '\"') return text\n\n if (previous === \"#\") return utils.rel.ify(text)\n\n if (previous === \"+\") {\n if (text.length === 0) return true\n\n return parseFloat(text)\n }\n\n if (previous === \"-\") return false\n\n if (previous === \" \") return null\n } else {\n state = parseFloat(state)\n // If state was found then return an array with [value, state] or [value, state, sig]\n if (sig) {\n if (previous === '\"') return [value, state, sig]\n\n if (previous === \"#\") return [utils.rel.ify(value), state, sig]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, state, sig]\n\n return [parseFloat(value), state, sig]\n }\n\n if (previous === \"-\") return [false, state, sig]\n\n if (previous === \" \") return [null, state, sig]\n } else {\n if (previous === '\"') return [value, state]\n\n if (previous === \"#\") return [utils.rel.ify(value), state]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, state]\n\n return [parseFloat(value), state]\n }\n\n if (previous === \"-\") return [false, state]\n\n if (previous === \" \") return [null, state]\n }\n }\n}\n\nexport default Radisk\n", "import Radisk from \"./radisk.js\"\nimport Radix from \"./radix.js\"\nimport * as utils from \"./utils.js\"\n\nconst isNode = typeof document === \"undefined\"\nconst fs = isNode ? await import(/*webpackIgnore: true*/ \"node:fs\") : undefined\n\n// ASCII character for enquiry.\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator.\nconst unit = String.fromCharCode(31)\n// On-disk root node format.\nconst root = unit + \"+0\" + unit + \"#\" + unit + '\"root' + unit\n\nconst fileSystem = opt => {\n const dir = opt.file\n\n if (isNode) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir)\n if (!fs.existsSync(dir + \"/!\")) fs.writeFileSync(dir + \"/!\", root)\n\n return {\n get: (file, cb) => {\n fs.readFile(dir + \"/\" + file, (err, data) => {\n if (err) {\n if (err.code === \"ENOENT\") {\n cb()\n return\n }\n\n console.log(\"fs.readFile error:\", err)\n }\n if (data) data = data.toString()\n cb(err, data)\n })\n },\n put: (file, data, cb) => {\n // Don't put tmp files under dir so that they're not listed.\n var tmp = file + \".\" + utils.text.random(9) + \".tmp\"\n fs.writeFile(tmp, data, err => {\n if (err) {\n console.log(\"fs.writeFile error:\", err)\n cb(err)\n return\n }\n\n fs.rename(tmp, dir + \"/\" + file, cb)\n })\n },\n list: cb => {\n fs.readdir(dir, (err, files) => {\n if (err) {\n console.log(\"fs.readdir error:\", err)\n cb()\n return\n }\n\n files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db\n const dbReady = new Promise((resolve, reject) => {\n const o = indexedDB.open(dir, 1)\n o.onupgradeneeded = event => {\n event.target.result.createObjectStore(dir)\n }\n o.onerror = event => {\n console.log(event)\n reject(event)\n }\n o.onsuccess = () => {\n db = o.result\n // Create the root node if it doesn't exist.\n if (db) {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getKey(\"!\")\n req.onerror = () => {\n console.log(`error getting key ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n if (!req.result) {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(root, \"!\")\n req.onerror = () => {\n console.log(`error putting root on ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n resolve()\n }\n } else {\n resolve()\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n reject(new Error(\"indexedDB not available\"))\n }\n }\n })\n\n return {\n get: (file, cb) => {\n const _get = (file, cb) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).get(file)\n req.onerror = () => {\n console.log(`error getting ${dir}/${file}`)\n }\n req.onsuccess = () => {\n cb(null, req.result)\n }\n }\n\n dbReady\n .then(() => {\n _get(file, cb)\n })\n .catch(err => {\n cb(err)\n })\n },\n put: (file, data, cb) => {\n const _put = (file, data, cb) => {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(data, file)\n req.onerror = () => {\n console.log(`error putting data on ${dir}/${file}`)\n }\n req.onsuccess = () => {\n cb(null)\n }\n }\n\n dbReady\n .then(() => {\n _put(file, data, cb)\n })\n .catch(err => {\n cb(err)\n })\n },\n list: cb => {\n const _list = cb => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getAllKeys()\n req.onerror = () => console.log(\"error getting keys for\", dir)\n req.onsuccess = () => {\n req.result.forEach(cb)\n cb()\n }\n }\n\n dbReady\n .then(() => {\n _list(cb)\n })\n .catch(err => {\n console.log(\"error indexedDB not available:\", err)\n cb()\n })\n },\n }\n }\n\n // No browser storage.\n return {\n get: (file, cb) => {\n cb(null, root)\n },\n put: (file, data, cb) => {\n cb(null)\n },\n list: cb => {\n cb(\"!\")\n cb()\n },\n }\n}\n\n// Store provides get and put methods that can access radisk.\nconst Store = opt => {\n if (!utils.obj.is(opt)) opt = {}\n opt.file = String(opt.file || \"radata\")\n if (!opt.store) opt.store = fileSystem(opt)\n const radisk = Radisk(opt)\n\n return {\n get: (lex, cb, _opt) => {\n if (!lex || !utils.obj.is(lex)) {\n cb(\"lex required\")\n return\n }\n if (!lex[\"#\"]) {\n cb(\"soul required in lex\")\n return\n }\n\n if (!_opt) _opt = {}\n\n var soul = lex[\"#\"]\n var key = !_opt.secure && typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n var node\n var signatures = {}\n const each = (value, key) => {\n // Always include userPublicKey for verification, regardless of filter\n if (key !== utils.userPublicKey && !utils.match(lex[\".\"], key)) return\n\n if (!node) node = {_: {\"#\": soul, \">\": {}}}\n node[key] = value[0]\n node._[\">\"][key] = value[1]\n // If signature is present, store it in _[\"s\"]\n if (value.length === 3 && value[2]) {\n const state = value[1]\n // Store signature under both state and key for compatibility\n signatures[state] = value[2]\n // TODO: Can probably remove the following when old data is no\n // longer a problem.\n signatures[key] = value[2]\n }\n }\n\n radisk(soul + enq + key, (err, value) => {\n let graph\n if (utils.obj.is(value)) {\n Radix.map(value, each)\n if (!node) each(value, key)\n graph = {[soul]: node}\n } else if (value) {\n each(value, key)\n graph = {[soul]: node}\n }\n // Only add _[\"s\"] if we found any signatures\n if (graph && graph[soul] && Object.keys(signatures).length > 0) {\n graph[soul]._[\"s\"] = signatures\n }\n cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n let count = 0\n let finished = false\n const ack = err => {\n count--\n if (finished) return\n\n if (err) {\n finished = true\n cb(err)\n return\n }\n\n if (count === 0) {\n finished = true\n cb(null)\n }\n }\n\n Object.keys(graph).forEach(soul => {\n var node = graph[soul]\n Object.keys(node).forEach(key => {\n if (key === \"_\") return\n\n count++\n let value = node[key]\n let state = node._[\">\"][key]\n let sig = node._[\"s\"] && node._[\"s\"][state]\n let data = sig ? [value, state, sig] : [value, state]\n radisk(soul + enq + key, data, ack)\n })\n })\n },\n }\n}\n\nexport default Store\n", "import Dup from \"./dup.js\"\nimport Get from \"./get.js\"\nimport Ham from \"./ham.js\"\nimport Store from \"./store.js\"\nimport * as utils from \"./utils.js\"\n\nconst isNode = typeof document === \"undefined\"\n\nconst wsModule = isNode ? await import(\"ws\") : undefined\n\nif (typeof globalThis.WebSocket === \"undefined\") {\n globalThis.WebSocket = wsModule?.WebSocket\n}\n\n// Rate limiting with throttling\nconst createRateLimiter = isTestEnv => {\n const clients = new Map()\n const maxRequests = 1500 // requests per minute\n const windowMs = 60000 // 1 minute window\n const disconnectThreshold = 10 // Disconnect after 10 violations\n let cleanupInterval = null\n\n const cleanup = () => {\n const now = Date.now()\n for (const [clientId, data] of clients.entries()) {\n if (now - data.lastCleanup > windowMs) {\n data.requests = []\n data.lastCleanup = now\n }\n data.requests = data.requests.filter(time => now - time < windowMs)\n // Reset throttle counts periodically\n if (now - data.lastCleanup > windowMs * 10) {\n data.throttleCount = 0\n }\n }\n }\n\n if (!isTestEnv) {\n cleanupInterval = setInterval(cleanup, windowMs / 4)\n }\n\n return {\n getDelay: clientId => {\n const now = Date.now()\n const client = clients.get(clientId) || {\n requests: [],\n lastCleanup: now,\n throttleCount: 0,\n }\n\n // Filter old requests\n client.requests = client.requests.filter(time => now - time < windowMs)\n\n if (client.requests.length >= maxRequests) {\n // Calculate delay based on oldest request that will expire\n const oldestRequest = Math.min(...client.requests)\n const delay = windowMs - (now - oldestRequest)\n // Increment throttle count and update client data\n client.throttleCount = (client.throttleCount || 0) + 1\n clients.set(clientId, client)\n return Math.max(0, delay)\n }\n\n // No delay needed, track this request\n client.requests.push(now)\n clients.set(clientId, client)\n return 0\n },\n\n getRemainingRequests: clientId => {\n const client = clients.get(clientId)\n if (!client) return maxRequests\n\n const now = Date.now()\n const validRequests = client.requests.filter(\n time => now - time < windowMs,\n )\n return Math.max(0, maxRequests - validRequests.length)\n },\n\n getThrottleCount: clientId => {\n const client = clients.get(clientId)\n return client ? client.throttleCount || 0 : 0\n },\n\n shouldDisconnect: clientId => {\n const client = clients.get(clientId)\n if (!client) return false\n return client.throttleCount >= disconnectThreshold\n },\n\n destroy: () => {\n if (cleanupInterval) {\n clearInterval(cleanupInterval)\n cleanupInterval = null\n }\n clients.clear()\n },\n }\n}\n\n// Safe JSON parser with size limit\nconst safeJSONParse = (data, maxSize = 1024 * 1024) => {\n try {\n if (typeof data === \"string\" && data.length > maxSize) {\n throw new Error(\"Message too large\")\n }\n return {success: true, data: JSON.parse(data)}\n } catch (error) {\n return {success: false, error: error.message}\n }\n}\n\n// Message size validator\nconst validateMessage = (data, maxSize = 1024 * 1024) => {\n // 1MB default\n if (typeof data === \"string\" && data.length > maxSize) {\n return {valid: false, error: \"Message too large\"}\n }\n if (Buffer.isBuffer(data) && data.length > maxSize) {\n return {valid: false, error: \"Message too large\"}\n }\n return {valid: true}\n}\n\n// Connection manager to limit concurrent connections\nconst createConnectionManager = (maxConnections = 1000) => {\n const connections = new Set()\n\n return {\n add: ws => {\n if (connections.size >= maxConnections) {\n return false\n }\n connections.add(ws)\n\n // Clean up on close\n const originalClose = ws.close\n ws.close = (...args) => {\n connections.delete(ws)\n return originalClose.apply(ws, args)\n }\n\n return true\n },\n\n remove: ws => {\n connections.delete(ws)\n },\n\n count: () => connections.size,\n\n isFull: () => connections.size >= maxConnections,\n }\n}\n\n// Enhanced retry mechanism with exponential backoff\nconst createRetryHandler = (maxRetries = 5) => {\n let retryCount = 0\n\n return {\n shouldRetry: () => retryCount < maxRetries,\n getDelay: () => Math.min(1000 * Math.pow(2, retryCount), 30000), // Max 30s\n increment: () => retryCount++,\n reset: () => (retryCount = 0),\n }\n}\n\n// Wire starts a websocket client or server and returns get and put methods\n// for access to the wire spec and storage.\nconst Wire = opt => {\n const dup = Dup(opt.maxAge)\n const store = Store(opt)\n const graph = {}\n const queue = {}\n const listen = {}\n\n // Track references we want but don't have yet\n const pendingReferences = new Set()\n\n // Track pending timeouts that should start when message is sent\n const pendingTimeouts = new Map()\n\n // Helper to check if we have a soul in memory or storage\n const hasSoul = async soul => {\n if (graph[soul]) return true\n return new Promise(resolve => {\n store.get({\"#\": soul}, (err, data) => {\n resolve(!err && data && data[soul])\n })\n })\n }\n\n // Initialize rate limiting and connection management\n // Check if test environment (mock-socket usage)\n const isTestEnv = opt.wss && opt.wss.constructor.name === \"Server\"\n const rateLimiter = createRateLimiter(isTestEnv)\n const connectionManager = createConnectionManager(opt.maxConnections || 1000)\n\n // The check function is required because user data must provide a public key\n // so that it can be verified. The public key might verify the provided\n // signature but not actually match the user under which the data is being\n // stored. To avoid this, the current data on a soul needs to be checked to\n // make sure the stored public key matches the one provided with the update.\n const check = async (data, send, cb) => {\n const key = utils.userPublicKey\n\n for (const soul of Object.keys(data)) {\n const msg = await new Promise(res => {\n getWithCallback({\"#\": soul, \".\": key}, res, send)\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n const node = data[soul]\n // If there is no current node then the data is ok to write without\n // matching public keys, as the provided soul also needs a rel on the\n // parent node which then also requires checking. Otherwise public keys\n // need to match for existing data. If the incoming update doesn't\n // include a userPublicKey property at all, allow it - the update is\n // not trying to change the public key.\n if (\n !msg.put ||\n !msg.put[soul] ||\n node[key] === undefined ||\n msg.put[soul][key] === node[key]\n ) {\n continue\n }\n\n // If a soul exists but does not have a public key, then one should not be\n // added because the node is not user data. The above check fails in this\n // case if a public key is provided. Note that this is only an error case\n // if called via the API, which is when a callback is provided here.\n // (The wire spec can fetch and put data on the wire without a signature\n // or public key and this can be ignored.)\n if (cb) {\n cb(`error in wire check public key does not match for soul: ${soul}`)\n }\n return false\n }\n\n return true\n }\n\n const get = (msg, send) => {\n const ack = Get(msg.get, graph)\n if (ack) {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n }),\n )\n } else {\n // Always pass secure to ensure public key is fetched. User data may be\n // requested that requires the public key for verification.\n store.get(\n msg.get,\n (err, ack) => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n err: err,\n }),\n )\n },\n {secure: true},\n )\n }\n }\n\n const put = async (msg, send) => {\n // Store updates returned from Ham.mix and defer updates if required.\n const update = await Ham.mix(msg.put, graph, opt.secure, listen)\n if (Object.keys(update.now).length === 0) {\n // No updates to store, check deferred.\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(\n () => put({put: update.defer, \"#\": msg[\"#\"]}, send),\n update.wait,\n )\n }\n return\n }\n\n if (!(await check(update.now, send))) return\n\n store.put(update.now, err => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: err,\n }),\n )\n // Fire listeners after data is stored\n update.listeners.forEach(cb => cb())\n })\n\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(\n () => put({put: update.defer, \"#\": msg[\"#\"]}, send),\n update.wait,\n )\n }\n }\n\n const getWithCallback = (lex, cb, send, _opt) => {\n if (!cb) return\n\n if (!utils.obj.is(_opt)) _opt = {}\n\n const ack = Get(lex, graph, _opt.fast)\n const track = utils.text.random(9)\n const request = JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n })\n\n if (ack) {\n // Also send request on the wire to check for updates.\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n return\n }\n cb({put: ack})\n return\n }\n\n store.get(\n lex,\n (err, ack) => {\n if (ack) {\n // Also send request on the wire to check for updates.\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n return\n }\n cb({put: ack, err: err})\n return\n }\n\n if (err) console.log(err)\n\n queue[track] = cb\n\n // Store timeout config to start after message is sent from queue\n pendingTimeouts.set(track, {\n lex: lex,\n wait: _opt.wait || 100,\n })\n\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n delete queue[track]\n pendingTimeouts.delete(track)\n return\n }\n },\n _opt,\n )\n }\n\n const api = send => {\n return {\n get: (lex, cb, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = {...lex, \".\": String(lex[\".\"])}\n }\n // Mark requested soul as something we want to store\n if (lex && lex[\"#\"]) {\n pendingReferences.add(lex[\"#\"])\n }\n getWithCallback(lex, cb, send, _opt)\n },\n put: async (data, cb) => {\n // Deferred updates are only stored using wire spec, they're ignored\n // here using the api. This is ok because correct timestamps should be\n // used whereas wire spec needs to handle clock skew for updates\n // across the network.\n const update = await Ham.mix(data, graph, opt.secure, listen)\n if (Object.keys(update.now).length === 0) {\n // No updates, still respond to callback.\n if (cb) cb(null)\n return\n }\n\n if (!(await check(update.now, send, cb))) {\n return\n }\n\n // Seed pendingReferences with any new references from API calls\n for (const [soul, node] of Object.entries(update.now)) {\n if (node && typeof node === \"object\") {\n for (const [key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value)\n if (soulId) {\n // Add referenced soul to pending list\n pendingReferences.add(soulId)\n }\n }\n }\n }\n\n store.put(update.now, err => {\n if (cb) cb(err)\n // Fire listeners after data is stored\n update.listeners.forEach(l => l())\n })\n\n // Always put data on the wire spec even if no local update needed\n const sendResult = send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n }),\n )\n // Handle queue overflow error.\n if (sendResult && sendResult.err) {\n if (cb) cb(sendResult.err)\n return\n }\n },\n on: (lex, cb, _get, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = {...lex, \".\": String(lex[\".\"])}\n }\n const soul = lex && lex[\"#\"]\n if (!soul || !cb) return\n\n if (listen[soul]) {\n listen[soul].push({\".\": lex[\".\"], cb: cb})\n } else {\n listen[soul] = [{\".\": lex[\".\"], cb: cb}]\n }\n if (_get) getWithCallback(lex, cb, send, _opt)\n },\n off: (lex, cb) => {\n const soul = lex && lex[\"#\"]\n if (!soul || !listen[soul]) return\n\n if (cb) {\n const found = listen[soul].find(l => l.cb === cb)\n if (found) {\n listen[soul].splice(listen[soul].indexOf(found), 1)\n }\n } else {\n // Remove all callbacks when none provided.\n delete listen[soul]\n }\n },\n }\n }\n\n if (isNode) {\n let wss = opt.wss\n // Node's websocket server provides clients as an array, whereas\n // mock-sockets provides clients as a function that returns an array.\n let clients = () => wss.clients()\n if (!wss) {\n const config = opt.server\n ? {server: opt.server}\n : {port: opt.port || 8765}\n wss = new wsModule.WebSocketServer(config)\n clients = () => wss.clients\n }\n\n const send = (data, isBinary) => {\n // Start timeout for this message now that it's being sent\n const msg = JSON.parse(data)\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)\n pendingTimeouts.delete(trackId)\n\n // Respond to callback with null if no response.\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack = {[id]: null}\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = {[timeoutConfig.lex[\".\"]]: null}\n }\n cb({put: ack})\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n\n clients().forEach(client => {\n if (client && client.readyState === WebSocket.OPEN) {\n client.send(data, {binary: isBinary})\n } else {\n const retryHandler = client._retryHandler || createRetryHandler()\n client._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (client && client.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n client.send(data, {binary: isBinary})\n }\n }, delay)\n }\n }\n })\n }\n wss.on(\"connection\", ws => {\n // Check connection limit\n if (!connectionManager.add(ws)) {\n console.log(\"Connection limit reached, rejecting connection\")\n ws.close(1013, \"Connection limit reached - try again later\")\n return\n }\n\n // Generate unique client ID for rate limiting\n const clientId = utils.text.random(9)\n console.log(`New WebSocket client connected: ${clientId}`)\n\n ws.on(\"error\", error => {\n console.log(\"WebSocket error:\", error)\n connectionManager.remove(ws)\n })\n\n ws.on(\"close\", () => {\n console.log(`WebSocket client disconnected: ${clientId}`)\n connectionManager.remove(ws)\n })\n\n ws.on(\"message\", (data, isBinary) => {\n // Validate message size\n const validation = validateMessage(data, opt.maxMessageSize)\n if (!validation.valid) {\n console.warn(`Invalid message: ${validation.error}`)\n ws.send(JSON.stringify({error: validation.error}))\n return\n }\n\n // Safe JSON parsing\n const parseResult = safeJSONParse(data, opt.maxMessageSize)\n if (!parseResult.success) {\n console.warn(`JSON parse error: ${parseResult.error}`)\n ws.send(JSON.stringify({error: \"Invalid JSON\"}))\n return\n }\n\n const msg = parseResult.data\n if (dup.check(msg[\"#\"])) return\n\n // Check rate limit and get delay\n const delay = rateLimiter.getDelay(clientId)\n // Log rate limiting activity and enforce stricter limits\n if (delay > 0) {\n const throttleCount = rateLimiter.getThrottleCount(clientId)\n console.log(\n `Client ${clientId}: rate limit exceeded, delay would be ${delay}ms, dropping message (throttle count: ${throttleCount})`,\n )\n // Check if we should disconnect the bad actor\n if (rateLimiter.shouldDisconnect(clientId)) {\n console.log(\n `Client ${clientId}: Disconnecting after ${throttleCount} throttle violations`,\n )\n ws.close(1008, \"Rate limit violations\")\n return\n }\n\n // Send throttle warning back to client instead of processing\n ws.send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: `Rate limit exceeded. Slow down requests. Wait ${Math.ceil(delay / 1000)}s`,\n throttle: delay,\n }),\n )\n return\n }\n\n const processMessage = async () => {\n dup.track(msg[\"#\"])\n\n if (msg.get) get(msg, send)\n if (msg.put) await put(msg, send)\n send(data, isBinary)\n\n const id = msg[\"@\"]\n const cb = queue[id]\n if (cb) {\n delete msg[\"#\"]\n delete msg[\"@\"]\n cb(msg)\n\n delete queue[id]\n }\n }\n\n if (delay > 0) {\n // Throttle the client by delaying message processing\n setTimeout(processMessage, delay)\n } else {\n // Process immediately\n processMessage()\n }\n })\n })\n return api(send)\n }\n\n // Browser logic.\n const peers = []\n // Client-side throttling state\n let clientThrottled = false\n let throttleUntil = 0\n let messageQueue = []\n let queueProcessor = null\n const maxQueueLength = opt.maxQueueLength || 10000\n\n const processQueue = () => {\n if (messageQueue.length === 0) {\n queueProcessor = null\n return\n }\n\n const now = Date.now()\n if (clientThrottled && now < throttleUntil) {\n // Still throttled, schedule next queue check\n queueProcessor = setTimeout(\n processQueue,\n Math.min(1000, throttleUntil - now),\n )\n return\n }\n\n // Throttle period ended, resume processing\n if (clientThrottled && now >= throttleUntil) {\n console.log(`Throttle period ended, resuming queue processing`)\n clientThrottled = false\n throttleUntil = 0\n }\n\n // Process next message in queue\n const data = messageQueue[0]\n const sent = sendToPeers(data)\n\n if (sent) {\n // Only remove from queue if successfully sent\n messageQueue.shift()\n\n // Start timeout for this message now that it's been sent\n const msg = JSON.parse(data)\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)\n pendingTimeouts.delete(trackId)\n\n // Respond to callback with null if no response.\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack = {[id]: null}\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = {[timeoutConfig.lex[\".\"]]: null}\n }\n cb({put: ack})\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n }\n\n // Schedule processing of next message if queue not empty\n if (messageQueue.length > 0) {\n // Add delay between messages to respect rate limit\n queueProcessor = setTimeout(processQueue, 50)\n } else {\n queueProcessor = null\n }\n }\n\n const sendToPeers = data => {\n let sentToAtLeastOne = false\n peers.forEach(peer => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n peer.send(data)\n sentToAtLeastOne = true\n } else {\n const retryHandler = peer._retryHandler || createRetryHandler()\n peer._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n peer.send(data)\n }\n }, delay)\n }\n }\n })\n return sentToAtLeastOne\n }\n\n const send = data => {\n if (messageQueue.length >= maxQueueLength) {\n return {\n err: `Message queue exceeded maximum length (${maxQueueLength}). Update query logic to request less data.`,\n queueLength: messageQueue.length,\n maxQueueLength: maxQueueLength,\n }\n }\n\n messageQueue.push(data)\n // Start queue processor if not already running\n if (!queueProcessor) {\n queueProcessor = setTimeout(processQueue, 50)\n }\n }\n if (!(opt.peers instanceof Array) || opt.peers.length === 0) {\n opt.peers = [`ws://localhost:${opt.port || 8765}`]\n }\n opt.peers.forEach(peer => {\n const start = () => {\n let ws = new WebSocket(peer)\n peers.push(ws)\n const retryHandler = createRetryHandler()\n\n ws.onclose = c => {\n if (peers.indexOf(ws) !== -1) {\n peers.splice(peers.indexOf(ws), 1)\n }\n ws = null\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n setTimeout(start, delay)\n }\n }\n\n ws.onopen = () => {\n retryHandler.reset()\n }\n\n ws.onerror = e => {\n console.log(e)\n }\n ws.onmessage = async m => {\n const msg = JSON.parse(m.data)\n if (dup.check(msg[\"#\"])) return\n\n // Handle throttle messages from server\n if (msg.throttle && msg.err) {\n console.log(`Server throttling: ${msg.err}`)\n clientThrottled = true\n throttleUntil = Date.now() + msg.throttle\n return\n }\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) {\n // Handle selective storage for client WebSocket messages\n const filteredPut = {}\n for (const [soul, node] of Object.entries(msg.put)) {\n let shouldStore = false\n // Case 1: We already have this soul - always update\n if (await hasSoul(soul)) {\n shouldStore = true\n // Check if this update adds new references\n if (node && typeof node === \"object\") {\n for (const [key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value)\n if (soulId) {\n // Add referenced soul to pending list\n pendingReferences.add(soulId)\n }\n }\n }\n }\n // Case 2: This soul was referenced by something we have\n if (pendingReferences.has(soul)) {\n shouldStore = true\n pendingReferences.delete(soul) // Got it, remove from pending\n }\n if (shouldStore) {\n filteredPut[soul] = node\n }\n }\n // Store filtered data if any\n if (Object.keys(filteredPut).length > 0) {\n // Create filtered message for Ham.mix with original message ID\n const filteredMsg = {put: filteredPut, \"#\": msg[\"#\"]}\n await put(filteredMsg, send)\n }\n }\n\n const id = msg[\"@\"]\n const cb = queue[id]\n if (cb) {\n delete msg[\"#\"]\n delete msg[\"@\"]\n cb(msg)\n\n delete queue[id]\n }\n }\n }\n start()\n })\n\n return api(send)\n}\n\nexport default Wire\n", "import * as utils from \"./utils.js\"\nimport Wire from \"./wire.js\"\nimport SEA from \"./sea.js\"\nimport {userPublicKey, userSignature} from \"./utils.js\"\n\nconst User = (opt, wire) => {\n if (!wire) wire = Wire(opt)\n const wait = opt?.wait ?? 5000\n let pubs = []\n let creating = false\n let authing = false\n let retries = 0\n\n const auth = (username, password, newPassword, ack) => {\n const retry = username => {\n retries++\n auth(username, password, newPassword, ack)\n }\n const done = err => {\n pubs = []\n retries = 0\n authing = false\n ack(err)\n }\n const next = () => {\n if (pubs.length === 0) {\n done(\"Wrong username or password\")\n return\n }\n\n const pub = pubs.shift()\n wire.get(\n {\"#\": pub, \".\": [\"auth\", \"pub\", \"epub\"]},\n async msg => {\n if (msg.err) {\n done(`error getting ${pub}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[pub]\n if (!data || !data.auth) return next()\n\n const auth = JSON.parse(data.auth)\n const work = await SEA.work(password, auth.salt)\n const dec = await SEA.decrypt(auth.enc, work)\n if (!dec) return next()\n\n user.is = {\n username: username,\n pub: data.pub,\n epub: data.epub,\n priv: dec.priv,\n epriv: dec.epriv,\n }\n if (newPassword !== \"\") {\n // Encrypt private key using new password and a new salt.\n const salt = utils.text.random(64)\n const work = await SEA.work(newPassword, salt)\n const enc = await SEA.encrypt(dec, work)\n // Only update the auth property with the new password encryption.\n const update = {\n auth: JSON.stringify({enc: enc, salt: salt}),\n }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const graph = utils.graph(pub, update, sig, data.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${update} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n done(null)\n },\n {wait: wait},\n )\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get(\n {\"#\": soul},\n async msg => {\n if (msg.err) {\n done(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[soul]\n if (!data) return retry(username)\n\n delete msg.put[soul]._\n // Usernames aren't guaranteed to be unique, so store the list and then\n // try each of them until one is successful with the given password.\n pubs = Object.keys(data)\n next()\n },\n {wait: wait},\n )\n }\n\n const user = {\n create: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else console.log(err)\n }\n\n if (creating) {\n ack(\"User is already being created\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n creating = true\n\n const soul = \"~@\" + username\n wire.get(\n {\"#\": soul},\n async msg => {\n if (msg.err) {\n creating = false\n ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n if (msg.put && msg.put[soul]) {\n creating = false\n ack(\"Username already exists\")\n return\n }\n\n const salt = utils.text.random(64)\n const work = await SEA.work(password, salt)\n const pair = await SEA.pair()\n const priv = {priv: pair.priv, epriv: pair.epriv}\n const enc = await SEA.encrypt(priv, work)\n const data = {\n username: username,\n pub: pair.pub,\n epub: pair.epub,\n auth: JSON.stringify({enc: enc, salt: salt}),\n }\n\n const pub = \"~\" + pair.pub\n // Sign the timestamp for new account\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, pair)\n const graph = utils.graph(pub, data, sig, pair.pub, timestamp)\n wire.put(graph, err => {\n creating = false\n if (err) {\n ack(`error putting ${data} on ${pub}: ${err}`)\n return\n }\n\n const rel = {[pub]: {\"#\": pub}}\n wire.put(utils.graph(soul, rel), err => {\n if (err) {\n ack(`error putting ${rel} on ${soul}: ${err}`)\n return\n }\n\n // Return null on success.\n if (cb) cb(null)\n })\n })\n },\n {wait: wait},\n )\n },\n auth: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", ack)\n },\n change: (username, password, newPassword, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n if (newPassword === \"\") {\n ack(\"Please provide a new password\")\n return\n }\n\n authing = true\n auth(username, password, newPassword, ack)\n },\n store: localStorage => {\n if (!user.is) {\n console.log(\"Please authenticate before calling store\")\n return\n }\n\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n },\n recall: () => {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n return\n }\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n const is = globalThis.sessionStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n }\n }\n },\n leave: () => {\n user.is = null\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n },\n delete: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", async err => {\n if (err) {\n ack(err)\n return\n }\n\n const data = {username: null, pub: null, epub: null, auth: null}\n // Sign the timestamp for account deletion\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const pub = \"~\" + user.is.pub\n const graph = utils.graph(pub, data, sig, user.is.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n ack(`error putting null on ${pub}: ${err}`)\n return\n }\n\n user.is = null\n // Return null on success. Note currently not updating ~@username,\n // not sure if allowing username re-user is a good idea anyway?\n if (cb) cb(null)\n })\n })\n },\n }\n return user\n}\n\nexport default User\n", "import * as utils from \"./utils.js\"\nimport Wire from \"./wire.js\"\nimport User from \"./user.js\"\nimport SEA from \"./sea.js\"\n\nconst Holster = opt => {\n if (typeof opt === \"string\") opt = {peers: [opt]}\n else if (opt instanceof Array) opt = {peers: opt}\n else if (!utils.obj.is(opt)) opt = {}\n\n const wire = Wire(opt)\n const user = User(opt, wire)\n // Map callbacks since the user's callback is not passed to wire.on.\n const map = new Map()\n // Allow concurrent calls to the api by storing each context.\n const allctx = new Map()\n\n const ok = data => {\n return (\n data === null ||\n data === true ||\n data === false ||\n typeof data === \"string\" ||\n utils.rel.is(data) ||\n utils.num.is(data)\n )\n }\n\n // check returns true if data is ok to add to a graph, an error string if\n // the data can't be converted, and the keys on the data object otherwise.\n const check = data => {\n if (ok(data)) return true\n\n if (utils.obj.is(data)) {\n const keys = []\n for (const [key, value] of Object.entries(data)) {\n if (key === \"_\") {\n return \"error underscore cannot be used as a property name\"\n }\n if (utils.obj.is(value) || ok(value)) {\n keys.push(key)\n continue\n }\n if (typeof value === \"undefined\") {\n return `error undefined ${key} cannot be converted to a graph`\n }\n const error = JSON.stringify({[key]: value})\n return `error ${error} cannot be converted to a graph`\n }\n if (keys.length !== 0) return keys\n }\n const error = JSON.stringify(data)\n return `error ${error} cannot be converted to a graph`\n }\n\n const api = ctxid => {\n const get = (lex, soul, ack, _opt) => {\n wire.get(\n utils.obj.put(lex, \"#\", soul),\n async msg => {\n if (msg.err) console.log(msg.err)\n if (msg.put && msg.put[soul]) {\n delete msg.put[soul]._\n delete msg.put[soul][utils.userPublicKey]\n delete msg.put[soul][utils.userSignature]\n // Resolve any rels on the node before returning to the user.\n for (const key of Object.keys(msg.put[soul])) {\n const id = utils.rel.is(msg.put[soul][key])\n if (id) {\n // Retry with delays if we get null\n const attemptRead = async (retries = 0) => {\n const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n const ctx = allctx.get(ctxid)\n allctx.set(_ctxid, {\n chain: [{item: null, soul: id}],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null, res, _opt)\n })\n if (data !== null || retries >= 5) {\n return data\n }\n // Data not ready, retry after delay\n await new Promise(resolve => setTimeout(resolve, 50))\n return attemptRead(retries + 1)\n }\n msg.put[soul][key] = await attemptRead()\n }\n }\n ack(msg.put[soul])\n } else {\n // No data callback.\n ack(null)\n }\n },\n _opt,\n )\n }\n\n const graph = async (soul, data, userctx, cb) => {\n if (userctx) {\n // Sign the timestamp\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, userctx)\n return utils.graph(soul, data, sig, userctx.pub, timestamp)\n }\n\n if (opt.secure) {\n if (!cb) cb = console.log\n cb(`error putting data on ${soul}: user required in secure mode`)\n return null\n }\n\n return utils.graph(soul, data)\n }\n\n // done takes a context id and returns a new callback function so that the\n // callback is not overwritten by simultaneous requests.\n const done = ctxid => {\n return data => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") {\n // Use a timeout so that the context can be removed before data is\n // returned to the callback (allows nested get calls).\n setTimeout(() => ctx.cb(data), 1)\n } else if (data) {\n console.log(\"error no callback for data\", data, \"ctx\", ctx)\n }\n // A context updated by \"on\" should only be removed by \"off\".\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n }\n\n const resolve = (request, cb) => {\n if (!request) {\n console.log(\"error resolve request parameter required\")\n return\n }\n\n const get = typeof request.get !== \"undefined\"\n const put = typeof request.put !== \"undefined\"\n const on = typeof request.on !== \"undefined\"\n const off = typeof request.off !== \"undefined\"\n\n let found = false\n const ctx = allctx.get(ctxid)\n for (var i = 1; i < ctx.chain.length; i++) {\n if (ctx.chain[i].soul !== null) continue\n\n found = true\n break\n }\n\n if (found) {\n // Found a soul that needs resolving, need the previous context\n // (ie the parent node) to find a soul relation for it.\n const {item, soul} = ctx.chain[i - 1]\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n console.log(`error getting ${item} on ${soul}: ${msg.err}`)\n if (cb) cb(null)\n return\n }\n\n let node = msg.put && msg.put[soul]\n if (node && typeof node[item] !== \"undefined\") {\n let id = utils.rel.is(node[item])\n if (id) {\n ctx.chain[i].soul = id\n allctx.set(ctxid, {...ctx})\n // Call api again using the updated context.\n if (get) {\n api(ctxid).next(null, request.get, cb, request._opt)\n } else if (put) {\n api(ctxid).put(request.put, cb)\n } else if (on) {\n api(ctxid).on(request.on, cb, request._get, request._opt)\n } else if (off) {\n api(ctxid).off(cb)\n }\n } else if (get) {\n // Request was not for a node, return property on current soul.\n cb(node[item])\n } else if (put) {\n // Request was chained before put, so rel doesn't exist yet.\n id = utils.text.random()\n node[item] = utils.rel.ify(id)\n const g = await graph(soul, node, ctx.user, cb)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n cb(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n\n ctx.chain[i].soul = id\n api(ctxid).put(request.put, cb)\n })\n } else if (on) {\n // Allow listening to a node that doesn't exist.\n cb(null)\n } else if (off) {\n // Allow stop listening to a node that doesn't exist.\n if (cb) cb(null)\n }\n } else if (put) {\n // Request was chained before put, so rel doesn't exist yet.\n const id = utils.text.random()\n if (!node) node = {}\n node[item] = utils.rel.ify(id)\n const g = await graph(soul, node, ctx.user, cb)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n cb(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n\n ctx.chain[i].soul = id\n api(ctxid).put(request.put, cb)\n })\n } else {\n // Allow querying a node that doesn't exist.\n if (cb) cb(null)\n }\n },\n {...request._opt, secure: ctx.user || opt.secure},\n )\n // Callback has been passed to next soul lookup or called above, so\n // return false as the calling code should not continue.\n return false\n }\n\n if (get && ctx.chain[ctx.chain.length - 1].item !== null) {\n // The context has been resolved but it does not include the requested\n // node, which requires one more lookup.\n ctx.chain.push({item: null, soul: null})\n api(ctxid).next(null, request.get, cb, request._opt)\n return false\n }\n\n // Return the last context, ie the soul required by the calling code.\n return ctx.chain[ctx.chain.length - 1]\n }\n\n return {\n get: (key, lex, cb, _opt) => {\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (cb) cb(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && typeof cb !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n // Top level keys are added to a root node so their values don't need\n // to be objects.\n ctxid = utils.text.random()\n allctx.set(ctxid, {chain: [{item: String(key), soul: \"root\"}], cb: cb})\n if (!cb) return api(ctxid)\n\n const _done = done(ctxid)\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex, _opt: _opt}, _done)\n if (soul) get(lex, soul, _done, _opt)\n },\n next: (key, lex, cb, _opt) => {\n // ack needs to work the same as done, pass it the context id and then\n // return a new function for the actual callback.\n const ack = ctxid => {\n return data => {\n if (cb) {\n cb(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n const _ack = ack(ctxid)\n if (key === \"\" || key === \"_\") {\n _ack(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && typeof cb !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n const ctx = allctx.get(ctxid)\n // ctx already removed by another chained callback is ok?\n if (!ctx) return\n\n if (cb && typeof ctx.cb === \"undefined\") {\n // This (and ack) allows nested objects to set their own callbacks.\n ctx.cb = cb\n cb = null\n }\n\n // Push the key to the context as it needs a soul lookup.\n // (null is used to call the api with updated context)\n if (key !== null) ctx.chain.push({item: String(key), soul: null})\n if (!ctx.cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex, _opt: _opt}, _ack)\n if (soul) get(lex, soul, _ack, _opt)\n },\n put: (data, set, cb) => {\n if (typeof set === \"function\") {\n cb = set\n set = false\n }\n const ack = ctxid => {\n return data => {\n if (cb) {\n cb(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n if (!ctxid) {\n if (cb) cb(\"error please provide a key using get(key)\")\n return\n }\n\n const ctx = allctx.get(ctxid)\n // ctx already removed by another chained callback is ok?\n if (!ctx) return\n\n if (!ctx.cb) {\n if (!cb) return\n\n // This (and ack) allows nested objects to set their own callbacks.\n ctx.cb = cb\n cb = null\n }\n if (set) data = {[utils.text.random()]: data}\n\n const _ack = ack(ctxid)\n const result = check(data)\n if (typeof result === \"string\") {\n // All strings returned from check are errors, cannot continue.\n _ack(result)\n return\n }\n\n // Resolve the current context before putting data. (Note that set is\n // not passed to resolve because it's already been applied above.)\n const {item, soul} = resolve({put: data}, _ack)\n if (!soul) return\n\n if (result === true) {\n // When result is true data is a property to put on the current soul.\n // Need to check if item is a rel and also set the node to null. (This\n // applies for any update from a rel to a property, not just null.)\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item]\n const id = utils.rel.is(current)\n if (!id) {\n // Not a rel, can just put the data.\n if (!node) node = {}\n node[item] = data\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n return\n }\n\n wire.get({\"#\": id}, async msg => {\n if (msg.err) {\n _ack(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n _ack(`error ${id} not found`)\n return\n }\n\n // null each of the properties on the node before putting data.\n for (const key of Object.keys(msg.put[id])) {\n if (\n key === \"_\" ||\n key === utils.userPublicKey ||\n key === utils.userSignature\n ) {\n continue\n }\n\n const err = await new Promise(res => {\n const _ctxid = utils.text.random()\n const chain = [{item: key, soul: id}]\n allctx.set(_ctxid, {chain: chain, user: ctx.user})\n api(_ctxid).put(null, res)\n })\n if (err) {\n _ack(err)\n return\n }\n }\n if (!node) node = {}\n node[item] = data\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n })\n },\n {secure: ctx.user || opt.secure},\n )\n return\n }\n\n // Otherwise put the data using the keys returned in result.\n // Need to check if a rel has already been added on the current node.\n // Use attemptRead to retry if data hasn't propagated yet.\n const attemptRead = (retries = 0) => {\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item]\n\n // If we didn't find the item but still have retries, retry\n if (!current && retries < 5) {\n await new Promise(r => setTimeout(r, 50))\n return attemptRead(retries + 1)\n }\n\n const id = utils.rel.is(current)\n if (!id) {\n // The current rel doesn't exist, so add it first.\n if (!node) node = {}\n node[item] = utils.rel.ify(utils.text.random())\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n _ack(`error putting ${item} on ${soul}: ${err}`)\n } else {\n const _ctxid = utils.text.random()\n const chain = [{item: item, soul: soul}]\n // Pass on the previous context's callback and user flag here.\n allctx.set(_ctxid, {\n chain: chain,\n user: ctx.user,\n cb: ctx.cb,\n })\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n const update = []\n for (const key of result) {\n const err = await new Promise(res => {\n if (utils.obj.is(data[key]) && !utils.rel.is(data[key])) {\n // Use the current rel as the context for nested objects.\n const _ctxid = utils.text.random()\n const chain = [{item: key, soul: id}]\n allctx.set(_ctxid, {chain: chain, user: ctx.user})\n api(_ctxid).put(data[key], res)\n } else {\n // Group the rest of the updates for put below.\n update.push(key)\n res(null)\n }\n })\n if (err) {\n _ack(err, ctxid)\n return\n }\n }\n\n if (update.length === 0) {\n _ack(null)\n return\n }\n\n // The nested objects created above will also have rels on the\n // parent object, so fetch the node so that the rest of the\n // updates can be added.\n wire.get({\"#\": id}, async msg => {\n if (msg.err) {\n _ack(`error getting ${id}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[id]\n if (!node) node = {}\n update.forEach(key => {\n node[key] = data[key]\n })\n const g = await graph(id, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n })\n },\n {secure: ctx.user || opt.secure},\n )\n }\n attemptRead()\n },\n on: (lex, cb, _get, _opt) => {\n if (typeof lex === \"function\") {\n _opt = _get\n _get = cb\n cb = lex\n lex = null\n }\n if (typeof cb !== \"function\") {\n console.log(\"error on() requires a callback function\")\n return\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n cb(null)\n return\n }\n\n // Resolve the current context before adding event listener.\n const {item, soul} = resolve({on: lex, _get: _get, _opt: _opt}, cb)\n if (!soul) return\n\n // Get the context to check if it has user info\n const ctx = allctx.get(ctxid)\n\n // Flag that this context is set from on and shouldn't be removed.\n allctx.set(ctxid, {\n chain: [{item: item, soul: soul}],\n on: true,\n user: ctx ? ctx.user : null,\n })\n // Map the user's callback because it can also be passed to off,\n // so need a reference to it to compare them.\n // Create a new context for each listener invocation to avoid mutation\n map.set(cb, () => {\n // When listener fires, re-check if the item is now a rel.\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n const current = msg.put && msg.put[soul] && msg.put[soul][item]\n const id = utils.rel.is(current)\n if (id) {\n // It's a rel, read the related node. It might not be in the\n // graph yet when the listener fires, so we retry with delays.\n const attemptRead = async (retries = 0) => {\n const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {\n chain: [{item: null, soul: id}],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null, res, _opt)\n })\n if (data !== null || retries >= 5) {\n cb(data)\n } else {\n // Data not ready, retry after delay\n await new Promise(resolve => setTimeout(resolve, 50))\n attemptRead(retries + 1)\n }\n }\n attemptRead()\n } else {\n // It's a direct property or null\n cb(current !== undefined ? current : null)\n }\n },\n {..._opt, secure: ctx.user || opt.secure},\n )\n })\n\n // Register listener immediately to avoid missing updates due to\n // queueing. Initially register the soul without _get, then update if\n // it's a rel.\n let initialLex\n if (lex) {\n initialLex = utils.obj.put(lex, \"#\", soul)\n // Normalize numeric property filters to strings for wire operations\n // Only convert if it's a number, not if it's a complex filter object\n if (initialLex[\".\"] != null && typeof initialLex[\".\"] === \"number\") {\n initialLex = {...initialLex, \".\": String(initialLex[\".\"])}\n }\n } else {\n initialLex = {\"#\": soul, \".\": item}\n }\n wire.on(initialLex, map.get(cb), false, _opt)\n\n // Check if item is a rel and update listener if needed.\n // This happens async but the listener is already registered above.\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n if (msg.err) {\n console.log(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul][item]\n const id = utils.rel.is(current)\n if (id) {\n // It's a rel, need to switch listener to the related node\n // First remove the initial listener\n wire.off(initialLex, map.get(cb))\n // Then add listener on the related node\n let relLex\n if (lex) relLex = utils.obj.put(initialLex, \"#\", id)\n else relLex = {\"#\": id, \".\": null}\n wire.on(relLex, map.get(cb), _get, _opt)\n } else if (_get) {\n // Not a rel, but _get was requested, so trigger callback.\n map.get(cb)()\n }\n },\n {..._opt, secure: ctx.user || opt.secure},\n )\n },\n off: cb => {\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n // Resolve the current context before removing event listener.\n const {item, soul} = resolve({off: true}, cb)\n if (!soul) return\n\n // Remove listener immediately from the original soul to avoid race condition.\n // The listener may be on a related soul if item is a rel, but we remove\n // from the original soul first since that's where it's initially registered.\n wire.off({\"#\": soul}, map.get(cb))\n\n // Check if item is a rel and remove from the related node as well.\n wire.get({\"#\": soul, \".\": item}, msg => {\n if (msg.err) {\n // Even if get fails, we've already removed from original soul\n map.delete(cb)\n allctx.delete(ctxid)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul][item]\n const id = utils.rel.is(current)\n if (id) wire.off({\"#\": id}, map.get(cb))\n map.delete(cb)\n allctx.delete(ctxid)\n })\n },\n user: () => {\n if (!user.get) {\n // Return the combined Holster and User APIs.\n Object.assign(user, api())\n // Need to provide a user specific get() function to know if user\n // context should be checked.\n user.get = (keys, lex, cb, _opt) => {\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n\n let pub = null\n let key = null\n if (user.is) pub = user.is.pub\n if (typeof keys === \"string\") {\n key = keys\n } else if (keys instanceof Array) {\n if (keys.length === 2) {\n pub = keys[0]\n key = keys[1]\n } else if (keys.length === 1) {\n key = keys[0]\n }\n }\n if (!pub) {\n console.log(\"error please log in or provide a public key\")\n if (cb) cb(null)\n return\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (cb) cb(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && !cb) {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n ctxid = utils.text.random()\n const chain = [{item: String(key), soul: \"~\" + pub}]\n allctx.set(ctxid, {chain: chain, user: user.is, cb: cb})\n if (!cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const _done = done(ctxid)\n const {soul} = resolve({get: lex, _opt: _opt}, _done)\n if (soul) get(lex, soul, _done, _opt)\n }\n }\n return user\n },\n // Allow the wire spec to be used via holster.\n wire: wire,\n // Allow SEA functions to be used via holster.\n SEA: SEA,\n }\n }\n return api()\n}\n\nexport default Holster\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["num", "n", "parsed", "obj", "o", "match", "list", "cb", "keys", "i", "result", "key", "value", "map_soul", "soul", "rel", "userSignature", "userPublicKey", "graph", "data", "sig", "pub", "timestamp", "g", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "Dup", "maxAge", "dup", "id", "now", "dup_default", "Get", "lex", "graph", "fast", "soul", "node", "signatures", "key", "state", "userPublicKey", "pkState", "match", "get_default", "data", "SeaArray", "enc", "start", "end", "buf", "byte", "_", "i", "charCode", "utf8String", "array_default", "SECURITY_LIMITS", "SafeBuffer", "props", "validateStringInput", "input", "encoding", "validateBufferSize", "size", "operation", "parseHexString", "hexString", "cleanHex", "bytes", "i", "hexByte", "encodeUtf8String", "str", "err", "encodeBinaryString", "charCode", "parseBase64String", "base64String", "cleanBase64", "decodedString", "processArrayLikeInput", "val", "arr", "array_default", "length", "fill", "buffer", "totalLength", "validatedBuffers", "item", "result", "offset", "obj", "string", "clean", "start", "end", "buffer_default", "isNode", "crypto", "subtle", "stringify", "data", "parse", "text", "random", "length", "array", "buffer_default", "jwk", "pub", "priv", "x", "y", "sha256", "hash", "aeskey", "key", "salt", "combined", "keyToJwk", "SEA", "cb", "ecdsa", "subtle", "keys", "pub", "ecdh", "pair", "data", "rand", "random", "ct", "aeskey", "aes", "stringify", "enc", "buffer_default", "dec", "parse", "signed", "key", "jwk", "msg", "k", "userPublicKey", "userSignature", "hash", "sha256", "sig", "alg", "verified", "check", "timestamp", "timestampStr", "signature", "publicKey", "isValid", "err", "
|
|
4
|
+
"sourcesContent": ["export const num = {\n is: n => {\n if (n instanceof Array) return false\n\n if (typeof n === \"number\") return !isNaN(n)\n\n if (typeof n === \"string\") {\n const parsed = parseFloat(n)\n return !isNaN(parsed) && isFinite(parsed)\n }\n\n return false\n },\n}\n\nexport const obj = {\n is: o => {\n if (!o || typeof o !== \"object\") return false\n\n const toString = Object.prototype.toString.call(o)\n const match = toString.match(/^\\[object (\\w+)\\]$/)\n return o.constructor === Object || (match && match[1] === \"Object\")\n },\n map: (list, cb, o) => {\n var keys = Object.keys(list)\n for (let i = 0; i < keys.length; i++) {\n let result = cb(list[keys[i]], keys[i], o)\n if (typeof result !== \"undefined\") return result\n }\n },\n put: (o, key, value) => {\n if (!o) o = {}\n o[key] = value\n return o\n },\n del: (o, key) => {\n if (!o) return\n\n o[key] = null\n delete o[key]\n return o\n },\n}\n\nconst map_soul = (soul, key, o) => {\n // If id is already defined AND we're still looping through the object,\n // then it is considered invalid.\n if (o.id) {\n o.id = false\n return\n }\n\n if (key === \"#\" && typeof soul === \"string\") {\n o.id = soul\n return\n }\n\n // If there exists anything else on the object that isn't the soul,\n // then it is considered invalid.\n o.id = false\n}\n\n// Check if an object is a soul relation, ie {'#': 'UUID'}\nexport const rel = {\n is: value => {\n if (value && value[\"#\"] && !value._ && obj.is(value)) {\n let o = {}\n obj.map(value, map_soul, o)\n if (o.id) return o.id\n }\n\n return false\n },\n // Convert a soul into a relation and return it.\n ify: soul => obj.put({}, \"#\", soul),\n}\n\nexport const userSignature = \"_holster_user_signature\"\nexport const userPublicKey = \"_holster_user_public_key\"\n\n// graph converts objects to graph format with updated states,\n// with optional meta data to verify signed data.\nexport const graph = (soul, data, sig, pub, timestamp) => {\n const g = {[soul]: {_: {\"#\": soul, \">\": {}}}}\n\n for (const [key, value] of Object.entries(data)) {\n if (key !== \"_\" && key !== userPublicKey && key !== userSignature) {\n g[soul][key] = value\n g[soul]._[\">\"][key] = timestamp || Date.now()\n }\n }\n if (sig && pub && timestamp) {\n g[soul]._[\"s\"] = {[timestamp]: sig}\n g[soul][userPublicKey] = pub\n g[soul]._[\">\"][userPublicKey] = timestamp\n }\n return g\n}\n\nexport const match = (lex, key) => {\n // Null is used to match listeners on souls, which don't provide a key.\n if (typeof key === \"undefined\") return lex === null\n\n if (typeof lex === \"undefined\") return true\n\n if (typeof lex === \"string\") return lex === key\n\n // Array support: check if key is in the array\n if (Array.isArray(lex)) return lex.includes(key)\n\n if (!obj.is(lex) || !key) return false\n\n const prefix = lex[\"*\"]\n if (prefix) return key.slice(0, prefix.length) === prefix\n\n const gt = lex[\">\"]\n const lt = lex[\"<\"]\n if (gt && lt) return key >= gt && key <= lt\n\n if (gt) return key >= gt\n\n if (lt) return key <= lt\n\n return false\n}\n\nexport const text = {\n random: length => {\n var s = \"\"\n const c = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"\n if (!length) length = 24\n for (let i = 0; i < length; i++) {\n s += c.charAt(Math.floor(Math.random() * c.length))\n }\n return s\n },\n}\n", "const Dup = maxAge => {\n // Allow maxAge to be passed in as tests wait on the setTimeout.\n if (!maxAge) maxAge = 9000\n const dup = {store: {}}\n dup.check = id => (dup.store[id] ? dup.track(id) : false)\n dup.track = id => {\n // Keep the liveliness of the message up while it is being received.\n dup.store[id] = Date.now()\n if (!dup.expiry) {\n dup.expiry = setTimeout(() => {\n if (dup.expiry) return\n\n const now = Date.now()\n Object.keys(dup.store).forEach(id => {\n if (now - dup.store[id] > maxAge) delete dup.store[id]\n })\n dup.expiry = null\n }, maxAge)\n }\n return id\n }\n return dup\n}\n\nexport default Dup\n", "import {match, userPublicKey} from \"./utils.js\"\n\nconst Get = (lex, graph, fast) => {\n if (!lex || typeof lex !== \"object\") {\n throw new TypeError(\"lex must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n\n const soul = lex[\"#\"]\n if (!soul || typeof soul !== \"string\") {\n throw new TypeError(\"soul must be a string\")\n }\n\n if (!graph[soul]) return\n\n const node = {_: {\"#\": soul, \">\": {}}}\n let signatures = {}\n\n if (typeof lex[\".\"] === \"string\") {\n const key = lex[\".\"]\n if (typeof graph[soul][key] === \"undefined\") return\n\n node[key] = graph[soul][key]\n node._[\">\"][key] = graph[soul]._[\">\"][key]\n const state = graph[soul]._[\">\"][key]\n if (graph[soul]._[\"s\"] && graph[soul]._[\"s\"][state]) {\n signatures[state] = graph[soul]._[\"s\"][state]\n }\n\n // Always include userPublicKey for verification, regardless of filter\n if (userPublicKey && typeof graph[soul][userPublicKey] !== \"undefined\") {\n node[userPublicKey] = graph[soul][userPublicKey]\n node._[\">\"][userPublicKey] = graph[soul]._[\">\"][userPublicKey]\n const pkState = graph[soul]._[\">\"][userPublicKey]\n if (graph[soul]._[\"s\"] && graph[soul]._[\"s\"][pkState]) {\n signatures[pkState] = graph[soul]._[\"s\"][pkState]\n }\n }\n } else {\n // For fast requests, return properties currently in the graph. Otherwise\n // return undefined to ensure we get all matching properties from store.\n if (!fast) return\n\n for (const key of Object.keys(graph[soul])) {\n // Always include userPublicKey for verification, regardless of filter\n if (key === userPublicKey || match(lex[\".\"], key)) {\n node[key] = graph[soul][key]\n node._[\">\"][key] = graph[soul]._[\">\"][key]\n const state = graph[soul]._[\">\"][key]\n if (graph[soul]._[\"s\"] && graph[soul]._[\"s\"][state]) {\n signatures[state] = graph[soul]._[\"s\"][state]\n }\n }\n }\n }\n if (Object.keys(signatures).length > 0) {\n node._[\"s\"] = signatures\n }\n return {[soul]: node}\n}\n\nexport default Get\n", "if (typeof btoa === \"undefined\") {\n globalThis.btoa = data => Buffer.from(data, \"binary\").toString(\"base64\")\n globalThis.atob = data => Buffer.from(data, \"base64\").toString(\"binary\")\n}\n\n// This is Array extended to have .toString([\"utf8\"|\"hex\"|\"base64\"])\nfunction SeaArray() {}\nObject.assign(SeaArray, {from: Array.from})\nSeaArray.prototype = Object.create(Array.prototype)\n\nSeaArray.prototype.toString = function (enc, start, end) {\n if (!enc) enc = \"utf8\"\n if (!start) start = 0\n\n end = end ? Math.min(Math.max(end, start), this.length) : this.length\n\n if (enc === \"hex\") {\n const buf = new Uint8Array(this.slice(start, end))\n return Array.from(buf, byte => byte.toString(16).padStart(2, \"0\")).join(\"\")\n }\n\n if (enc === \"utf8\") {\n return Array.from({length: end - start}, (_, i) => {\n const charCode = this[i + start]\n // Use unicode replacement character for invalid character codes.\n if (charCode < 0 || charCode > 0x10ffff) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n }\n\n if (enc === \"base64\") {\n const utf8String = Array.from({length: end - start}, (_, i) => {\n const charCode = this[i + start]\n if (charCode < 0 || charCode > 255) {\n return String.fromCharCode(0xfffd)\n }\n return String.fromCharCode(charCode)\n }).join(\"\")\n return btoa(utf8String)\n }\n}\n\nexport default SeaArray\n", "import SeaArray from \"./array.js\"\n\n// Security constants\nconst SECURITY_LIMITS = {\n MAX_BUFFER_SIZE: 10 * 1024 * 1024, // 10MB limit\n MAX_STRING_LENGTH: 1024 * 1024, // 1MB string limit\n}\n\n// Secure Buffer implementation for SEA.js\n// Compatible with NodeJS safe-buffer but with enhanced security\nfunction SafeBuffer(...props) {\n console.warn(\"new SafeBuffer() is deprecated, please use SafeBuffer.from()\")\n return SafeBuffer.from(...props)\n}\n\nSafeBuffer.prototype = Object.create(Array.prototype)\n\n// Input validation helpers\nconst validateStringInput = (input, encoding) => {\n if (typeof input !== \"string\") {\n throw new TypeError(\"Input must be a string for encoding: \" + encoding)\n }\n\n if (input.length > SECURITY_LIMITS.MAX_STRING_LENGTH) {\n throw new RangeError(\n `String too large: ${input.length} > ${SECURITY_LIMITS.MAX_STRING_LENGTH}`,\n )\n }\n}\n\nconst validateBufferSize = (size, operation = \"buffer operation\") => {\n if (size > SECURITY_LIMITS.MAX_BUFFER_SIZE) {\n throw new RangeError(\n `Buffer size too large for ${operation}: ${size} > ${SECURITY_LIMITS.MAX_BUFFER_SIZE}`,\n )\n }\n}\n\n// Secure hex parsing\nconst parseHexString = hexString => {\n validateStringInput(hexString, \"hex\")\n\n // Remove any whitespace and convert to lowercase\n const cleanHex = hexString.replace(/\\s/g, \"\").toLowerCase()\n\n // Validate hex format: only 0-9, a-f characters\n if (!/^[0-9a-f]*$/.test(cleanHex)) {\n throw new TypeError(\"Invalid hex string: contains non-hex characters\")\n }\n\n // Must be even length\n if (cleanHex.length % 2 !== 0) {\n throw new TypeError(\"Invalid hex string: must have even length\")\n }\n\n if (cleanHex.length === 0) {\n return new Uint8Array(0)\n }\n\n validateBufferSize(cleanHex.length / 2, \"hex parsing\")\n\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < cleanHex.length; i += 2) {\n const hexByte = cleanHex.substr(i, 2)\n bytes[i / 2] = parseInt(hexByte, 16)\n }\n return bytes\n}\n\nconst encodeUtf8String = str => {\n validateStringInput(str, \"utf8\")\n\n try {\n // Use standard TextEncoder for proper UTF-8 encoding\n const encoder = new TextEncoder()\n const bytes = encoder.encode(str)\n\n validateBufferSize(bytes.length, \"UTF-8 encoding\")\n return bytes\n } catch (err) {\n throw new TypeError(\"Failed to encode UTF-8 string: \" + err.message)\n }\n}\n\nconst encodeBinaryString = str => {\n validateStringInput(str, \"binary\")\n\n validateBufferSize(str.length, \"binary encoding\")\n\n const bytes = new Uint8Array(str.length)\n for (let i = 0; i < str.length; i++) {\n const charCode = str.charCodeAt(i)\n\n // Binary strings should only contain bytes (0-255)\n if (charCode > 255) {\n throw new TypeError(\n `Invalid binary string: character at position ${i} exceeds byte range (${charCode} > 255)`,\n )\n }\n\n bytes[i] = charCode\n }\n return bytes\n}\n\n// Secure base64 decoding\nconst parseBase64String = base64String => {\n validateStringInput(base64String, \"base64\")\n\n // Remove any whitespace\n const cleanBase64 = base64String.replace(/\\s/g, \"\")\n\n // Validate base64 format\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\n throw new TypeError(\"Invalid base64 string: contains invalid characters\")\n }\n\n try {\n const decodedString = atob(cleanBase64)\n validateBufferSize(decodedString.length, \"base64 decoding\")\n\n const bytes = new Uint8Array(decodedString.length)\n for (let i = 0; i < decodedString.length; i++) {\n bytes[i] = decodedString.charCodeAt(i)\n }\n\n return bytes\n } catch (err) {\n throw new TypeError(\"Failed to decode base64 string: \" + err.message)\n }\n}\n\n// Secure array-like input processing\nconst processArrayLikeInput = input => {\n let bytes\n\n if (input instanceof ArrayBuffer) {\n validateBufferSize(input.byteLength, \"ArrayBuffer processing\")\n bytes = new Uint8Array(input)\n } else if (ArrayBuffer.isView(input)) {\n validateBufferSize(\n input.byteLength || input.length,\n \"TypedArray processing\",\n )\n bytes = new Uint8Array(input.buffer, input.byteOffset, input.byteLength)\n } else if (Array.isArray(input)) {\n validateBufferSize(input.length, \"Array processing\")\n\n // Validate all array elements are valid byte values\n for (let i = 0; i < input.length; i++) {\n const val = input[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`,\n )\n }\n }\n\n bytes = new Uint8Array(input)\n } else if (\n typeof input === \"object\" &&\n input !== null &&\n typeof input.byteLength === \"number\"\n ) {\n // Handle ArrayBuffer from different contexts (e.g. jsdom)\n validateBufferSize(input.byteLength, \"ArrayBuffer-like processing\")\n bytes = new Uint8Array(input)\n } else if (\n typeof input === \"object\" &&\n input !== null &&\n typeof input.length === \"number\"\n ) {\n // Handle array-like objects\n validateBufferSize(input.length, \"array-like processing\")\n\n const arr = Array.from(input)\n for (let i = 0; i < arr.length; i++) {\n const val = arr[i]\n if (\n typeof val !== \"number\" ||\n val < 0 ||\n val > 255 ||\n !Number.isInteger(val)\n ) {\n throw new TypeError(\n `Invalid byte value at index ${i}: ${val} (must be integer 0-255)`,\n )\n }\n }\n bytes = new Uint8Array(arr)\n } else {\n throw new TypeError(\"Unsupported input type: \" + typeof input)\n }\n\n return bytes\n}\n\nObject.assign(SafeBuffer, {\n from() {\n const argCount = arguments.length\n\n if (argCount === 0) {\n throw new TypeError(\"SafeBuffer.from() requires at least one argument\")\n }\n\n const input = arguments[0]\n\n if (input === null || input === undefined) {\n throw new TypeError(\"First argument must not be null or undefined\")\n }\n\n let bytes\n\n if (typeof input === \"string\") {\n const encoding = (arguments[1] || \"utf8\").toLowerCase()\n\n switch (encoding) {\n case \"hex\":\n bytes = parseHexString(input)\n break\n\n case \"utf8\":\n case \"utf-8\":\n bytes = encodeUtf8String(input)\n break\n\n case \"binary\":\n case \"latin1\":\n bytes = encodeBinaryString(input)\n break\n\n case \"base64\":\n bytes = parseBase64String(input)\n break\n\n case \"ascii\":\n // ASCII is subset of UTF-8, but validate range\n validateStringInput(input, \"ascii\")\n for (let i = 0; i < input.length; i++) {\n if (input.charCodeAt(i) > 127) {\n throw new TypeError(\n `Invalid ASCII character at position ${i}: ${input.charCodeAt(i)} > 127`,\n )\n }\n }\n bytes = encodeUtf8String(input) // Safe since ASCII is UTF-8 subset\n break\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n } else {\n bytes = processArrayLikeInput(input)\n }\n\n if (!bytes || bytes.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n try {\n return SeaArray.from(bytes)\n } catch (err) {\n throw new Error(\"Failed to create SafeBuffer: \" + err.message)\n }\n },\n\n alloc(length, fill = 0) {\n if (typeof length !== \"number\" || !Number.isInteger(length) || length < 0) {\n throw new TypeError(\"Length must be a non-negative integer\")\n }\n\n validateBufferSize(length, \"buffer allocation\")\n\n // Validate fill value\n if (typeof fill === \"number\") {\n if (fill < 0 || fill > 255 || !Number.isInteger(fill)) {\n throw new TypeError(\"Fill value must be an integer between 0 and 255\")\n }\n } else if (typeof fill === \"string\") {\n if (fill.length !== 1) {\n throw new TypeError(\"Fill string must be exactly one character\")\n }\n fill = fill.charCodeAt(0)\n if (fill > 255) {\n throw new TypeError(\"Fill character code must be <= 255\")\n }\n } else {\n throw new TypeError(\"Fill must be a number or single character string\")\n }\n\n try {\n const buffer = new Uint8Array(length)\n if (fill !== 0) {\n buffer.fill(fill)\n }\n return SeaArray.from(buffer)\n } catch (err) {\n throw new Error(\"Failed to allocate buffer: \" + err.message)\n }\n },\n\n concat(arr) {\n if (!Array.isArray(arr)) {\n throw new TypeError(\"First argument must be an array\")\n }\n\n if (arr.length === 0) {\n return SeaArray.from(new Uint8Array(0))\n }\n\n // Validate all array elements and calculate total size\n let totalLength = 0\n const validatedBuffers = []\n\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i]\n\n if (!item) {\n throw new TypeError(`Array element at index ${i} is null or undefined`)\n }\n\n let bytes\n try {\n bytes = processArrayLikeInput(item)\n } catch (err) {\n throw new TypeError(\n `Invalid array element at index ${i}: ${err.message}`,\n )\n }\n\n totalLength += bytes.length\n validateBufferSize(totalLength, \"buffer concatenation\")\n\n validatedBuffers.push(bytes)\n }\n\n try {\n const result = new Uint8Array(totalLength)\n let offset = 0\n\n for (const buffer of validatedBuffers) {\n result.set(buffer, offset)\n offset += buffer.length\n }\n\n return SeaArray.from(result)\n } catch (err) {\n throw new Error(\"Failed to concatenate buffers: \" + err.message)\n }\n },\n\n // Helper method to check if object is SafeBuffer\n isBuffer(obj) {\n return (\n obj instanceof SeaArray ||\n (obj && typeof obj === \"object\" && obj.constructor === SafeBuffer)\n )\n },\n\n // Get byte length of string in specific encoding\n byteLength(string, encoding = \"utf8\") {\n if (typeof string !== \"string\") {\n throw new TypeError(\"First argument must be a string\")\n }\n\n switch (encoding.toLowerCase()) {\n case \"utf8\":\n case \"utf-8\":\n return new TextEncoder().encode(string).length\n\n case \"ascii\":\n case \"binary\":\n case \"latin1\":\n return string.length\n\n case \"base64\":\n const clean = string.replace(/\\s/g, \"\")\n return (\n Math.floor((clean.length * 3) / 4) - (clean.match(/=/g) || []).length\n )\n\n case \"hex\":\n return Math.floor(string.replace(/\\s/g, \"\").length / 2)\n\n default:\n throw new TypeError(\"Unknown encoding: \" + encoding)\n }\n },\n})\n\nSafeBuffer.prototype.from = SafeBuffer.from\nSafeBuffer.prototype.toString = function (\n encoding = \"utf8\",\n start = 0,\n end = this.length,\n) {\n // Input validation\n if (typeof encoding !== \"string\") {\n throw new TypeError(\"Encoding must be a string\")\n }\n\n if (typeof start !== \"number\" || !Number.isInteger(start) || start < 0) {\n throw new TypeError(\"Start must be a non-negative integer\")\n }\n\n if (typeof end !== \"number\" || !Number.isInteger(end) || end < start) {\n throw new TypeError(\"End must be an integer >= start\")\n }\n\n // Delegate to SeaArray with validation\n try {\n return SeaArray.prototype.toString.call(this, encoding, start, end)\n } catch (err) {\n throw new Error(\"Failed to convert buffer to string: \" + err.message)\n }\n}\n\nexport default SafeBuffer\n", "import SafeBuffer from \"./buffer.js\"\n\nconst isNode = typeof document === \"undefined\"\nconst crypto = isNode\n ? (await import(/*webpackIgnore: true*/ \"node:crypto\")).webcrypto\n : globalThis.crypto\nexport const subtle = crypto.subtle\n\nexport const stringify = data => {\n return typeof data === \"string\" ? data : JSON.stringify(data)\n}\n\nexport const parse = text => {\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\nexport const random = length => {\n const array = new Uint8Array(SafeBuffer.alloc(length))\n return SafeBuffer.from(crypto.getRandomValues(array))\n}\n\nexport const jwk = (pub, priv) => {\n const [x, y] = pub.split(\".\")\n const ops = priv ? [\"sign\"] : [\"verify\"]\n return {\n kty: \"EC\",\n crv: \"P-256\",\n x: x,\n y: y,\n d: priv,\n ext: true,\n key_ops: ops,\n }\n}\n\nexport const sha256 = async data => {\n const hash = await subtle.digest(\n {name: \"SHA-256\"},\n new TextEncoder().encode(stringify(data)),\n )\n return SafeBuffer.from(hash)\n}\n\nexport const aeskey = async (key, salt) => {\n const combined = key + salt.toString(\"utf8\")\n const hash = SafeBuffer.from(await sha256(combined), \"binary\")\n const jwk = keyToJwk(hash)\n return await subtle.importKey(\"jwk\", jwk, {name: \"AES-GCM\"}, false, [\n \"encrypt\",\n \"decrypt\",\n ])\n}\n\nconst keyToJwk = key => {\n const k = key\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/\\=/g, \"\")\n return {kty: \"oct\", k: k, ext: false, alg: \"A256GCM\"}\n}\n", "import {userPublicKey, userSignature} from \"./utils.js\"\nimport * as utils from \"./sea-utils.js\"\nimport SafeBuffer from \"./buffer.js\"\n\n// Security, Encryption, and Authorization: SEA.js from GunDB.\nconst SEA = {\n pair: async cb => {\n // ECDSA keys for signing/verifying.\n const ecdsa = await utils.subtle\n .generateKey({name: \"ECDSA\", namedCurve: \"P-256\"}, true, [\n \"sign\",\n \"verify\",\n ])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n priv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d,\n pub: pub.x + \".\" + pub.y,\n }\n })\n\n // ECDH keys for encryption/decryption.\n const ecdh = await utils.subtle\n .generateKey({name: \"ECDH\", namedCurve: \"P-256\"}, true, [\"deriveKey\"])\n .then(async keys => {\n const pub = await utils.subtle.exportKey(\"jwk\", keys.publicKey)\n return {\n epriv: (await utils.subtle.exportKey(\"jwk\", keys.privateKey)).d,\n epub: pub.x + \".\" + pub.y,\n }\n })\n\n const pair = {\n pub: ecdsa.pub,\n priv: ecdsa.priv,\n epub: ecdh.epub,\n epriv: ecdh.epriv,\n }\n if (cb) cb(pair)\n return pair\n },\n encrypt: async (data, pair, cb) => {\n if (!pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const rand = {s: utils.random(9), iv: utils.random(15)}\n const ct = await utils.aeskey(pair.epriv, rand.s).then(aes => {\n return utils.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(rand.iv),\n },\n aes,\n new TextEncoder().encode(utils.stringify(data)),\n )\n })\n const enc = {\n ct: SafeBuffer.from(ct, \"binary\").toString(\"base64\"),\n iv: rand.iv.toString(\"base64\"),\n s: rand.s.toString(\"base64\"),\n }\n if (cb) cb(enc)\n return enc\n },\n decrypt: async (enc, pair, cb) => {\n if (!enc || !enc.ct || !enc.iv || !enc.s || !pair || !pair.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const data = {\n ct: SafeBuffer.from(enc.ct, \"base64\"),\n iv: SafeBuffer.from(enc.iv, \"base64\"),\n s: SafeBuffer.from(enc.s, \"base64\"),\n }\n try {\n const ct = await utils.aeskey(pair.epriv, data.s).then(aes => {\n return utils.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: new Uint8Array(data.iv),\n tagLength: 128,\n },\n aes,\n new Uint8Array(data.ct),\n )\n })\n const dec = utils.parse(new TextDecoder(\"utf8\").decode(ct))\n if (cb) cb(dec)\n return dec\n } catch (err) {\n // An error will be thrown if the wrong key is used.\n if (cb) cb(null)\n return null\n }\n },\n verify: async (data, pair, cb) => {\n if (!pair || !pair.pub) {\n if (cb) cb(null)\n return null\n }\n\n const signed = utils.parse(data)\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(pair.pub),\n {name: \"ECDSA\", namedCurve: \"P-256\"},\n false,\n [\"verify\"],\n )\n\n let msg = {}\n if (typeof signed.m === \"string\") {\n msg = signed.m\n } else {\n // Allow data to be passed in with graph meta data,\n // (which should not be part of signature, so not verified).\n for (const k of Object.keys(signed.m).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n msg[k] = signed.m[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const sig = new Uint8Array(SafeBuffer.from(signed.s, \"base64\"))\n const alg = {name: \"ECDSA\", hash: {name: \"SHA-256\"}}\n if (await utils.subtle.verify(alg, key, sig, new Uint8Array(hash))) {\n const verified = utils.parse(signed.m)\n if (cb) cb(verified)\n return verified\n }\n\n if (cb) cb(null)\n return null\n },\n sign: async (data, pair, cb) => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n let msg = {}\n if (typeof data === \"string\") {\n msg = data\n } else {\n const check = utils.parse(data)\n for (const k of Object.keys(check).sort()) {\n if (k !== \"_\" && k !== userPublicKey && k !== userSignature) {\n msg[k] = check[k]\n }\n }\n }\n const hash = await utils.sha256(msg)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = {name: \"ECDSA\", namedCurve: \"P-256\"}\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n {name: \"ECDSA\", hash: {name: \"SHA-256\"}},\n key,\n new Uint8Array(hash),\n ),\n )\n const signed = {\n m: msg,\n s: SafeBuffer.from(sig, \"binary\").toString(\"base64\"),\n }\n\n if (cb) cb(signed)\n return signed\n },\n // Sign a timestamp to prove ownership of an update\n signTimestamp: async (timestamp, pair, cb) => {\n if (!pair || !pair.pub || !pair.priv) {\n if (cb) cb(null)\n return null\n }\n\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n const jwk = utils.jwk(pair.pub, pair.priv)\n const alg = {name: \"ECDSA\", namedCurve: \"P-256\"}\n\n const sig = await utils.subtle\n .importKey(\"jwk\", jwk, alg, false, [\"sign\"])\n .then(key =>\n utils.subtle.sign(\n {name: \"ECDSA\", hash: {name: \"SHA-256\"}},\n key,\n new Uint8Array(hash),\n ),\n )\n\n const signature = SafeBuffer.from(sig, \"binary\").toString(\"base64\")\n\n if (cb) cb(signature)\n return signature\n },\n // Verify a timestamp signature to confirm ownership of update\n verifyTimestamp: async (timestamp, signature, publicKey, cb) => {\n if (!publicKey || !timestamp || !signature) {\n if (cb) cb(false)\n return false\n }\n\n try {\n // Convert timestamp to string for consistent hashing\n const timestampStr = timestamp.toString()\n const hash = await utils.sha256(timestampStr)\n\n const key = await utils.subtle.importKey(\n \"jwk\",\n utils.jwk(publicKey),\n {name: \"ECDSA\", namedCurve: \"P-256\"},\n false,\n [\"verify\"],\n )\n\n const sig = new Uint8Array(SafeBuffer.from(signature, \"base64\"))\n const alg = {name: \"ECDSA\", hash: {name: \"SHA-256\"}}\n\n const isValid = await utils.subtle.verify(\n alg,\n key,\n sig,\n new Uint8Array(hash),\n )\n\n if (cb) cb(isValid)\n return isValid\n } catch (err) {\n console.log(`error verifying timestamp signature: ${err.message}`)\n if (cb) cb(false)\n return false\n }\n },\n work: async (data, salt, cb) => {\n if (typeof salt === \"function\") {\n cb = salt\n salt = undefined\n }\n if (typeof salt === \"undefined\") salt = utils.random(9)\n\n const key = await utils.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(utils.stringify(data)),\n {name: \"PBKDF2\"},\n false,\n [\"deriveBits\"],\n )\n const alg = {\n name: \"PBKDF2\",\n iterations: 100000,\n salt: new TextEncoder().encode(salt),\n hash: {name: \"SHA-256\"},\n }\n const work = await utils.subtle.deriveBits(alg, key, 512)\n // Use \"pair\" format so that work can be used as epriv by decrypt.\n const pair = {epriv: SafeBuffer.from(work, \"binary\").toString(\"base64\")}\n if (cb) cb(pair)\n return pair\n },\n secret: async (to, from, cb) => {\n if (!to || !to.epub || !from || !from.epub || !from.epriv) {\n if (cb) cb(null)\n return null\n }\n\n const alg = {name: \"ECDH\", namedCurve: \"P-256\"}\n const pub = utils.jwk(to.epub)\n const pubKey = await utils.subtle.importKey(\"jwk\", pub, alg, true, [])\n const priv = utils.jwk(from.epub, from.epriv, false)\n // utils.jwk provides default key_ops but it shouldn't be used here.\n delete priv.key_ops\n const derived = await utils.subtle\n .importKey(\"jwk\", priv, alg, false, [\"deriveBits\"])\n .then(async key => {\n const derivedBits = await utils.subtle.deriveBits(\n {public: pubKey, name: \"ECDH\", namedCurve: \"P-256\"},\n key,\n 256,\n )\n const derivedKey = await utils.subtle.importKey(\n \"raw\",\n new Uint8Array(derivedBits),\n {name: \"AES-GCM\", length: 256},\n true,\n [\"encrypt\", \"decrypt\"],\n )\n return utils.subtle.exportKey(\"jwk\", derivedKey).then(({k}) => k)\n })\n // Use \"pair\" format so that secret can be used as epriv by encrypt.\n if (cb) cb({epriv: derived})\n return {epriv: derived}\n },\n}\n\nexport default SEA\n", "import * as utils from \"./utils.js\"\nimport SEA from \"./sea.js\"\n\n// Maximum number of souls to keep in memory\nconst MAX_GRAPH_SIZE = 10000\n\n// state and value are the incoming changes.\n// currentState and currentValue are the current graph data.\nconst Ham = (state, currentState, value, currentValue, signed = false) => {\n if (state < currentState) return {historical: true}\n\n if (state > currentState) return {incoming: true}\n\n // state is equal to currentState. Old data is expected to propagate through\n // the network, but conflicting values with same signed timestamp are ignored\n // since the owner can only create one value per timestamp.\n if (signed && value !== currentValue) {\n return {historical: true}\n }\n\n // Lexically compare to resolve conflict (for unsigned or matching values)\n if (typeof value !== \"string\") {\n value = JSON.stringify(value) || \"\"\n }\n if (typeof currentValue !== \"string\") {\n currentValue = JSON.stringify(currentValue) || \"\"\n }\n // No update required.\n if (value === currentValue) return {state: true}\n\n // Keep the current value.\n if (value < currentValue) return {current: true}\n\n // Otherwise update using the incoming value.\n return {incoming: true}\n}\n\nHam.mix = async (change, graph, secure, listen) => {\n if (!change || typeof change !== \"object\") {\n throw new TypeError(\"change must be an object\")\n }\n if (!graph || typeof graph !== \"object\") {\n throw new TypeError(\"graph must be an object\")\n }\n if (!listen || typeof listen !== \"object\") {\n throw new TypeError(\"listen must be an object\")\n }\n\n const machine = Date.now()\n const now = {}\n const defer = {}\n const listeners = [] // Collect listeners to fire after store.put\n const validProperties = new Map() // Track valid properties per soul\n const validTimestamps = new Map() // Track valid timestamps per soul\n let wait = 0\n\n for (const soul of Object.keys(change)) {\n const node = change[soul]\n let updated = false\n let alias = false\n let nodeWait = 0\n let verify = secure\n\n if (!node || !node._) continue\n\n const pub = node[utils.userPublicKey]\n // If timestamp signatures and public key are provided then always verify\n if (node._[\"s\"] && pub) verify = true\n\n // Special case if soul starts with \"~\". Node must be system data ie,\n // ~@alias or ~publickey. For aliases, key and value must be a self\n // identifying rel. For public keys, data needs to be signed and verified.\n // (This is also true for any data when the secure flag is used.)\n if (soul.length > 1 && soul[0] === \"~\") {\n if (soul[1] === \"@\") {\n alias = true\n verify = false\n } else {\n if (pub && soul != \"~\" + pub) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n\n verify = true\n }\n }\n if (verify) {\n // Signature verification: check node._[\"s\"] which can contain:\n // 1. Per-property signatures (legacy): keys are property names\n // 2. Timestamp signatures (new): keys are numeric timestamps\n if (!pub || !node._) {\n continue\n }\n\n const signedTimestamps = new Set()\n const signedProperties = new Set()\n\n // Skip verification of timestamps that are older than what's in the graph\n // to prevent old signatures from distributed messages causing conflicts\n const incomingTimestamps = Object.entries(node._[\">\"] || {})\n\n for (const [key, sig] of Object.entries(node._[\"s\"] || {})) {\n const asNumber = Number(key)\n if (!isNaN(asNumber) && asNumber > 0) {\n // Skip verification only if ALL properties for this timestamp are\n // already newer in the graph. Using some() would incorrectly skip\n // valid updates when only one property in a batch is outdated.\n const propsForTimestamp = incomingTimestamps.filter(\n ([, ts]) => Number(ts) === asNumber,\n )\n const allNewerInGraph =\n propsForTimestamp.length > 0 &&\n propsForTimestamp.every(([prop]) => {\n const graphState =\n graph[soul] && graph[soul]._[\">\"] ? graph[soul]._[\">\"][prop] : 0\n return graphState > asNumber\n })\n\n if (allNewerInGraph) {\n continue\n }\n\n const isValid = await SEA.verifyTimestamp(asNumber, sig, pub)\n if (isValid) {\n signedTimestamps.add(asNumber)\n // Add all properties with this timestamp to signed set\n for (const [prop, ts] of incomingTimestamps) {\n if (Number(ts) === asNumber) {\n signedProperties.add(prop)\n }\n }\n }\n }\n }\n\n // If no properties verified, skip this update\n if (signedProperties.size === 0) {\n continue\n }\n\n // Track signed properties and timestamps for this soul\n validProperties.set(soul, signedProperties)\n validTimestamps.set(soul, signedTimestamps)\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n // Properties without signatures in this update are left unchanged\n if (validProperties.has(soul) && !validProperties.get(soul).has(key)) {\n continue\n }\n\n const value = node[key]\n const state = node._ && node._[\">\"] ? node._[\">\"][key] : 0\n const currentValue = (graph[soul] || {})[key]\n const currentState = (graph[soul] || {_: {\">\": {}}})._[\">\"][key] || 0\n\n if (alias && key !== utils.rel.is(value)) {\n console.log(`error alias ${alias}: ${key} !== ${utils.rel.is(value)}`)\n continue\n }\n\n // Defer the update if ahead of machine time.\n const skew = state - machine\n if (skew > 0) {\n // Ignore update if ahead by more than 24 hours.\n if (skew > 86400000) continue\n\n // Wait the shortest difference before trying the updates again.\n if (wait === 0 || skew < wait) wait = nodeWait = skew\n if (!defer[soul]) {\n defer[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n defer[soul][key] = value\n defer[soul]._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n defer[soul]._[\"s\"][state] = node._[\"s\"][state]\n }\n } else {\n // Check if this property has a signed timestamp\n const isSigned =\n validTimestamps.has(soul) && validTimestamps.get(soul).has(state)\n const result = Ham(state, currentState, value, currentValue, isSigned)\n if (result.incoming) {\n if (!now[soul]) {\n now[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n if (!graph[soul]) {\n graph[soul] = {_: {\"#\": soul, \">\": {}, s: {}}}\n }\n graph[soul][key] = now[soul][key] = value\n graph[soul]._[\">\"][key] = now[soul]._[\">\"][key] = state\n if (node._[\"s\"] && node._[\"s\"][state]) {\n graph[soul]._[\"s\"][state] = now[soul]._[\"s\"][state] =\n node._[\"s\"][state]\n }\n // Collect event listeners to fire after store.put completes.\n // This ensures listeners always fire with data that's been stored.\n if (listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => listeners.push(l.cb))\n }\n updated = true\n }\n }\n }\n\n // Collect event listeners for update on soul.\n if (updated && listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"]))\n .forEach(l => listeners.push(l.cb))\n }\n }\n\n const souls = Object.keys(graph)\n if (souls.length > MAX_GRAPH_SIZE) {\n // Sort by oldest state timestamp and remove oldest entries\n const soulsByAge = souls\n .map(soul => {\n const states = graph[soul]._ && graph[soul]._[\">\"]\n const maxState = states ? Math.max(...Object.values(states)) : 0\n return {soul, maxState}\n })\n .sort((a, b) => a.maxState - b.maxState)\n const remove = soulsByAge.slice(0, souls.length - MAX_GRAPH_SIZE)\n remove.forEach(({soul}) => delete graph[soul])\n }\n\n return {now: now, defer: defer, wait: wait, listeners: listeners}\n}\n\nexport default Ham\n", "import * as utils from \"./utils.js\"\n\n// ASCII character for group separator.\nconst group = String.fromCharCode(29)\n// ASCII character for record separator.\nconst record = String.fromCharCode(30)\n\nconst Radix = () => {\n const radix = (keys, value, tree) => {\n if (!tree) {\n if (!radix[group]) radix[group] = {}\n tree = radix[group]\n }\n if (!keys) return tree\n\n let i = 0\n let tmp = {}\n let key = keys[i]\n const max = keys.length - 1\n const noValue = typeof value === \"undefined\"\n // Find a matching value using the shortest string from keys.\n let found = tree[key]\n while (!found && i < max) {\n key += keys[++i]\n found = tree[key]\n }\n\n if (!found) {\n // If not found from the provided keys try matching with an existing key.\n const result = utils.obj.map(tree, (hasValue, hasKey) => {\n let j = 0\n let matchingKey = \"\"\n while (hasKey[j] === keys[j]) {\n matchingKey += hasKey[j++]\n }\n if (matchingKey) {\n if (noValue) {\n // matchingKey has to be as long as the original keys when reading.\n if (j <= max) return\n\n tmp[hasKey.slice(j)] = hasValue\n return hasValue\n }\n\n let replace = {\n [hasKey.slice(j)]: hasValue,\n [keys.slice(j)]: {[record]: value},\n }\n tree[matchingKey] = {[group]: replace}\n delete tree[hasKey]\n return true\n }\n })\n if (!result) {\n if (noValue) return\n\n if (!tree[key]) tree[key] = {}\n tree[key][record] = value\n } else if (noValue) {\n return tmp\n }\n } else if (i === max) {\n // If no value use the key provided to return a whole group or record.\n if (noValue) {\n // If an individual record isn't found then return the whole group.\n return typeof found[record] === \"undefined\"\n ? found[group]\n : found[record]\n }\n // Otherwise create a new record at the provided key for value.\n found[record] = value\n } else {\n // Found at a shorter key, try again.\n if (!found[group] && !noValue) found[group] = {}\n return radix(keys.slice(++i), value, found[group])\n }\n }\n return radix\n}\n\nRadix.map = function map(radix, cb, opt, pre) {\n if (!pre) pre = []\n var tree = radix[group] || radix\n var keys = Object.keys(tree).sort()\n var u\n\n for (let i = 0; i < keys.length; i++) {\n let key = keys[i]\n let found = tree[key]\n let tmp = found[record]\n if (typeof tmp !== \"undefined\") {\n tmp = cb(tmp, pre.join(\"\") + key, key, pre)\n if (typeof tmp !== \"undefined\") return tmp\n } else if (opt) {\n cb(u, pre.join(\"\"), key, pre)\n }\n if (found[group]) {\n pre.push(key)\n tmp = map(found[group], cb, opt, pre)\n if (typeof tmp !== \"undefined\") return tmp\n pre.pop()\n }\n }\n}\n\nexport default Radix\n", "import Radix from \"./radix.js\"\nimport * as utils from \"./utils.js\"\n\n// ASCII character for end of text\nconst etx = String.fromCharCode(3)\n// ASCII character for enquiry\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator\nconst unit = String.fromCharCode(31)\n\n// Radisk provides access to a radix tree that is stored in the provided\n// opt.store interface\nconst Radisk = opt => {\n var u\n\n // Multi-file cache for all parsed radix trees\n const cache = new Map()\n // File listing cache to avoid repeated directory scans\n let fileListCache = null\n let fileListCacheTime = 0\n const FILE_LIST_CACHE_TTL = 10000 // 10 seconds\n // Pending reads queue to avoid duplicate reads for the same key\n const pendingReads = new Map()\n\n // Memory monitoring and cleanup\n let lastMemoryCheck = 0\n const MEMORY_CHECK_INTERVAL = 30000 // Check every 30 seconds\n const HEAP_WARNING_THRESHOLD = 0.8 // Warn at 80% of max heap size\n const HEAP_CLEANUP_THRESHOLD = 0.9 // Clean cache at 90% of max heap size\n\n if (!opt) opt = {}\n if (!opt.log) opt.log = console.log\n if (!opt.batch) opt.batch = 100 // Balanced batch size for performance\n if (!opt.write) opt.write = 1 // Wait time before write in milliseconds\n if (!opt.size) opt.size = 1024 * 1024 // File size on disk, default 1MB\n if (!opt.memoryLimit) opt.memoryLimit = 500 // Memory limit in MB\n if (!opt.readTimeout) opt.readTimeout = 1000 // Read timeout in milliseconds\n if (typeof opt.cache === \"undefined\") opt.cache = true\n\n if (!opt.store) {\n opt.log(\n \"Radisk needs `store` interface with `{get: fn, put: fn, list: fn}`\",\n )\n return\n }\n if (!opt.store.get) {\n opt.log(\"Radisk needs `store.get` interface with `(file, cb)`\")\n return\n }\n if (!opt.store.put) {\n opt.log(\"Radisk needs `store.put` interface with `(file, data, cb)`\")\n return\n }\n if (!opt.store.list) {\n opt.log(\"Radisk needs a streaming `store.list` interface with `(cb)`\")\n return\n }\n\n // Performance logging\n const perfLog = (operation, startTime, key, size) => {\n const duration = Date.now() - startTime\n if (duration > 2000) {\n console.log(\n `[RADISK-SLOW] ${operation}: ${duration}ms for ${key}${size ? ` (${size} bytes)` : \"\"}`,\n )\n }\n }\n\n // Memory monitoring and cache cleanup\n const checkMemoryUsage = () => {\n if (typeof process === \"undefined\" || !process.memoryUsage) return\n\n const now = Date.now()\n if (now - lastMemoryCheck < MEMORY_CHECK_INTERVAL) return\n lastMemoryCheck = now\n\n const memUsage = process.memoryUsage()\n const heapUsed = memUsage.heapUsed\n const heapTotal = memUsage.heapTotal\n const maxHeapSize = opt.memoryLimit * 1024 * 1024\n const heapUsageRatio = heapUsed / maxHeapSize\n\n if (heapUsageRatio > HEAP_CLEANUP_THRESHOLD) {\n const cacheSize = cache.size\n console.log(\n `[RADISK-MEMORY] High memory usage: ${Math.round(heapUsageRatio * 100)}% of heap limit. Clearing ${cacheSize} cached files.`,\n )\n cache.clear()\n // Force garbage collection if available\n if (global.gc) {\n global.gc()\n }\n // Reset timer to avoid immediate re-check until GC has time to work\n lastMemoryCheck = now + MEMORY_CHECK_INTERVAL\n } else if (heapUsageRatio > HEAP_WARNING_THRESHOLD) {\n console.log(\n `[RADISK-MEMORY] Memory warning: ${Math.round(heapUsageRatio * 100)}% of heap limit used. Cache size: ${cache.size} files.`,\n )\n }\n }\n\n // Any and all storage adapters should:\n // 1. Because writing to disk takes time, we should batch data to disk.\n // This improves performance, and reduces potential disk corruption.\n // 2. If a batch exceeds a certain number of writes, we should immediately\n // write to disk when physically possible. This caps total performance,\n // but reduces potential loss.\n const radisk = (key, value, cb) => {\n key = \"\" + key\n\n // If no value is provided then the second parameter is the callback\n // function. Read value from memory or disk and call callback with it.\n if (typeof value === \"function\") {\n cb = value\n value = radisk.batch(key)\n if (typeof value !== \"undefined\") {\n return cb(u, value)\n }\n\n if (radisk.thrash.at) {\n value = radisk.thrash.at(key)\n if (typeof value !== \"undefined\") {\n return cb(u, value)\n }\n }\n\n // Check if there's already a pending read for this key\n if (pendingReads.has(key)) {\n // Add callback to existing pending read\n pendingReads.get(key).callbacks.push(cb)\n return\n }\n\n // Start new read and create callback queue with fired flag\n const pending = {callbacks: [cb], fired: false, timeoutId: null}\n pendingReads.set(key, pending)\n\n // Set a timeout to fire callbacks if read takes too long\n pending.timeoutId = setTimeout(() => {\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n const err = new Error(\"radisk read timeout\")\n pending.callbacks.forEach(callback => callback(err, undefined))\n }\n }, opt.readTimeout)\n\n const readStart = Date.now()\n return radisk.read(key, (err, result) => {\n clearTimeout(pending.timeoutId)\n perfLog(\"read\", readStart, key)\n // Execute all pending callbacks for this key if timeout hasn't fired\n if (!pending.fired) {\n pending.fired = true\n pendingReads.delete(key)\n pending.callbacks.forEach(callback => callback(err, result))\n }\n })\n }\n\n // Otherwise store the value provided.\n radisk.batch(key, value)\n // Check memory usage after writing to in-memory radix tree\n checkMemoryUsage()\n if (cb) {\n radisk.batch.acks.push(cb)\n }\n // Don't wait if we have batched too many.\n if (++radisk.batch.ed >= opt.batch) {\n return radisk.thrash()\n }\n\n // Otherwise wait for more updates before writing.\n clearTimeout(radisk.batch.timeout)\n radisk.batch.timeout = setTimeout(radisk.thrash, opt.write)\n }\n\n radisk.batch = Radix()\n radisk.batch.acks = []\n radisk.batch.ed = 0\n\n radisk.thrash = () => {\n if (radisk.thrash.ing) {\n return (radisk.thrash.more = true)\n }\n\n const thrashStart = Date.now()\n clearTimeout(radisk.batch.timeout)\n radisk.thrash.more = false\n radisk.thrash.ing = true\n var batch = (radisk.thrash.at = radisk.batch)\n radisk.batch = null\n radisk.batch = Radix()\n radisk.batch.acks = []\n radisk.batch.ed = 0\n let i = 0\n radisk.save(batch, err => {\n // This is to ignore multiple callbacks from radisk.save calling\n // radisk.write? It looks like multiple callbacks will be made if a\n // file needs to be split.\n if (++i > 1) return\n\n perfLog(\"thrash\", thrashStart, `batch-${batch.ed}`)\n if (err) opt.log(err)\n batch.acks.forEach(cb => cb(err))\n radisk.thrash.at = null\n radisk.thrash.ing = false\n if (radisk.thrash.more) radisk.thrash()\n })\n }\n\n // 1. Find the first radix item in memory\n // 2. Use that as the starting index in the directory of files\n // 3. Find the first file that is lexically larger than it\n // 4. Read the previous file into memory\n // 5. Scan through in memory radix for all values lexically less than limit\n // 6. Merge and write all of those to the in-memory file and back to disk\n radisk.save = (rad, cb) => {\n const save = {\n find: (tree, key) => {\n // This is false for any key until save.start is set to an initial key.\n if (key < save.start) return\n\n save.start = key\n opt.store.list(save.lex)\n return true\n },\n lex: file => {\n if (!file || file > save.start) {\n save.end = file\n // ! is used as the first file name as it's the first printable\n // character, so always matches as lexically less than any node.\n // Also save.start can be set to undefined by a previous call to\n // save.mix, so don't continue in this case.\n if (save.start) save.mix(save.file || \"!\", save.start, save.end)\n } else {\n save.file = file\n }\n },\n mix: (file, start, end) => {\n save.start = save.end = save.file = u\n // Use cache if available, otherwise parse from disk\n if (cache.has(file)) {\n const disk = cache.get(file)\n Radix.map(rad, (value, key) => {\n if (key < start) return\n\n if (end && end < key) {\n save.start = key\n return\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\n } else {\n radisk.parse(file, (err, disk) => {\n if (err) return cb(err)\n\n Radix.map(rad, (value, key) => {\n if (key < start) return\n\n if (end && end < key) {\n save.start = key\n return\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\n })\n }\n },\n next: err => {\n if (err) return cb(err)\n\n if (save.start) return Radix.map(rad, save.find)\n\n cb(err)\n },\n }\n Radix.map(rad, save.find)\n }\n\n radisk.write = (file, rad, cb) => {\n const write = {\n text: \"\",\n limit: \"\",\n done: false,\n count: 0,\n each: (value, key, k, pre) => {\n // each is called for all keys, but stop adding to write.text when\n // write.slice is called, then the current contents of write.text\n // will be written to file.\n if (write.done) return\n\n write.count++\n value = typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)\n const enc =\n Radisk.encode(pre.length) + \"#\" + Radisk.encode(k) + value + \"\\n\"\n // Cannot split the file if only have one entry to write. Also don't\n // start a split if in the middle of writing a node (pre > 0).\n if (\n write.count > 1 &&\n pre.length === 0 &&\n write.text.length + enc.length > opt.size\n ) {\n const end = k.indexOf(enq)\n write.limit = end === -1 ? k : k.substring(0, end)\n // Cannot split if they key is the same as the current file name.\n if (write.limit !== file) {\n write.done = true\n write.sub = Radix()\n Radix.map(rad, write.slice)\n radisk.write(write.limit, write.sub, cb)\n return\n }\n }\n\n write.text += enc\n },\n slice: (value, key) => {\n if (key < write.limit) return\n\n write.sub(key, value)\n },\n }\n Radix.map(rad, write.each, true)\n // There is always accumulated write.text to store once write.each has\n // finished.\n const writeStart = Date.now()\n opt.store.put(file, write.text, err => {\n perfLog(\"file-write\", writeStart, file, write.text.length)\n cb(err)\n })\n }\n\n radisk.read = (key, cb) => {\n // Only the soul of the key is compared to filenames (see radisk.write).\n const end = key.indexOf(enq)\n const soul = end === -1 ? key : key.substring(0, end)\n\n const read = {\n lex: file => {\n // store.list should call lex without a file last, which means all file\n // names were compared to soul, so the current read.file is ok to use.\n if (!file) {\n if (!read.file) {\n cb(\"no file found\", u)\n return\n }\n\n // Check multi-file cache first\n if (opt.cache && cache.has(read.file)) {\n const cachedRadix = cache.get(read.file)\n read.value = cachedRadix(key)\n // Return cached result (defined or undefined) since in-memory\n // radix tree is authoritative\n return cb(u, read.value)\n }\n\n radisk.parse(read.file, read.it)\n return\n }\n\n // Want the filename closest to soul.\n if (file > soul || file < read.file) return\n\n read.file = file\n },\n it: (err, disk) => {\n if (err) opt.log(err)\n if (disk) {\n if (opt.cache) {\n cache.set(read.file, disk)\n checkMemoryUsage() // Check memory usage after adding to cache\n }\n read.value = disk(key)\n }\n cb(err, read.value)\n },\n }\n const now = Date.now()\n if (\n opt.cache &&\n fileListCache &&\n now - fileListCacheTime < FILE_LIST_CACHE_TTL\n ) {\n // Use cached file list\n fileListCache.forEach(file => read.lex(file))\n read.lex() // Signal end of list\n } else {\n // Refresh cache\n const files = []\n const originalLex = read.lex\n read.lex = file => {\n if (file) files.push(file)\n return originalLex(file)\n }\n\n opt.store.list(file => {\n read.lex(file)\n if (!file && opt.cache) {\n // End of list - cache the results\n fileListCache = files\n fileListCacheTime = now\n }\n })\n }\n }\n\n // Let us start by assuming we are the only process that is\n // changing the directory or bucket. Not because we do not want\n // to be multi-process/machine, but because we want to experiment\n // with how much performance and scale we can get out of only one.\n // Then we can work on the harder problem of being multi-process.\n radisk.parse = (file, cb) => {\n const parse = {\n disk: Radix(),\n read: (err, data) => {\n if (err) return cb(err)\n\n if (!data) return cb(u, parse.disk)\n\n let pre = []\n let preString = \"\"\n // Work though data by splitting into 3 values. The first value says\n // if the second value is one of: the radix level for a key, the key\n // iteself, or a value. The third is the rest of the data to work with.\n let tmp = parse.split(data)\n while (tmp) {\n let key\n let value\n let i = tmp[1]\n tmp = parse.split(tmp[2]) || \"\"\n if (tmp[0] === \"#\") {\n key = tmp[1]\n // Optimize prefix building - avoid repeated joins\n if (i < pre.length) {\n pre.length = i\n }\n if (i <= pre.length) {\n pre[i] = key\n pre.length = i + 1\n }\n // Only rebuild preString when prefix changes\n preString = pre.join(\"\")\n }\n tmp = parse.split(tmp[2]) || \"\"\n if (tmp[0] === \"\\n\") continue\n\n if (tmp[0] === \"=\") value = tmp[1]\n if (typeof key !== \"undefined\" && typeof value !== \"undefined\") {\n parse.disk(preString, value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(u, parse.disk)\n },\n split: data => {\n if (!data) return\n\n const i = data.indexOf(unit)\n if (i === -1) return\n\n const a = data.slice(0, i)\n let o = {}\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i)]\n },\n }\n opt.store.get(file, parse.read)\n }\n\n return radisk\n}\n\nRadisk.encode = data => {\n // A key should be passed in as a string to encode, a value can optionally be\n // an array of 2-3 items: [value, state] or [value, state, signature].\n let state = \"\"\n let sig = \"\"\n if (data instanceof Array && (data.length === 2 || data.length === 3)) {\n state = etx + data[1]\n if (data.length === 3 && data[2]) {\n sig = etx + data[2]\n }\n data = data[0]\n }\n\n if (typeof data === \"string\") {\n let i = 0\n let current = null\n let text = unit\n while ((current = data[i++])) {\n if (current === unit) text += unit\n }\n return text + '\"' + data + state + sig + unit\n }\n\n const rel = utils.rel.is(data)\n if (rel) return unit + \"#\" + rel + state + sig + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + sig + unit\n\n if (data === true) return unit + \"+\" + state + sig + unit\n\n if (data === false) return unit + \"-\" + state + sig + unit\n\n if (data === null) return unit + \" \" + state + sig + unit\n}\n\nRadisk.decode = (data, obj) => {\n var i = -1\n var n = 0\n var current = null\n var previous = null\n var textStart = -1\n var textEnd = -1\n if (data[0] !== unit) return\n\n // Find a control character previous to the text we want, skipping\n // consecutive unit separator characters at the beginning of the data.\n while ((current = data[++i])) {\n if (previous) {\n if (textStart === -1) textStart = i\n if (current === unit) {\n if (--n <= 0) {\n textEnd = i\n break\n }\n }\n } else if (current === unit) {\n n++\n } else {\n previous = current || true\n }\n }\n\n const text =\n textStart !== -1 ? data.slice(textStart, textEnd !== -1 ? textEnd : i) : \"\"\n\n if (obj) obj.i = i + 1\n\n let parts = text.split(etx)\n let value = parts[0]\n let state = parts[1]\n let sig = parts[2]\n\n if (!state) {\n if (previous === '\"') return text\n\n if (previous === \"#\") return utils.rel.ify(text)\n\n if (previous === \"+\") {\n if (text.length === 0) return true\n\n return parseFloat(text)\n }\n\n if (previous === \"-\") return false\n\n if (previous === \" \") return null\n } else {\n state = parseFloat(state)\n // If state was found then return an array with [value, state] or [value, state, sig]\n if (sig) {\n if (previous === '\"') return [value, state, sig]\n\n if (previous === \"#\") return [utils.rel.ify(value), state, sig]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, state, sig]\n\n return [parseFloat(value), state, sig]\n }\n\n if (previous === \"-\") return [false, state, sig]\n\n if (previous === \" \") return [null, state, sig]\n } else {\n if (previous === '\"') return [value, state]\n\n if (previous === \"#\") return [utils.rel.ify(value), state]\n\n if (previous === \"+\") {\n if (value.length === 0) return [true, state]\n\n return [parseFloat(value), state]\n }\n\n if (previous === \"-\") return [false, state]\n\n if (previous === \" \") return [null, state]\n }\n }\n}\n\nexport default Radisk\n", "import Radisk from \"./radisk.js\"\nimport Radix from \"./radix.js\"\nimport * as utils from \"./utils.js\"\n\nconst isNode = typeof document === \"undefined\"\nconst fs = isNode ? await import(/*webpackIgnore: true*/ \"node:fs\") : undefined\n\n// ASCII character for enquiry.\nconst enq = String.fromCharCode(5)\n// ASCII character for unit separator.\nconst unit = String.fromCharCode(31)\n// On-disk root node format.\nconst root = unit + \"+0\" + unit + \"#\" + unit + '\"root' + unit\n\nconst fileSystem = opt => {\n const dir = opt.file\n\n if (isNode) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir)\n if (!fs.existsSync(dir + \"/!\")) fs.writeFileSync(dir + \"/!\", root)\n\n return {\n get: (file, cb) => {\n fs.readFile(dir + \"/\" + file, (err, data) => {\n if (err) {\n if (err.code === \"ENOENT\") {\n cb()\n return\n }\n\n console.log(\"fs.readFile error:\", err)\n }\n if (data) data = data.toString()\n cb(err, data)\n })\n },\n put: (file, data, cb) => {\n // Don't put tmp files under dir so that they're not listed.\n var tmp = file + \".\" + utils.text.random(9) + \".tmp\"\n fs.writeFile(tmp, data, err => {\n if (err) {\n console.log(\"fs.writeFile error:\", err)\n cb(err)\n return\n }\n\n fs.rename(tmp, dir + \"/\" + file, cb)\n })\n },\n list: cb => {\n fs.readdir(dir, (err, files) => {\n if (err) {\n console.log(\"fs.readdir error:\", err)\n cb()\n return\n }\n\n files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db\n const dbReady = new Promise((resolve, reject) => {\n const o = indexedDB.open(dir, 1)\n o.onupgradeneeded = event => {\n event.target.result.createObjectStore(dir)\n }\n o.onerror = event => {\n console.log(event)\n reject(event)\n }\n o.onsuccess = () => {\n db = o.result\n // Create the root node if it doesn't exist.\n if (db) {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getKey(\"!\")\n req.onerror = () => {\n console.log(`error getting key ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n if (!req.result) {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(root, \"!\")\n req.onerror = () => {\n console.log(`error putting root on ${dir}/!`)\n reject(req.error)\n }\n req.onsuccess = () => {\n resolve()\n }\n } else {\n resolve()\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n reject(new Error(\"indexedDB not available\"))\n }\n }\n })\n\n return {\n get: (file, cb) => {\n const _get = (file, cb) => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).get(file)\n req.onerror = () => {\n console.log(`error getting ${dir}/${file}`)\n cb(req.error)\n }\n req.onsuccess = () => {\n cb(null, req.result)\n }\n }\n\n dbReady\n .then(() => {\n _get(file, cb)\n })\n .catch(err => {\n cb(err)\n })\n },\n put: (file, data, cb) => {\n const _put = (file, data, cb) => {\n const tx = db.transaction([dir], \"readwrite\")\n const req = tx.objectStore(dir).put(data, file)\n req.onerror = () => {\n console.log(`error putting data on ${dir}/${file}`)\n cb(req.error)\n }\n req.onsuccess = () => {\n cb(null)\n }\n }\n\n dbReady\n .then(() => {\n _put(file, data, cb)\n })\n .catch(err => {\n cb(err)\n })\n },\n list: cb => {\n const _list = cb => {\n const tx = db.transaction([dir], \"readonly\")\n const req = tx.objectStore(dir).getAllKeys()\n req.onerror = () => {\n console.log(\"error getting keys for\", dir)\n cb()\n }\n req.onsuccess = () => {\n req.result.forEach(cb)\n cb()\n }\n }\n\n dbReady\n .then(() => {\n _list(cb)\n })\n .catch(err => {\n console.log(\"error indexedDB not available:\", err)\n cb()\n })\n },\n }\n }\n\n // No browser storage.\n return {\n get: (file, cb) => {\n cb(null, root)\n },\n put: (file, data, cb) => {\n cb(null)\n },\n list: cb => {\n cb(\"!\")\n cb()\n },\n }\n}\n\n// Store provides get and put methods that can access radisk.\nconst Store = opt => {\n if (!utils.obj.is(opt)) opt = {}\n opt.file = String(opt.file || \"radata\")\n if (!opt.store) opt.store = fileSystem(opt)\n const radisk = Radisk(opt)\n\n return {\n get: (lex, cb, _opt) => {\n if (!lex || !utils.obj.is(lex)) {\n cb(\"lex required\")\n return\n }\n if (!lex[\"#\"]) {\n cb(\"soul required in lex\")\n return\n }\n\n if (!_opt) _opt = {}\n\n var soul = lex[\"#\"]\n var key = !_opt.secure && typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n var node\n var signatures = {}\n const each = (value, key) => {\n // Always include userPublicKey for verification, regardless of filter\n if (key !== utils.userPublicKey && !utils.match(lex[\".\"], key)) return\n\n if (!node) node = {_: {\"#\": soul, \">\": {}}}\n node[key] = value[0]\n node._[\">\"][key] = value[1]\n // If signature is present, store it in _[\"s\"]\n if (value.length === 3 && value[2]) {\n signatures[value[1]] = value[2]\n }\n }\n\n radisk(soul + enq + key, (err, value) => {\n let graph\n if (utils.obj.is(value)) {\n Radix.map(value, each)\n if (!node) each(value, key)\n graph = {[soul]: node}\n } else if (value) {\n each(value, key)\n graph = {[soul]: node}\n }\n // Only add _[\"s\"] if we found any signatures\n if (graph && graph[soul] && Object.keys(signatures).length > 0) {\n graph[soul]._[\"s\"] = signatures\n }\n cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n let count = 0\n let finished = false\n const ack = err => {\n count--\n if (finished) return\n\n if (err) {\n finished = true\n cb(err)\n return\n }\n\n if (count === 0) {\n finished = true\n cb(null)\n }\n }\n\n Object.keys(graph).forEach(soul => {\n var node = graph[soul]\n Object.keys(node).forEach(key => {\n if (key === \"_\") return\n\n count++\n let value = node[key]\n let state = node._[\">\"][key]\n let sig = node._[\"s\"] && node._[\"s\"][state]\n let data = sig ? [value, state, sig] : [value, state]\n radisk(soul + enq + key, data, ack)\n })\n })\n },\n }\n}\n\nexport default Store\n", "import Dup from \"./dup.js\"\nimport Get from \"./get.js\"\nimport Ham from \"./ham.js\"\nimport Store from \"./store.js\"\nimport * as utils from \"./utils.js\"\n\nconst isNode = typeof document === \"undefined\"\n\nconst wsModule = isNode ? await import(\"ws\") : undefined\n\nif (typeof globalThis.WebSocket === \"undefined\") {\n globalThis.WebSocket = wsModule?.WebSocket\n}\n\n// Rate limiting with throttling\nconst createRateLimiter = isTestEnv => {\n const clients = new Map()\n const maxRequests = 1500 // requests per minute\n const windowMs = 60000 // 1 minute window\n const disconnectThreshold = 10 // Disconnect after 10 violations\n let cleanupInterval = null\n\n const cleanup = () => {\n const now = Date.now()\n for (const [clientId, data] of clients.entries()) {\n if (now - data.lastCleanup > windowMs) {\n data.requests = []\n data.lastCleanup = now\n }\n data.requests = data.requests.filter(time => now - time < windowMs)\n // Reset throttle counts periodically\n if (now - data.lastCleanup > windowMs * 10) {\n data.throttleCount = 0\n }\n }\n }\n\n if (!isTestEnv) {\n cleanupInterval = setInterval(cleanup, windowMs / 4)\n }\n\n return {\n getDelay: clientId => {\n const now = Date.now()\n const client = clients.get(clientId) || {\n requests: [],\n lastCleanup: now,\n throttleCount: 0,\n }\n\n // Filter old requests\n client.requests = client.requests.filter(time => now - time < windowMs)\n\n if (client.requests.length >= maxRequests) {\n // Calculate delay based on oldest request that will expire\n const oldestRequest = Math.min(...client.requests)\n const delay = windowMs - (now - oldestRequest)\n // Increment throttle count and update client data\n client.throttleCount = (client.throttleCount || 0) + 1\n clients.set(clientId, client)\n return Math.max(0, delay)\n }\n\n // No delay needed, track this request\n client.requests.push(now)\n clients.set(clientId, client)\n return 0\n },\n\n getRemainingRequests: clientId => {\n const client = clients.get(clientId)\n if (!client) return maxRequests\n\n const now = Date.now()\n const validRequests = client.requests.filter(\n time => now - time < windowMs,\n )\n return Math.max(0, maxRequests - validRequests.length)\n },\n\n getThrottleCount: clientId => {\n const client = clients.get(clientId)\n return client ? client.throttleCount || 0 : 0\n },\n\n shouldDisconnect: clientId => {\n const client = clients.get(clientId)\n if (!client) return false\n return client.throttleCount >= disconnectThreshold\n },\n\n destroy: () => {\n if (cleanupInterval) {\n clearInterval(cleanupInterval)\n cleanupInterval = null\n }\n clients.clear()\n },\n }\n}\n\n// Safe JSON parser with size limit\nconst safeJSONParse = (data, maxSize = 1024 * 1024) => {\n try {\n if (typeof data === \"string\" && data.length > maxSize) {\n throw new Error(\"Message too large\")\n }\n return {success: true, data: JSON.parse(data)}\n } catch (error) {\n return {success: false, error: error.message}\n }\n}\n\n// Message size validator\nconst validateMessage = (data, maxSize = 1024 * 1024) => {\n // 1MB default\n if (typeof data === \"string\" && data.length > maxSize) {\n return {valid: false, error: \"Message too large\"}\n }\n if (Buffer.isBuffer(data) && data.length > maxSize) {\n return {valid: false, error: \"Message too large\"}\n }\n return {valid: true}\n}\n\n// Connection manager to limit concurrent connections\nconst createConnectionManager = (maxConnections = 1000) => {\n const connections = new Set()\n\n return {\n add: ws => {\n if (connections.size >= maxConnections) {\n return false\n }\n connections.add(ws)\n\n // Clean up on close\n const originalClose = ws.close\n ws.close = (...args) => {\n connections.delete(ws)\n return originalClose.apply(ws, args)\n }\n\n return true\n },\n\n remove: ws => {\n connections.delete(ws)\n },\n\n count: () => connections.size,\n\n isFull: () => connections.size >= maxConnections,\n }\n}\n\n// Enhanced retry mechanism with exponential backoff\nconst createRetryHandler = (maxRetries = 5) => {\n let retryCount = 0\n\n return {\n shouldRetry: () => retryCount < maxRetries,\n getDelay: () => Math.min(1000 * Math.pow(2, retryCount), 30000), // Max 30s\n increment: () => retryCount++,\n reset: () => (retryCount = 0),\n }\n}\n\n// Wire starts a websocket client or server and returns get and put methods\n// for access to the wire spec and storage.\nconst Wire = opt => {\n const dup = Dup(opt.maxAge)\n const store = Store(opt)\n const graph = {}\n const queue = {}\n const listen = {}\n\n // Track references we want but don't have yet\n const pendingReferences = new Set()\n\n // Track pending timeouts that should start when message is sent\n const pendingTimeouts = new Map()\n\n // Helper to check if we have a soul in memory or storage\n const hasSoul = async soul => {\n if (graph[soul]) return true\n return new Promise(resolve => {\n store.get({\"#\": soul}, (err, data) => {\n resolve(!err && data && data[soul])\n })\n })\n }\n\n // Initialize rate limiting and connection management\n // Check if test environment (mock-socket usage)\n const isTestEnv = opt.wss && opt.wss.constructor.name === \"Server\"\n const rateLimiter = createRateLimiter(isTestEnv)\n const connectionManager = createConnectionManager(opt.maxConnections || 1000)\n\n // The check function is required because user data must provide a public key\n // so that it can be verified. The public key might verify the provided\n // signature but not actually match the user under which the data is being\n // stored. To avoid this, the current data on a soul needs to be checked to\n // make sure the stored public key matches the one provided with the update.\n const check = async (data, send, cb) => {\n const key = utils.userPublicKey\n\n for (const soul of Object.keys(data)) {\n const msg = await new Promise(res => {\n getWithCallback({\"#\": soul, \".\": key}, res, send)\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n const node = data[soul]\n // If there is no current node then the data is ok to write without\n // matching public keys, as the provided soul also needs a rel on the\n // parent node which then also requires checking. Otherwise public keys\n // need to match for existing data. If the incoming update doesn't\n // include a userPublicKey property at all, allow it - the update is\n // not trying to change the public key.\n if (\n !msg.put ||\n !msg.put[soul] ||\n node[key] === undefined ||\n msg.put[soul][key] === node[key]\n ) {\n continue\n }\n\n // If a soul exists but does not have a public key, then one should not be\n // added because the node is not user data. The above check fails in this\n // case if a public key is provided. Note that this is only an error case\n // if called via the API, which is when a callback is provided here.\n // (The wire spec can fetch and put data on the wire without a signature\n // or public key and this can be ignored.)\n if (cb) {\n cb(`error in wire check public key does not match for soul: ${soul}`)\n }\n return false\n }\n\n return true\n }\n\n const get = (msg, send) => {\n const ack = Get(msg.get, graph)\n if (ack) {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n }),\n )\n } else {\n // Always pass secure to ensure public key is fetched. User data may be\n // requested that requires the public key for verification.\n store.get(\n msg.get,\n (err, ack) => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n put: ack,\n err: err,\n }),\n )\n },\n {secure: true},\n )\n }\n }\n\n const put = async (msg, send) => {\n // Store updates returned from Ham.mix and defer updates if required.\n const update = await Ham.mix(msg.put, graph, opt.secure, listen)\n if (Object.keys(update.now).length === 0) {\n // No updates to store, check deferred.\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(\n () => put({put: update.defer, \"#\": msg[\"#\"]}, send),\n update.wait,\n )\n }\n return\n }\n\n if (!(await check(update.now, send))) return\n\n store.put(update.now, err => {\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: err,\n }),\n )\n // Fire listeners after data is stored\n update.listeners.forEach(cb => cb())\n })\n\n if (Object.keys(update.defer).length !== 0) {\n setTimeout(\n () => put({put: update.defer, \"#\": msg[\"#\"]}, send),\n update.wait,\n )\n }\n }\n\n const getWithCallback = (lex, cb, send, _opt) => {\n if (!cb) return\n\n if (!utils.obj.is(_opt)) _opt = {}\n\n const ack = Get(lex, graph, _opt.fast)\n const track = utils.text.random(9)\n const request = JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n })\n\n if (ack) {\n // Also send request on the wire to check for updates.\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n return\n }\n cb({put: ack})\n return\n }\n\n store.get(\n lex,\n (err, ack) => {\n if (ack) {\n // Populate in-memory graph from store data before sending the server\n // request, so stale server responses with older state are correctly\n // rejected by ham.mix.\n for (const [soul, node] of Object.entries(ack)) {\n if (!graph[soul] && node) graph[soul] = {...node}\n }\n // Also send request on the wire to check for updates.\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n return\n }\n cb(err ? {put: ack, err: err} : {put: ack})\n return\n }\n\n if (err) console.log(err)\n\n queue[track] = cb\n\n // Store timeout config to start after message is sent from queue\n pendingTimeouts.set(track, {\n lex: lex,\n wait: _opt.wait || 100,\n })\n\n const sendResult = send(request)\n if (sendResult && sendResult.err) {\n cb({err: sendResult.err})\n delete queue[track]\n pendingTimeouts.delete(track)\n return\n }\n },\n _opt,\n )\n }\n\n const api = send => {\n return {\n get: (lex, cb, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = {...lex, \".\": String(lex[\".\"])}\n }\n // Mark requested soul as something we want to store\n if (lex && lex[\"#\"]) {\n pendingReferences.add(lex[\"#\"])\n }\n getWithCallback(lex, cb, send, _opt)\n },\n put: async (data, cb) => {\n // Deferred updates are only stored using wire spec, they're ignored\n // here using the api. This is ok because correct timestamps should be\n // used whereas wire spec needs to handle clock skew for updates\n // across the network.\n const update = await Ham.mix(data, graph, opt.secure, listen)\n if (Object.keys(update.now).length === 0) {\n // No updates, still respond to callback.\n if (cb) cb(null)\n return\n }\n\n if (!(await check(update.now, send, cb))) {\n return\n }\n\n // Seed pendingReferences with any new references from API calls\n for (const [soul, node] of Object.entries(update.now)) {\n if (node && typeof node === \"object\") {\n for (const [key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value)\n if (soulId) {\n // Add referenced soul to pending list\n pendingReferences.add(soulId)\n }\n }\n }\n }\n\n store.put(update.now, err => {\n if (cb) cb(err)\n // Fire listeners after data is stored\n update.listeners.forEach(l => l())\n })\n\n // Always put data on the wire spec even if no local update needed\n const sendResult = send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n }),\n )\n // Handle queue overflow error.\n if (sendResult && sendResult.err) {\n if (cb) cb(sendResult.err)\n return\n }\n },\n on: (lex, cb, _get, _opt) => {\n if (lex && typeof lex[\".\"] === \"number\") {\n lex = {...lex, \".\": String(lex[\".\"])}\n }\n const soul = lex && lex[\"#\"]\n if (!soul || !cb) return\n\n if (listen[soul]) {\n listen[soul].push({\".\": lex[\".\"], cb: cb})\n } else {\n listen[soul] = [{\".\": lex[\".\"], cb: cb}]\n }\n if (_get) getWithCallback(lex, cb, send, _opt)\n },\n off: (lex, cb) => {\n const soul = lex && lex[\"#\"]\n if (!soul || !listen[soul]) return\n\n if (cb) {\n const found = listen[soul].find(l => l.cb === cb)\n if (found) {\n listen[soul].splice(listen[soul].indexOf(found), 1)\n }\n } else {\n // Remove all callbacks when none provided.\n delete listen[soul]\n }\n },\n }\n }\n\n if (isNode) {\n let wss = opt.wss\n // Node's websocket server provides clients as an array, whereas\n // mock-sockets provides clients as a function that returns an array.\n let clients = () => wss.clients()\n if (!wss) {\n const config = opt.server\n ? {server: opt.server}\n : {port: opt.port || 8765}\n wss = new wsModule.WebSocketServer(config)\n clients = () => wss.clients\n }\n\n const send = (data, isBinary) => {\n // Start timeout for this message now that it's being sent\n const msg = JSON.parse(data)\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)\n pendingTimeouts.delete(trackId)\n\n // Respond to callback with null if no response.\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack = {[id]: null}\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = {[timeoutConfig.lex[\".\"]]: null}\n }\n cb({put: ack})\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n\n clients().forEach(client => {\n if (client && client.readyState === WebSocket.OPEN) {\n client.send(data, {binary: isBinary})\n } else {\n const retryHandler = client._retryHandler || createRetryHandler()\n client._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (client && client.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n client.send(data, {binary: isBinary})\n }\n }, delay)\n }\n }\n })\n }\n wss.on(\"connection\", ws => {\n // Check connection limit\n if (!connectionManager.add(ws)) {\n console.log(\"Connection limit reached, rejecting connection\")\n ws.close(1013, \"Connection limit reached - try again later\")\n return\n }\n\n // Generate unique client ID for rate limiting\n const clientId = utils.text.random(9)\n console.log(`New WebSocket client connected: ${clientId}`)\n\n ws.on(\"error\", error => {\n console.log(\"WebSocket error:\", error)\n connectionManager.remove(ws)\n })\n\n ws.on(\"close\", () => {\n console.log(`WebSocket client disconnected: ${clientId}`)\n connectionManager.remove(ws)\n })\n\n ws.on(\"message\", (data, isBinary) => {\n // Validate message size\n const validation = validateMessage(data, opt.maxMessageSize)\n if (!validation.valid) {\n console.warn(`Invalid message: ${validation.error}`)\n ws.send(JSON.stringify({error: validation.error}))\n return\n }\n\n // Safe JSON parsing\n const parseResult = safeJSONParse(data, opt.maxMessageSize)\n if (!parseResult.success) {\n console.warn(`JSON parse error: ${parseResult.error}`)\n ws.send(JSON.stringify({error: \"Invalid JSON\"}))\n return\n }\n\n const msg = parseResult.data\n if (dup.check(msg[\"#\"])) return\n\n // Check rate limit and get delay\n const delay = rateLimiter.getDelay(clientId)\n // Log rate limiting activity and enforce stricter limits\n if (delay > 0) {\n const throttleCount = rateLimiter.getThrottleCount(clientId)\n console.log(\n `Client ${clientId}: rate limit exceeded, delay would be ${delay}ms, dropping message (throttle count: ${throttleCount})`,\n )\n // Check if we should disconnect the bad actor\n if (rateLimiter.shouldDisconnect(clientId)) {\n console.log(\n `Client ${clientId}: Disconnecting after ${throttleCount} throttle violations`,\n )\n ws.close(1008, \"Rate limit violations\")\n return\n }\n\n // Send throttle warning back to client instead of processing\n ws.send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n \"@\": msg[\"#\"],\n err: `Rate limit exceeded. Slow down requests. Wait ${Math.ceil(delay / 1000)}s`,\n throttle: delay,\n }),\n )\n return\n }\n\n const processMessage = async () => {\n dup.track(msg[\"#\"])\n\n if (msg.get) get(msg, send)\n if (msg.put) await put(msg, send)\n send(data, isBinary)\n\n const id = msg[\"@\"]\n const cb = queue[id]\n if (cb) {\n delete msg[\"#\"]\n delete msg[\"@\"]\n cb(msg)\n\n delete queue[id]\n }\n }\n\n if (delay > 0) {\n // Throttle the client by delaying message processing\n setTimeout(processMessage, delay)\n } else {\n // Process immediately\n processMessage()\n }\n })\n })\n return api(send)\n }\n\n // Browser logic.\n const peers = []\n // Client-side throttling state\n let clientThrottled = false\n let throttleUntil = 0\n let messageQueue = []\n let queueProcessor = null\n const maxQueueLength = opt.maxQueueLength || 10000\n\n const processQueue = () => {\n if (messageQueue.length === 0) {\n queueProcessor = null\n return\n }\n\n const now = Date.now()\n if (clientThrottled && now < throttleUntil) {\n // Still throttled, schedule next queue check\n queueProcessor = setTimeout(\n processQueue,\n Math.min(1000, throttleUntil - now),\n )\n return\n }\n\n // Throttle period ended, resume processing\n if (clientThrottled && now >= throttleUntil) {\n console.log(`Throttle period ended, resuming queue processing`)\n clientThrottled = false\n throttleUntil = 0\n }\n\n // Process next message in queue\n const data = messageQueue[0]\n const sent = sendToPeers(data)\n\n if (sent) {\n // Only remove from queue if successfully sent\n messageQueue.shift()\n\n // Start timeout for this message now that it's been sent\n const msg = JSON.parse(data)\n const trackId = msg[\"#\"]\n if (trackId && pendingTimeouts.has(trackId)) {\n const timeoutConfig = pendingTimeouts.get(trackId)\n pendingTimeouts.delete(trackId)\n\n // Respond to callback with null if no response.\n timeoutConfig.timeoutId = setTimeout(() => {\n const cb = queue[trackId]\n if (cb) {\n const id = timeoutConfig.lex[\"#\"]\n const ack = {[id]: null}\n if (typeof timeoutConfig.lex[\".\"] === \"string\") {\n ack[id] = {[timeoutConfig.lex[\".\"]]: null}\n }\n cb({put: ack})\n delete queue[trackId]\n }\n }, timeoutConfig.wait)\n }\n }\n\n // Schedule processing of next message if queue not empty\n if (messageQueue.length > 0) {\n // Add delay between messages to respect rate limit\n queueProcessor = setTimeout(processQueue, 50)\n } else {\n queueProcessor = null\n }\n }\n\n const sendToPeers = data => {\n let sentToAtLeastOne = false\n peers.forEach(peer => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n peer.send(data)\n sentToAtLeastOne = true\n } else {\n const retryHandler = peer._retryHandler || createRetryHandler()\n peer._retryHandler = retryHandler\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n\n setTimeout(() => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n retryHandler.reset()\n peer.send(data)\n }\n }, delay)\n }\n }\n })\n return sentToAtLeastOne\n }\n\n const send = data => {\n if (messageQueue.length >= maxQueueLength) {\n return {\n err: `Message queue exceeded maximum length (${maxQueueLength}). Update query logic to request less data.`,\n queueLength: messageQueue.length,\n maxQueueLength: maxQueueLength,\n }\n }\n\n messageQueue.push(data)\n // Start queue processor if not already running\n if (!queueProcessor) {\n queueProcessor = setTimeout(processQueue, 50)\n }\n }\n if (!(opt.peers instanceof Array) || opt.peers.length === 0) {\n opt.peers = [`ws://localhost:${opt.port || 8765}`]\n }\n opt.peers.forEach(peer => {\n const start = () => {\n let ws = new WebSocket(peer)\n peers.push(ws)\n const retryHandler = createRetryHandler()\n\n ws.onclose = c => {\n if (peers.indexOf(ws) !== -1) {\n peers.splice(peers.indexOf(ws), 1)\n }\n ws = null\n\n if (retryHandler.shouldRetry()) {\n const delay = retryHandler.getDelay()\n retryHandler.increment()\n setTimeout(start, delay)\n }\n }\n\n ws.onopen = () => {\n retryHandler.reset()\n }\n\n ws.onerror = e => {\n console.log(e)\n }\n ws.onmessage = async m => {\n const msg = JSON.parse(m.data)\n if (dup.check(msg[\"#\"])) return\n\n // Handle throttle messages from server\n if (msg.throttle && msg.err) {\n console.log(`Server throttling: ${msg.err}`)\n clientThrottled = true\n throttleUntil = Date.now() + msg.throttle\n return\n }\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) {\n // Handle selective storage for client WebSocket messages\n const filteredPut = {}\n for (const [soul, node] of Object.entries(msg.put)) {\n let shouldStore = false\n // Case 1: We already have this soul - always update\n if (await hasSoul(soul)) {\n shouldStore = true\n // Check if this update adds new references\n if (node && typeof node === \"object\") {\n for (const [key, value] of Object.entries(node)) {\n const soulId = utils.rel.is(value)\n if (soulId) {\n // Add referenced soul to pending list\n pendingReferences.add(soulId)\n }\n }\n }\n }\n // Case 2: This soul was referenced by something we have\n if (pendingReferences.has(soul)) {\n shouldStore = true\n pendingReferences.delete(soul) // Got it, remove from pending\n }\n if (shouldStore) {\n filteredPut[soul] = node\n }\n }\n // Store filtered data if any\n if (Object.keys(filteredPut).length > 0) {\n // Create filtered message for Ham.mix with original message ID\n const filteredMsg = {put: filteredPut, \"#\": msg[\"#\"]}\n await put(filteredMsg, send)\n }\n }\n\n const id = msg[\"@\"]\n const cb = queue[id]\n if (cb) {\n delete msg[\"#\"]\n delete msg[\"@\"]\n cb(msg)\n\n delete queue[id]\n }\n }\n }\n start()\n })\n\n return api(send)\n}\n\nexport default Wire\n", "import * as utils from \"./utils.js\"\nimport Wire from \"./wire.js\"\nimport SEA from \"./sea.js\"\nimport {userPublicKey, userSignature} from \"./utils.js\"\n\nconst User = (opt, wire) => {\n if (!wire) wire = Wire(opt)\n const wait = opt?.wait ?? 5000\n let pubs = []\n let creating = false\n let authing = false\n let retries = 0\n\n const auth = (username, password, newPassword, ack) => {\n const retry = username => {\n retries++\n auth(username, password, newPassword, ack)\n }\n const done = err => {\n pubs = []\n retries = 0\n authing = false\n ack(err)\n }\n const next = () => {\n if (pubs.length === 0) {\n done(\"Wrong username or password\")\n return\n }\n\n const pub = pubs.shift()\n wire.get(\n {\"#\": pub, \".\": [\"auth\", \"pub\", \"epub\"]},\n async msg => {\n if (msg.err) {\n done(`error getting ${pub}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[pub]\n if (!data || !data.auth) return next()\n\n const auth = JSON.parse(data.auth)\n const work = await SEA.work(password, auth.salt)\n const dec = await SEA.decrypt(auth.enc, work)\n if (!dec) return next()\n\n user.is = {\n username: username,\n pub: data.pub,\n epub: data.epub,\n priv: dec.priv,\n epriv: dec.epriv,\n }\n if (newPassword !== \"\") {\n // Encrypt private key using new password and a new salt.\n const salt = utils.text.random(64)\n const work = await SEA.work(newPassword, salt)\n const enc = await SEA.encrypt(dec, work)\n // Only update the auth property with the new password encryption.\n const update = {\n auth: JSON.stringify({enc: enc, salt: salt}),\n }\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const graph = utils.graph(pub, update, sig, data.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${update} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n done(null)\n },\n {wait: wait},\n )\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get(\n {\"#\": soul},\n async msg => {\n if (msg.err) {\n done(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n const data = msg.put && msg.put[soul]\n if (!data) return retry(username)\n\n delete msg.put[soul]._\n // Usernames aren't guaranteed to be unique, so store the list and then\n // try each of them until one is successful with the given password.\n pubs = Object.keys(data)\n next()\n },\n {wait: wait},\n )\n }\n\n const user = {\n create: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else console.log(err)\n }\n\n if (creating) {\n ack(\"User is already being created\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n creating = true\n\n const soul = \"~@\" + username\n wire.get(\n {\"#\": soul},\n async msg => {\n if (msg.err) {\n creating = false\n ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n if (msg.put && msg.put[soul]) {\n creating = false\n ack(\"Username already exists\")\n return\n }\n\n const salt = utils.text.random(64)\n const work = await SEA.work(password, salt)\n const pair = await SEA.pair()\n const priv = {priv: pair.priv, epriv: pair.epriv}\n const enc = await SEA.encrypt(priv, work)\n const data = {\n username: username,\n pub: pair.pub,\n epub: pair.epub,\n auth: JSON.stringify({enc: enc, salt: salt}),\n }\n\n const pub = \"~\" + pair.pub\n // Sign the timestamp for new account\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, pair)\n const graph = utils.graph(pub, data, sig, pair.pub, timestamp)\n wire.put(graph, err => {\n creating = false\n if (err) {\n ack(`error putting ${data} on ${pub}: ${err}`)\n return\n }\n\n const rel = {[pub]: {\"#\": pub}}\n wire.put(utils.graph(soul, rel), err => {\n if (err) {\n ack(`error putting ${rel} on ${soul}: ${err}`)\n return\n }\n\n // Return null on success.\n if (cb) cb(null)\n })\n })\n },\n {wait: wait},\n )\n },\n auth: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", ack)\n },\n change: (username, password, newPassword, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else if (err) console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n user.is = null\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n if (newPassword === \"\") {\n ack(\"Please provide a new password\")\n return\n }\n\n authing = true\n auth(username, password, newPassword, ack)\n },\n store: localStorage => {\n if (!user.is) {\n console.log(\"Please authenticate before calling store\")\n return\n }\n\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n },\n recall: () => {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n return\n }\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n const is = globalThis.sessionStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n }\n }\n },\n leave: () => {\n user.is = null\n if (typeof globalThis.localStorage !== \"undefined\") {\n globalThis.localStorage.removeItem(\"user.is\")\n }\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.removeItem(\"user.is\")\n }\n },\n delete: (username, password, cb) => {\n const ack = err => {\n if (cb) cb(err)\n else console.log(err)\n }\n\n if (authing) {\n ack(\"User is already authenticating\")\n return\n }\n\n if (username === \"\") {\n ack(\"Please provide a username\")\n return\n }\n\n if (password === \"\") {\n ack(\"Please provide a password\")\n return\n }\n\n authing = true\n auth(username, password, \"\", async err => {\n if (err) {\n ack(err)\n return\n }\n\n const data = {username: null, pub: null, epub: null, auth: null}\n // Sign the timestamp for account deletion\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, user.is)\n const pub = \"~\" + user.is.pub\n const graph = utils.graph(pub, data, sig, user.is.pub, timestamp)\n wire.put(graph, err => {\n if (err) {\n ack(`error putting null on ${pub}: ${err}`)\n return\n }\n\n user.is = null\n // Return null on success. Note currently not updating ~@username,\n // not sure if allowing username re-user is a good idea anyway?\n if (cb) cb(null)\n })\n })\n },\n }\n return user\n}\n\nexport default User\n", "import * as utils from \"./utils.js\"\nimport Wire from \"./wire.js\"\nimport User from \"./user.js\"\nimport SEA from \"./sea.js\"\n\nconst Holster = opt => {\n if (typeof opt === \"string\") opt = {peers: [opt]}\n else if (opt instanceof Array) opt = {peers: opt}\n else if (!utils.obj.is(opt)) opt = {}\n\n const wire = Wire(opt)\n const user = User(opt, wire)\n // Map callbacks since the user's callback is not passed to wire.on.\n const map = new Map()\n // Allow concurrent calls to the api by storing each context.\n const allctx = new Map()\n\n const ok = data => {\n return (\n data === null ||\n data === true ||\n data === false ||\n typeof data === \"string\" ||\n utils.rel.is(data) ||\n utils.num.is(data)\n )\n }\n\n // check returns true if data is ok to add to a graph, an error string if\n // the data can't be converted, and the keys on the data object otherwise.\n const check = data => {\n if (ok(data)) return true\n\n if (utils.obj.is(data)) {\n const keys = []\n for (const [key, value] of Object.entries(data)) {\n if (key === \"_\") {\n return \"error underscore cannot be used as a property name\"\n }\n if (utils.obj.is(value) || ok(value)) {\n keys.push(key)\n continue\n }\n if (typeof value === \"undefined\") {\n return `error undefined ${key} cannot be converted to a graph`\n }\n const error = JSON.stringify({[key]: value})\n return `error ${error} cannot be converted to a graph`\n }\n if (keys.length !== 0) return keys\n }\n const error = JSON.stringify(data)\n return `error ${error} cannot be converted to a graph`\n }\n\n const api = ctxid => {\n const get = (lex, soul, ack, _opt) => {\n wire.get(\n utils.obj.put(lex, \"#\", soul),\n async msg => {\n if (msg.err) console.log(msg.err)\n if (msg.put && msg.put[soul]) {\n delete msg.put[soul]._\n delete msg.put[soul][utils.userPublicKey]\n delete msg.put[soul][utils.userSignature]\n // Resolve any rels on the node before returning to the user.\n for (const key of Object.keys(msg.put[soul])) {\n const id = utils.rel.is(msg.put[soul][key])\n if (id) {\n // Retry with delays if we get null\n const attemptRead = async (retries = 0) => {\n const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n const ctx = allctx.get(ctxid)\n allctx.set(_ctxid, {\n chain: [{item: null, soul: id}],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null, res, _opt)\n })\n if (data !== null || retries >= 5) {\n return data\n }\n // Data not ready, retry after delay\n await new Promise(resolve => setTimeout(resolve, 50))\n return attemptRead(retries + 1)\n }\n msg.put[soul][key] = await attemptRead()\n }\n }\n ack(msg.put[soul])\n } else {\n // No data callback.\n ack(null)\n }\n },\n _opt,\n )\n }\n\n const graph = async (soul, data, userctx, cb) => {\n if (userctx) {\n // Sign the timestamp\n const timestamp = Date.now()\n const sig = await SEA.signTimestamp(timestamp, userctx)\n return utils.graph(soul, data, sig, userctx.pub, timestamp)\n }\n\n if (opt.secure) {\n if (!cb) cb = console.log\n cb(`error putting data on ${soul}: user required in secure mode`)\n return null\n }\n\n return utils.graph(soul, data)\n }\n\n // done takes a context id and returns a new callback function so that the\n // callback is not overwritten by simultaneous requests.\n const done = ctxid => {\n return data => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") {\n // Use a timeout so that the context can be removed before data is\n // returned to the callback (allows nested get calls).\n setTimeout(() => ctx.cb(data), 1)\n } else if (data) {\n console.log(\"error no callback for data\", data, \"ctx\", ctx)\n }\n // A context updated by \"on\" should only be removed by \"off\".\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n }\n\n const watchForRel = (soul, item, ctx, i, request, cb) => {\n const handler = () => {\n // Bail out if the context was removed by off().\n if (!allctx.has(ctxid)) {\n wire.off({\"#\": soul, \".\": item}, handler)\n return\n }\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n const node = msg.put && msg.put[soul]\n const id = utils.rel.is(node && node[item])\n if (!id) return\n wire.off({\"#\": soul, \".\": item}, handler)\n ctx.chain[i].soul = id\n allctx.set(ctxid, {...ctx})\n api(ctxid).on(request.on, cb, request._get, request._opt)\n },\n {...request._opt, secure: ctx.user || opt.secure},\n )\n }\n wire.on({\"#\": soul, \".\": item}, handler, false, request._opt)\n }\n\n const resolve = (request, cb) => {\n if (!request) {\n console.log(\"error resolve request parameter required\")\n return\n }\n\n const get = typeof request.get !== \"undefined\"\n const put = typeof request.put !== \"undefined\"\n const on = typeof request.on !== \"undefined\"\n const off = typeof request.off !== \"undefined\"\n\n let found = false\n const ctx = allctx.get(ctxid)\n for (var i = 1; i < ctx.chain.length; i++) {\n if (ctx.chain[i].soul !== null) continue\n\n found = true\n break\n }\n\n if (found) {\n // Found a soul that needs resolving, need the previous context\n // (ie the parent node) to find a soul relation for it.\n const {item, soul} = ctx.chain[i - 1]\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n console.log(`error getting ${item} on ${soul}: ${msg.err}`)\n if (cb) cb(null)\n return\n }\n\n let node = msg.put && msg.put[soul]\n if (node && typeof node[item] !== \"undefined\") {\n let id = utils.rel.is(node[item])\n if (id) {\n ctx.chain[i].soul = id\n allctx.set(ctxid, {...ctx})\n // Call api again using the updated context.\n if (get) {\n api(ctxid).next(null, request.get, cb, request._opt)\n } else if (put) {\n api(ctxid).put(request.put, cb)\n } else if (on) {\n api(ctxid).on(request.on, cb, request._get, request._opt)\n } else if (off) {\n api(ctxid).off(cb)\n }\n } else if (get) {\n // Request was not for a node, return property on current soul.\n cb(node[item])\n } else if (put) {\n // Request was chained before put, so rel doesn't exist yet.\n id = utils.text.random()\n node[item] = utils.rel.ify(id)\n const g = await graph(soul, node, ctx.user, cb)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n cb(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n\n ctx.chain[i].soul = id\n api(ctxid).put(request.put, cb)\n })\n } else if (on) {\n // Item is not a rel yet \u2014 watch the parent soul for when it\n // becomes one, then retry chain resolution.\n watchForRel(soul, item, ctx, i, request, cb)\n if (request._get) cb(null)\n } else if (off) {\n // Allow stop listening to a node that doesn't exist.\n if (cb) cb(null)\n }\n } else if (put) {\n // Request was chained before put, so rel doesn't exist yet.\n const id = utils.text.random()\n if (!node) node = {}\n node[item] = utils.rel.ify(id)\n const g = await graph(soul, node, ctx.user, cb)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n cb(`error putting ${item} on ${soul}: ${err}`)\n return\n }\n\n ctx.chain[i].soul = id\n api(ctxid).put(request.put, cb)\n })\n } else {\n if (on) {\n // Node doesn't exist yet \u2014 watch for it to appear.\n watchForRel(soul, item, ctx, i, request, cb)\n if (request._get) cb(null)\n } else {\n // Allow querying a node that doesn't exist.\n if (cb) cb(null)\n }\n }\n },\n {...request._opt, secure: ctx.user || opt.secure},\n )\n // Callback has been passed to next soul lookup or called above, so\n // return false as the calling code should not continue.\n return false\n }\n\n if (get && ctx.chain[ctx.chain.length - 1].item !== null) {\n // The context has been resolved but it does not include the requested\n // node, which requires one more lookup.\n ctx.chain.push({item: null, soul: null})\n api(ctxid).next(null, request.get, cb, request._opt)\n return false\n }\n\n // Return the last context, ie the soul required by the calling code.\n return ctx.chain[ctx.chain.length - 1]\n }\n\n return {\n get: (key, lex, cb, _opt) => {\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (cb) cb(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && typeof cb !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n // Top level keys are added to a root node so their values don't need\n // to be objects.\n ctxid = utils.text.random()\n allctx.set(ctxid, {chain: [{item: String(key), soul: \"root\"}], cb: cb})\n if (!cb) return api(ctxid)\n\n const _done = done(ctxid)\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex, _opt: _opt}, _done)\n if (soul) get(lex, soul, _done, _opt)\n },\n next: (key, lex, cb, _opt) => {\n // ack needs to work the same as done, pass it the context id and then\n // return a new function for the actual callback.\n const ack = ctxid => {\n return data => {\n if (cb) {\n cb(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n const _ack = ack(ctxid)\n if (key === \"\" || key === \"_\") {\n _ack(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && typeof cb !== \"function\") {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n const ctx = allctx.get(ctxid)\n // ctx already removed by another chained callback is ok?\n if (!ctx) return\n\n if (cb && typeof ctx.cb === \"undefined\") {\n // This (and ack) allows nested objects to set their own callbacks.\n ctx.cb = cb\n cb = null\n }\n\n // Push the key to the context as it needs a soul lookup.\n // (null is used to call the api with updated context)\n if (key !== null) ctx.chain.push({item: String(key), soul: null})\n if (!ctx.cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex, _opt: _opt}, _ack)\n if (soul) get(lex, soul, _ack, _opt)\n },\n put: (data, set, cb) => {\n if (typeof set === \"function\") {\n cb = set\n set = false\n }\n const ack = ctxid => {\n return data => {\n if (cb) {\n cb(data)\n } else {\n done(ctxid)(data)\n }\n }\n }\n if (!ctxid) {\n if (cb) cb(\"error please provide a key using get(key)\")\n return\n }\n\n const ctx = allctx.get(ctxid)\n // ctx already removed by another chained callback is ok?\n if (!ctx) return\n\n if (!ctx.cb) {\n if (!cb) return\n\n // This (and ack) allows nested objects to set their own callbacks.\n ctx.cb = cb\n cb = null\n }\n if (set) data = {[utils.text.random()]: data}\n\n const _ack = ack(ctxid)\n const result = check(data)\n if (typeof result === \"string\") {\n // All strings returned from check are errors, cannot continue.\n _ack(result)\n return\n }\n\n // Resolve the current context before putting data. (Note that set is\n // not passed to resolve because it's already been applied above.)\n const {item, soul} = resolve({put: data}, _ack)\n if (!soul) return\n\n if (result === true) {\n // When result is true data is a property to put on the current soul.\n // Need to check if item is a rel and also set the node to null. (This\n // applies for any update from a rel to a property, not just null.)\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item]\n const id = utils.rel.is(current)\n if (!id) {\n // Not a rel, can just put the data.\n if (!node) node = {}\n node[item] = data\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n return\n }\n\n wire.get({\"#\": id}, async msg => {\n if (msg.err) {\n _ack(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n _ack(`error ${id} not found`)\n return\n }\n\n // null each of the properties on the node before putting data.\n for (const key of Object.keys(msg.put[id])) {\n if (\n key === \"_\" ||\n key === utils.userPublicKey ||\n key === utils.userSignature\n ) {\n continue\n }\n\n const err = await new Promise(res => {\n const _ctxid = utils.text.random()\n const chain = [{item: key, soul: id}]\n allctx.set(_ctxid, {chain: chain, user: ctx.user})\n api(_ctxid).put(null, res)\n })\n if (err) {\n _ack(err)\n return\n }\n }\n if (!node) node = {}\n node[item] = data\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n })\n },\n {secure: ctx.user || opt.secure},\n )\n return\n }\n\n // Otherwise put the data using the keys returned in result.\n // Need to check if a rel has already been added on the current node.\n // Use attemptRead to retry if data hasn't propagated yet.\n const attemptRead = (retries = 0) => {\n wire.get(\n {\"#\": soul, \".\": item},\n async msg => {\n if (msg.err) {\n _ack(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n let node = msg.put && msg.put[soul]\n const current = node && node[item]\n\n // If we didn't find the item but still have retries, retry\n if (!current && retries < 5) {\n await new Promise(r => setTimeout(r, 50))\n return attemptRead(retries + 1)\n }\n\n const id = utils.rel.is(current)\n if (!id) {\n // The current rel doesn't exist, so add it first.\n if (!node) node = {}\n node[item] = utils.rel.ify(utils.text.random())\n const g = await graph(soul, node, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, err => {\n if (err) {\n _ack(`error putting ${item} on ${soul}: ${err}`)\n } else {\n const _ctxid = utils.text.random()\n const chain = [{item: item, soul: soul}]\n // Pass on the previous context's callback and user flag here.\n allctx.set(_ctxid, {\n chain: chain,\n user: ctx.user,\n cb: ctx.cb,\n })\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n const update = []\n for (const key of result) {\n const err = await new Promise(res => {\n if (utils.obj.is(data[key]) && !utils.rel.is(data[key])) {\n // Use the current rel as the context for nested objects.\n const _ctxid = utils.text.random()\n const chain = [{item: key, soul: id}]\n allctx.set(_ctxid, {chain: chain, user: ctx.user})\n api(_ctxid).put(data[key], res)\n } else {\n // Group the rest of the updates for put below.\n update.push(key)\n res(null)\n }\n })\n if (err) {\n _ack(err, ctxid)\n return\n }\n }\n\n if (update.length === 0) {\n _ack(null)\n return\n }\n\n // Only write the primitive update keys. Rels created by the\n // recursive puts above are already in the in-memory graph.\n const updateNode = {}\n update.forEach(key => {\n updateNode[key] = data[key]\n })\n const g = await graph(id, updateNode, ctx.user, _ack)\n if (g === null) return\n\n wire.put(g, _ack)\n },\n {secure: ctx.user || opt.secure},\n )\n }\n attemptRead()\n },\n on: (lex, cb, _get, _opt) => {\n if (typeof lex === \"function\") {\n _opt = _get\n _get = cb\n cb = lex\n lex = null\n }\n if (typeof cb !== \"function\") {\n console.log(\"error on() requires a callback function\")\n return\n }\n\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n cb(null)\n return\n }\n\n // Resolve the current context before adding event listener.\n const {item, soul} = resolve({on: lex, _get: _get, _opt: _opt}, cb)\n if (!soul) return\n\n // Get the context to check if it has user info\n const ctx = allctx.get(ctxid)\n\n // Flag that this context is set from on and shouldn't be removed.\n allctx.set(ctxid, {\n chain: [{item: item, soul: soul}],\n on: true,\n user: ctx ? ctx.user : null,\n })\n // Map the user's callback because it can also be passed to off,\n // so need a reference to it to compare them.\n // Shared retry state for this on() subscription.\n let retryCount = 0\n const maxRetries = 5\n const retryDelay = 1000 // Start with 1 second\n let retryTimer = null\n\n map.set(cb, () => {\n // Bail out if off() has already cleaned up this context \u2014 the mapped\n // callback can fire twice (once from wire.on and once from the _get\n // immediate-read path) and the second call after async context cleanup\n // would crash in resolve(). Matches the guard in watchForRel.\n if (!allctx.has(ctxid)) return\n // Cancel any pending retry \u2014 the persistent listener firing means we\n // have an update and should not call cb twice.\n clearTimeout(retryTimer)\n retryTimer = null\n // When listener fires, re-check if the item is now a rel.\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n const node = msg.put && msg.put[soul]\n const current = node && node[item]\n const id = utils.rel.is(current)\n if (id) {\n // It's a rel, read the related node. It might not be in the\n // graph yet when the listener fires, so we retry with delays.\n const attemptRead = async (retries = 0) => {\n const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {\n chain: [{item: null, soul: id}],\n user: ctx ? ctx.user : null,\n })\n api(_ctxid).next(null, res, retries === 0 ? utils.obj.put(_opt, \"fast\", true) : _opt)\n })\n if (data !== null || retries >= 5) {\n retryCount = 0 // Reset retry counter on success\n cb(data)\n } else {\n // Data not ready, retry after delay\n await new Promise(resolve => setTimeout(resolve, 50))\n attemptRead(retries + 1)\n }\n }\n attemptRead()\n } else {\n // It's a direct property or null.\n const nodeExists = !!node\n\n if (nodeExists) {\n // Node exists \u2014 return the value and reset retry state.\n retryCount = 0\n cb(current !== undefined ? current : null)\n } else if (retryCount < maxRetries) {\n // No data yet \u2014 keep polling until we get a response or\n // exhaust retries. on() with _get can return null on a cache\n // miss and never fire again if the data doesn't change while\n // the listener is attached, so we must poll for initial load.\n const retry = () => {\n const delay = Math.min(retryDelay * Math.pow(2, retryCount), 30000)\n retryCount++\n retryTimer = setTimeout(() => {\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n const retryNode = msg.put && msg.put[soul]\n if (retryNode) {\n retryCount = 0\n retryTimer = null\n const retryValue = retryNode[item]\n cb(retryValue !== undefined ? retryValue : null)\n } else if (retryCount < maxRetries) {\n retry()\n } else {\n retryTimer = null\n cb(null)\n }\n },\n {..._opt, secure: ctx.user || opt.secure},\n )\n }, delay)\n }\n retry()\n } else {\n cb(null)\n }\n }\n },\n {..._opt, secure: ctx.user || opt.secure},\n )\n })\n\n // Register listener immediately to avoid missing updates due to\n // queueing. Initially register the soul without _get, then update if\n // it's a rel.\n let initialLex\n if (lex) {\n initialLex = utils.obj.put(lex, \"#\", soul)\n // Normalize numeric property filters to strings for wire operations\n // Only convert if it's a number, not if it's a complex filter object\n if (initialLex[\".\"] != null && typeof initialLex[\".\"] === \"number\") {\n initialLex = {...initialLex, \".\": String(initialLex[\".\"])}\n }\n } else {\n initialLex = {\"#\": soul, \".\": item}\n }\n wire.on(initialLex, map.get(cb), false, _opt)\n\n // Check if item is a rel and update listener if needed.\n // This happens async but the listener is already registered above.\n wire.get(\n {\"#\": soul, \".\": item},\n msg => {\n if (msg.err) {\n console.log(`error getting ${soul}.${item}: ${msg.err}`)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul][item]\n const id = utils.rel.is(current)\n if (id) {\n // It's a rel, need to switch listener to the related node\n // First remove the initial listener\n wire.off(initialLex, map.get(cb))\n // Then add listener on the related node\n let relLex\n if (lex) relLex = utils.obj.put(initialLex, \"#\", id)\n else relLex = {\"#\": id, \".\": null}\n wire.on(relLex, map.get(cb), false, _opt)\n if (_get) map.get(cb)()\n } else if (_get) {\n // Not a rel, but _get was requested, so trigger callback.\n map.get(cb)()\n }\n },\n {..._opt, secure: ctx.user || opt.secure},\n )\n },\n off: cb => {\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n if (cb) cb(null)\n return\n }\n\n // Resolve the current context before removing event listener.\n const {item, soul} = resolve({off: true}, cb)\n if (!soul) return\n\n // Remove listener immediately from the original soul to avoid race condition.\n // The listener may be on a related soul if item is a rel, but we remove\n // from the original soul first since that's where it's initially registered.\n wire.off({\"#\": soul}, map.get(cb))\n\n // Check if item is a rel and remove from the related node as well.\n wire.get({\"#\": soul, \".\": item}, msg => {\n if (msg.err) {\n // Even if get fails, we've already removed from original soul\n map.delete(cb)\n allctx.delete(ctxid)\n return\n }\n\n const current = msg.put && msg.put[soul] && msg.put[soul][item]\n const id = utils.rel.is(current)\n if (id) wire.off({\"#\": id}, map.get(cb))\n map.delete(cb)\n allctx.delete(ctxid)\n })\n },\n user: () => {\n if (!user.get) {\n // Return the combined Holster and User APIs.\n Object.assign(user, api())\n // Need to provide a user specific get() function to know if user\n // context should be checked.\n user.get = (keys, lex, cb, _opt) => {\n if (typeof lex === \"function\") {\n _opt = cb\n cb = lex\n lex = null\n }\n\n let pub = null\n let key = null\n if (user.is) pub = user.is.pub\n if (typeof keys === \"string\") {\n key = keys\n } else if (keys instanceof Array) {\n if (keys.length === 2) {\n pub = keys[0]\n key = keys[1]\n } else if (keys.length === 1) {\n key = keys[0]\n }\n }\n if (!pub) {\n console.log(\"error please log in or provide a public key\")\n if (cb) cb(null)\n return\n }\n\n if (key === null || key === \"\" || key === \"_\") {\n console.log(\"error please provide a key\")\n if (cb) cb(null)\n return\n }\n\n // lex requires a callback as it's not included in the chain below.\n if (lex && !cb) {\n console.log(\"error lex requires a callback function\")\n return\n }\n\n ctxid = utils.text.random()\n const chain = [{item: String(key), soul: \"~\" + pub}]\n allctx.set(ctxid, {chain: chain, user: user.is, cb: cb})\n if (!cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const _done = done(ctxid)\n const {soul} = resolve({get: lex, _opt: _opt}, _done)\n if (soul) get(lex, soul, _done, _opt)\n }\n }\n return user\n },\n // Allow the wire spec to be used via holster.\n wire: wire,\n // Allow SEA functions to be used via holster.\n SEA: SEA,\n }\n }\n return api()\n}\n\nexport default Holster\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["num", "n", "parsed", "obj", "o", "match", "list", "cb", "keys", "i", "result", "key", "value", "map_soul", "soul", "rel", "userSignature", "userPublicKey", "graph", "data", "sig", "pub", "timestamp", "g", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "Dup", "maxAge", "dup", "id", "now", "dup_default", "Get", "lex", "graph", "fast", "soul", "node", "signatures", "key", "state", "userPublicKey", "pkState", "match", "get_default", "data", "SeaArray", "enc", "start", "end", "buf", "byte", "_", "i", "charCode", "utf8String", "array_default", "SECURITY_LIMITS", "SafeBuffer", "props", "validateStringInput", "input", "encoding", "validateBufferSize", "size", "operation", "parseHexString", "hexString", "cleanHex", "bytes", "i", "hexByte", "encodeUtf8String", "str", "err", "encodeBinaryString", "charCode", "parseBase64String", "base64String", "cleanBase64", "decodedString", "processArrayLikeInput", "val", "arr", "array_default", "length", "fill", "buffer", "totalLength", "validatedBuffers", "item", "result", "offset", "obj", "string", "clean", "start", "end", "buffer_default", "isNode", "crypto", "subtle", "stringify", "data", "parse", "text", "random", "length", "array", "buffer_default", "jwk", "pub", "priv", "x", "y", "sha256", "hash", "aeskey", "key", "salt", "combined", "keyToJwk", "SEA", "cb", "ecdsa", "subtle", "keys", "pub", "ecdh", "pair", "data", "rand", "random", "ct", "aeskey", "aes", "stringify", "enc", "buffer_default", "dec", "parse", "signed", "key", "jwk", "msg", "k", "userPublicKey", "userSignature", "hash", "sha256", "sig", "alg", "verified", "check", "timestamp", "timestampStr", "signature", "publicKey", "isValid", "err", "salt", "work", "to", "from", "pubKey", "priv", "derived", "derivedBits", "derivedKey", "sea_default", "MAX_GRAPH_SIZE", "Ham", "state", "currentState", "value", "currentValue", "signed", "change", "graph", "secure", "listen", "machine", "now", "defer", "listeners", "validProperties", "validTimestamps", "wait", "soul", "node", "updated", "alias", "nodeWait", "verify", "pub", "userPublicKey", "signedTimestamps", "signedProperties", "incomingTimestamps", "key", "sig", "asNumber", "propsForTimestamp", "ts", "prop", "sea_default", "rel", "skew", "isSigned", "l", "match", "souls", "states", "maxState", "a", "b", "ham_default", "group", "record", "Radix", "radix", "keys", "value", "tree", "i", "tmp", "key", "max", "noValue", "found", "obj", "hasValue", "hasKey", "j", "matchingKey", "replace", "map", "cb", "opt", "pre", "u", "radix_default", "etx", "enq", "unit", "Radisk", "opt", "u", "cache", "fileListCache", "fileListCacheTime", "FILE_LIST_CACHE_TTL", "pendingReads", "lastMemoryCheck", "MEMORY_CHECK_INTERVAL", "HEAP_WARNING_THRESHOLD", "HEAP_CLEANUP_THRESHOLD", "perfLog", "operation", "startTime", "key", "size", "duration", "checkMemoryUsage", "now", "memUsage", "heapUsed", "heapTotal", "maxHeapSize", "heapUsageRatio", "cacheSize", "radisk", "value", "cb", "pending", "err", "callback", "readStart", "result", "radix_default", "thrashStart", "batch", "i", "rad", "save", "tree", "file", "start", "end", "disk", "write", "k", "pre", "enc", "writeStart", "soul", "read", "cachedRadix", "files", "originalLex", "parse", "data", "preString", "tmp", "a", "o", "state", "sig", "current", "text", "rel", "num", "obj", "previous", "textStart", "textEnd", "parts", "radisk_default", "isNode", "fs", "enq", "unit", "root", "fileSystem", "opt", "dir", "file", "cb", "err", "data", "tmp", "text", "files", "db", "dbReady", "resolve", "reject", "o", "event", "req", "_get", "_put", "_list", "Store", "obj", "radisk", "radisk_default", "lex", "_opt", "soul", "key", "node", "signatures", "each", "value", "userPublicKey", "match", "graph", "radix_default", "count", "finished", "ack", "state", "sig", "store_default", "isNode", "wsModule", "createRateLimiter", "isTestEnv", "clients", "maxRequests", "windowMs", "disconnectThreshold", "cleanupInterval", "now", "clientId", "data", "time", "client", "oldestRequest", "delay", "validRequests", "safeJSONParse", "maxSize", "error", "validateMessage", "createConnectionManager", "maxConnections", "connections", "ws", "originalClose", "args", "createRetryHandler", "maxRetries", "retryCount", "Wire", "opt", "dup", "dup_default", "store", "store_default", "graph", "queue", "listen", "pendingReferences", "pendingTimeouts", "hasSoul", "soul", "resolve", "err", "rateLimiter", "connectionManager", "check", "send", "cb", "key", "userPublicKey", "msg", "res", "getWithCallback", "node", "get", "ack", "get_default", "text", "put", "update", "ham_default", "lex", "_opt", "obj", "track", "request", "sendResult", "api", "value", "soulId", "rel", "l", "_get", "found", "wss", "config", "isBinary", "trackId", "timeoutConfig", "id", "retryHandler", "validation", "parseResult", "throttleCount", "processMessage", "peers", "clientThrottled", "throttleUntil", "messageQueue", "queueProcessor", "maxQueueLength", "processQueue", "sendToPeers", "sentToAtLeastOne", "peer", "start", "c", "e", "m", "filteredPut", "shouldStore", "filteredMsg", "wire_default", "User", "opt", "wire", "wire_default", "wait", "pubs", "creating", "authing", "retries", "auth", "username", "password", "newPassword", "ack", "retry", "done", "err", "next", "pub", "msg", "data", "work", "sea_default", "dec", "user", "salt", "text", "enc", "update", "timestamp", "sig", "graph", "soul", "cb", "pair", "priv", "rel", "localStorage", "is", "user_default", "Holster", "opt", "obj", "wire", "wire_default", "user", "user_default", "map", "allctx", "ok", "data", "rel", "num", "check", "keys", "key", "value", "api", "ctxid", "get", "lex", "soul", "ack", "_opt", "msg", "userPublicKey", "userSignature", "id", "attemptRead", "retries", "res", "_ctxid", "text", "ctx", "resolve", "graph", "userctx", "cb", "timestamp", "sig", "sea_default", "done", "watchForRel", "item", "i", "request", "handler", "node", "put", "on", "off", "found", "g", "err", "_done", "_ack", "set", "result", "current", "chain", "r", "update", "updateNode", "_get", "retryCount", "maxRetries", "retryDelay", "retryTimer", "retry", "delay", "retryNode", "retryValue", "initialLex", "relLex", "pub", "holster_default"]
|
|
7
7
|
}
|