univo 0.2.4 → 0.2.5

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/dist/cli.mjs CHANGED
@@ -5,10 +5,10 @@ import { config } from 'dotenv';
5
5
  import { WebSocket } from 'partysocket';
6
6
  import { defineCommand, runMain } from 'citty';
7
7
  import { http } from './transport.mjs';
8
- import { c as createLogger, v as version, f as name } from './shared/univo.6U84KZUp.mjs';
8
+ import { c as createLogger, v as version, g as name } from './shared/univo.CpIzl9sz.mjs';
9
9
  import './shared/univo.C0flyVee.mjs';
10
10
 
11
- const log = createLogger({ quiet: false });
11
+ const log = createLogger({ quiet: false, prefix: "[cli]" });
12
12
  const dev = defineCommand({
13
13
  args: {
14
14
  url: {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as createLogger, d as decompress, a as decoder, h as hexToNumber, i as isHexEqual, r as retry, v as version, n as nonNullable } from './shared/univo.6U84KZUp.mjs';
1
+ import { c as createLogger, d as decompress, a as decoder, h as hexToNumber, i as isHexEqual, r as retry, v as version, n as nonNullable, b as normalizeHex } from './shared/univo.CpIzl9sz.mjs';
2
2
  import { c as createException, g as getException, a as catchException } from './shared/univo.C0flyVee.mjs';
3
3
 
4
4
  function matchFilter(block, filter) {
@@ -41,7 +41,7 @@ const includesLogEvent = (block, filter) => {
41
41
  return false;
42
42
  };
43
43
  function indexer(opts) {
44
- const log = createLogger({ quiet: opts.quiet ?? false });
44
+ const log = createLogger({ quiet: opts.quiet ?? false, prefix: "[indexer]" });
45
45
  const all_events = [];
46
46
  const events_grouped_by_storage_map = /* @__PURE__ */ new Map();
47
47
  const metadata = {
@@ -49,7 +49,7 @@ function indexer(opts) {
49
49
  async get(head) {
50
50
  let prefix = `/blocks/v1/${head.chain.toLowerCase()}`;
51
51
  if (typeof head.number === "string") {
52
- prefix += `/${head.number.toLowerCase()}`;
52
+ prefix += `/${normalizeHex(head.number, 16)}`;
53
53
  }
54
54
  if (typeof head.hash === "string") {
55
55
  if (head.number === void 0) {
@@ -64,6 +64,7 @@ function indexer(opts) {
64
64
  }
65
65
  const keys = await opts.metadataStorage.getKeys(prefix);
66
66
  const results = await opts.metadataStorage.getItems(keys);
67
+ results.sort((a, b) => a.key.localeCompare(b.key));
67
68
  return results.map((result) => result.value);
68
69
  },
69
70
  async upsert(blocks) {
@@ -72,9 +73,9 @@ function indexer(opts) {
72
73
  }
73
74
  await opts.metadataStorage.setItems(
74
75
  blocks.map((block) => {
75
- const chain = block.eth_chainId.toLowerCase();
76
- const hash = block.eth_getBlockByNumber.hash.toLowerCase();
77
- const number = block.eth_getBlockByNumber.number.toLowerCase();
76
+ const chain = normalizeHex(block.eth_chainId);
77
+ const hash = normalizeHex(block.eth_getBlockByNumber.hash);
78
+ const number = normalizeHex(block.eth_getBlockByNumber.number, 16);
78
79
  const key = `/blocks/v1/${chain}/${number}/${hash}`;
79
80
  return { key, value: block };
80
81
  })
@@ -86,9 +87,9 @@ function indexer(opts) {
86
87
  }
87
88
  await Promise.all(
88
89
  blocks.map(async (block) => {
89
- const chain = block.eth_chainId.toLowerCase();
90
- const hash = block.eth_getBlockByNumber.hash.toLowerCase();
91
- const number = block.eth_getBlockByNumber.number.toLowerCase();
90
+ const chain = normalizeHex(block.eth_chainId);
91
+ const hash = normalizeHex(block.eth_getBlockByNumber.hash);
92
+ const number = normalizeHex(block.eth_getBlockByNumber.number, 16);
92
93
  await opts.metadataStorage.del(`/blocks/v1/${chain}/${number}/${hash}`);
93
94
  })
94
95
  );
@@ -119,20 +120,11 @@ function indexer(opts) {
119
120
  return block;
120
121
  }
121
122
  const public_getFinalizedHeight = async (chain) => {
122
- const [finalized, [stored]] = await Promise.all([
123
- getBlock({ chain, number: "finalized" }),
124
- //
125
- metadata.blocks.get({ chain })
126
- ]);
127
- if (finalized === null) {
128
- throw new Error("Failed to determine unfinalized height");
129
- }
130
- const finalizedHeight = hexToNumber(finalized.eth_getBlockByNumber.number);
123
+ const [stored] = await metadata.blocks.get({ chain });
131
124
  if (stored === void 0) {
132
- return finalizedHeight;
125
+ return null;
133
126
  }
134
- const storedHeight = hexToNumber(stored.eth_getBlockByNumber.number) - 1;
135
- return Math.min(finalizedHeight, storedHeight);
127
+ return hexToNumber(stored.eth_getBlockByNumber.number) - 1;
136
128
  };
137
129
  const public_writeUnfinalizedHeads = async (heads) => {
138
130
  let chain = void 0;
@@ -247,76 +239,72 @@ function indexer(opts) {
247
239
  }
248
240
  }
249
241
  if (chain === void 0) {
250
- throw new Error("Received invalid chain");
242
+ throw new Error(InvalidHeadsError);
251
243
  }
252
244
  log.debug(`Received ${heads.length} finalized heads...`);
253
- const [unfinalizedBlocks, finalizedBlock] = await Promise.all([
254
- metadata.blocks.get({ chain }),
245
+ const [indexerHeight, finalizedBlock] = await Promise.all([
246
+ public_getFinalizedHeight(chain),
255
247
  //
256
248
  getBlock({ chain, number: "finalized" })
257
249
  ]);
258
- const [nextUnfinalizedBlock] = unfinalizedBlocks;
259
- if (nextUnfinalizedBlock === void 0) {
260
- return log.debug(`No unfinalised blocks processed for chain ${hexToNumber(chain)}, ignoring...`);
250
+ if (indexerHeight === null) {
251
+ return log.debug(`No unfinalized blocks processed for chain ${hexToNumber(chain)}, aborting...`);
261
252
  }
262
253
  if (finalizedBlock === null) {
254
+ log.debug("Failed to load finalized block, aborting...");
263
255
  throw new Error(GetBlockError);
264
256
  }
265
- const nextUnfinalizedHeight = hexToNumber(nextUnfinalizedBlock.eth_getBlockByNumber.number);
266
- const canonicalFinalizedHeight = hexToNumber(finalizedBlock.eth_getBlockByNumber.number);
267
- if (canonicalFinalizedHeight < nextUnfinalizedHeight) {
268
- throw new Error("Expected finalized chain to trail canonical chain");
269
- }
270
- const finalizedHeads = heads.filter((head) => {
271
- return hexToNumber(head.number) >= nextUnfinalizedHeight && hexToNumber(head.number) <= canonicalFinalizedHeight;
257
+ const finalizedHeight = hexToNumber(finalizedBlock.eth_getBlockByNumber.number);
258
+ log.debug(`Indexer height ${indexerHeight}, finalized height ${finalizedHeight}`);
259
+ const newHeads = heads.filter((head) => {
260
+ if (hexToNumber(head.number) > finalizedHeight) {
261
+ return false;
262
+ }
263
+ if (hexToNumber(head.number) > indexerHeight) {
264
+ return true;
265
+ }
266
+ return false;
272
267
  });
273
- const [firstFinalizedHead, ...remainingFinalizedHeads] = finalizedHeads;
274
- if (firstFinalizedHead === void 0) {
268
+ const [firstHead, ...remainingHeads] = newHeads;
269
+ if (firstHead === void 0) {
270
+ log.debug("Received no new finalized heads, aborting...");
275
271
  throw new Error(InvalidHeadsError);
276
272
  }
277
- if (hexToNumber(firstFinalizedHead.number) !== nextUnfinalizedHeight) {
273
+ if (hexToNumber(firstHead.number) !== indexerHeight + 1) {
274
+ log.debug("First unfinalized head received didn't match metadata, aborting...");
278
275
  throw new Error(InvalidHeadsError);
279
276
  }
280
- let previousHead = firstFinalizedHead;
281
- for (const head of remainingFinalizedHeads) {
277
+ let previousHead = firstHead;
278
+ for (const head of remainingHeads) {
282
279
  if (hexToNumber(head.number) !== hexToNumber(previousHead.number) + 1) {
280
+ log.debug("Found invalid block number in received heads, aborting...");
283
281
  throw new Error(InvalidHeadsError);
284
282
  }
285
283
  if (!isHexEqual(head.parentHash, previousHead.hash)) {
284
+ log.debug("Found invalid block hash in received heads, aborting...");
286
285
  throw new Error(InvalidHeadsError);
287
286
  }
288
287
  previousHead = head;
289
288
  }
290
- for (const finalizedHead of finalizedHeads) {
291
- let processedBlocks = void 0;
292
- processedBlocks = unfinalizedBlocks.filter((block) => {
293
- return isHexEqual(finalizedHead.number, block.eth_getBlockByNumber.number);
289
+ for (const head of newHeads) {
290
+ const processed = await metadata.blocks.get({ chain: head.chain, number: head.number });
291
+ if (processed.length === 0) {
292
+ await writeFinalizedHead(head, null);
293
+ continue;
294
+ }
295
+ const reorganised = processed.filter((block2) => {
296
+ return !isHexEqual(head.hash, block2.eth_getBlockByNumber.hash);
294
297
  });
295
- if (processedBlocks.length === 0) {
296
- processedBlocks = await metadata.blocks.get({ chain: finalizedHead.chain, number: finalizedHead.number });
298
+ if (reorganised.length > 0) {
299
+ await deleteReorganisedBlocks(reorganised);
297
300
  }
298
- await reprocessFinalizedHead(finalizedHead, processedBlocks);
299
- await metadata.blocks.delete(processedBlocks);
301
+ const block = processed.find((block2) => {
302
+ return isHexEqual(head.hash, block2.eth_getBlockByNumber.hash);
303
+ });
304
+ await writeFinalizedHead(head, block ?? null);
305
+ await metadata.blocks.delete(processed);
300
306
  }
301
307
  };
302
- async function reprocessFinalizedHead(canonical, processed) {
303
- if (processed.length === 0) {
304
- return await writeFinalizedHead(canonical, null);
305
- }
306
- const reorganised = processed.filter((block2) => {
307
- return !isHexEqual(canonical.hash, block2.eth_getBlockByNumber.hash);
308
- });
309
- if (reorganised.length > 0) {
310
- await deleteReorganisedBlocks(reorganised);
311
- }
312
- const block = processed.find((block2) => {
313
- return isHexEqual(canonical.hash, block2.eth_getBlockByNumber.hash);
314
- });
315
- if (block === void 0) {
316
- return await writeFinalizedHead(canonical, null);
317
- }
318
- return await writeFinalizedHead(canonical, block);
319
- }
320
308
  async function writeFinalizedHead(head, block_nullable) {
321
309
  let block = block_nullable;
322
310
  if (block === null) {
package/dist/realtime.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { c as createLogger, b as iife, h as hexToNumber, e as numberToHex, m as mutex, r as retry, i as isHexEqual } from './shared/univo.6U84KZUp.mjs';
1
+ import { c as createLogger, e as iife, h as hexToNumber, f as numberToHex, m as mutex, r as retry, i as isHexEqual } from './shared/univo.CpIzl9sz.mjs';
2
2
 
3
3
  const MAX_LENGTH = 1e4;
4
4
  function defineBlockchain(opts) {
5
- const log = createLogger({ quiet: opts.quiet });
5
+ const log = createLogger({ quiet: opts.quiet, prefix: "[realtime]" });
6
6
  const chain = [];
7
7
  function setHeadBlock(newBlock) {
8
8
  chain.push(newBlock);
@@ -79,29 +79,18 @@ function defineBlockchain(opts) {
79
79
  }
80
80
  const POLLING_INTERVAL_MS = 12 * 1e3;
81
81
  function realtime(opts) {
82
- const log = createLogger({ quiet: opts.quiet ?? false });
82
+ const log = createLogger({ quiet: opts.quiet ?? false, prefix: "[realtime]" });
83
83
  const getBlockByHash = async (hash) => {
84
- return await opts.node.request({ method: "eth_getBlockByHash", params: [hash, false] });
85
- };
86
- const getLatestBlock = async () => {
87
- return await opts.node.request({ method: "eth_getBlockByNumber", params: ["latest", false] });
88
- };
89
- const getChainFinalizedBlock = async () => {
90
- return await opts.node.request({ method: "eth_getBlockByNumber", params: ["finalized", false] });
91
- };
92
- const getIndexerFinalizedBlock = async (chain) => {
93
- const height = await opts.indexer.request({ method: "public_getFinalizedHeight", params: [chain] });
94
- return await opts.node.request({ method: "eth_getBlockByNumber", params: [numberToHex(height), false] });
84
+ const block = await opts.node.request({ method: "eth_getBlockByHash", params: [hash, false] });
85
+ return { number: block.number, hash: block.hash, parentHash: block.parentHash };
95
86
  };
96
87
  const promise = iife(async () => {
97
88
  log.debug("Initialising realtime client for indexer");
98
89
  const chain = await opts.node.request({ method: "eth_chainId", params: [] });
99
90
  log.debug(`Determined chain identifier for connected node: ${hexToNumber(chain)}`);
100
- const [latestBlock, chainFinalizedBlock, indexerFinalizedBlock] = await Promise.all([
101
- getLatestBlock(),
102
- getChainFinalizedBlock(),
103
- //
104
- getIndexerFinalizedBlock(chain)
91
+ const [latestBlock, initialIndexerHeight] = await Promise.all([
92
+ opts.node.request({ method: "eth_getBlockByNumber", params: ["latest", false] }),
93
+ opts.indexer.request({ method: "public_getFinalizedHeight", params: [chain] })
105
94
  ]);
106
95
  let pending = [];
107
96
  const latest = defineBlockchain({
@@ -109,6 +98,7 @@ function realtime(opts) {
109
98
  quiet: opts.quiet ?? false,
110
99
  onBlockAdded: async (head) => {
111
100
  try {
101
+ log.debug("Received unfinalized head");
112
102
  pending.push(head);
113
103
  const heads = pending.map((head2) => ({ chain, ...head2 }));
114
104
  await opts.indexer.request({ method: "public_writeUnfinalizedHeads", params: [heads] });
@@ -118,72 +108,102 @@ function realtime(opts) {
118
108
  return isHexEqual(head2.hash, _head.hash);
119
109
  });
120
110
  });
121
- } catch {
122
- log.warn("Failed to write heads");
111
+ } catch (error) {
112
+ if (error instanceof Error) {
113
+ log.warn(`Failed to write heads: ${error.message}`);
114
+ }
123
115
  }
124
116
  },
125
117
  onBlockReorganised: async (head) => {
126
118
  try {
127
119
  await retry(() => opts.indexer.request({ method: "public_deleteReorganisedHead", params: [{ chain, ...head }] }), 2);
128
- } catch {
129
- log.warn("Failed to write reorganised head");
120
+ } catch (error) {
121
+ if (error instanceof Error) {
122
+ log.warn(`Failed to write reorganised head: ${error.message}`);
123
+ }
130
124
  }
131
125
  }
132
126
  });
133
127
  await latest.reconcile(latestBlock);
134
- log.debug("Reconciled latest block...");
135
128
  await opts.node.subscribe("newHeads", async (head) => {
136
129
  try {
137
130
  await latest.reconcile(head);
138
- } catch {
139
- log.error("Failed to reconcile latest head");
131
+ } catch (error) {
132
+ if (error instanceof Error) {
133
+ log.error(`Failed to reconcile latest head: ${error.message}`);
134
+ }
140
135
  }
141
136
  });
142
- log.debug("Subscribed to latest blocks");
143
- let lastFinalizedHeight = hexToNumber(indexerFinalizedBlock.number);
144
- log.debug(`Indexer last finalized at ${lastFinalizedHeight}, chain at ${hexToNumber(chainFinalizedBlock.number)}`);
145
- const finalized = defineBlockchain({
137
+ log.debug("Subscribed latest chain to new heads");
138
+ const indexer = defineBlockchain({
146
139
  getBlockByHash,
147
140
  quiet: opts.quiet ?? false
148
141
  });
149
- await finalized.reconcile(indexerFinalizedBlock);
150
- await finalized.reconcile(chainFinalizedBlock);
151
- log.debug("Reconciled finalized chain...");
142
+ if (initialIndexerHeight === null) {
143
+ await indexer.reconcile(latestBlock);
144
+ } else {
145
+ log.debug(`Indexer last finalized at ${initialIndexerHeight}, reconciling local chain...`);
146
+ const indexerBlock = await opts.node.request({
147
+ method: "eth_getBlockByNumber",
148
+ params: [numberToHex(initialIndexerHeight), false]
149
+ });
150
+ await indexer.reconcile(indexerBlock);
151
+ await indexer.reconcile(latestBlock);
152
+ log.debug("Reconciled local indexer chain");
153
+ }
154
+ await opts.node.subscribe("newHeads", async (head) => {
155
+ try {
156
+ await indexer.reconcile(head);
157
+ } catch (error) {
158
+ if (error instanceof Error) {
159
+ log.debug(`Failed to reconcile latest indexer head: ${error.message}`);
160
+ }
161
+ }
162
+ });
163
+ log.debug("Subscribed indexer chain to new heads");
164
+ let indexerHeight = initialIndexerHeight || hexToNumber(latestBlock.number);
152
165
  const poll = async () => {
153
166
  try {
154
167
  const finalizedBlock = await opts.node.request({
155
168
  method: "eth_getBlockByNumber",
156
169
  params: ["finalized", false]
157
- //
158
170
  });
159
171
  const finalizedHeight = hexToNumber(finalizedBlock.number);
160
- if (finalizedHeight === lastFinalizedHeight) {
161
- return log.debug("Chain finalized height equal to indexer finalised height, ignoring...");
162
- }
163
- log.debug(`Received new chain height ${finalizedHeight} with last indexer height ${lastFinalizedHeight}`);
164
- const heads = finalized.chain.filter((head) => {
165
- if (hexToNumber(head.number) > finalizedHeight) return false;
166
- if (hexToNumber(head.number) < lastFinalizedHeight) return false;
167
- return true;
172
+ log.debug(`Finalized chain height ${finalizedHeight} and indexer height ${indexerHeight}`);
173
+ const newHeads = indexer.chain.filter((head) => {
174
+ if (hexToNumber(head.number) > finalizedHeight) {
175
+ return false;
176
+ }
177
+ if (hexToNumber(head.number) > indexerHeight) {
178
+ return true;
179
+ }
180
+ return false;
168
181
  }).map((head) => {
169
182
  return { chain, ...head };
170
183
  });
171
- if (heads.length === 0) {
184
+ if (newHeads.length === 0) {
172
185
  return log.debug("No new finalized heads to deliver, ignoring...");
173
186
  }
174
- await opts.indexer.request({ method: "public_writeFinalizedHeads", params: [heads] });
175
- log.debug(`Delivered ${heads.length} finalized head(s)`);
176
- lastFinalizedHeight = hexToNumber(finalizedBlock.number);
177
- } catch {
178
- log.error("Failed to reconcile finalized head");
187
+ log.debug(`Delivering ${newHeads.length} finalized head(s)...`);
188
+ await opts.indexer.request({ method: "public_writeFinalizedHeads", params: [newHeads] });
189
+ log.debug(`Delivered ${newHeads.length} finalized head(s)`);
190
+ indexerHeight = hexToNumber(finalizedBlock.number);
191
+ log.debug(`Updated indexer height to ${indexerHeight}`);
192
+ } catch (error) {
193
+ if (error instanceof Error) {
194
+ log.error(`Failed to reconcile finalized head: ${error.message}`);
195
+ }
196
+ } finally {
197
+ setTimeout(poll, POLLING_INTERVAL_MS);
179
198
  }
180
199
  };
181
200
  await poll();
182
- setInterval(poll, POLLING_INTERVAL_MS);
183
- log.debug("Start polling finalized height");
201
+ log.debug("Started polling finalized height");
184
202
  });
185
- promise.catch(() => {
186
- log.error("Failed to initialise realtime client");
203
+ promise.catch((error) => {
204
+ if (error instanceof Error) {
205
+ log.error(`Failed to initialise realtime client: ${error.message}`);
206
+ }
187
207
  });
188
208
  }
189
209
 
package/dist/rpc.d.mts CHANGED
@@ -29,12 +29,20 @@ type NodeRpc = {
29
29
  * Accepts a block tag and boolean for including receipts
30
30
  * @returns A block with optional receipts
31
31
  */
32
- eth_getBlockByNumber: (number: string, receipts: boolean) => Promise<Head>;
32
+ eth_getBlockByNumber: (number: string, receipts: boolean) => Promise<{
33
+ hash: `0x${string}`;
34
+ number: `0x${string}`;
35
+ parentHash: `0x${string}`;
36
+ }>;
33
37
  /**
34
38
  * Accepts a block hash and boolean for including receipts
35
39
  * @returns A block with optional receipts
36
40
  */
37
- eth_getBlockByHash: (hash: `0x${string}`, receipts: boolean) => Promise<Head>;
41
+ eth_getBlockByHash: (hash: `0x${string}`, receipts: boolean) => Promise<{
42
+ hash: `0x${string}`;
43
+ number: `0x${string}`;
44
+ parentHash: `0x${string}`;
45
+ }>;
38
46
  };
39
47
  subscribe: {
40
48
  newHeads: Head;
@@ -49,7 +57,7 @@ type IndexerRpc = {
49
57
  * Accepts a chain identifier
50
58
  * @returns Height of the last finalized block indexed
51
59
  */
52
- public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number>;
60
+ public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number | null>;
53
61
  /**
54
62
  * Accepts a reorganised block and deletes all related events from storage
55
63
  */
package/dist/rpc.d.ts CHANGED
@@ -29,12 +29,20 @@ type NodeRpc = {
29
29
  * Accepts a block tag and boolean for including receipts
30
30
  * @returns A block with optional receipts
31
31
  */
32
- eth_getBlockByNumber: (number: string, receipts: boolean) => Promise<Head>;
32
+ eth_getBlockByNumber: (number: string, receipts: boolean) => Promise<{
33
+ hash: `0x${string}`;
34
+ number: `0x${string}`;
35
+ parentHash: `0x${string}`;
36
+ }>;
33
37
  /**
34
38
  * Accepts a block hash and boolean for including receipts
35
39
  * @returns A block with optional receipts
36
40
  */
37
- eth_getBlockByHash: (hash: `0x${string}`, receipts: boolean) => Promise<Head>;
41
+ eth_getBlockByHash: (hash: `0x${string}`, receipts: boolean) => Promise<{
42
+ hash: `0x${string}`;
43
+ number: `0x${string}`;
44
+ parentHash: `0x${string}`;
45
+ }>;
38
46
  };
39
47
  subscribe: {
40
48
  newHeads: Head;
@@ -49,7 +57,7 @@ type IndexerRpc = {
49
57
  * Accepts a chain identifier
50
58
  * @returns Height of the last finalized block indexed
51
59
  */
52
- public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number>;
60
+ public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number | null>;
53
61
  /**
54
62
  * Accepts a reorganised block and deletes all related events from storage
55
63
  */
@@ -1,5 +1,5 @@
1
1
  const name = "univo";
2
- const version = "0.2.4";
2
+ const version = "0.2.5";
3
3
 
4
4
  function createLogger(opts) {
5
5
  return {
@@ -8,7 +8,7 @@ function createLogger(opts) {
8
8
  return;
9
9
  }
10
10
  if (process.env.LOG_LEVEL === "DEBUG") {
11
- console.log(`[${name}@${version}] DEBUG`, ...any);
11
+ console.log(`[${name}@${version}] ${opts.prefix} DEBUG`, ...any);
12
12
  }
13
13
  },
14
14
  info(...any) {
@@ -16,7 +16,7 @@ function createLogger(opts) {
16
16
  return;
17
17
  }
18
18
  if (process.env.LOG_LEVEL === "DEBUG" || process.env.LOG_LEVEL === "INFO") {
19
- console.log(`[${name}@${version}] INFO`, ...any);
19
+ console.log(`[${name}@${version}] ${opts.prefix} INFO`, ...any);
20
20
  }
21
21
  },
22
22
  warn(...any) {
@@ -24,7 +24,7 @@ function createLogger(opts) {
24
24
  return;
25
25
  }
26
26
  if (process.env.LOG_LEVEL === "DEBUG" || process.env.LOG_LEVEL === "INFO" || process.env.LOG_LEVEL === "WARN") {
27
- console.log(`[${name}@${version}] WARN`, ...any);
27
+ console.log(`[${name}@${version}] ${opts.prefix} WARN`, ...any);
28
28
  }
29
29
  },
30
30
  error(...any) {
@@ -32,7 +32,7 @@ function createLogger(opts) {
32
32
  return;
33
33
  }
34
34
  if (process.env.LOG_LEVEL === "DEBUG" || process.env.LOG_LEVEL === "INFO" || process.env.LOG_LEVEL === "WARN" || process.env.LOG_LEVEL === "ERROR") {
35
- console.log(`[${name}@${version}] ERROR`, ...any);
35
+ console.log(`[${name}@${version}] ${opts.prefix} ERROR`, ...any);
36
36
  }
37
37
  }
38
38
  };
@@ -81,5 +81,11 @@ async function decompress(input) {
81
81
  return new Response(decompressed).text();
82
82
  }
83
83
  const decoder = new TextDecoder();
84
+ const normalizeHex = (hex, length) => {
85
+ if (length === void 0) {
86
+ return hex.toLowerCase();
87
+ }
88
+ return `0x${hex.slice(2).toLowerCase().padStart(length, "0")}`;
89
+ };
84
90
 
85
- export { decoder as a, iife as b, createLogger as c, decompress as d, numberToHex as e, name as f, compress as g, hexToNumber as h, isHexEqual as i, raise as j, mutex as m, nonNullable as n, retry as r, version as v };
91
+ export { decoder as a, normalizeHex as b, createLogger as c, decompress as d, iife as e, numberToHex as f, name as g, hexToNumber as h, isHexEqual as i, compress as j, raise as k, mutex as m, nonNullable as n, retry as r, version as v };
@@ -1,7 +1,7 @@
1
1
  import ws from 'ws';
2
2
  import { WebSocket } from 'partysocket';
3
3
  import { c as createException } from './shared/univo.C0flyVee.mjs';
4
- import { g as compress, j as raise, c as createLogger } from './shared/univo.6U84KZUp.mjs';
4
+ import { j as compress, k as raise, c as createLogger } from './shared/univo.CpIzl9sz.mjs';
5
5
 
6
6
  function createSocket(url, opts) {
7
7
  const socket = new WebSocket(url, [], { WebSocket: ws });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "univo",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "0.2.4",
5
+ "version": "0.2.5",
6
6
  "sideEffects": false,
7
7
  "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",