clean up container code a bit

This commit is contained in:
MapleLeaf
2021-12-15 11:21:30 -06:00
parent 20dc55d557
commit b7a3be73ee
3 changed files with 31 additions and 35 deletions

View File

@@ -85,7 +85,7 @@ test("state", async (t) => {
await assertSomeMessageHasContent(t, initialMessage)
setMessage!(newMessage)
await root.awaitActions()
await root.completion()
await assertSomeMessageHasContent(t, newMessage)

View File

@@ -5,56 +5,45 @@ type Action =
| { type: "deleteMessage" }
export class ReacordContainer {
channel: TextBasedChannels
message?: Message
actions: Action[] = []
runningPromise?: Promise<void>
private channel: TextBasedChannels
private message?: Message
private actions: Action[] = []
private runningPromise?: Promise<void>
constructor(channel: TextBasedChannels) {
this.channel = channel
}
async render(instances: string[]) {
render(instances: string[]) {
const messageOptions: MessageOptions = {
content: instances.join("") || undefined, // empty strings are not allowed
}
const hasContent = messageOptions.content !== undefined
await this.addAction(
this.addAction(
hasContent
? { type: "updateMessage", options: messageOptions }
: { type: "deleteMessage" },
)
}
private async addAction(action: Action) {
completion() {
return this.runningPromise ?? Promise.resolve()
}
private addAction(action: Action) {
const lastAction = this.actions[this.actions.length - 1]
if (lastAction?.type === action.type) {
this.actions[this.actions.length - 1] = action
} else {
this.actions.push(action)
}
await this.runActions()
this.runActions()
}
private async runActions() {
if (this.runningPromise) {
return this.runningPromise
}
const runAction = async (action: Action) => {
if (action.type === "updateMessage") {
this.message = await (this.message
? this.message.edit(action.options)
: this.channel.send(action.options))
}
if (action.type === "deleteMessage") {
await this.message?.delete()
this.message = undefined
}
}
private runActions() {
if (this.runningPromise) return
this.runningPromise = new Promise((resolve) => {
// using a microtask to allow multiple actions to be added synchronously
@@ -62,21 +51,28 @@ export class ReacordContainer {
let action: Action | undefined
while ((action = this.actions.shift())) {
try {
await runAction(action)
await this.runAction(action)
} catch (error) {
console.error(`Failed to run action:`, action)
console.error(error)
}
}
resolve()
this.runningPromise = undefined
})
})
await this.runningPromise
this.runningPromise = undefined
}
awaitActions() {
return this.runningPromise ?? Promise.resolve()
private async runAction(action: Action) {
if (action.type === "updateMessage") {
this.message = await (this.message
? this.message.edit(action.options)
: this.channel.send(action.options))
}
if (action.type === "deleteMessage") {
await this.message?.delete()
this.message = undefined
}
}
}

View File

@@ -12,12 +12,12 @@ export function createRoot(target: ReacordRenderTarget) {
return {
render: (content: ReactNode) => {
reconciler.updateContainer(content, containerId)
return container.awaitActions()
return container.completion()
},
destroy: () => {
reconciler.updateContainer(null, containerId)
return container.awaitActions()
return container.completion()
},
awaitActions: () => container.awaitActions(),
completion: () => container.completion(),
}
}