clean up container code a bit
This commit is contained in:
@@ -85,7 +85,7 @@ test("state", async (t) => {
|
|||||||
await assertSomeMessageHasContent(t, initialMessage)
|
await assertSomeMessageHasContent(t, initialMessage)
|
||||||
|
|
||||||
setMessage!(newMessage)
|
setMessage!(newMessage)
|
||||||
await root.awaitActions()
|
await root.completion()
|
||||||
|
|
||||||
await assertSomeMessageHasContent(t, newMessage)
|
await assertSomeMessageHasContent(t, newMessage)
|
||||||
|
|
||||||
|
|||||||
@@ -5,56 +5,45 @@ type Action =
|
|||||||
| { type: "deleteMessage" }
|
| { type: "deleteMessage" }
|
||||||
|
|
||||||
export class ReacordContainer {
|
export class ReacordContainer {
|
||||||
channel: TextBasedChannels
|
private channel: TextBasedChannels
|
||||||
message?: Message
|
private message?: Message
|
||||||
actions: Action[] = []
|
private actions: Action[] = []
|
||||||
runningPromise?: Promise<void>
|
private runningPromise?: Promise<void>
|
||||||
|
|
||||||
constructor(channel: TextBasedChannels) {
|
constructor(channel: TextBasedChannels) {
|
||||||
this.channel = channel
|
this.channel = channel
|
||||||
}
|
}
|
||||||
|
|
||||||
async render(instances: string[]) {
|
render(instances: string[]) {
|
||||||
const messageOptions: MessageOptions = {
|
const messageOptions: MessageOptions = {
|
||||||
content: instances.join("") || undefined, // empty strings are not allowed
|
content: instances.join("") || undefined, // empty strings are not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasContent = messageOptions.content !== undefined
|
const hasContent = messageOptions.content !== undefined
|
||||||
|
|
||||||
await this.addAction(
|
this.addAction(
|
||||||
hasContent
|
hasContent
|
||||||
? { type: "updateMessage", options: messageOptions }
|
? { type: "updateMessage", options: messageOptions }
|
||||||
: { type: "deleteMessage" },
|
: { 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]
|
const lastAction = this.actions[this.actions.length - 1]
|
||||||
if (lastAction?.type === action.type) {
|
if (lastAction?.type === action.type) {
|
||||||
this.actions[this.actions.length - 1] = action
|
this.actions[this.actions.length - 1] = action
|
||||||
} else {
|
} else {
|
||||||
this.actions.push(action)
|
this.actions.push(action)
|
||||||
}
|
}
|
||||||
await this.runActions()
|
this.runActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private async runActions() {
|
private runActions() {
|
||||||
if (this.runningPromise) {
|
if (this.runningPromise) return
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.runningPromise = new Promise((resolve) => {
|
this.runningPromise = new Promise((resolve) => {
|
||||||
// using a microtask to allow multiple actions to be added synchronously
|
// using a microtask to allow multiple actions to be added synchronously
|
||||||
@@ -62,21 +51,28 @@ export class ReacordContainer {
|
|||||||
let action: Action | undefined
|
let action: Action | undefined
|
||||||
while ((action = this.actions.shift())) {
|
while ((action = this.actions.shift())) {
|
||||||
try {
|
try {
|
||||||
await runAction(action)
|
await this.runAction(action)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to run action:`, action)
|
console.error(`Failed to run action:`, action)
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolve()
|
resolve()
|
||||||
|
this.runningPromise = undefined
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.runningPromise
|
|
||||||
this.runningPromise = undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
awaitActions() {
|
private async runAction(action: Action) {
|
||||||
return this.runningPromise ?? Promise.resolve()
|
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 {
|
return {
|
||||||
render: (content: ReactNode) => {
|
render: (content: ReactNode) => {
|
||||||
reconciler.updateContainer(content, containerId)
|
reconciler.updateContainer(content, containerId)
|
||||||
return container.awaitActions()
|
return container.completion()
|
||||||
},
|
},
|
||||||
destroy: () => {
|
destroy: () => {
|
||||||
reconciler.updateContainer(null, containerId)
|
reconciler.updateContainer(null, containerId)
|
||||||
return container.awaitActions()
|
return container.completion()
|
||||||
},
|
},
|
||||||
awaitActions: () => container.awaitActions(),
|
completion: () => container.completion(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user