Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/package-lock.json
/.vscode
/data
/test-lightclient-node
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"./wasm/light-client-db-worker",
"./wasm/light-client-wasm",
"./wasm/light-client-js"
]
],
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
16 changes: 16 additions & 0 deletions wasm/light-client-db-worker/index.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as wasmModule from "./pkg/light-client-db-worker.js";
import wasm from "./pkg/light-client-db-worker_bg.wasm"
import "fake-indexeddb/auto"
import path from "path";

import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// const indexedDB = IndexedDB.create(destructible, path.join(__dirname, 'tmp', 'readme'))
globalThis.indexedDB = indexedDB;

wasmModule.initSync({ module: wasm });

export default wasmModule;
5 changes: 0 additions & 5 deletions wasm/light-client-db-worker/index.ts

This file was deleted.

6 changes: 5 additions & 1 deletion wasm/light-client-db-worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"serve": "webpack serve"
},
"devDependencies": {
"@types/node": "^25.0.2",
"@wasm-tool/wasm-pack-plugin": "1.5.0",
"arraybuffer-loader": "^1.0.8",
"buffer": "^6.0.3",
Expand All @@ -16,5 +17,8 @@
"webpack-cli": "^5.1.4"
},
"main": "dist/index.js",
"version": "0.1.0"
"version": "0.1.0",
"dependencies": {
"fake-indexeddb": "^6.2.5"
}
}
4 changes: 2 additions & 2 deletions wasm/light-client-db-worker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ pub async fn main_loop(log_level: &str) {
match wait_for_command_sync(&input_i32_arr, InputCommand::Waiting)
.unwrap()
{
s @ (InputCommand::Waiting
| InputCommand::OpenDatabase
InputCommand::Waiting => {},
s @ (InputCommand::OpenDatabase
| InputCommand::Shutdown
| InputCommand::ResponseTakeWhile) => {
log::warn!(
Expand Down
4 changes: 2 additions & 2 deletions wasm/light-client-db-worker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"compilerOptions": {
"outDir": "./dist/",
"noImplicitAny": true,
"module": "es6",
"module": "nodenext",
"target": "ES2015",
"allowJs": true,
"moduleResolution": "node",
"moduleResolution": "nodenext",
"sourceMap": true,
"declaration": true,
"declarationDir": "dist",
Expand Down
22 changes: 13 additions & 9 deletions wasm/light-client-db-worker/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const path = require('path');
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
const webpack = require("webpack");
module.exports = {
entry: './index.ts',
target: "webworker",
entry: './index.mts',
target: "node",
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
Expand All @@ -19,9 +19,9 @@ module.exports = {
outName: "light-client-db-worker",
extraArgs: "--target web"
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
// new webpack.ProvidePlugin({
// Buffer: ['buffer', 'Buffer'],
// }),
],
module: {
rules: [
Expand All @@ -40,9 +40,13 @@ module.exports = {
outputModule: true
},
mode: "production",
resolve: {
fallback: {
buffer: require.resolve('buffer/'),
},
// resolve: {
// fallback: {
// buffer: require.resolve('buffer/'),
// },
// },
node: {
global: false,
__dirname: false
},
};
21 changes: 16 additions & 5 deletions wasm/light-client-js/esbuild.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as esbuild from 'esbuild'
import inlineWorkerPlugin from 'esbuild-plugin-inline-worker';
import inlineWorkerPlugin from './inline-worker-plugin.js';
import { polyfillNode } from "esbuild-plugin-polyfill-node";
import { dtsPlugin } from "esbuild-plugin-d.ts";
import fs from "node:fs/promises";
Expand All @@ -10,16 +10,27 @@ await esbuild.build({
entryPoints: ["./src/index.ts"],
bundle: true,
outdir: "dist",
plugins: [polyfillNode(), inlineWorkerPlugin({
plugins: [/*polyfillNode(),*/ inlineWorkerPlugin({
format: "iife"
}), dtsPlugin({ tsconfig })],
}), /*dtsPlugin({ tsconfig })*/],
target: [
"esnext"
],
platform: "browser",
platform: "node",
sourcemap: true,
format: "esm",
globalName: "CkbLightClient",
minify: profile === "prod",
logLevel: "debug"
logLevel: "debug",
external: [
"ws",
"isomorphic-ws",
"events",
"buffer",
"util",
"stream"
],
banner: {
js: "import { createRequire } from 'module'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const require = createRequire(import.meta.url); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename);"
}
})
128 changes: 128 additions & 0 deletions wasm/light-client-js/inline-worker-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { build } from "esbuild";
import findCacheDir from "find-cache-dir";
import fs from "fs";
import path from "path";


export default function inlineWorkerPlugin(
workerPluginConfig = {},
) {
return {
name: "esbuild-plugin-inline-worker",

setup(build) {
build.onLoad(
{ filter: /\.worker.(js|jsx|ts|tsx)$/ },
async ({ path: workerPath }) => {
// const workerCode = await fs.promises.readFile(workerPath, {
// encoding: 'utf-8',
// });

const workerCode = await buildWorker(workerPath, workerPluginConfig);
return {
contents: `import inlineWorker from '__inline-worker'
export default function Worker() {
return inlineWorker(${JSON.stringify(workerCode)});
}
`,
loader: "js",
};
},
);

const options = {
name: workerPluginConfig.workerName || undefined,
...workerPluginConfig.workerArguments,
}

const inlineWorkerFunctionCode = `
export default function inlineWorker(scriptText) {
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
const { Worker } = require('worker_threads');
const fs = require('fs');
const path = require('path');
const os = require('os');
const crypto = require('crypto');

const hash = crypto.createHash('md5').update(scriptText).digest('hex').slice(0, 8);
const tempDir = os.tmpdir();
const tempFilePath = path.join(tempDir, \`worker-\${hash}-\${Date.now()}.mjs\`);

fs.writeFileSync(tempFilePath, scriptText, 'utf-8');
console.log('[inline-worker] Created temporary worker file:', tempFilePath);

const worker = new Worker(tempFilePath, ${JSON.stringify(options)});

const cleanup = () => {
try {
if (fs.existsSync(tempFilePath)) {
// fs.unlinkSync(tempFilePath);
// console.log('[inline-worker] Cleaned up temporary worker file:', tempFilePath);
}
} catch (err) {
console.error('[inline-worker] Failed to cleanup temporary file:', err);
}
};

worker.on('exit', cleanup);
// worker.on('error', cleanup);
worker.on('error', (err) => {
console.error('[inline-worker] Worker error:', err);
cleanup();
});

return worker;
} else {
const blob = new Blob([scriptText], {type: 'text/javascript'});
const url = URL.createObjectURL(blob);
const worker = new Worker(url, ${JSON.stringify(options)});
URL.revokeObjectURL(url);
return worker;
}
}
`;

build.onResolve({ filter: /^__inline-worker$/ }, ({ path }) => {
return { path, namespace: "inline-worker" };
});
build.onLoad({ filter: /.*/, namespace: "inline-worker" }, () => {
return { contents: inlineWorkerFunctionCode, loader: "js" };
});
},
};
}

const cacheDir = findCacheDir({
name: "esbuild-plugin-inline-worker",
create: true,
});

async function buildWorker(workerPath, pluginConfig) {
const scriptNameParts = path.basename(workerPath).split(".");
scriptNameParts.pop();
scriptNameParts.push("js");
const scriptName = scriptNameParts.join(".");
if (!cacheDir) {
throw new Error("Cache directory not found. Please ensure 'find-cache-dir' is installed.");
}
const bundlePath = path.resolve(cacheDir, scriptName);

if (pluginConfig.buildOptions) {
delete pluginConfig.buildOptions.entryPoints;
delete pluginConfig.buildOptions.outfile;
delete pluginConfig.buildOptions.outdir;
}

await build({
entryPoints: [workerPath],
bundle: true,
minify: true,
outfile: bundlePath,
target: "esnext",
format: "esm",
platform: "node",
...pluginConfig.buildOptions,
});

return fs.promises.readFile(bundlePath, { encoding: "utf-8" });
}
10 changes: 5 additions & 5 deletions wasm/light-client-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.14",
"esbuild": "0.24.2",
"ckb-light-client-db-worker": "*",
"ckb-light-client-wasm": "*",
"esbuild": "^0.27.1",
"esbuild-plugin-d.ts": "^1.3.1",
"esbuild-plugin-inline-worker": "^0.1.1",
"esbuild-plugin-polyfill-node": "^0.3.0",
"find-cache-dir": "^5.0.0",
"jest": "^29.7.0",
"ts-jest": "^29.2.5",
"ckb-light-client-db-worker": "*",
"ckb-light-client-wasm": "*"
"ts-jest": "^29.2.5"
},
"dependencies": {
"@ckb-ccc/core": "0.1.0-alpha.6",
Expand Down
13 changes: 7 additions & 6 deletions wasm/light-client-js/src/db.worker.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { DbWorkerInitializeOptions } from "./types";
import wasmModule from "ckb-light-client-db-worker";
onerror = event => {
console.error(event);
}
import { parentPort as self } from "worker_threads";
// onerror = event => {
// console.error(event);
// }

onmessage = async (evt) => {
const data = evt.data as DbWorkerInitializeOptions;
self.on("message", async (evt) => {
const data = evt as DbWorkerInitializeOptions;
wasmModule.set_shared_array(data.inputBuffer, data.outputBuffer);
self.postMessage({});
await wasmModule.main_loop(data.logLevel);
}
});

export default {} as typeof Worker & { new(): Worker };
24 changes: 12 additions & 12 deletions wasm/light-client-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ class LightClient {
networkConfigIsJSObject
} as LightClientWorkerInitializeOptions);
await new Promise<void>((res, rej) => {
this.dbWorker.onmessage = () => res();
this.dbWorker.onerror = (evt) => rej(evt);
this.dbWorker.on("message",() => res()) ;
this.dbWorker.on("error",(evt) => rej(evt));
});
await new Promise<void>((res, rej) => {
this.lightClientWorker.onmessage = () => res();
this.lightClientWorker.onerror = (evt) => rej(evt);
this.lightClientWorker.on("message",() => res());
this.lightClientWorker.on("error",(evt) => rej(evt));
});
(async () => {
while (!this.stopping) {
Expand Down Expand Up @@ -119,14 +119,14 @@ class LightClient {
});
return await new Promise((resolve, reject) => {
const clean = () => {
this.lightClientWorker.removeEventListener("message", resolveFn);
this.lightClientWorker.removeEventListener("error", errorFn);
this.lightClientWorker.removeListener("message", resolveFn);
this.lightClientWorker.removeListener("error", errorFn);
}
const resolveFn = (evt: MessageEvent<{ ok: true; data: any } | { ok: false; error: string; }>) => {
if (evt.data.ok === true) {
resolve(evt.data.data);
const resolveFn = (evt: { ok: true; data: any } | { ok: false; error: string; }) => {
if (evt.ok === true) {
resolve(evt.data);
} else {
reject(evt.data.error);
reject(evt.error);
}
clean();

Expand All @@ -136,8 +136,8 @@ class LightClient {
clean();

};
this.lightClientWorker.addEventListener("message", resolveFn);
this.lightClientWorker.addEventListener("error", errorFn);
this.lightClientWorker.on("message", resolveFn);
this.lightClientWorker.on("error", errorFn);
})
})

Expand Down
Loading
Loading