diff --git a/dist/error.d.ts b/dist/error.d.ts index dce0d99..d3f0fcc 100644 --- a/dist/error.d.ts +++ b/dist/error.d.ts @@ -1,2 +1,2 @@ -export declare const ERR_NOT_READY = "NOT_READY"; +export declare const ERR_MAX_TRIES_HIT = "ERR_MAX_TRIES_HIT"; //# sourceMappingURL=error.d.ts.map diff --git a/dist/error.d.ts.map b/dist/error.d.ts.map index 63f7520..2027c0c 100644 --- a/dist/error.d.ts.map +++ b/dist/error.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,cAAc,CAAC"} \ No newline at end of file +{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"} \ No newline at end of file diff --git a/dist/error.js b/dist/error.js index 74282fc..efb866d 100644 --- a/dist/error.js +++ b/dist/error.js @@ -1 +1 @@ -export const ERR_NOT_READY = "NOT_READY"; +export const ERR_MAX_TRIES_HIT = "ERR_MAX_TRIES_HIT"; diff --git a/dist/index.d.ts b/dist/index.d.ts index 944f13c..f9eaa37 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,5 +1,14 @@ -import RpcNetwork from "./rpcNetwork.js"; -import RpcQuery from "./rpcNetwork.js"; +import RpcNetwork from "./network.js"; +import RpcQueryBase from "./query/base.js"; +import SimpleRpcQuery from "./query/simple.js"; +import StreamingRpcQuery from "./query/streaming.js"; +import WisdomRpcQuery from "./query/wisdom.js"; export * from "./types.js"; -export { RpcNetwork, RpcQuery }; +export { + RpcNetwork, + RpcQueryBase, + SimpleRpcQuery, + StreamingRpcQuery, + WisdomRpcQuery, +}; //# sourceMappingURL=index.d.ts.map diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index fc54449..5cdddd9 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AACzC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAEvC,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAC/C,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AACrD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,cAAc,YAAY,CAAC;AAE3B,OAAO,EACL,UAAU,EACV,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 952652c..64345ca 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,4 +1,7 @@ -import RpcNetwork from "./rpcNetwork.js"; -import RpcQuery from "./rpcNetwork.js"; +import RpcNetwork from "./network.js"; +import RpcQueryBase from "./query/base.js"; +import SimpleRpcQuery from "./query/simple.js"; +import StreamingRpcQuery from "./query/streaming.js"; +import WisdomRpcQuery from "./query/wisdom.js"; export * from "./types.js"; -export { RpcNetwork, RpcQuery }; +export { RpcNetwork, RpcQueryBase, SimpleRpcQuery, StreamingRpcQuery, WisdomRpcQuery, }; diff --git a/dist/rpcNetwork.d.ts b/dist/rpcNetwork.d.ts deleted file mode 100644 index e8fbc3e..0000000 --- a/dist/rpcNetwork.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import RpcQuery from "./rpcQuery.js"; -export default class RpcNetwork { - constructor(dht?: any); - private _dht; - get dht(): any; - private _majorityThreshold; - get majorityThreshold(): number; - set majorityThreshold(value: number); - private _maxTtl; - get maxTtl(): number; - set maxTtl(value: number); - private _queryTimeout; - get queryTimeout(): number; - set queryTimeout(value: number); - private _relayTimeout; - get relayTimeout(): number; - set relayTimeout(value: number); - private _relays; - get relays(): string[]; - private _ready?; - get ready(): Promise; - private _bypassCache; - get bypassCache(): boolean; - set bypassCache(value: boolean); - addRelay(pubkey: string): void; - removeRelay(pubkey: string): boolean; - clearRelays(): void; - query( - query: string, - chain: string, - data?: object | any[], - bypassCache?: boolean - ): RpcQuery; -} -//# sourceMappingURL=rpcNetwork.d.ts.map diff --git a/dist/rpcNetwork.d.ts.map b/dist/rpcNetwork.d.ts.map deleted file mode 100644 index 746b1f7..0000000 --- a/dist/rpcNetwork.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rpcNetwork.d.ts","sourceRoot":"","sources":["../src/rpcNetwork.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAIrC,MAAM,CAAC,OAAO,OAAO,UAAU;gBACjB,GAAG,MAAY;IAI3B,OAAO,CAAC,IAAI,CAAa;IAEzB,IAAI,GAAG,QAEN;IAED,OAAO,CAAC,kBAAkB,CAAQ;IAElC,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAElC;IAED,OAAO,CAAC,OAAO,CAAgB;IAE/B,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAEvB;IAED,OAAO,CAAC,aAAa,CAAM;IAE3B,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,OAAO,CAAC,aAAa,CAAK;IAE1B,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,OAAO,CAAC,OAAO,CAAgB;IAE/B,IAAI,MAAM,IAAI,MAAM,EAAE,CAErB;IAED,OAAO,CAAC,MAAM,CAAC,CAAgB;IAE/B,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAKzB;IAED,OAAO,CAAC,YAAY,CAAkB;IAEtC,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,OAAO,EAE7B;IAEM,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK9B,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAWpC,WAAW,IAAI,IAAI;IAInB,KAAK,CACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,MAAM,GAAG,GAAG,EAAO,EACzB,WAAW,GAAE,OAAe,GAC3B,QAAQ;CAQZ"} \ No newline at end of file diff --git a/dist/rpcNetwork.js b/dist/rpcNetwork.js deleted file mode 100644 index 84ee115..0000000 --- a/dist/rpcNetwork.js +++ /dev/null @@ -1,81 +0,0 @@ -import RpcQuery from "./rpcQuery.js"; -// @ts-ignore -import DHT from "@hyperswarm/dht"; -export default class RpcNetwork { - constructor(dht = new DHT()) { - this._dht = dht; - } - _dht; - get dht() { - return this._dht; - } - _majorityThreshold = 0.75; - get majorityThreshold() { - return this._majorityThreshold; - } - set majorityThreshold(value) { - this._majorityThreshold = value; - } - _maxTtl = 12 * 60 * 60; - get maxTtl() { - return this._maxTtl; - } - set maxTtl(value) { - this._maxTtl = value; - } - _queryTimeout = 30; - get queryTimeout() { - return this._queryTimeout; - } - set queryTimeout(value) { - this._queryTimeout = value; - } - _relayTimeout = 2; - get relayTimeout() { - return this._relayTimeout; - } - set relayTimeout(value) { - this._relayTimeout = value; - } - _relays = []; - get relays() { - return this._relays; - } - _ready; - get ready() { - if (!this._ready) { - this._ready = this._dht.ready(); - } - return this._ready; - } - _bypassCache = false; - get bypassCache() { - return this._bypassCache; - } - set bypassCache(value) { - this._bypassCache = value; - } - addRelay(pubkey) { - this._relays.push(pubkey); - this._relays = [...new Set(this._relays)]; - } - removeRelay(pubkey) { - if (!this._relays.includes(pubkey)) { - return false; - } - delete this._relays[this._relays.indexOf(pubkey)]; - this._relays = Object.values(this._relays); - return true; - } - clearRelays() { - this._relays = []; - } - query(query, chain, data = {}, bypassCache = false) { - return new RpcQuery(this, { - query, - chain, - data, - bypassCache: bypassCache || this._bypassCache, - }); - } -} diff --git a/dist/rpcQuery.d.ts b/dist/rpcQuery.d.ts deleted file mode 100644 index acc57b6..0000000 --- a/dist/rpcQuery.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import RpcNetwork from "./rpcNetwork.js"; -import { RPCRequest } from "./types.js"; -export default class RpcQuery { - private _network; - private _query; - private _promise?; - private _timeoutTimer?; - private _timeout; - private _completed; - private _responses; - private _promiseResolve?; - private _maxTries; - private _tries; - constructor(network: RpcNetwork, query: RPCRequest); - get result(): Promise; - private handeTimeout; - private resolve; - private init; - private queryRelay; - private checkResponses; - private retry; -} -//# sourceMappingURL=rpcQuery.d.ts.map diff --git a/dist/rpcQuery.d.ts.map b/dist/rpcQuery.d.ts.map deleted file mode 100644 index d7be119..0000000 --- a/dist/rpcQuery.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"rpcQuery.d.ts","sourceRoot":"","sources":["../src/rpcQuery.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAKrD,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAe;IAChC,OAAO,CAAC,aAAa,CAAC,CAAM;IAC5B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,UAAU,CAAwC;IAC1D,OAAO,CAAC,eAAe,CAAC,CAAsB;IAC9C,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,MAAM,CAAK;gBAEP,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;IAMlD,IAAI,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAEzB;IAED,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,OAAO;YAQD,IAAI;YA2BJ,UAAU;IAkCxB,OAAO,CAAC,cAAc;IAqDtB,OAAO,CAAC,KAAK;CASd"} \ No newline at end of file diff --git a/dist/rpcQuery.js b/dist/rpcQuery.js deleted file mode 100644 index 509388c..0000000 --- a/dist/rpcQuery.js +++ /dev/null @@ -1,133 +0,0 @@ -import { clearTimeout, setTimeout } from "timers"; -import { pack, unpack } from "msgpackr"; -import { Buffer } from "buffer"; -import { blake2b } from "libskynet"; -import { flatten } from "./util.js"; -export default class RpcQuery { - _network; - _query; - _promise; - _timeoutTimer; - _timeout = false; - _completed = false; - _responses = {}; - _promiseResolve; - _maxTries = 3; - _tries = 0; - constructor(network, query) { - this._network = network; - this._query = query; - this.init(); - } - get result() { - return this._promise; - } - handeTimeout() { - this.resolve(false, true); - } - resolve(data, timeout = false) { - clearTimeout(this._timeoutTimer); - this._timeout = timeout; - this._completed = true; - // @ts-ignore - this._promiseResolve(data); - } - async init() { - this._promise = - this._promise ?? - new Promise((resolve) => { - this._promiseResolve = resolve; - }); - this._timeoutTimer = - this._timeoutTimer ?? - setTimeout(this.handeTimeout.bind(this), this._network.queryTimeout * 1000); - await this._network.ready; - const promises = []; - // tslint:disable-next-line:forin - for (const relay of this._network.relays) { - promises.push(this.queryRelay(relay)); - } - await Promise.allSettled(promises); - this.checkResponses(); - } - async queryRelay(relay) { - let socket; - try { - socket = this._network.dht.connect(Buffer.from(relay, "hex")); - if (isPromise(socket)) { - socket = await socket; - } - } - catch (e) { - return; - } - return new Promise((resolve, reject) => { - let timer; - socket.on("data", (res) => { - if (timer && timer.close) { - clearTimeout(timer); - } - socket.end(); - const response = unpack(res); - if (response && response.error) { - return reject(response); - } - this._responses[relay] = response; - resolve(null); - }); - socket.on("error", (error) => reject({ error })); - socket.write("rpc"); - socket.write(pack(this._query)); - timer = setTimeout(() => { - reject("timeout"); - }, this._network.relayTimeout * 1000); - }); - } - checkResponses() { - const responseStore = this._responses; - const responseStoreData = Object.values(responseStore); - const responseObjects = responseStoreData.reduce((output, item) => { - const itemFlattened = flatten(item?.data).sort(); - const hash = Buffer.from(blake2b(Buffer.from(JSON.stringify(itemFlattened)))).toString("hex"); - output[hash] = item?.data; - return output; - }, {}); - const responses = responseStoreData.reduce((output, item) => { - const itemFlattened = flatten(item?.data).sort(); - const hash = Buffer.from(blake2b(Buffer.from(JSON.stringify(itemFlattened)))).toString("hex"); - output[hash] = output[hash] ?? 0; - output[hash]++; - return output; - }, {}); - for (const responseHash in responses) { - if (responses[responseHash] / responseStoreData.length >= - this._network.majorityThreshold) { - // @ts-ignore - let response = responseObjects[responseHash]; - // @ts-ignore - if (null === response) { - if (this._tries <= this._maxTries) { - this._tries++; - this.retry(); - return; - } - response = false; - } - this.resolve(response); - break; - } - } - } - retry() { - this._responses = {}; - if (this._completed) { - return; - } - this.init(); - } -} -function isPromise(obj) { - return (!!obj && - (typeof obj === "object" || typeof obj === "function") && - typeof obj.then === "function"); -} diff --git a/dist/types.d.ts b/dist/types.d.ts index 0a98375..f1776b4 100644 --- a/dist/types.d.ts +++ b/dist/types.d.ts @@ -1,12 +1,9 @@ -export interface RPCRequest { - bypassCache: boolean; - chain: string; - query: string; - data: any; +export interface RpcQueryOptions { + queryTimeout?: number; + relayTimeout?: number; } -export interface RPCResponse { - updated: number; - data: any; - error?: string; +export interface StreamingRpcQueryOptions extends RpcQueryOptions { + streamHandler: StreamHandlerFunction; } +export declare type StreamHandlerFunction = (data: Uint8Array) => void; //# sourceMappingURL=types.d.ts.map diff --git a/dist/types.d.ts.map b/dist/types.d.ts.map index 70f9a46..ef80f9e 100644 --- a/dist/types.d.ts.map +++ b/dist/types.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"} \ No newline at end of file +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AACD,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,aAAa,EAAE,qBAAqB,CAAC;CACtC;AAED,oBAAY,qBAAqB,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC"} \ No newline at end of file diff --git a/dist/util.d.ts b/dist/util.d.ts index a8a14da..0454630 100644 --- a/dist/util.d.ts +++ b/dist/util.d.ts @@ -1,2 +1,3 @@ export declare function flatten(target: any, opts?: any): any[]; +export declare function isPromise(obj: Promise): boolean; //# sourceMappingURL=util.d.ts.map diff --git a/dist/util.d.ts.map b/dist/util.d.ts.map index 159e9ae..21ad54e 100644 --- a/dist/util.d.ts.map +++ b/dist/util.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAaA,wBAAgB,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,GAAE,GAAQ,GAAG,GAAG,EAAE,CA0C1D"} \ No newline at end of file +{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAaA,wBAAgB,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,GAAE,GAAQ,GAAG,GAAG,EAAE,CA0C1D;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,WAM1C"} \ No newline at end of file diff --git a/dist/util.js b/dist/util.js index 9cefbaa..99f2bfb 100644 --- a/dist/util.js +++ b/dist/util.js @@ -40,3 +40,8 @@ export function flatten(target, opts = {}) { step(target); return output; } +export function isPromise(obj) { + return (!!obj && + (typeof obj === "object" || typeof obj === "function") && + typeof obj.then === "function"); +}