From f005ebfcf9113aa73722bbd5392557cb8ce35b3e Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Sun, 19 Feb 2023 15:23:34 -0500 Subject: [PATCH] *Update to new system design *Remove rpc code for now --- package.json | 17 +- src-build/build.ts | 431 +++++++++++++++------------------------- src/common.ts | 5 +- src/index.ts | 21 +- src/relays.ts | 64 ------ src/resolverRegistry.ts | 40 ++-- src/ws.ts | 74 ------- 7 files changed, 191 insertions(+), 461 deletions(-) delete mode 100644 src/relays.ts delete mode 100644 src/ws.ts diff --git a/package.json b/package.json index 3a3ae37..19fa85d 100644 --- a/package.json +++ b/package.json @@ -23,19 +23,22 @@ "@lumeweb/safe-buffer": "^5.2.1", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.3.0", + "@scure/bip39": "^1.1.1", "@skynetlabs/skynet-nodejs": "^2.6.0", + "@types/node": "^18.14.0", "@types/read": "^0.0.29", "@typescript-eslint/eslint-plugin": "^5.18.0", "assert": "^2.0.0", "buffer-browserify": "^0.2.5", "buffer-fill": "^1.0.0", + "cli-progress": "^3.12.0", "cpy-cli": "^4.1.0", "crypto-browserify": "^3.12.0", "esbuild": "^0.14.47", "eslint": "^8.13.0", "events": "^3.3.0", "https-browserify": "^1.0.0", - "libskynet": "^0.0.43", + "libskynet": "^0.1.9", "libskynetnode": "^0.1.2", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", @@ -49,13 +52,13 @@ "whatwg-fetch": "^3.6.2" }, "dependencies": { - "@lumeweb/kernel-dht-client": "https://github.com/LumeWeb/kernel-dht-client.git", - "@lumeweb/kernel-rpc-client": "https://github.com/LumeWeb/kernel-rpc-client.git", - "@lumeweb/kernel-utils": "https://github.com/LumeWeb/kernel-utils.git", - "@lumeweb/resolver-common": "github:LumeWeb/resolver-common", + "@lumeweb/kernel-swarm-client": "git+https://git.lumeweb.com/LumeWeb/kernel-swarm-client.git", + "@lumeweb/libkernel-universal": "git+https://git.lumeweb.com/LumeWeb/libkernel-universal.git", + "@lumeweb/libresolver": "git+https://git.lumeweb.com/LumeWeb/libresolver.git", + "@siaweb/libweb": "git+https://git.lumeweb.com/LumeWeb/libsiaweb.git", "libkmodule": "^0.2.11", - "randombytes": "https://github.com/LumeWeb/randombytes-browser.git", - "randomfill": "https://github.com/LumeWeb/randomfill.git" + "randombytes": "git+https://github.com/LumeWeb/randombytes-browser.git", + "randomfill": "git+https://github.com/LumeWeb/randomfill.git" }, "browser": { "crypto": "crypto-browserify", diff --git a/src-build/build.ts b/src-build/build.ts index 8adbca2..8703c34 100644 --- a/src-build/build.ts +++ b/src-build/build.ts @@ -1,105 +1,50 @@ // This is the standard build script for a kernel module. -import * as fs from "fs" -import { - addContextToErr, - b64ToBuf, - bufToHex, - deriveRegistryEntryID, - generateSeedPhraseDeterministic, - resolverLink, - sha512, - taggedRegistryEntryKeys, - validSeedPhrase, -} from "libskynet" -import { generateSeedPhraseRandom, overwriteRegistryEntry, upload } from "libskynetnode" -import read from "read" -// @ts-ignore -import {SkynetClient} from "@skynetlabs/skynet-nodejs" +import * as fs from "fs"; +import read from "read"; +import * as bip39 from "@scure/bip39"; +import { wordlist } from "@scure/bip39/wordlists/english.js"; +//@ts-ignore +import { SkynetClient } from "@skynetlabs/skynet-nodejs"; // Helper variables to make it easier to return empty values alongside errors. -const nu8 = new Uint8Array(0) +const nu8 = new Uint8Array(0); const nkp = { - publicKey: nu8, - secretKey: nu8, -} + publicKey: nu8, + secretKey: nu8, +}; // readFile is a wrapper for fs.readFileSync that handles the try-catch for the // caller. function readFile(fileName: string): [string, string | null] { - try { - let data = fs.readFileSync(fileName, "utf8") - return [data, null] - } catch (err) { - return ["", "unable to read file: " + JSON.stringify(err)] - } + try { + let data = fs.readFileSync(fileName, "utf8"); + return [data, null]; + } catch (err) { + return ["", "unable to read file: " + JSON.stringify(err)]; + } } // readFileBinary is a wrapper for fs.readFileSync that handles the try-catch // for the caller. function readFileBinary(fileName: string): [Uint8Array, string | null] { - try { - let data = fs.readFileSync(fileName, null) - return [data, null] - } catch (err) { - return [nu8, "unable to read file: " + JSON.stringify(err)] - } + try { + let data = fs.readFileSync(fileName, null); + return [data, null]; + } catch (err) { + return [nu8, "unable to read file: " + JSON.stringify(err)]; + } } // writeFile is a wrapper for fs.writeFileSync which handles the try-catch in a // non-exception way. function writeFile(fileName: string, fileData: string): string | null { - try { - fs.writeFileSync(fileName, fileData) - return null - } catch (err) { - return "unable to write file: " + JSON.stringify(err) - } -} - -// hardenedSeedPhrase will take a password, harden it with 100,000 iterations -// of hashing, and then turn it into a seed phrase. -function hardenedSeedPhrase(password: string): [string, string | null] { - let pw = password - // Add some hashing iterations to the password to make it stronger. - for(let i = 0; i < 1000000; i++) { - let passU8 = new TextEncoder().encode(password) - let hashIter = sha512(passU8) - password = bufToHex(hashIter) - } - return generateSeedPhraseDeterministic(password) -} - -// seedPhraseToRegistryKeys will convert a seed phrase to the set of registry -// keys that govern the registry entry where the module is published. -function seedPhraseToRegistryKeys(seedPhrase: string): [any, Uint8Array, string | null] { - let [seed, errVSP] = validSeedPhrase(seedPhrase) - if (errVSP !== null) { - return [nkp, nu8, addContextToErr(errVSP, "unable to compute seed phrase")] - } - let [keypair, datakey, errTREK] = taggedRegistryEntryKeys(seed, "module-build", "module-key") - if (errTREK !== null) { - return [nkp, nu8, addContextToErr(errTREK, "unable to compute registry entry keys")] - } - return [keypair, datakey, null] -} - -// seedPhraseToRegistryLink will take a seedPhrase as input and convert it to -// the registry link for the module. -function seedPhraseToRegistryLink(seedPhrase: string): [string, string | null] { - let [keypair, datakey, errSPTRK] = seedPhraseToRegistryKeys(seedPhrase) - if (errSPTRK !== null) { - return ["", addContextToErr(errSPTRK, "unable to compute registry keys")] - } - let [entryID, errDREID] = deriveRegistryEntryID(keypair.publicKey, datakey) - if (errDREID !== null) { - return ["", addContextToErr(errDREID, "unable to compute registry entry id")] - } - let [registryLink, errRL] = resolverLink(entryID) - if (errRL !== null) { - return ["", addContextToErr(errRL, "unable to compute registry link")] - } - return [registryLink, null] + try { + fs.writeFileSync(fileName, fileData); + return null; + } catch (err) { + return "unable to write file: " + JSON.stringify(err); + } } // handlePass handles all portions of the script that occur after the password @@ -108,230 +53,166 @@ function seedPhraseToRegistryLink(seedPhrase: string): [string, string | null] { // password reader is async and we can only access the password when using a // callback. function handlePass(password: string) { - try { - // If we are running prod and the seed file does not exist, we - // need to confirm the password and also warn the user to use a - // secure password. - if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { - // The file does not exist, we need to confirm the - // password. - console.log() - console.log("No production entry found for module. Creating new production module...") - console.log("If someone can guess the password, they can push arbitrary changes to your module.") - console.log("Please use a secure password.") - console.log() - read({ prompt: "Confirm Password: ", silent: true }, function (err: any, confirmPassword: string) { - if (err) { - console.error("unable to fetch password:", err) - process.exit(1) - } - if (password !== confirmPassword) { - console.error("passwords do not match") - process.exit(1) - } - password = password + moduleSalt - handlePassConfirm(password) - }) - } else { - // If the seed file does exist, or if we are using dev, - // there's no need to confirm the password but we do - // need to pass the logic off to the handlePassConfirm - // callback. - password = password + moduleSalt - handlePassConfirm(password) - } - } catch (err) { - console.error("Unable to read seedFile:", err) - process.exit(1) - } + try { + // If we are running prod and the seed file does not exist, we + // need to confirm the password and also warn the user to use a + // secure password. + if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { + // The file does not exist, we need to confirm the + // password. + console.log(); + console.log( + "No production entry found for module. Creating new production module..." + ); + console.log( + "If someone can guess the password, they can push arbitrary changes to your module." + ); + console.log("Please use a secure password."); + console.log(); + read( + { prompt: "Confirm Password: ", silent: true }, + function (err: any, confirmPassword: string) { + if (err) { + console.error("unable to fetch password:", err); + process.exit(1); + } + if (password !== confirmPassword) { + console.error("passwords do not match"); + process.exit(1); + } + handlePassConfirm(moduleSalt, password); + } + ); + } else { + // If the seed file does exist, or if we are using dev, + // there's no need to confirm the password but we do + // need to pass the logic off to the handlePassConfirm + // callback. + handlePassConfirm(moduleSalt, password); + } + } catch (err) { + console.error("Unable to read seedFile:", err); + process.exit(1); + } } // handlePassConfirm handles the full script after the confirmation password // has been provided. If not confirmation password is needed, this function // will be called anyway using the unconfirmed password as input. -function handlePassConfirm(password: string) { - // Create the seedFile if it does not exist. For dev we just save the - // seed to disk outright, because this is a dev build and therefore not - // security sensitive. Also the dev seed does not get pushed to the - // github repo. - // - // For prod, we use the seed to create a new seed (called the shield) - // which allows us to verify that the developer has provided the right - // password when deploying the module. The shield does get pushed to - // the github repo so that the production module is the same on all - // devices. - if (!fs.existsSync(seedFile) && process.argv[2] !== "prod") { - // Generate the seed phrase and write it to the file. - let [seedPhrase, errGSP] = generateSeedPhraseRandom() - if (errGSP !== null) { - console.error("Unable to generate seed phrase:", errGSP) - process.exit(1) - } - let errWF = writeFile(seedFile, seedPhrase) - if (errWF !== null) { - console.error("unable to write file:", errWF) - process.exit(1) - } - } else if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { - // Generate the seed phrase. - let [seedPhrase, errGSP] = hardenedSeedPhrase(password) - if (errGSP !== null) { - console.error("Unable to generate seed phrase:", errGSP) - process.exit(1) - } - let [registryLink, errSPTRL] = seedPhraseToRegistryLink(seedPhrase) - if (errSPTRL !== null) { - console.error("Unable to generate registry link:", errSPTRL) - process.exit(1) - } +function handlePassConfirm(seed: string, password: string) { + // Create the seedFile if it does not exist. For dev we just save the + // seed to disk outright, because this is a dev build and therefore not + // security sensitive. Also the dev seed does not get pushed to the + // github repo. + // + // For prod, we use the seed to create a new seed (called the shield) + // which allows us to verify that the developer has provided the right + // password when deploying the module. The shield does get pushed to + // the github repo so that the production module is the same on all + // devices. + if (!fs.existsSync(seedFile) && process.argv[2] !== "prod") { + // Generate the seed phrase and write it to the file. + let seedPhrase = bip39.generateMnemonic(wordlist); + let errWF = writeFile(seedFile, seedPhrase); + if (errWF !== null) { + console.error("unable to write file:", errWF); + process.exit(1); + } + } else if (!fs.existsSync(seedFile) && process.argv[2] === "prod") { + // Generate the seed phrase. + let seedPhrase = bip39.generateMnemonic(wordlist); + // Write the registry link to the file. + } - // Write the registry link to the file. - let errWF = writeFile(seedFile, registryLink) - if (errWF !== null) { - console.error("unable to write registry link file:", errWF) - process.exit(1) - } - } + // Load or verify the seed. If this is prod, the password is used to + // create and verify the seed. If this is dev, we just load the seed + // with no password. + let seedPhrase: string; + let registryLink: string; + if (process.argv[2] === "prod") { + // Generate the seed phrase from the password. + seedPhrase = bip39.generateMnemonic(wordlist); + } else { + let [sp, errRF] = readFile(seedFile); + if (errRF !== null) { + console.error("unable to read seed phrase for dev command from disk"); + process.exit(1); + } + seedPhrase = sp; + } - // Load or verify the seed. If this is prod, the password is used to - // create and verify the seed. If this is dev, we just load the seed - // with no password. - let seedPhrase: string - let registryLink: string - if (process.argv[2] === "prod") { - // Generate the seed phrase from the password. - let [sp, errGSP] = hardenedSeedPhrase(password) - if (errGSP !== null) { - console.error("Unable to generate seed phrase: ", errGSP) - process.exit(1) - } - let [rl, errSPTRL] = seedPhraseToRegistryLink(sp) - registryLink = rl - if (errSPTRL !== null) { - console.error("Unable to generate registry link:", errSPTRL) - process.exit(1) - } - let [registryLinkVerify, errRF] = readFile(seedFile) - if (errRF !== null) { - console.error("unable to read seedFile") - process.exit(1) - } - registryLinkVerify = registryLinkVerify.replace(/\n$/, "") - if (registryLink !== registryLinkVerify) { - console.error("Incorrect password") - process.exit(1) - } - seedPhrase = sp - } else { - let [sp, errRF] = readFile(seedFile) - if (errRF !== null) { - console.error("unable to read seed phrase for dev command from disk") - process.exit(1) - } - let [rl, errSPTRL] = seedPhraseToRegistryLink(sp) - registryLink = rl - if (errSPTRL !== null) { - console.error("Unable to generate registry link:", errSPTRL) - process.exit(1) - } - // Write the registry link to the module skylink dev file. - let errWF = writeFile("build/module-skylink-dev", registryLink) - if (errWF !== null) { - console.error("unable to write registry link file:", errWF) - process.exit(1) - } - seedPhrase = sp - } - - console.log("Uploading module...") - const client = new SkynetClient("https://web3portal.com"); - client.uploadFile("dist/index.js") - .then((result:any) => { - console.log("Updating module's registry entry...") - // Update the v2 skylink. - let [keypair, datakey, errSPTRK] = seedPhraseToRegistryKeys(seedPhrase) - if (errSPTRK !== null) { - return ["", addContextToErr(errSPTRK, "unable to compute registry keys")] - } - let [bufLink, errBTB] = b64ToBuf(result.replace("sia://","")) - if (errBTB !== null) { - return ["", addContextToErr(errBTB, "unable to decode skylink")] - } - overwriteRegistryEntry(keypair, datakey, bufLink) - .then(() => { - console.log("registry entry is updated") - console.log("Immutable Link for Module:", result) - console.log("Resolver Link for Module:", registryLink) - }) - .catch((err: any) => { - console.log("unable to update registry entry:", err) - }) - }) - .catch((err) => { - console.error("unable to upload file", err) - process.exit(1) - }) + let metadata = { + Filename: "index.js", + }; + const client = new SkynetClient("https://web3portal.com"); + client + .uploadFile("dist/index.js") + .then((result: any) => { + console.log("Immutable Link for kernel:", result); + }) + .catch((err: any) => { + console.error("unable to upload file", err); + process.exit(1); + }); } // Add a newline for readability. -console.log() +console.log(); // Check for a 'dev' or 'prod' input to the script. if (process.argv.length !== 3) { - console.error("need to provide either 'dev' or 'prod' as an input") - process.exit(1) + console.error("need to provide either 'dev' or 'prod' as an input"); + process.exit(1); } // Create the build folder if it does not exist. if (!fs.existsSync("build")) { - fs.mkdirSync("build") + fs.mkdirSync("build"); } // Determine the seed file. -let seedFile: string +let seedFile: string; if (process.argv[2] === "prod") { - seedFile = "module-skylink" + seedFile = "module-skylink"; } else if (process.argv[2] === "dev") { - seedFile = "build/dev-seed" + seedFile = "build/dev-seed"; } else { - console.error("need to provide either 'dev' or 'prod' as an input") - process.exit(1) + console.error("need to provide either 'dev' or 'prod' as an input"); + process.exit(1); } // If doing a prod deployment, check whether the salt file exists. If it does // not, create it. -let moduleSalt: string +let moduleSalt: string; if (!fs.existsSync(".module-salt")) { - let [ms, errGSPR] = generateSeedPhraseRandom() - if (errGSPR !== null) { - console.error("unable to generate module salt:", errGSPR) - process.exit(1) - } - moduleSalt = ms - let errWF = writeFile(".module-salt", moduleSalt) - if (errWF !== null) { - console.error("unable to write module salt file:", errWF) - process.exit(1) - } + moduleSalt = bip39.generateMnemonic(wordlist); + let errWF = writeFile(".module-salt", moduleSalt); + if (errWF !== null) { + console.error("unable to write module salt file:", errWF); + process.exit(1); + } } else { - let [ms, errRF] = readFile(".module-salt") - if (errRF !== null) { - console.error("unable to read moduleSalt") - process.exit(1) - } - ms = ms.replace(/\n$/, "") - moduleSalt = ms + let [ms, errRF] = readFile(".module-salt"); + if (errRF !== null) { + console.error("unable to read moduleSalt"); + process.exit(1); + } + ms = ms.replace(/\n$/, ""); + moduleSalt = ms; } // Need to get a password if this is a prod build. if (process.argv[2] === "prod") { - read({ prompt: "Password: ", silent: true }, function (err: any, password: string) { - if (err) { - console.error("unable to fetch password:", err) - process.exit(1) - } - handlePass(password) - }) + read( + { prompt: "Password: ", silent: true }, + function (err: any, password: string) { + if (err) { + console.error("unable to fetch password:", err); + process.exit(1); + } + handlePass(password); + } + ); } else { - handlePass("") + handlePass(""); } diff --git a/src/common.ts b/src/common.ts index 382b323..41497f7 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,6 +1,3 @@ -import { RpcNetwork } from "@lumeweb/kernel-rpc-client"; import { ResolverRegistry } from "./resolverRegistry.js"; -const network: RpcNetwork = new RpcNetwork(); - -export const resolver = new ResolverRegistry(network as any); +export const resolver = new ResolverRegistry(); diff --git a/src/index.ts b/src/index.ts index 65c5e77..fe2e4ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,12 +2,10 @@ import { addHandler, handleMessage } from "libkmodule"; import type { ActiveQuery } from "libkmodule"; import { resolver } from "./common.js"; -import { relayReady, setupRelayListSubscription } from "./relays.js"; -import { validSkylink } from "libskynet/dist/skylinkvalidate.js"; +import { validateSkylink } from "@siaweb/libweb/dist/skylinkValidate.js"; import { ResolverModule } from "./resolverRegistry.js"; -import { b64ToBuf } from "libskynet"; - -setupRelayListSubscription(); +import { b64ToBuf } from "@siaweb/libweb"; +import { factory } from "@lumeweb/libkernel-universal"; addHandler("resolve", handleResolve); addHandler("register", handleRegister); @@ -22,23 +20,24 @@ async function handleResolve(aq: ActiveQuery) { return; } - await relayReady(); aq.respond( await resolver.resolve( - aq.callerInput.domain, - aq.callerInput.options ?? {}, - aq.callerInput.bypassCache || false + query?.domain, + query?.options, + query?.bypassCache || false ) ); } async function handleRegister(aq: ActiveQuery) { - if (!validSkylink(b64ToBuf(aq.domain).shift() as Uint8Array)) { + if (!validateSkylink(b64ToBuf(aq.domain).shift() as Uint8Array)?.[1]) { aq.reject("invalid skylink"); return; } - resolver.register(new ResolverModule(resolver, aq.domain)); + resolver.register( + factory(ResolverModule, aq.domain)(resolver, aq.domain) + ); aq.respond(); } diff --git a/src/relays.ts b/src/relays.ts deleted file mode 100644 index 1bfdf25..0000000 --- a/src/relays.ts +++ /dev/null @@ -1,64 +0,0 @@ -import WSReconnect from "./ws.js" -import {resolver} from "./common.js" -import {hashDataKey} from "@lumeweb/kernel-utils"; -import {bufToHex} from "libskynet"; -import {deriveRegistryEntryID, downloadSkylink} from "libskynet"; -import {entryIDToSkylink} from "libskynet"; -import {RpcNetwork} from "@lumeweb/kernel-rpc-client"; - -const relayListName = "lumeweb-relays" -const relayListOwner = Buffer.from("86c7421160eb5cb4a39495fc3e3ae25a60b330fff717e06aab978ad353722014", "hex"); - -/* - TODO: Use kernel code to use many different portals and not hard code a portal - */ -let portalConnection: WSReconnect - -let relayPromiseResolve: any = () => true; -let relayPromise: Promise; - -export function relayReady(): Promise { - return relayPromise; -} - -function resetRelayPromise() { - relayPromise = new Promise((resolve) => { - relayPromiseResolve = resolve; - }) -} - -async function fetchRelays() { -/* const [data, err] = await downloadSkylink(entryIDToSkylink(deriveRegistryEntryID(relayListOwner, hashDataKey(relayListName))[0])) - if (err) { - return; - }*/ - // const list: string[] = JSON.parse(Buffer.from(data).toString()); - const list: string[] = ["ef92890bec753c86cfecbe1adea632a8aa130d479bab69ec999c0ea28afd48cf"]; - resolver.rpcNetwork.clearRelays(); - list.forEach((item) => { - resolver.rpcNetwork.addRelay(item); - }); - await (resolver.rpcNetwork as unknown as RpcNetwork).processQueue() - relayPromiseResolve() - // resetRelayPromise(); -} - -export function setupRelayListSubscription() { -/* portalConnection = new WSReconnect("wss://web3portal.com/skynet/registry/subscription") - // @ts-ignore - portalConnection.on("connect", () => { - portalConnection.send( - JSON.stringify({ - action: "subscribe", - pubkey: `ed25519:${relayListOwner}`, - datakey: bufToHex(hashDataKey(relayListName)), - }) - ) - }) - - // @ts-ignore - portalConnection.on("message", fetchRelays) - portalConnection.start()*/ - resetRelayPromise(); - fetchRelays() -} diff --git a/src/resolverRegistry.ts b/src/resolverRegistry.ts index f010e76..9bf908e 100644 --- a/src/resolverRegistry.ts +++ b/src/resolverRegistry.ts @@ -3,33 +3,21 @@ import { ResolverOptions, DNS_RECORD_TYPE, resolverError, -} from "@lumeweb/resolver-common"; -import type { RpcNetwork } from "@lumeweb/kernel-rpc-client"; -import { callModule } from "libkmodule/dist"; +} from "@lumeweb/libresolver"; +import { Client } from "@lumeweb/libkernel-universal"; export class ResolverRegistry { - constructor(network: RpcNetwork) { - this._rpcNetwork = network; - } - private _resolvers: Set = new Set(); get resolvers(): Set { return this._resolvers; } - - private _rpcNetwork: RpcNetwork; - - get rpcNetwork(): RpcNetwork { - return this._rpcNetwork; - } - public async resolve( domain: string, - options: ResolverOptions = { type: DNS_RECORD_TYPE.DEFAULT }, + options: ResolverOptions = { type: DNS_RECORD_TYPE.CONTENT }, bypassCache: boolean = false ): Promise { - for (const resolver: ResolverModule of this._resolvers) { + for (const resolver of this._resolvers) { const result = await resolver.resolve(domain, options, bypassCache); if (!result.error && result.records.length) { return result; @@ -55,10 +43,11 @@ export class ResolverRegistry { } } -export class ResolverModule { +export class ResolverModule extends Client { private _resolver: ResolverRegistry; constructor(resolver: ResolverRegistry, domain: string) { + super(); this._resolver = resolver; this._domain = domain; } @@ -74,15 +63,14 @@ export class ResolverModule { options: ResolverOptions, bypassCache: boolean ): Promise { - const [ret, err] = await callModule(this._domain, "resolve", { - domain, - options, - bypassCache, - }); - if (err) { - return resolverError(err); + try { + return this.callModuleReturn("resolve", { + domain, + options, + bypassCache, + }); + } catch (e: any) { + return resolverError(e as Error); } - - return ret; } } diff --git a/src/ws.ts b/src/ws.ts deleted file mode 100644 index a873fff..0000000 --- a/src/ws.ts +++ /dev/null @@ -1,74 +0,0 @@ -import EventEmitter from "events" - -interface Options { - retryCount?: number - reconnectInterval?: number -} - -/* - Ported from https://github.com/ofirattia/ws-reconnect - */ -export default class WSReconnect extends EventEmitter { - private url: string - private options: Options - private retryCount: number - private _retryCount: number - private reconnectInterval: number - private shouldAttemptReconnect: boolean - private isConnected = false - private socket: WebSocket | undefined - private reconnectTimeoutId: NodeJS.Timeout | undefined - - constructor(url: string, options: Options = {}) { - super() - this.url = url - this.options = options - this.retryCount = this.options.retryCount || -1 - this._retryCount = this.retryCount - this.reconnectInterval = this.options?.reconnectInterval ?? 5 - this.shouldAttemptReconnect = !!this.reconnectInterval - } - - start() { - this.shouldAttemptReconnect = !!this.reconnectInterval - this.isConnected = false - this.socket = new WebSocket(this.url) - this.socket.onmessage = this.onMessage.bind(this) - this.socket.onopen = this.onOpen.bind(this) - this.socket.onclose = this.onClose.bind(this) - } - - destroy() { - clearTimeout(this.reconnectTimeoutId as NodeJS.Timeout) - this.shouldAttemptReconnect = false - this.socket?.close() - } - - onOpen() { - this.isConnected = true - this.emit("connect") - // set again the retry count - this.retryCount = this._retryCount - } - - onClose() { - if (this.shouldAttemptReconnect && (this.retryCount > 0 || this.retryCount == -1)) { - if (this.retryCount !== -1) this.retryCount-- - clearTimeout(this.reconnectTimeoutId as NodeJS.Timeout) - this.reconnectTimeoutId = setTimeout(() => { - this.emit("reconnect") - this.start() - }, this.reconnectInterval * 1000) - } else { - this.emit("destroyed") - } - } - - onMessage(message: MessageEvent) { - this.emit("message", message.data) - } - - send(message: string | ArrayBufferLike | Blob | ArrayBufferView) { - this.socket?.send(message) - } -}