From c5bfcb8bd905038e8dfaadb5a63a264b916c5526 Mon Sep 17 00:00:00 2001 From: haad <haad@headbanggames.com> Date: Thu, 2 Feb 2023 14:07:14 +0200 Subject: [PATCH] WIP 3 --- benchmarks/append.js | 5 +- dist/ipfslog.min.js | 2 +- src/database.js | 25 ++++++--- src/events.js | 10 +++- src/feed.js | 10 +++- src/ipfs-block-storage.js | 10 +++- src/kv-persisted.js | 6 +- src/kv.js | 3 + src/level-storage.js | 36 ++++++------ src/log.js | 15 ++++- src/lru-storage.js | 8 +++ src/memory-storage.js | 8 +++ test/events.spec.js | 108 +++++++++++++----------------------- test/feed.spec.js | 92 +++++++++++------------------- test/kv.spec.js | 99 ++++++++++++--------------------- test/log-references.spec.js | 26 ++++++--- test/utils/wait-for.js | 12 ++++ 17 files changed, 236 insertions(+), 239 deletions(-) create mode 100644 test/utils/wait-for.js diff --git a/benchmarks/append.js b/benchmarks/append.js index 76a2195..40f2257 100644 --- a/benchmarks/append.js +++ b/benchmarks/append.js @@ -22,9 +22,12 @@ const queryLoop = async () => { console.log('Starting benchmark...') const identity = await IdentityProvider.createIdentity({ id: 'userA' }) + // MemoeryStorage is the default storage for Log but defining them here + // in case we want to benchmark different storage modules const storage = await MemoryStorage() + const stateStorage = await MemoryStorage() - log = await Log(identity, { logId: 'A', storage }) + log = await Log(identity, { logId: 'A', storage, stateStorage }) // Output metrics at 1 second interval setInterval(() => { diff --git a/dist/ipfslog.min.js b/dist/ipfslog.min.js index 78914965..2dae067 100644 --- a/dist/ipfslog.min.js +++ b/dist/ipfslog.min.js @@ -1 +1 @@ -var Log;(()=>{var e={187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,r=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise((function(n,r){function o(n){e.removeListener(t,i),r(n)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",o),n([].slice.call(arguments))}y(e,t,i,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&y(e,"error",t,{once:!0})}(e,o)}))},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var s=10;function a(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function c(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function u(e,t,n,r){var o,i,s,u;if(a(n),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),i=e._events),s=i[t]),void 0===s)s=i[t]=n,++e._eventsCount;else if("function"==typeof s?s=i[t]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),(o=c(e))>0&&s.length>o&&!s.warned){s.warned=!0;var f=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");f.name="MaxListenersExceededWarning",f.emitter=e,f.type=t,f.count=s.length,u=f,console&&console.warn&&console.warn(u)}return e}function f(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function h(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=f.bind(r);return o.listener=n,r.wrapFn=o,o}function l(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(o):p(o,o.length)}function d(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function p(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}function y(e,t,n,r){if("function"==typeof e.on)r.once?e.once(t,n):e.on(t,n);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,(function o(i){r.once&&e.removeEventListener(t,o),n(i)}))}}Object.defineProperty(i,"defaultMaxListeners",{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");s=e}}),i.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},i.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},i.prototype.getMaxListeners=function(){return c(this)},i.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var o="error"===e,i=this._events;if(void 0!==i)o=o&&void 0===i.error;else if(!o)return!1;if(o){var s;if(t.length>0&&(s=t[0]),s instanceof Error)throw s;var a=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw a.context=s,a}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)r(c,this,t);else{var u=c.length,f=p(c,u);for(n=0;n<u;++n)r(f[n],this,t)}return!0},i.prototype.addListener=function(e,t){return u(this,e,t,!1)},i.prototype.on=i.prototype.addListener,i.prototype.prependListener=function(e,t){return u(this,e,t,!0)},i.prototype.once=function(e,t){return a(t),this.on(e,h(this,e,t)),this},i.prototype.prependOnceListener=function(e,t){return a(t),this.prependListener(e,h(this,e,t)),this},i.prototype.removeListener=function(e,t){var n,r,o,i,s;if(a(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(o=-1,i=n.length-1;i>=0;i--)if(n[i]===t||n[i].listener===t){s=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,o),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,s||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var o,i=Object.keys(n);for(r=0;r<i.length;++r)"removeListener"!==(o=i[r])&&this.removeAllListeners(o);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},i.prototype.listeners=function(e){return l(this,e,!0)},i.prototype.rawListeners=function(e){return l(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):d.call(e,t)},i.prototype.listenerCount=d,i.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},717:e=>{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){if(t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}}},117:(e,t,n)=>{var r=n(187),o=n(717);function i(e){if(!(this instanceof i))return new i(e);"number"==typeof e&&(e={max:e}),e||(e={}),r.EventEmitter.call(this),this.cache={},this.head=this.tail=null,this.length=0,this.max=e.max||1e3,this.maxAge=e.maxAge||0}e.exports=i,o(i,r.EventEmitter),Object.defineProperty(i.prototype,"keys",{get:function(){return Object.keys(this.cache)}}),i.prototype.clear=function(){this.cache={},this.head=this.tail=null,this.length=0},i.prototype.remove=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];return delete this.cache[e],this._unlink(e,t.prev,t.next),t.value}},i.prototype._unlink=function(e,t,n){this.length--,0===this.length?this.head=this.tail=null:this.head===e?(this.head=t,this.cache[this.head].next=null):this.tail===e?(this.tail=n,this.cache[this.tail].prev=null):(this.cache[t].next=n,this.cache[n].prev=t)},i.prototype.peek=function(e){if(this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return t.value}},i.prototype.set=function(e,t){var n;if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){if((n=this.cache[e]).value=t,this.maxAge&&(n.modified=Date.now()),e===this.head)return t;this._unlink(e,n.prev,n.next)}else n={value:t,modified:0,next:null,prev:null},this.maxAge&&(n.modified=Date.now()),this.cache[e]=n,this.length===this.max&&this.evict();return this.length++,n.next=null,n.prev=this.head,this.head&&(this.cache[this.head].next=e),this.head=e,this.tail||(this.tail=e),t},i.prototype._checkAge=function(e,t){return!(this.maxAge&&Date.now()-t.modified>this.maxAge&&(this.remove(e),this.emit("evict",{key:e,value:t.value}),1))},i.prototype.get=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return this.head!==e&&(e===this.tail?(this.tail=t.next,this.cache[this.tail].prev=null):this.cache[t.prev].next=t.next,this.cache[t.next].prev=t.prev,this.cache[this.head].next=e,t.prev=this.head,t.next=null,this.head=e),t.value}},i.prototype.evict=function(){if(this.tail){var e=this.tail,t=this.remove(this.tail);this.emit("evict",{key:e,value:t})}}}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{ComposedStorage:()=>qt,DefaultAccessController:()=>Jt,Entry:()=>Mt,IPFSBlockStorage:()=>Pt,LRUStorage:()=>Vt,Log:()=>Qt,MemoryStorage:()=>Rt,Sorting:()=>zt});var e={};n.r(e),n.d(e,{code:()=>jt,decode:()=>It,encode:()=>St,name:()=>Ct});var t=n(117);class o{constructor(e,t){this.id=e,this.time=t||0}tick(){return new o(this.id,++this.time)}merge(e){return this.time=Math.max(this.time,e.time),new o(this.id,this.time)}clone(){return new o(this.id,this.time)}static compare(e,t){const n=e.time-t.time;return 0===n&&e.id!==t.id?e.id<t.id?-1:1:n}}const i=o,s=e=>null!=e;var a=Math.pow(2,31),c=Math.pow(2,7),u=Math.pow(2,14),f=Math.pow(2,21),h=Math.pow(2,28),l=Math.pow(2,35),d=Math.pow(2,42),p=Math.pow(2,49),y=Math.pow(2,56),w=Math.pow(2,63);const g={encode:function e(t,n,r){n=n||[];for(var o=r=r||0;t>=a;)n[r++]=255&t|128,t/=128;for(;-128&t;)n[r++]=255&t|128,t>>>=7;return n[r]=0|t,e.bytes=r-o+1,n},decode:function e(t,n){var r,o=0,i=0,s=n=n||0,a=t.length;do{if(s>=a)throw e.bytes=0,new RangeError("Could not decode varint");r=t[s++],o+=i<28?(127&r)<<i:(127&r)*Math.pow(2,i),i+=7}while(r>=128);return e.bytes=s-n,o},encodingLength:function(e){return e<c?1:e<u?2:e<f?3:e<h?4:e<l?5:e<d?6:e<p?7:e<y?8:e<w?9:10}},b=(e,t=0)=>[g.decode(e,t),g.decode.bytes],v=(e,t,n=0)=>(g.encode(e,t,n),t),m=e=>g.encodingLength(e),E=(new Uint8Array(0),e=>{if(e instanceof Uint8Array&&"Uint8Array"===e.constructor.name)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Unknown type, must be binary type")}),k=(e,t)=>{const n=t.byteLength,r=m(e),o=r+m(n),i=new Uint8Array(o+n);return v(e,i,0),v(n,i,r),i.set(t,o),new x(e,n,t,i)};class x{constructor(e,t,n,r){this.code=e,this.size=t,this.digest=n,this.bytes=r}}const A=function(e,t){if(e.length>=255)throw new TypeError("Alphabet too long");for(var n=new Uint8Array(256),r=0;r<n.length;r++)n[r]=255;for(var o=0;o<e.length;o++){var i=e.charAt(o),s=i.charCodeAt(0);if(255!==n[s])throw new TypeError(i+" is ambiguous");n[s]=o}var a=e.length,c=e.charAt(0),u=Math.log(a)/Math.log(256),f=Math.log(256)/Math.log(a);function h(e){if("string"!=typeof e)throw new TypeError("Expected String");if(0===e.length)return new Uint8Array;var t=0;if(" "!==e[t]){for(var r=0,o=0;e[t]===c;)r++,t++;for(var i=(e.length-t)*u+1>>>0,s=new Uint8Array(i);e[t];){var f=n[e.charCodeAt(t)];if(255===f)return;for(var h=0,l=i-1;(0!==f||h<o)&&-1!==l;l--,h++)f+=a*s[l]>>>0,s[l]=f%256>>>0,f=f/256>>>0;if(0!==f)throw new Error("Non-zero carry");o=h,t++}if(" "!==e[t]){for(var d=i-o;d!==i&&0===s[d];)d++;for(var p=new Uint8Array(r+(i-d)),y=r;d!==i;)p[y++]=s[d++];return p}}}return{encode:function(t){if(t instanceof Uint8Array||(ArrayBuffer.isView(t)?t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength):Array.isArray(t)&&(t=Uint8Array.from(t))),!(t instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(0===t.length)return"";for(var n=0,r=0,o=0,i=t.length;o!==i&&0===t[o];)o++,n++;for(var s=(i-o)*f+1>>>0,u=new Uint8Array(s);o!==i;){for(var h=t[o],l=0,d=s-1;(0!==h||l<r)&&-1!==d;d--,l++)h+=256*u[d]>>>0,u[d]=h%a>>>0,h=h/a>>>0;if(0!==h)throw new Error("Non-zero carry");r=l,o++}for(var p=s-r;p!==s&&0===u[p];)p++;for(var y=c.repeat(n);p<s;++p)y+=e.charAt(u[p]);return y},decodeUnsafe:h,decode:function(e){var n=h(e);if(n)return n;throw new Error(`Non-${t} character`)}}};class C{constructor(e,t,n){this.name=e,this.prefix=t,this.baseEncode=n}encode(e){if(e instanceof Uint8Array)return`${this.prefix}${this.baseEncode(e)}`;throw Error("Unknown type, must be binary type")}}class j{constructor(e,t,n){if(this.name=e,this.prefix=t,void 0===t.codePointAt(0))throw new Error("Invalid prefix character");this.prefixCodePoint=t.codePointAt(0),this.baseDecode=n}decode(e){if("string"==typeof e){if(e.codePointAt(0)!==this.prefixCodePoint)throw Error(`Unable to decode multibase string ${JSON.stringify(e)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);return this.baseDecode(e.slice(this.prefix.length))}throw Error("Can only multibase decode strings")}or(e){return I(this,e)}}class S{constructor(e){this.decoders=e}or(e){return I(this,e)}decode(e){const t=e[0],n=this.decoders[t];if(n)return n.decode(e);throw RangeError(`Unable to decode multibase string ${JSON.stringify(e)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)}}const I=(e,t)=>new S({...e.decoders||{[e.prefix]:e},...t.decoders||{[t.prefix]:t}});class U{constructor(e,t,n,r){this.name=e,this.prefix=t,this.baseEncode=n,this.baseDecode=r,this.encoder=new C(e,t,n),this.decoder=new j(e,t,r)}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}}const $=({name:e,prefix:t,encode:n,decode:r})=>new U(e,t,n,r),L=({prefix:e,name:t,alphabet:n})=>{const{encode:r,decode:o}=A(n,t);return $({prefix:e,name:t,encode:r,decode:e=>E(o(e))})},B=({name:e,prefix:t,bitsPerChar:n,alphabet:r})=>$({prefix:t,name:e,encode:e=>((e,t,n)=>{const r="="===t[t.length-1],o=(1<<n)-1;let i="",s=0,a=0;for(let r=0;r<e.length;++r)for(a=a<<8|e[r],s+=8;s>n;)s-=n,i+=t[o&a>>s];if(s&&(i+=t[o&a<<n-s]),r)for(;i.length*n&7;)i+="=";return i})(e,r,n),decode:t=>((e,t,n,r)=>{const o={};for(let e=0;e<t.length;++e)o[t[e]]=e;let i=e.length;for(;"="===e[i-1];)--i;const s=new Uint8Array(i*n/8|0);let a=0,c=0,u=0;for(let t=0;t<i;++t){const i=o[e[t]];if(void 0===i)throw new SyntaxError(`Non-${r} character`);c=c<<n|i,a+=n,a>=8&&(a-=8,s[u++]=255&c>>a)}if(a>=n||255&c<<8-a)throw new SyntaxError("Unexpected end of data");return s})(t,r,n,e)}),N=L({name:"base58btc",prefix:"z",alphabet:"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"}),O=(L({name:"base58flickr",prefix:"Z",alphabet:"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"}),B({prefix:"b",name:"base32",alphabet:"abcdefghijklmnopqrstuvwxyz234567",bitsPerChar:5})),T=(B({prefix:"B",name:"base32upper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",bitsPerChar:5}),B({prefix:"c",name:"base32pad",alphabet:"abcdefghijklmnopqrstuvwxyz234567=",bitsPerChar:5}),B({prefix:"C",name:"base32padupper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",bitsPerChar:5}),B({prefix:"v",name:"base32hex",alphabet:"0123456789abcdefghijklmnopqrstuv",bitsPerChar:5}),B({prefix:"V",name:"base32hexupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV",bitsPerChar:5}),B({prefix:"t",name:"base32hexpad",alphabet:"0123456789abcdefghijklmnopqrstuv=",bitsPerChar:5}),B({prefix:"T",name:"base32hexpadupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV=",bitsPerChar:5}),B({prefix:"h",name:"base32z",alphabet:"ybndrfg8ejkmcpqxot1uwisza345h769",bitsPerChar:5}),(e,t)=>{const{bytes:n,version:r}=e;return 0===r?P(n,D(e),t||N.encoder):R(n,D(e),t||O.encoder)}),M=new WeakMap,D=e=>{const t=M.get(e);if(null==t){const t=new Map;return M.set(e,t),t}return t};class _{constructor(e,t,n,r){this.code=t,this.version=e,this.multihash=n,this.bytes=r,this["/"]=r}get asCID(){return this}get byteOffset(){return this.bytes.byteOffset}get byteLength(){return this.bytes.byteLength}toV0(){switch(this.version){case 0:return this;case 1:{const{code:e,multihash:t}=this;if(e!==F)throw new Error("Cannot convert a non dag-pb CID to CIDv0");if(t.code!==V)throw new Error("Cannot convert non sha2-256 multihash CID to CIDv0");return _.createV0(t)}default:throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`)}}toV1(){switch(this.version){case 0:{const{code:e,digest:t}=this.multihash,n=k(e,t);return _.createV1(this.code,n)}case 1:return this;default:throw Error(`Can not convert CID version ${this.version} to version 1. This is a bug please report`)}}equals(e){return _.equals(this,e)}static equals(e,t){const n=t;return n&&e.code===n.code&&e.version===n.version&&((e,t)=>{if(e===t)return!0;{const n=t;return e.code===n.code&&e.size===n.size&&n.bytes instanceof Uint8Array&&((e,t)=>{if(e===t)return!0;if(e.byteLength!==t.byteLength)return!1;for(let n=0;n<e.byteLength;n++)if(e[n]!==t[n])return!1;return!0})(e.bytes,n.bytes)}})(e.multihash,n.multihash)}toString(e){return T(this,e)}toJSON(){return{"/":T(this)}}link(){return this}get[Symbol.toStringTag](){return"CID"}[Symbol.for("nodejs.util.inspect.custom")](){return`CID(${this.toString()})`}static asCID(e){if(null==e)return null;const t=e;if(t instanceof _)return t;if(null!=t["/"]&&t["/"]===t.bytes||t.asCID===t){const{version:e,code:n,multihash:r,bytes:o}=t;return new _(e,n,r,o||q(e,n,r.bytes))}if(!0===t[K]){const{version:e,multihash:n,code:r}=t,o=(e=>{const t=E(e),[n,r]=b(t),[o,i]=b(t.subarray(r)),s=t.subarray(r+i);if(s.byteLength!==o)throw new Error("Incorrect length");return new x(n,o,s,t)})(n);return _.create(e,r,o)}return null}static create(e,t,n){if("number"!=typeof t)throw new Error("String codecs are no longer supported");if(!(n.bytes instanceof Uint8Array))throw new Error("Invalid digest");switch(e){case 0:if(t!==F)throw new Error(`Version 0 CID must use dag-pb (code: ${F}) block encoding`);return new _(e,t,n,n.bytes);case 1:{const r=q(e,t,n.bytes);return new _(e,t,n,r)}default:throw new Error("Invalid version")}}static createV0(e){return _.create(0,F,e)}static createV1(e,t){return _.create(1,e,t)}static decode(e){const[t,n]=_.decodeFirst(e);if(n.length)throw new Error("Incorrect length");return t}static decodeFirst(e){const t=_.inspectBytes(e),n=t.size-t.multihashSize,r=E(e.subarray(n,n+t.multihashSize));if(r.byteLength!==t.multihashSize)throw new Error("Incorrect length");const o=r.subarray(t.multihashSize-t.digestSize),i=new x(t.multihashCode,t.digestSize,o,r);return[0===t.version?_.createV0(i):_.createV1(t.codec,i),e.subarray(t.size)]}static inspectBytes(e){let t=0;const n=()=>{const[n,r]=b(e.subarray(t));return t+=r,n};let r=n(),o=F;if(18===r?(r=0,t=0):o=n(),0!==r&&1!==r)throw new RangeError(`Invalid CID version ${r}`);const i=t,s=n(),a=n(),c=t+a;return{version:r,codec:o,multihashCode:s,digestSize:a,multihashSize:c-i,size:c}}static parse(e,t){const[n,r]=z(e,t),o=_.decode(r);if(0===o.version&&"Q"!==e[0])throw Error("Version 0 CID string must not include multibase prefix");return D(o).set(n,e),o}}const z=(e,t)=>{switch(e[0]){case"Q":{const n=t||N;return[N.prefix,n.decode(`${N.prefix}${e}`)]}case N.prefix:{const n=t||N;return[N.prefix,n.decode(e)]}case O.prefix:{const n=t||O;return[O.prefix,n.decode(e)]}default:if(null==t)throw Error("To parse non base32 or base58btc encoded CID multibase decoder must be provided");return[e[0],t.decode(e)]}},P=(e,t,n)=>{const{prefix:r}=n;if(r!==N.prefix)throw Error(`Cannot string encode V0 in ${n.name} encoding`);const o=t.get(r);if(null==o){const o=n.encode(e).slice(1);return t.set(r,o),o}return o},R=(e,t,n)=>{const{prefix:r}=n,o=t.get(r);if(null==o){const o=n.encode(e);return t.set(r,o),o}return o},F=112,V=18,q=(e,t,n)=>{const r=m(e),o=r+m(t),i=new Uint8Array(o+n.byteLength);return v(e,i,0),v(t,i,r),i.set(n,o),i},K=Symbol.for("@ipld/js-cid/CID"),G=({name:e,code:t,encode:n})=>new W(e,t,n);class W{constructor(e,t,n){this.name=e,this.code=t,this.encode=n}digest(e){if(e instanceof Uint8Array){const t=this.encode(e);return t instanceof Uint8Array?k(this.code,t):t.then((e=>k(this.code,e)))}throw Error("Unknown type, must be binary type")}}function H({enumerable:e=!0,configurable:t=!1}={}){return{enumerable:e,configurable:t,writable:!1}}function*J(e,t){if(null!=t&&"object"==typeof t)if(Array.isArray(t))for(const[n,r]of t.entries()){const t=[...e,n],o=_.asCID(r);o?yield[t.join("/"),o]:"object"==typeof r&&(yield*Q(r,t))}else{const n=_.asCID(t);n?yield[e.join("/"),n]:yield*Q(t,e)}}function*Q(e,t){if(null==e||e instanceof Uint8Array)return;const n=_.asCID(e);n&&(yield[t.join("/"),n]);for(const[n,r]of Object.entries(e)){const e=[...t,n];yield*J(e,r)}}function*Z(e,t){if(Array.isArray(t))for(const[n,r]of t.entries()){const t=[...e,n];yield t.join("/"),"object"!=typeof r||_.asCID(r)||(yield*X(r,t))}else yield*X(t,e)}function*X(e,t){if(null!=e&&"object"==typeof e)for(const[n,r]of Object.entries(e)){const e=[...t,n];yield e.join("/"),null==r||r instanceof Uint8Array||"object"!=typeof r||_.asCID(r)||(yield*Z(e,r))}}class Y{constructor({cid:e,bytes:t,value:n}){if(!e||!t||void 0===n)throw new Error("Missing required argument");this.cid=e,this.bytes=t,this.value=n,this.asBlock=this,Object.defineProperties(this,{cid:H(),bytes:H(),value:H(),asBlock:H()})}links(){return Q(this.value,[])}tree(){return X(this.value,[])}get(e="/"){return function(e,t){let n=e;for(const[e,r]of t.entries()){if(n=n[r],null==n)throw new Error(`Object has no property at ${t.slice(0,e+1).map((e=>`[${JSON.stringify(e)}]`)).join("")}`);const o=_.asCID(n);if(o)return{value:o,remaining:t.slice(e+1).join("/")}}return{value:n}}(this.value,e.split("/").filter(Boolean))}}async function ee({value:e,codec:t,hasher:n}){if(void 0===e)throw new Error('Missing required argument "value"');if(!t||!n)throw new Error("Missing required argument: codec or hasher");const r=t.encode(e),o=await n.digest(r),i=_.create(1,t.code,o);return new Y({value:e,bytes:r,cid:i})}const te=["string","number","bigint","symbol"],ne=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","HTMLElement","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];class re{constructor(e,t,n){this.major=e,this.majorEncoded=e<<5,this.name=t,this.terminal=n}toString(){return`Type[${this.major}].${this.name}`}compare(e){return this.major<e.major?-1:this.major>e.major?1:0}}re.uint=new re(0,"uint",!0),re.negint=new re(1,"negint",!0),re.bytes=new re(2,"bytes",!0),re.string=new re(3,"string",!0),re.array=new re(4,"array",!1),re.map=new re(5,"map",!1),re.tag=new re(6,"tag",!1),re.float=new re(7,"float",!0),re.false=new re(7,"false",!0),re.true=new re(7,"true",!0),re.null=new re(7,"null",!0),re.undefined=new re(7,"undefined",!0),re.break=new re(7,"break",!0);class oe{constructor(e,t,n){this.type=e,this.value=t,this.encodedLength=n,this.encodedBytes=void 0,this.byteValue=void 0}toString(){return`Token[${this.type}].${this.value}`}}const ie=globalThis.process&&!globalThis.process.browser&&globalThis.Buffer&&"function"==typeof globalThis.Buffer.isBuffer,se=new TextDecoder,ae=new TextEncoder;function ce(e){return ie&&globalThis.Buffer.isBuffer(e)}function ue(e){return e instanceof Uint8Array?ce(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):e:Uint8Array.from(e)}const fe=ie?(e,t,n)=>n-t>64?globalThis.Buffer.from(e.subarray(t,n)).toString("utf8"):ge(e,t,n):(e,t,n)=>n-t>64?se.decode(e.subarray(t,n)):ge(e,t,n),he=ie?e=>e.length>64?globalThis.Buffer.from(e):we(e):e=>e.length>64?ae.encode(e):we(e),le=e=>Uint8Array.from(e),de=ie?(e,t,n)=>ce(e)?new Uint8Array(e.subarray(t,n)):e.slice(t,n):(e,t,n)=>e.slice(t,n),pe=ie?(e,t)=>(e=e.map((e=>e instanceof Uint8Array?e:globalThis.Buffer.from(e))),ue(globalThis.Buffer.concat(e,t))):(e,t)=>{const n=new Uint8Array(t);let r=0;for(let t of e)r+t.length>n.length&&(t=t.subarray(0,n.length-r)),n.set(t,r),r+=t.length;return n},ye=ie?e=>globalThis.Buffer.allocUnsafe(e):e=>new Uint8Array(e);function we(e,t=1/0){let n;const r=e.length;let o=null;const i=[];for(let s=0;s<r;++s){if(n=e.charCodeAt(s),n>55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function ge(e,t,n){const r=[];for(;t<n;){const o=e[t];let i=null,s=o>239?4:o>223?3:o>191?2:1;if(t+s<=n){let n,r,a,c;switch(s){case 1:o<128&&(i=o);break;case 2:n=e[t+1],128==(192&n)&&(c=(31&o)<<6|63&n,c>127&&(i=c));break;case 3:n=e[t+1],r=e[t+2],128==(192&n)&&128==(192&r)&&(c=(15&o)<<12|(63&n)<<6|63&r,c>2047&&(c<55296||c>57343)&&(i=c));break;case 4:n=e[t+1],r=e[t+2],a=e[t+3],128==(192&n)&&128==(192&r)&&128==(192&a)&&(c=(15&o)<<18|(63&n)<<12|(63&r)<<6|63&a,c>65535&&c<1114112&&(i=c))}}null===i?(i=65533,s=1):i>65535&&(i-=65536,r.push(i>>>10&1023|55296),i=56320|1023&i),r.push(i),t+=s}return function(e){const t=e.length;if(t<=be)return String.fromCharCode.apply(String,e);let n="",r=0;for(;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=be));return n}(r)}const be=4096;class ve{constructor(e=256){this.chunkSize=e,this.cursor=0,this.maxCursor=-1,this.chunks=[],this._initReuseChunk=null}reset(){this.cursor=0,this.maxCursor=-1,this.chunks.length&&(this.chunks=[]),null!==this._initReuseChunk&&(this.chunks.push(this._initReuseChunk),this.maxCursor=this._initReuseChunk.length-1)}push(e){let t=this.chunks[this.chunks.length-1];if(this.cursor+e.length<=this.maxCursor+1){const n=t.length-(this.maxCursor-this.cursor)-1;t.set(e,n)}else{if(t){const e=t.length-(this.maxCursor-this.cursor)-1;e<t.length&&(this.chunks[this.chunks.length-1]=t.subarray(0,e),this.maxCursor=this.cursor-1)}e.length<64&&e.length<this.chunkSize?(t=ye(this.chunkSize),this.chunks.push(t),this.maxCursor+=t.length,null===this._initReuseChunk&&(this._initReuseChunk=t),t.set(e,0)):(this.chunks.push(e),this.maxCursor+=e.length)}this.cursor+=e.length}toBytes(e=!1){let t;if(1===this.chunks.length){const n=this.chunks[0];e&&this.cursor>n.length/2?(t=this.cursor===n.length?n:n.subarray(0,this.cursor),this._initReuseChunk=null,this.chunks=[]):t=de(n,0,this.cursor)}else t=pe(this.chunks,this.cursor);return e&&this.reset(),t}}const me="CBOR decode error:",Ee="CBOR encode error:",ke=[];function xe(e,t,n){if(e.length-t<n)throw new Error(`${me} not enough data for type`)}ke[23]=1,ke[24]=2,ke[25]=3,ke[26]=5,ke[27]=9;const Ae=[24,256,65536,4294967296,BigInt("18446744073709551616")];function Ce(e,t,n){xe(e,t,1);const r=e[t];if(!0===n.strict&&r<Ae[0])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function je(e,t,n){xe(e,t,2);const r=e[t]<<8|e[t+1];if(!0===n.strict&&r<Ae[1])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function Se(e,t,n){xe(e,t,4);const r=16777216*e[t]+(e[t+1]<<16)+(e[t+2]<<8)+e[t+3];if(!0===n.strict&&r<Ae[2])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function Ie(e,t,n){xe(e,t,8);const r=16777216*e[t]+(e[t+1]<<16)+(e[t+2]<<8)+e[t+3],o=16777216*e[t+4]+(e[t+5]<<16)+(e[t+6]<<8)+e[t+7],i=(BigInt(r)<<BigInt(32))+BigInt(o);if(!0===n.strict&&i<Ae[3])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);if(i<=Number.MAX_SAFE_INTEGER)return Number(i);if(!0===n.allowBigInt)return i;throw new Error(`${me} integers outside of the safe integer range are not supported`)}function Ue(e,t){return $e(e,0,t.value)}function $e(e,t,n){if(n<Ae[0]){const r=Number(n);e.push([t|r])}else if(n<Ae[1]){const r=Number(n);e.push([24|t,r])}else if(n<Ae[2]){const r=Number(n);e.push([25|t,r>>>8,255&r])}else if(n<Ae[3]){const r=Number(n);e.push([26|t,r>>>24&255,r>>>16&255,r>>>8&255,255&r])}else{const r=BigInt(n);if(!(r<Ae[4]))throw new Error(`${me} encountered BigInt larger than allowable range`);{const n=[27|t,0,0,0,0,0,0,0];let o=Number(r&BigInt(4294967295)),i=Number(r>>BigInt(32)&BigInt(4294967295));n[8]=255&o,o>>=8,n[7]=255&o,o>>=8,n[6]=255&o,o>>=8,n[5]=255&o,n[4]=255&i,i>>=8,n[3]=255&i,i>>=8,n[2]=255&i,i>>=8,n[1]=255&i,e.push(n)}}}Ue.encodedSize=function(e){return $e.encodedSize(e.value)},$e.encodedSize=function(e){return e<Ae[0]?1:e<Ae[1]?2:e<Ae[2]?3:e<Ae[3]?5:9},Ue.compareTokens=function(e,t){return e.value<t.value?-1:e.value>t.value?1:0};const Le=BigInt(-1),Be=BigInt(1);function Ne(e,t){const n=t.value,r="bigint"==typeof n?n*Le-Be:-1*n-1;$e(e,t.type.majorEncoded,r)}function Oe(e,t,n,r){xe(e,t,n+r);const o=de(e,t+n,t+n+r);return new oe(re.bytes,o,n+r)}function Te(e,t,n,r){return Oe(e,t,1,n)}function Me(e){return void 0===e.encodedBytes&&(e.encodedBytes=e.type===re.string?he(e.value):e.value),e.encodedBytes}function De(e,t){const n=Me(t);$e(e,t.type.majorEncoded,n.length),e.push(n)}function _e(e,t,n,r,o){const i=n+r;xe(e,t,i);const s=new oe(re.string,fe(e,t+n,t+i),i);return!0===o.retainStringBytes&&(s.byteValue=de(e,t+n,t+i)),s}function ze(e,t,n,r){return _e(e,t,1,n,r)}Ne.encodedSize=function(e){const t=e.value,n="bigint"==typeof t?t*Le-Be:-1*t-1;return n<Ae[0]?1:n<Ae[1]?2:n<Ae[2]?3:n<Ae[3]?5:9},Ne.compareTokens=function(e,t){return e.value<t.value?1:e.value>t.value?-1:0},De.encodedSize=function(e){const t=Me(e);return $e.encodedSize(t.length)+t.length},De.compareTokens=function(e,t){return n=Me(e),r=Me(t),n.length<r.length?-1:n.length>r.length?1:function(e,t){if(ce(e)&&ce(t))return e.compare(t);for(let n=0;n<e.length;n++)if(e[n]!==t[n])return e[n]<t[n]?-1:1;return 0}(n,r);var n,r};const Pe=De;function Re(e,t,n,r){return new oe(re.array,r,n)}function Fe(e,t,n,r){return Re(0,0,1,n)}function Ve(e,t){$e(e,re.array.majorEncoded,t.value)}function qe(e,t,n,r){return new oe(re.map,r,n)}function Ke(e,t,n,r){return qe(0,0,1,n)}function Ge(e,t){$e(e,re.map.majorEncoded,t.value)}function We(e,t,n,r){return new oe(re.tag,n,1)}function He(e,t){$e(e,re.tag.majorEncoded,t.value)}function Je(e,t,n){if(n){if(!1===n.allowNaN&&Number.isNaN(e))throw new Error(`${me} NaN values are not supported`);if(!1===n.allowInfinity&&(e===1/0||e===-1/0))throw new Error(`${me} Infinity values are not supported`)}return new oe(re.float,e,t)}function Qe(e,t,n){const r=t.value;if(!1===r)e.push([20|re.float.majorEncoded]);else if(!0===r)e.push([21|re.float.majorEncoded]);else if(null===r)e.push([22|re.float.majorEncoded]);else if(void 0===r)e.push([23|re.float.majorEncoded]);else{let t,i=!1;n&&!0===n.float64||(et(r),t=tt(Ye,1),r===t||Number.isNaN(r)?(Ye[0]=249,e.push(Ye.slice(0,3)),i=!0):(nt(r),t=rt(Ye,1),r===t&&(Ye[0]=250,e.push(Ye.slice(0,5)),i=!0))),i||(o=r,Xe.setFloat64(0,o,!1),t=ot(Ye,1),Ye[0]=251,e.push(Ye.slice(0,9)))}var o}Ve.compareTokens=Ue.compareTokens,Ve.encodedSize=function(e){return $e.encodedSize(e.value)},Ge.compareTokens=Ue.compareTokens,Ge.encodedSize=function(e){return $e.encodedSize(e.value)},He.compareTokens=Ue.compareTokens,He.encodedSize=function(e){return $e.encodedSize(e.value)},Qe.encodedSize=function(e,t){const n=e.value;if(!1===n||!0===n||null==n)return 1;if(!t||!0!==t.float64){et(n);let e=tt(Ye,1);if(n===e||Number.isNaN(n))return 3;if(nt(n),e=rt(Ye,1),n===e)return 5}return 9};const Ze=new ArrayBuffer(9),Xe=new DataView(Ze,1),Ye=new Uint8Array(Ze,0);function et(e){if(e===1/0)Xe.setUint16(0,31744,!1);else if(e===-1/0)Xe.setUint16(0,64512,!1);else if(Number.isNaN(e))Xe.setUint16(0,32256,!1);else{Xe.setFloat32(0,e);const t=Xe.getUint32(0),n=(2139095040&t)>>23,r=8388607&t;if(255===n)Xe.setUint16(0,31744,!1);else if(0===n)Xe.setUint16(0,(2147483648&e)>>16|r>>13,!1);else{const e=n-127;e<-24?Xe.setUint16(0,0):e<-14?Xe.setUint16(0,(2147483648&t)>>16|1<<24+e,!1):Xe.setUint16(0,(2147483648&t)>>16|e+15<<10|r>>13,!1)}}}function tt(e,t){if(e.length-t<2)throw new Error(`${me} not enough data for float16`);const n=(e[t]<<8)+e[t+1];if(31744===n)return 1/0;if(64512===n)return-1/0;if(32256===n)return NaN;const r=n>>10&31,o=1023&n;let i;return i=0===r?o*2**-24:31!==r?(o+1024)*2**(r-25):0===o?1/0:NaN,32768&n?-i:i}function nt(e){Xe.setFloat32(0,e,!1)}function rt(e,t){if(e.length-t<4)throw new Error(`${me} not enough data for float32`);const n=(e.byteOffset||0)+t;return new DataView(e.buffer,n,4).getFloat32(0,!1)}function ot(e,t){if(e.length-t<8)throw new Error(`${me} not enough data for float64`);const n=(e.byteOffset||0)+t;return new DataView(e.buffer,n,8).getFloat64(0,!1)}function it(e,t,n){throw new Error(`${me} encountered invalid minor (${n}) for major ${e[t]>>>5}`)}function st(e){return()=>{throw new Error(`${me} ${e}`)}}Qe.compareTokens=Ue.compareTokens;const at=[];for(let e=0;e<=23;e++)at[e]=it;at[24]=function(e,t,n,r){return new oe(re.uint,Ce(e,t+1,r),2)},at[25]=function(e,t,n,r){return new oe(re.uint,je(e,t+1,r),3)},at[26]=function(e,t,n,r){return new oe(re.uint,Se(e,t+1,r),5)},at[27]=function(e,t,n,r){return new oe(re.uint,Ie(e,t+1,r),9)},at[28]=it,at[29]=it,at[30]=it,at[31]=it;for(let e=32;e<=55;e++)at[e]=it;at[56]=function(e,t,n,r){return new oe(re.negint,-1-Ce(e,t+1,r),2)},at[57]=function(e,t,n,r){return new oe(re.negint,-1-je(e,t+1,r),3)},at[58]=function(e,t,n,r){return new oe(re.negint,-1-Se(e,t+1,r),5)},at[59]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"!=typeof o){const e=-1-o;if(e>=Number.MIN_SAFE_INTEGER)return new oe(re.negint,e,9)}if(!0!==r.allowBigInt)throw new Error(`${me} integers outside of the safe integer range are not supported`);return new oe(re.negint,Le-BigInt(o),9)},at[60]=it,at[61]=it,at[62]=it,at[63]=it;for(let e=64;e<=87;e++)at[e]=Te;at[88]=function(e,t,n,r){return Oe(e,t,2,Ce(e,t+1,r))},at[89]=function(e,t,n,r){return Oe(e,t,3,je(e,t+1,r))},at[90]=function(e,t,n,r){return Oe(e,t,5,Se(e,t+1,r))},at[91]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer bytes lengths not supported`);return Oe(e,t,9,o)},at[92]=it,at[93]=it,at[94]=it,at[95]=st("indefinite length bytes/strings are not supported");for(let e=96;e<=119;e++)at[e]=ze;at[120]=function(e,t,n,r){return _e(e,t,2,Ce(e,t+1,r),r)},at[121]=function(e,t,n,r){return _e(e,t,3,je(e,t+1,r),r)},at[122]=function(e,t,n,r){return _e(e,t,5,Se(e,t+1,r),r)},at[123]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer string lengths not supported`);return _e(e,t,9,o,r)},at[124]=it,at[125]=it,at[126]=it,at[127]=st("indefinite length bytes/strings are not supported");for(let e=128;e<=151;e++)at[e]=Fe;at[152]=function(e,t,n,r){return Re(0,0,2,Ce(e,t+1,r))},at[153]=function(e,t,n,r){return Re(0,0,3,je(e,t+1,r))},at[154]=function(e,t,n,r){return Re(0,0,5,Se(e,t+1,r))},at[155]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer array lengths not supported`);return Re(0,0,9,o)},at[156]=it,at[157]=it,at[158]=it,at[159]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return Re(0,0,1,1/0)};for(let e=160;e<=183;e++)at[e]=Ke;at[184]=function(e,t,n,r){return qe(0,0,2,Ce(e,t+1,r))},at[185]=function(e,t,n,r){return qe(0,0,3,je(e,t+1,r))},at[186]=function(e,t,n,r){return qe(0,0,5,Se(e,t+1,r))},at[187]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer map lengths not supported`);return qe(0,0,9,o)},at[188]=it,at[189]=it,at[190]=it,at[191]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return qe(0,0,1,1/0)};for(let e=192;e<=215;e++)at[e]=We;at[216]=function(e,t,n,r){return new oe(re.tag,Ce(e,t+1,r),2)},at[217]=function(e,t,n,r){return new oe(re.tag,je(e,t+1,r),3)},at[218]=function(e,t,n,r){return new oe(re.tag,Se(e,t+1,r),5)},at[219]=function(e,t,n,r){return new oe(re.tag,Ie(e,t+1,r),9)},at[220]=it,at[221]=it,at[222]=it,at[223]=it;for(let e=224;e<=243;e++)at[e]=st("simple values are not supported");at[244]=it,at[245]=it,at[246]=it,at[247]=function(e,t,n,r){if(!1===r.allowUndefined)throw new Error(`${me} undefined values are not supported`);return!0===r.coerceUndefinedToNull?new oe(re.null,null,1):new oe(re.undefined,void 0,1)},at[248]=st("simple values are not supported"),at[249]=function(e,t,n,r){return Je(tt(e,t+1),3,r)},at[250]=function(e,t,n,r){return Je(rt(e,t+1),5,r)},at[251]=function(e,t,n,r){return Je(ot(e,t+1),9,r)},at[252]=it,at[253]=it,at[254]=it,at[255]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return new oe(re.break,void 0,1)};const ct=[];for(let e=0;e<24;e++)ct[e]=new oe(re.uint,e,1);for(let e=-1;e>=-24;e--)ct[31-e]=new oe(re.negint,e,1);ct[64]=new oe(re.bytes,new Uint8Array(0),1),ct[96]=new oe(re.string,"",1),ct[128]=new oe(re.array,0,1),ct[160]=new oe(re.map,0,1),ct[244]=new oe(re.false,!1,1),ct[245]=new oe(re.true,!0,1),ct[246]=new oe(re.null,null,1);const ut={float64:!1,mapSorter:function(e,t){const n=Array.isArray(e[0])?e[0][0]:e[0],r=Array.isArray(t[0])?t[0][0]:t[0];if(n.type!==r.type)return n.type.compare(r.type);const o=n.type.major,i=ft[o].compareTokens(n,r);return 0===i&&console.warn("WARNING: complex key types used, CBOR key sorting guarantees are gone"),i},quickEncodeToken:function(e){switch(e.type){case re.false:return le([244]);case re.true:return le([245]);case re.null:return le([246]);case re.bytes:return e.value.length?void 0:le([64]);case re.string:return""===e.value?le([96]):void 0;case re.array:return 0===e.value?le([128]):void 0;case re.map:return 0===e.value?le([160]):void 0;case re.uint:return e.value<24?le([Number(e.value)]):void 0;case re.negint:if(e.value>=-24)return le([31-Number(e.value)])}}},ft=function(){const e=[];return e[re.uint.major]=Ue,e[re.negint.major]=Ne,e[re.bytes.major]=De,e[re.string.major]=Pe,e[re.array.major]=Ve,e[re.map.major]=Ge,e[re.tag.major]=He,e[re.float.major]=Qe,e}(),ht=new ve;class lt{constructor(e,t){this.obj=e,this.parent=t}includes(e){let t=this;do{if(t.obj===e)return!0}while(t=t.parent);return!1}static createCheck(e,t){if(e&&e.includes(t))throw new Error(`${Ee} object contains circular references`);return new lt(t,e)}}const dt={null:new oe(re.null,null),undefined:new oe(re.undefined,void 0),true:new oe(re.true,!0),false:new oe(re.false,!1),emptyArray:new oe(re.array,0),emptyMap:new oe(re.map,0)},pt={number:(e,t,n,r)=>Number.isInteger(e)&&Number.isSafeInteger(e)?new oe(e>=0?re.uint:re.negint,e):new oe(re.float,e),bigint:(e,t,n,r)=>e>=BigInt(0)?new oe(re.uint,e):new oe(re.negint,e),Uint8Array:(e,t,n,r)=>new oe(re.bytes,e),string:(e,t,n,r)=>new oe(re.string,e),boolean:(e,t,n,r)=>e?dt.true:dt.false,null:(e,t,n,r)=>dt.null,undefined:(e,t,n,r)=>dt.undefined,ArrayBuffer:(e,t,n,r)=>new oe(re.bytes,new Uint8Array(e)),DataView:(e,t,n,r)=>new oe(re.bytes,new Uint8Array(e.buffer,e.byteOffset,e.byteLength)),Array(e,t,n,r){if(!e.length)return!0===n.addBreakTokens?[dt.emptyArray,new oe(re.break)]:dt.emptyArray;r=lt.createCheck(r,e);const o=[];let i=0;for(const t of e)o[i++]=yt(t,n,r);return n.addBreakTokens?[new oe(re.array,e.length),o,new oe(re.break)]:[new oe(re.array,e.length),o]},Object(e,t,n,r){const o="Object"!==t,i=o?e.keys():Object.keys(e),s=o?e.size:i.length;if(!s)return!0===n.addBreakTokens?[dt.emptyMap,new oe(re.break)]:dt.emptyMap;r=lt.createCheck(r,e);const a=[];let c=0;for(const t of i)a[c++]=[yt(t,n,r),yt(o?e.get(t):e[t],n,r)];return function(e,t){t.mapSorter&&e.sort(t.mapSorter)}(a,n),n.addBreakTokens?[new oe(re.map,s),a,new oe(re.break)]:[new oe(re.map,s),a]}};pt.Map=pt.Object,pt.Buffer=pt.Uint8Array;for(const e of"Uint8Clamped Uint16 Uint32 Int8 Int16 Int32 BigUint64 BigInt64 Float32 Float64".split(" "))pt[`${e}Array`]=pt.DataView;function yt(e,t={},n){const r=function(e){if(null===e)return"null";if(void 0===e)return"undefined";if(!0===e||!1===e)return"boolean";const t=typeof e;if(te.includes(t))return t;if("function"===t)return"Function";if(Array.isArray(e))return"Array";if(function(e){return e&&e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer.call(null,e)}(e))return"Buffer";return function(e){const t=Object.prototype.toString.call(e).slice(8,-1);if(ne.includes(t))return t}(e)||"Object"}(e),o=t&&t.typeEncoders&&t.typeEncoders[r]||pt[r];if("function"==typeof o){const i=o(e,r,t,n);if(null!=i)return i}const i=pt[r];if(!i)throw new Error(`${Ee} unsupported type: ${r}`);return i(e,r,t,n)}function wt(e,t,n,r){if(Array.isArray(t))for(const o of t)wt(e,o,n,r);else n[t.type.major](e,t,r)}function gt(e,t,n){const r=yt(e,n);if(!Array.isArray(r)&&n.quickEncodeToken){const e=n.quickEncodeToken(r);if(e)return e;const o=t[r.type.major];if(o.encodedSize){const e=o.encodedSize(r,n),t=new ve(e);if(o(t,r,n),1!==t.chunks.length)throw new Error(`Unexpected error: pre-calculated length for ${r} was wrong`);return ue(t.chunks[0])}}return ht.reset(),wt(ht,r,t,n),ht.toBytes(!0)}const bt={strict:!1,allowIndefinite:!0,allowUndefined:!0,allowBigInt:!0};class vt{constructor(e,t={}){this.pos=0,this.data=e,this.options=t}done(){return this.pos>=this.data.length}next(){const e=this.data[this.pos];let t=ct[e];if(void 0===t){const n=at[e];if(!n)throw new Error(`${me} no decoder for major type ${e>>>5} (byte 0x${e.toString(16).padStart(2,"0")})`);const r=31&e;t=n(this.data,this.pos,r,this.options)}return this.pos+=t.encodedLength,t}}const mt=Symbol.for("DONE"),Et=Symbol.for("BREAK");function kt(e,t){if(e.done())return mt;const n=e.next();if(n.type===re.break)return Et;if(n.type.terminal)return n.value;if(n.type===re.array)return function(e,t,n){const r=[];for(let o=0;o<e.value;o++){const i=kt(t,n);if(i===Et){if(e.value===1/0)break;throw new Error(`${me} got unexpected break to lengthed array`)}if(i===mt)throw new Error(`${me} found array but not enough entries (got ${o}, expected ${e.value})`);r[o]=i}return r}(n,e,t);if(n.type===re.map)return function(e,t,n){const r=!0===n.useMaps,o=r?void 0:{},i=r?new Map:void 0;for(let s=0;s<e.value;s++){const a=kt(t,n);if(a===Et){if(e.value===1/0)break;throw new Error(`${me} got unexpected break to lengthed map`)}if(a===mt)throw new Error(`${me} found map but not enough entries (got ${s} [no key], expected ${e.value})`);if(!0!==r&&"string"!=typeof a)throw new Error(`${me} non-string keys not supported (got ${typeof a})`);if(!0===n.rejectDuplicateMapKeys&&(r&&i.has(a)||!r&&a in o))throw new Error(`${me} found repeat map key "${a}"`);const c=kt(t,n);if(c===mt)throw new Error(`${me} found map but not enough entries (got ${s} [no value], expected ${e.value})`);r?i.set(a,c):o[a]=c}return r?i:o}(n,e,t);if(n.type===re.tag){if(t.tags&&"function"==typeof t.tags[n.value]){const r=kt(e,t);return t.tags[n.value](r)}throw new Error(`${me} tag not supported (${n.value})`)}throw new Error("unsupported")}const xt={float64:!0,typeEncoders:{Object:function(e){if(e.asCID!==e&&e["/"]!==e.bytes)return null;const t=_.asCID(e);if(!t)return null;const n=new Uint8Array(t.bytes.byteLength+1);return n.set(t.bytes,1),[new oe(re.tag,42),new oe(re.bytes,n)]},undefined:function(){throw new Error("`undefined` is not supported by the IPLD Data Model and cannot be encoded")},number:function(e){if(Number.isNaN(e))throw new Error("`NaN` is not supported by the IPLD Data Model and cannot be encoded");if(e===1/0||e===-1/0)throw new Error("`Infinity` and `-Infinity` is not supported by the IPLD Data Model and cannot be encoded");return null}}},At={allowIndefinite:!1,coerceUndefinedToNull:!0,allowNaN:!1,allowInfinity:!1,allowBigInt:!0,strict:!0,useMaps:!1,rejectDuplicateMapKeys:!0,tags:[]};At.tags[42]=function(e){if(0!==e[0])throw new Error("Invalid CID for CBOR tag 42; expected leading 0x00");return _.decode(e.subarray(1))};const Ct="dag-cbor",jt=113,St=e=>{return t=e,n=xt,n=Object.assign({},ut,n),gt(t,ft,n);var t,n},It=e=>function(e,t){if(!(e instanceof Uint8Array))throw new Error(`${me} data to decode must be a Uint8Array`);const n=(t=Object.assign({},bt,t)).tokenizer||new vt(e,t),r=kt(n,t);if(r===mt)throw new Error(`${me} did not find any content to decode`);if(r===Et)throw new Error(`${me} got unexpected break`);if(!n.done())throw new Error(`${me} too many terminals, data makes no sense`);return r}(e,At),Ut=e=>async t=>new Uint8Array(await crypto.subtle.digest(e,t)),$t=G({name:"sha2-256",code:18,encode:Ut("SHA-256")}),Lt=(G({name:"sha2-512",code:19,encode:Ut("SHA-512")}),e),Bt=$t,Nt=N,Ot=e=>e&&void 0!==e.id&&void 0!==e.next&&void 0!==e.payload&&void 0!==e.v&&void 0!==e.clock&&void 0!==e.refs,Tt=async e=>{const{cid:t,bytes:n}=await ee({value:e,codec:Lt,hasher:Bt}),r=t.toString(Nt),o=new i(e.clock.id,e.clock.time);return{...e,clock:o,hash:r,bytes:n}},Mt={create:async(e,t,n,r=null,o=[],a=[])=>{if(!s(e))throw new Error("Identity is required, cannot create entry");if(!s(t))throw new Error("Entry requires an id");if(!s(n))throw new Error("Entry requires a payload");if(!s(o)||!Array.isArray(o))throw new Error("'next' argument is not an array");const c={id:t,payload:n,next:o,refs:a,clock:r=r||new i(e.publicKey),v:2},{bytes:u}=await ee({value:c,codec:Lt,hasher:Bt}),f=await e.provider.sign(e,u);return c.key=e.publicKey,c.identity=e.toJSON(),c.sig=f,Tt(c)},verify:async(e,t)=>{if(!e)throw new Error("Identity-provider is required, cannot verify entry");if(!Ot(t))throw new Error("Invalid Log entry");if(!t.key)throw new Error("Entry doesn't have a key");if(!t.sig)throw new Error("Entry doesn't have a signature");const n={id:t.id,payload:t.payload,next:t.next,refs:t.refs,clock:t.clock,v:t.v},{bytes:r}=await ee({value:n,codec:Lt,hasher:Bt});return e.verify(t.sig,t.key,r)},decode:async e=>{const{value:t}=await async function({bytes:e,codec:t,hasher:n}){if(!e)throw new Error('Missing required argument "bytes"');if(!t||!n)throw new Error("Missing required argument: codec or hasher");const r=t.decode(e),o=await n.digest(e),i=_.create(1,t.code,o);return new Y({value:r,bytes:e,cid:i})}({bytes:e,codec:Lt,hasher:Bt});return Tt(t)},isEntry:Ot,isEqual:(e,t)=>e&&t&&e.hash===t.hash};function Dt(e,t,n){const r=i.compare(e.clock,t.clock);return 0===r?n(e,t):r}function _t(e,t,n){return e.clock.id===t.clock.id?n(e,t):e.clock.id<t.clock.id?-1:1}const zt={SortByClocks:Dt,SortByClockId:_t,LastWriteWins:function(e,t){const n=(e,t)=>e,r=(e,t)=>_t(e,t,n);return((e,t)=>Dt(e,t,r))(e,t)},NoZeroes:function(e){const t=`Your log's tiebreaker function, ${e.name}, has returned zero and therefore cannot be`;return(n,r)=>{const o=e(n,r);if(0===o)throw Error(t);return o}}},Pt=async({ipfs:e,timeout:t,pin:n})=>(t=t||3e4,{put:async(r,o)=>{const i=_.parse(r,N);await e.block.put(o,{cid:i.bytes,version:i.version,format:"dag-cbor",mhtype:"sha2-256",pin:n,timeout:t})},get:async n=>{const r=_.parse(n,N),o=await e.block.get(r,{timeout:t});if(o)return o},iterator:async function*(){},merge:async e=>{},clear:async()=>{},close:async()=>{}}),Rt=async()=>{let e={};const t=async(t,n)=>{e[t]=n};return{put:t,get:async t=>{if(e[t])return e[t]},iterator:async function*(){for await(const[t,n]of Object.entries(e))yield[t,n]},merge:async e=>{if(e)for await(const[n,r]of e.iterator())t(n,r)},clear:async()=>e={},close:async()=>{}}},Ft=1e6,Vt=async({size:e}={})=>{let n=new t(e||Ft);return{put:async(e,t)=>{n.set(e,t)},get:async e=>{if(n.peek(e))return n.get(e)},iterator:async function*(){for await(const e of n.keys){const t=n.get(e);yield[e,t]}},merge:async e=>{if(e)for await(const[t,r]of e.iterator())n.set(t,r)},clear:async()=>{n=new t(e||Ft)},close:async()=>{}}},qt=async(...e)=>({put:async(t,n)=>{for await(const r of e)await r.put(t,n)},get:async t=>{for await(const n of e){const e=await n.get(t);if(e)return e}},iterator:async function*(){return e[0].iterator()},merge:async t=>{for await(const t of e)for await(const n of e)await t.merge(n)},clear:async()=>{for await(const t of e)await t.clear()},close:async()=>{for await(const t of e)await t.close()}}),{LastWriteWins:Kt,NoZeroes:Gt}=zt,Wt=(e,t)=>Math.max(e,t.clock.time),Ht=Rt,Jt=async()=>({canAppend:async(e,t)=>!0}),Qt=async(e,{logId:n,logHeads:r,access:o,storage:a,stateStorage:c,sortFn:u}={})=>{if(!s(e))throw new Error("Identity is required");if(s(r)&&!Array.isArray(r))throw new Error("'logHeads' argument must be an array");const f=n||(new Date).getTime().toString();o=o||await Jt(),a=a||await Ht(),c=c||await Ht();const h=Zt(new Set(r||[]));for(const e of h)await c.put(e.hash,!0);u=Gt(u||Kt);const l=async()=>{const t=Math.max(0,(await d()).reduce(Wt,0));return new i(e.publicKey,t)},d=async()=>{const e=[];for await(const[t]of c.iterator())if(t){const n=await p(t);n&&e.push(n)}return e.sort(u).reverse()},p=async e=>{const t=await a.get(e);if(t)return await Mt.decode(t)},y=async t=>{const n=e.provider;if(t.id!==f)throw new Error(`Entry's id (${t.id}) doesn't match the log's id (${f}).`);const r=await d();if(r.find((e=>e.hash===t.hash)))return;if(!await o.canAppend(t,n))throw new Error(`Could not append entry:\nKey "${t.identity.id}" is not allowed to write to the log`);if(!await Mt.verify(n,t))throw new Error(`Could not validate signature for entry "${t.hash}"`);const i=Zt(new Set([...r,t]));await c.clear();for(const e of i)await c.put(e.hash,!0);return await a.put(t.hash,t.bytes),!0},w=async function*(e,t){t=t||(()=>!1);let n=(e=e||await d()).sort(u);const r={};let o;for(;n.length>0&&!0!==await t(o);)if(o=n.pop(),o){yield o;for(const e of[...o.next,...o.refs])if(!r[e]){r[e]=!0;const t=await p(e);t&&(n=[t,...n].sort(u))}}};return{id:f,clock:l,heads:d,values:async()=>{const e=[];for await(const t of w())e.unshift(t);return e},get:p,append:async(t,n={pointerCount:1})=>{const r=await(async(e=1)=>{let t=2,n=0;const r=[],o=()=>n>=e;for await(const e of w(null,o))n++,n===t&&(e.hash&&r.push(e.hash),t*=2);return r})(n.pointerCount),i=(await d()).map((e=>e.hash)),s=await Mt.create(e,f,t,(await l()).tick(),i,r);if(!await o.canAppend(s,e.provider))throw new Error(`Could not append entry:\nKey "${e.id}" is not allowed to write to the log`);return await c.clear(),await c.put(s.hash,!0),await a.put(s.hash,s.bytes),s},join:async e=>{if(!e)throw new Error("Log instance not defined");if(!(t=e)||void 0===t.id||void 0===t.clock||void 0===t.heads||void 0===t.values||void 0===t.access||void 0===t.identity||void 0===t.storage)throw new Error("Given argument is not an instance of Log");var t;const n=await e.heads();for(const e of n)await y(e);a.merge&&await a.merge(e.storage)},joinEntry:y,traverse:w,iterator:async function*({amount:e=-1,gt:n,gte:r,lt:o,lte:i}={}){if(0===e)return;if("string"==typeof i&&(i=[await p(i)]),"string"==typeof o){const e=await p(o);o=await Promise.all(e.next.map((e=>p(e))))}if(s(o)&&!Array.isArray(o))throw new Error("lt must be a string or an array of Entries");if(s(i)&&!Array.isArray(i))throw new Error("lte must be a string or an array of Entries");const a=(o||i||await d()).filter(s),c=n||r?await p(n||r):null,u=c||-1===e?-1:i||o?e-1:e;let f=0;const h=c&&-1!==e&&!o&&!i,l=h?new t(e+2):null;let y=0;const g=w(a,(async e=>!!e&&(f>=u&&-1!==u||!(!c||!Mt.isEqual(e,c))||(f++,!1))));for await(const e of g){const t=o&&Mt.isEqual(e,a),r=n&&Mt.isEqual(e,c);t||r||(h?l.set(y++,e.hash):yield e)}if(h){const t=l.keys.length-1,n=t-e,r=l.keys.slice(n,t);for(const e of r){const t=l.get(e),n=await p(t);yield n}}},access:o,identity:e,storage:a}},Zt=e=>{const t={};for(const n of e)for(const e of n.next)t[e]=n.hash;const n=[];for(const r of e)t[r.hash]||n.push(r);return n}})(),Log=r})(); \ No newline at end of file +var Log;(()=>{var e={187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,r=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function i(){i.init.call(this)}e.exports=i,e.exports.once=function(e,t){return new Promise((function(n,r){function o(n){e.removeListener(t,i),r(n)}function i(){"function"==typeof e.removeListener&&e.removeListener("error",o),n([].slice.call(arguments))}y(e,t,i,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&y(e,"error",t,{once:!0})}(e,o)}))},i.EventEmitter=i,i.prototype._events=void 0,i.prototype._eventsCount=0,i.prototype._maxListeners=void 0;var s=10;function a(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function c(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function u(e,t,n,r){var o,i,s,u;if(a(n),void 0===(i=e._events)?(i=e._events=Object.create(null),e._eventsCount=0):(void 0!==i.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),i=e._events),s=i[t]),void 0===s)s=i[t]=n,++e._eventsCount;else if("function"==typeof s?s=i[t]=r?[n,s]:[s,n]:r?s.unshift(n):s.push(n),(o=c(e))>0&&s.length>o&&!s.warned){s.warned=!0;var f=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");f.name="MaxListenersExceededWarning",f.emitter=e,f.type=t,f.count=s.length,u=f,console&&console.warn&&console.warn(u)}return e}function f(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function h(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=f.bind(r);return o.listener=n,r.wrapFn=o,o}function l(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n<t.length;++n)t[n]=e[n].listener||e[n];return t}(o):p(o,o.length)}function d(e){var t=this._events;if(void 0!==t){var n=t[e];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function p(e,t){for(var n=new Array(t),r=0;r<t;++r)n[r]=e[r];return n}function y(e,t,n,r){if("function"==typeof e.on)r.once?e.once(t,n):e.on(t,n);else{if("function"!=typeof e.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof e);e.addEventListener(t,(function o(i){r.once&&e.removeEventListener(t,o),n(i)}))}}Object.defineProperty(i,"defaultMaxListeners",{enumerable:!0,get:function(){return s},set:function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+e+".");s=e}}),i.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},i.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||o(e))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+e+".");return this._maxListeners=e,this},i.prototype.getMaxListeners=function(){return c(this)},i.prototype.emit=function(e){for(var t=[],n=1;n<arguments.length;n++)t.push(arguments[n]);var o="error"===e,i=this._events;if(void 0!==i)o=o&&void 0===i.error;else if(!o)return!1;if(o){var s;if(t.length>0&&(s=t[0]),s instanceof Error)throw s;var a=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw a.context=s,a}var c=i[e];if(void 0===c)return!1;if("function"==typeof c)r(c,this,t);else{var u=c.length,f=p(c,u);for(n=0;n<u;++n)r(f[n],this,t)}return!0},i.prototype.addListener=function(e,t){return u(this,e,t,!1)},i.prototype.on=i.prototype.addListener,i.prototype.prependListener=function(e,t){return u(this,e,t,!0)},i.prototype.once=function(e,t){return a(t),this.on(e,h(this,e,t)),this},i.prototype.prependOnceListener=function(e,t){return a(t),this.prependListener(e,h(this,e,t)),this},i.prototype.removeListener=function(e,t){var n,r,o,i,s;if(a(t),void 0===(r=this._events))return this;if(void 0===(n=r[e]))return this;if(n===t||n.listener===t)0==--this._eventsCount?this._events=Object.create(null):(delete r[e],r.removeListener&&this.emit("removeListener",e,n.listener||t));else if("function"!=typeof n){for(o=-1,i=n.length-1;i>=0;i--)if(n[i]===t||n[i].listener===t){s=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1<e.length;t++)e[t]=e[t+1];e.pop()}(n,o),1===n.length&&(r[e]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",e,s||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[e]),this;if(0===arguments.length){var o,i=Object.keys(n);for(r=0;r<i.length;++r)"removeListener"!==(o=i[r])&&this.removeAllListeners(o);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(t=n[e]))this.removeListener(e,t);else if(void 0!==t)for(r=t.length-1;r>=0;r--)this.removeListener(e,t[r]);return this},i.prototype.listeners=function(e){return l(this,e,!0)},i.prototype.rawListeners=function(e){return l(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):d.call(e,t)},i.prototype.listenerCount=d,i.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},717:e=>{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){if(t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}}},117:(e,t,n)=>{var r=n(187),o=n(717);function i(e){if(!(this instanceof i))return new i(e);"number"==typeof e&&(e={max:e}),e||(e={}),r.EventEmitter.call(this),this.cache={},this.head=this.tail=null,this.length=0,this.max=e.max||1e3,this.maxAge=e.maxAge||0}e.exports=i,o(i,r.EventEmitter),Object.defineProperty(i.prototype,"keys",{get:function(){return Object.keys(this.cache)}}),i.prototype.clear=function(){this.cache={},this.head=this.tail=null,this.length=0},i.prototype.remove=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];return delete this.cache[e],this._unlink(e,t.prev,t.next),t.value}},i.prototype._unlink=function(e,t,n){this.length--,0===this.length?this.head=this.tail=null:this.head===e?(this.head=t,this.cache[this.head].next=null):this.tail===e?(this.tail=n,this.cache[this.tail].prev=null):(this.cache[t].next=n,this.cache[n].prev=t)},i.prototype.peek=function(e){if(this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return t.value}},i.prototype.set=function(e,t){var n;if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){if((n=this.cache[e]).value=t,this.maxAge&&(n.modified=Date.now()),e===this.head)return t;this._unlink(e,n.prev,n.next)}else n={value:t,modified:0,next:null,prev:null},this.maxAge&&(n.modified=Date.now()),this.cache[e]=n,this.length===this.max&&this.evict();return this.length++,n.next=null,n.prev=this.head,this.head&&(this.cache[this.head].next=e),this.head=e,this.tail||(this.tail=e),t},i.prototype._checkAge=function(e,t){return!(this.maxAge&&Date.now()-t.modified>this.maxAge&&(this.remove(e),this.emit("evict",{key:e,value:t.value}),1))},i.prototype.get=function(e){if("string"!=typeof e&&(e=""+e),this.cache.hasOwnProperty(e)){var t=this.cache[e];if(this._checkAge(e,t))return this.head!==e&&(e===this.tail?(this.tail=t.next,this.cache[this.tail].prev=null):this.cache[t.prev].next=t.next,this.cache[t.next].prev=t.prev,this.cache[this.head].next=e,t.prev=this.head,t.next=null,this.head=e),t.value}},i.prototype.evict=function(){if(this.tail){var e=this.tail,t=this.remove(this.tail);this.emit("evict",{key:e,value:t})}}}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{ComposedStorage:()=>qt,DefaultAccessController:()=>Jt,Entry:()=>Mt,IPFSBlockStorage:()=>Pt,LRUStorage:()=>Vt,Log:()=>Qt,MemoryStorage:()=>Rt,Sorting:()=>zt});var e={};n.r(e),n.d(e,{code:()=>jt,decode:()=>It,encode:()=>St,name:()=>Ct});var t=n(117);class o{constructor(e,t){this.id=e,this.time=t||0}tick(){return new o(this.id,++this.time)}merge(e){return this.time=Math.max(this.time,e.time),new o(this.id,this.time)}clone(){return new o(this.id,this.time)}static compare(e,t){const n=e.time-t.time;return 0===n&&e.id!==t.id?e.id<t.id?-1:1:n}}const i=o,s=e=>null!=e;var a=Math.pow(2,31),c=Math.pow(2,7),u=Math.pow(2,14),f=Math.pow(2,21),h=Math.pow(2,28),l=Math.pow(2,35),d=Math.pow(2,42),p=Math.pow(2,49),y=Math.pow(2,56),w=Math.pow(2,63);const g={encode:function e(t,n,r){n=n||[];for(var o=r=r||0;t>=a;)n[r++]=255&t|128,t/=128;for(;-128&t;)n[r++]=255&t|128,t>>>=7;return n[r]=0|t,e.bytes=r-o+1,n},decode:function e(t,n){var r,o=0,i=0,s=n=n||0,a=t.length;do{if(s>=a)throw e.bytes=0,new RangeError("Could not decode varint");r=t[s++],o+=i<28?(127&r)<<i:(127&r)*Math.pow(2,i),i+=7}while(r>=128);return e.bytes=s-n,o},encodingLength:function(e){return e<c?1:e<u?2:e<f?3:e<h?4:e<l?5:e<d?6:e<p?7:e<y?8:e<w?9:10}},b=(e,t=0)=>[g.decode(e,t),g.decode.bytes],v=(e,t,n=0)=>(g.encode(e,t,n),t),m=e=>g.encodingLength(e),E=(new Uint8Array(0),e=>{if(e instanceof Uint8Array&&"Uint8Array"===e.constructor.name)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);throw new Error("Unknown type, must be binary type")}),k=(e,t)=>{const n=t.byteLength,r=m(e),o=r+m(n),i=new Uint8Array(o+n);return v(e,i,0),v(n,i,r),i.set(t,o),new x(e,n,t,i)};class x{constructor(e,t,n,r){this.code=e,this.size=t,this.digest=n,this.bytes=r}}const A=function(e,t){if(e.length>=255)throw new TypeError("Alphabet too long");for(var n=new Uint8Array(256),r=0;r<n.length;r++)n[r]=255;for(var o=0;o<e.length;o++){var i=e.charAt(o),s=i.charCodeAt(0);if(255!==n[s])throw new TypeError(i+" is ambiguous");n[s]=o}var a=e.length,c=e.charAt(0),u=Math.log(a)/Math.log(256),f=Math.log(256)/Math.log(a);function h(e){if("string"!=typeof e)throw new TypeError("Expected String");if(0===e.length)return new Uint8Array;var t=0;if(" "!==e[t]){for(var r=0,o=0;e[t]===c;)r++,t++;for(var i=(e.length-t)*u+1>>>0,s=new Uint8Array(i);e[t];){var f=n[e.charCodeAt(t)];if(255===f)return;for(var h=0,l=i-1;(0!==f||h<o)&&-1!==l;l--,h++)f+=a*s[l]>>>0,s[l]=f%256>>>0,f=f/256>>>0;if(0!==f)throw new Error("Non-zero carry");o=h,t++}if(" "!==e[t]){for(var d=i-o;d!==i&&0===s[d];)d++;for(var p=new Uint8Array(r+(i-d)),y=r;d!==i;)p[y++]=s[d++];return p}}}return{encode:function(t){if(t instanceof Uint8Array||(ArrayBuffer.isView(t)?t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength):Array.isArray(t)&&(t=Uint8Array.from(t))),!(t instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(0===t.length)return"";for(var n=0,r=0,o=0,i=t.length;o!==i&&0===t[o];)o++,n++;for(var s=(i-o)*f+1>>>0,u=new Uint8Array(s);o!==i;){for(var h=t[o],l=0,d=s-1;(0!==h||l<r)&&-1!==d;d--,l++)h+=256*u[d]>>>0,u[d]=h%a>>>0,h=h/a>>>0;if(0!==h)throw new Error("Non-zero carry");r=l,o++}for(var p=s-r;p!==s&&0===u[p];)p++;for(var y=c.repeat(n);p<s;++p)y+=e.charAt(u[p]);return y},decodeUnsafe:h,decode:function(e){var n=h(e);if(n)return n;throw new Error(`Non-${t} character`)}}};class C{constructor(e,t,n){this.name=e,this.prefix=t,this.baseEncode=n}encode(e){if(e instanceof Uint8Array)return`${this.prefix}${this.baseEncode(e)}`;throw Error("Unknown type, must be binary type")}}class j{constructor(e,t,n){if(this.name=e,this.prefix=t,void 0===t.codePointAt(0))throw new Error("Invalid prefix character");this.prefixCodePoint=t.codePointAt(0),this.baseDecode=n}decode(e){if("string"==typeof e){if(e.codePointAt(0)!==this.prefixCodePoint)throw Error(`Unable to decode multibase string ${JSON.stringify(e)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);return this.baseDecode(e.slice(this.prefix.length))}throw Error("Can only multibase decode strings")}or(e){return I(this,e)}}class S{constructor(e){this.decoders=e}or(e){return I(this,e)}decode(e){const t=e[0],n=this.decoders[t];if(n)return n.decode(e);throw RangeError(`Unable to decode multibase string ${JSON.stringify(e)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)}}const I=(e,t)=>new S({...e.decoders||{[e.prefix]:e},...t.decoders||{[t.prefix]:t}});class U{constructor(e,t,n,r){this.name=e,this.prefix=t,this.baseEncode=n,this.baseDecode=r,this.encoder=new C(e,t,n),this.decoder=new j(e,t,r)}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}}const $=({name:e,prefix:t,encode:n,decode:r})=>new U(e,t,n,r),L=({prefix:e,name:t,alphabet:n})=>{const{encode:r,decode:o}=A(n,t);return $({prefix:e,name:t,encode:r,decode:e=>E(o(e))})},B=({name:e,prefix:t,bitsPerChar:n,alphabet:r})=>$({prefix:t,name:e,encode:e=>((e,t,n)=>{const r="="===t[t.length-1],o=(1<<n)-1;let i="",s=0,a=0;for(let r=0;r<e.length;++r)for(a=a<<8|e[r],s+=8;s>n;)s-=n,i+=t[o&a>>s];if(s&&(i+=t[o&a<<n-s]),r)for(;i.length*n&7;)i+="=";return i})(e,r,n),decode:t=>((e,t,n,r)=>{const o={};for(let e=0;e<t.length;++e)o[t[e]]=e;let i=e.length;for(;"="===e[i-1];)--i;const s=new Uint8Array(i*n/8|0);let a=0,c=0,u=0;for(let t=0;t<i;++t){const i=o[e[t]];if(void 0===i)throw new SyntaxError(`Non-${r} character`);c=c<<n|i,a+=n,a>=8&&(a-=8,s[u++]=255&c>>a)}if(a>=n||255&c<<8-a)throw new SyntaxError("Unexpected end of data");return s})(t,r,n,e)}),N=L({name:"base58btc",prefix:"z",alphabet:"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"}),O=(L({name:"base58flickr",prefix:"Z",alphabet:"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"}),B({prefix:"b",name:"base32",alphabet:"abcdefghijklmnopqrstuvwxyz234567",bitsPerChar:5})),T=(B({prefix:"B",name:"base32upper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",bitsPerChar:5}),B({prefix:"c",name:"base32pad",alphabet:"abcdefghijklmnopqrstuvwxyz234567=",bitsPerChar:5}),B({prefix:"C",name:"base32padupper",alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",bitsPerChar:5}),B({prefix:"v",name:"base32hex",alphabet:"0123456789abcdefghijklmnopqrstuv",bitsPerChar:5}),B({prefix:"V",name:"base32hexupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV",bitsPerChar:5}),B({prefix:"t",name:"base32hexpad",alphabet:"0123456789abcdefghijklmnopqrstuv=",bitsPerChar:5}),B({prefix:"T",name:"base32hexpadupper",alphabet:"0123456789ABCDEFGHIJKLMNOPQRSTUV=",bitsPerChar:5}),B({prefix:"h",name:"base32z",alphabet:"ybndrfg8ejkmcpqxot1uwisza345h769",bitsPerChar:5}),(e,t)=>{const{bytes:n,version:r}=e;return 0===r?P(n,D(e),t||N.encoder):R(n,D(e),t||O.encoder)}),M=new WeakMap,D=e=>{const t=M.get(e);if(null==t){const t=new Map;return M.set(e,t),t}return t};class _{constructor(e,t,n,r){this.code=t,this.version=e,this.multihash=n,this.bytes=r,this["/"]=r}get asCID(){return this}get byteOffset(){return this.bytes.byteOffset}get byteLength(){return this.bytes.byteLength}toV0(){switch(this.version){case 0:return this;case 1:{const{code:e,multihash:t}=this;if(e!==F)throw new Error("Cannot convert a non dag-pb CID to CIDv0");if(t.code!==V)throw new Error("Cannot convert non sha2-256 multihash CID to CIDv0");return _.createV0(t)}default:throw Error(`Can not convert CID version ${this.version} to version 0. This is a bug please report`)}}toV1(){switch(this.version){case 0:{const{code:e,digest:t}=this.multihash,n=k(e,t);return _.createV1(this.code,n)}case 1:return this;default:throw Error(`Can not convert CID version ${this.version} to version 1. This is a bug please report`)}}equals(e){return _.equals(this,e)}static equals(e,t){const n=t;return n&&e.code===n.code&&e.version===n.version&&((e,t)=>{if(e===t)return!0;{const n=t;return e.code===n.code&&e.size===n.size&&n.bytes instanceof Uint8Array&&((e,t)=>{if(e===t)return!0;if(e.byteLength!==t.byteLength)return!1;for(let n=0;n<e.byteLength;n++)if(e[n]!==t[n])return!1;return!0})(e.bytes,n.bytes)}})(e.multihash,n.multihash)}toString(e){return T(this,e)}toJSON(){return{"/":T(this)}}link(){return this}get[Symbol.toStringTag](){return"CID"}[Symbol.for("nodejs.util.inspect.custom")](){return`CID(${this.toString()})`}static asCID(e){if(null==e)return null;const t=e;if(t instanceof _)return t;if(null!=t["/"]&&t["/"]===t.bytes||t.asCID===t){const{version:e,code:n,multihash:r,bytes:o}=t;return new _(e,n,r,o||q(e,n,r.bytes))}if(!0===t[K]){const{version:e,multihash:n,code:r}=t,o=(e=>{const t=E(e),[n,r]=b(t),[o,i]=b(t.subarray(r)),s=t.subarray(r+i);if(s.byteLength!==o)throw new Error("Incorrect length");return new x(n,o,s,t)})(n);return _.create(e,r,o)}return null}static create(e,t,n){if("number"!=typeof t)throw new Error("String codecs are no longer supported");if(!(n.bytes instanceof Uint8Array))throw new Error("Invalid digest");switch(e){case 0:if(t!==F)throw new Error(`Version 0 CID must use dag-pb (code: ${F}) block encoding`);return new _(e,t,n,n.bytes);case 1:{const r=q(e,t,n.bytes);return new _(e,t,n,r)}default:throw new Error("Invalid version")}}static createV0(e){return _.create(0,F,e)}static createV1(e,t){return _.create(1,e,t)}static decode(e){const[t,n]=_.decodeFirst(e);if(n.length)throw new Error("Incorrect length");return t}static decodeFirst(e){const t=_.inspectBytes(e),n=t.size-t.multihashSize,r=E(e.subarray(n,n+t.multihashSize));if(r.byteLength!==t.multihashSize)throw new Error("Incorrect length");const o=r.subarray(t.multihashSize-t.digestSize),i=new x(t.multihashCode,t.digestSize,o,r);return[0===t.version?_.createV0(i):_.createV1(t.codec,i),e.subarray(t.size)]}static inspectBytes(e){let t=0;const n=()=>{const[n,r]=b(e.subarray(t));return t+=r,n};let r=n(),o=F;if(18===r?(r=0,t=0):o=n(),0!==r&&1!==r)throw new RangeError(`Invalid CID version ${r}`);const i=t,s=n(),a=n(),c=t+a;return{version:r,codec:o,multihashCode:s,digestSize:a,multihashSize:c-i,size:c}}static parse(e,t){const[n,r]=z(e,t),o=_.decode(r);if(0===o.version&&"Q"!==e[0])throw Error("Version 0 CID string must not include multibase prefix");return D(o).set(n,e),o}}const z=(e,t)=>{switch(e[0]){case"Q":{const n=t||N;return[N.prefix,n.decode(`${N.prefix}${e}`)]}case N.prefix:{const n=t||N;return[N.prefix,n.decode(e)]}case O.prefix:{const n=t||O;return[O.prefix,n.decode(e)]}default:if(null==t)throw Error("To parse non base32 or base58btc encoded CID multibase decoder must be provided");return[e[0],t.decode(e)]}},P=(e,t,n)=>{const{prefix:r}=n;if(r!==N.prefix)throw Error(`Cannot string encode V0 in ${n.name} encoding`);const o=t.get(r);if(null==o){const o=n.encode(e).slice(1);return t.set(r,o),o}return o},R=(e,t,n)=>{const{prefix:r}=n,o=t.get(r);if(null==o){const o=n.encode(e);return t.set(r,o),o}return o},F=112,V=18,q=(e,t,n)=>{const r=m(e),o=r+m(t),i=new Uint8Array(o+n.byteLength);return v(e,i,0),v(t,i,r),i.set(n,o),i},K=Symbol.for("@ipld/js-cid/CID"),G=({name:e,code:t,encode:n})=>new W(e,t,n);class W{constructor(e,t,n){this.name=e,this.code=t,this.encode=n}digest(e){if(e instanceof Uint8Array){const t=this.encode(e);return t instanceof Uint8Array?k(this.code,t):t.then((e=>k(this.code,e)))}throw Error("Unknown type, must be binary type")}}function H({enumerable:e=!0,configurable:t=!1}={}){return{enumerable:e,configurable:t,writable:!1}}function*J(e,t){if(null!=t&&"object"==typeof t)if(Array.isArray(t))for(const[n,r]of t.entries()){const t=[...e,n],o=_.asCID(r);o?yield[t.join("/"),o]:"object"==typeof r&&(yield*Q(r,t))}else{const n=_.asCID(t);n?yield[e.join("/"),n]:yield*Q(t,e)}}function*Q(e,t){if(null==e||e instanceof Uint8Array)return;const n=_.asCID(e);n&&(yield[t.join("/"),n]);for(const[n,r]of Object.entries(e)){const e=[...t,n];yield*J(e,r)}}function*Z(e,t){if(Array.isArray(t))for(const[n,r]of t.entries()){const t=[...e,n];yield t.join("/"),"object"!=typeof r||_.asCID(r)||(yield*X(r,t))}else yield*X(t,e)}function*X(e,t){if(null!=e&&"object"==typeof e)for(const[n,r]of Object.entries(e)){const e=[...t,n];yield e.join("/"),null==r||r instanceof Uint8Array||"object"!=typeof r||_.asCID(r)||(yield*Z(e,r))}}class Y{constructor({cid:e,bytes:t,value:n}){if(!e||!t||void 0===n)throw new Error("Missing required argument");this.cid=e,this.bytes=t,this.value=n,this.asBlock=this,Object.defineProperties(this,{cid:H(),bytes:H(),value:H(),asBlock:H()})}links(){return Q(this.value,[])}tree(){return X(this.value,[])}get(e="/"){return function(e,t){let n=e;for(const[e,r]of t.entries()){if(n=n[r],null==n)throw new Error(`Object has no property at ${t.slice(0,e+1).map((e=>`[${JSON.stringify(e)}]`)).join("")}`);const o=_.asCID(n);if(o)return{value:o,remaining:t.slice(e+1).join("/")}}return{value:n}}(this.value,e.split("/").filter(Boolean))}}async function ee({value:e,codec:t,hasher:n}){if(void 0===e)throw new Error('Missing required argument "value"');if(!t||!n)throw new Error("Missing required argument: codec or hasher");const r=t.encode(e),o=await n.digest(r),i=_.create(1,t.code,o);return new Y({value:e,bytes:r,cid:i})}const te=["string","number","bigint","symbol"],ne=["Function","Generator","AsyncGenerator","GeneratorFunction","AsyncGeneratorFunction","AsyncFunction","Observable","Array","Buffer","Object","RegExp","Date","Error","Map","Set","WeakMap","WeakSet","ArrayBuffer","SharedArrayBuffer","DataView","Promise","URL","HTMLElement","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];class re{constructor(e,t,n){this.major=e,this.majorEncoded=e<<5,this.name=t,this.terminal=n}toString(){return`Type[${this.major}].${this.name}`}compare(e){return this.major<e.major?-1:this.major>e.major?1:0}}re.uint=new re(0,"uint",!0),re.negint=new re(1,"negint",!0),re.bytes=new re(2,"bytes",!0),re.string=new re(3,"string",!0),re.array=new re(4,"array",!1),re.map=new re(5,"map",!1),re.tag=new re(6,"tag",!1),re.float=new re(7,"float",!0),re.false=new re(7,"false",!0),re.true=new re(7,"true",!0),re.null=new re(7,"null",!0),re.undefined=new re(7,"undefined",!0),re.break=new re(7,"break",!0);class oe{constructor(e,t,n){this.type=e,this.value=t,this.encodedLength=n,this.encodedBytes=void 0,this.byteValue=void 0}toString(){return`Token[${this.type}].${this.value}`}}const ie=globalThis.process&&!globalThis.process.browser&&globalThis.Buffer&&"function"==typeof globalThis.Buffer.isBuffer,se=new TextDecoder,ae=new TextEncoder;function ce(e){return ie&&globalThis.Buffer.isBuffer(e)}function ue(e){return e instanceof Uint8Array?ce(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):e:Uint8Array.from(e)}const fe=ie?(e,t,n)=>n-t>64?globalThis.Buffer.from(e.subarray(t,n)).toString("utf8"):ge(e,t,n):(e,t,n)=>n-t>64?se.decode(e.subarray(t,n)):ge(e,t,n),he=ie?e=>e.length>64?globalThis.Buffer.from(e):we(e):e=>e.length>64?ae.encode(e):we(e),le=e=>Uint8Array.from(e),de=ie?(e,t,n)=>ce(e)?new Uint8Array(e.subarray(t,n)):e.slice(t,n):(e,t,n)=>e.slice(t,n),pe=ie?(e,t)=>(e=e.map((e=>e instanceof Uint8Array?e:globalThis.Buffer.from(e))),ue(globalThis.Buffer.concat(e,t))):(e,t)=>{const n=new Uint8Array(t);let r=0;for(let t of e)r+t.length>n.length&&(t=t.subarray(0,n.length-r)),n.set(t,r),r+=t.length;return n},ye=ie?e=>globalThis.Buffer.allocUnsafe(e):e=>new Uint8Array(e);function we(e,t=1/0){let n;const r=e.length;let o=null;const i=[];for(let s=0;s<r;++s){if(n=e.charCodeAt(s),n>55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(s+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function ge(e,t,n){const r=[];for(;t<n;){const o=e[t];let i=null,s=o>239?4:o>223?3:o>191?2:1;if(t+s<=n){let n,r,a,c;switch(s){case 1:o<128&&(i=o);break;case 2:n=e[t+1],128==(192&n)&&(c=(31&o)<<6|63&n,c>127&&(i=c));break;case 3:n=e[t+1],r=e[t+2],128==(192&n)&&128==(192&r)&&(c=(15&o)<<12|(63&n)<<6|63&r,c>2047&&(c<55296||c>57343)&&(i=c));break;case 4:n=e[t+1],r=e[t+2],a=e[t+3],128==(192&n)&&128==(192&r)&&128==(192&a)&&(c=(15&o)<<18|(63&n)<<12|(63&r)<<6|63&a,c>65535&&c<1114112&&(i=c))}}null===i?(i=65533,s=1):i>65535&&(i-=65536,r.push(i>>>10&1023|55296),i=56320|1023&i),r.push(i),t+=s}return function(e){const t=e.length;if(t<=be)return String.fromCharCode.apply(String,e);let n="",r=0;for(;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=be));return n}(r)}const be=4096;class ve{constructor(e=256){this.chunkSize=e,this.cursor=0,this.maxCursor=-1,this.chunks=[],this._initReuseChunk=null}reset(){this.cursor=0,this.maxCursor=-1,this.chunks.length&&(this.chunks=[]),null!==this._initReuseChunk&&(this.chunks.push(this._initReuseChunk),this.maxCursor=this._initReuseChunk.length-1)}push(e){let t=this.chunks[this.chunks.length-1];if(this.cursor+e.length<=this.maxCursor+1){const n=t.length-(this.maxCursor-this.cursor)-1;t.set(e,n)}else{if(t){const e=t.length-(this.maxCursor-this.cursor)-1;e<t.length&&(this.chunks[this.chunks.length-1]=t.subarray(0,e),this.maxCursor=this.cursor-1)}e.length<64&&e.length<this.chunkSize?(t=ye(this.chunkSize),this.chunks.push(t),this.maxCursor+=t.length,null===this._initReuseChunk&&(this._initReuseChunk=t),t.set(e,0)):(this.chunks.push(e),this.maxCursor+=e.length)}this.cursor+=e.length}toBytes(e=!1){let t;if(1===this.chunks.length){const n=this.chunks[0];e&&this.cursor>n.length/2?(t=this.cursor===n.length?n:n.subarray(0,this.cursor),this._initReuseChunk=null,this.chunks=[]):t=de(n,0,this.cursor)}else t=pe(this.chunks,this.cursor);return e&&this.reset(),t}}const me="CBOR decode error:",Ee="CBOR encode error:",ke=[];function xe(e,t,n){if(e.length-t<n)throw new Error(`${me} not enough data for type`)}ke[23]=1,ke[24]=2,ke[25]=3,ke[26]=5,ke[27]=9;const Ae=[24,256,65536,4294967296,BigInt("18446744073709551616")];function Ce(e,t,n){xe(e,t,1);const r=e[t];if(!0===n.strict&&r<Ae[0])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function je(e,t,n){xe(e,t,2);const r=e[t]<<8|e[t+1];if(!0===n.strict&&r<Ae[1])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function Se(e,t,n){xe(e,t,4);const r=16777216*e[t]+(e[t+1]<<16)+(e[t+2]<<8)+e[t+3];if(!0===n.strict&&r<Ae[2])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);return r}function Ie(e,t,n){xe(e,t,8);const r=16777216*e[t]+(e[t+1]<<16)+(e[t+2]<<8)+e[t+3],o=16777216*e[t+4]+(e[t+5]<<16)+(e[t+6]<<8)+e[t+7],i=(BigInt(r)<<BigInt(32))+BigInt(o);if(!0===n.strict&&i<Ae[3])throw new Error(`${me} integer encoded in more bytes than necessary (strict decode)`);if(i<=Number.MAX_SAFE_INTEGER)return Number(i);if(!0===n.allowBigInt)return i;throw new Error(`${me} integers outside of the safe integer range are not supported`)}function Ue(e,t){return $e(e,0,t.value)}function $e(e,t,n){if(n<Ae[0]){const r=Number(n);e.push([t|r])}else if(n<Ae[1]){const r=Number(n);e.push([24|t,r])}else if(n<Ae[2]){const r=Number(n);e.push([25|t,r>>>8,255&r])}else if(n<Ae[3]){const r=Number(n);e.push([26|t,r>>>24&255,r>>>16&255,r>>>8&255,255&r])}else{const r=BigInt(n);if(!(r<Ae[4]))throw new Error(`${me} encountered BigInt larger than allowable range`);{const n=[27|t,0,0,0,0,0,0,0];let o=Number(r&BigInt(4294967295)),i=Number(r>>BigInt(32)&BigInt(4294967295));n[8]=255&o,o>>=8,n[7]=255&o,o>>=8,n[6]=255&o,o>>=8,n[5]=255&o,n[4]=255&i,i>>=8,n[3]=255&i,i>>=8,n[2]=255&i,i>>=8,n[1]=255&i,e.push(n)}}}Ue.encodedSize=function(e){return $e.encodedSize(e.value)},$e.encodedSize=function(e){return e<Ae[0]?1:e<Ae[1]?2:e<Ae[2]?3:e<Ae[3]?5:9},Ue.compareTokens=function(e,t){return e.value<t.value?-1:e.value>t.value?1:0};const Le=BigInt(-1),Be=BigInt(1);function Ne(e,t){const n=t.value,r="bigint"==typeof n?n*Le-Be:-1*n-1;$e(e,t.type.majorEncoded,r)}function Oe(e,t,n,r){xe(e,t,n+r);const o=de(e,t+n,t+n+r);return new oe(re.bytes,o,n+r)}function Te(e,t,n,r){return Oe(e,t,1,n)}function Me(e){return void 0===e.encodedBytes&&(e.encodedBytes=e.type===re.string?he(e.value):e.value),e.encodedBytes}function De(e,t){const n=Me(t);$e(e,t.type.majorEncoded,n.length),e.push(n)}function _e(e,t,n,r,o){const i=n+r;xe(e,t,i);const s=new oe(re.string,fe(e,t+n,t+i),i);return!0===o.retainStringBytes&&(s.byteValue=de(e,t+n,t+i)),s}function ze(e,t,n,r){return _e(e,t,1,n,r)}Ne.encodedSize=function(e){const t=e.value,n="bigint"==typeof t?t*Le-Be:-1*t-1;return n<Ae[0]?1:n<Ae[1]?2:n<Ae[2]?3:n<Ae[3]?5:9},Ne.compareTokens=function(e,t){return e.value<t.value?1:e.value>t.value?-1:0},De.encodedSize=function(e){const t=Me(e);return $e.encodedSize(t.length)+t.length},De.compareTokens=function(e,t){return n=Me(e),r=Me(t),n.length<r.length?-1:n.length>r.length?1:function(e,t){if(ce(e)&&ce(t))return e.compare(t);for(let n=0;n<e.length;n++)if(e[n]!==t[n])return e[n]<t[n]?-1:1;return 0}(n,r);var n,r};const Pe=De;function Re(e,t,n,r){return new oe(re.array,r,n)}function Fe(e,t,n,r){return Re(0,0,1,n)}function Ve(e,t){$e(e,re.array.majorEncoded,t.value)}function qe(e,t,n,r){return new oe(re.map,r,n)}function Ke(e,t,n,r){return qe(0,0,1,n)}function Ge(e,t){$e(e,re.map.majorEncoded,t.value)}function We(e,t,n,r){return new oe(re.tag,n,1)}function He(e,t){$e(e,re.tag.majorEncoded,t.value)}function Je(e,t,n){if(n){if(!1===n.allowNaN&&Number.isNaN(e))throw new Error(`${me} NaN values are not supported`);if(!1===n.allowInfinity&&(e===1/0||e===-1/0))throw new Error(`${me} Infinity values are not supported`)}return new oe(re.float,e,t)}function Qe(e,t,n){const r=t.value;if(!1===r)e.push([20|re.float.majorEncoded]);else if(!0===r)e.push([21|re.float.majorEncoded]);else if(null===r)e.push([22|re.float.majorEncoded]);else if(void 0===r)e.push([23|re.float.majorEncoded]);else{let t,i=!1;n&&!0===n.float64||(et(r),t=tt(Ye,1),r===t||Number.isNaN(r)?(Ye[0]=249,e.push(Ye.slice(0,3)),i=!0):(nt(r),t=rt(Ye,1),r===t&&(Ye[0]=250,e.push(Ye.slice(0,5)),i=!0))),i||(o=r,Xe.setFloat64(0,o,!1),t=ot(Ye,1),Ye[0]=251,e.push(Ye.slice(0,9)))}var o}Ve.compareTokens=Ue.compareTokens,Ve.encodedSize=function(e){return $e.encodedSize(e.value)},Ge.compareTokens=Ue.compareTokens,Ge.encodedSize=function(e){return $e.encodedSize(e.value)},He.compareTokens=Ue.compareTokens,He.encodedSize=function(e){return $e.encodedSize(e.value)},Qe.encodedSize=function(e,t){const n=e.value;if(!1===n||!0===n||null==n)return 1;if(!t||!0!==t.float64){et(n);let e=tt(Ye,1);if(n===e||Number.isNaN(n))return 3;if(nt(n),e=rt(Ye,1),n===e)return 5}return 9};const Ze=new ArrayBuffer(9),Xe=new DataView(Ze,1),Ye=new Uint8Array(Ze,0);function et(e){if(e===1/0)Xe.setUint16(0,31744,!1);else if(e===-1/0)Xe.setUint16(0,64512,!1);else if(Number.isNaN(e))Xe.setUint16(0,32256,!1);else{Xe.setFloat32(0,e);const t=Xe.getUint32(0),n=(2139095040&t)>>23,r=8388607&t;if(255===n)Xe.setUint16(0,31744,!1);else if(0===n)Xe.setUint16(0,(2147483648&e)>>16|r>>13,!1);else{const e=n-127;e<-24?Xe.setUint16(0,0):e<-14?Xe.setUint16(0,(2147483648&t)>>16|1<<24+e,!1):Xe.setUint16(0,(2147483648&t)>>16|e+15<<10|r>>13,!1)}}}function tt(e,t){if(e.length-t<2)throw new Error(`${me} not enough data for float16`);const n=(e[t]<<8)+e[t+1];if(31744===n)return 1/0;if(64512===n)return-1/0;if(32256===n)return NaN;const r=n>>10&31,o=1023&n;let i;return i=0===r?o*2**-24:31!==r?(o+1024)*2**(r-25):0===o?1/0:NaN,32768&n?-i:i}function nt(e){Xe.setFloat32(0,e,!1)}function rt(e,t){if(e.length-t<4)throw new Error(`${me} not enough data for float32`);const n=(e.byteOffset||0)+t;return new DataView(e.buffer,n,4).getFloat32(0,!1)}function ot(e,t){if(e.length-t<8)throw new Error(`${me} not enough data for float64`);const n=(e.byteOffset||0)+t;return new DataView(e.buffer,n,8).getFloat64(0,!1)}function it(e,t,n){throw new Error(`${me} encountered invalid minor (${n}) for major ${e[t]>>>5}`)}function st(e){return()=>{throw new Error(`${me} ${e}`)}}Qe.compareTokens=Ue.compareTokens;const at=[];for(let e=0;e<=23;e++)at[e]=it;at[24]=function(e,t,n,r){return new oe(re.uint,Ce(e,t+1,r),2)},at[25]=function(e,t,n,r){return new oe(re.uint,je(e,t+1,r),3)},at[26]=function(e,t,n,r){return new oe(re.uint,Se(e,t+1,r),5)},at[27]=function(e,t,n,r){return new oe(re.uint,Ie(e,t+1,r),9)},at[28]=it,at[29]=it,at[30]=it,at[31]=it;for(let e=32;e<=55;e++)at[e]=it;at[56]=function(e,t,n,r){return new oe(re.negint,-1-Ce(e,t+1,r),2)},at[57]=function(e,t,n,r){return new oe(re.negint,-1-je(e,t+1,r),3)},at[58]=function(e,t,n,r){return new oe(re.negint,-1-Se(e,t+1,r),5)},at[59]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"!=typeof o){const e=-1-o;if(e>=Number.MIN_SAFE_INTEGER)return new oe(re.negint,e,9)}if(!0!==r.allowBigInt)throw new Error(`${me} integers outside of the safe integer range are not supported`);return new oe(re.negint,Le-BigInt(o),9)},at[60]=it,at[61]=it,at[62]=it,at[63]=it;for(let e=64;e<=87;e++)at[e]=Te;at[88]=function(e,t,n,r){return Oe(e,t,2,Ce(e,t+1,r))},at[89]=function(e,t,n,r){return Oe(e,t,3,je(e,t+1,r))},at[90]=function(e,t,n,r){return Oe(e,t,5,Se(e,t+1,r))},at[91]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer bytes lengths not supported`);return Oe(e,t,9,o)},at[92]=it,at[93]=it,at[94]=it,at[95]=st("indefinite length bytes/strings are not supported");for(let e=96;e<=119;e++)at[e]=ze;at[120]=function(e,t,n,r){return _e(e,t,2,Ce(e,t+1,r),r)},at[121]=function(e,t,n,r){return _e(e,t,3,je(e,t+1,r),r)},at[122]=function(e,t,n,r){return _e(e,t,5,Se(e,t+1,r),r)},at[123]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer string lengths not supported`);return _e(e,t,9,o,r)},at[124]=it,at[125]=it,at[126]=it,at[127]=st("indefinite length bytes/strings are not supported");for(let e=128;e<=151;e++)at[e]=Fe;at[152]=function(e,t,n,r){return Re(0,0,2,Ce(e,t+1,r))},at[153]=function(e,t,n,r){return Re(0,0,3,je(e,t+1,r))},at[154]=function(e,t,n,r){return Re(0,0,5,Se(e,t+1,r))},at[155]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer array lengths not supported`);return Re(0,0,9,o)},at[156]=it,at[157]=it,at[158]=it,at[159]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return Re(0,0,1,1/0)};for(let e=160;e<=183;e++)at[e]=Ke;at[184]=function(e,t,n,r){return qe(0,0,2,Ce(e,t+1,r))},at[185]=function(e,t,n,r){return qe(0,0,3,je(e,t+1,r))},at[186]=function(e,t,n,r){return qe(0,0,5,Se(e,t+1,r))},at[187]=function(e,t,n,r){const o=Ie(e,t+1,r);if("bigint"==typeof o)throw new Error(`${me} 64-bit integer map lengths not supported`);return qe(0,0,9,o)},at[188]=it,at[189]=it,at[190]=it,at[191]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return qe(0,0,1,1/0)};for(let e=192;e<=215;e++)at[e]=We;at[216]=function(e,t,n,r){return new oe(re.tag,Ce(e,t+1,r),2)},at[217]=function(e,t,n,r){return new oe(re.tag,je(e,t+1,r),3)},at[218]=function(e,t,n,r){return new oe(re.tag,Se(e,t+1,r),5)},at[219]=function(e,t,n,r){return new oe(re.tag,Ie(e,t+1,r),9)},at[220]=it,at[221]=it,at[222]=it,at[223]=it;for(let e=224;e<=243;e++)at[e]=st("simple values are not supported");at[244]=it,at[245]=it,at[246]=it,at[247]=function(e,t,n,r){if(!1===r.allowUndefined)throw new Error(`${me} undefined values are not supported`);return!0===r.coerceUndefinedToNull?new oe(re.null,null,1):new oe(re.undefined,void 0,1)},at[248]=st("simple values are not supported"),at[249]=function(e,t,n,r){return Je(tt(e,t+1),3,r)},at[250]=function(e,t,n,r){return Je(rt(e,t+1),5,r)},at[251]=function(e,t,n,r){return Je(ot(e,t+1),9,r)},at[252]=it,at[253]=it,at[254]=it,at[255]=function(e,t,n,r){if(!1===r.allowIndefinite)throw new Error(`${me} indefinite length items not allowed`);return new oe(re.break,void 0,1)};const ct=[];for(let e=0;e<24;e++)ct[e]=new oe(re.uint,e,1);for(let e=-1;e>=-24;e--)ct[31-e]=new oe(re.negint,e,1);ct[64]=new oe(re.bytes,new Uint8Array(0),1),ct[96]=new oe(re.string,"",1),ct[128]=new oe(re.array,0,1),ct[160]=new oe(re.map,0,1),ct[244]=new oe(re.false,!1,1),ct[245]=new oe(re.true,!0,1),ct[246]=new oe(re.null,null,1);const ut={float64:!1,mapSorter:function(e,t){const n=Array.isArray(e[0])?e[0][0]:e[0],r=Array.isArray(t[0])?t[0][0]:t[0];if(n.type!==r.type)return n.type.compare(r.type);const o=n.type.major,i=ft[o].compareTokens(n,r);return 0===i&&console.warn("WARNING: complex key types used, CBOR key sorting guarantees are gone"),i},quickEncodeToken:function(e){switch(e.type){case re.false:return le([244]);case re.true:return le([245]);case re.null:return le([246]);case re.bytes:return e.value.length?void 0:le([64]);case re.string:return""===e.value?le([96]):void 0;case re.array:return 0===e.value?le([128]):void 0;case re.map:return 0===e.value?le([160]):void 0;case re.uint:return e.value<24?le([Number(e.value)]):void 0;case re.negint:if(e.value>=-24)return le([31-Number(e.value)])}}},ft=function(){const e=[];return e[re.uint.major]=Ue,e[re.negint.major]=Ne,e[re.bytes.major]=De,e[re.string.major]=Pe,e[re.array.major]=Ve,e[re.map.major]=Ge,e[re.tag.major]=He,e[re.float.major]=Qe,e}(),ht=new ve;class lt{constructor(e,t){this.obj=e,this.parent=t}includes(e){let t=this;do{if(t.obj===e)return!0}while(t=t.parent);return!1}static createCheck(e,t){if(e&&e.includes(t))throw new Error(`${Ee} object contains circular references`);return new lt(t,e)}}const dt={null:new oe(re.null,null),undefined:new oe(re.undefined,void 0),true:new oe(re.true,!0),false:new oe(re.false,!1),emptyArray:new oe(re.array,0),emptyMap:new oe(re.map,0)},pt={number:(e,t,n,r)=>Number.isInteger(e)&&Number.isSafeInteger(e)?new oe(e>=0?re.uint:re.negint,e):new oe(re.float,e),bigint:(e,t,n,r)=>e>=BigInt(0)?new oe(re.uint,e):new oe(re.negint,e),Uint8Array:(e,t,n,r)=>new oe(re.bytes,e),string:(e,t,n,r)=>new oe(re.string,e),boolean:(e,t,n,r)=>e?dt.true:dt.false,null:(e,t,n,r)=>dt.null,undefined:(e,t,n,r)=>dt.undefined,ArrayBuffer:(e,t,n,r)=>new oe(re.bytes,new Uint8Array(e)),DataView:(e,t,n,r)=>new oe(re.bytes,new Uint8Array(e.buffer,e.byteOffset,e.byteLength)),Array(e,t,n,r){if(!e.length)return!0===n.addBreakTokens?[dt.emptyArray,new oe(re.break)]:dt.emptyArray;r=lt.createCheck(r,e);const o=[];let i=0;for(const t of e)o[i++]=yt(t,n,r);return n.addBreakTokens?[new oe(re.array,e.length),o,new oe(re.break)]:[new oe(re.array,e.length),o]},Object(e,t,n,r){const o="Object"!==t,i=o?e.keys():Object.keys(e),s=o?e.size:i.length;if(!s)return!0===n.addBreakTokens?[dt.emptyMap,new oe(re.break)]:dt.emptyMap;r=lt.createCheck(r,e);const a=[];let c=0;for(const t of i)a[c++]=[yt(t,n,r),yt(o?e.get(t):e[t],n,r)];return function(e,t){t.mapSorter&&e.sort(t.mapSorter)}(a,n),n.addBreakTokens?[new oe(re.map,s),a,new oe(re.break)]:[new oe(re.map,s),a]}};pt.Map=pt.Object,pt.Buffer=pt.Uint8Array;for(const e of"Uint8Clamped Uint16 Uint32 Int8 Int16 Int32 BigUint64 BigInt64 Float32 Float64".split(" "))pt[`${e}Array`]=pt.DataView;function yt(e,t={},n){const r=function(e){if(null===e)return"null";if(void 0===e)return"undefined";if(!0===e||!1===e)return"boolean";const t=typeof e;if(te.includes(t))return t;if("function"===t)return"Function";if(Array.isArray(e))return"Array";if(function(e){return e&&e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer.call(null,e)}(e))return"Buffer";return function(e){const t=Object.prototype.toString.call(e).slice(8,-1);if(ne.includes(t))return t}(e)||"Object"}(e),o=t&&t.typeEncoders&&t.typeEncoders[r]||pt[r];if("function"==typeof o){const i=o(e,r,t,n);if(null!=i)return i}const i=pt[r];if(!i)throw new Error(`${Ee} unsupported type: ${r}`);return i(e,r,t,n)}function wt(e,t,n,r){if(Array.isArray(t))for(const o of t)wt(e,o,n,r);else n[t.type.major](e,t,r)}function gt(e,t,n){const r=yt(e,n);if(!Array.isArray(r)&&n.quickEncodeToken){const e=n.quickEncodeToken(r);if(e)return e;const o=t[r.type.major];if(o.encodedSize){const e=o.encodedSize(r,n),t=new ve(e);if(o(t,r,n),1!==t.chunks.length)throw new Error(`Unexpected error: pre-calculated length for ${r} was wrong`);return ue(t.chunks[0])}}return ht.reset(),wt(ht,r,t,n),ht.toBytes(!0)}const bt={strict:!1,allowIndefinite:!0,allowUndefined:!0,allowBigInt:!0};class vt{constructor(e,t={}){this.pos=0,this.data=e,this.options=t}done(){return this.pos>=this.data.length}next(){const e=this.data[this.pos];let t=ct[e];if(void 0===t){const n=at[e];if(!n)throw new Error(`${me} no decoder for major type ${e>>>5} (byte 0x${e.toString(16).padStart(2,"0")})`);const r=31&e;t=n(this.data,this.pos,r,this.options)}return this.pos+=t.encodedLength,t}}const mt=Symbol.for("DONE"),Et=Symbol.for("BREAK");function kt(e,t){if(e.done())return mt;const n=e.next();if(n.type===re.break)return Et;if(n.type.terminal)return n.value;if(n.type===re.array)return function(e,t,n){const r=[];for(let o=0;o<e.value;o++){const i=kt(t,n);if(i===Et){if(e.value===1/0)break;throw new Error(`${me} got unexpected break to lengthed array`)}if(i===mt)throw new Error(`${me} found array but not enough entries (got ${o}, expected ${e.value})`);r[o]=i}return r}(n,e,t);if(n.type===re.map)return function(e,t,n){const r=!0===n.useMaps,o=r?void 0:{},i=r?new Map:void 0;for(let s=0;s<e.value;s++){const a=kt(t,n);if(a===Et){if(e.value===1/0)break;throw new Error(`${me} got unexpected break to lengthed map`)}if(a===mt)throw new Error(`${me} found map but not enough entries (got ${s} [no key], expected ${e.value})`);if(!0!==r&&"string"!=typeof a)throw new Error(`${me} non-string keys not supported (got ${typeof a})`);if(!0===n.rejectDuplicateMapKeys&&(r&&i.has(a)||!r&&a in o))throw new Error(`${me} found repeat map key "${a}"`);const c=kt(t,n);if(c===mt)throw new Error(`${me} found map but not enough entries (got ${s} [no value], expected ${e.value})`);r?i.set(a,c):o[a]=c}return r?i:o}(n,e,t);if(n.type===re.tag){if(t.tags&&"function"==typeof t.tags[n.value]){const r=kt(e,t);return t.tags[n.value](r)}throw new Error(`${me} tag not supported (${n.value})`)}throw new Error("unsupported")}const xt={float64:!0,typeEncoders:{Object:function(e){if(e.asCID!==e&&e["/"]!==e.bytes)return null;const t=_.asCID(e);if(!t)return null;const n=new Uint8Array(t.bytes.byteLength+1);return n.set(t.bytes,1),[new oe(re.tag,42),new oe(re.bytes,n)]},undefined:function(){throw new Error("`undefined` is not supported by the IPLD Data Model and cannot be encoded")},number:function(e){if(Number.isNaN(e))throw new Error("`NaN` is not supported by the IPLD Data Model and cannot be encoded");if(e===1/0||e===-1/0)throw new Error("`Infinity` and `-Infinity` is not supported by the IPLD Data Model and cannot be encoded");return null}}},At={allowIndefinite:!1,coerceUndefinedToNull:!0,allowNaN:!1,allowInfinity:!1,allowBigInt:!0,strict:!0,useMaps:!1,rejectDuplicateMapKeys:!0,tags:[]};At.tags[42]=function(e){if(0!==e[0])throw new Error("Invalid CID for CBOR tag 42; expected leading 0x00");return _.decode(e.subarray(1))};const Ct="dag-cbor",jt=113,St=e=>{return t=e,n=xt,n=Object.assign({},ut,n),gt(t,ft,n);var t,n},It=e=>function(e,t){if(!(e instanceof Uint8Array))throw new Error(`${me} data to decode must be a Uint8Array`);const n=(t=Object.assign({},bt,t)).tokenizer||new vt(e,t),r=kt(n,t);if(r===mt)throw new Error(`${me} did not find any content to decode`);if(r===Et)throw new Error(`${me} got unexpected break`);if(!n.done())throw new Error(`${me} too many terminals, data makes no sense`);return r}(e,At),Ut=e=>async t=>new Uint8Array(await crypto.subtle.digest(e,t)),$t=G({name:"sha2-256",code:18,encode:Ut("SHA-256")}),Lt=(G({name:"sha2-512",code:19,encode:Ut("SHA-512")}),e),Bt=$t,Nt=N,Ot=e=>e&&void 0!==e.id&&void 0!==e.next&&void 0!==e.payload&&void 0!==e.v&&void 0!==e.clock&&void 0!==e.refs,Tt=async e=>{const{cid:t,bytes:n}=await ee({value:e,codec:Lt,hasher:Bt}),r=t.toString(Nt),o=new i(e.clock.id,e.clock.time);return{...e,clock:o,hash:r,bytes:n}},Mt={create:async(e,t,n,r=null,o=[],a=[])=>{if(!s(e))throw new Error("Identity is required, cannot create entry");if(!s(t))throw new Error("Entry requires an id");if(!s(n))throw new Error("Entry requires a payload");if(!s(o)||!Array.isArray(o))throw new Error("'next' argument is not an array");const c={id:t,payload:n,next:o,refs:a,clock:r=r||new i(e.publicKey),v:2},{bytes:u}=await ee({value:c,codec:Lt,hasher:Bt}),f=await e.provider.sign(e,u);return c.key=e.publicKey,c.identity=e.toJSON(),c.sig=f,Tt(c)},verify:async(e,t)=>{if(!e)throw new Error("Identity-provider is required, cannot verify entry");if(!Ot(t))throw new Error("Invalid Log entry");if(!t.key)throw new Error("Entry doesn't have a key");if(!t.sig)throw new Error("Entry doesn't have a signature");const n={id:t.id,payload:t.payload,next:t.next,refs:t.refs,clock:t.clock,v:t.v},{bytes:r}=await ee({value:n,codec:Lt,hasher:Bt});return e.verify(t.sig,t.key,r)},decode:async e=>{const{value:t}=await async function({bytes:e,codec:t,hasher:n}){if(!e)throw new Error('Missing required argument "bytes"');if(!t||!n)throw new Error("Missing required argument: codec or hasher");const r=t.decode(e),o=await n.digest(e),i=_.create(1,t.code,o);return new Y({value:r,bytes:e,cid:i})}({bytes:e,codec:Lt,hasher:Bt});return Tt(t)},isEntry:Ot,isEqual:(e,t)=>e&&t&&e.hash===t.hash};function Dt(e,t,n){const r=i.compare(e.clock,t.clock);return 0===r?n(e,t):r}function _t(e,t,n){return e.clock.id===t.clock.id?n(e,t):e.clock.id<t.clock.id?-1:1}const zt={SortByClocks:Dt,SortByClockId:_t,LastWriteWins:function(e,t){const n=(e,t)=>e,r=(e,t)=>_t(e,t,n);return((e,t)=>Dt(e,t,r))(e,t)},NoZeroes:function(e){const t=`Your log's tiebreaker function, ${e.name}, has returned zero and therefore cannot be`;return(n,r)=>{const o=e(n,r);if(0===o)throw Error(t);return o}}},Pt=async({ipfs:e,timeout:t,pin:n})=>(t=t||3e4,{put:async(r,o)=>{const i=_.parse(r,N);await e.block.put(o,{cid:i.bytes,version:i.version,format:"dag-cbor",mhtype:"sha2-256",pin:n,timeout:t})},get:async n=>{const r=_.parse(n,N),o=await e.block.get(r,{timeout:t});if(o)return o},iterator:async function*(){},merge:async e=>{},clear:async()=>{},close:async()=>{}}),Rt=async()=>{let e={};const t=async(t,n)=>{e[t]=n};return{put:t,get:async t=>{if(e[t])return e[t]},iterator:async function*(){for await(const[t,n]of Object.entries(e))yield[t,n]},merge:async e=>{if(e)for await(const[n,r]of e.iterator())t(n,r)},clear:async()=>e={},close:async()=>{}}},Ft=1e6,Vt=async({size:e}={})=>{let n=new t(e||Ft);return{put:async(e,t)=>{n.set(e,t)},get:async e=>{if(n.peek(e))return n.get(e)},iterator:async function*(){for await(const e of n.keys){const t=n.get(e);yield[e,t]}},merge:async e=>{if(e)for await(const[t,r]of e.iterator())n.set(t,r)},clear:async()=>{n=new t(e||Ft)},close:async()=>{}}},qt=async(...e)=>({put:async(t,n)=>{for await(const r of e)await r.put(t,n)},get:async t=>{for await(const n of e){const e=await n.get(t);if(e)return e}},iterator:async function*(){return e[0].iterator()},merge:async t=>{for await(const t of e)for await(const n of e)await t.merge(n)},clear:async()=>{for await(const t of e)await t.clear()},close:async()=>{for await(const t of e)await t.close()}}),{LastWriteWins:Kt,NoZeroes:Gt}=zt,Wt=(e,t)=>Math.max(e,t.clock.time),Ht=Rt,Jt=async()=>({canAppend:async(e,t)=>!0}),Qt=async(e,{logId:n,logHeads:r,access:o,storage:a,stateStorage:c,sortFn:u}={})=>{if(!s(e))throw new Error("Identity is required");if(s(r)&&!Array.isArray(r))throw new Error("'logHeads' argument must be an array");const f=n||(new Date).getTime().toString();o=o||await Jt(),a=a||await Ht(),c=c||await Ht();const h=Zt(new Set(r||[]));for(const e of h)await c.put(e.hash,!0);u=Gt(u||Kt);const l=async()=>{const t=Math.max(0,(await d()).reduce(Wt,0));return new i(e.publicKey,t)},d=async()=>{const e=[];for await(const[t]of c.iterator())if(t){const n=await p(t);n&&e.push(n)}return e.sort(u).reverse()},p=async e=>{const t=await a.get(e);if(t)return await Mt.decode(t)},y=async t=>{const n=e.provider;if(t.id!==f)throw new Error(`Entry's id (${t.id}) doesn't match the log's id (${f}).`);const r=await d();if(r.find((e=>e.hash===t.hash)))return;if(!await o.canAppend(t,n))throw new Error(`Could not append entry:\nKey "${t.identity.id}" is not allowed to write to the log`);if(!await Mt.verify(n,t))throw new Error(`Could not validate signature for entry "${t.hash}"`);const i=Zt(new Set([...r,t]));await c.clear();for(const e of i)await c.put(e.hash,!0);return await a.put(t.hash,t.bytes),!0},w=async function*(e,t){t=t||(()=>!1);let n=(e=e||await d()).sort(u);const r={};let o;for(;n.length>0&&!0!==await t(o);)if(o=n.pop(),o&&!r[o.hash]){r[o.hash]=!0,yield o;for(const e of[...o.next,...o.refs])if(!r[e]){const t=await p(e);t&&(n=[t,...n].sort(u))}}};return{id:f,clock:l,heads:d,values:async()=>{const e=[];for await(const t of w())e.unshift(t);return e},get:p,append:async(t,n={pointerCount:1})=>{const r=await(async(e=1)=>{let t=2,n=0;const r=[],o=()=>n>=e;for await(const e of w(null,o))n++,n===t&&(e.hash&&r.push(e.hash),t*=2);return r})(n.pointerCount),i=(await d()).map((e=>e.hash)),s=await Mt.create(e,f,t,(await l()).tick(),i,r);if(!await o.canAppend(s,e.provider))throw new Error(`Could not append entry:\nKey "${e.id}" is not allowed to write to the log`);return await c.clear(),await c.put(s.hash,!0),await a.put(s.hash,s.bytes),s},join:async e=>{if(!e)throw new Error("Log instance not defined");if(!(t=e)||void 0===t.id||void 0===t.clock||void 0===t.heads||void 0===t.values||void 0===t.access||void 0===t.identity||void 0===t.storage)throw new Error("Given argument is not an instance of Log");var t;const n=await e.heads();for(const e of n)await y(e);a.merge&&await a.merge(e.storage)},joinEntry:y,traverse:w,iterator:async function*({amount:e=-1,gt:n,gte:r,lt:o,lte:i}={}){if(0===e)return;if("string"==typeof i&&(i=[await p(i)]),"string"==typeof o){const e=await p(o);o=await Promise.all(e.next.map((e=>p(e))))}if(s(o)&&!Array.isArray(o))throw new Error("lt must be a string or an array of Entries");if(s(i)&&!Array.isArray(i))throw new Error("lte must be a string or an array of Entries");const a=(o||i||await d()).filter(s),c=n||r?await p(n||r):null,u=c||-1===e?-1:i||o?e-1:e;let f=0;const h=c&&-1!==e&&!o&&!i,l=h?new t(e+2):null;let y=0;const g=w(a,(async e=>!!e&&(f>=u&&-1!==u||!(!c||!Mt.isEqual(e,c))||(f++,!1))));for await(const e of g){const t=o&&Mt.isEqual(e,a),r=n&&Mt.isEqual(e,c);t||r||(h?l.set(y++,e.hash):yield e)}if(h){const t=l.keys.length-1,n=t-e,r=l.keys.slice(n,t);for(const e of r){const t=l.get(e),n=await p(t);yield n}}},access:o,identity:e,storage:a}},Zt=e=>{const t={};for(const n of e)for(const e of n.next)t[e]=n.hash;const n=[];for(const r of e)t[r.hash]||n.push(r);return n}})(),Log=r})(); \ No newline at end of file diff --git a/src/database.js b/src/database.js index 3fd2b37..d697256 100644 --- a/src/database.js +++ b/src/database.js @@ -2,14 +2,14 @@ import { Level } from 'level' import { EventEmitter } from 'events' const valueEncoding = 'view' -const defaultPointerCount = 64 +const defaultPointerCount = 16 const Database = async ({ OpLog, ipfs, identity, databaseId, accessController, storage }) => { const { Log, Entry, IPFSBlockStorage } = OpLog storage = storage || await IPFSBlockStorage({ ipfs, pin: true }) - const path = `./${identity.id}/${databaseId}_state` + const path = `./${identity.id}/${databaseId}/_state` const stateStorage = new Level(path, { valueEncoding }) await stateStorage.open() @@ -26,23 +26,26 @@ const Database = async ({ OpLog, ipfs, identity, databaseId, accessController, s const handleMessage = async (message) => { const { id: peerId } = await ipfs.id() - const messageIsFromMe = (message) => String(peerId) === String(message.from) + const messageIsNotFromMe = (message) => String(peerId) !== String(message.from) + const messageHasData = (message) => message.data !== undefined try { - if (!messageIsFromMe(message)) { + if (messageIsNotFromMe(message) && messageHasData(message)) { await sync(message.data) } } catch (e) { events.emit('error', e) - // console.error(e) + console.error(e) } } const sync = async (bytes) => { const entry = await Entry.decode(bytes) - events.emit('sync', entry) - const updated = await log.joinEntry(entry) - if (updated) { - events.emit('update', entry) + if (entry) { + events.emit('sync', entry) + const updated = await log.joinEntry(entry) + if (updated) { + events.emit('update', entry) + } } } @@ -53,11 +56,14 @@ const Database = async ({ OpLog, ipfs, identity, databaseId, accessController, s events.emit('close') } + // TODO: rename to clear() const drop = async () => { await stateStorage.clear() await storage.clear() } + const merge = async (other) => {} + // Automatically subscribe to the pubsub channel for this database await ipfs.pubsub.subscribe(log.id, handleMessage) @@ -65,6 +71,7 @@ const Database = async ({ OpLog, ipfs, identity, databaseId, accessController, s databaseId, identity, sync, + merge, close, drop, addOperation, diff --git a/src/events.js b/src/events.js index e0f6ec6..c2692a6 100644 --- a/src/events.js +++ b/src/events.js @@ -3,17 +3,22 @@ const EventStore = async ({ OpLog, Database, ipfs, identity, databaseId, accessC const { addOperation, log } = database + const put = async (key = null, value) => { + return add(value) + } + const add = async (value) => { return addOperation({ op: 'ADD', key: null, value }) } const get = async (hash) => { const entry = await log.get(hash) - return entry.payload + return entry.payload.value } const iterator = async function * ({ gt, gte, lt, lte, amount } = {}) { - for await (const event of log.iterator({ gt, gte, lt, lte, amount })) { + const it = log.iterator({ gt, gte, lt, lte, amount }) + for await (const event of it) { yield event.payload.value } } @@ -29,6 +34,7 @@ const EventStore = async ({ OpLog, Database, ipfs, identity, databaseId, accessC return { ...database, type: 'events', + put, add, get, iterator, diff --git a/src/feed.js b/src/feed.js index 7dcb9e9..bebec5c 100644 --- a/src/feed.js +++ b/src/feed.js @@ -3,6 +3,10 @@ const Feed = async ({ OpLog, Database, ipfs, identity, databaseId, accessControl const { addOperation, log } = database + const put = async (key = null, value) => { + return add(value) + } + const add = async (value) => { return addOperation({ op: 'ADD', key: null, value }) } @@ -13,12 +17,13 @@ const Feed = async ({ OpLog, Database, ipfs, identity, databaseId, accessControl const get = async (hash) => { const entry = await log.get(hash) - return entry.payload + return entry.payload.value } const iterator = async function * ({ gt, gte, lt, lte, amount } = {}) { const deleted = {} - for await (const entry of log.iterator({ gt, gte, lt, lte, amount })) { + const it = log.iterator({ gt, gte, lt, lte, amount }) + for await (const entry of it) { const { hash, payload } = entry const { op, key, value } = payload if (op === 'ADD' && !deleted[hash]) { @@ -40,6 +45,7 @@ const Feed = async ({ OpLog, Database, ipfs, identity, databaseId, accessControl return { ...database, type: 'feed', + put, add, del, get, diff --git a/src/ipfs-block-storage.js b/src/ipfs-block-storage.js index f4169a9..0bd8cf4 100644 --- a/src/ipfs-block-storage.js +++ b/src/ipfs-block-storage.js @@ -3,7 +3,7 @@ import { base58btc } from 'multiformats/bases/base58' const defaultTimeout = 30000 -const IPFSBlockStorage = async ({ ipfs, timeout, pin }) => { +const IPFSBlockStorage = async ({ ipfs, timeout, pin } = {}) => { timeout = timeout || defaultTimeout const put = async (hash, data) => { @@ -18,6 +18,10 @@ const IPFSBlockStorage = async ({ ipfs, timeout, pin }) => { }) } + const del = async (hash) => { + // TODO? + } + const get = async (hash) => { const cid = CID.parse(hash, base58btc) const block = await ipfs.block.get(cid, { timeout }) @@ -28,6 +32,8 @@ const IPFSBlockStorage = async ({ ipfs, timeout, pin }) => { const iterator = async function * () {} + // TODO: all() + const merge = async (other) => {} const clear = async () => {} @@ -36,8 +42,10 @@ const IPFSBlockStorage = async ({ ipfs, timeout, pin }) => { return { put, + del, get, iterator, + // TODO: all, merge, clear, close diff --git a/src/kv-persisted.js b/src/kv-persisted.js index 9d9cc6a..deaa629 100644 --- a/src/kv-persisted.js +++ b/src/kv-persisted.js @@ -6,7 +6,7 @@ const KeyValuePersisted = async ({ KeyValue, OpLog, Database, ipfs, identity, da const keyValueStore = await KeyValue({ OpLog, Database, ipfs, identity, databaseId, accessController, storage }) const { events, log } = keyValueStore - const path = `./${identity.id}/${databaseId}_index` + const path = `./${identity.id}/${databaseId}/_index` const index = new Level(path, { valueEncoding }) await index.open() @@ -45,12 +45,15 @@ const KeyValuePersisted = async ({ KeyValue, OpLog, Database, ipfs, identity, da } } + // TODO: all() + const close = async () => { events.off('update', updateIndex(index)) await index.close() await keyValueStore.close() } + // TOD: rename to clear() const drop = async () => { events.off('update', updateIndex(index)) await index.clear() @@ -64,6 +67,7 @@ const KeyValuePersisted = async ({ KeyValue, OpLog, Database, ipfs, identity, da ...keyValueStore, get, iterator, + // TODO: all, close, drop } diff --git a/src/kv.js b/src/kv.js index d8f2267..6160d7b 100644 --- a/src/kv.js +++ b/src/kv.js @@ -35,6 +35,8 @@ const KeyValue = async ({ OpLog, Database, ipfs, identity, databaseId, accessCon } } + // TODO: all() + return { ...database, type: 'kv', @@ -43,6 +45,7 @@ const KeyValue = async ({ OpLog, Database, ipfs, identity, databaseId, accessCon del, get, iterator + // TODO: all, } } diff --git a/src/level-storage.js b/src/level-storage.js index 989a230..1c84a44 100644 --- a/src/level-storage.js +++ b/src/level-storage.js @@ -1,6 +1,6 @@ import { Level } from 'level' -const LevelStorage = async ({ path, valueEncoding } = {}, next) => { +const LevelStorage = async ({ path, valueEncoding } = {}) => { path = path || './level' // console.log("Path:", path) @@ -8,11 +8,16 @@ const LevelStorage = async ({ path, valueEncoding } = {}, next) => { const db = new Level(path, { valueEncoding: valueEncoding || 'view', passive: true }) await db.open() - const add = async (hash, data) => { - await db.put(hash, data, { valueEncoding }) - if (next) { - return next.add(data) - } + const put = async (key = null, value) => { + return add(null, value) + } + + const add = async (hash, value) => { + await db.put(hash, value, { valueEncoding }) + } + + const del = async (hash) => { + await db.del(hash) } const get = async (hash) => { @@ -20,18 +25,9 @@ const LevelStorage = async ({ path, valueEncoding } = {}, next) => { if (value !== undefined) { return value } - if (next) { - return next.get(hash) - } - } - - const del = async (hash) => { - await db.del(hash) - if (next) { - return next.add(hash) - } } + // TODO: rename to iterator() // const values = async () => { // const res = {} // for await (const [key, value] of await db.iterator({ valueEncoding }).all()) { @@ -40,6 +36,8 @@ const LevelStorage = async ({ path, valueEncoding } = {}, next) => { // return res // } + // TODO: all() + const merge = async (other) => {} const clear = async () => { @@ -52,9 +50,11 @@ const LevelStorage = async ({ path, valueEncoding } = {}, next) => { return { add, - get, + put, del, - // values, + get, + // TODO: iterator, + // TODO: all, merge, clear, close diff --git a/src/log.js b/src/log.js index 10ad5c9..d6d97d2 100644 --- a/src/log.js +++ b/src/log.js @@ -5,6 +5,7 @@ import Sorting from './log-sorting.js' import IPFSBlockStorage from './ipfs-block-storage.js' import MemoryStorage from './memory-storage.js' import LRUStorage from './lru-storage.js' +// import LevelStorage from './level-storage.js' import ComposedStorage from './composed-storage.js' import { isDefined } from './utils/index.js' @@ -16,6 +17,7 @@ const maxClockTimeReducer = (res, acc) => Math.max(res, acc.clock.time) // Default storage for storing the Log and its entries. Default: Memory. Options: Memory, LRU, IPFS. const DefaultStorage = MemoryStorage // const DefaultStorage = LRUStorage +// const DefaultStorage = LevelStorage // const DefaultStorage = IPFSBlockStorage // Default AccessController for the Log. @@ -132,6 +134,11 @@ const Log = async (identity, { logId, logHeads, access, storage, stateStorage, s * @return {Promise<Entry>} Entry that was appended */ const append = async (data, options = { pointerCount: 1 }) => { + // 1. Prepare entry + // 2. Authorize entry + // 3. Store entry + // 4. return Entry + // Get references (entry at every pow2 of distance) const refs = await getReferences(options.pointerCount) // Create the next pointers from heads @@ -252,7 +259,10 @@ const Log = async (identity, { logId, logHeads, access, storage, stateStorage, s } // Get the next entry from the stack entry = stack.pop() - if (entry) { + // If we have an entry that we haven't traversed yet, process it + if (entry && !traversed[entry.hash]) { + // Add to the hashes we've traversed + traversed[entry.hash] = true // Yield the current entry yield entry // Add hashes of next entries to the stack from entry's @@ -260,8 +270,6 @@ const Log = async (identity, { logId, logHeads, access, storage, stateStorage, s for (const hash of [...entry.next, ...entry.refs]) { // Check if we've already traversed this entry if (!traversed[hash]) { - // Add to the hashes we've traversed - traversed[hash] = true // Fetch the next entry const next = await get(hash) if (next) { @@ -424,6 +432,7 @@ const Log = async (identity, { logId, logHeads, access, storage, stateStorage, s clock, heads, values, + all: values, // Alias for values() get, append, join, diff --git a/src/lru-storage.js b/src/lru-storage.js index 27502d2..c1ffd50 100644 --- a/src/lru-storage.js +++ b/src/lru-storage.js @@ -9,6 +9,10 @@ const LRUStorage = async ({ size } = {}) => { lru.set(hash, data) } + const del = async (hash) => { + lru.remove(hash) + } + const get = async (hash) => { if (lru.peek(hash)) { return lru.get(hash) @@ -22,6 +26,8 @@ const LRUStorage = async ({ size } = {}) => { } } + // TODO: all() + const merge = async (other) => { if (other) { for await (const [key, value] of other.iterator()) { @@ -38,8 +44,10 @@ const LRUStorage = async ({ size } = {}) => { return { put, + del, get, iterator, + // TODO: all, merge, clear, close diff --git a/src/memory-storage.js b/src/memory-storage.js index d4d0379..7d47b8d 100644 --- a/src/memory-storage.js +++ b/src/memory-storage.js @@ -5,6 +5,10 @@ const MemoryStorage = async () => { memory[hash] = data } + const del = async (hash) => { + delete memory[hash] + } + const get = async (hash) => { if (memory[hash]) { return memory[hash] @@ -25,14 +29,18 @@ const MemoryStorage = async () => { } } + // TODO: all() + const clear = async () => (memory = {}) const close = async () => {} return { put, + del, get, iterator, + // TODO: all, merge, clear, close diff --git a/test/events.spec.js b/test/events.spec.js index bdff899..32c1151 100644 --- a/test/events.spec.js +++ b/test/events.spec.js @@ -10,6 +10,7 @@ import Database from '../src/database.js' // Test utils import { config, testAPIs, startIpfs, stopIpfs, getIpfsPeerId, waitForPeers } from 'orbit-db-test-utils' import connectPeers from './utils/connect-nodes.js' +import waitFor from './utils/wait-for.js' import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js' const { sync: rmrf } = rimraf @@ -29,6 +30,9 @@ Object.keys(testAPIs).forEach((IPFS) => { const databaseId = 'events-AAA' before(async () => { + rmrf('./keys_1') + rmrf('./keys_2') + // Start two IPFS instances ipfsd1 = await startIpfs(IPFS, config.daemon1) ipfsd2 = await startIpfs(IPFS, config.daemon2) @@ -56,6 +60,9 @@ Object.keys(testAPIs).forEach((IPFS) => { // Create an identity for each peers testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore }) testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore }) + + rmrf(testIdentity1.id) + rmrf(testIdentity2.id) }) afterEach(async () => { @@ -96,29 +103,30 @@ Object.keys(testAPIs).forEach((IPFS) => { describe('using database', () => { it('returns all entries in the database', async () => { let updateCount = 0 - let syncCount = 0 + // let syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id } const onUpdate = (entry) => { - updateCount++ - } - const onSync = (entry) => { - syncCount++ + // console.log(".", updateCount, entry.payload) + ++updateCount } + // const onSync = (entry) => { + // ++syncCount + // } const onError = () => { } kv1 = await EventStore({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await EventStore({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) - kv1.events.on('error', onError) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) + // kv1.events.on('error', onError) kv2.events.on('error', onError) strictEqual(kv1.type, 'events') @@ -139,40 +147,18 @@ Object.keys(testAPIs).forEach((IPFS) => { await kv1.add('') await kv1.add('friend33') // const hash = await kv1.add('friend33') - // await kv1.set('init', true) - // await kv1.set('hello', 'friend') - // await kv1.del('hello') - // await kv1.set('hello', 'friend2') - // await kv1.del('hello') - // await kv1.set('empty', '') - // await kv1.del('empty') - // const hash = await kv1.set('hello', 'friend3') // const lastEntry = await kv1.get(hash) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(5000) // give some time for ipfs peers to sync - - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') - // await sleep(1000) // give some time for ipfs peers to sync + await waitFor(() => updateCount, () => 8) + + // onUpdate test + strictEqual(updateCount, 8) + // // write access test // let errorMessage // try { @@ -219,16 +205,13 @@ Object.keys(testAPIs).forEach((IPFS) => { // onError test // notStrictEqual(error, undefined) // strictEqual(error.message, 'CBOR decode error: too many terminals, data makes no sense') - - // onUpdate test - strictEqual(updateCount, 8 * 2) }) }) - describe.skip('load database', () => { + describe('load database', () => { it('returns all entries in the database', async () => { let updateCount = 0 - let syncCount = 0 + // let syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id @@ -237,17 +220,17 @@ Object.keys(testAPIs).forEach((IPFS) => { const onUpdate = (entry) => { ++updateCount } - const onSync = (entry) => { - ++syncCount - } + // const onSync = (entry) => { + // ++syncCount + // } kv1 = await EventStore({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await EventStore({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) await waitForPeers(ipfs1, [peerId2], databaseId) await waitForPeers(ipfs2, [peerId1], databaseId) @@ -263,34 +246,21 @@ Object.keys(testAPIs).forEach((IPFS) => { // const hash = await kv1.add('friend33') // const lastEntry = await kv1.log.get(hash) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(10000) // give some time for ipfs peers to sync - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() - // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') - // await kv1.close() - // await kv2.close() + await waitFor(() => updateCount, () => 8) - // kv1 = await EventStore({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) - // kv2 = await EventStore({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) + // onUpdate test + strictEqual(updateCount, 8) + + await kv1.close() + await kv2.close() + + kv1 = await EventStore({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) + kv2 = await EventStore({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) // all() test const all2 = [] diff --git a/test/feed.spec.js b/test/feed.spec.js index 9d26a7d..4b7ab20 100644 --- a/test/feed.spec.js +++ b/test/feed.spec.js @@ -10,6 +10,7 @@ import Database from '../src/database.js' // Test utils import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils' import connectPeers from './utils/connect-nodes.js' +import waitFor from './utils/wait-for.js' import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js' const { sync: rmrf } = rimraf @@ -56,6 +57,9 @@ Object.keys(testAPIs).forEach((IPFS) => { // Create an identity for each peers testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore }) testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore }) + + rmrf(testIdentity1.id) + rmrf(testIdentity2.id) }) afterEach(async () => { @@ -96,7 +100,7 @@ Object.keys(testAPIs).forEach((IPFS) => { describe('using database', () => { it('returns all entries in the database', async () => { let updateCount = 0 - let syncCount = 0 + // let syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id @@ -105,19 +109,19 @@ Object.keys(testAPIs).forEach((IPFS) => { const onUpdate = (entry) => { ++updateCount } - const onSync = (entry) => { - ++syncCount - } + // const onSync = (entry) => { + // ++syncCount + // } const onError = () => { } kv1 = await Feed({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await Feed({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) kv1.events.on('error', onError) kv2.events.on('error', onError) @@ -141,30 +145,16 @@ Object.keys(testAPIs).forEach((IPFS) => { // const hash = await kv1.add('friend33') // const lastEntry = await kv1.get(hash) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(10000) // give some time for ipfs peers to sync - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() - // // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') - // await sleep(1000) // give some time for ipfs peers to sync + await waitFor(() => updateCount, () => 8) + + // onUpdate test + strictEqual(updateCount, 8) + // // write access test // let errorMessage // try { @@ -211,16 +201,13 @@ Object.keys(testAPIs).forEach((IPFS) => { // onError test // notStrictEqual(error, undefined) // strictEqual(error.message, 'CBOR decode error: too many terminals, data makes no sense') - - // onUpdate test - strictEqual(updateCount, 8 * 2) }) }) - describe.skip('load database', () => { + describe('load database', () => { it('returns all entries in the database', async () => { let updateCount = 0 - let syncCount = 0 + // let syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id @@ -229,19 +216,19 @@ Object.keys(testAPIs).forEach((IPFS) => { const onUpdate = (entry) => { ++updateCount } - const onSync = (entry) => { - ++syncCount - } + // const onSync = (entry) => { + // ++syncCount + // } const onError = () => { } kv1 = await Feed({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await Feed({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) kv1.events.on('error', onError) kv2.events.on('error', onError) @@ -262,36 +249,23 @@ Object.keys(testAPIs).forEach((IPFS) => { // const hashX = await kv1.del(hash) // const lastEntry = await kv1.log.get(hashX) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(10000) // give some time for ipfs peers to sync - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() - // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') - // await kv1.close() - // await kv2.close() + await waitFor(() => updateCount, () => 11) + + // onUpdate test + strictEqual(updateCount, 11) + + await kv1.close() + await kv2.close() // // await sleep(1000) // give some time for ipfs peers to sync - // kv1 = await Feed({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) - // kv2 = await Feed({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) + kv1 = await Feed({ OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) + kv2 = await Feed({ OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) // all() test const all2 = [] diff --git a/test/kv.spec.js b/test/kv.spec.js index 65cf408..491829b 100644 --- a/test/kv.spec.js +++ b/test/kv.spec.js @@ -11,6 +11,7 @@ import Database from '../src/database.js' // Test utils import { config, testAPIs, getIpfsPeerId, waitForPeers, startIpfs, stopIpfs } from 'orbit-db-test-utils' import connectPeers from './utils/connect-nodes.js' +import waitFor from './utils/wait-for.js' import { identityKeys, signingKeys } from './fixtures/orbit-db-identity-keys.js' const { sync: rmrf } = rimraf @@ -57,6 +58,9 @@ Object.keys(testAPIs).forEach((IPFS) => { // Create an identity for each peers testIdentity1 = await createIdentity({ id: 'userA', keystore, signingKeystore }) testIdentity2 = await createIdentity({ id: 'userB', keystore, signingKeystore }) + + rmrf(testIdentity1.id) + rmrf(testIdentity2.id) }) after(async () => { @@ -98,18 +102,18 @@ Object.keys(testAPIs).forEach((IPFS) => { it('returns all entries in the database', async () => { // let error let updateCount = 0 - let syncCount = 0 + // const syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id } const onUpdate = (entry) => { - updateCount++ - } - const onSync = (entry) => { - syncCount++ + ++updateCount } + // const onSync = (entry) => { + // ++syncCount + // } const onError = () => { // error = err } @@ -119,10 +123,10 @@ Object.keys(testAPIs).forEach((IPFS) => { kv1 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) kv1.events.on('error', onError) kv2.events.on('error', onError) @@ -146,29 +150,18 @@ Object.keys(testAPIs).forEach((IPFS) => { // const hash = await kv1.set('hello', 'friend3') // const lastEntry = await kv1.database.log.get(hash) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(10000) // give some time for ipfs peers to sync - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() - // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') + await waitFor(() => updateCount, () => 8) + + // update event test + strictEqual(updateCount, 8) + // sync event test + // strictEqual(syncCount, 8) + // write access test // let errorMessage // try { @@ -229,39 +222,34 @@ Object.keys(testAPIs).forEach((IPFS) => { // onError test // notStrictEqual(error, undefined) // strictEqual(error.message, 'CBOR decode error: too many terminals, data makes no sense') - - // update event test - strictEqual(updateCount, 8 * 2) - // sync event test - strictEqual(syncCount, 8) }) }) - describe.skip('load database', () => { + describe('load database', () => { it('returns all entries in the database', async () => { let updateCount = 0 - let syncCount = 0 + // let syncCount = 0 const accessController = { canAppend: (entry) => entry.identity.id === testIdentity1.id } const onUpdate = (entry) => { - updateCount++ - } - const onSync = (entry) => { - syncCount++ + ++updateCount } + // const onSync = (entry) => { + // ++syncCount + // } // kv1 = await KeyValueStore({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) // kv2 = await KeyValueStore({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) kv1 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) kv2 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - kv1.events.on('update', onUpdate) + // kv1.events.on('update', onUpdate) kv2.events.on('update', onUpdate) - kv1.events.on('sync', onSync) - kv2.events.on('sync', onSync) + // kv1.events.on('sync', onSync) + // kv2.events.on('sync', onSync) await waitForPeers(ipfs1, [peerId2], databaseId) await waitForPeers(ipfs2, [peerId1], databaseId) @@ -277,36 +265,21 @@ Object.keys(testAPIs).forEach((IPFS) => { // const hash = await kv1.set('hello', 'friend3') // const lastEntry = await kv1.log.get(hash) - // const sleep = (time) => new Promise((resolve) => { - // setTimeout(() => { - // resolve() - // }, time) - // }) - // await sleep(10000) // give some time for ipfs peers to sync - const waitForAllUpdates = async () => { - return new Promise((resolve) => { - const interval = setInterval(() => { - if (updateCount >= 8 * 2 || syncCount >= 8) { - clearInterval(interval) - resolve() - } - }, 100) - }) - } - await waitForAllUpdates() - // sync() test // console.time('sync') // await kv2.sync(lastEntry.bytes) // console.timeEnd('sync') - // await kv1.close() - // await kv2.close() + await waitFor(() => updateCount, () => 8) + strictEqual(updateCount, 8) + + await kv1.close() + await kv2.close() // kv1 = await KeyValueStore({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) // kv2 = await KeyValueStore({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) - // kv1 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) - // kv2 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) + kv1 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs1, identity: testIdentity1, databaseId, accessController }) + kv2 = await KeyValueStorePersisted({ KeyValue: KeyValueStore, OpLog: Log, Database, ipfs: ipfs2, identity: testIdentity2, databaseId, accessController }) console.time('get') const value0 = await kv2.get('init') @@ -349,8 +322,6 @@ Object.keys(testAPIs).forEach((IPFS) => { { key: 'hello', value: 'friend3' }, { key: 'init', value: true } ]) - - strictEqual(syncCount, 8) }) }) }) diff --git a/test/log-references.spec.js b/test/log-references.spec.js index c12af9b..c0ea710 100644 --- a/test/log-references.spec.js +++ b/test/log-references.spec.js @@ -1,7 +1,7 @@ import { strictEqual } from 'assert' import rimraf from 'rimraf' import { copy } from 'fs-extra' -import { Log } from '../src/log.js' +import { Log, MemoryStorage } from '../src/log.js' import IdentityProvider from 'orbit-db-identity-provider' import Keystore from '../src/Keystore.js' @@ -110,20 +110,26 @@ Object.keys(testAPIs).forEach((IPFS) => { { amount: 32, referenceCount: 16, refLength: 4 }, { amount: 18, referenceCount: 32, refLength: 5 }, { amount: 128, referenceCount: 32, refLength: 5 }, + { amount: 63, referenceCount: 64, refLength: 5 }, { amount: 64, referenceCount: 64, refLength: 6 }, { amount: 65, referenceCount: 64, refLength: 6 }, + { amount: 91, referenceCount: 64, refLength: 6 }, { amount: 128, referenceCount: 64, refLength: 6 }, { amount: 128, referenceCount: 1, refLength: 0 }, { amount: 128, referenceCount: 2, refLength: 1 }, { amount: 256, referenceCount: 1, refLength: 0 }, - { amount: 256, referenceCount: 256, refLength: 8 }, - { amount: 256, referenceCount: 1024, refLength: 8 } + { amount: 256, referenceCount: 4, refLength: 2 }, + { amount: 256, referenceCount: 8, refLength: 3 }, + { amount: 256, referenceCount: 16, refLength: 4 }, + { amount: 256, referenceCount: 32, refLength: 5 }, + { amount: 1024, referenceCount: 2, refLength: 1 } ] inputs.forEach(input => { it(`has ${input.refLength} references, max distance ${input.referenceCount}, total of ${input.amount} entries`, async () => { const test = async (amount, referenceCount, refLength) => { - const log1 = await Log(testIdentity, { logId: 'A' }) + const storage = await MemoryStorage() + const log1 = await Log(testIdentity, { logId: 'A', storage }) for (let i = 0; i < amount; i++) { await log1.append((i + 1).toString(), { pointerCount: referenceCount }) } @@ -140,19 +146,21 @@ Object.keys(testAPIs).forEach((IPFS) => { // Check the first ref (distance 2) if (values[idx].refs.length > 0) { strictEqual(values[idx].refs[0], values[idx - 2].hash) } - // Check the second ref (distance 2) - + // Check the second ref (distance 4) if (values[idx].refs.length > 1 && idx > referenceCount) { strictEqual(values[idx].refs[1], values[idx - 4].hash) } - // Check the third ref (distance 4) + // Check the third ref (distance 8) if (values[idx].refs.length > 2 && idx > referenceCount) { strictEqual(values[idx].refs[2], values[idx - 8].hash) } - // Check the fourth ref (distance 8) + // Check the fourth ref (distance 16) if (values[idx].refs.length > 3 && idx > referenceCount) { strictEqual(values[idx].refs[3], values[idx - 16].hash) } - // Check the fifth ref (distance 16) + // Check the fifth ref (distance 32) if (values[idx].refs.length > 4 && idx > referenceCount) { strictEqual(values[idx].refs[4], values[idx - 32].hash) } + // Check the fifth ref (distance 64) + if (values[idx].refs.length > 5 && idx > referenceCount) { strictEqual(values[idx].refs[5], values[idx - 64].hash) } + // Check the reference of each entry if (idx > referenceCount) { strictEqual(values[idx].refs.length, refLength) } } diff --git a/test/utils/wait-for.js b/test/utils/wait-for.js new file mode 100644 index 0000000..b2f34fc --- /dev/null +++ b/test/utils/wait-for.js @@ -0,0 +1,12 @@ +const waitFor = async (valueA, toBeValueB, pollInterval = 100) => { + return new Promise((resolve) => { + const interval = setInterval(() => { + if (valueA() === toBeValueB()) { + clearInterval(interval) + resolve() + } + }, pollInterval) + }) +} + +export default waitFor