From 01a32d87341452676bcbc5b927e84c0cea0cdb01 Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Thu, 4 Aug 2022 23:33:16 -0400 Subject: [PATCH] *refactor to use dynamic imports for ESM modules and do so via a helper that bypasses typescript parsing. --- src/dht.ts | 20 ++++++------ src/dns.ts | 12 +++++-- src/file.ts | 89 ++++++++++++++++++++++++++++++++++------------------ src/relay.ts | 6 +++- src/util.ts | 4 +++ 5 files changed, 86 insertions(+), 45 deletions(-) diff --git a/src/dht.ts b/src/dht.ts index 4804a42..7e326c6 100644 --- a/src/dht.ts +++ b/src/dht.ts @@ -3,14 +3,9 @@ // @ts-ignore import DHT from "@hyperswarm/dht"; -import { - deriveMyskyRootKeypair, - Ed25519Keypair, - seedPhraseToSeed, - validSeedPhrase, -} from "libskynet"; import config from "./config.js"; import { errorExit } from "./error.js"; +import { dynImport } from "./util.js"; let node: { ready: () => any; @@ -18,12 +13,17 @@ let node: { defaultKeyPair: any; on: any; }; -let server: { - listen: (arg0: Ed25519Keypair) => any; - on: any; -}; +let server: any; async function start() { + const { + deriveMyskyRootKeypair, + // @ts-ignore + Ed25519Keypair, + seedPhraseToSeed, + validSeedPhrase, + } = await dynImport("libskynet"); + const seed = config.str("seed"); let err = validSeedPhrase(seed); diff --git a/src/dns.ts b/src/dns.ts index 707e387..318b909 100644 --- a/src/dns.ts +++ b/src/dns.ts @@ -1,18 +1,19 @@ import cron from "node-cron"; -import fetch from "node-fetch"; import { get as getDHT } from "./dht.js"; -import { overwriteRegistryEntry } from "libskynetnode"; import { Buffer } from "buffer"; import { Parser } from "xml2js"; import { URL } from "url"; import { pack } from "msgpackr"; import config from "./config.js"; -import { hashDataKey } from "@lumeweb/kernel-utils"; import { errorExit } from "./error.js"; import log from "loglevel"; import { createHash } from "crypto"; +import { dynImport } from "./util.js"; let activeIp: string; +let fetch: typeof import("node-fetch").default; +let overwriteRegistryEntry: typeof import("libskynetnode").overwriteRegistryEntry; +let hashDataKey: typeof import("@lumeweb/kernel-utils").hashDataKey; const REGISTRY_NODE_KEY = "lumeweb-dht-node"; @@ -33,6 +34,11 @@ async function ipUpdate() { } export async function start() { + fetch = (await dynImport("node-fetch")).default; + overwriteRegistryEntry = (await dynImport("libskynetnode")) + .overwriteRegistryEntry; + hashDataKey = (await dynImport("@lumeweb/kernel-utils")).hashDataKey; + const dht = (await getDHT()) as any; await ipUpdate(); diff --git a/src/file.ts b/src/file.ts index a1b1efc..8b5c113 100644 --- a/src/file.ts +++ b/src/file.ts @@ -1,30 +1,7 @@ -import { - addContextToErr, - blake2b, - bufToHex, - Ed25519Keypair, - ed25519Sign, - encodePrefixedBytes, - encodeU64, - Err, -} from "libskynet"; -import { progressiveFetch } from "libskynetnode/dist/progressivefetch.js"; -import { defaultPortalList } from "libskynet/dist/defaultportals.js"; -import { readRegistryEntry } from "libskynetnode/dist/registryread.js"; -import { - bufToB64, - decryptFileSmall, - deriveChildSeed, - deriveRegistryEntryID, - encryptFileSmall, - entryIDToSkylink, - namespaceInode, - skylinkToResolverEntryData, - taggedRegistryEntryKeys, -} from "libskynet"; -import { upload } from "libskynetnode"; +import type { Ed25519Keypair, Err, progressiveFetchResult } from "libskynet"; // @ts-ignore import { SkynetClient } from "@skynetlabs/skynet-nodejs"; +import { dynImport } from "./util.js"; const ERR_EXISTS = "exists"; const ERR_NOT_EXISTS = "DNE"; @@ -63,12 +40,58 @@ interface IndependentFileSmallViewer { readData: ReadDataFn; } -function overwriteRegistryEntry( +let addContextToErr: typeof import("libskynet").addContextToErr, + blake2b: typeof import("libskynet").blake2b, + bufToHex: typeof import("libskynet").bufToHex, + ed25519Sign: typeof import("libskynet").ed25519Sign, + encodePrefixedBytes: typeof import("libskynet").encodePrefixedBytes, + encodeU64: typeof import("libskynet").encodeU64, + progressiveFetch: typeof import("libskynet").progressiveFetch, + defaultPortalList: typeof import("libskynet").defaultPortalList, + readRegistryEntry: typeof import("libskynetnode/dist/registryread.js").readRegistryEntry, + upload: typeof import("libskynetnode").upload, + skylinkToResolverEntryData: typeof import("libskynet").skylinkToResolverEntryData, + encryptFileSmall: typeof import("libskynet").encryptFileSmall, + deriveChildSeed: typeof import("libskynet").deriveChildSeed, + bufToB64: typeof import("libskynet").bufToB64, + decryptFileSmall: typeof import("libskynet").decryptFileSmall, + entryIDToSkylink: typeof import("libskynet").entryIDToSkylink, + deriveRegistryEntryID: typeof import("libskynet").deriveRegistryEntryID, + taggedRegistryEntryKeys: typeof import("libskynet").taggedRegistryEntryKeys, + namespaceInode: typeof import("libskynet").namespaceInode; + +async function loadLibs() { + const libskynet = await dynImport("libskynet"); + addContextToErr = libskynet.addContextToErr; + bufToHex = libskynet.bufToHex; + ed25519Sign = libskynet.ed25519Sign; + encodePrefixedBytes = libskynet.encodePrefixedBytes; + encodeU64 = libskynet.encodeU64; + defaultPortalList = libskynet.defaultPortalList; + skylinkToResolverEntryData = libskynet.skylinkToResolverEntryData; + encryptFileSmall = libskynet.encryptFileSmall; + deriveChildSeed = libskynet.deriveChildSeed; + bufToB64 = libskynet.bufToB64; + decryptFileSmall = libskynet.decryptFileSmall; + entryIDToSkylink = libskynet.entryIDToSkylink; + deriveRegistryEntryID = libskynet.deriveRegistryEntryID; + taggedRegistryEntryKeys = libskynet.taggedRegistryEntryKeys; + namespaceInode = libskynet.namespaceInode; + + progressiveFetch = (await dynImport("libskynetnode/dist/progressivefetch.js")) + .progressiveFetch; + readRegistryEntry = (await dynImport("libskynetnode/dist/registryread.js")) + .readRegistryEntry; + upload = (await dynImport("libskynetnode")).upload; +} + +async function overwriteRegistryEntry( keypair: any, datakey: Uint8Array, data: Uint8Array, revision: bigint ): Promise { + await loadLibs(); return new Promise((resolve, reject) => { if (data.length > 86) { reject("provided data is too large to fit in a registry entry"); @@ -119,7 +142,7 @@ function overwriteRegistryEntry( fetchOpts, defaultPortalList, verifyRegistryWrite - ).then((result) => { + ).then((result: progressiveFetchResult) => { if (result.success === true) { resolve(null); return; @@ -128,7 +151,8 @@ function overwriteRegistryEntry( }); }); } -function verifyRegistryWrite(response: Response): Promise { +async function verifyRegistryWrite(response: Response): Promise { + await loadLibs(); return new Promise((resolve) => { if (!("status" in response)) { resolve("response did not contain a status"); @@ -142,11 +166,12 @@ function verifyRegistryWrite(response: Response): Promise { }); } -function createIndependentFileSmall( +async function createIndependentFileSmall( seed: Uint8Array, userInode: string, fileData: Uint8Array ): Promise<[IndependentFileSmall, Err]> { + await loadLibs(); return new Promise(async (resolve) => { let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode); if (errNI !== null) { @@ -276,10 +301,11 @@ function createIndependentFileSmall( }); } -function openIndependentFileSmall( +async function openIndependentFileSmall( seed: Uint8Array, userInode: string ): Promise<[IndependentFileSmall, Err]> { + await loadLibs(); return new Promise(async (resolve) => { let [inode, errNI] = namespaceInode("IndependentFileSmall", userInode); if (errNI !== null) { @@ -378,10 +404,11 @@ function openIndependentFileSmall( resolve([ifile, null]); }); } -function overwriteIndependentFileSmall( +async function overwriteIndependentFileSmall( file: IndependentFileSmall, newData: Uint8Array ): Promise { + await loadLibs(); return new Promise(async (resolve) => { // Create a new metadata for the file based on the current file // metadata. Need to update the largest historic size. diff --git a/src/relay.ts b/src/relay.ts index 83fd33a..116ae5c 100644 --- a/src/relay.ts +++ b/src/relay.ts @@ -22,10 +22,10 @@ import { openIndependentFileSmall, overwriteIndependentFileSmall, } from "./file.js"; -import { seedPhraseToSeed } from "libskynet"; import log from "loglevel"; import { AddressInfo } from "net"; import { sprintf } from "sprintf-js"; +import { dynImport } from "./util.js"; let sslCtx: tls.SecureContext = tls.createSecureContext(); const sslParams: tls.SecureContextOptions = { cert: "", key: "" }; @@ -35,6 +35,8 @@ let acmeClient: acme.Client; let app: Express; let router = express.Router(); +let seedPhraseToSeed: typeof import("libskynet").seedPhraseToSeed; + const FILE_CERT_NAME = "/lumeweb/relay/ssl.crt"; const FILE_KEY_NAME = "/lumeweb/relay/ssl.key"; const FILE_ACCOUNT_KEY_NAME = "/lumeweb/relay/account.key"; @@ -42,6 +44,8 @@ const FILE_ACCOUNT_KEY_NAME = "/lumeweb/relay/account.key"; type SslData = { crt: IndependentFileSmall; key: IndependentFileSmall }; export async function start() { + seedPhraseToSeed = (await dynImport("libskynet")).seedPhraseToSeed; + const relayPort = config.uint("port"); app = express(); app.use(function (req, res, next) { diff --git a/src/util.ts b/src/util.ts index 5436b32..db34b19 100644 --- a/src/util.ts +++ b/src/util.ts @@ -32,3 +32,7 @@ export function isIp(ip: string) { ip ); } + +export function dynImport(module: string) { + return Function(`return import("${module}")`)() as Promise; +}