lunibee 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -0
- package/dist/builders/attachment.d.ts +20 -0
- package/dist/builders/commands.d.ts +118 -0
- package/dist/builders/components.d.ts +151 -0
- package/dist/builders/embed.d.ts +59 -0
- package/dist/builders/index.d.ts +5 -0
- package/dist/builders/index.js +828 -0
- package/dist/builders/index.js.map +13 -0
- package/dist/collection/cache.d.ts +37 -0
- package/dist/collection/index.d.ts +47 -0
- package/dist/collection/index.js +214 -0
- package/dist/collection/index.js.map +11 -0
- package/dist/core/client-state.d.ts +10 -0
- package/dist/core/collector.d.ts +27 -0
- package/dist/core/events.d.ts +5 -0
- package/dist/core/index.d.ts +111 -0
- package/dist/core/index.js +3188 -0
- package/dist/core/index.js.map +29 -0
- package/dist/core/permissions.d.ts +293 -0
- package/dist/formatters/index.d.ts +10 -0
- package/dist/formatters/index.js +43 -0
- package/dist/formatters/index.js.map +10 -0
- package/dist/handlers/index.d.ts +16 -0
- package/dist/handlers/index.js +37 -0
- package/dist/handlers/index.js.map +10 -0
- package/{src/index.ts → dist/index.d.ts} +2 -29
- package/dist/index.js +4182 -0
- package/dist/index.js.map +41 -0
- package/dist/managers/application.d.ts +28 -0
- package/dist/managers/base.d.ts +28 -0
- package/dist/managers/index.d.ts +96 -0
- package/dist/managers/index.js +947 -0
- package/dist/managers/index.js.map +22 -0
- package/dist/managers/member.d.ts +35 -0
- package/dist/managers/message.d.ts +25 -0
- package/dist/managers/role.d.ts +34 -0
- package/dist/managers/thread.d.ts +14 -0
- package/dist/rest/index.d.ts +49 -0
- package/dist/rest/index.js +344 -0
- package/dist/rest/index.js.map +12 -0
- package/dist/rest/routes.d.ts +44 -0
- package/dist/rest/types.d.ts +26 -0
- package/dist/rest/webhook.d.ts +40 -0
- package/dist/sharding/bus.d.ts +22 -0
- package/dist/sharding/index.d.ts +34 -0
- package/dist/sharding/index.js +732 -0
- package/dist/sharding/index.js.map +13 -0
- package/dist/structures/base.d.ts +75 -0
- package/dist/structures/index.d.ts +39 -0
- package/dist/structures/index.js +571 -0
- package/dist/structures/index.js.map +14 -0
- package/dist/structures/interactions.d.ts +136 -0
- package/dist/structures/permissions.d.ts +73 -0
- package/dist/structures/resources.d.ts +64 -0
- package/dist/types/index.d.ts +535 -0
- package/dist/types/index.js +132 -0
- package/dist/types/index.js.map +10 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +10 -0
- package/dist/voice/index.d.ts +97 -0
- package/dist/voice/index.js +161 -0
- package/dist/voice/index.js.map +10 -0
- package/dist/ws/index.d.ts +76 -0
- package/dist/ws/index.js +582 -0
- package/dist/ws/index.js.map +11 -0
- package/package.json +113 -28
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/builders/src/embed.ts", "../../packages/builders/src/components.ts", "../../packages/builders/src/commands.ts", "../../packages/builders/src/attachment.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/** Discord API embed field payload. */\nexport interface EmbedField {\n /** Field name. */ name: string;\n /** Field value. */ value: string;\n /** Whether the field is displayed inline. */ inline?: boolean;\n}\n/** Discord API embed footer payload. */\nexport interface EmbedFooter {\n /** Footer text. */ text: string;\n /** Footer icon URL. */ icon_url?: string;\n}\n/** Discord API embed author payload. */\nexport interface EmbedAuthor {\n /** Author display name. */ name: string;\n /** Author URL. */ url?: string;\n /** Author icon URL. */ icon_url?: string;\n}\n/** Strict Discord API embed payload. */\nexport interface APIEmbed {\n /** Embed title. */ title?: string;\n /** Embed description. */ description?: string;\n /** Embed URL. */ url?: string;\n /** Embed color. */ color?: number;\n /** ISO-8601 timestamp. */ timestamp?: string;\n /** Embed footer. */ footer?: EmbedFooter;\n /** Embed author. */ author?: EmbedAuthor;\n /** Thumbnail payload. */ thumbnail?: { /** Thumbnail URL. */ url: string };\n /** Image payload. */ image?: { /** Image URL. */ url: string };\n /** Embed fields. */ fields?: EmbedField[];\n}\n\n/** Builds compile-time-safe rich embed payloads for Discord API requests. */\nexport class EmbedBuilder {\n readonly #data: APIEmbed = {};\n /** Sets the embed title. @param value Title text. @returns This builder. @throws {RangeError} If title exceeds Discord's limit. */ public setTitle(\n value: string,\n ): this {\n this.#data.title = validate(value, 256, \"Embed title\");\n return this;\n }\n /** Sets the embed description. @param value Description text. @returns This builder. @throws {RangeError} If description exceeds Discord's limit. */ public setDescription(\n value: string,\n ): this {\n this.#data.description = validate(value, 4096, \"Embed description\");\n return this;\n }\n /** Sets the embed URL. @param value Absolute URL. @returns This builder. @throws {TypeError} If URL is invalid. */ public setURL(\n value: string,\n ): this {\n this.#data.url = url(value, \"Embed URL\");\n return this;\n }\n /** Sets the embed color. @param value RGB integer. @returns This builder. @throws {RangeError} If color is outside 24-bit RGB range. */ public setColor(\n value: number,\n ): this {\n if (!Number.isInteger(value) || value < 0 || value > 0xffffff)\n throw new RangeError(\n \"Embed color must be an integer between 0 and 16777215.\",\n );\n this.#data.color = value;\n return this;\n }\n /** Sets the embed timestamp. @param value Date value. @returns This builder. @throws {RangeError} If date is invalid. */ public setTimestamp(\n value = new Date(),\n ): this {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime()))\n throw new RangeError(\"Embed timestamp must be a valid date.\");\n this.#data.timestamp = date.toISOString();\n return this;\n }\n /** Sets the embed footer. @param value Footer payload. @returns This builder. @throws {RangeError} If footer text exceeds Discord's limit. */ public setFooter(\n value: EmbedFooter,\n ): this {\n this.#data.footer = {\n text: validate(value.text, 2048, \"Footer text\"),\n ...(value.icon_url\n ? { icon_url: url(value.icon_url, \"Footer icon URL\") }\n : {}),\n };\n return this;\n }\n /** Sets the embed author. @param value Author payload. @returns This builder. @throws {RangeError} If author name exceeds Discord's limit. */ public setAuthor(\n value: EmbedAuthor,\n ): this {\n this.#data.author = {\n name: validate(value.name, 256, \"Author name\"),\n ...(value.url ? { url: url(value.url, \"Author URL\") } : {}),\n ...(value.icon_url\n ? { icon_url: url(value.icon_url, \"Author icon URL\") }\n : {}),\n };\n return this;\n }\n /** Sets the thumbnail URL. @param value Thumbnail URL or payload. @returns This builder. @throws {TypeError} If URL is invalid. */ public setThumbnail(\n value: { url: string } | string,\n ): this {\n const valueURL = typeof value === \"string\" ? value : value.url;\n this.#data.thumbnail = { url: url(valueURL, \"Thumbnail URL\") };\n return this;\n }\n /** Sets the image URL. @param value Image URL or payload. @returns This builder. @throws {TypeError} If URL is invalid. */ public setImage(\n value: { url: string } | string,\n ): this {\n const valueURL = typeof value === \"string\" ? value : value.url;\n this.#data.image = { url: url(valueURL, \"Image URL\") };\n return this;\n }\n /** Adds embed fields. @param fields Field payloads. @returns This builder. @throws {RangeError} If the 25-field limit is exceeded. */ public addFields(\n ...fields: EmbedField[]\n ): this {\n if (!fields.length)\n throw new TypeError(\"At least one embed field is required.\");\n const current = this.#data.fields ?? [];\n if (current.length + fields.length > 25)\n throw new RangeError(\"An embed cannot contain more than 25 fields.\");\n for (const field of fields) {\n validate(field.name, 256, \"Embed field name\");\n validate(field.value, 1024, \"Embed field value\");\n }\n this.#data.fields = [...current, ...fields.map((field) => ({ ...field }))];\n return this;\n }\n public setFields(fields: EmbedField[]): this {\n this.#data.fields = [];\n return this.addFields(...fields);\n }\n /** Replaces fields starting at an index. @param index Start index. @param deleteCount Number of fields to remove. @param fields Replacement fields. @returns This builder. @throws {RangeError} If arguments are invalid or the 25-field limit is exceeded. */ public spliceFields(\n index: number,\n deleteCount: number,\n ...fields: EmbedField[]\n ): this {\n const current = [...(this.#data.fields ?? [])];\n if (\n !Number.isInteger(index) ||\n !Number.isInteger(deleteCount) ||\n index < 0 ||\n deleteCount < 0\n )\n throw new RangeError(\n \"Field index and delete count must be non-negative integers.\",\n );\n current.splice(index, deleteCount, ...fields);\n if (current.length > 25)\n throw new RangeError(\"An embed cannot contain more than 25 fields.\");\n this.#data.fields = current;\n return this;\n }\n /** Removes all embed fields. @returns This builder. */ public clearFields(): this {\n delete this.#data.fields;\n return this;\n }\n /** Removes the embed title. @returns This builder. */ public clearTitle(): this {\n delete this.#data.title;\n return this;\n }\n /** Removes the embed description. @returns This builder. */ public clearDescription(): this {\n delete this.#data.description;\n return this;\n }\n /** Returns a deep-cloned Discord API payload. @returns Strict embed payload. */ public get data(): APIEmbed {\n return this.toJSON();\n }\n public toJSON(): APIEmbed {\n return structuredClone(this.#data);\n }\n}\n/** Validates a bounded Discord string field. @param value Field value. @param max Maximum length. @param field Human-readable field name. @returns Validated value. @throws {RangeError} If length is invalid. */\nfunction validate(value: string, max: number, field: string): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new RangeError(`${field} must contain 1-${max} characters.`);\n return value;\n}\n/** Validates and normalizes an absolute URL. @param value URL value. @param field Human-readable field name. @returns Normalized URL. @throws {TypeError} If URL is invalid. */\nfunction url(value: string, field: string): string {\n try {\n return new URL(value).toString();\n } catch (error) {\n throw new TypeError(`${field} must be a valid URL.`, { cause: error });\n }\n}\n",
|
|
6
|
+
"/** Component type constants exposed by Lunibee. */\nexport const ComponentType = {\n ActionRow: 1,\n Button: 2,\n StringSelect: 3,\n TextInput: 4,\n UserSelect: 5,\n RoleSelect: 6,\n MentionableSelect: 7,\n ChannelSelect: 8,\n} as const;\nexport const ButtonStyle = {\n Primary: 1,\n Secondary: 2,\n Success: 3,\n Danger: 4,\n Link: 5,\n} as const;\nexport const TextInputStyle = { Short: 1, Paragraph: 2 } as const;\nexport interface APIComponentEmoji {\n id?: string | null;\n name?: string | null;\n animated?: boolean;\n}\nexport interface APIButtonComponent {\n type: typeof ComponentType.Button;\n style: 1 | 2 | 3 | 4 | 5;\n custom_id?: string;\n label?: string;\n emoji?: APIComponentEmoji;\n url?: string;\n disabled?: boolean;\n}\nexport interface APISelectOption {\n label: string;\n value: string;\n description?: string;\n emoji?: APIComponentEmoji;\n default?: boolean;\n}\nexport interface APIStringSelectComponent {\n type: typeof ComponentType.StringSelect;\n custom_id?: string;\n placeholder?: string;\n min_values?: number;\n max_values?: number;\n required?: boolean;\n disabled?: boolean;\n options?: APISelectOption[];\n}\nexport interface APIEntitySelectComponent {\n type:\n | typeof ComponentType.UserSelect\n | typeof ComponentType.RoleSelect\n | typeof ComponentType.MentionableSelect\n | typeof ComponentType.ChannelSelect;\n custom_id?: string;\n placeholder?: string;\n min_values?: number;\n max_values?: number;\n required?: boolean;\n disabled?: boolean;\n}\nexport interface APITextInputComponent {\n type: typeof ComponentType.TextInput;\n style: typeof TextInputStyle.Short | typeof TextInputStyle.Paragraph;\n custom_id?: string;\n label?: string;\n placeholder?: string;\n min_length?: number;\n max_length?: number;\n required?: boolean;\n value?: string;\n}\nexport interface APIModalComponent {\n type: 9;\n custom_id?: string;\n title?: string;\n components: APIActionRowComponent[];\n}\nexport type APIActionRowChild =\n | APIButtonComponent\n | APIStringSelectComponent\n | APIEntitySelectComponent\n | APITextInputComponent;\nexport interface APIActionRowComponent {\n type: typeof ComponentType.ActionRow;\n components: APIActionRowChild[];\n}\n\nexport class ActionRowBuilder<\n T extends { toJSON(): APIActionRowChild } = { toJSON(): APIActionRowChild },\n> {\n readonly #components: T[] = [];\n public addComponents(...components: T[]): this {\n if (!components.length)\n throw new TypeError(\"At least one component is required.\");\n if (this.#components.length + components.length > 5)\n throw new RangeError(\n \"An action row cannot contain more than 5 components.\",\n );\n this.#components.push(...components);\n return this;\n }\n public clearComponents(): this {\n this.#components.length = 0;\n return this;\n }\n public toJSON(): APIActionRowComponent {\n return {\n type: ComponentType.ActionRow,\n components: this.#components.map((component) => component.toJSON()),\n };\n }\n}\nexport class StringSelectBuilder {\n readonly #data: APIStringSelectComponent = {\n type: ComponentType.StringSelect,\n };\n public setCustomId(value: string): this {\n validateText(value, 100, \"Component custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 150, \"Component placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinValues(value: number): this {\n validateCount(value, \"min_values\", 0);\n this.#data.min_values = value;\n return this;\n }\n public setMaxValues(value: number): this {\n validateCount(value, \"max_values\", 1);\n this.#data.max_values = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public addOptions(...options: APISelectOption[]): this {\n if (!options.length)\n throw new TypeError(\"At least one select option is required.\");\n const current = this.#data.options ?? [];\n if (current.length + options.length > 25)\n throw new RangeError(\n \"A string select cannot contain more than 25 options.\",\n );\n for (const option of options) {\n validateText(option.label, 100, \"Select option label\");\n validateText(option.value, 100, \"Select option value\");\n if (option.description)\n validateText(option.description, 100, \"Select option description\");\n }\n this.#data.options = [\n ...current,\n ...options.map((option) => ({ ...option })),\n ];\n return this;\n }\n public toJSON(): APIStringSelectComponent {\n return structuredClone(this.#data);\n }\n}\nexport class ButtonBuilder {\n readonly #data: APIButtonComponent = {\n type: ComponentType.Button,\n style: ButtonStyle.Secondary,\n };\n public setStyle(style: APIButtonComponent[\"style\"]): this {\n this.#data.style = style;\n if (style === ButtonStyle.Link) delete this.#data.custom_id;\n return this;\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Button custom ID\");\n if (this.#data.style === ButtonStyle.Link)\n throw new TypeError(\"Link buttons cannot use custom IDs.\");\n this.#data.custom_id = value;\n return this;\n }\n public setLabel(value: string): this {\n validateText(value, 80, \"Button label\");\n this.#data.label = value;\n return this;\n }\n public setURL(value: string): this {\n validateText(value, 512, \"Button URL\");\n let url: URL;\n try {\n url = new URL(value);\n } catch (error) {\n throw new TypeError(\"Button URL must be a valid URL.\", { cause: error });\n }\n this.#data.style = ButtonStyle.Link;\n delete this.#data.custom_id;\n this.#data.url = url.toString();\n return this;\n }\n public setEmoji(emoji: APIComponentEmoji | string): this {\n this.#data.emoji =\n typeof emoji === \"string\" ? { name: emoji } : { ...emoji };\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public toJSON(): APIButtonComponent {\n return structuredClone(this.#data);\n }\n}\nexport class EntitySelectBuilder {\n readonly #data: APIEntitySelectComponent;\n public constructor(\n type:\n | typeof ComponentType.UserSelect\n | typeof ComponentType.RoleSelect\n | typeof ComponentType.MentionableSelect\n | typeof ComponentType.ChannelSelect,\n ) {\n if (\n type !== ComponentType.UserSelect &&\n type !== ComponentType.RoleSelect &&\n type !== ComponentType.MentionableSelect &&\n type !== ComponentType.ChannelSelect\n )\n throw new TypeError(\"Invalid select component type.\");\n this.#data = { type };\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Component custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 150, \"Component placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinValues(value: number): this {\n validateCount(value, \"min_values\", 0);\n this.#data.min_values = value;\n return this;\n }\n public setMaxValues(value: number): this {\n validateCount(value, \"max_values\", 1);\n this.#data.max_values = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public setDefaultValues(\n ...values: { id: string; type: \"user\" | \"role\" | \"channel\" }[]\n ): this {\n (this.#data as any).default_values = values;\n return this;\n }\n public toJSON(): APIEntitySelectComponent {\n return structuredClone(this.#data);\n }\n}\nexport class ModalBuilder {\n readonly #components: Array<{ toJSON(): APIActionRowComponent }> = [];\n #custom_id?: string;\n #title?: string;\n public setCustomId(value: string): this {\n validateText(value, 100, \"Modal custom ID\");\n this.#custom_id = value;\n return this;\n }\n public setTitle(value: string): this {\n validateText(value, 45, \"Modal title\");\n this.#title = value;\n return this;\n }\n public addComponents(\n ...components: Array<{ toJSON(): APIActionRowComponent }>\n ): this {\n if (!components.length)\n throw new TypeError(\"At least one modal component is required.\");\n if (this.#components.length + components.length > 5)\n throw new RangeError(\"A modal cannot contain more than 5 action rows.\");\n this.#components.push(...components);\n return this;\n }\n public toJSON(): APIModalComponent {\n return {\n type: 9,\n ...(this.#custom_id ? { custom_id: this.#custom_id } : {}),\n ...(this.#title ? { title: this.#title } : {}),\n components: this.#components.map((component) => component.toJSON()),\n };\n }\n}\nexport class TextInputBuilder {\n readonly #data: APITextInputComponent = {\n type: ComponentType.TextInput,\n style: TextInputStyle.Short,\n };\n public setStyle(style: APITextInputComponent[\"style\"]): this {\n this.#data.style = style;\n return this;\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Text input custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setLabel(value: string): this {\n validateText(value, 45, \"Text input label\");\n this.#data.label = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 100, \"Text input placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinLength(value: number): this {\n validateLength(value, \"min_length\", 4000);\n this.#data.min_length = value;\n return this;\n }\n public setMaxLength(value: number): this {\n validateLength(value, \"max_length\", 4000);\n this.#data.max_length = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setValue(value: string): this {\n validateText(value, 4000, \"Text input value\");\n this.#data.value = value;\n return this;\n }\n public toJSON(): APITextInputComponent {\n return structuredClone(this.#data);\n }\n}\nfunction validateText(value: string, max: number, field: string): void {\n if (typeof value !== \"string\")\n throw new TypeError(`${field} must be a string.`);\n if (!value.trim())\n throw new RangeError(`${field} must be a non-empty string.`);\n if (value.length > max)\n throw new RangeError(`${field} cannot exceed ${max} characters.`);\n}\nfunction validateCount(\n value: number,\n field: string,\n min: number,\n max = 25,\n): void {\n if (!Number.isInteger(value) || value < min || value > max)\n throw new RangeError(\n `${field} must be an integer between ${min} and ${max}.`,\n );\n}\nfunction validateLength(value: number, field: string, max = 4000): void {\n if (!Number.isInteger(value) || value < 0 || value > max)\n throw new RangeError(`${field} must be an integer between 0 and ${max}.`);\n}\n",
|
|
7
|
+
"/** Discord application command option types. */\nexport const ApplicationCommandOptionType = {\n Subcommand: 1,\n SubcommandGroup: 2,\n String: 3,\n Integer: 4,\n Boolean: 5,\n User: 6,\n Channel: 7,\n Role: 8,\n Mentionable: 9,\n Number: 10,\n Attachment: 11,\n} as const;\n\n/** Builds Discord application command payloads. */\nexport class SlashCommandBuilder {\n readonly #data: Record<string, unknown> = { type: 1 };\n /** Sets the command name. */ public setName(name: string): this {\n validateName(name, \"Command name\");\n this.#data.name = name;\n return this;\n }\n /** Sets the command description. */ public setDescription(\n description: string,\n ): this {\n validateText(description, \"Command description\", 100);\n this.#data.description = description;\n return this;\n }\n /** Sets whether the command is available in direct messages. */ public setDMPermission(\n enabled: boolean,\n ): this {\n this.#data.dm_permission = enabled;\n return this;\n }\n /** Sets whether the command is NSFW. */\n public setNSFW(nsfw = true): this {\n this.#data.nsfw = nsfw;\n return this;\n }\n /** Sets whether the command is NSFW. */\n public setNsfw(nsfw = true): this {\n return this.setNSFW(nsfw);\n }\n /** Sets command default member permissions. */ public setDefaultMemberPermissions(\n permissions: bigint | number | string | null,\n ): this {\n this.#data.default_member_permissions =\n permissions === null ? null : BigInt(permissions).toString();\n return this;\n }\n /** Sets command integration types. */ public setIntegrationTypes(\n ...types: number[]\n ): this {\n this.#data.integration_types = [...types];\n return this;\n }\n /** Adds a string option. */ public addStringOption(\n configure: (option: StringOptionBuilder) => StringOptionBuilder,\n ): this {\n return this.addOption(configure(new StringOptionBuilder()));\n }\n /** Adds an integer option. */ public addIntegerOption(\n configure: (option: IntegerOptionBuilder) => IntegerOptionBuilder,\n ): this {\n return this.addOption(configure(new IntegerOptionBuilder()));\n }\n /** Adds a number option. */ public addNumberOption(\n configure: (option: NumberOptionBuilder) => NumberOptionBuilder,\n ): this {\n return this.addOption(configure(new NumberOptionBuilder()));\n }\n /** Adds a boolean option. */ public addBooleanOption(\n configure: (option: BooleanOptionBuilder) => BooleanOptionBuilder,\n ): this {\n return this.addOption(configure(new BooleanOptionBuilder()));\n }\n /** Adds a user option. */ public addUserOption(\n configure: (option: UserOptionBuilder) => UserOptionBuilder,\n ): this {\n return this.addOption(configure(new UserOptionBuilder()));\n }\n /** Adds a channel option. */ public addChannelOption(\n configure: (option: ChannelOptionBuilder) => ChannelOptionBuilder,\n ): this {\n return this.addOption(configure(new ChannelOptionBuilder()));\n }\n /** Adds a role option. */ public addRoleOption(\n configure: (option: RoleOptionBuilder) => RoleOptionBuilder,\n ): this {\n return this.addOption(configure(new RoleOptionBuilder()));\n }\n /** Adds a mentionable option. */ public addMentionableOption(\n configure: (option: MentionableOptionBuilder) => MentionableOptionBuilder,\n ): this {\n return this.addOption(configure(new MentionableOptionBuilder()));\n }\n /** Adds an attachment option. */ public addAttachmentOption(\n configure: (option: AttachmentOptionBuilder) => AttachmentOptionBuilder,\n ): this {\n return this.addOption(configure(new AttachmentOptionBuilder()));\n }\n /** Adds a subcommand. */ public addSubcommand(\n configure: (option: SubcommandBuilder) => SubcommandBuilder,\n ): this {\n return this.addOption(configure(new SubcommandBuilder()));\n }\n /** Adds a subcommand group. */ public addSubcommandGroup(\n configure: (option: SubcommandGroupBuilder) => SubcommandGroupBuilder,\n ): this {\n return this.addOption(configure(new SubcommandGroupBuilder()));\n }\n /** Serializes the command payload. */ public toJSON(): Record<\n string,\n unknown\n > {\n return structuredClone(this.#data);\n }\n /** Adds a validated top-level command option. */ protected addOption(\n option: CommandOptionBuilder,\n ): this {\n const options = (this.#data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\n \"An application command cannot contain more than 25 options.\",\n );\n const payload = option.toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);\n if (\n payload.required === true &&\n options.some(\n (existing) => (existing as Record<string, unknown>).required !== true,\n )\n )\n throw new RangeError(\n \"Required application command options must be placed before optional options.\",\n );\n options.push(payload);\n this.#data.options = options;\n return this;\n }\n}\n\n/** Base builder for command options. */\nexport class CommandOptionBuilder {\n protected readonly data: Record<string, unknown>;\n /** Creates an option builder. */ public constructor(type: number) {\n this.data = { type };\n }\n /** Sets the option name. */ public setName(name: string): this {\n validateName(name, \"Option name\");\n this.data.name = name;\n return this;\n }\n /** Sets the option description. */ public setDescription(\n description: string,\n ): this {\n validateText(description, \"Option description\", 100);\n this.data.description = description;\n return this;\n }\n /** Makes the option required or optional. */ public setRequired(\n required = true,\n ): this {\n this.data.required = required;\n return this;\n }\n /** Sets autocomplete. */ public setAutocomplete(enabled = true): this {\n this.data.autocomplete = enabled;\n return this;\n }\n /** Serializes the option payload. */ public toJSON(): Record<\n string,\n unknown\n > {\n return structuredClone(this.data);\n }\n}\n\n/** Builds a string command option. */\nexport class StringOptionBuilder extends CommandOptionBuilder {\n /** Creates a string option. */ public constructor() {\n super(ApplicationCommandOptionType.String);\n }\n /** Adds string choices. */ public addChoices(\n ...choices: Array<{ name: string; value: string }>\n ): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n for (const choice of choices) {\n validateText(choice.name, \"Choice name\", 100);\n validateText(choice.value, \"Choice value\", 100);\n }\n this.data.choices = [\n ...current,\n ...choices.map((choice) => ({ ...choice })),\n ];\n return this;\n }\n /** Sets the minimum string length. */ public setMinLength(\n value: number,\n ): this {\n validateIntegerRange(value, 0, 6000, \"min_length\");\n this.data.min_length = value;\n return this;\n }\n /** Sets the maximum string length. */ public setMaxLength(\n value: number,\n ): this {\n validateIntegerRange(value, 1, 6000, \"max_length\");\n if (\n (this.data.min_length as number | undefined) !== undefined &&\n (this.data.min_length as number) > value\n )\n throw new RangeError(\"min_length cannot exceed max_length.\");\n this.data.max_length = value;\n return this;\n }\n}\n/** Builds an integer command option. */\nexport class IntegerOptionBuilder extends CommandOptionBuilder {\n public constructor() {\n super(ApplicationCommandOptionType.Integer);\n }\n public setMinValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"min_value\",\n true,\n );\n this.data.min_value = value;\n return this;\n }\n public setMaxValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"max_value\",\n true,\n );\n if (\n (this.data.min_value as number | undefined) !== undefined &&\n (this.data.min_value as number) > value\n )\n throw new RangeError(\"min_value cannot exceed max_value.\");\n this.data.max_value = value;\n return this;\n }\n public setAutocomplete(enabled = true): this {\n if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n this.data.autocomplete = enabled;\n return this;\n }\n public addChoices(...choices: { name: string; value: number }[]): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n this.data.choices = [...current, ...choices];\n return this;\n }\n}\n/** Builds a number command option. */\nexport class NumberOptionBuilder extends CommandOptionBuilder {\n public constructor() {\n super(ApplicationCommandOptionType.Number);\n }\n public setMinValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"min_value\",\n false,\n );\n this.data.min_value = value;\n return this;\n }\n public setMaxValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"max_value\",\n false,\n );\n if (\n (this.data.min_value as number | undefined) !== undefined &&\n (this.data.min_value as number) > value\n )\n throw new RangeError(\"min_value cannot exceed max_value.\");\n this.data.max_value = value;\n return this;\n }\n public setAutocomplete(enabled = true): this {\n if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n this.data.autocomplete = enabled;\n return this;\n }\n public addChoices(...choices: { name: string; value: number }[]): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n this.data.choices = [...current, ...choices];\n return this;\n }\n}\n/** Builds a boolean command option. */ export class BooleanOptionBuilder extends CommandOptionBuilder {\n /** Creates a boolean option. */ public constructor() {\n super(ApplicationCommandOptionType.Boolean);\n }\n}\n/** Builds a user command option. */ export class UserOptionBuilder extends CommandOptionBuilder {\n /** Creates a user option. */ public constructor() {\n super(ApplicationCommandOptionType.User);\n }\n}\n/** Builds a role command option. */ export class RoleOptionBuilder extends CommandOptionBuilder {\n /** Creates a role option. */ public constructor() {\n super(ApplicationCommandOptionType.Role);\n }\n}\n/** Builds a mentionable command option. */ export class MentionableOptionBuilder extends CommandOptionBuilder {\n /** Creates a mentionable option. */ public constructor() {\n super(ApplicationCommandOptionType.Mentionable);\n }\n}\n/** Builds an attachment command option. */ export class AttachmentOptionBuilder extends CommandOptionBuilder {\n /** Creates an attachment option. */ public constructor() {\n super(ApplicationCommandOptionType.Attachment);\n }\n}\n/** Builds a channel command option. */ export class ChannelOptionBuilder extends CommandOptionBuilder {\n /** Creates a channel option. */ public constructor() {\n super(ApplicationCommandOptionType.Channel);\n }\n /** Restricts accepted channel types. */ public addChannelTypes(\n ...types: number[]\n ): this {\n if (types.some((type) => !Number.isInteger(type) || type < 0))\n throw new RangeError(\"Channel types must be non-negative integers.\");\n this.data.channel_types = [...new Set(types)];\n return this;\n }\n}\n/** Builds a nested subcommand. */ export class SubcommandBuilder extends CommandOptionBuilder {\n /** Creates a subcommand. */ public constructor() {\n super(ApplicationCommandOptionType.Subcommand);\n }\n /** Adds a string option to this subcommand. */ public addStringOption(\n configure: (option: StringOptionBuilder) => StringOptionBuilder,\n ): this {\n return this.addChildOption(configure(new StringOptionBuilder()));\n }\n /** Adds an integer option to this subcommand. */ public addIntegerOption(\n configure: (option: IntegerOptionBuilder) => IntegerOptionBuilder,\n ): this {\n return this.addChildOption(configure(new IntegerOptionBuilder()));\n }\n /** Adds a number option to this subcommand. */ public addNumberOption(\n configure: (option: NumberOptionBuilder) => NumberOptionBuilder,\n ): this {\n return this.addChildOption(configure(new NumberOptionBuilder()));\n }\n /** Adds a boolean option to this subcommand. */ public addBooleanOption(\n configure: (option: BooleanOptionBuilder) => BooleanOptionBuilder,\n ): this {\n return this.addChildOption(configure(new BooleanOptionBuilder()));\n }\n /** Adds a user option to this subcommand. */ public addUserOption(\n configure: (option: UserOptionBuilder) => UserOptionBuilder,\n ): this {\n return this.addChildOption(configure(new UserOptionBuilder()));\n }\n /** Adds a channel option to this subcommand. */ public addChannelOption(\n configure: (option: ChannelOptionBuilder) => ChannelOptionBuilder,\n ): this {\n return this.addChildOption(configure(new ChannelOptionBuilder()));\n }\n /** Adds a role option to this subcommand. */ public addRoleOption(\n configure: (option: RoleOptionBuilder) => RoleOptionBuilder,\n ): this {\n return this.addChildOption(configure(new RoleOptionBuilder()));\n }\n /** Adds a mentionable option to this subcommand. */ public addMentionableOption(\n configure: (option: MentionableOptionBuilder) => MentionableOptionBuilder,\n ): this {\n return this.addChildOption(configure(new MentionableOptionBuilder()));\n }\n /** Adds an attachment option to this subcommand. */ public addAttachmentOption(\n configure: (option: AttachmentOptionBuilder) => AttachmentOptionBuilder,\n ): this {\n return this.addChildOption(configure(new AttachmentOptionBuilder()));\n }\n protected addChildOption(option: CommandOptionBuilder): this {\n const options = (this.data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\"A subcommand cannot contain more than 25 options.\");\n const payload = option.toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);\n if (\n payload.required === true &&\n options.some(\n (existing) => (existing as Record<string, unknown>).required !== true,\n )\n )\n throw new RangeError(\n \"Required subcommand options must be placed before optional options.\",\n );\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).type ===\n ApplicationCommandOptionType.Subcommand,\n )\n )\n throw new RangeError(\"Subcommands cannot contain nested subcommands.\");\n options.push(payload);\n this.data.options = options;\n return this;\n }\n}\n/** Builds a nested subcommand group. */ export class SubcommandGroupBuilder extends CommandOptionBuilder {\n /** Creates a subcommand group. */ public constructor() {\n super(ApplicationCommandOptionType.SubcommandGroup);\n }\n /** Adds a subcommand to this group. */ public addSubcommand(\n configure: (option: SubcommandBuilder) => SubcommandBuilder,\n ): this {\n const options = (this.data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\n \"A subcommand group cannot contain more than 25 subcommands.\",\n );\n const payload = configure(new SubcommandBuilder()).toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(\n `Duplicate subcommand name: ${String(payload.name)}.`,\n );\n if (payload.type !== ApplicationCommandOptionType.Subcommand)\n throw new TypeError(\"Subcommand group children must be subcommands.\");\n options.push(payload);\n this.data.options = options;\n return this;\n }\n}\nfunction validateName(value: string, field: string): void {\n if (!/^[\\p{L}\\p{N}_-]{1,32}$/u.test(value) || value !== value.toLowerCase())\n throw new RangeError(\n `${field} must contain 1-32 lowercase letters, numbers, underscores, or hyphens.`,\n );\n}\nfunction validateText(value: string, field: string, max: number): void {\n if (typeof value !== \"string\" || !value.trim() || value.length > max)\n throw new RangeError(`${field} must contain 1-${max} characters.`);\n}\nfunction validateIntegerRange(\n value: number,\n minimum: number,\n maximum: number,\n field: string,\n): void {\n if (!Number.isInteger(value) || value < minimum || value > maximum)\n throw new RangeError(\n `${field} must be an integer between ${minimum} and ${maximum}.`,\n );\n}\nfunction validateNumberRange(\n value: number,\n minimum: number,\n maximum: number,\n field: string,\n integerOnly = true,\n): void {\n if (\n !Number.isFinite(value) ||\n (integerOnly && !Number.isInteger(value)) ||\n value < minimum ||\n value > maximum\n )\n throw new RangeError(\n `${field} must be ${integerOnly ? \"an integer\" : \"a number\"} between ${minimum} and ${maximum}.`,\n );\n}\n",
|
|
8
|
+
"import { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nexport interface AttachmentData {\n name: string;\n description?: string;\n file: Uint8Array | ArrayBuffer | Blob | Buffer | string;\n}\n\n/** Builder for message attachments and file uploads. */\nexport class AttachmentBuilder {\n public name: string;\n public description?: string;\n public file: Uint8Array | ArrayBuffer | Blob | Buffer | string;\n\n public constructor(\n file: Uint8Array | ArrayBuffer | Blob | Buffer | string,\n data?: Partial<Omit<AttachmentData, \"file\">> | string,\n ) {\n this.file = file;\n if (typeof data === \"string\") {\n this.name = data;\n } else {\n this.name =\n data?.name ?? (typeof file === \"string\" ? basename(file) : \"file.bin\");\n this.description = data?.description;\n }\n }\n\n /** Sets the attachment filename. */\n public setName(name: string): this {\n this.name = name;\n return this;\n }\n\n /** Sets the attachment description / alt text. */\n public setDescription(description: string): this {\n this.description = description;\n return this;\n }\n\n /** Sets the file contents. */\n public setFile(\n file: Uint8Array | ArrayBuffer | Blob | Buffer | string,\n ): this {\n this.file = file;\n return this;\n }\n\n /** Resolves the attachment payload to a binary Uint8Array. */\n public async toBuffer(): Promise<Uint8Array> {\n if (typeof this.file === \"string\") {\n const buffer = await readFile(this.file);\n return new Uint8Array(buffer);\n }\n if (this.file instanceof Uint8Array) return this.file;\n if (this.file instanceof ArrayBuffer) return new Uint8Array(this.file);\n if (this.file instanceof Blob) {\n const buf = await this.file.arrayBuffer();\n return new Uint8Array(buf);\n }\n if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(this.file)) {\n return new Uint8Array(this.file);\n }\n return new Uint8Array();\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "2D9849BFEE96124664756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Cache policy for bounded resource storage. */
|
|
2
|
+
export interface CacheOptions {
|
|
3
|
+
/** Maximum number of entries retained. */
|
|
4
|
+
maxSize?: number;
|
|
5
|
+
/** Time-to-live in milliseconds. Omit to disable expiration. */
|
|
6
|
+
ttl?: number;
|
|
7
|
+
/** Sweep interval in milliseconds. */
|
|
8
|
+
sweepInterval?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Bounded cache with TTL expiration and explicit invalidation support. */
|
|
11
|
+
export declare class Cache<K, V> {
|
|
12
|
+
#private;
|
|
13
|
+
/** Creates a cache using the supplied retention policy. */
|
|
14
|
+
constructor(options?: CacheOptions);
|
|
15
|
+
/** Number of currently live entries. */
|
|
16
|
+
get size(): number;
|
|
17
|
+
/** Reads a live entry. */
|
|
18
|
+
get(key: K): V | undefined;
|
|
19
|
+
/** Returns whether a live entry exists. */
|
|
20
|
+
has(key: K): boolean;
|
|
21
|
+
/** Stores an entry and evicts the oldest entries when the bound is exceeded. */
|
|
22
|
+
set(key: K, value: V): this;
|
|
23
|
+
/** Invalidates one key. */
|
|
24
|
+
delete(key: K): boolean;
|
|
25
|
+
/** Invalidates every cached resource. */
|
|
26
|
+
clear(): void;
|
|
27
|
+
/** Invalidates every entry matching a predicate. */
|
|
28
|
+
invalidate(predicate: (value: V, key: K) => boolean): number;
|
|
29
|
+
/** Removes expired entries and returns the number removed. */
|
|
30
|
+
sweep(): number;
|
|
31
|
+
/** Stops the background sweeper and releases its timer. */
|
|
32
|
+
dispose(): void;
|
|
33
|
+
/** Returns live cached values. */
|
|
34
|
+
values(): V[];
|
|
35
|
+
/** Returns live cached entries. */
|
|
36
|
+
entries(): [K, V][];
|
|
37
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A lightweight keyed collection for Lunibee resource and application state. */
|
|
2
|
+
export declare class Collection<K, V> extends Map<K, V> {
|
|
3
|
+
/** Returns the first stored value. */
|
|
4
|
+
first(): V | undefined;
|
|
5
|
+
/** Returns the first stored key. */
|
|
6
|
+
firstKey(): K | undefined;
|
|
7
|
+
/** Returns the last stored value. */
|
|
8
|
+
last(): V | undefined;
|
|
9
|
+
/** Returns the last stored key. */
|
|
10
|
+
lastKey(): K | undefined;
|
|
11
|
+
/** Finds the first value matching a predicate. */
|
|
12
|
+
find(predicate: (value: V, key: K, collection: this) => boolean): V | undefined;
|
|
13
|
+
/** Returns all values matching a predicate. */
|
|
14
|
+
filter(predicate: (value: V, key: K, collection: this) => boolean): Collection<K, V>;
|
|
15
|
+
/** Transforms every stored value into an array. */
|
|
16
|
+
map<T>(transform: (value: V, key: K, collection: this) => T): T[];
|
|
17
|
+
/** Returns whether at least one stored value satisfies a predicate. */
|
|
18
|
+
some(predicate: (value: V, key: K, collection: this) => boolean): boolean;
|
|
19
|
+
/** Returns whether every stored value satisfies a predicate. */
|
|
20
|
+
every(predicate: (value: V, key: K, collection: this) => boolean): boolean;
|
|
21
|
+
/** Runs a callback for each stored value. */
|
|
22
|
+
each(callback: (value: V, key: K, collection: this) => unknown): this;
|
|
23
|
+
/** Returns an array containing all stored values. */
|
|
24
|
+
array(): V[];
|
|
25
|
+
/** Returns an array containing all stored keys. */
|
|
26
|
+
keyArray(): K[];
|
|
27
|
+
/** Returns a plain array of entries. */
|
|
28
|
+
entriesArray(): [K, V][];
|
|
29
|
+
/** Returns a new collection with the same entries. */
|
|
30
|
+
clone(): Collection<K, V>;
|
|
31
|
+
/** Returns whether all supplied keys are present. */
|
|
32
|
+
hasAll(...keys: K[]): boolean;
|
|
33
|
+
/** Returns whether at least one supplied key is present. */
|
|
34
|
+
hasAny(...keys: K[]): boolean;
|
|
35
|
+
/** Returns the first key whose value matches a predicate. */
|
|
36
|
+
findKey(predicate: (value: V, key: K, collection: this) => boolean): K | undefined;
|
|
37
|
+
/** Returns whether a predicate matches at least one entry. */
|
|
38
|
+
someEntry(predicate: (value: V, key: K, collection: this) => boolean): boolean;
|
|
39
|
+
/** Removes every entry matching a predicate and returns the number removed. */
|
|
40
|
+
sweep(predicate: (value: V, key: K, collection: this) => boolean): number;
|
|
41
|
+
/** Returns the collection's first matching entry as a tuple. */
|
|
42
|
+
firstEntry(): [K, V] | undefined;
|
|
43
|
+
/** Returns the collection's last matching entry as a tuple. */
|
|
44
|
+
lastEntry(): [K, V] | undefined;
|
|
45
|
+
}
|
|
46
|
+
export { Cache } from "./cache.js";
|
|
47
|
+
export type { CacheOptions } from "./cache.js";
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/collection/src/cache.ts
|
|
3
|
+
class Cache {
|
|
4
|
+
#entries = new Collection;
|
|
5
|
+
#maxSize;
|
|
6
|
+
#ttl;
|
|
7
|
+
#timer;
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.#maxSize = options.maxSize ?? Infinity;
|
|
10
|
+
this.#ttl = options.ttl ?? 0;
|
|
11
|
+
if (!Number.isInteger(this.#maxSize) && this.#maxSize !== Infinity || this.#maxSize < 1)
|
|
12
|
+
throw new RangeError("Cache maxSize must be a positive integer.");
|
|
13
|
+
if (!Number.isFinite(this.#ttl) || this.#ttl < 0)
|
|
14
|
+
throw new RangeError("Cache ttl must be a non-negative finite number.");
|
|
15
|
+
if (this.#ttl > 0) {
|
|
16
|
+
const interval = options.sweepInterval ?? Math.min(this.#ttl, 60000);
|
|
17
|
+
if (!Number.isFinite(interval) || interval < 1)
|
|
18
|
+
throw new RangeError("Cache sweepInterval must be positive.");
|
|
19
|
+
this.#timer = setInterval(() => this.sweep(), interval);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
get size() {
|
|
23
|
+
this.#sweepExpired();
|
|
24
|
+
return this.#entries.size;
|
|
25
|
+
}
|
|
26
|
+
get(key) {
|
|
27
|
+
const entry = this.#entries.get(key);
|
|
28
|
+
if (!entry)
|
|
29
|
+
return;
|
|
30
|
+
if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {
|
|
31
|
+
this.#entries.delete(key);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
return entry.value;
|
|
35
|
+
}
|
|
36
|
+
has(key) {
|
|
37
|
+
return this.get(key) !== undefined;
|
|
38
|
+
}
|
|
39
|
+
set(key, value) {
|
|
40
|
+
const expiresAt = this.#ttl > 0 ? Date.now() + this.#ttl : 0;
|
|
41
|
+
this.#entries.delete(key);
|
|
42
|
+
this.#entries.set(key, { value, expiresAt });
|
|
43
|
+
while (this.#entries.size > this.#maxSize) {
|
|
44
|
+
const oldest = this.#entries.firstKey();
|
|
45
|
+
if (oldest !== undefined)
|
|
46
|
+
this.#entries.delete(oldest);
|
|
47
|
+
}
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
delete(key) {
|
|
51
|
+
return this.#entries.delete(key);
|
|
52
|
+
}
|
|
53
|
+
clear() {
|
|
54
|
+
this.#entries.clear();
|
|
55
|
+
}
|
|
56
|
+
invalidate(predicate) {
|
|
57
|
+
return this.#entries.sweep((entry, key) => predicate(entry.value, key));
|
|
58
|
+
}
|
|
59
|
+
sweep() {
|
|
60
|
+
return this.#entries.sweep((entry) => this.#expired(entry));
|
|
61
|
+
}
|
|
62
|
+
dispose() {
|
|
63
|
+
if (this.#timer)
|
|
64
|
+
clearInterval(this.#timer);
|
|
65
|
+
this.#timer = undefined;
|
|
66
|
+
}
|
|
67
|
+
values() {
|
|
68
|
+
this.#sweepExpired();
|
|
69
|
+
return this.#entries.map((entry) => entry.value);
|
|
70
|
+
}
|
|
71
|
+
entries() {
|
|
72
|
+
this.#sweepExpired();
|
|
73
|
+
return this.#entries.map((entry, key) => [key, entry.value]);
|
|
74
|
+
}
|
|
75
|
+
#expired(entry) {
|
|
76
|
+
return entry.expiresAt > 0 && entry.expiresAt <= Date.now();
|
|
77
|
+
}
|
|
78
|
+
#sweepExpired() {
|
|
79
|
+
if (this.#ttl > 0)
|
|
80
|
+
this.sweep();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// packages/collection/src/index.ts
|
|
85
|
+
class Collection extends Map {
|
|
86
|
+
first() {
|
|
87
|
+
for (const value of this.values())
|
|
88
|
+
return value;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
firstKey() {
|
|
92
|
+
for (const key of this.keys())
|
|
93
|
+
return key;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
last() {
|
|
97
|
+
let value;
|
|
98
|
+
for (const item of this.values())
|
|
99
|
+
value = item;
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
lastKey() {
|
|
103
|
+
let key;
|
|
104
|
+
for (const item of this.keys())
|
|
105
|
+
key = item;
|
|
106
|
+
return key;
|
|
107
|
+
}
|
|
108
|
+
find(predicate) {
|
|
109
|
+
for (const [key, value] of this) {
|
|
110
|
+
if (predicate(value, key, this))
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
filter(predicate) {
|
|
116
|
+
const result = new Collection;
|
|
117
|
+
for (const [key, value] of this) {
|
|
118
|
+
if (predicate(value, key, this))
|
|
119
|
+
result.set(key, value);
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
map(transform) {
|
|
124
|
+
const result = [];
|
|
125
|
+
for (const [key, value] of this) {
|
|
126
|
+
result.push(transform(value, key, this));
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
some(predicate) {
|
|
131
|
+
for (const [key, value] of this) {
|
|
132
|
+
if (predicate(value, key, this))
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
every(predicate) {
|
|
138
|
+
for (const [key, value] of this) {
|
|
139
|
+
if (!predicate(value, key, this))
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
each(callback) {
|
|
145
|
+
for (const [key, value] of this) {
|
|
146
|
+
callback(value, key, this);
|
|
147
|
+
}
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
array() {
|
|
151
|
+
return [...this.values()];
|
|
152
|
+
}
|
|
153
|
+
keyArray() {
|
|
154
|
+
return [...this.keys()];
|
|
155
|
+
}
|
|
156
|
+
entriesArray() {
|
|
157
|
+
return [...this.entries()];
|
|
158
|
+
}
|
|
159
|
+
clone() {
|
|
160
|
+
const copy = new Collection;
|
|
161
|
+
for (const [key, value] of this)
|
|
162
|
+
copy.set(key, value);
|
|
163
|
+
return copy;
|
|
164
|
+
}
|
|
165
|
+
hasAll(...keys) {
|
|
166
|
+
for (let i = 0;i < keys.length; i++) {
|
|
167
|
+
if (!this.has(keys[i]))
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
hasAny(...keys) {
|
|
173
|
+
for (let i = 0;i < keys.length; i++) {
|
|
174
|
+
if (this.has(keys[i]))
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
findKey(predicate) {
|
|
180
|
+
for (const [key, value] of this) {
|
|
181
|
+
if (predicate(value, key, this))
|
|
182
|
+
return key;
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
someEntry(predicate) {
|
|
187
|
+
return this.some(predicate);
|
|
188
|
+
}
|
|
189
|
+
sweep(predicate) {
|
|
190
|
+
let removed = 0;
|
|
191
|
+
for (const [key, value] of this) {
|
|
192
|
+
if (predicate(value, key, this) && this.delete(key))
|
|
193
|
+
removed++;
|
|
194
|
+
}
|
|
195
|
+
return removed;
|
|
196
|
+
}
|
|
197
|
+
firstEntry() {
|
|
198
|
+
for (const [key, value] of this)
|
|
199
|
+
return [key, value];
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
lastEntry() {
|
|
203
|
+
let entry;
|
|
204
|
+
for (const item of this)
|
|
205
|
+
entry = [item[0], item[1]];
|
|
206
|
+
return entry;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
export {
|
|
210
|
+
Cache,
|
|
211
|
+
Collection
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
//# debugId=826D66A990E1FAF264756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/collection/src/cache.ts", "../../packages/collection/src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Collection } from \"./index.js\";\r\n\r\n/** Cache policy for bounded resource storage. */\r\nexport interface CacheOptions {\r\n /** Maximum number of entries retained. */\r\n maxSize?: number;\r\n /** Time-to-live in milliseconds. Omit to disable expiration. */\r\n ttl?: number;\r\n /** Sweep interval in milliseconds. */\r\n sweepInterval?: number;\r\n}\r\n\r\ntype Entry<V> = { value: V; expiresAt: number };\r\n\r\n/** Bounded cache with TTL expiration and explicit invalidation support. */\r\nexport class Cache<K, V> {\r\n readonly #entries = new Collection<K, Entry<V>>();\r\n readonly #maxSize: number;\r\n readonly #ttl: number;\r\n #timer?: ReturnType<typeof setInterval>;\r\n\r\n /** Creates a cache using the supplied retention policy. */\r\n public constructor(options: CacheOptions = {}) {\r\n this.#maxSize = options.maxSize ?? Infinity;\r\n this.#ttl = options.ttl ?? 0;\r\n if (\r\n (!Number.isInteger(this.#maxSize) && this.#maxSize !== Infinity) ||\r\n this.#maxSize < 1\r\n )\r\n throw new RangeError(\"Cache maxSize must be a positive integer.\");\r\n if (!Number.isFinite(this.#ttl) || this.#ttl < 0)\r\n throw new RangeError(\"Cache ttl must be a non-negative finite number.\");\r\n if (this.#ttl > 0) {\r\n const interval = options.sweepInterval ?? Math.min(this.#ttl, 60_000);\r\n if (!Number.isFinite(interval) || interval < 1)\r\n throw new RangeError(\"Cache sweepInterval must be positive.\");\r\n this.#timer = setInterval(() => this.sweep(), interval);\r\n }\r\n }\r\n\r\n /** Number of currently live entries. */\r\n public get size(): number {\r\n this.#sweepExpired();\r\n return this.#entries.size;\r\n }\r\n /** Reads a live entry. */\r\n public get(key: K): V | undefined {\r\n const entry = this.#entries.get(key);\r\n if (!entry) return undefined;\r\n if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {\r\n this.#entries.delete(key);\r\n return undefined;\r\n }\r\n return entry.value;\r\n }\r\n /** Returns whether a live entry exists. */\r\n public has(key: K): boolean {\r\n return this.get(key) !== undefined;\r\n }\r\n /** Stores an entry and evicts the oldest entries when the bound is exceeded. */\r\n public set(key: K, value: V): this {\r\n const expiresAt = this.#ttl > 0 ? Date.now() + this.#ttl : 0;\r\n this.#entries.delete(key);\r\n this.#entries.set(key, { value, expiresAt });\r\n while (this.#entries.size > this.#maxSize) {\r\n const oldest = this.#entries.firstKey();\r\n if (oldest !== undefined) this.#entries.delete(oldest);\r\n }\r\n return this;\r\n }\r\n /** Invalidates one key. */\r\n public delete(key: K): boolean {\r\n return this.#entries.delete(key);\r\n }\r\n /** Invalidates every cached resource. */\r\n public clear(): void {\r\n this.#entries.clear();\r\n }\r\n /** Invalidates every entry matching a predicate. */\r\n public invalidate(predicate: (value: V, key: K) => boolean): number {\r\n return this.#entries.sweep((entry, key) => predicate(entry.value, key));\r\n }\r\n /** Removes expired entries and returns the number removed. */\r\n public sweep(): number {\r\n return this.#entries.sweep((entry) => this.#expired(entry));\r\n }\r\n /** Stops the background sweeper and releases its timer. */\r\n public dispose(): void {\r\n if (this.#timer) clearInterval(this.#timer);\r\n this.#timer = undefined;\r\n }\r\n /** Returns live cached values. */\r\n public values(): V[] {\r\n this.#sweepExpired();\r\n return this.#entries.map((entry) => entry.value);\r\n }\r\n /** Returns live cached entries. */\r\n public entries(): [K, V][] {\r\n this.#sweepExpired();\r\n return this.#entries.map((entry, key) => [key, entry.value]);\r\n }\r\n #expired(entry: Entry<V>): boolean {\r\n return entry.expiresAt > 0 && entry.expiresAt <= Date.now();\r\n }\r\n #sweepExpired(): void {\r\n if (this.#ttl > 0) this.sweep();\r\n }\r\n}\r\n",
|
|
6
|
+
"/** A lightweight keyed collection for Lunibee resource and application state. */\r\nexport class Collection<K, V> extends Map<K, V> {\r\n /** Returns the first stored value. */\r\n public first(): V | undefined {\r\n for (const value of this.values()) return value;\r\n return undefined;\r\n }\r\n /** Returns the first stored key. */\r\n public firstKey(): K | undefined {\r\n for (const key of this.keys()) return key;\r\n return undefined;\r\n }\r\n /** Returns the last stored value. */\r\n public last(): V | undefined {\r\n let value: V | undefined;\r\n for (const item of this.values()) value = item;\r\n return value;\r\n }\r\n /** Returns the last stored key. */\r\n public lastKey(): K | undefined {\r\n let key: K | undefined;\r\n for (const item of this.keys()) key = item;\r\n return key;\r\n }\r\n /** Finds the first value matching a predicate. */\r\n public find(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return value;\r\n }\r\n return undefined;\r\n }\r\n /** Returns all values matching a predicate. */\r\n public filter(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Transforms every stored value into an array. */\r\n public map<T>(transform: (value: V, key: K, collection: this) => T): T[] {\r\n const result: T[] = [];\r\n for (const [key, value] of this) {\r\n result.push(transform(value, key, this));\r\n }\r\n return result;\r\n }\r\n /** Returns whether at least one stored value satisfies a predicate. */\r\n public some(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns whether every stored value satisfies a predicate. */\r\n public every(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (!predicate(value, key, this)) return false;\r\n }\r\n return true;\r\n }\r\n /** Runs a callback for each stored value. */\r\n public each(callback: (value: V, key: K, collection: this) => unknown): this {\r\n for (const [key, value] of this) {\r\n callback(value, key, this);\r\n }\r\n return this;\r\n }\r\n /** Returns an array containing all stored values. */\r\n public array(): V[] {\r\n return [...this.values()];\r\n }\r\n /** Returns an array containing all stored keys. */\r\n public keyArray(): K[] {\r\n return [...this.keys()];\r\n }\r\n /** Returns a plain array of entries. */\r\n public entriesArray(): [K, V][] {\r\n return [...this.entries()];\r\n }\r\n /** Returns a new collection with the same entries. */\r\n public clone(): Collection<K, V> {\r\n const copy = new Collection<K, V>();\r\n for (const [key, value] of this) copy.set(key, value);\r\n return copy;\r\n }\r\n /** Returns whether all supplied keys are present. */\r\n public hasAll(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (!this.has(keys[i]!)) return false;\r\n }\r\n return true;\r\n }\r\n /** Returns whether at least one supplied key is present. */\r\n public hasAny(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (this.has(keys[i]!)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns the first key whose value matches a predicate. */\r\n public findKey(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): K | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return key;\r\n }\r\n return undefined;\r\n }\r\n /** Returns whether a predicate matches at least one entry. */\r\n public someEntry(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n return this.some(predicate);\r\n }\r\n /** Removes every entry matching a predicate and returns the number removed. */\r\n public sweep(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): number {\r\n let removed = 0;\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this) && this.delete(key)) removed++;\r\n }\r\n return removed;\r\n }\r\n /** Returns the collection's first matching entry as a tuple. */\r\n public firstEntry(): [K, V] | undefined {\r\n for (const [key, value] of this) return [key, value];\r\n return undefined;\r\n }\r\n /** Returns the collection's last matching entry as a tuple. */\r\n public lastEntry(): [K, V] | undefined {\r\n let entry: [K, V] | undefined;\r\n for (const item of this) entry = [item[0], item[1]];\r\n return entry;\r\n }\r\n}\r\n\r\nexport { Cache } from \"./cache.js\";\r\nexport type { CacheOptions } from \"./cache.js\";\r\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "826D66A990E1FAF264756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Lifecycle states exposed by the Lunibee client. */
|
|
2
|
+
export type ClientStatus = "idle" | "connecting" | "ready" | "disconnecting" | "disconnected";
|
|
3
|
+
/** Tracks client lifecycle state without coupling it to a transport implementation. */
|
|
4
|
+
export declare class ClientState {
|
|
5
|
+
#private;
|
|
6
|
+
/** Current lifecycle status. */
|
|
7
|
+
get status(): ClientStatus;
|
|
8
|
+
/** Updates the lifecycle status. */
|
|
9
|
+
set status(value: ClientStatus);
|
|
10
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
export interface CollectorOptions<T> {
|
|
3
|
+
/** Filter predicate to accept or reject items. */
|
|
4
|
+
filter?: (item: T) => boolean | Promise<boolean>;
|
|
5
|
+
/** Lifetime of the collector in milliseconds. */
|
|
6
|
+
time?: number;
|
|
7
|
+
/** Maximum number of elements to collect. */
|
|
8
|
+
max?: number;
|
|
9
|
+
/** Maximum number of processed elements. */
|
|
10
|
+
maxProcessed?: number;
|
|
11
|
+
}
|
|
12
|
+
/** General-purpose event collector for interactions and messages. */
|
|
13
|
+
export declare class Collector<K, V> extends EventEmitter {
|
|
14
|
+
#private;
|
|
15
|
+
readonly collected: Map<K, V>;
|
|
16
|
+
readonly options: CollectorOptions<V>;
|
|
17
|
+
ended: boolean;
|
|
18
|
+
endReason?: string;
|
|
19
|
+
totalProcessed: number;
|
|
20
|
+
constructor(options?: CollectorOptions<V>);
|
|
21
|
+
/** Handles a candidate item for collection. */
|
|
22
|
+
handle(key: K, item: V): Promise<boolean>;
|
|
23
|
+
/** Stops the collector and emits the "end" event. */
|
|
24
|
+
stop(reason?: string): void;
|
|
25
|
+
/** Returns a Promise that resolves with the next collected item or rejects on end/timeout. */
|
|
26
|
+
next(): Promise<V>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ClientEvents } from "./index.js";
|
|
2
|
+
/** Names of events emitted by a Lunibee client. */
|
|
3
|
+
export type ClientEvent = keyof ClientEvents;
|
|
4
|
+
/** Listener signature for a Lunibee client event. */
|
|
5
|
+
export type ClientListener<K extends ClientEvent> = (...args: ClientEvents[K]) => unknown;
|