From b1f6a44a6a29c38c25f80503852fabdc399e9361 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Fri, 25 Feb 2022 03:22:58 +0000 Subject: [PATCH] SystemQueryClient: Add generator for fetching tables via SSE --- src/static/js/SystemQueryClient.mjs | 22 ++++++++++++++++++++++ src/static/js/misc/events.mjs | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/static/js/misc/events.mjs diff --git a/src/static/js/SystemQueryClient.mjs b/src/static/js/SystemQueryClient.mjs index acbe651..03720cd 100644 --- a/src/static/js/SystemQueryClient.mjs +++ b/src/static/js/SystemQueryClient.mjs @@ -1,5 +1,7 @@ "use strict"; +import { once } from './misc/events.mjs'; + class SystemQueryClient { constructor() { @@ -9,6 +11,26 @@ class SystemQueryClient { return this.fetch_json(`/api/status`); } + async *table(table_name) { + const abort = new AbortController(); + const source = new EventSource(`/api/table/${table_name}`); + + source.addEventListener(`end`, () => { + source.close(); + abort.abort(); + }, { once: true }); + + let count = 0; + while(source.readyState !== EventSource.CLOSED) { + let item = await once(source, "table", abort.signal); + if(item.type === "abort") break; + + yield JSON.parse(item.data); + count++; + } + console.log(`FETCH TABLE ${table_name}: ${count} items returned`); + } + async fetch_json(path) { let response = await fetch(path, { headers: { diff --git a/src/static/js/misc/events.mjs b/src/static/js/misc/events.mjs new file mode 100644 index 0000000..d596de5 --- /dev/null +++ b/src/static/js/misc/events.mjs @@ -0,0 +1,22 @@ +"use strict"; + +function once(event_emitter, event_name, abort_signal = null) { + return new Promise((resolve, reject) => { + let options = { + once: true + }; + if(abort_signal !== null) options.signal = abort_signal; + + let resolve_handler = function() { + event_emitter.removeEventListener("error", reject); + abort_signal.removeEventListener("abort", resolve_handler); + resolve(...arguments); + }; + + abort_signal.addEventListener("abort", resolve_handler); + event_emitter.addEventListener("error", reject, options); + event_emitter.addEventListener(event_name, resolve_handler, options); + }); +} + +export { once };