summaryrefslogtreecommitdiff
path: root/ui/lib
diff options
context:
space:
mode:
Diffstat (limited to 'ui/lib')
-rw-r--r--ui/lib/outbox.svelte.js47
1 files changed, 47 insertions, 0 deletions
diff --git a/ui/lib/outbox.svelte.js b/ui/lib/outbox.svelte.js
new file mode 100644
index 0000000..0681f29
--- /dev/null
+++ b/ui/lib/outbox.svelte.js
@@ -0,0 +1,47 @@
+import * as api from './apiServer.js';
+import * as md from './markdown.js';
+
+class Message {
+ constructor(channel, body) {
+ this.channel = channel;
+ this.body = body;
+ this.renderedBody = md.render(body);
+ }
+}
+
+export class Outbox {
+ pending = $state([]);
+
+ static empty() {
+ return new Outbox([]);
+ }
+
+ constructor(pending) {
+ this.pending = pending;
+ }
+
+ send(channel, body) {
+ this.pending.push(new Message(channel, body));
+ this.start();
+ }
+
+ start() {
+ if (this.sending) {
+ return;
+ }
+ // This is a promise transform primarily to keep the management of `this.sending` in one place,
+ // rather than spreading it across multiple methods.
+ this.sending = this.drain().finally(() => {
+ this.sending = null;
+ });
+ }
+
+ async drain() {
+ while (this.pending.length > 0) {
+ const { channel, body } = this.pending[0];
+
+ await api.retry(() => api.postToChannel(channel, body));
+ this.pending.shift();
+ }
+ }
+}