UNPKG

opnet

Version:

The perfect library for building Bitcoin-based applications.

92 lines (91 loc) 3.34 kB
import { BaseThreader } from './SharedThreader.js'; import { jsonWorkerScript } from './worker-scripts/JSONWorker.js'; let _isServiceWorker = null; function checkIsServiceWorker() { if (_isServiceWorker !== null) return _isServiceWorker; if (typeof __IS_SERVICE_WORKER__ !== 'undefined' && __IS_SERVICE_WORKER__) { _isServiceWorker = true; return true; } if (typeof ServiceWorkerGlobalScope !== 'undefined' && self instanceof ServiceWorkerGlobalScope) { _isServiceWorker = true; return true; } _isServiceWorker = false; return false; } const isServiceWorker = checkIsServiceWorker(); export class JsonThreader extends BaseThreader { workerScript = jsonWorkerScript; threadingThreshold; constructor(options = {}) { super(options); this.threadingThreshold = options.threadingThreshold ?? 16_384; } async parse(json) { if (isServiceWorker || json.length < this.threadingThreshold) { return JSON.parse(json); } const result = await this.run('parse', json); return result; } async parseBuffer(buffer) { if (isServiceWorker || buffer.byteLength <= this.threadingThreshold) { const text = new TextDecoder().decode(buffer); return JSON.parse(text); } const result = await this.runWithTransfer('parse', buffer, [buffer]); return result; } async stringify(data) { const result = JSON.stringify(data); if (isServiceWorker || result.length < this.threadingThreshold) { return result; } return (await this.run('stringify', data)); } async fetch(request) { if (isServiceWorker) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), request.timeout || 20_000); try { const resp = await fetch(request.url, { method: 'POST', headers: request.headers || { 'Content-Type': 'application/json', Accept: 'application/json', }, body: JSON.stringify(request.payload), signal: controller.signal, }); clearTimeout(timeoutId); if (!resp.ok) { throw new Error(`HTTP ${resp.status}: ${resp.statusText}`); } return (await resp.json()); } catch (err) { clearTimeout(timeoutId); if (err.name === 'AbortError') { throw new Error(`Request timed out after ${request.timeout || 20_000}ms`, { cause: err, }); } throw err; } } const result = await this.run('fetch', request); return result; } } const GLOBAL_KEY = Symbol.for('opnet.jsonThreader'); const globalObj = (typeof globalThis !== 'undefined' ? globalThis : global); if (!(GLOBAL_KEY in globalObj)) { globalObj[GLOBAL_KEY] = new JsonThreader(); } export function initJsonThreader() { return Promise.resolve(globalObj[GLOBAL_KEY]); } export const jsonThreader = globalObj[GLOBAL_KEY];