UNPKG

@brimdata/zealot

Version:

The Javascript Client for Zed Lakes

81 lines (67 loc) 1.85 kB
import EventEmitter from "events" import * as zed from "../zed" import * as zjson from "../zjson" import {Collector, TypeDefs} from "../types" import {DecodeStream} from "../zed/decode-stream" export class Channel extends EventEmitter { rows: zed.Value[] = [] shapesMap: TypeDefs = {} stream = new DecodeStream(zed.DefaultContext) get shapes() { return Object.values(this.shapesMap) } addRow(row: zed.Value) { this.rows.push(row) this.emit("row", row) } addShape(id: number | string, type: zed.Type) { this.shapesMap[id] = type this.emit("shape", type) } hasShape(id: number) { return id in this.shapesMap } done() { this.emit("end") } consume(json: zjson.Object) { const value = this.stream.decode(json) if ("id" in json.type && !this.hasShape(json.type.id)) { this.addShape(json.type.id, value.type) } else if (json.type.kind === "primitive") { this.addShape(json.type.name, value.type) } this.addRow(value) } collect(collector: Collector) { /** * The goal here is to get the first batch of results out * to the collector as soon as possible. Then, only give * updates every timeThres. This allows the UI to avoid * frequent, expensive updates. */ let first = true let count = 0 let countThresh = 2000 let timeThresh = 2000 let timeId = 0 const flush = () => { collector({rows: this.rows, shapesMap: this.shapesMap}) first = false count = 0 clearTimeout(timeId) } const startTimer = () => { timeId = setTimeout(() => { if (count > 0) flush() startTimer() }, timeThresh) } this.on("row", () => { count += 1 if (first && count >= countThresh) flush() }) this.on("end", () => flush()) startTimer() } }