From 8ced53114446580a0d885fab800bf072b58e5f2b Mon Sep 17 00:00:00 2001 From: MapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com> Date: Sat, 25 Dec 2021 12:56:58 -0600 Subject: [PATCH] library exports organization --- playground/counter.tsx | 5 +- src.new/{element.tsx => element.ts} | 0 src.new/embed/embed-field.tsx | 4 +- src.new/embed/embed-title.tsx | 4 +- src.new/jsx.d.ts | 15 ----- src.new/main.ts | 91 ++--------------------------- src.new/reacord.ts | 70 ++++++++++++++++++++++ 7 files changed, 80 insertions(+), 109 deletions(-) rename src.new/{element.tsx => element.ts} (100%) delete mode 100644 src.new/jsx.d.ts create mode 100644 src.new/reacord.ts diff --git a/playground/counter.tsx b/playground/counter.tsx index cb461c0..07456f6 100644 --- a/playground/counter.tsx +++ b/playground/counter.tsx @@ -1,8 +1,5 @@ import * as React from "react" -import { Button } from "../src.new/button.js" -import { EmbedField } from "../src.new/embed/embed-field.js" -import { EmbedTitle } from "../src.new/embed/embed-title.js" -import { Embed } from "../src.new/embed/embed.js" +import { Button, Embed, EmbedField, EmbedTitle } from "../src.new/main" export function Counter(props: { onDeactivate: () => void }) { const [count, setCount] = React.useState(0) diff --git a/src.new/element.tsx b/src.new/element.ts similarity index 100% rename from src.new/element.tsx rename to src.new/element.ts diff --git a/src.new/embed/embed-field.tsx b/src.new/embed/embed-field.tsx index 02f8b33..6c3013f 100644 --- a/src.new/embed/embed-field.tsx +++ b/src.new/embed/embed-field.tsx @@ -1,6 +1,6 @@ -import { MessageEmbedOptions } from "discord.js" +import type { MessageEmbedOptions } from "discord.js" import React from "react" -import { ReacordElement } from "../element.jsx" +import { ReacordElement } from "../element.js" import { EmbedChildNode } from "./embed-child.js" export type EmbedFieldProps = { diff --git a/src.new/embed/embed-title.tsx b/src.new/embed/embed-title.tsx index 9bc3b32..50958ef 100644 --- a/src.new/embed/embed-title.tsx +++ b/src.new/embed/embed-title.tsx @@ -1,6 +1,6 @@ -import { MessageEmbedOptions } from "discord.js" +import type { MessageEmbedOptions } from "discord.js" import React from "react" -import { ReacordElement } from "../element.jsx" +import { ReacordElement } from "../element.js" import { EmbedChildNode } from "./embed-child.js" export type EmbedTitleProps = { diff --git a/src.new/jsx.d.ts b/src.new/jsx.d.ts deleted file mode 100644 index 6619dd9..0000000 --- a/src.new/jsx.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ReactNode } from "react" -import type { Node } from "./node.js" - -declare global { - namespace JSX { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions - interface IntrinsicElements { - "reacord-element": { - props: Record - createNode: (props: Record) => Node - children?: ReactNode - } - } - } -} diff --git a/src.new/main.ts b/src.new/main.ts index 5505a24..24cbec5 100644 --- a/src.new/main.ts +++ b/src.new/main.ts @@ -1,86 +1,5 @@ -import type { - Client, - CommandInteraction, - MessageComponentInteraction, -} from "discord.js" -import type { ReactNode } from "react" -import type { OpaqueRoot } from "react-reconciler" -import { reconciler } from "./reconciler.js" -import { Renderer } from "./renderer.js" - -export type ReacordConfig = { - /** - * A Discord.js client. Reacord will listen to interaction events - * and send them to active instances. */ - client: Client - - /** - * The max number of active instances. - * When this limit is exceeded, the oldest instances will be disabled. - */ - maxInstances?: number -} - -export class Reacord { - private instances: Instance[] = [] - - private constructor(private readonly config: ReacordConfig) {} - - private get maxInstances() { - return this.config.maxInstances ?? 50 - } - - static create(config: ReacordConfig) { - const manager = new Reacord(config) - - config.client.on("interactionCreate", (interaction) => { - if (!interaction.isMessageComponent()) return - for (const instance of manager.instances) { - if (instance.handleInteraction(interaction)) return - } - }) - - return manager - } - - reply(interaction: CommandInteraction) { - const instance = new Instance(interaction) - this.instances.push(instance) - - if (this.instances.length > this.maxInstances) { - this.deactivate(this.instances[0]!) - } - - return { - render: (content: ReactNode) => instance.render(content), - deactivate: () => this.deactivate(instance), - } - } - - private deactivate(instance: Instance) { - this.instances = this.instances.filter((it) => it !== instance) - instance.deactivate() - } -} - -class Instance { - private renderer: Renderer - private container: OpaqueRoot - - constructor(interaction: CommandInteraction) { - this.renderer = new Renderer(interaction) - this.container = reconciler.createContainer(this.renderer, 0, false, {}) - } - - render(content: ReactNode) { - reconciler.updateContainer(content, this.container) - } - - deactivate() { - this.renderer.deactivate() - } - - handleInteraction(interaction: MessageComponentInteraction) { - return this.renderer.handleInteraction(interaction) - } -} +export * from "./button" +export * from "./embed/embed" +export * from "./embed/embed-field" +export * from "./embed/embed-title" +export * from "./reacord" diff --git a/src.new/reacord.ts b/src.new/reacord.ts new file mode 100644 index 0000000..b4597a3 --- /dev/null +++ b/src.new/reacord.ts @@ -0,0 +1,70 @@ +import type { Client, CommandInteraction } from "discord.js" +import type { ReactNode } from "react" +import { reconciler } from "./reconciler.js" +import { Renderer } from "./renderer.js" + +export type ReacordConfig = { + /** + * A Discord.js client. Reacord will listen to interaction events + * and send them to active instances. */ + client: Client + + /** + * The max number of active instances. + * When this limit is exceeded, the oldest instances will be disabled. + */ + maxInstances?: number +} + +export type ReacordInstance = { + render: (content: ReactNode) => void + deactivate: () => void +} + +export class Reacord { + private renderers: Renderer[] = [] + + private constructor(private readonly config: ReacordConfig) {} + + private get maxInstances() { + return this.config.maxInstances ?? 50 + } + + static create(config: ReacordConfig) { + const manager = new Reacord(config) + + config.client.on("interactionCreate", (interaction) => { + if (!interaction.isMessageComponent()) return + for (const renderer of manager.renderers) { + if (renderer.handleInteraction(interaction)) return + } + }) + + return manager + } + + reply(interaction: CommandInteraction): ReacordInstance { + if (this.renderers.length > this.maxInstances) { + this.deactivate(this.renderers[0]!) + } + + const renderer = new Renderer(interaction) + this.renderers.push(renderer) + + const container = reconciler.createContainer(renderer, 0, false, {}) + + return { + render: (content: ReactNode) => { + reconciler.updateContainer(content, container) + }, + deactivate: () => { + this.deactivate(renderer) + }, + } + } + + private deactivate(renderer: Renderer) { + this.renderers = this.renderers.filter((it) => it !== renderer) + renderer.deactivate() + } +}