univo 0.2.16 → 0.2.18
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 +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +30 -91
- package/dist/realtime.d.mts +1 -1
- package/dist/realtime.d.ts +1 -1
- package/dist/realtime.mjs +6 -12
- package/dist/rpc.d.mts +1 -5
- package/dist/rpc.d.ts +1 -5
- package/dist/shared/{univo.DdHfpTWq.d.mts → univo.BNqa7KED.d.mts} +1 -2
- package/dist/shared/{univo.DdHfpTWq.d.ts → univo.BNqa7KED.d.ts} +1 -2
- package/dist/shared/{univo.CkhykU8v.mjs → univo.GuW0GiSl.mjs} +4 -3
- package/dist/shared/{univo.BVikUbk_.mjs → univo.TYA11b8i.mjs} +1 -1
- package/dist/transport.d.mts +1 -1
- package/dist/transport.d.ts +1 -1
- package/dist/transport.mjs +2 -2
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import open from 'open';
|
|
|
4
4
|
import { config } from 'dotenv';
|
|
5
5
|
import { WebSocket } from 'partysocket';
|
|
6
6
|
import { defineCommand, runMain } from 'citty';
|
|
7
|
-
import { h as http } from './shared/univo.
|
|
8
|
-
import { c as createLogger, v as version, b as name } from './shared/univo.
|
|
7
|
+
import { h as http } from './shared/univo.GuW0GiSl.mjs';
|
|
8
|
+
import { c as createLogger, v as version, b as name } from './shared/univo.TYA11b8i.mjs';
|
|
9
9
|
|
|
10
10
|
const log = createLogger({ quiet: false });
|
|
11
11
|
const dev = defineCommand({
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { B as Block, E as Event, a as Filter, H as Head, I as Indexer, M as Metadata, R as Result, i as indexer } from './shared/univo.
|
|
1
|
+
export { B as Block, E as Event, a as Filter, H as Head, I as Indexer, M as Metadata, R as Result, i as indexer } from './shared/univo.BNqa7KED.mjs';
|
|
2
2
|
import '@storagesdk/core';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { B as Block, E as Event, a as Filter, H as Head, I as Indexer, M as Metadata, R as Result, i as indexer } from './shared/univo.
|
|
1
|
+
export { B as Block, E as Event, a as Filter, H as Head, I as Indexer, M as Metadata, R as Result, i as indexer } from './shared/univo.BNqa7KED.js';
|
|
2
2
|
import '@storagesdk/core';
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StorageError } from '@storagesdk/core';
|
|
2
|
-
import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.
|
|
3
|
-
import { c as createLogger, d as decompress, e as decoder, r as retry, v as version, h as hexToNumber, a as isHexEqual, f as normalizeHex, g as compress } from './shared/univo.
|
|
2
|
+
import { g as getException, c as createException, a as catchException, l as local } from './shared/univo.GuW0GiSl.mjs';
|
|
3
|
+
import { c as createLogger, d as decompress, e as decoder, r as retry, v as version, h as hexToNumber, a as isHexEqual, f as normalizeHex, g as compress } from './shared/univo.TYA11b8i.mjs';
|
|
4
4
|
import 'ws';
|
|
5
5
|
import 'partysocket';
|
|
6
6
|
|
|
@@ -309,86 +309,6 @@ function indexer(opts) {
|
|
|
309
309
|
await Promise.all(promises);
|
|
310
310
|
log.debug(`Wrote head in ${Date.now() - events_start}ms`);
|
|
311
311
|
};
|
|
312
|
-
const public_writeUnfinalizedHeads = async (heads) => {
|
|
313
|
-
if (heads.length === 0) {
|
|
314
|
-
return log.debug("No heads received, returning...");
|
|
315
|
-
}
|
|
316
|
-
let chain = void 0;
|
|
317
|
-
for (const head of heads) {
|
|
318
|
-
if (chain === void 0) {
|
|
319
|
-
chain = head.chain;
|
|
320
|
-
}
|
|
321
|
-
if (!isHexEqual(chain, head.chain)) {
|
|
322
|
-
throw new Error("Received heads from separate chains");
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (chain === void 0) {
|
|
326
|
-
throw new Error("Internal error. Expected chain to be defined after checking heads length");
|
|
327
|
-
}
|
|
328
|
-
log.debug(`Received ${heads.length} unfinalized heads...`);
|
|
329
|
-
const blocks_start = Date.now();
|
|
330
|
-
const [finalizedBlock, ...blocks_nullable] = await Promise.all([
|
|
331
|
-
getBlock({ chain, number: "finalized" }),
|
|
332
|
-
...heads.map(async (head) => {
|
|
333
|
-
return await getBlock({ chain, number: head.number, hash: head.hash });
|
|
334
|
-
})
|
|
335
|
-
]);
|
|
336
|
-
if (finalizedBlock === null) {
|
|
337
|
-
log.debug("Failed to determine finalized height when processing unfinalized heads");
|
|
338
|
-
throw new Error(GetBlockError);
|
|
339
|
-
}
|
|
340
|
-
const finalizedHeight = hexToNumber(finalizedBlock.eth_getBlockByNumber.number);
|
|
341
|
-
const blocks = blocks_nullable.flatMap((block) => {
|
|
342
|
-
if (block === null) {
|
|
343
|
-
return [];
|
|
344
|
-
}
|
|
345
|
-
if (hexToNumber(block.eth_getBlockByNumber.number) <= finalizedHeight) {
|
|
346
|
-
return [];
|
|
347
|
-
}
|
|
348
|
-
return block;
|
|
349
|
-
});
|
|
350
|
-
if (blocks.length === 0) {
|
|
351
|
-
return log.debug("All blocks failed to load, aborting early...");
|
|
352
|
-
}
|
|
353
|
-
log.debug(`Loaded ${blocks.length} block(s) in ${Date.now() - blocks_start}ms`);
|
|
354
|
-
await metadata.blocks.upsert(blocks);
|
|
355
|
-
log.debug(`Recorded ${blocks.length} block(s) to metadata storage`);
|
|
356
|
-
const events_start = Date.now();
|
|
357
|
-
const promises = events_grouped_by_storage_map.entries().map(async ([storage, grouped_events]) => {
|
|
358
|
-
const batch = [];
|
|
359
|
-
for (const block of blocks) {
|
|
360
|
-
for (const event2 of grouped_events) {
|
|
361
|
-
try {
|
|
362
|
-
if (!event2.filters.some((filter) => matchFilter(block, filter))) {
|
|
363
|
-
log.debug(`Block matches no filters for event ${event2.id}`);
|
|
364
|
-
continue;
|
|
365
|
-
}
|
|
366
|
-
const events = event2.handler(block);
|
|
367
|
-
for (const event3 of events) {
|
|
368
|
-
batch.push(event3);
|
|
369
|
-
}
|
|
370
|
-
} catch (error) {
|
|
371
|
-
log.error(`Failed to run your 'handler' for event ${event2.id}`);
|
|
372
|
-
throw error;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
if (batch.length > 0) {
|
|
377
|
-
const start = Date.now();
|
|
378
|
-
await retry(() => storage.upsert(batch), 2).catch((error) => {
|
|
379
|
-
for (const event2 of grouped_events) {
|
|
380
|
-
log.error(`Failed to run your 'upsert' handler for event ${event2.id}`);
|
|
381
|
-
}
|
|
382
|
-
throw error;
|
|
383
|
-
});
|
|
384
|
-
for (const event2 of grouped_events) {
|
|
385
|
-
log.debug(`Recorded ${batch.length} ${event2.id} in ${Date.now() - start}ms`);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
await Promise.all(promises);
|
|
390
|
-
log.debug(`Wrote ${heads.length} heads in ${Date.now() - events_start}ms`);
|
|
391
|
-
};
|
|
392
312
|
const public_deleteReorganisedHead = async (head) => {
|
|
393
313
|
log.debug(`Received reorganised head ${hexToNumber(head.number)}`);
|
|
394
314
|
const [canonical_block, stored_block] = await Promise.all([
|
|
@@ -404,10 +324,7 @@ function indexer(opts) {
|
|
|
404
324
|
if (isHexEqual(head.hash, canonical_block.eth_getBlockByNumber.hash)) {
|
|
405
325
|
throw new Error("Attempted to delete canonical block");
|
|
406
326
|
}
|
|
407
|
-
const
|
|
408
|
-
if (event2.storage.delete === void 0) {
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
327
|
+
const deletes = all_events.map(async (event2) => {
|
|
411
328
|
const batch = [];
|
|
412
329
|
try {
|
|
413
330
|
const events = event2.handler(stored_block);
|
|
@@ -426,7 +343,33 @@ function indexer(opts) {
|
|
|
426
343
|
throw error;
|
|
427
344
|
});
|
|
428
345
|
});
|
|
429
|
-
await Promise.all(
|
|
346
|
+
await Promise.all(deletes);
|
|
347
|
+
const upserts = events_grouped_by_storage_map.entries().map(async ([storage, grouped_events]) => {
|
|
348
|
+
const batch = [];
|
|
349
|
+
for (const event2 of grouped_events) {
|
|
350
|
+
try {
|
|
351
|
+
if (!event2.filters.some((filter) => matchFilter(canonical_block, filter))) {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
const events = event2.handler(canonical_block);
|
|
355
|
+
for (const event3 of events) {
|
|
356
|
+
batch.push(event3);
|
|
357
|
+
}
|
|
358
|
+
} catch (error) {
|
|
359
|
+
log.error(`Failed to run your 'handler' for event ${event2.id}`);
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (batch.length > 0) {
|
|
364
|
+
await retry(() => storage.upsert(batch), 2).catch((error) => {
|
|
365
|
+
for (const event2 of grouped_events) {
|
|
366
|
+
log.error(`Failed to run your 'upsert' handler for event ${event2.id}`);
|
|
367
|
+
}
|
|
368
|
+
throw error;
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
await Promise.all(upserts);
|
|
430
373
|
};
|
|
431
374
|
const public_writeFinalizedHeads = async (heads) => {
|
|
432
375
|
if (heads.length === 0) {
|
|
@@ -558,9 +501,6 @@ function indexer(opts) {
|
|
|
558
501
|
return;
|
|
559
502
|
}
|
|
560
503
|
const promises = all_events.map(async (event2) => {
|
|
561
|
-
if (event2.storage.delete === void 0) {
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
504
|
const batch = [];
|
|
565
505
|
try {
|
|
566
506
|
for (const block of blocks) {
|
|
@@ -860,7 +800,6 @@ function indexer(opts) {
|
|
|
860
800
|
public_getFinalizedHeight,
|
|
861
801
|
public_writeFinalizedHeads,
|
|
862
802
|
public_writeUnfinalizedHead,
|
|
863
|
-
public_writeUnfinalizedHeads,
|
|
864
803
|
public_deleteReorganisedHead,
|
|
865
804
|
private_getEvents,
|
|
866
805
|
private_getMetadata,
|
package/dist/realtime.d.mts
CHANGED
package/dist/realtime.d.ts
CHANGED
package/dist/realtime.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as createLogger, i as iife, h as hexToNumber, n as numberToHex, m as mutex, r as retry, a as isHexEqual } from './shared/univo.
|
|
1
|
+
import { c as createLogger, i as iife, h as hexToNumber, n as numberToHex, m as mutex, r as retry, a as isHexEqual } from './shared/univo.TYA11b8i.mjs';
|
|
2
2
|
|
|
3
3
|
function defineBlockchain(opts) {
|
|
4
4
|
const log = createLogger({ quiet: opts.quiet });
|
|
@@ -97,31 +97,25 @@ function realtime(opts) {
|
|
|
97
97
|
opts.node.request({ method: "eth_getBlockByNumber", params: ["latest", false] }),
|
|
98
98
|
opts.indexer.request({ method: "public_getFinalizedHeight", params: [chain] })
|
|
99
99
|
]);
|
|
100
|
-
let pending = [];
|
|
101
100
|
const latest = defineBlockchain({
|
|
102
101
|
getBlockByHash,
|
|
103
102
|
quiet: opts.quiet ?? false,
|
|
104
103
|
onBlockAdded: async (head) => {
|
|
105
104
|
try {
|
|
106
105
|
log.debug("Received unfinalized head");
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
await opts.indexer.request({ method: "public_writeUnfinalizedHeads", params: [heads] });
|
|
110
|
-
log.debug(`Delivered ${heads.length} unfinalized head(s)`);
|
|
111
|
-
pending = pending.filter((head2) => {
|
|
112
|
-
return !heads.some((_head) => {
|
|
113
|
-
return isHexEqual(head2.hash, _head.hash);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
106
|
+
await retry(() => opts.indexer.request({ method: "public_writeUnfinalizedHead", params: [{ chain, ...head }] }), 2);
|
|
107
|
+
log.debug("Delivered unfinalized head");
|
|
116
108
|
} catch (error) {
|
|
117
109
|
if (error instanceof Error) {
|
|
118
|
-
log.warn(`Failed to write
|
|
110
|
+
log.warn(`Failed to write unfinalized head: ${error.message}`);
|
|
119
111
|
}
|
|
120
112
|
}
|
|
121
113
|
},
|
|
122
114
|
onBlockReorganised: async (head) => {
|
|
123
115
|
try {
|
|
116
|
+
log.debug("Received reorganised head");
|
|
124
117
|
await retry(() => opts.indexer.request({ method: "public_deleteReorganisedHead", params: [{ chain, ...head }] }), 2);
|
|
118
|
+
log.debug("Delivered reorganised head");
|
|
125
119
|
} catch (error) {
|
|
126
120
|
if (error instanceof Error) {
|
|
127
121
|
log.warn(`Failed to write reorganised head: ${error.message}`);
|
package/dist/rpc.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as Head, M as Metadata, F as Flatten, a as Filter, B as Block, R as Result } from './shared/univo.
|
|
1
|
+
import { H as Head, M as Metadata, F as Flatten, a as Filter, B as Block, R as Result } from './shared/univo.BNqa7KED.mjs';
|
|
2
2
|
import '@storagesdk/core';
|
|
3
3
|
|
|
4
4
|
type Rpc = {
|
|
@@ -58,10 +58,6 @@ type IndexerRpc = {
|
|
|
58
58
|
* Accepts an unfinalized head and writes all events to storage
|
|
59
59
|
*/
|
|
60
60
|
public_writeUnfinalizedHead: (head: Head) => Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Accepts a list of the latest block heads and writes all events to storage
|
|
63
|
-
*/
|
|
64
|
-
public_writeUnfinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
65
61
|
/**
|
|
66
62
|
* Accepts a chain of finalized heads and upserts canonical events and deletes reorganised events
|
|
67
63
|
*/
|
package/dist/rpc.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as Head, M as Metadata, F as Flatten, a as Filter, B as Block, R as Result } from './shared/univo.
|
|
1
|
+
import { H as Head, M as Metadata, F as Flatten, a as Filter, B as Block, R as Result } from './shared/univo.BNqa7KED.js';
|
|
2
2
|
import '@storagesdk/core';
|
|
3
3
|
|
|
4
4
|
type Rpc = {
|
|
@@ -58,10 +58,6 @@ type IndexerRpc = {
|
|
|
58
58
|
* Accepts an unfinalized head and writes all events to storage
|
|
59
59
|
*/
|
|
60
60
|
public_writeUnfinalizedHead: (head: Head) => Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Accepts a list of the latest block heads and writes all events to storage
|
|
63
|
-
*/
|
|
64
|
-
public_writeUnfinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
65
61
|
/**
|
|
66
62
|
* Accepts a chain of finalized heads and upserts canonical events and deletes reorganised events
|
|
67
63
|
*/
|
|
@@ -106,7 +106,7 @@ type Event<TBlock, TEvent> = {
|
|
|
106
106
|
* same batch of events created by that reorganised block. This ensures that any events that were previously
|
|
107
107
|
* upserted into your storage system that are no longer part of the canonical chain are safely removed.
|
|
108
108
|
*/
|
|
109
|
-
delete
|
|
109
|
+
delete: (events: TEvent[]) => Promise<void>;
|
|
110
110
|
};
|
|
111
111
|
};
|
|
112
112
|
/**
|
|
@@ -192,7 +192,6 @@ declare function indexer<TBlock extends Block>(opts: IndexerOptions<TBlock>): {
|
|
|
192
192
|
public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number>;
|
|
193
193
|
public_deleteReorganisedHead: (head: Head) => Promise<void>;
|
|
194
194
|
public_writeUnfinalizedHead: (head: Head) => Promise<void>;
|
|
195
|
-
public_writeUnfinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
196
195
|
public_writeFinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
197
196
|
private_getMetadata: () => Promise<Metadata>;
|
|
198
197
|
private_getEvents: () => Promise<{
|
|
@@ -106,7 +106,7 @@ type Event<TBlock, TEvent> = {
|
|
|
106
106
|
* same batch of events created by that reorganised block. This ensures that any events that were previously
|
|
107
107
|
* upserted into your storage system that are no longer part of the canonical chain are safely removed.
|
|
108
108
|
*/
|
|
109
|
-
delete
|
|
109
|
+
delete: (events: TEvent[]) => Promise<void>;
|
|
110
110
|
};
|
|
111
111
|
};
|
|
112
112
|
/**
|
|
@@ -192,7 +192,6 @@ declare function indexer<TBlock extends Block>(opts: IndexerOptions<TBlock>): {
|
|
|
192
192
|
public_getFinalizedHeight: (chain: `0x${string}`) => Promise<number>;
|
|
193
193
|
public_deleteReorganisedHead: (head: Head) => Promise<void>;
|
|
194
194
|
public_writeUnfinalizedHead: (head: Head) => Promise<void>;
|
|
195
|
-
public_writeUnfinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
196
195
|
public_writeFinalizedHeads: (heads: Head[]) => Promise<void>;
|
|
197
196
|
private_getMetadata: () => Promise<Metadata>;
|
|
198
197
|
private_getEvents: () => Promise<{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ws from 'ws';
|
|
2
2
|
import { WebSocket } from 'partysocket';
|
|
3
|
-
import { g as compress, j as raise, c as createLogger } from './univo.
|
|
3
|
+
import { g as compress, j as raise, c as createLogger } from './univo.TYA11b8i.mjs';
|
|
4
4
|
|
|
5
5
|
function createException(message) {
|
|
6
6
|
return `univo:${message}`;
|
|
@@ -22,6 +22,7 @@ function getException(unknown) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
const DEFAULT_TIMEOUT = 60 * 1e3;
|
|
25
26
|
const UnknownMethodError = createException("The requested RPC method does not exist on the provided implementation");
|
|
26
27
|
function local(rpc) {
|
|
27
28
|
const request = async (opts) => {
|
|
@@ -114,7 +115,7 @@ function wss(url, opts = {}) {
|
|
|
114
115
|
const timeout = setTimeout(() => {
|
|
115
116
|
requests.delete(body.id);
|
|
116
117
|
reject(new Error("wss request timed out after 30 seconds"));
|
|
117
|
-
},
|
|
118
|
+
}, DEFAULT_TIMEOUT);
|
|
118
119
|
requests.set(body.id, (data) => {
|
|
119
120
|
clearTimeout(timeout);
|
|
120
121
|
requests.delete(body.id);
|
|
@@ -194,7 +195,7 @@ function http(url, opts = {}) {
|
|
|
194
195
|
headers.set("Content-Encoding", "gzip");
|
|
195
196
|
headers.set("Authorization", `Bearer ${opts.signingKey}`);
|
|
196
197
|
}
|
|
197
|
-
const res = await fetch(url, { headers, body, method: "POST", signal: AbortSignal.timeout(
|
|
198
|
+
const res = await fetch(url, { headers, body, method: "POST", signal: AbortSignal.timeout(DEFAULT_TIMEOUT) }).catch((cause) => {
|
|
198
199
|
throw new Error(ClientConnectionError, { cause });
|
|
199
200
|
});
|
|
200
201
|
if (!res.ok || res.status < 200 || res.status >= 300) {
|
package/dist/transport.d.mts
CHANGED
package/dist/transport.d.ts
CHANGED
package/dist/transport.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'ws';
|
|
2
2
|
import 'partysocket';
|
|
3
|
-
export { h as http, l as local, w as wss } from './shared/univo.
|
|
4
|
-
import './shared/univo.
|
|
3
|
+
export { h as http, l as local, w as wss } from './shared/univo.GuW0GiSl.mjs';
|
|
4
|
+
import './shared/univo.TYA11b8i.mjs';
|