@substreams/node
Version:
Substreams for Node.js & Web
122 lines • 4.45 kB
JavaScript
import { createCallbackClient } from "@connectrpc/connect";
import { isEmptyMessage, unpackMapOutput } from "@substreams/core";
import { Stream, } from "@substreams/core/proto";
import { EventEmitter } from "eventemitter3";
export class TypedEventEmitter {
emitter = new EventEmitter();
emit(eventName, ...eventArg) {
return this.emitter.emit(eventName, ...eventArg);
}
on(eventName, handler) {
return this.emitter.on(eventName, handler);
}
once(eventName, handler) {
return this.emitter.once(eventName, handler);
}
removeListener(eventName, handler) {
return this.emitter.removeListener(eventName, handler);
}
removeAllListeners(eventName) {
if (eventName) {
return this.emitter.removeAllListeners(eventName);
}
return this.emitter.removeAllListeners();
}
eventNames() {
return this.emitter.eventNames();
}
listenerCount(eventName) {
return this.emitter.listenerCount(eventName);
}
off(eventName, handler) {
return this.emitter.off(eventName, handler);
}
}
export class BlockEmitter extends TypedEventEmitter {
transport;
request; // Request
registry; // IMessageTypeRegistry
options;
cancelFn;
constructor(transport, request /* Request */, registry /* IMessageTypeRegistry */, options) {
super();
this.transport = transport;
this.request = request;
this.registry = registry;
this.options = options;
}
/**
* Stop streaming blocks
*/
stop() {
if (this.cancelFn) {
this.cancelFn();
}
else {
throw new Error("BlockEmitter.stop() called before BlockEmitter.start()");
}
}
/**
* Start streaming blocks
*/
start() {
const closeCallback = (error) => {
this.emit("close", error);
this.cancelFn = undefined;
};
const messageCallback = (response) => {
this.emit("response", response);
switch (response.message.case) {
case "blockScopedData": {
const block = response.message.value;
const isNotTyped = block.output?.mapOutput?.typeUrl == '';
const isEmpty = block.output?.mapOutput?.value.byteLength === 0;
this.emit("block", block);
if (block.clock && !isEmpty && !isNotTyped) {
const output = unpackMapOutput(response, this.registry);
if (output) {
this.emit("output", output, block.cursor, block.clock);
if (!isEmptyMessage(output)) {
const message = output.toJson({ typeRegistry: this.registry });
this.emit("anyMessage", message, block.cursor, block.clock);
}
}
}
if (block.clock) {
this.emit("clock", block.clock);
this.emit("cursor", block.cursor, block.clock);
}
break;
}
case "progress": {
this.emit("progress", response.message.value);
break;
}
case "session": {
this.emit("session", response.message.value);
break;
}
case "blockUndoSignal": {
this.emit("undo", response.message.value);
break;
}
case "debugSnapshotData": {
this.emit("debugSnapshotData", response.message.value);
break;
}
case "debugSnapshotComplete": {
this.emit("debugSnapshotComplete", response.message.value);
break;
}
case "fatalError": {
this.emit("fatalError", response.message.value);
break;
}
}
};
const client = createCallbackClient(Stream, this.transport);
this.cancelFn = client.blocks(this.request, messageCallback, closeCallback, this.options);
return this.cancelFn;
}
}
//# sourceMappingURL=BlockEmitter.js.map