@mblaney/holster 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +33 -0
- package/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/examples/user.js +5 -0
- package/package.json +2 -2
- package/src/holster.js +57 -46
- package/src/index.js +0 -1
- package/src/sea-utils.js +1 -1
- package/src/store.js +1 -1
- package/src/wire.js +47 -35
- package/test/holster.put.test.js +59 -0
- package/test/holster.user.put.test.js +19 -1
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 !(n instanceof Array) &&\n (n - parseFloat(n) + 1 >= 0 || Infinity === n || -Infinity === n),\n}\n\nexport const obj = {\n is: o => {\n if (!o) return false\n\n return (\n (o instanceof Object && o.constructor === Object) ||\n Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] ===\n \"Object\"\n )\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 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) => {\n const g = {[soul]: {_: {\"#\": soul, \">\": {}, s: sig, p: pub}}}\n for (const [key, value] of Object.entries(data)) {\n g[soul][key] = value\n g[soul]._[\">\"][key] = Date.now()\n }\n // If a public key is provided it also needs to be stored on the node to\n // ensure that future updates are only possible with the same public key.\n if (pub) {\n g[soul][userPublicKey] = pub\n g[soul]._[\">\"][userPublicKey] = Date.now()\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 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 = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz\"\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 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", "const Get = (lex, graph) => {\n const soul = lex[\"#\"]\n const key = typeof lex[\".\"] === \"string\" ? lex[\".\"] : false\n var node = graph[soul]\n\n // Can only return a node if a key is provided, because the graph may not\n // have all the keys populated for a given soul. This is because Ham.mix\n // only adds incoming changes to the graph.\n if (!node || !key) return\n\n let value = node[key]\n if (!value) return\n\n node = {_: node._, [key]: value}\n node._[\">\"] = {[key]: node._[\">\"][key]}\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() {}\n\nObject.assign(SeaArray, {from: Array.from})\nSeaArray.prototype = Object.create(Array.prototype)\nSeaArray.prototype.toString = function (enc, start, end) {\n if (!enc) enc = \"utf8\"\n if (!start) start = 0\n\n const length = this.length\n if (enc === \"hex\") {\n const buf = new Uint8Array(this)\n return [...Array(((end && end + 1) || length) - start).keys()]\n .map(i => buf[i + start].toString(16).padStart(2, \"0\"))\n .join(\"\")\n }\n\n if (enc === \"utf8\") {\n return Array.from({length: (end || length) - start}, (_, i) =>\n String.fromCharCode(this[i + start]),\n ).join(\"\")\n }\n\n if (enc === \"base64\") {\n return btoa(this)\n }\n}\n\nexport default SeaArray\n", "import SeaArray from \"./array.js\"\n\n// This is Buffer implementation used in SEA. Functionality is mostly\n// compatible with NodeJS \"safe-buffer\" and is used for encoding conversions\n// between binary and \"hex\" | \"utf8\" | \"base64\"\n// See documentation and validation for safe implementation in:\n// https://github.com/feross/safe-buffer#update\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)\nObject.assign(SafeBuffer, {\n // (data, enc) where typeof data === \"string\" then\n // enc === \"utf8\"|\"hex\"|\"base64\"\n from() {\n if (!Object.keys(arguments).length || arguments[0] == null) {\n throw new TypeError(\n \"First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.\",\n )\n }\n const input = arguments[0]\n let buf\n if (typeof input === \"string\") {\n const enc = arguments[1] || \"utf8\"\n if (enc === \"hex\") {\n const bytes = input\n .match(/([\\da-fA-F]{2})/g)\n .map(byte => parseInt(byte, 16))\n if (!bytes || !bytes.length) {\n throw new TypeError(\"Invalid first argument for type 'hex'.\")\n }\n buf = SeaArray.from(bytes)\n } else if (enc === \"utf8\" || enc === \"binary\") {\n const length = input.length\n const words = new Uint16Array(length)\n Array.from({length: length}, (_, i) => (words[i] = input.charCodeAt(i)))\n buf = SeaArray.from(words)\n } else if (enc === \"base64\") {\n const dec = atob(input)\n const length = dec.length\n const bytes = new Uint8Array(length)\n Array.from({length: length}, (_, i) => (bytes[i] = dec.charCodeAt(i)))\n buf = SeaArray.from(bytes)\n } else {\n console.info(\"SafeBuffer.from unknown encoding: \" + enc)\n }\n return buf\n }\n const length = input.byteLength ? input.byteLength : input.length\n if (length) {\n let buf\n if (input instanceof ArrayBuffer) {\n buf = new Uint8Array(input)\n }\n const check = SeaArray.from(buf || input)\n return check\n }\n },\n // This is \"safe-buffer.alloc\" sans encoding support\n alloc(length, fill = 0) {\n return SeaArray.from(\n new Uint8Array(Array.from({length: length}, () => fill)),\n )\n },\n // This puts together array of array like members\n concat(arr) {\n // octet array\n if (!Array.isArray(arr)) {\n throw new TypeError(\n \"First argument must be Array containing ArrayBuffer or Uint8Array instances.\",\n )\n }\n return SeaArray.from(\n arr.reduce((ret, item) => ret.concat(Array.from(item)), []),\n )\n },\n})\nSafeBuffer.prototype.from = SafeBuffer.from\nSafeBuffer.prototype.toString = SeaArray.prototype.toString\n\nexport default SafeBuffer\n", "import SafeBuffer from \"./buffer.js\"\n\nconst isNode = typeof document === \"undefined\"\nconst crypto = isNode\n ? (await import(\"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} 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)) {\n if (k !== \"_\" && k != userPublicKey) msg[k] = signed.m[k]\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 const msg = utils.parse(data)\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 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// state and value are the incoming changes.\n// currentState and currentValue are the current graph data.\nconst Ham = (state, currentState, value, currentValue) => {\n if (state < currentState) return {historical: true}\n\n if (state > currentState) return {incoming: true}\n\n // state is equal to currentState, lexically compare to resolve conflict.\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 var machine = Date.now()\n var now = {}\n var defer = {}\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 pub = \"\"\n let verify = secure\n\n if (!node || !node._) continue\n\n // If a signature and public key are provided then always verify.\n if (node._.s && node._.p) 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 (node._.p && soul != \"~\" + node._.p) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n\n // Need to be able to create public key data before a user is\n // authenticated, in this case the soul is the public key which\n // should've been used to sign the data.\n node._.p = soul.slice(1)\n verify = true\n }\n }\n if (verify) {\n if (!node._.s || !node._.p) {\n console.log(\"error signature and public key required to verify data\")\n continue\n }\n\n if (!(await SEA.verify({m: node, s: node._.s}, {pub: node._.p}))) {\n console.log(`error could not verify soul: ${soul}`)\n continue\n }\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n const value = node[key]\n const state = node._[\">\"][key]\n const currentValue = (graph[soul] || {})[key]\n const currentState = (graph[soul] || {_: {\">\": {}}})._[\">\"][key] || 0\n\n if (alias && key !== utils.rel.is(value)) continue\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: node._.s, p: node._.p}}\n }\n defer[soul][key] = value\n defer[soul]._[\">\"][key] = state\n } else {\n const result = Ham(state, currentState, value, currentValue)\n if (result.incoming) {\n if (!now[soul]) {\n now[soul] = {_: {\"#\": soul, \">\": {}, s: node._.s, p: node._.p}}\n }\n // TODO: graph should not just grow indefintitely in memory.\n // Need to have a max size after which start dropping the oldest state\n // Do something similar to Dup which can handle deletes?\n if (!graph[soul]) {\n graph[soul] = {_: {\"#\": soul, \">\": {}, s: node._.s, p: node._.p}}\n }\n graph[soul][key] = now[soul][key] = value\n graph[soul]._[\">\"][key] = now[soul]._[\">\"][key] = state\n // Call event listeners for update on key, mix is called before\n // put has finished so wait for what could be multiple nested\n // updates on a node.\n if (listen[soul]) {\n setTimeout(() => {\n if (listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => l.cb())\n }\n }, 100)\n }\n updated = true\n }\n }\n }\n\n if (verify && nodeWait !== 0 && now[soul]) {\n // Secure updates can't be split, so move now to deferred as well.\n Object.assign(defer[soul], now[soul])\n delete now[soul]\n }\n // Call event listeners for update on soul.\n if (updated && listen[soul]) {\n setTimeout(() => {\n if (listen[soul]) {\n listen[soul].filter(l => utils.match(l[\".\"])).forEach(l => l.cb())\n }\n }, 100)\n }\n }\n return {now: now, defer: defer, wait: wait}\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 var cache = null\n\n if (!opt) opt = {}\n if (!opt.log) opt.log = console.log\n if (!opt.batch) opt.batch = 10 * 1000\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.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 // 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 return radisk.read(key, cb)\n }\n\n // Otherwise store the value provided.\n radisk.batch(key, value)\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 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 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 // 7. If file is to large then split. More details needed here\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 save.mix(save.file || \"!\", save.start, save.end)\n return true\n }\n\n save.file = file\n },\n mix: (file, start, end) => {\n save.start = save.end = save.file = u\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 save.start\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\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 // Invalidate cache on write.\n cache = null\n const write = {\n text: \"\",\n count: 0,\n file: file,\n each: (value, key, k, pre) => {\n write.count++\n var enc =\n Radisk.encode(pre.length) +\n \"#\" +\n Radisk.encode(k) +\n (typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)) +\n \"\\n\"\n // Cannot split the file if only have one entry to write.\n if (write.count > 1 && write.text.length + enc.length > opt.size) {\n write.text = \"\"\n // Otherwise split the entries in half.\n write.limit = Math.ceil(write.count / 2)\n write.count = 0\n write.sub = Radix()\n Radix.map(rad, write.slice)\n return true\n }\n\n write.text += enc\n },\n put: () => {\n opt.store.put(file, write.text, cb)\n },\n slice: (value, key) => {\n if (key < write.file) return\n\n if (++write.count > write.limit) {\n var name = write.file\n // Use only the soul of the key as the filename so that all\n // properties of a soul are written to the same file.\n let end = key.indexOf(enq)\n if (end === -1) {\n write.file = key\n } else {\n write.file = key.substring(0, end)\n }\n // write.limit can be reached after already writing properties of\n // the current node, so remove it from write.sub before writing to\n // disk so that it's not duplicated across files.\n write.sub(write.file, null)\n write.count = 0\n radisk.write(name, write.sub, write.next)\n return true\n }\n\n write.sub(key, value)\n },\n next: err => {\n if (err) return cb(err)\n\n write.sub = Radix()\n if (!Radix.map(rad, write.slice)) {\n radisk.write(write.file, write.sub, cb)\n }\n },\n }\n // If Radix.map doesn't return true when called with write.each as a\n // callback then didn't need to split the data. The accumulated write.text\n // can then be stored with write.put().\n if (!Radix.map(rad, write.each, true)) write.put()\n }\n\n radisk.read = (key, cb) => {\n if (cache) {\n let value = cache(key)\n if (typeof value !== \"undefined\") return cb(u, value)\n }\n // Only the soul of the key is compared to filenames (see radisk.write).\n let soul = key\n let end = key.indexOf(enq)\n if (end !== -1) {\n soul = key.substring(0, end)\n }\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 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 cache = disk\n read.value = disk(key)\n }\n cb(err, read.value)\n },\n }\n opt.store.list(read.lex)\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 // 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 pre = pre.slice(0, i)\n if (i <= pre.length) pre.push(key)\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(pre.join(\"\"), value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(u, parse.disk)\n },\n split: data => {\n if (!data) return\n\n let i = -1\n let a = \"\"\n let c = null\n while ((c = data[++i])) {\n if (c === unit) break\n\n a += c\n }\n let o = {}\n if (c) {\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i)]\n }\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 items to include the value's state, as is done by store.js.\n let state = \"\"\n if (data instanceof Array && data.length === 2) {\n state = etx + data[1]\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 + unit\n }\n\n const rel = utils.rel.is(data)\n if (rel) return unit + \"#\" + rel + state + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + unit\n\n if (data === true) return unit + \"+\" + state + unit\n\n if (data === false) return unit + \"-\" + state + unit\n\n if (data === null) return unit + \" \" + state + unit\n}\n\nRadisk.decode = (data, obj) => {\n var text = \"\"\n var i = -1\n var n = 0\n var current = null\n var previous = null\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 (current === unit) {\n if (--n <= 0) break\n }\n text += current\n } else if (current === unit) {\n n++\n } else {\n previous = current || true\n }\n }\n\n if (obj) obj.i = i + 1\n\n let [value, state] = text.split(etx)\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.\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\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(\"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 var random = Math.random().toString(36).slice(-9)\n // Don't put tmp files under dir so that they're not listed.\n var tmp = file + \".\" + random + \".tmp\"\n fs.writeFile(tmp, data, err => {\n if (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 files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db\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 }\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 }\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 }\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n }\n }\n\n return {\n get: (file, cb) => {\n if (db) {\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 } else {\n cb(\"error indexedDB not available\")\n }\n },\n put: (file, data, cb) => {\n if (db) {\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 } else {\n cb(\"error indexedDB not available\")\n }\n },\n list: cb => {\n if (db) {\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 } else {\n console.log(\"error indexedDB not available\")\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) => {\n if (!lex) {\n cb(\"lex required\")\n return\n }\n\n var soul = lex[\"#\"]\n var key = typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n var node\n const each = (value, key) => {\n if (!utils.match(lex[\".\"], key)) return\n\n if (!node) node = {_: {\"#\": soul, \">\": {}}}\n node[key] = value[0]\n node._[\">\"][key] = value[1]\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 cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n var count = 0\n const ack = err => {\n count--\n if (ack.err) return\n\n ack.err = err\n if (ack.err) {\n cb(ack.err)\n return\n }\n\n if (count === 0) cb(null)\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 radisk(soul + enq + key, [value, state], 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// 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 if (!utils.obj.is(opt)) opt = {}\n\n const dup = Dup(opt.maxAge)\n const store = Store(opt)\n const graph = {}\n const queue = {}\n const listen = {}\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 for (const soul of Object.keys(data)) {\n const msg = await new Promise(res => {\n getWithCallback({\"#\": soul}, res, send)\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n const node = data[soul]\n const pub = node._ ? node._.p : undefined\n const key = utils.userPublicKey\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 publc keys\n // need to match for existing data.\n if (!msg.put || !msg.put[soul] || msg.put[soul][key] === pub) {\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 store.get(msg.get, (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 }\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) {\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 })\n }\n if (Object.keys(update.defer).length) {\n setTimeout(() => put({put: update.defer}, send), update.wait)\n }\n }\n\n const getWithCallback = (lex, cb, send, opt) => {\n if (!cb) return\n\n if (!utils.obj.is(opt)) opt = {}\n const ack = Get(lex, graph)\n if (ack) {\n cb({put: ack})\n return\n }\n\n store.get(lex, (err, ack) => {\n if (ack) {\n cb({put: ack, err: err})\n return\n }\n\n if (err) console.log(err)\n\n const track = utils.text.random(9)\n queue[track] = cb\n send(\n JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n }),\n )\n // Respond to callback with null if no response.\n setTimeout(() => {\n const cb = queue[track]\n if (cb) {\n const id = lex[\"#\"]\n const ack = {[id]: null}\n if (typeof lex[\".\"] === \"string\") ack[id] = {[lex[\".\"]]: null}\n cb({put: ack})\n delete queue[track]\n }\n }, opt.wait || 100)\n })\n }\n\n const api = send => {\n return {\n get: (lex, cb, opt) => {\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 const none = Object.keys(update.now).length === 0\n if (none || !(await check(update.now, send, cb))) return\n\n store.put(update.now, cb)\n // Also put data on the wire spec.\n // TODO: Note that this means all clients now receive all updates, so\n // need to filter what should be stored, both in graph and on disk.\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n }),\n )\n },\n on: (lex, cb) => {\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 },\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 wss = new wsModule.WebSocketServer({port: 8080})\n clients = () => wss.clients\n }\n\n const send = (data, isBinary) => {\n clients().forEach(client => {\n if (client.readyState === WebSocket.OPEN) {\n client.send(data, {binary: isBinary})\n }\n })\n }\n wss.on(\"connection\", ws => {\n ws.on(\"error\", console.error)\n\n ws.on(\"message\", (data, isBinary) => {\n const msg = JSON.parse(data)\n if (dup.check(msg[\"#\"])) return\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) 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 return api(send)\n }\n\n let ws = new WebSocket(\"ws://localhost:8080\")\n const send = data => {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n console.log(\"websocket not available\")\n return\n }\n\n ws.send(data)\n }\n const start = () => {\n if (!ws) ws = new WebSocket(\"ws://localhost:8080\")\n ws.onclose = c => {\n ws = null\n setTimeout(start, Math.floor(Math.random() * 5000))\n }\n ws.onerror = e => {\n console.error(e)\n }\n ws.onmessage = m => {\n const msg = JSON.parse(m.data)\n if (dup.check(msg[\"#\"])) return\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) put(msg, send)\n send(m.data)\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\n start()\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\"\n\nconst User = (opt, wire) => {\n if (!wire) wire = Wire(opt)\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({\"#\": pub}, 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 // Holster API uses ctx to set the root node for user data.\n user.ctx = \"~\" + data.pub\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 const auth = {auth: JSON.stringify({enc: enc, salt: salt})}\n const signed = await SEA.sign(auth, user.is)\n const graph = utils.graph(pub, signed.m, signed.s, data.pub)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${auth} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n return done(null)\n })\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get({\"#\": soul}, 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 }\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({\"#\": soul}, 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 const signed = await SEA.sign(data, pair)\n const graph = utils.graph(pub, signed.m, signed.s, pair.pub)\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 },\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 return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n },\n recall: localStorage => {\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n user.ctx = \"~\" + user.is.pub\n } else {\n console.log(\"User credentials not stored in local storage\")\n }\n }\n return\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 user.ctx = \"~\" + user.is.pub\n } else {\n console.log(\"User credentials not stored in session storage\")\n }\n }\n },\n leave: () => {\n user.is = null\n user.ctx = 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 const signed = await SEA.sign(data, user.is)\n const pub = \"~\" + user.is.pub\n const graph = utils.graph(pub, signed.m, signed.s, user.is.pub)\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 user.ctx = 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 const wire = Wire(opt)\n const user = User(null, 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 an item name\"\n }\n if (utils.obj.is(value) || ok(value)) {\n keys.push(key)\n continue\n }\n return `error {${key}:${value}} cannot be converted to graph`\n }\n if (keys.length !== 0) return keys\n }\n return `error ${data} cannot be converted to a graph`\n }\n\n const api = ctxid => {\n const get = (lex, soul, ack) => {\n wire.get(utils.obj.put(lex, \"#\", soul), 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 // 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 const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: null, soul: id}]})\n api(_ctxid).next(null, res)\n })\n msg.put[soul][key] = data\n }\n }\n ack(msg.put[soul])\n } else {\n // No data callback.\n ack(null)\n }\n })\n }\n\n const graph = async (soul, data, cb) => {\n if (!cb) cb = console.log\n\n if (!user.is) {\n if (opt.secure) {\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 if (!user.is) {\n cb(`error putting data on ${soul}: user not authenticated`)\n return null\n }\n\n const signed = await SEA.sign(data, user.is)\n return utils.graph(soul, signed.m, signed.s, user.is.pub)\n }\n\n const done = data => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") ctx.cb(data)\n else if (data) console.log(data)\n // A context updated by \"on\" should only be removed by \"off\".\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n\n const resolve = (request, cb) => {\n const get = request && typeof request.get !== \"undefined\"\n const put = request && typeof request.put !== \"undefined\"\n const on = request && typeof request.on !== \"undefined\"\n const off = request && 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({\"#\": soul, \".\": item}, 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 const 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 // Not sure why the map needs to be set rather than just ctx?\n allctx.set(ctxid, {chain: ctx.chain, cb: ctx.cb})\n // Call api again using the updated context.\n if (get) api(ctxid).next(null, request.get, cb)\n else if (put) api(ctxid).put(request.put, cb)\n else if (on) api(ctxid).on(request.on, cb)\n else if (off) api(ctxid).off(cb)\n } else if (get) {\n // Request was not for a node, return a property on the current\n // 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 const rel = {[item]: utils.rel.ify(id)}\n const g = await graph(soul, rel, 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 console.log(`error resolving on for ${item} on ${soul}`)\n cb(null)\n } else if (off) {\n console.log(`error resolving off for ${item} on ${soul}`)\n if (cb) cb(null)\n }\n } else if (put) {\n cb(`error ${item} not found on ${soul}`)\n } else {\n console.log(`error ${item} not found on ${soul}`)\n if (cb) cb(null)\n }\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)\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) => {\n if (typeof lex === \"function\") {\n cb = lex\n lex = null\n }\n if (key === null || key === \"\" || 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(\"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, the user's public key is used as the root node when\n // user.ctx is set.\n const root = user.ctx ? user.ctx : \"root\"\n\n ctxid = utils.text.random()\n allctx.set(ctxid, {chain: [{item: key, soul: root}], cb: cb})\n if (!cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex}, done)\n if (soul) get(lex, soul, done)\n },\n next: (key, lex, cb) => {\n const ack = data => {\n cb ? cb(data) : done(data)\n }\n\n if (typeof lex === \"function\") {\n cb = lex\n lex = null\n }\n if (!ctxid) {\n console.log(\"please provide a key using get(key)\")\n ack(null)\n return\n }\n\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 && !cb) {\n console.log(\"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: 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}, ack)\n if (soul) get(lex, soul, ack)\n },\n put: (data, cb) => {\n const ack = err => {\n cb ? cb(err) : done(err)\n }\n\n if (!ctxid) {\n ack(\"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\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.\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({\"#\": soul, \".\": item}, async msg => {\n if (msg.err) {\n console.log(`error getting ${soul}: ${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 // Not a rel, can just put the data.\n const g = await graph(soul, {[item]: data}, 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 console.log(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n console.log(`error ${id} not found`)\n return\n }\n\n delete msg.put[id]._\n // null each of the properties on the node before putting data.\n for (const key of Object.keys(msg.put[id])) {\n if (key === utils.userPublicKey) continue\n\n const err = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: key, soul: id}]})\n api(_ctxid).put(null, res)\n })\n if (err) {\n ack(err)\n return\n }\n }\n const g = await graph(soul, {[item]: data}, ack)\n if (g === null) return\n\n wire.put(g, ack)\n })\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 wire.get({\"#\": soul, \".\": item}, async msg => {\n if (msg.err) {\n ack(`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 // The current rel doesn't exist, so add it first.\n const rel = {[item]: utils.rel.ify(utils.text.random())}\n const g = await graph(soul, rel, 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 the previous context's callback on here.\n allctx.set(_ctxid, {chain: chain, cb: ctx.cb})\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n let put = false\n const update = {}\n for (const key of result) {\n const err = await new Promise(res => {\n if (utils.obj.is(data[key])) {\n // Use the current rel as the context for nested objects.\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: key, soul: id}]})\n api(_ctxid).put(data[key], res)\n } else {\n put = true\n // Group other properties into one update.\n update[key] = data[key]\n res(null)\n }\n })\n if (err) {\n ack(err)\n return\n }\n }\n if (put) {\n const g = await graph(id, update, ack)\n if (g === null) return\n\n wire.put(g, ack)\n } else {\n // Callback on behalf of nested objects.\n ack(null)\n }\n })\n },\n on: (lex, cb) => {\n if (typeof lex === \"function\") {\n cb = lex\n lex = null\n }\n if (!cb) return\n\n if (!ctxid) {\n console.log(\"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}, cb)\n if (!soul) return\n\n // Flag that this context is set from on and shouldn't be removed.\n allctx.set(ctxid, {chain: [{item: item, soul: soul}], on: true})\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 map.set(cb, () => api(ctxid).next(null, cb))\n // Check if item is a rel and add event listener for the node.\n wire.get({\"#\": soul, \".\": item}, 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 if (lex) lex = utils.obj.put(lex, \"#\", id)\n else lex = {\"#\": id, \".\": null}\n } else {\n if (lex) lex = utils.obj.put(lex, \"#\", soul)\n else lex = {\"#\": soul, \".\": item}\n }\n wire.on(lex, map.get(cb))\n })\n },\n off: cb => {\n if (!ctxid) {\n console.log(\"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 // Check if item is a rel and remove event listener for the node.\n wire.get({\"#\": soul, \".\": item}, 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) wire.off({\"#\": id}, map.get(cb))\n else wire.off({\"#\": soul}, map.get(cb))\n map.delete(cb)\n allctx.delete(ctxid)\n })\n },\n user: pub => {\n // Return the combined Holster and User APIs. Passing in a public key\n // will set the user context to that key, otherwise user.ctx is set when\n // a user logs in so that their public key will be used as the root node\n // in get(), also put() will sign all graph updates for verification.\n if (pub) user.ctx = \"~\" + pub\n return Object.assign(user, api())\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", "obj", "o", "list", "cb", "keys", "i", "result", "key", "value", "map_soul", "soul", "rel", "userPublicKey", "graph", "data", "sig", "pub", "g", "match", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "Dup", "maxAge", "dup", "id", "now", "dup_default", "Get", "lex", "graph", "soul", "key", "node", "value", "get_default", "data", "SeaArray", "enc", "start", "end", "length", "buf", "i", "_", "array_default", "SafeBuffer", "props", "input", "buf", "enc", "bytes", "byte", "array_default", "length", "words", "_", "i", "dec", "fill", "arr", "ret", "item", "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", "hash", "sha256", "sig", "alg", "verified", "salt", "work", "to", "from", "pubKey", "priv", "derived", "derivedBits", "derivedKey", "sea_default", "Ham", "state", "currentState", "value", "currentValue", "change", "graph", "secure", "listen", "machine", "now", "defer", "wait", "soul", "node", "updated", "alias", "nodeWait", "pub", "verify", "sea_default", "key", "rel", "skew", "l", "match", "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", "radisk", "key", "value", "cb", "radix_default", "batch", "i", "err", "rad", "save", "tree", "file", "start", "end", "disk", "write", "k", "pre", "enc", "name", "soul", "read", "parse", "data", "tmp", "c", "o", "state", "current", "text", "rel", "num", "obj", "previous", "radisk_default", "isNode", "fs", "enq", "unit", "root", "fileSystem", "opt", "dir", "file", "cb", "err", "data", "random", "tmp", "files", "db", "o", "event", "req", "Store", "obj", "radisk", "radisk_default", "lex", "soul", "key", "node", "each", "value", "match", "graph", "radix_default", "count", "ack", "state", "store_default", "isNode", "wsModule", "Wire", "opt", "
|
|
4
|
+
"sourcesContent": ["export const num = {\n is: n =>\n !(n instanceof Array) &&\n (n - parseFloat(n) + 1 >= 0 || Infinity === n || -Infinity === n),\n}\n\nexport const obj = {\n is: o => {\n if (!o) return false\n\n return (\n (o instanceof Object && o.constructor === Object) ||\n Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] ===\n \"Object\"\n )\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 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) => {\n const g = {[soul]: {_: {\"#\": soul, \">\": {}, s: sig, p: pub}}}\n for (const [key, value] of Object.entries(data)) {\n g[soul][key] = value\n g[soul]._[\">\"][key] = Date.now()\n }\n // If a public key is provided it also needs to be stored on the node to\n // ensure that future updates are only possible with the same public key.\n if (pub) {\n g[soul][userPublicKey] = pub\n g[soul]._[\">\"][userPublicKey] = Date.now()\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 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 = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz\"\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 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", "const Get = (lex, graph) => {\n const soul = lex[\"#\"]\n const key = typeof lex[\".\"] === \"string\" ? lex[\".\"] : false\n var node = graph[soul]\n\n // Can only return a node if a key is provided, because the graph may not\n // have all the keys populated for a given soul. This is because Ham.mix\n // only adds incoming changes to the graph.\n if (!node || !key) return\n\n let value = node[key]\n if (!value) return\n\n node = {_: node._, [key]: value}\n node._[\">\"] = {[key]: node._[\">\"][key]}\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() {}\n\nObject.assign(SeaArray, {from: Array.from})\nSeaArray.prototype = Object.create(Array.prototype)\nSeaArray.prototype.toString = function (enc, start, end) {\n if (!enc) enc = \"utf8\"\n if (!start) start = 0\n\n const length = this.length\n if (enc === \"hex\") {\n const buf = new Uint8Array(this)\n return [...Array(((end && end + 1) || length) - start).keys()]\n .map(i => buf[i + start].toString(16).padStart(2, \"0\"))\n .join(\"\")\n }\n\n if (enc === \"utf8\") {\n return Array.from({length: (end || length) - start}, (_, i) =>\n String.fromCharCode(this[i + start]),\n ).join(\"\")\n }\n\n if (enc === \"base64\") {\n return btoa(this)\n }\n}\n\nexport default SeaArray\n", "import SeaArray from \"./array.js\"\n\n// This is Buffer implementation used in SEA. Functionality is mostly\n// compatible with NodeJS \"safe-buffer\" and is used for encoding conversions\n// between binary and \"hex\" | \"utf8\" | \"base64\"\n// See documentation and validation for safe implementation in:\n// https://github.com/feross/safe-buffer#update\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)\nObject.assign(SafeBuffer, {\n // (data, enc) where typeof data === \"string\" then\n // enc === \"utf8\"|\"hex\"|\"base64\"\n from() {\n if (!Object.keys(arguments).length || arguments[0] == null) {\n throw new TypeError(\n \"First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.\",\n )\n }\n const input = arguments[0]\n let buf\n if (typeof input === \"string\") {\n const enc = arguments[1] || \"utf8\"\n if (enc === \"hex\") {\n const bytes = input\n .match(/([\\da-fA-F]{2})/g)\n .map(byte => parseInt(byte, 16))\n if (!bytes || !bytes.length) {\n throw new TypeError(\"Invalid first argument for type 'hex'.\")\n }\n buf = SeaArray.from(bytes)\n } else if (enc === \"utf8\" || enc === \"binary\") {\n const length = input.length\n const words = new Uint16Array(length)\n Array.from({length: length}, (_, i) => (words[i] = input.charCodeAt(i)))\n buf = SeaArray.from(words)\n } else if (enc === \"base64\") {\n const dec = atob(input)\n const length = dec.length\n const bytes = new Uint8Array(length)\n Array.from({length: length}, (_, i) => (bytes[i] = dec.charCodeAt(i)))\n buf = SeaArray.from(bytes)\n } else {\n console.info(\"SafeBuffer.from unknown encoding: \" + enc)\n }\n return buf\n }\n const length = input.byteLength ? input.byteLength : input.length\n if (length) {\n let buf\n if (input instanceof ArrayBuffer) {\n buf = new Uint8Array(input)\n }\n const check = SeaArray.from(buf || input)\n return check\n }\n },\n // This is \"safe-buffer.alloc\" sans encoding support\n alloc(length, fill = 0) {\n return SeaArray.from(\n new Uint8Array(Array.from({length: length}, () => fill)),\n )\n },\n // This puts together array of array like members\n concat(arr) {\n // octet array\n if (!Array.isArray(arr)) {\n throw new TypeError(\n \"First argument must be Array containing ArrayBuffer or Uint8Array instances.\",\n )\n }\n return SeaArray.from(\n arr.reduce((ret, item) => ret.concat(Array.from(item)), []),\n )\n },\n})\nSafeBuffer.prototype.from = SafeBuffer.from\nSafeBuffer.prototype.toString = SeaArray.prototype.toString\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} 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)) {\n if (k !== \"_\" && k != userPublicKey) msg[k] = signed.m[k]\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 const msg = utils.parse(data)\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 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// state and value are the incoming changes.\n// currentState and currentValue are the current graph data.\nconst Ham = (state, currentState, value, currentValue) => {\n if (state < currentState) return {historical: true}\n\n if (state > currentState) return {incoming: true}\n\n // state is equal to currentState, lexically compare to resolve conflict.\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 var machine = Date.now()\n var now = {}\n var defer = {}\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 pub = \"\"\n let verify = secure\n\n if (!node || !node._) continue\n\n // If a signature and public key are provided then always verify.\n if (node._.s && node._.p) 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 (node._.p && soul != \"~\" + node._.p) {\n console.log(`error public key does not match for soul: ${soul}`)\n continue\n }\n\n // Need to be able to create public key data before a user is\n // authenticated, in this case the soul is the public key which\n // should've been used to sign the data.\n node._.p = soul.slice(1)\n verify = true\n }\n }\n if (verify) {\n if (!node._.s || !node._.p) {\n console.log(\"error signature and public key required to verify data\")\n continue\n }\n\n if (!(await SEA.verify({m: node, s: node._.s}, {pub: node._.p}))) {\n console.log(`error could not verify soul: ${soul}`)\n continue\n }\n }\n\n for (const key of Object.keys(node)) {\n if (key === \"_\") continue\n\n const value = node[key]\n const state = node._[\">\"][key]\n const currentValue = (graph[soul] || {})[key]\n const currentState = (graph[soul] || {_: {\">\": {}}})._[\">\"][key] || 0\n\n if (alias && key !== utils.rel.is(value)) continue\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: node._.s, p: node._.p}}\n }\n defer[soul][key] = value\n defer[soul]._[\">\"][key] = state\n } else {\n const result = Ham(state, currentState, value, currentValue)\n if (result.incoming) {\n if (!now[soul]) {\n now[soul] = {_: {\"#\": soul, \">\": {}, s: node._.s, p: node._.p}}\n }\n // TODO: graph should not just grow indefintitely in memory.\n // Need to have a max size after which start dropping the oldest state\n // Do something similar to Dup which can handle deletes?\n if (!graph[soul]) {\n graph[soul] = {_: {\"#\": soul, \">\": {}, s: node._.s, p: node._.p}}\n }\n graph[soul][key] = now[soul][key] = value\n graph[soul]._[\">\"][key] = now[soul]._[\">\"][key] = state\n // Call event listeners for update on key, mix is called before\n // put has finished so wait for what could be multiple nested\n // updates on a node.\n if (listen[soul]) {\n setTimeout(() => {\n if (listen[soul]) {\n listen[soul]\n .filter(l => utils.match(l[\".\"], key))\n .forEach(l => l.cb())\n }\n }, 100)\n }\n updated = true\n }\n }\n }\n\n if (verify && nodeWait !== 0 && now[soul]) {\n // Secure updates can't be split, so move now to deferred as well.\n Object.assign(defer[soul], now[soul])\n delete now[soul]\n }\n // Call event listeners for update on soul.\n if (updated && listen[soul]) {\n setTimeout(() => {\n if (listen[soul]) {\n listen[soul].filter(l => utils.match(l[\".\"])).forEach(l => l.cb())\n }\n }, 100)\n }\n }\n return {now: now, defer: defer, wait: wait}\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 var cache = null\n\n if (!opt) opt = {}\n if (!opt.log) opt.log = console.log\n if (!opt.batch) opt.batch = 10 * 1000\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.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 // 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 return radisk.read(key, cb)\n }\n\n // Otherwise store the value provided.\n radisk.batch(key, value)\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 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 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 // 7. If file is to large then split. More details needed here\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 save.mix(save.file || \"!\", save.start, save.end)\n return true\n }\n\n save.file = file\n },\n mix: (file, start, end) => {\n save.start = save.end = save.file = u\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 save.start\n }\n\n disk(key, value)\n })\n radisk.write(file, disk, save.next)\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 // Invalidate cache on write.\n cache = null\n const write = {\n text: \"\",\n count: 0,\n file: file,\n each: (value, key, k, pre) => {\n write.count++\n var enc =\n Radisk.encode(pre.length) +\n \"#\" +\n Radisk.encode(k) +\n (typeof value === \"undefined\" ? \"\" : \"=\" + Radisk.encode(value)) +\n \"\\n\"\n // Cannot split the file if only have one entry to write.\n if (write.count > 1 && write.text.length + enc.length > opt.size) {\n write.text = \"\"\n // Otherwise split the entries in half.\n write.limit = Math.ceil(write.count / 2)\n write.count = 0\n write.sub = Radix()\n Radix.map(rad, write.slice)\n return true\n }\n\n write.text += enc\n },\n put: () => {\n opt.store.put(file, write.text, cb)\n },\n slice: (value, key) => {\n if (key < write.file) return\n\n if (++write.count > write.limit) {\n var name = write.file\n // Use only the soul of the key as the filename so that all\n // properties of a soul are written to the same file.\n let end = key.indexOf(enq)\n if (end === -1) {\n write.file = key\n } else {\n write.file = key.substring(0, end)\n }\n // write.limit can be reached after already writing properties of\n // the current node, so remove it from write.sub before writing to\n // disk so that it's not duplicated across files.\n write.sub(write.file, null)\n write.count = 0\n radisk.write(name, write.sub, write.next)\n return true\n }\n\n write.sub(key, value)\n },\n next: err => {\n if (err) return cb(err)\n\n write.sub = Radix()\n if (!Radix.map(rad, write.slice)) {\n radisk.write(write.file, write.sub, cb)\n }\n },\n }\n // If Radix.map doesn't return true when called with write.each as a\n // callback then didn't need to split the data. The accumulated write.text\n // can then be stored with write.put().\n if (!Radix.map(rad, write.each, true)) write.put()\n }\n\n radisk.read = (key, cb) => {\n if (cache) {\n let value = cache(key)\n if (typeof value !== \"undefined\") return cb(u, value)\n }\n // Only the soul of the key is compared to filenames (see radisk.write).\n let soul = key\n let end = key.indexOf(enq)\n if (end !== -1) {\n soul = key.substring(0, end)\n }\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 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 cache = disk\n read.value = disk(key)\n }\n cb(err, read.value)\n },\n }\n opt.store.list(read.lex)\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 // 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 pre = pre.slice(0, i)\n if (i <= pre.length) pre.push(key)\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(pre.join(\"\"), value)\n }\n tmp = parse.split(tmp[2])\n }\n cb(u, parse.disk)\n },\n split: data => {\n if (!data) return\n\n let i = -1\n let a = \"\"\n let c = null\n while ((c = data[++i])) {\n if (c === unit) break\n\n a += c\n }\n let o = {}\n if (c) {\n return [a, Radisk.decode(data.slice(i), o), data.slice(i + o.i)]\n }\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 items to include the value's state, as is done by store.js.\n let state = \"\"\n if (data instanceof Array && data.length === 2) {\n state = etx + data[1]\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 + unit\n }\n\n const rel = utils.rel.is(data)\n if (rel) return unit + \"#\" + rel + state + unit\n\n if (utils.num.is(data)) return unit + \"+\" + (data || 0) + state + unit\n\n if (data === true) return unit + \"+\" + state + unit\n\n if (data === false) return unit + \"-\" + state + unit\n\n if (data === null) return unit + \" \" + state + unit\n}\n\nRadisk.decode = (data, obj) => {\n var text = \"\"\n var i = -1\n var n = 0\n var current = null\n var previous = null\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 (current === unit) {\n if (--n <= 0) break\n }\n text += current\n } else if (current === unit) {\n n++\n } else {\n previous = current || true\n }\n }\n\n if (obj) obj.i = i + 1\n\n let [value, state] = text.split(etx)\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.\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\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 var random = Math.random().toString(36).slice(-9)\n // Don't put tmp files under dir so that they're not listed.\n var tmp = file + \".\" + random + \".tmp\"\n fs.writeFile(tmp, data, err => {\n if (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 files.forEach(cb)\n cb()\n })\n },\n }\n }\n\n if (opt.indexedDB) {\n let db\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 }\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 }\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 }\n }\n }\n } else {\n console.log(\"error indexedDB not available\")\n }\n }\n\n return {\n get: (file, cb) => {\n if (db) {\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 } else {\n cb(\"error indexedDB not available\")\n }\n },\n put: (file, data, cb) => {\n if (db) {\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 } else {\n cb(\"error indexedDB not available\")\n }\n },\n list: cb => {\n if (db) {\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 } else {\n console.log(\"error indexedDB not available\")\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) => {\n if (!lex) {\n cb(\"lex required\")\n return\n }\n\n var soul = lex[\"#\"]\n var key = typeof lex[\".\"] === \"string\" ? lex[\".\"] : \"\"\n var node\n const each = (value, key) => {\n if (!utils.match(lex[\".\"], key)) return\n\n if (!node) node = {_: {\"#\": soul, \">\": {}}}\n node[key] = value[0]\n node._[\">\"][key] = value[1]\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 cb(err, graph)\n })\n },\n put: (graph, cb) => {\n if (!graph) {\n cb(\"graph required\")\n return\n }\n\n var count = 0\n const ack = err => {\n count--\n if (ack.err) return\n\n ack.err = err\n if (ack.err) {\n cb(ack.err)\n return\n }\n\n if (count === 0) cb(null)\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 radisk(soul + enq + key, [value, state], 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// 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 // 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 for (const soul of Object.keys(data)) {\n const msg = await new Promise(res => {\n getWithCallback({\"#\": soul}, res, send)\n })\n if (msg.err) {\n if (cb) cb(msg.err)\n return false\n }\n\n const node = data[soul]\n const pub = node._ ? node._.p : undefined\n const key = utils.userPublicKey\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 publc keys\n // need to match for existing data.\n if (!msg.put || !msg.put[soul] || msg.put[soul][key] === pub) {\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 store.get(msg.get, (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 }\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) {\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 })\n }\n if (Object.keys(update.defer).length) {\n setTimeout(() => put({put: update.defer}, send), update.wait)\n }\n }\n\n const getWithCallback = (lex, cb, send, opt) => {\n if (!cb) return\n\n if (!utils.obj.is(opt)) opt = {}\n const ack = Get(lex, graph)\n if (ack) {\n cb({put: ack})\n return\n }\n\n store.get(lex, (err, ack) => {\n if (ack) {\n cb({put: ack, err: err})\n return\n }\n\n if (err) console.log(err)\n\n const track = utils.text.random(9)\n queue[track] = cb\n send(\n JSON.stringify({\n \"#\": dup.track(track),\n get: lex,\n }),\n )\n // Respond to callback with null if no response.\n setTimeout(() => {\n const cb = queue[track]\n if (cb) {\n const id = lex[\"#\"]\n const ack = {[id]: null}\n if (typeof lex[\".\"] === \"string\") ack[id] = {[lex[\".\"]]: null}\n cb({put: ack})\n delete queue[track]\n }\n }, opt.wait || 100)\n })\n }\n\n const api = send => {\n return {\n get: (lex, cb, opt) => {\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 const none = Object.keys(update.now).length === 0\n if (none || !(await check(update.now, send, cb))) return\n\n store.put(update.now, cb)\n // Also put data on the wire spec.\n // TODO: Note that this means all clients now receive all updates, so\n // need to filter what should be stored, both in graph and on disk.\n send(\n JSON.stringify({\n \"#\": dup.track(utils.text.random(9)),\n put: data,\n }),\n )\n },\n on: (lex, cb) => {\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 },\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 clients().forEach(client => {\n if (client.readyState === WebSocket.OPEN) {\n client.send(data, {binary: isBinary})\n }\n })\n }\n wss.on(\"connection\", ws => {\n ws.on(\"error\", console.error)\n\n ws.on(\"message\", (data, isBinary) => {\n const msg = JSON.parse(data)\n if (dup.check(msg[\"#\"])) return\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) 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 return api(send)\n }\n\n const peers = []\n const send = data => {\n peers.forEach(peer => {\n if (peer && peer.readyState === WebSocket.OPEN) {\n peer.send(data)\n } else {\n console.log(\"websocket not available\")\n }\n })\n }\n if (!(opt.peers instanceof Array)) {\n opt.peers = [`ws://localhost:${opt.port || 8765}`]\n }\n opt.peers.forEach(peer => {\n let ws = new WebSocket(peer)\n peers.push(ws)\n const start = () => {\n if (!ws) ws = new WebSocket(peer)\n ws.onclose = c => {\n if (peers.indexOf(ws) !== -1) {\n peers.splice(peers.indexOf(ws), 1)\n }\n ws = null\n setTimeout(start, Math.floor(Math.random() * 5000))\n }\n ws.onerror = e => {\n console.error(e)\n }\n ws.onmessage = m => {\n const msg = JSON.parse(m.data)\n if (dup.check(msg[\"#\"])) return\n\n dup.track(msg[\"#\"])\n if (msg.get) get(msg, send)\n if (msg.put) put(msg, send)\n send(m.data)\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\"\n\nconst User = (opt, wire) => {\n if (!wire) wire = Wire(opt)\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({\"#\": pub}, 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 // Holster API uses ctx to set the root node for user data.\n user.ctx = \"~\" + data.pub\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 const auth = {auth: JSON.stringify({enc: enc, salt: salt})}\n const signed = await SEA.sign(auth, user.is)\n const graph = utils.graph(pub, signed.m, signed.s, data.pub)\n wire.put(graph, err => {\n if (err) {\n done(`error putting ${auth} on ${pub}: ${err}`)\n } else {\n done(null)\n }\n })\n return\n }\n\n return done(null)\n })\n }\n\n if (retries > 9) {\n done(\"Wrong username or password\")\n return\n }\n\n const soul = \"~@\" + username\n wire.get({\"#\": soul}, 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 }\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({\"#\": soul}, 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 const signed = await SEA.sign(data, pair)\n const graph = utils.graph(pub, signed.m, signed.s, pair.pub)\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 },\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 return\n }\n\n if (typeof globalThis.sessionStorage !== \"undefined\") {\n globalThis.sessionStorage.setItem(\"user.is\", JSON.stringify(user.is))\n }\n },\n recall: localStorage => {\n if (localStorage) {\n if (typeof globalThis.localStorage !== \"undefined\") {\n const is = globalThis.localStorage.getItem(\"user.is\")\n if (is) {\n user.is = JSON.parse(is)\n user.ctx = \"~\" + user.is.pub\n } else {\n console.log(\"User credentials not stored in local storage\")\n }\n }\n return\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 user.ctx = \"~\" + user.is.pub\n } else {\n console.log(\"User credentials not stored in session storage\")\n }\n }\n },\n leave: () => {\n user.is = null\n user.ctx = 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 const signed = await SEA.sign(data, user.is)\n const pub = \"~\" + user.is.pub\n const graph = utils.graph(pub, signed.m, signed.s, user.is.pub)\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 user.ctx = 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(null, 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 // Allow user queries by public key\n let publicKey\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 an item name\"\n }\n if (utils.obj.is(value) || ok(value)) {\n keys.push(key)\n continue\n }\n return `error {${key}:${value}} cannot be converted to graph`\n }\n if (keys.length !== 0) return keys\n }\n return `error ${data} 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 // 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 const data = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: null, soul: id}]})\n api(_ctxid).next(null, res)\n })\n msg.put[soul][key] = data\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, cb) => {\n if (!cb) cb = console.log\n\n if (user.is) {\n const signed = await SEA.sign(data, user.is)\n return utils.graph(soul, signed.m, signed.s, user.is.pub)\n }\n\n if (opt.secure) {\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 const done = data => {\n const ctx = allctx.get(ctxid)\n if (ctx && typeof ctx.cb !== \"undefined\") ctx.cb(data)\n else if (data) console.log(data)\n // A context updated by \"on\" should only be removed by \"off\".\n if (ctx && !ctx.on) allctx.delete(ctxid)\n }\n\n const resolve = (request, cb) => {\n const get = request && typeof request.get !== \"undefined\"\n const put = request && typeof request.put !== \"undefined\"\n const on = request && typeof request.on !== \"undefined\"\n const off = request && 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({\"#\": soul, \".\": item}, 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 const 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 // Not sure why the map needs to be set rather than just ctx?\n allctx.set(ctxid, {chain: ctx.chain, cb: ctx.cb})\n // Call api again using the updated context.\n if (get) api(ctxid).next(null, request.get, cb)\n else if (put) api(ctxid).put(request.put, cb)\n else if (on) api(ctxid).on(request.on, cb)\n else if (off) api(ctxid).off(cb)\n } else if (get) {\n // Request was not for a node, return a property on the current\n // 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 const rel = {[item]: utils.rel.ify(id)}\n const g = await graph(soul, rel, 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 console.log(`error resolving on for ${item} on ${soul}`)\n cb(null)\n } else if (off) {\n console.log(`error resolving off for ${item} on ${soul}`)\n if (cb) cb(null)\n }\n } else if (put) {\n cb(`error ${item} not found on ${soul}`)\n } else {\n console.log(`error ${item} not found on ${soul}`)\n if (cb) cb(null)\n }\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)\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 cb = lex\n lex = null\n }\n if (key === null || key === \"\" || 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 // Top level keys are added to a root node so their values don't need\n // to be objects, the user's public key is used as the root node when\n // publicKey or user.ctx is set.\n const root = publicKey ? publicKey : user.ctx ? user.ctx : \"root\"\n\n ctxid = utils.text.random()\n allctx.set(ctxid, {chain: [{item: key, soul: root}], cb: cb})\n if (!cb) return api(ctxid)\n\n // When there's a callback need to resolve the context first.\n const {soul} = resolve({get: lex}, done)\n if (soul) get(lex, soul, done, opt)\n },\n next: (key, lex, cb, opt) => {\n const ack = data => {\n cb ? cb(data) : done(data)\n }\n\n if (typeof lex === \"function\") {\n cb = lex\n lex = null\n }\n if (!ctxid) {\n console.log(\"error please provide a key using get(key)\")\n ack(null)\n return\n }\n\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 && !cb) {\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: 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}, 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 = err => {\n cb ? cb(err) : done(err)\n }\n\n if (!ctxid) {\n ack(\"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 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.\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({\"#\": soul, \".\": item}, async msg => {\n if (msg.err) {\n console.log(`error getting ${soul}: ${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 // Not a rel, can just put the data.\n const g = await graph(soul, {[item]: data}, 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 console.log(`error getting ${id}: ${msg.err}`)\n return\n }\n\n if (!msg.put || !msg.put[id]) {\n console.log(`error ${id} not found`)\n return\n }\n\n delete msg.put[id]._\n // null each of the properties on the node before putting data.\n for (const key of Object.keys(msg.put[id])) {\n if (key === utils.userPublicKey) continue\n\n const err = await new Promise(res => {\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: key, soul: id}]})\n api(_ctxid).put(null, res)\n })\n if (err) {\n ack(err)\n return\n }\n }\n const g = await graph(soul, {[item]: data}, ack)\n if (g === null) return\n\n wire.put(g, ack)\n })\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 wire.get({\"#\": soul, \".\": item}, async msg => {\n if (msg.err) {\n ack(`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 // The current rel doesn't exist, so add it first.\n const rel = {[item]: utils.rel.ify(utils.text.random())}\n const g = await graph(soul, rel, 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 the previous context's callback on here.\n allctx.set(_ctxid, {chain: chain, cb: ctx.cb})\n api(_ctxid).put(data)\n }\n })\n return\n }\n\n let put = false\n const update = {}\n for (const key of result) {\n const err = await new Promise(res => {\n if (utils.obj.is(data[key])) {\n // Use the current rel as the context for nested objects.\n const _ctxid = utils.text.random()\n allctx.set(_ctxid, {chain: [{item: key, soul: id}]})\n api(_ctxid).put(data[key], res)\n } else {\n put = true\n // Group other properties into one update.\n update[key] = data[key]\n res(null)\n }\n })\n if (err) {\n ack(err)\n return\n }\n }\n if (put) {\n const g = await graph(id, update, ack)\n if (g === null) return\n\n wire.put(g, ack)\n } else {\n // Callback on behalf of nested objects.\n ack(null)\n }\n })\n },\n on: (lex, cb) => {\n if (typeof lex === \"function\") {\n cb = lex\n lex = null\n }\n if (!cb) return\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}, cb)\n if (!soul) return\n\n // Flag that this context is set from on and shouldn't be removed.\n allctx.set(ctxid, {chain: [{item: item, soul: soul}], on: true})\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 map.set(cb, () => api(ctxid).next(null, cb))\n // Check if item is a rel and add event listener for the node.\n wire.get({\"#\": soul, \".\": item}, 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 if (lex) lex = utils.obj.put(lex, \"#\", id)\n else lex = {\"#\": id, \".\": null}\n } else {\n if (lex) lex = utils.obj.put(lex, \"#\", soul)\n else lex = {\"#\": soul, \".\": item}\n }\n wire.on(lex, map.get(cb))\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 // Check if item is a rel and remove event listener for the node.\n wire.get({\"#\": soul, \".\": item}, 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) wire.off({\"#\": id}, map.get(cb))\n else wire.off({\"#\": soul}, map.get(cb))\n map.delete(cb)\n allctx.delete(ctxid)\n })\n },\n user: pub => {\n // Return the combined Holster and User APIs. Passing in a public key\n // will set the user context to that key, otherwise user.ctx is set when\n // a user logs in so that their public key will be used as the root node\n // in get(), also put() will sign all graph updates for verification.\n if (pub) publicKey = \"~\" + pub\n else publicKey = null\n return Object.assign(user, api())\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", "obj", "o", "list", "cb", "keys", "i", "result", "key", "value", "map_soul", "soul", "rel", "userPublicKey", "graph", "data", "sig", "pub", "g", "match", "lex", "prefix", "gt", "lt", "text", "length", "s", "c", "Dup", "maxAge", "dup", "id", "now", "dup_default", "Get", "lex", "graph", "soul", "key", "node", "value", "get_default", "data", "SeaArray", "enc", "start", "end", "length", "buf", "i", "_", "array_default", "SafeBuffer", "props", "input", "buf", "enc", "bytes", "byte", "array_default", "length", "words", "_", "i", "dec", "fill", "arr", "ret", "item", "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", "hash", "sha256", "sig", "alg", "verified", "salt", "work", "to", "from", "pubKey", "priv", "derived", "derivedBits", "derivedKey", "sea_default", "Ham", "state", "currentState", "value", "currentValue", "change", "graph", "secure", "listen", "machine", "now", "defer", "wait", "soul", "node", "updated", "alias", "nodeWait", "pub", "verify", "sea_default", "key", "rel", "skew", "l", "match", "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", "radisk", "key", "value", "cb", "radix_default", "batch", "i", "err", "rad", "save", "tree", "file", "start", "end", "disk", "write", "k", "pre", "enc", "name", "soul", "read", "parse", "data", "tmp", "a", "c", "o", "state", "current", "text", "rel", "num", "obj", "previous", "radisk_default", "isNode", "fs", "enq", "unit", "root", "fileSystem", "opt", "dir", "file", "cb", "err", "data", "random", "tmp", "files", "db", "o", "event", "req", "Store", "obj", "radisk", "radisk_default", "lex", "soul", "key", "node", "each", "value", "match", "graph", "radix_default", "count", "ack", "state", "store_default", "isNode", "wsModule", "Wire", "opt", "dup", "dup_default", "store", "store_default", "graph", "queue", "listen", "check", "data", "send", "cb", "soul", "msg", "res", "getWithCallback", "node", "pub", "key", "userPublicKey", "get", "ack", "get_default", "text", "err", "put", "update", "ham_default", "lex", "obj", "track", "id", "api", "found", "l", "wss", "clients", "config", "isBinary", "client", "ws", "peers", "peer", "start", "c", "e", "m", "wire_default", "User", "opt", "wire", "wire_default", "pubs", "creating", "authing", "retries", "auth", "username", "password", "newPassword", "ack", "retry", "done", "err", "next", "pub", "msg", "data", "work", "sea_default", "dec", "user", "salt", "text", "enc", "signed", "graph", "soul", "cb", "pair", "priv", "rel", "localStorage", "is", "user_default", "Holster", "opt", "obj", "wire", "wire_default", "user", "user_default", "map", "allctx", "publicKey", "ok", "data", "rel", "num", "check", "keys", "key", "value", "api", "ctxid", "get", "lex", "soul", "ack", "msg", "userPublicKey", "id", "res", "_ctxid", "text", "graph", "cb", "signed", "sea_default", "done", "ctx", "resolve", "request", "put", "on", "off", "found", "i", "item", "node", "g", "err", "root", "set", "result", "current", "chain", "update", "pub", "holster_default"]
|
|
7
7
|
}
|