opnet 1.7.21 → 1.7.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/229.index.js +1 -0
- package/browser/_version.d.ts +1 -1
- package/browser/block/Block.d.ts +8 -2
- package/browser/cache/LRUCaching.d.ts +7 -0
- package/browser/cache/P2OPCache.d.ts +2 -0
- package/browser/fetch/fetch-browser.d.ts +1 -0
- package/browser/fetch/fetch.d.ts +2 -2
- package/browser/fetch/fetcher-type.d.ts +4 -0
- package/browser/index.js +1 -1
- package/browser/providers/JSONRpcProvider.d.ts +5 -2
- package/browser/threading/JSONThreader.d.ts +20 -0
- package/browser/threading/SharedThreader.d.ts +36 -0
- package/browser/threading/WorkerCreator.d.ts +3 -0
- package/browser/threading/interfaces/IThread.d.ts +28 -0
- package/browser/threading/worker-scripts/JSONWorker.d.ts +2 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/block/Block.d.ts +8 -2
- package/build/block/Block.js +24 -10
- package/build/cache/LRUCaching.d.ts +7 -0
- package/build/cache/LRUCaching.js +28 -0
- package/build/cache/P2OPCache.d.ts +2 -0
- package/build/cache/P2OPCache.js +19 -0
- package/build/fetch/fetch.d.ts +2 -2
- package/build/fetch/fetch.js +9 -5
- package/build/fetch/fetcher-type.d.ts +4 -0
- package/build/providers/JSONRpcProvider.d.ts +5 -2
- package/build/providers/JSONRpcProvider.js +22 -6
- package/build/threading/JSONThreader.d.ts +20 -0
- package/build/threading/JSONThreader.js +38 -0
- package/build/threading/SharedThreader.d.ts +36 -0
- package/build/threading/SharedThreader.js +188 -0
- package/build/threading/WorkerCreator.d.ts +3 -0
- package/build/threading/WorkerCreator.js +57 -0
- package/build/threading/interfaces/IThread.d.ts +28 -0
- package/build/threading/interfaces/IThread.js +1 -0
- package/build/threading/worker-scripts/JSONWorker.d.ts +2 -0
- package/build/threading/worker-scripts/JSONWorker.js +76 -0
- package/build/transactions/metadata/TransactionReceipt.js +4 -8
- package/package.json +3 -2
- package/src/_version.ts +1 -1
- package/src/block/Block.ts +32 -14
- package/src/cache/LRUCaching.ts +30 -0
- package/src/cache/P2OPCache.ts +22 -0
- package/src/fetch/fetch-browser.js +3 -1
- package/src/fetch/fetch.ts +14 -9
- package/src/fetch/fetcher-type.ts +5 -0
- package/src/providers/JSONRpcProvider.ts +24 -10
- package/src/threading/JSONThreader.ts +62 -0
- package/src/threading/SharedThreader.ts +259 -0
- package/src/threading/WorkerCreator.ts +67 -0
- package/src/threading/interfaces/IThread.ts +38 -0
- package/src/threading/worker-scripts/JSONWorker.ts +78 -0
- package/src/transactions/metadata/TransactionReceipt.ts +5 -14
- package/webpack.config.js +2 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { Logger } from '@btc-vision/logger';
|
|
2
|
+
import {
|
|
3
|
+
PendingTask,
|
|
4
|
+
QueuedTask,
|
|
5
|
+
ResultMessage,
|
|
6
|
+
ThreaderOptions,
|
|
7
|
+
UniversalWorker,
|
|
8
|
+
WorkerScript,
|
|
9
|
+
} from './interfaces/IThread.js';
|
|
10
|
+
|
|
11
|
+
import { createWorker, isNode } from './WorkerCreator.js';
|
|
12
|
+
|
|
13
|
+
export abstract class BaseThreader<TOp extends string, TData, TResult> extends Logger {
|
|
14
|
+
public readonly logColor: string = '#FF5733';
|
|
15
|
+
|
|
16
|
+
protected abstract readonly workerScript: WorkerScript;
|
|
17
|
+
|
|
18
|
+
private workers: UniversalWorker<TOp, TData, TResult>[] = [];
|
|
19
|
+
private available: UniversalWorker<TOp, TData, TResult>[] = [];
|
|
20
|
+
private pending = new Map<number, PendingTask<TResult>>();
|
|
21
|
+
private queue: QueuedTask<TOp, TData, TResult>[] = [];
|
|
22
|
+
private idCounter = 0;
|
|
23
|
+
private readonly poolSize: number;
|
|
24
|
+
private initialized = false;
|
|
25
|
+
private initializing: Promise<void> | null = null;
|
|
26
|
+
|
|
27
|
+
private tasksProcessed = 0;
|
|
28
|
+
private tasksFailed = 0;
|
|
29
|
+
private lastStatsLog = 0;
|
|
30
|
+
private readonly statsInterval = 30_000;
|
|
31
|
+
|
|
32
|
+
private cleanupBound = false;
|
|
33
|
+
|
|
34
|
+
protected constructor(options: ThreaderOptions = {}) {
|
|
35
|
+
super();
|
|
36
|
+
|
|
37
|
+
this.poolSize =
|
|
38
|
+
options.poolSize ??
|
|
39
|
+
(isNode
|
|
40
|
+
? 6
|
|
41
|
+
: Math.max(Math.max(1, Math.ceil((navigator?.hardwareConcurrency ?? 8) / 2)), 6));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get stats(): {
|
|
45
|
+
pending: number;
|
|
46
|
+
queued: number;
|
|
47
|
+
available: number;
|
|
48
|
+
total: number;
|
|
49
|
+
processed: number;
|
|
50
|
+
failed: number;
|
|
51
|
+
} {
|
|
52
|
+
return {
|
|
53
|
+
pending: this.pending.size,
|
|
54
|
+
queued: this.queue.length,
|
|
55
|
+
available: this.available.length,
|
|
56
|
+
total: this.workers.length,
|
|
57
|
+
processed: this.tasksProcessed,
|
|
58
|
+
failed: this.tasksFailed,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public async terminate(): Promise<void> {
|
|
63
|
+
if (!this.initialized && !this.initializing) return;
|
|
64
|
+
|
|
65
|
+
const queuedCount = this.queue.length;
|
|
66
|
+
const pendingCount = this.pending.size;
|
|
67
|
+
|
|
68
|
+
for (const task of this.queue) {
|
|
69
|
+
task.reject(new Error('Threader terminated'));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const [, handler] of this.pending) {
|
|
73
|
+
handler.reject(new Error('Threader terminated'));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const worker of this.workers) {
|
|
77
|
+
await worker.terminate();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this.queue = [];
|
|
81
|
+
this.pending.clear();
|
|
82
|
+
this.workers = [];
|
|
83
|
+
this.available = [];
|
|
84
|
+
this.initialized = false;
|
|
85
|
+
this.initializing = null;
|
|
86
|
+
|
|
87
|
+
if (queuedCount > 0 || pendingCount > 0) {
|
|
88
|
+
this.info(
|
|
89
|
+
`Terminated. Rejected ${queuedCount} queued and ${pendingCount} pending tasks. Total processed: ${this.tasksProcessed}, failed: ${this.tasksFailed}`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async drain(): Promise<void> {
|
|
95
|
+
if (!this.initialized) return;
|
|
96
|
+
|
|
97
|
+
const queuedCount = this.queue.length;
|
|
98
|
+
const pendingCount = this.pending.size;
|
|
99
|
+
|
|
100
|
+
this.info(
|
|
101
|
+
`Draining. Rejecting ${queuedCount} queued, waiting for ${pendingCount} pending...`,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
for (const task of this.queue) {
|
|
105
|
+
task.reject(new Error('Threader draining'));
|
|
106
|
+
}
|
|
107
|
+
this.queue = [];
|
|
108
|
+
|
|
109
|
+
if (this.pending.size > 0) {
|
|
110
|
+
await new Promise<void>((resolve) => {
|
|
111
|
+
const checkDone = () => {
|
|
112
|
+
if (this.pending.size === 0) {
|
|
113
|
+
resolve();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const originalPending = new Map(this.pending);
|
|
118
|
+
for (const [id, handler] of originalPending) {
|
|
119
|
+
const origResolve = handler.resolve;
|
|
120
|
+
const origReject = handler.reject;
|
|
121
|
+
|
|
122
|
+
handler.resolve = (v) => {
|
|
123
|
+
origResolve(v);
|
|
124
|
+
checkDone();
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
handler.reject = (e) => {
|
|
128
|
+
origReject(e);
|
|
129
|
+
checkDone();
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
this.pending.set(id, handler);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
checkDone();
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await this.terminate();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected runWithTransfer(
|
|
143
|
+
op: TOp,
|
|
144
|
+
data: TData,
|
|
145
|
+
transferables: ArrayBuffer[],
|
|
146
|
+
): Promise<TResult> {
|
|
147
|
+
return new Promise(async (resolve, reject) => {
|
|
148
|
+
await this.init();
|
|
149
|
+
|
|
150
|
+
this.queue.push({ resolve, reject, op, data, transferables });
|
|
151
|
+
this.processQueue();
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
protected run(op: TOp, data: TData): Promise<TResult> {
|
|
156
|
+
return new Promise(async (resolve, reject) => {
|
|
157
|
+
await this.init();
|
|
158
|
+
|
|
159
|
+
this.queue.push({ resolve, reject, op, data });
|
|
160
|
+
this.processQueue();
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private bindCleanupHandlers(): void {
|
|
165
|
+
if (this.cleanupBound) return;
|
|
166
|
+
this.cleanupBound = true;
|
|
167
|
+
|
|
168
|
+
const cleanup = () => {
|
|
169
|
+
this.terminate().catch(() => {});
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (isNode) {
|
|
173
|
+
process.once('beforeExit', cleanup);
|
|
174
|
+
process.once('SIGINT', cleanup);
|
|
175
|
+
process.once('SIGTERM', cleanup);
|
|
176
|
+
} else if (typeof window !== 'undefined') {
|
|
177
|
+
window.addEventListener('beforeunload', cleanup);
|
|
178
|
+
window.addEventListener('unload', cleanup);
|
|
179
|
+
} else if (typeof self !== 'undefined') {
|
|
180
|
+
self.addEventListener('beforeunload', cleanup);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private async init(): Promise<void> {
|
|
185
|
+
if (this.initialized) return;
|
|
186
|
+
if (this.initializing) return this.initializing;
|
|
187
|
+
|
|
188
|
+
this.bindCleanupHandlers();
|
|
189
|
+
|
|
190
|
+
this.initializing = (async () => {
|
|
191
|
+
const startTime = Date.now();
|
|
192
|
+
|
|
193
|
+
const workers = await Promise.all(
|
|
194
|
+
Array.from({ length: this.poolSize }, () =>
|
|
195
|
+
createWorker<TOp, TData, TResult>(this.workerScript),
|
|
196
|
+
),
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
for (const worker of workers) {
|
|
200
|
+
worker.onMessage((msg: ResultMessage<TResult>) => {
|
|
201
|
+
const handler = this.pending.get(msg.id);
|
|
202
|
+
if (handler) {
|
|
203
|
+
this.pending.delete(msg.id);
|
|
204
|
+
|
|
205
|
+
if (msg.error) {
|
|
206
|
+
this.tasksFailed++;
|
|
207
|
+
handler.reject(new Error(msg.error));
|
|
208
|
+
} else {
|
|
209
|
+
this.tasksProcessed++;
|
|
210
|
+
|
|
211
|
+
handler.resolve(msg.result as TResult);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.available.push(worker);
|
|
216
|
+
this.logStatsIfNeeded();
|
|
217
|
+
this.processQueue();
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
this.workers.push(worker);
|
|
221
|
+
this.available.push(worker);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this.initialized = true;
|
|
225
|
+
})();
|
|
226
|
+
|
|
227
|
+
return this.initializing;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private logStatsIfNeeded(): void {
|
|
231
|
+
const now = Date.now();
|
|
232
|
+
if (now - this.lastStatsLog < this.statsInterval) return;
|
|
233
|
+
|
|
234
|
+
this.lastStatsLog = now;
|
|
235
|
+
const s = this.stats;
|
|
236
|
+
this.debug(
|
|
237
|
+
`Stats: ${s.processed} processed, ${s.failed} failed, ${s.pending} pending, ${s.queued} queued, ${s.available}/${s.total} workers available`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private processQueue(): void {
|
|
242
|
+
if (this.queue.length > 100 && this.available.length === 0) {
|
|
243
|
+
this.warn(`Queue backing up: ${this.queue.length} tasks waiting, no workers available`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
while (this.queue.length > 0 && this.available.length > 0) {
|
|
247
|
+
const task = this.queue.shift();
|
|
248
|
+
if (!task) break;
|
|
249
|
+
|
|
250
|
+
const worker = this.available.pop();
|
|
251
|
+
if (!worker) break;
|
|
252
|
+
|
|
253
|
+
const id = this.idCounter++;
|
|
254
|
+
this.pending.set(id, task);
|
|
255
|
+
|
|
256
|
+
worker.postMessage({ id, op: task.op, data: task.data }, task.transferables);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ResultMessage, TaskMessage, UniversalWorker, WorkerScript } from './interfaces/IThread.js';
|
|
2
|
+
|
|
3
|
+
export const isNode =
|
|
4
|
+
typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
5
|
+
|
|
6
|
+
export async function createWorker<TOp extends string, TData, TResult>(
|
|
7
|
+
workerScript: WorkerScript,
|
|
8
|
+
): Promise<UniversalWorker<TOp, TData, TResult>> {
|
|
9
|
+
if (isNode) {
|
|
10
|
+
const { Worker } = await import('worker_threads');
|
|
11
|
+
const worker = new Worker(workerScript, { eval: true });
|
|
12
|
+
|
|
13
|
+
worker.on('error', (err) => {
|
|
14
|
+
console.error('[WorkerCreator] Worker error:', err);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
let messageCallback: ((msg: ResultMessage<TResult>) => void) | null = null;
|
|
18
|
+
|
|
19
|
+
worker.on('message', (msg: ResultMessage<TResult>) => {
|
|
20
|
+
if (messageCallback) messageCallback(msg);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// unref AFTER all listeners are set up
|
|
24
|
+
worker.unref();
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
postMessage: (msg: TaskMessage<TOp, TData>, transferables?: ArrayBuffer[]) => {
|
|
28
|
+
if (transferables && transferables.length > 0) {
|
|
29
|
+
worker.postMessage(msg, transferables);
|
|
30
|
+
} else {
|
|
31
|
+
worker.postMessage(msg);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
onMessage: (callback: (msg: ResultMessage<TResult>) => void) => {
|
|
35
|
+
messageCallback = callback;
|
|
36
|
+
},
|
|
37
|
+
terminate: async () => {
|
|
38
|
+
await worker.terminate();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
} else {
|
|
42
|
+
const blob = new Blob([workerScript], { type: 'application/javascript' });
|
|
43
|
+
const url = URL.createObjectURL(blob);
|
|
44
|
+
const worker = new Worker(url);
|
|
45
|
+
|
|
46
|
+
worker.onerror = (err) => {
|
|
47
|
+
console.error('[WorkerCreator] Worker error:', err);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
postMessage: (msg: TaskMessage<TOp, TData>, transferables?: ArrayBuffer[]) => {
|
|
52
|
+
if (transferables && transferables.length > 0) {
|
|
53
|
+
worker.postMessage(msg, transferables);
|
|
54
|
+
} else {
|
|
55
|
+
worker.postMessage(msg);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
onMessage: (callback: (msg: ResultMessage<TResult>) => void) => {
|
|
59
|
+
worker.onmessage = (e: MessageEvent<ResultMessage<TResult>>) => callback(e.data);
|
|
60
|
+
},
|
|
61
|
+
terminate: () => {
|
|
62
|
+
worker.terminate();
|
|
63
|
+
URL.revokeObjectURL(url);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface TaskMessage<TOp extends string = string, TData = unknown> {
|
|
2
|
+
id: number;
|
|
3
|
+
op: TOp;
|
|
4
|
+
data: TData;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ResultMessage<TResult = unknown> {
|
|
8
|
+
id: number;
|
|
9
|
+
result?: TResult;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface PendingTask<TResult = unknown> {
|
|
14
|
+
resolve: (value: TResult) => void;
|
|
15
|
+
reject: (error: Error) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface QueuedTask<
|
|
19
|
+
TOp extends string = string,
|
|
20
|
+
TData = unknown,
|
|
21
|
+
TResult = unknown,
|
|
22
|
+
> extends PendingTask<TResult> {
|
|
23
|
+
op: TOp;
|
|
24
|
+
data: TData;
|
|
25
|
+
transferables?: ArrayBuffer[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ThreaderOptions {
|
|
29
|
+
poolSize?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface UniversalWorker<TOp extends string = string, TData = unknown, TResult = unknown> {
|
|
33
|
+
postMessage(msg: TaskMessage<TOp, TData>, transferables?: readonly Transferable[]): void;
|
|
34
|
+
onMessage(callback: (msg: ResultMessage<TResult>) => void): void;
|
|
35
|
+
terminate(): void | Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type WorkerScript = string;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { WorkerScript } from '../interfaces/IThread.js';
|
|
2
|
+
|
|
3
|
+
export const jsonWorkerScript: WorkerScript = `
|
|
4
|
+
(async () => {
|
|
5
|
+
let parentPort = null;
|
|
6
|
+
let isBrowser = typeof self !== 'undefined' && typeof self.onmessage !== 'undefined';
|
|
7
|
+
|
|
8
|
+
if (!isBrowser) {
|
|
9
|
+
const wt = await import('node:worker_threads');
|
|
10
|
+
parentPort = wt.parentPort;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const send = (msg) => {
|
|
14
|
+
if (isBrowser) {
|
|
15
|
+
postMessage(msg);
|
|
16
|
+
} else if (parentPort) {
|
|
17
|
+
parentPort.postMessage(msg);
|
|
18
|
+
} else {
|
|
19
|
+
console.error('[JsonWorker] No way to send message:', msg);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const handler = (e) => {
|
|
24
|
+
// Node: e is the message directly
|
|
25
|
+
// Browser: e is MessageEvent, e.data is the message
|
|
26
|
+
const msg = isBrowser ? e.data : e;
|
|
27
|
+
|
|
28
|
+
// Handle raw ArrayBuffer (shouldn't happen but defensive)
|
|
29
|
+
if (msg instanceof ArrayBuffer) {
|
|
30
|
+
console.error('[JsonWorker] Received raw ArrayBuffer instead of message object. Length:', msg.byteLength);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { id, op, data } = msg ?? {};
|
|
35
|
+
|
|
36
|
+
if (typeof id !== 'number') {
|
|
37
|
+
console.error('[JsonWorker] Invalid message, missing id. Got:', msg);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
let result;
|
|
43
|
+
if (op === 'parse') {
|
|
44
|
+
if (data === undefined || data === null) {
|
|
45
|
+
throw new Error('No data provided for parse operation');
|
|
46
|
+
}
|
|
47
|
+
const text = data instanceof ArrayBuffer
|
|
48
|
+
? new TextDecoder().decode(data)
|
|
49
|
+
: data;
|
|
50
|
+
result = JSON.parse(text);
|
|
51
|
+
} else if (op === 'stringify') {
|
|
52
|
+
result = JSON.stringify(data);
|
|
53
|
+
} else {
|
|
54
|
+
throw new Error('Unknown operation: ' + op);
|
|
55
|
+
}
|
|
56
|
+
send({ id, result });
|
|
57
|
+
} catch (err) {
|
|
58
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
59
|
+
console.error('[JsonWorker] Error processing task ' + id + ':', error);
|
|
60
|
+
send({ id, error });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (isBrowser) {
|
|
65
|
+
self.onmessage = handler;
|
|
66
|
+
self.onerror = (err) => {
|
|
67
|
+
console.error('[JsonWorker] Uncaught error:', err);
|
|
68
|
+
};
|
|
69
|
+
} else if (parentPort) {
|
|
70
|
+
parentPort.on('message', handler);
|
|
71
|
+
parentPort.on('error', (err) => {
|
|
72
|
+
console.error('[JsonWorker] Uncaught error:', err);
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
console.error('[JsonWorker] No parentPort and not browser - worker cannot receive messages');
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
-
import {
|
|
2
|
+
import { NetEvent } from '@btc-vision/transaction';
|
|
3
|
+
import { getP2op } from '../../cache/P2OPCache.js';
|
|
3
4
|
import { CallResult } from '../../contracts/CallResult.js';
|
|
4
5
|
import {
|
|
5
6
|
ContractEvents,
|
|
@@ -46,7 +47,6 @@ export class TransactionReceipt implements ITransactionReceipt {
|
|
|
46
47
|
: undefined;
|
|
47
48
|
|
|
48
49
|
this.receiptProofs = receipt.receiptProofs || [];
|
|
49
|
-
|
|
50
50
|
this.events = receipt.events ? this.parseEvents(receipt.events, network) : {};
|
|
51
51
|
|
|
52
52
|
this.rawRevert = receipt.revert
|
|
@@ -54,7 +54,6 @@ export class TransactionReceipt implements ITransactionReceipt {
|
|
|
54
54
|
: undefined;
|
|
55
55
|
|
|
56
56
|
this.revert = this.rawRevert ? CallResult.decodeRevertData(this.rawRevert) : undefined;
|
|
57
|
-
|
|
58
57
|
this.gasUsed = BigInt(receipt.gasUsed || '0x00') || 0n;
|
|
59
58
|
this.specialGasUsed = BigInt(receipt.specialGasUsed || '0x00') || 0n;
|
|
60
59
|
}
|
|
@@ -70,30 +69,22 @@ export class TransactionReceipt implements ITransactionReceipt {
|
|
|
70
69
|
network: Network,
|
|
71
70
|
): ContractEvents {
|
|
72
71
|
const parsedEvents: ContractEvents = {};
|
|
72
|
+
|
|
73
73
|
if (!Array.isArray(events)) {
|
|
74
74
|
for (const [key, value] of Object.entries(events)) {
|
|
75
|
-
const
|
|
76
|
-
const caP2op = ca.p2op(network);
|
|
75
|
+
const caP2op = getP2op(key, network);
|
|
77
76
|
const v = (value as NetEventDocument[]).map((event: NetEventDocument) => {
|
|
78
77
|
return this.decodeEvent(event);
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
parsedEvents[caP2op] = v;
|
|
82
|
-
|
|
83
81
|
this.rawEvents[key] = v;
|
|
84
82
|
}
|
|
85
83
|
} else {
|
|
86
84
|
for (const event of events) {
|
|
87
85
|
const parsedEvent = this.decodeEvent(event);
|
|
88
86
|
const contractAddress = event.contractAddress;
|
|
89
|
-
|
|
90
|
-
// TODO: Add a weak cache to avoid parsing the same address multiple times?
|
|
91
|
-
const ca = Address.fromString(contractAddress);
|
|
92
|
-
const caP2op = ca.p2op(network);
|
|
93
|
-
|
|
94
|
-
if (!parsedEvents[caP2op]) {
|
|
95
|
-
parsedEvents[caP2op] = [];
|
|
96
|
-
}
|
|
87
|
+
const caP2op = getP2op(contractAddress, network);
|
|
97
88
|
|
|
98
89
|
if (!parsedEvents[caP2op]) {
|
|
99
90
|
parsedEvents[caP2op] = [];
|
package/webpack.config.js
CHANGED
|
@@ -35,6 +35,8 @@ export default {
|
|
|
35
35
|
os: import.meta.resolve('os-browserify/browser/'),
|
|
36
36
|
stream: import.meta.resolve('stream-browserify'),
|
|
37
37
|
process: import.meta.resolve('process/browser'),
|
|
38
|
+
'node:worker_threads': false,
|
|
39
|
+
worker_threads: false,
|
|
38
40
|
},
|
|
39
41
|
},
|
|
40
42
|
cache: false,
|