From 508eb692e3197dc495c5cb9f3e56272e563d79fe Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Thu, 18 Aug 2022 16:35:40 -0400 Subject: [PATCH] *First steps in breaking resolver framework to be modular --- package.json | 5 +-- src/common.ts | 8 ++--- src/index.ts | 60 ++++++++++++++++++++++++--------- src/resolverRegistry.ts | 74 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 src/resolverRegistry.ts diff --git a/package.json b/package.json index 5fbbe27..3a3ae37 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@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": "https://github.com/LumeWeb/resolver.git#hypercore", + "@lumeweb/resolver-common": "github:LumeWeb/resolver-common", "libkmodule": "^0.2.11", "randombytes": "https://github.com/LumeWeb/randombytes-browser.git", "randomfill": "https://github.com/LumeWeb/randomfill.git" @@ -63,6 +63,7 @@ "os": "os-browserify", "stream": "os-browserify", "libskynetnode": false, - "js-sha3": "@lumeweb/js-sha3-browser" + "js-sha3": "@lumeweb/js-sha3-browser", + "@lumeweb/dht-rpc-client": false } } diff --git a/src/common.ts b/src/common.ts index a3f9fc5..382b323 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,6 +1,6 @@ -import resolvers from "@lumeweb/resolver" -import { RpcNetwork } from "@lumeweb/kernel-rpc-client" +import { RpcNetwork } from "@lumeweb/kernel-rpc-client"; +import { ResolverRegistry } from "./resolverRegistry.js"; -const network = new RpcNetwork() +const network: RpcNetwork = new RpcNetwork(); -export const resolver = resolvers.createDefaultResolver(network as any) +export const resolver = new ResolverRegistry(network as any); diff --git a/src/index.ts b/src/index.ts index 2b486c0..bbd8f39 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,24 +1,52 @@ -import {addHandler, handleMessage} from "libkmodule" -import type {ActiveQuery} from "libkmodule" -import {resolver} from "./common.js" +import { addHandler, handleMessage } from "libkmodule"; +import type { ActiveQuery } from "libkmodule"; +import { resolver } from "./common.js"; -import {relayReady, setupRelayListSubscription} from "./relays.js" +import { relayReady, setupRelayListSubscription } from "./relays.js"; +import { validSkylink } from "libskynet/dist/skylinkvalidate.js"; +import { ResolverModule } from "./resolverRegistry.js"; +import { b64ToBuf } from "libskynet"; -setupRelayListSubscription() +setupRelayListSubscription(); -addHandler("resolve", resolveHandler) -onmessage = handleMessage +addHandler("resolve", handleResolve); +addHandler("register", handleRegister); +addHandler("clear", handleClear); +addHandler("getResolvers", handleGetResolvers); +onmessage = handleMessage; -async function resolveHandler(aq: ActiveQuery) { - const query = aq.callerInput +async function handleResolve(aq: ActiveQuery) { + const query = aq.callerInput; + if (!("domain" in query)) { + aq.reject("domain required"); + return; + } - if (!("domain" in query)) { - aq.reject("domain required") - return - } - - await relayReady(); - aq.respond(await resolver.resolve(aq.callerInput.domain, aq.callerInput.params ?? {}, aq.callerInput.force || false)) + await relayReady(); + aq.respond( + await resolver.resolve( + aq.callerInput.domain, + aq.callerInput.options ?? {}, + aq.callerInput.bypassCache || false + ) + ); } +async function handleRegister(aq: ActiveQuery) { + if (!validSkylink(b64ToBuf(aq.domain).shift() as Uint8Array)) { + aq.reject("invalid skylink"); + return; + } + resolver.register(new ResolverModule(resolver, aq.domain)); + aq.respond(); +} + +async function handleClear(aq: ActiveQuery) { + resolver.clear(); + aq.respond(); +} + +async function handleGetResolvers(aq: ActiveQuery) { + aq.respond([...resolver.resolvers.values()]); +} diff --git a/src/resolverRegistry.ts b/src/resolverRegistry.ts new file mode 100644 index 0000000..10590b2 --- /dev/null +++ b/src/resolverRegistry.ts @@ -0,0 +1,74 @@ +import { + DNSResult, + ResolverOptions, + DNS_RECORD_TYPE, + resolverError, +} from "@lumeweb/resolver-common"; +import type { RpcNetwork } from "@lumeweb/kernel-rpc-client"; +import { callModule } from "libkmodule/dist"; + +export class ResolverRegistry { + private _resolvers: Set = new Set(); + private _rpcNetwork: RpcNetwork; + + constructor(network: RpcNetwork) { + this._rpcNetwork = network; + } + + get resolvers(): Set { + return this._resolvers; + } + + get rpcNetwork(): RpcNetwork { + return this._rpcNetwork; + } + + public async resolve( + domain: string, + options: ResolverOptions = { type: DNS_RECORD_TYPE.DEFAULT }, + bypassCache: boolean = false + ): Promise { + for (const resolver of this._resolvers) { + const result = await resolver.resolve(domain, options, bypassCache); + if (!result.error && result.records.length) { + return result; + } + } + + return { records: [] }; + } + + public register(resolver: ResolverModule): void { + this._resolvers.add(resolver); + } + + public clear(): void { + this._resolvers.clear(); + } +} + +export class ResolverModule { + private resolver: ResolverRegistry; + private domain: string; + + constructor(resolver: ResolverRegistry, domain: string) { + this.resolver = resolver; + } + + async resolve( + domain: string, + options: ResolverOptions, + bypassCache: boolean + ): Promise { + const [ret, err] = await callModule(this.domain, "resolve", { + domain, + options, + bypassCache, + }); + if (err) { + return resolverError(err); + } + + return ret; + } +}