clean up container code a bit
This commit is contained in:
@@ -85,7 +85,7 @@ test("state", async (t) => {
|
||||
await assertSomeMessageHasContent(t, initialMessage)
|
||||
|
||||
setMessage!(newMessage)
|
||||
await root.awaitActions()
|
||||
await root.completion()
|
||||
|
||||
await assertSomeMessageHasContent(t, newMessage)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user