*Update dist
This commit is contained in:
parent
00ccbc9536
commit
ac53e5833a
|
@ -0,0 +1,52 @@
|
||||||
|
/// <reference types="node" />
|
||||||
|
import WisdomRpcQuery from "./query/wisdom.js";
|
||||||
|
import StreamingRpcQuery from "./query/streaming.js";
|
||||||
|
import { RpcQueryOptions, StreamHandlerFunction } from "./types.js";
|
||||||
|
import SimpleRpcQuery from "./query/simple.js";
|
||||||
|
export default class RpcNetwork {
|
||||||
|
constructor(dht?: any);
|
||||||
|
private _dht;
|
||||||
|
get dht(): any;
|
||||||
|
private _majorityThreshold;
|
||||||
|
get majorityThreshold(): number;
|
||||||
|
set majorityThreshold(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<void>;
|
||||||
|
private _bypassCache;
|
||||||
|
get bypassCache(): boolean;
|
||||||
|
set bypassCache(value: boolean);
|
||||||
|
addRelay(pubkey: string): void;
|
||||||
|
removeRelay(pubkey: string): boolean;
|
||||||
|
clearRelays(): void;
|
||||||
|
wisdomQuery(
|
||||||
|
method: string,
|
||||||
|
module: string,
|
||||||
|
data?: object | any[],
|
||||||
|
bypassCache?: boolean,
|
||||||
|
options?: RpcQueryOptions
|
||||||
|
): WisdomRpcQuery;
|
||||||
|
streamingQuery(
|
||||||
|
relay: Buffer | string,
|
||||||
|
method: string,
|
||||||
|
module: string,
|
||||||
|
streamHandler: StreamHandlerFunction,
|
||||||
|
data?: object | any[],
|
||||||
|
options?: RpcQueryOptions
|
||||||
|
): StreamingRpcQuery;
|
||||||
|
simpleQuery(
|
||||||
|
relay: Buffer | string,
|
||||||
|
method: string,
|
||||||
|
module: string,
|
||||||
|
data?: object | any[],
|
||||||
|
options?: RpcQueryOptions
|
||||||
|
): SimpleRpcQuery;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=network.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../src/network.ts"],"names":[],"mappings":";AAAA,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAG/C,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,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,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,WAAW,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAM,GAAG,GAAG,EAAO,EACzB,WAAW,GAAE,OAAe,EAC5B,OAAO,GAAE,eAAoB,GAC5B,cAAc;IAaV,cAAc,CACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,qBAAqB,EACpC,IAAI,GAAE,MAAM,GAAG,GAAG,EAAO,EACzB,OAAO,GAAE,eAAoB,GAC5B,iBAAiB;IASb,WAAW,CAChB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAM,GAAG,GAAG,EAAO,EACzB,OAAO,GAAE,eAAoB,GAC5B,cAAc;CAYlB"}
|
|
@ -0,0 +1,86 @@
|
||||||
|
import WisdomRpcQuery from "./query/wisdom.js";
|
||||||
|
// @ts-ignore
|
||||||
|
import DHT from "@hyperswarm/dht";
|
||||||
|
import StreamingRpcQuery from "./query/streaming.js";
|
||||||
|
import SimpleRpcQuery from "./query/simple.js";
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
_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 = [];
|
||||||
|
}
|
||||||
|
wisdomQuery(method, module, data = {}, bypassCache = false, options = {}) {
|
||||||
|
return new WisdomRpcQuery(this, {
|
||||||
|
method,
|
||||||
|
module,
|
||||||
|
data,
|
||||||
|
bypassCache: bypassCache || this._bypassCache,
|
||||||
|
}, options).run();
|
||||||
|
}
|
||||||
|
streamingQuery(relay, method, module, streamHandler, data = {}, options = {}) {
|
||||||
|
return new StreamingRpcQuery(this, relay, { method, module, data }, { streamHandler, ...options }).run();
|
||||||
|
}
|
||||||
|
simpleQuery(relay, method, module, data = {}, options = {}) {
|
||||||
|
return new SimpleRpcQuery(this, relay, {
|
||||||
|
method,
|
||||||
|
module,
|
||||||
|
data,
|
||||||
|
}, options).run();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/// <reference types="node" />
|
||||||
|
import { Buffer } from "buffer";
|
||||||
|
import RpcNetwork from "../network.js";
|
||||||
|
import { RpcQueryOptions } from "../types.js";
|
||||||
|
import type { RPCRequest, RPCResponse } from "@lumeweb/relay";
|
||||||
|
export default abstract class RpcQueryBase {
|
||||||
|
protected _network: RpcNetwork;
|
||||||
|
protected _query: RPCRequest;
|
||||||
|
protected _options: RpcQueryOptions;
|
||||||
|
protected _promise?: Promise<any>;
|
||||||
|
protected _timeoutTimer?: any;
|
||||||
|
protected _timeout: boolean;
|
||||||
|
protected _completed: boolean;
|
||||||
|
protected _responses: {
|
||||||
|
[relay: string]: RPCResponse;
|
||||||
|
};
|
||||||
|
protected _errors: {
|
||||||
|
[relay: string]: any;
|
||||||
|
};
|
||||||
|
protected _promiseResolve?: (data: any) => void;
|
||||||
|
constructor(
|
||||||
|
network: RpcNetwork,
|
||||||
|
query: RPCRequest,
|
||||||
|
options?: RpcQueryOptions
|
||||||
|
);
|
||||||
|
get result(): Promise<RPCResponse>;
|
||||||
|
private handeTimeout;
|
||||||
|
protected resolve(data?: RPCResponse, timeout?: boolean): void;
|
||||||
|
run(): this;
|
||||||
|
protected queryRelay(relay: string | Buffer): Promise<any>;
|
||||||
|
protected abstract checkResponses(): void;
|
||||||
|
protected abstract getRelays(): string[] | Buffer[];
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=base.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/query/base.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,UAAU,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,YAAY;IACxC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,eAAe,CAAC;IAEpC,SAAS,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAClC,SAAS,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC;IAC9B,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAS;IACpC,SAAS,CAAC,UAAU,EAAE,OAAO,CAAS;IACtC,SAAS,CAAC,UAAU,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAM;IAC5D,SAAS,CAAC,OAAO,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAM;IACjD,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;gBAG9C,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,eAAoB;IAO/B,IAAI,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,CAEjC;IAED,OAAO,CAAC,YAAY;IAIpB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,OAAO,GAAE,OAAe,GAAG,IAAI;IAc9D,GAAG,IAAI,IAAI;cA2BF,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAmDhE,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI;IAEzC,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,MAAM,EAAE,GAAG,MAAM,EAAE;CACpD"}
|
|
@ -0,0 +1,104 @@
|
||||||
|
import { clearTimeout, setTimeout } from "timers";
|
||||||
|
import { pack, unpack } from "msgpackr";
|
||||||
|
import { Buffer } from "buffer";
|
||||||
|
import { isPromise } from "../util.js";
|
||||||
|
export default class RpcQueryBase {
|
||||||
|
_network;
|
||||||
|
_query;
|
||||||
|
_options;
|
||||||
|
_promise;
|
||||||
|
_timeoutTimer;
|
||||||
|
_timeout = false;
|
||||||
|
_completed = false;
|
||||||
|
_responses = {};
|
||||||
|
_errors = {};
|
||||||
|
_promiseResolve;
|
||||||
|
constructor(network, query, options = {}) {
|
||||||
|
this._network = network;
|
||||||
|
this._query = query;
|
||||||
|
this._options = options;
|
||||||
|
}
|
||||||
|
get result() {
|
||||||
|
return this._promise;
|
||||||
|
}
|
||||||
|
handeTimeout() {
|
||||||
|
this.resolve(undefined, true);
|
||||||
|
}
|
||||||
|
resolve(data, timeout = false) {
|
||||||
|
clearTimeout(this._timeoutTimer);
|
||||||
|
this._timeout = timeout;
|
||||||
|
this._completed = true;
|
||||||
|
if (timeout) {
|
||||||
|
data = {
|
||||||
|
error: "timeout",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this._promiseResolve?.(data);
|
||||||
|
}
|
||||||
|
run() {
|
||||||
|
this._promise =
|
||||||
|
this._promise ??
|
||||||
|
new Promise((resolve) => {
|
||||||
|
this._promiseResolve = resolve;
|
||||||
|
});
|
||||||
|
this._timeoutTimer =
|
||||||
|
this._timeoutTimer ??
|
||||||
|
setTimeout(this.handeTimeout.bind(this), (this._options.queryTimeout || this._network.queryTimeout) * 1000);
|
||||||
|
this._network.ready.then(() => {
|
||||||
|
const promises = [];
|
||||||
|
for (const relay of this.getRelays()) {
|
||||||
|
promises.push(this.queryRelay(relay));
|
||||||
|
}
|
||||||
|
Promise.allSettled(promises).then(() => this.checkResponses());
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
async queryRelay(relay) {
|
||||||
|
let socket;
|
||||||
|
let relayKey = relay;
|
||||||
|
if (typeof relay === "string") {
|
||||||
|
relayKey = Buffer.from(relay, "hex");
|
||||||
|
}
|
||||||
|
if (relay instanceof Buffer) {
|
||||||
|
relayKey = relay;
|
||||||
|
relay = relay.toString("hex");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
socket = this._network.dht.connect(relayKey);
|
||||||
|
if (isPromise(socket)) {
|
||||||
|
socket = await socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let timer;
|
||||||
|
socket.on("data", (res) => {
|
||||||
|
relay = relay;
|
||||||
|
if (timer && timer.close) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
socket.end();
|
||||||
|
const response = unpack(res);
|
||||||
|
if (response && response.error) {
|
||||||
|
this._errors[relay] = response.error;
|
||||||
|
return reject(null);
|
||||||
|
}
|
||||||
|
this._responses[relay] = response;
|
||||||
|
resolve(null);
|
||||||
|
});
|
||||||
|
socket.on("error", (error) => {
|
||||||
|
relay = relay;
|
||||||
|
this._errors[relay] = error;
|
||||||
|
reject({ error });
|
||||||
|
});
|
||||||
|
socket.write("rpc");
|
||||||
|
socket.write(pack(this._query));
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
this._errors[relay] = "timeout";
|
||||||
|
reject(null);
|
||||||
|
}, (this._options.relayTimeout || this._network.relayTimeout) * 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/// <reference types="node" />
|
||||||
|
import RpcQueryBase from "./base.js";
|
||||||
|
import RpcNetwork from "../network.js";
|
||||||
|
import type { RPCRequest } from "@lumeweb/relay";
|
||||||
|
import { RpcQueryOptions } from "../types.js";
|
||||||
|
import type { Buffer } from "buffer";
|
||||||
|
export default class SimpleRpcQuery extends RpcQueryBase {
|
||||||
|
private _relay;
|
||||||
|
constructor(
|
||||||
|
network: RpcNetwork,
|
||||||
|
relay: string | Buffer,
|
||||||
|
query: RPCRequest,
|
||||||
|
options: RpcQueryOptions
|
||||||
|
);
|
||||||
|
protected checkResponses(): void;
|
||||||
|
protected getRelays(): string[] | Buffer[];
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=simple.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../src/query/simple.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,WAAW,CAAC;AACrC,OAAO,UAAU,MAAM,eAAe,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,YAAY;IACtD,OAAO,CAAC,MAAM,CAAkB;gBAE9B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,eAAe;IAM1B,SAAS,CAAC,cAAc,IAAI,IAAI;IAYhC,SAAS,CAAC,SAAS,IAAI,MAAM,EAAE,GAAG,MAAM,EAAE;CAG3C"}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import RpcQueryBase from "./base.js";
|
||||||
|
export default class SimpleRpcQuery extends RpcQueryBase {
|
||||||
|
_relay;
|
||||||
|
constructor(network, relay, query, options) {
|
||||||
|
super(network, query, options);
|
||||||
|
this._relay = relay;
|
||||||
|
}
|
||||||
|
checkResponses() {
|
||||||
|
if (Object.keys(this._responses).length) {
|
||||||
|
this.resolve(Object.values(this._responses).pop());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Object.keys(this._errors).length) {
|
||||||
|
this.resolve({ error: Object.values(this._errors).pop() });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getRelays() {
|
||||||
|
return [this._relay];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/// <reference types="node" />
|
||||||
|
import SimpleRpcQuery from "./simple.js";
|
||||||
|
import { Buffer } from "buffer";
|
||||||
|
import type { RPCRequest } from "@lumeweb/relay";
|
||||||
|
import RpcNetwork from "../network.js";
|
||||||
|
import { StreamingRpcQueryOptions } from "../types.js";
|
||||||
|
export default class StreamingRpcQuery extends SimpleRpcQuery {
|
||||||
|
protected _options: StreamingRpcQueryOptions;
|
||||||
|
constructor(
|
||||||
|
network: RpcNetwork,
|
||||||
|
relay: string | Buffer,
|
||||||
|
query: RPCRequest,
|
||||||
|
options: StreamingRpcQueryOptions
|
||||||
|
);
|
||||||
|
protected queryRelay(relay: string | Buffer): Promise<any>;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=streaming.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/query/streaming.ts"],"names":[],"mappings":";AAAA,OAAO,cAAc,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,UAAU,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,cAAc;IAC3D,SAAS,CAAC,QAAQ,EAAE,wBAAwB,CAAC;gBAE3C,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,wBAAwB;cAKnB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAwDjE"}
|
|
@ -0,0 +1,64 @@
|
||||||
|
import SimpleRpcQuery from "./simple.js";
|
||||||
|
import { Buffer } from "buffer";
|
||||||
|
import { isPromise } from "../util.js";
|
||||||
|
import { clearTimeout, setTimeout } from "timers";
|
||||||
|
import { pack, unpack } from "msgpackr";
|
||||||
|
export default class StreamingRpcQuery extends SimpleRpcQuery {
|
||||||
|
_options;
|
||||||
|
constructor(network, relay, query, options) {
|
||||||
|
super(network, relay, query, options);
|
||||||
|
this._options = options;
|
||||||
|
}
|
||||||
|
async queryRelay(relay) {
|
||||||
|
let socket;
|
||||||
|
let relayKey = relay;
|
||||||
|
if (relay === "string") {
|
||||||
|
relayKey = Buffer.from(relay, "hex");
|
||||||
|
}
|
||||||
|
if (relay instanceof Buffer) {
|
||||||
|
relayKey = relay;
|
||||||
|
relay = relay.toString("hex");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
socket = this._network.dht.connect(relayKey);
|
||||||
|
if (isPromise(socket)) {
|
||||||
|
socket = await socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let timer;
|
||||||
|
socket.on("data", (res) => {
|
||||||
|
relay = relay;
|
||||||
|
if (timer && timer.close) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
socket.end();
|
||||||
|
const response = unpack(res);
|
||||||
|
if (response && response.error) {
|
||||||
|
this._errors[relay] = response.error;
|
||||||
|
return reject(null);
|
||||||
|
}
|
||||||
|
if (response?.data.done) {
|
||||||
|
this._responses[relay] = {};
|
||||||
|
resolve(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._options.streamHandler(response?.data.data);
|
||||||
|
});
|
||||||
|
socket.on("error", (error) => {
|
||||||
|
relay = relay;
|
||||||
|
this._errors[relay] = error;
|
||||||
|
reject({ error });
|
||||||
|
});
|
||||||
|
socket.write("rpc");
|
||||||
|
socket.write(pack(this._query));
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
this._errors[relay] = "timeout";
|
||||||
|
reject(null);
|
||||||
|
}, (this._options.relayTimeout || this._network.relayTimeout) * 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import RpcQueryBase from "./base.js";
|
||||||
|
export default class WisdomRpcQuery extends RpcQueryBase {
|
||||||
|
private _maxTries;
|
||||||
|
private _tries;
|
||||||
|
protected checkResponses(): void;
|
||||||
|
private retry;
|
||||||
|
protected getRelays(): string[] | [];
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=wisdom.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"wisdom.d.ts","sourceRoot":"","sources":["../../src/query/wisdom.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,WAAW,CAAC;AAOrC,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,YAAY;IACtD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,MAAM,CAAK;IAEnB,SAAS,CAAC,cAAc,IAAI,IAAI;IAoDhC,OAAO,CAAC,KAAK;IAWb,SAAS,CAAC,SAAS,IAAI,MAAM,EAAE,GAAG,EAAE;CAGrC"}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import RpcQueryBase from "./base.js";
|
||||||
|
import { flatten } from "../util.js";
|
||||||
|
import { Buffer } from "buffer";
|
||||||
|
import { blake2b } from "libskynet";
|
||||||
|
import { ERR_MAX_TRIES_HIT } from "../error.js";
|
||||||
|
export default class WisdomRpcQuery extends RpcQueryBase {
|
||||||
|
_maxTries = 3;
|
||||||
|
_tries = 0;
|
||||||
|
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) {
|
||||||
|
let response = responseObjects[responseHash];
|
||||||
|
// @ts-ignore
|
||||||
|
if (null === response) {
|
||||||
|
if (this._tries <= this._maxTries) {
|
||||||
|
this._tries++;
|
||||||
|
this.retry();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
response = { error: ERR_MAX_TRIES_HIT };
|
||||||
|
}
|
||||||
|
this.resolve(response);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retry() {
|
||||||
|
this._responses = {};
|
||||||
|
this._errors = {};
|
||||||
|
if (this._completed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.run();
|
||||||
|
}
|
||||||
|
getRelays() {
|
||||||
|
return this._network.relays;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue