]> git.codecow.com Git - libnemo.git/commitdiff
Merge pool into workers barrel module.
authorChris Duncan <chris@zoso.dev>
Tue, 15 Jul 2025 12:33:37 +0000 (05:33 -0700)
committerChris Duncan <chris@zoso.dev>
Tue, 15 Jul 2025 12:33:37 +0000 (05:33 -0700)
package.json
src/lib/account.ts
src/lib/block.ts
src/lib/pool.ts [deleted file]
src/lib/wallets/bip44-wallet.ts
src/lib/wallets/index.ts
src/lib/wallets/ledger-wallet.ts
src/lib/workers/bip44-ckd.ts
src/lib/workers/index.ts
src/lib/workers/nano-nacl.ts
src/lib/workers/safe.ts

index ff669d8687c3719c75c9082bacbf0fce80cb1548..e166e5070161cf61c48abc6133b8c9195ae72e51 100644 (file)
@@ -54,8 +54,7 @@
        "imports": {
                "#dist/*": "./dist/*",
                "#src/*": "./src/*",
-               "#workers": "./src/lib/workers/index.js",
-               "#workers/*": "./src/lib/workers/*"
+               "#workers": "./src/lib/workers/index.js"
        },
        "dependencies": {
                "nano-pow": "^5.1.4"
index 6da954229c48b5d4cc822bd0e2ce5f209f583932..0215b18c408ba505f6eb10959cfec2067b0a47bb 100644 (file)
@@ -4,9 +4,8 @@
 import { Blake2b } from './blake2b'\r
 import { ACCOUNT_KEY_BYTE_LENGTH, ACCOUNT_KEY_HEX_LENGTH, ALPHABET, PREFIX, PREFIX_LEGACY } from './constants'\r
 import { base32, bytes, hex, obj, utf8 } from './convert'\r
-import { Queue } from './pool'\r
 import { Rpc } from './rpc'\r
-import { NanoNaClWorker, SafeWorker } from '#workers'\r
+import { NanoNaClWorker, Queue, SafeWorker } from '#workers'\r
 \r
 /**\r
 * Represents a single Nano address and the associated public key. To include the\r
index 213c60c222f45647665e316fb8f23b535fffd44e..6f4f078f25bae9828bf14f2ae5506116a1543da8 100644 (file)
@@ -6,9 +6,8 @@ import { Account } from './account'
 import { Blake2b } from './blake2b'
 import { BURN_ADDRESS, PREAMBLE, DIFFICULTY_RECEIVE, DIFFICULTY_SEND } from './constants'
 import { dec, hex } from './convert'
-import { Queue } from './pool'
 import { Rpc } from './rpc'
-import { NanoNaClWorker } from '#workers'
+import { NanoNaClWorker, Queue } from '#workers'
 
 /**
 * Represents a block as defined by the Nano cryptocurrency protocol. The Block
diff --git a/src/lib/pool.ts b/src/lib/pool.ts
deleted file mode 100644 (file)
index 7b56fb7..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-export type Headers = {
-       [key: string]: any
-}
-
-export type Data = {
-       [key: string]: ArrayBuffer
-}
-
-type Task = {
-       id: number
-       headers: Headers | null
-       data?: Data
-       reject: (value: any) => void
-       resolve: (value: any) => void
-}
-
-/**
-* Processes a queue of tasks using Web Workers.
-*/
-export class Queue {
-       static #decoder: TextDecoder = new TextDecoder()
-       static #encoder: TextEncoder = new TextEncoder()
-       static #instances: Queue[] = []
-       static get instances (): Queue[] { return this.#instances }
-
-       #job?: Task
-       #isIdle: boolean
-       #queue: Task[] = []
-       #url: string
-       #worker: Worker
-
-       /**
-       *       Creates a Web Worker from a stringified script.
-       *
-       * @param {string} worker - Stringified worker class body
-       * @param {number} [count=1] - Integer between 1 and CPU thread count shared among all Pools
-       */
-       constructor (worker: string) {
-               this.#isIdle = true
-               this.#queue = []
-               this.#url = URL.createObjectURL(new Blob([worker], { type: 'text/javascript' }))
-               this.#worker = new Worker(this.#url, { type: 'module' })
-               this.#worker.addEventListener('message', message => {
-                       let result = JSON.parse(Queue.#decoder.decode(message.data) || '[]')
-                       if (!Array.isArray(result)) result = [result]
-                       debugger
-                       this.#report(result)
-               })
-               Queue.#instances.push(this)
-       }
-
-       async add (headers: Headers | null, data?: Data): Promise<any> {
-               return await this.#assign(task => this.#queue.push(task), headers, data)
-       }
-
-       async prioritize (headers: Headers | null, data?: Data): Promise<any> {
-               return await this.#assign(task => this.#queue.unshift(task), headers, data)
-       }
-
-       terminate (): void {
-               this.#job = undefined
-               this.#worker.terminate()
-       }
-
-       async #assign (enqueue: (task: Task) => number, headers: Headers | null, data?: Data) {
-               return new Promise(async (resolve, reject): Promise<void> => {
-                       const task: Task = {
-                               id: performance.now(),
-                               headers,
-                               data,
-                               resolve,
-                               reject
-                       }
-                       await enqueue(task)
-                       debugger
-                       if (this.#isIdle) this.#process()
-               })
-       }
-
-       #process = (): void => {
-               debugger
-               this.#job = this.#queue.shift()
-               if (this.#job == null) {
-                       throw new Error('Failed to get job from empty task queue.')
-               }
-               const { id, headers, data, reject } = this.#job
-               this.#isIdle = !id
-               try {
-                       const buffers: ArrayBuffer[] = []
-                       if (data != null) {
-                               for (let d of Object.keys(data)) {
-                                       buffers.push(data[d])
-                               }
-                       }
-                       this.#worker.postMessage({ headers, data }, buffers)
-               } catch (err) {
-                       reject(err)
-               }
-       }
-
-       #report (results: any[]): void {
-               if (this.#job == null) {
-                       throw new Error('Worker returned results but had nowhere to report it.')
-               }
-               const { resolve, reject } = this.#job
-               debugger
-               try {
-                       resolve(results)
-               } catch (err) {
-                       reject(err)
-               } finally {
-                       this.#process()
-               }
-       }
-}
-
-/**
-* Provides basic worker event messaging to extending classes.
-*
-* In order to be properly bundled in a format that can be used to create an
-* inline Web Worker, the extending classes must export WorkerInterface and
-* themselves as a string:
-*```
-* export default `
-*      const WorkerInterface = ${WorkerInterface}
-*      const Pow = ${Pow}
-* `
-* ```
-* They must also initialize the event listener by calling their inherited
-* `listen()` function. Finally, they must override the implementation of the
-* `work()` function. See the documentation of those functions for details.
-*/
-export abstract class WorkerInterface {
-       /**
-       * Processes data through a worker.
-       *
-       * Extending classes must override this template by implementing the same
-       * function signature and providing their own processing call in the try-catch
-       * block.
-       *
-       * @param {Header} headers - Flat object of header data
-       * @param {any[]} data - Transferred buffer of data to process
-       * @returns Promise for processed data
-       */
-       static async work (headers: Headers | null, data?: Data): Promise<any> {
-               return new Promise(async (resolve, reject): Promise<void> => {
-                       try {
-                               let x, y
-                               if (headers != null) {
-                                       const { sample } = headers
-                                       x = sample
-                               }
-                               if (data != null) {
-                                       const { buf } = data
-                                       y = buf
-                               }
-                               resolve({ x, y })
-                       } catch (err) {
-                               reject(err)
-                       }
-               })
-       }
-
-       /**
-       * Encodes worker results as an ArrayBuffer so it can be transferred back to
-       * the main thread.
-       *
-       * @param {any[]} results - Array of processed data
-       */
-       static report (results: any[]): void {
-               const buffer = new TextEncoder().encode(JSON.stringify(results)).buffer
-               //@ts-expect-error
-               postMessage(buffer, [buffer])
-       }
-
-       /**
-       * Listens for messages from the main thread.
-       *
-       * Extending classes must call this in a static initialization block:
-       * ```
-       * static {
-       *       Extension.listen()
-       * }
-       * ```
-       */
-       static listen (): void {
-               addEventListener('message', (message: any): void => {
-                       const { name, headers, data } = message
-                       if (name === 'STOP') {
-                               close()
-                               const buffer = new ArrayBuffer(0)
-                               //@ts-expect-error
-                               postMessage(buffer, [buffer])
-                       } else {
-                               this.work(headers, data).then(this.report).catch(this.report)
-                       }
-               })
-       }
-}
index 21c2538b89b614b5934d5e18dc1824ee7989c15a..a5bc47cb6439944a2a0d6437ff77a2733c60f303 100644 (file)
@@ -6,8 +6,7 @@ import { Bip39Mnemonic } from '#src/lib/bip39-mnemonic.js'
 import { SEED_LENGTH_BIP44 } from '#src/lib/constants.js'\r
 import { hex, utf8 } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
-import { Queue } from '#src/lib/pool.js'\r
-import { Bip44CkdWorker } from '#workers'\r
+import { Bip44CkdWorker, Queue } from '#workers'\r
 \r
 /**\r
 * Hierarchical deterministic (HD) wallet created by using a source of entropy to\r
index b7161e47842b19e54e123b127c4dd357cf663a71..ada0f7bca39f338b126a1a3530db22526da339d8 100644 (file)
@@ -6,9 +6,8 @@ import { Bip39Mnemonic } from '#src/lib/bip39-mnemonic.js'
 import { ADDRESS_GAP } from '#src/lib/constants.js'\r
 import { hex, utf8 } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
-import { Queue } from '#src/lib/pool.js'\r
 import { Rpc } from '#src/lib/rpc.js'\r
-import { SafeWorker } from '#workers'\r
+import { Queue, SafeWorker } from '#workers'\r
 \r
 export { Bip44Wallet } from './bip44-wallet'\r
 export { Blake2bWallet } from './blake2b-wallet'\r
index 6601020777d2073edb43f18ed455d8db1d5b818c..24016595e048fa512324fe1267c710e93f5dd24f 100644 (file)
@@ -5,12 +5,12 @@ import { ledgerUSBVendorId } from '@ledgerhq/devices'
 import { default as TransportBLE } from '@ledgerhq/hw-transport-web-ble'\r
 import { default as TransportUSB } from '@ledgerhq/hw-transport-webusb'\r
 import { default as TransportHID } from '@ledgerhq/hw-transport-webhid'\r
+import { KeyPair, Wallet } from '.'\r
 import { ChangeBlock, ReceiveBlock, SendBlock } from '#src/lib/block.js'\r
 import { BIP44_COIN_NANO, BIP44_PURPOSE, HARDENED_OFFSET, LEDGER_ADPU_CODES, LEDGER_STATUS_CODES } from '#src/lib/constants.js'\r
 import { bytes, dec, hex } from '#src/lib/convert.js'\r
 import { Entropy } from '#src/lib/entropy.js'\r
 import { Rpc } from '#src/lib/rpc.js'\r
-import { KeyPair, Wallet } from '.'\r
 \r
 type DeviceStatus = 'DISCONNECTED' | 'BUSY' | 'LOCKED' | 'CONNECTED'\r
 \r
index ae2e93975b3135ae511080b79e6131d2ca5ddc52..7d634f6e41d61e3d7e769c87f08a10b46f008b5c 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
-import { Data, Headers, WorkerInterface } from '#src/lib/pool.js'
+
+import { Data, Headers, WorkerInterface } from '.'
 
 type ExtendedKey = {
        privateKey: DataView<ArrayBuffer>
index b9bd85ed931ba16724356bb35042be1670aaf89e..f2b9d2ee7d6a383499f31c0b5c50201d41e06adf 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
 // SPDX-License-Identifier: GPL-3.0-or-later
+
 import { default as Bip44CkdWorker, Bip44Ckd } from './bip44-ckd'
 import { default as NanoNaClWorker, NanoNaCl } from './nano-nacl'
 import { default as SafeWorker, Safe } from './safe'
@@ -12,3 +13,203 @@ export {
        Safe,
        SafeWorker
 }
+
+export type Headers = {
+       [key: string]: any
+}
+
+export type Data = {
+       [key: string]: ArrayBuffer
+}
+
+type Task = {
+       id: number
+       headers: Headers | null
+       data?: Data
+       reject: (value: any) => void
+       resolve: (value: any) => void
+}
+
+/**
+* Processes a queue of tasks using Web Workers.
+*/
+export class Queue {
+       static #decoder: TextDecoder = new TextDecoder()
+       static #encoder: TextEncoder = new TextEncoder()
+       static #instances: Queue[] = []
+       static get instances (): Queue[] { return this.#instances }
+
+       #job?: Task
+       #isIdle: boolean
+       #queue: Task[] = []
+       #url: string
+       #worker: Worker
+
+       /**
+       *       Creates a Web Worker from a stringified script.
+       *
+       * @param {string} worker - Stringified worker class body
+       * @param {number} [count=1] - Integer between 1 and CPU thread count shared among all Pools
+       */
+       constructor (worker: string) {
+               this.#isIdle = true
+               this.#queue = []
+               this.#url = URL.createObjectURL(new Blob([worker], { type: 'text/javascript' }))
+               this.#worker = new Worker(this.#url, { type: 'module' })
+               this.#worker.addEventListener('message', message => {
+                       let result = JSON.parse(Queue.#decoder.decode(message.data) || '[]')
+                       if (!Array.isArray(result)) result = [result]
+                       debugger
+                       this.#report(result)
+               })
+               Queue.#instances.push(this)
+       }
+
+       async add (headers: Headers | null, data?: Data): Promise<any> {
+               return await this.#assign(task => this.#queue.push(task), headers, data)
+       }
+
+       async prioritize (headers: Headers | null, data?: Data): Promise<any> {
+               return await this.#assign(task => this.#queue.unshift(task), headers, data)
+       }
+
+       terminate (): void {
+               this.#job = undefined
+               this.#worker.terminate()
+       }
+
+       async #assign (enqueue: (task: Task) => number, headers: Headers | null, data?: Data) {
+               return new Promise(async (resolve, reject): Promise<void> => {
+                       const task: Task = {
+                               id: performance.now(),
+                               headers,
+                               data,
+                               resolve,
+                               reject
+                       }
+                       await enqueue(task)
+                       debugger
+                       if (this.#isIdle) this.#process()
+               })
+       }
+
+       #process = (): void => {
+               debugger
+               this.#job = this.#queue.shift()
+               if (this.#job == null) {
+                       throw new Error('Failed to get job from empty task queue.')
+               }
+               const { id, headers, data, reject } = this.#job
+               this.#isIdle = !id
+               try {
+                       const buffers: ArrayBuffer[] = []
+                       if (data != null) {
+                               for (let d of Object.keys(data)) {
+                                       buffers.push(data[d])
+                               }
+                       }
+                       this.#worker.postMessage({ headers, data }, buffers)
+               } catch (err) {
+                       reject(err)
+               }
+       }
+
+       #report (results: any[]): void {
+               if (this.#job == null) {
+                       throw new Error('Worker returned results but had nowhere to report it.')
+               }
+               const { resolve, reject } = this.#job
+               debugger
+               try {
+                       resolve(results)
+               } catch (err) {
+                       reject(err)
+               } finally {
+                       this.#process()
+               }
+       }
+}
+
+/**
+* Provides basic worker event messaging to extending classes.
+*
+* In order to be properly bundled in a format that can be used to create an
+* inline Web Worker, the extending classes must export WorkerInterface and
+* themselves as a string:
+*```
+* export default `
+*      const WorkerInterface = ${WorkerInterface}
+*      const Pow = ${Pow}
+* `
+* ```
+* They must also initialize the event listener by calling their inherited
+* `listen()` function. Finally, they must override the implementation of the
+* `work()` function. See the documentation of those functions for details.
+*/
+export abstract class WorkerInterface {
+       /**
+       * Processes data through a worker.
+       *
+       * Extending classes must override this template by implementing the same
+       * function signature and providing their own processing call in the try-catch
+       * block.
+       *
+       * @param {Header} headers - Flat object of header data
+       * @param {any[]} data - Transferred buffer of data to process
+       * @returns Promise for processed data
+       */
+       static async work (headers: Headers | null, data?: Data): Promise<any> {
+               return new Promise(async (resolve, reject): Promise<void> => {
+                       try {
+                               let x, y
+                               if (headers != null) {
+                                       const { sample } = headers
+                                       x = sample
+                               }
+                               if (data != null) {
+                                       const { buf } = data
+                                       y = buf
+                               }
+                               resolve({ x, y })
+                       } catch (err) {
+                               reject(err)
+                       }
+               })
+       }
+
+       /**
+       * Encodes worker results as an ArrayBuffer so it can be transferred back to
+       * the main thread.
+       *
+       * @param {any[]} results - Array of processed data
+       */
+       static report (results: any[]): void {
+               const buffer = new TextEncoder().encode(JSON.stringify(results)).buffer
+               //@ts-expect-error
+               postMessage(buffer, [buffer])
+       }
+
+       /**
+       * Listens for messages from the main thread.
+       *
+       * Extending classes must call this in a static initialization block:
+       * ```
+       * static {
+       *       Extension.listen()
+       * }
+       * ```
+       */
+       static listen (): void {
+               addEventListener('message', (message: any): void => {
+                       const { name, headers, data } = message
+                       if (name === 'STOP') {
+                               close()
+                               const buffer = new ArrayBuffer(0)
+                               //@ts-expect-error
+                               postMessage(buffer, [buffer])
+                       } else {
+                               this.work(headers, data).then(this.report).catch(this.report)
+                       }
+               })
+       }
+}
index 928505fd3a08db2fd1860304f2b3f0582040af74..3aa624c9769b9a4ce1bb5260c938bdf2bc869a1a 100644 (file)
@@ -3,8 +3,8 @@
 \r
 'use strict'\r
 \r
+import { Data, Headers, WorkerInterface } from '.'\r
 import { Blake2b } from '#src/lib/blake2b.js'\r
-import { Data, Headers, WorkerInterface } from '#src/lib/pool.js'\r
 \r
 // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.\r
 // Public domain.\r
index afc4957487fa75ecaad56b88e624d11e5667012b..464548a8aed2eed0077910530c10f2b615f219d1 100644 (file)
@@ -3,9 +3,9 @@
 
 'use strict'
 
+import { Data, Headers, WorkerInterface } from '.'
 import { bytes, hex, utf8, default as Convert } from '#src/lib/convert.js'
 import { Entropy } from '#src/lib/entropy.js'
-import { Data, Headers, WorkerInterface } from '#src/lib/pool.js'
 
 type SafeRecord = {
        encrypted: string,