Remove benchmarks page & package (#4479)

* Remove benchmarks package and page

* Remove benchmarks CI
This commit is contained in:
Fleny
2025-10-02 21:30:06 +02:00
committed by GitHub
parent f61e8c0477
commit 2545bff5a6
20 changed files with 0 additions and 1746 deletions

View File

@@ -1,107 +0,0 @@
name: Benchmark
permissions:
contents: write
deployments: write
actions: write
on:
workflow_call:
inputs:
sha:
required: true
type: string
repo:
required: true
type: string
outputs:
cpuMatch:
value: ${{ jobs.benchmark.outputs.cpuMatch }}
jobs:
benchmark:
name: Benchmark
runs-on: ubuntu-latest
outputs:
cpuMatch: ${{ steps.cpuCheck.outputs.match }}
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 20
- name: Check cpu model
id: cpuCheck
run: node ./scripts/checkCpuModel.js
- name: Get yarn cache directory path
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- run: yarn install --immutable
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
- name: Build
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
run: yarn build
#
- name: Download db from benchmark repo
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
run: wget https://github.com/discordeno/benchmarks/raw/main/db.tar.gz
- name: Decompress db
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
run: tar -xzvf db.tar.gz
- name: Benchmark
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
run: node --expose-gc ./packages/benchmarks/dist/index.js | tee output.txt
- name: Download previous benchmark data
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
uses: actions/cache@v4
with:
path: ./benchmarksResult
key: ${{ github.ref }}-benchmark-${{ github.sha }}
restore-keys: |
${{ github.ref }}-benchmark-
- name: Store benchmark result to cache
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'benchmarkjs'
output-file-path: output.txt
external-data-json-path: benchmarksResult/data.json
- uses: actions/upload-artifact@v4
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
with:
name: benchmarkResults
path: benchmarksResult/data.json
- name: Save Commmit SHA
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
run: |
mkdir -p ./commitData
echo ${{ inputs.sha }} > ./commitData/sha
echo ${{ inputs.repo }} > ./commitData/repo
- uses: actions/upload-artifact@v4
if: ${{ steps.cpuCheck.outputs.match == 'true' }}
with:
name: commitData
path: commitData/
- name: remove changes
run: git reset --hard HEAD
- name: Store benchmark result (Main)
uses: benchmark-action/github-action-benchmark@v1
if: ${{ github.ref == 'refs/heads/main' && steps.cpuCheck.outputs.match == 'true' }}
with:
tool: 'benchmarkjs'
output-file-path: output.txt
gh-pages-branch: 'benchies'
benchmark-data-dir-path: benchmarksResult
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true

View File

@@ -1,114 +0,0 @@
name: Comment Benchmark Result
permissions:
contents: read
actions: read
pull-requests: write
on:
workflow_run:
workflows: [Benchmark with retry]
types:
- completed
jobs:
comment-benchmark-result:
name: Comment Benchmark Result
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v5
- uses: denoland/setup-deno@main
with:
deno-version: v1.x
- name: Download Commit Data Artifact
uses: actions/github-script@v8
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "commitData"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/commitData.zip`, Buffer.from(download.data));
- name: Unzip Commit Data Artifact
run: unzip commitData.zip
- name: Download Result Artifact
uses: actions/github-script@v8
with:
script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
});
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name == "benchmarkResults"
})[0];
let download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
let fs = require('fs');
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/benchmarkResults.zip`, Buffer.from(download.data));
- name: Unzip Result Artifact
run: unzip benchmarkResults.zip
- name: Generate Message
id: genMessage
run: |
MESSAGE=$(deno run -A scripts/generateMessage.js)
echo "MESSAGE<<EOF" >> $GITHUB_ENV
echo "$MESSAGE" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: 'Comment on PR'
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const commit_sha = fs.readFileSync('./sha', 'utf-8');
const repo = fs.readFileSync('./repo', 'utf-8');
if (repo.split('/')[1] === undefined) process.exit(0)
const pr = await github.rest.repos.listPullRequestsAssociatedWithCommit({
commit_sha: commit_sha.slice(0,-1),
owner: repo.split('/')[0],
repo: repo.split('/')[1].slice(0,-1),
});
if (pr.data[0]) {
const comments = await github.rest.issues.listComments({
owner: "discordeno",
repo: "discordeno",
issue_number: pr.data[0].number,
})
const oldComment = comments.data.find((comment) => comment.body.includes('benchmark comment by ci'))
if(!oldComment) {
github.rest.issues.createComment({
issue_number: pr.data[0].number,
owner: "discordeno",
repo: "discordeno",
body: `${{ env.MESSAGE }}`
})
} else {
github.rest.issues.updateComment({
owner: "discordeno",
repo: "discordeno",
comment_id: oldComment.id,
body: `${{ env.MESSAGE }}`
});
}
}

View File

@@ -1,91 +0,0 @@
name: Benchmark with retry
permissions:
contents: read
on:
pull_request:
paths-ignore:
- 'website/**'
push:
branches:
- main
paths-ignore:
- 'website/**'
jobs:
benchmark-try-1:
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-2:
needs: benchmark-try-1
if: ${{ needs.benchmark-try-1.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-3:
needs: benchmark-try-2
if: ${{ needs.benchmark-try-2.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-4:
needs: benchmark-try-3
if: ${{ needs.benchmark-try-3.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-5:
needs: benchmark-try-4
if: ${{ needs.benchmark-try-4.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-6:
needs: benchmark-try-5
if: ${{ needs.benchmark-try-5.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-7:
needs: benchmark-try-6
if: ${{ needs.benchmark-try-6.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-8:
needs: benchmark-try-7
if: ${{ needs.benchmark-try-7.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-9:
needs: benchmark-try-8
if: ${{ needs.benchmark-try-8.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}
benchmark-try-10:
needs: benchmark-try-9
if: ${{ needs.benchmark-try-9.outputs.cpuMatch == 'false' }}
uses: ./.github/workflows/benchmark.yml
with:
sha: ${{ github.event.pull_request.head.sha }}
repo: ${{ github.event.pull_request.head.repo.full_name }}

View File

@@ -1,25 +0,0 @@
{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2022",
"keepClassNames": true,
"loose": true
},
"module": {
"type": "es6",
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
},
"sourceMaps": "inline"
}

View File

@@ -1,38 +0,0 @@
{
"name": "benchmarks",
"version": "0.0.0",
"private": true,
"exports": "./dist/index.js",
"type": "module",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/discordeno/discordeno.git"
},
"scripts": {
"build": "swc src --strip-leading-paths --out-dir dist",
"build:type": "tsc --declaration --emitDeclarationOnly --declarationDir dist",
"release-build": "yarn build && yarn build:type",
"check": "biome check --write",
"build-message": "swc src/generateMessage.ts --strip-leading-paths -C sourceMaps=false --out-dir ../../scripts",
"bench": "node dist/index.js"
},
"dependencies": {
"@discordeno/bot": "workspace:^",
"@discordeno/gateway": "workspace:^",
"@discordeno/rest": "workspace:^",
"@discordeno/types": "workspace:^",
"@discordeno/utils": "workspace:^",
"benchmark": "^2.1.4"
},
"devDependencies": {
"@biomejs/biome": "2.2.4",
"@swc/cli": "^0.7.8",
"@swc/core": "^1.13.5",
"@types/benchmark": "^2.1.5",
"@types/node": "^24.6.1",
"ts-node": "^10.9.2",
"tsconfig": "*",
"typescript": "^5.9.2"
}
}

View File

@@ -1,3 +0,0 @@
import Benchmark from 'benchmark'
export const suite = new Benchmark.Suite()

View File

@@ -1,17 +0,0 @@
import { camelize, snakelize } from '@discordeno/utils'
import { suite } from '../benchmarkSuite.js'
import { events } from '../utils/db.js'
const camelizedEvents: any[] = []
events.forEach((event) => {
camelizedEvents.push(camelize(event))
})
suite.add(`Camelize 1 event`, () => {
camelize(events[1])
})
suite.add(`Snakelize 1 event`, () => {
snakelize(camelizedEvents[1])
})

View File

@@ -1,19 +0,0 @@
import { createBot, snakeToCamelCase } from '@discordeno/bot'
import { events as dbEvents } from '../utils/db.js'
import { memoryBenchmark } from '../utils/memoryBenchmark.js'
await memoryBenchmark(
'[Cache Plugin]',
() =>
createBot({
token: ' ',
applicationId: 1n,
events: {},
desiredProperties: {},
}),
(bot, event) => {
const eventName = snakeToCamelCase(event.payload.t!)
bot.events[eventName as keyof typeof bot.events]?.(event.payload.d as never, {} as never)
},
dbEvents.filter((event) => event.payload.t),
)

View File

@@ -1,19 +0,0 @@
import { createRestManager } from '@discordeno/rest'
import { suite } from '../benchmarkSuite.js'
const rest = createRestManager({ token: '1', applicationId: 1n })
suite.add(`rest.simplifyUrl`, () => {
rest.simplifyUrl('/messages/555555555555555555', 'PUT')
rest.simplifyUrl('/users/555555555555555555', 'PUT')
rest.simplifyUrl('/webhooks/555555555555555555', 'PUT')
rest.simplifyUrl('/channel/555555555555555555', 'PUT')
rest.simplifyUrl('/guild/555555555555555555', 'PUT')
rest.simplifyUrl('/channels/555555555555555555', 'PUT')
rest.simplifyUrl('/guilds/555555555555555555', 'PUT')
rest.simplifyUrl('/channels/555555555555555555/reactions/555555555555555555/wdiubaibfwuabfobaowbfoibnion', 'PUT')
rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'DELETE')
rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'POST')
rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'GET')
rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'PUT')
})

View File

@@ -1,774 +0,0 @@
import {
ApplicationFlags,
type Bot,
ButtonStyles,
createBot,
type DiscordMessage,
InteractionTypes,
iconHashToBigInt,
MemberToggles,
MessageActivityTypes,
MessageComponentTypes,
MessageTypes,
PremiumTypes,
StickerFormatTypes,
TeamMembershipStates,
TextStyles,
UserFlags,
} from '@discordeno/bot'
import { memoryBenchmark } from '../utils/memoryBenchmark.js'
export const CHANNEL_MENTION_REGEX = /<#[0-9]+>/g
const MESSAGE_SIZE = 20000
const bot = createBot({
token: process.env.DISCORD_TOKEN ?? ' ',
applicationId: 1n,
events: {},
desiredProperties: {
message: {
activity: true,
application: true,
applicationId: true,
attachments: true,
author: true,
channelId: true,
components: true,
content: true,
editedTimestamp: true,
embeds: true,
guildId: true,
id: true,
member: true,
mentionedChannelIds: true,
mentionedRoleIds: true,
mentions: true,
nonce: true,
reactions: true,
stickerItems: true,
thread: true,
type: true,
webhookId: true,
},
messageInteraction: {
id: true,
member: true,
name: true,
user: true,
type: true,
},
messageReference: {
channelId: true,
guildId: true,
messageId: true,
},
},
})
const URL = 'https://discordeno.js.org/'
const IMAGE_HASH = '5fff867ae5f666fcd0626bd84f5e69c0'
const GUILD_ID = '785384884197392384'
const USER = {
accent_color: 0,
avatar: IMAGE_HASH,
banner: IMAGE_HASH,
bot: true,
discriminator: '1234',
email: 'discordeno@discordeno.com',
flags: UserFlags.BotHttpInteractions,
id: GUILD_ID,
locale: 'en',
mfa_enabled: true,
premium_type: PremiumTypes.Nitro,
public_flags: UserFlags.BotHttpInteractions,
system: true,
username: 'skillz',
verified: true,
}
const MEMBER = {
nick: 'John',
roles: ['111111111111111111', '222222222222222222', '333333333333333333'],
joined_at: '2022-01-01T00:00:00.000Z',
premium_since: '2022-02-01T00:00:00.000Z',
deaf: false,
mute: true,
pending: false,
permissions: '2147483647',
}
console.log('before the bench')
await memoryBenchmark(
'[transformer] message cache check',
() => ({
cache: [] as any[],
}), // function returns a new instance of object wanted to test with
(object, event: DiscordMessage) => object.cache.push(bot.transformers.message(bot, event)),
// function specify how to add event to the object/ run the object
[...new Array(MESSAGE_SIZE)].map(
() =>
({
activity: {
party_id: 'party_id',
type: MessageActivityTypes.Join,
},
application: {
bot_public: true,
bot_require_code_grant: true,
cover_image: IMAGE_HASH,
custom_install_url: 'https://google.com',
description: 'discordeno is the best lib ever',
flags: ApplicationFlags.GatewayGuildMembers,
guild_id: GUILD_ID,
icon: IMAGE_HASH,
id: GUILD_ID,
install_params: {
permissions: '8',
scopes: ['identify'],
},
name: 'skillz',
owner: USER,
primary_sku_id: GUILD_ID,
privacy_policy_url: 'https://discordeno.js.org',
role_connections_verification_url: 'https://discordeno.js.org',
rpc_origins: [],
slug: 'discordeno',
tags: ['discordeno', 'discordeno', 'discordeno', 'discordeno', 'discordeno'],
team: {
icon: IMAGE_HASH,
id: GUILD_ID,
members: [
{
membership_state: TeamMembershipStates.Accepted,
permissions: ['*'],
team_id: GUILD_ID,
user: USER,
},
{
membership_state: TeamMembershipStates.Accepted,
permissions: ['*'],
team_id: GUILD_ID,
user: USER,
},
],
name: 'discordeno',
owner_user_id: GUILD_ID,
},
terms_of_service_url: 'https://discordeno.js.org',
verify_key: IMAGE_HASH,
},
application_id: GUILD_ID,
attachments: [
{
content_type: 'application/json',
description: 'discordeno discordeno discordeno',
ephemeral: true,
filename: 'discordeno',
height: 100,
id: GUILD_ID,
proxy_url: 'https://discordeno.js.org',
size: 100,
url: 'https://discordeno.js.org',
width: 100,
},
{
content_type: 'application/json',
description: 'discordeno discordeno discordeno',
ephemeral: true,
filename: 'discordeno',
height: 100,
id: GUILD_ID,
proxy_url: 'https://discordeno.js.org',
size: 100,
url: 'https://discordeno.js.org',
width: 100,
},
],
author: USER,
channel_id: GUILD_ID,
components: [
{
type: 1,
components: [
{
custom_id: GUILD_ID,
disabled: true,
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
label: 'discordeno',
style: ButtonStyles.Danger,
type: MessageComponentTypes.Button,
url: 'https://discordeno.js.org',
},
],
},
{
type: 1,
components: [
{
type: MessageComponentTypes.TextInput,
custom_id: 'discordeno',
label: 'discordeno',
max_length: 100,
min_length: 100,
placeholder: 'discordeno',
required: true,
style: TextStyles.Paragraph,
value: 'discordeno',
},
],
},
{
type: 1,
components: [
{
type: MessageComponentTypes.StringSelect,
custom_id: 'discordeno',
max_values: 100,
min_values: 100,
options: [
{
default: true,
description: 'idk idk idk',
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
label: 'discordeno',
value: 'discordeno',
},
],
placeholder: 'discordeno',
},
],
},
],
content: 'discordeno',
edited_timestamp: new Date().toISOString(),
embeds: [
{
author: {
icon_url: URL,
name: 'discordeno',
proxy_icon_url: URL,
url: URL,
},
color: 0,
description: 'discordeno',
fields: [
{
name: 'discordeno',
value: 'discordeno',
inline: true,
},
{
name: 'discordeno',
value: 'discordeno',
inline: true,
},
],
footer: {
icon_url: URL,
proxy_icon_url: URL,
text: 'discordeno',
},
image: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
provider: {
name: 'discordeno',
url: URL,
},
thumbnail: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
timestamp: new Date().toISOString(),
title: 'discordeno',
type: 'rich',
url: URL,
video: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
},
],
flags: 64,
guild_id: GUILD_ID,
id: GUILD_ID,
interaction: {
id: GUILD_ID,
name: 'discordeno',
type: InteractionTypes.ApplicationCommand,
user: USER,
member: MEMBER,
},
member: MEMBER,
mention_channels: [
{
guild_id: GUILD_ID,
id: GUILD_ID,
name: 'discordeno',
type: 0,
},
],
mention_roles: ['111111111111111111', '222222222222222222'],
mention_everyone: false,
mentions: [USER, USER, USER],
message_reference: {
message_id: GUILD_ID,
channel_id: GUILD_ID,
guild_id: GUILD_ID,
fail_if_not_exists: true,
},
nonce: 'discordeno',
pinned: true,
position: 100,
reactions: [
{
count: 100,
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
me: true,
me_burst: false,
count_details: {
normal: 100,
burst: 0,
},
burst_colors: [],
},
],
sticker_items: [
{
format_type: StickerFormatTypes.APng,
id: GUILD_ID,
name: 'discordeno',
},
],
thread: {
id: '987654321098765432',
name: 'My Thread',
type: 11,
guild_id: '123456789012345678',
parent_id: '876543210987654321',
owner_id: '111111111111111111',
message_count: 10,
member_count: 5,
created_timestamp: 1651388000,
last_message_id: '876543210987654321',
applied_tags: ['discordeno'],
default_thread_rate_limit_per_user: 100,
member: {
flags: 100,
id: GUILD_ID,
join_timestamp: new Date().toISOString(),
user_id: GUILD_ID,
},
},
timestamp: new Date().toISOString(),
tts: true,
type: MessageTypes.Default,
webhook_id: GUILD_ID,
}) as unknown as DiscordMessage,
), // array of event to test with
{ times: 1, log: false, table: false },
)
console.log('after the bench')
function oldtransformMessage(bot: Bot, payload: DiscordMessage): any {
const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined
const userId = bot.transformers.snowflake(payload.author.id)
const message = {
// UNTRANSFORMED STUFF HERE
content: payload.content ?? '',
isFromBot: payload.author.bot ?? false,
tag: `${payload.author.username}#${payload.author.discriminator}`,
timestamp: Date.parse(payload.timestamp),
editedTimestamp: payload.edited_timestamp ? Date.parse(payload.edited_timestamp) : undefined,
bitfield: (payload.tts ? 1n : 0n) | (payload.mention_everyone ? 2n : 0n) | (payload.pinned ? 4n : 0n),
attachments: payload.attachments?.map((attachment) => bot.transformers.attachment(bot, attachment)),
embeds: payload.embeds?.map((embed) => bot.transformers.embed(bot, embed)),
reactions: payload.reactions?.map((reaction) => ({
me: reaction.me,
count: reaction.count,
// @ts-expect-error: TODO: Deal with partials
emoji: bot.transformers.emoji(bot, reaction.emoji),
})),
type: payload.type,
activity: payload.activity
? {
type: payload.activity.type,
partyId: payload.activity.party_id,
}
: undefined,
application: payload.application,
flags: payload.flags,
interaction: payload.interaction
? {
id: bot.transformers.snowflake(payload.interaction.id),
type: payload.interaction.type,
name: payload.interaction.name,
user: bot.transformers.user(bot, payload.interaction.user),
member: payload.interaction.member
? {
id: userId,
guildId,
nick: payload.interaction.member.nick ?? undefined,
roles: payload.interaction.member.roles?.map((id) => bot.transformers.snowflake(id)),
joinedAt: payload.interaction.member.joined_at ? Date.parse(payload.interaction.member.joined_at) : undefined,
premiumSince: payload.interaction.member.premium_since ? Date.parse(payload.interaction.member.premium_since) : undefined,
toggles: new MemberToggles(payload.interaction.member),
avatar: payload.interaction.member.avatar ? iconHashToBigInt(payload.interaction.member.avatar) : undefined,
permissions: payload.interaction.member.permissions ? bot.transformers.snowflake(payload.interaction.member.permissions) : undefined,
communicationDisabledUntil: payload.interaction.member.communication_disabled_until
? Date.parse(payload.interaction.member.communication_disabled_until)
: undefined,
}
: undefined,
}
: undefined,
thread: payload.thread ? bot.transformers.channel(bot, payload.thread, { guildId }) : undefined,
components: payload.components?.map((component) => bot.transformers.component(bot, component)),
stickerItems: payload.sticker_items?.map((sticker) => ({
id: bot.transformers.snowflake(sticker.id),
name: sticker.name,
formatType: sticker.format_type,
})),
// TRANSFORMED STUFF BELOW
id: bot.transformers.snowflake(payload.id),
guildId,
channelId: bot.transformers.snowflake(payload.channel_id),
webhookId: payload.webhook_id ? bot.transformers.snowflake(payload.webhook_id) : undefined,
authorId: userId,
applicationId: payload.application_id ? bot.transformers.snowflake(payload.application_id) : undefined,
messageReference: payload.message_reference
? {
messageId: payload.message_reference.message_id ? bot.transformers.snowflake(payload.message_reference.message_id) : undefined,
channelId: payload.message_reference.channel_id ? bot.transformers.snowflake(payload.message_reference.channel_id) : undefined,
guildId: payload.message_reference.guild_id ? bot.transformers.snowflake(payload.message_reference.guild_id) : undefined,
}
: undefined,
mentionedUserIds: payload.mentions ? payload.mentions.map((m) => bot.transformers.snowflake(m.id)) : [],
mentionedRoleIds: payload.mention_roles ? payload.mention_roles.map((id) => bot.transformers.snowflake(id)) : [],
mentionedChannelIds: [
// Keep any ids tht discord sends
...(payload.mention_channels ?? []).map((m) => bot.transformers.snowflake(m.id)),
// Add any other ids that can be validated in a channel mention format
...(payload.content?.match(CHANNEL_MENTION_REGEX) ?? []).map((text) =>
// converts the <#123> into 123
bot.transformers.snowflake(text.substring(2, text.length - 1)),
),
],
// @ts-expect-error: partials
member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, userId) : undefined,
nonce: payload.nonce,
}
return message
}
await memoryBenchmark(
'[transformer] old message cache check',
() => ({
cache: [] as any[],
}), // function reutrn a new instance of object wanted to test with
(object, event: DiscordMessage) => object.cache.push(oldtransformMessage(bot as Bot, event)),
// function specify how to add event to the object/ run the object
[...new Array(MESSAGE_SIZE)].map(
() =>
({
activity: {
party_id: 'party_id',
type: MessageActivityTypes.Join,
},
application: {
bot_public: true,
bot_require_code_grant: true,
cover_image: IMAGE_HASH,
custom_install_url: 'https://google.com',
description: 'discordeno is the best lib ever',
flags: ApplicationFlags.GatewayGuildMembers,
guild_id: GUILD_ID,
icon: IMAGE_HASH,
id: GUILD_ID,
install_params: {
permissions: '8',
scopes: ['identify'],
},
name: 'skillz',
owner: USER,
primary_sku_id: GUILD_ID,
privacy_policy_url: 'https://discordeno.js.org',
role_connections_verification_url: 'https://discordeno.js.org',
rpc_origins: [],
slug: 'discordeno',
tags: ['discordeno', 'discordeno', 'discordeno', 'discordeno', 'discordeno'],
team: {
icon: IMAGE_HASH,
id: GUILD_ID,
members: [
{
membership_state: TeamMembershipStates.Accepted,
permissions: ['*'],
team_id: GUILD_ID,
user: USER,
},
{
membership_state: TeamMembershipStates.Accepted,
permissions: ['*'],
team_id: GUILD_ID,
user: USER,
},
],
name: 'discordeno',
owner_user_id: GUILD_ID,
},
terms_of_service_url: 'https://discordeno.js.org',
verify_key: IMAGE_HASH,
},
application_id: GUILD_ID,
attachments: [
{
content_type: 'application/json',
description: 'discordeno discordeno discordeno',
ephemeral: true,
filename: 'discordeno',
height: 100,
id: GUILD_ID,
proxy_url: 'https://discordeno.js.org',
size: 100,
url: 'https://discordeno.js.org',
width: 100,
},
{
content_type: 'application/json',
description: 'discordeno discordeno discordeno',
ephemeral: true,
filename: 'discordeno',
height: 100,
id: GUILD_ID,
proxy_url: 'https://discordeno.js.org',
size: 100,
url: 'https://discordeno.js.org',
width: 100,
},
],
author: USER,
channel_id: GUILD_ID,
components: [
{
type: 1,
components: [
{
custom_id: GUILD_ID,
disabled: true,
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
label: 'discordeno',
style: ButtonStyles.Danger,
type: MessageComponentTypes.Button,
url: 'https://discordeno.js.org',
},
],
},
{
type: 1,
components: [
{
type: MessageComponentTypes.TextInput,
custom_id: 'discordeno',
label: 'discordeno',
max_length: 100,
min_length: 100,
placeholder: 'discordeno',
required: true,
style: TextStyles.Paragraph,
value: 'discordeno',
},
],
},
{
type: 1,
components: [
{
type: MessageComponentTypes.StringSelect,
custom_id: 'discordeno',
max_values: 100,
min_values: 100,
options: [
{
default: true,
description: 'idk idk idk',
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
label: 'discordeno',
value: 'discordeno',
},
],
placeholder: 'discordeno',
},
],
},
],
content: 'discordeno',
edited_timestamp: new Date().toISOString(),
embeds: [
{
author: {
icon_url: URL,
name: 'discordeno',
proxy_icon_url: URL,
url: URL,
},
color: 0,
description: 'discordeno',
fields: [
{
name: 'discordeno',
value: 'discordeno',
inline: true,
},
{
name: 'discordeno',
value: 'discordeno',
inline: true,
},
],
footer: {
icon_url: URL,
proxy_icon_url: URL,
text: 'discordeno',
},
image: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
provider: {
name: 'discordeno',
url: URL,
},
thumbnail: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
timestamp: new Date().toISOString(),
title: 'discordeno',
type: 'rich',
url: URL,
video: {
height: 100,
width: 100,
proxy_url: URL,
url: URL,
},
},
],
flags: 64,
guild_id: GUILD_ID,
id: GUILD_ID,
interaction: {
id: GUILD_ID,
name: 'discordeno',
type: InteractionTypes.ApplicationCommand,
user: USER,
member: MEMBER,
},
member: MEMBER,
mention_channels: [
{
guild_id: GUILD_ID,
id: GUILD_ID,
name: 'discordeno',
type: 0,
},
],
mention_roles: ['111111111111111111', '222222222222222222'],
mention_everyone: false,
mentions: [USER, USER, USER],
message_reference: {
message_id: GUILD_ID,
channel_id: GUILD_ID,
guild_id: GUILD_ID,
fail_if_not_exists: true,
},
nonce: 'discordeno',
pinned: true,
position: 100,
reactions: [
{
count: 100,
emoji: {
animated: true,
id: GUILD_ID,
name: 'discordeno',
},
me: true,
me_burst: false,
count_details: {
normal: 100,
burst: 0,
},
burst_colors: [],
},
],
sticker_items: [
{
format_type: StickerFormatTypes.APng,
id: GUILD_ID,
name: 'discordeno',
},
],
thread: {
id: '987654321098765432',
name: 'My Thread',
type: 11,
guild_id: '123456789012345678',
parent_id: '876543210987654321',
owner_id: '111111111111111111',
message_count: 10,
member_count: 5,
created_timestamp: 1651388000,
last_message_id: '876543210987654321',
applied_tags: ['discordeno'],
default_thread_rate_limit_per_user: 100,
member: {
flags: 100,
id: GUILD_ID,
join_timestamp: new Date().toISOString(),
user_id: GUILD_ID,
},
},
timestamp: new Date().toISOString(),
tts: true,
type: MessageTypes.Default,
webhook_id: GUILD_ID,
}) as unknown as DiscordMessage,
), // array of event to test with
{ times: 1, log: false, table: false },
)

View File

@@ -1,84 +0,0 @@
import fs from 'node:fs/promises'
const benchmarkData = await fetch(`https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js`)
.then(async (res) => await res.text())
.then((text) => JSON.parse(text.slice(24)))
const results = JSON.parse(await fs.readFile('./data.json', 'utf-8'))
interface BenchmarksData {
commit: {
author: { email: string; name: string; username: string }
committer: { email: string; name: string; username: string }
distinct: boolean
id: string
message: string
timestamp: string
tree_id: string
url: string
}
date: number
tool: string
benches: Array<{ name: string; value: number; unit: string; range: string }>
}
type CompareTable = Record<string, Record<string, { name: string; value: number; unit: string; range: string }>>
const benchmarks = results.entries.Benchmark as BenchmarksData[]
benchmarks.reverse()
const compareWithHead: CompareTable = {}
const latestBaseBenchmarks = benchmarkData.entries.Benchmark.slice(-1)[0] as BenchmarksData
for (const benchmark of latestBaseBenchmarks.benches) {
compareWithHead[benchmark.name] = {
[latestBaseBenchmarks.commit.id]: benchmark,
}
}
for (let i = benchmarks.length - 1; i >= 0; i--) {
for (const bench of benchmarks[i].benches) {
if (compareWithHead[bench.name]) {
compareWithHead[bench.name][benchmarks[i].commit.id] = bench
} else {
compareWithHead[bench.name] = {
[benchmarks[i].commit.id]: bench,
}
}
}
}
let message = '<!-- benchmark comment by ci -->\n'
message += `## Benchmark\n\n`
message += '<details><summary>Detail results of benchmarks</summary>\n\n'
let header1 = `| Benchmark suite | Base (${latestBaseBenchmarks.commit.id}) |`
let header2 = `|-|-|`
const commitIds = benchmarks.map((benchmark) => benchmark.commit.id)
const uniqueCommitIds = commitIds.filter((benchmarkCommitId, index) => commitIds.indexOf(benchmarkCommitId) === index)
for (const [index, commitId] of uniqueCommitIds.entries()) {
header1 += index === 0 ? ` Latest Head (${commitId}) |` : ` ${commitId} |`
header2 += '-|'
}
message += `${header1}\n`
message += `${header2}\n`
for (const benchName of Object.keys(compareWithHead)) {
let benchData = `| ${benchName} |`
benchData += compareWithHead[benchName][latestBaseBenchmarks.commit.id]
? ` ${`\`${compareWithHead[benchName][latestBaseBenchmarks.commit.id].value}\` ${
compareWithHead[benchName][latestBaseBenchmarks.commit.id].unit
} \`${compareWithHead[benchName][latestBaseBenchmarks.commit.id].range}\``} |`
: '|'
for (const commitId of uniqueCommitIds) {
benchData += compareWithHead[benchName][commitId]
? ` \`${compareWithHead[benchName][commitId].value}\` ${compareWithHead[benchName][commitId].unit} \`${compareWithHead[benchName][commitId].range}\`|`
: '|'
}
message += `${benchData}\n`
}
message += '</details>\n\n'
console.log(message.replaceAll('`', '\\`'))

View File

@@ -1,12 +0,0 @@
import fs from 'node:fs/promises'
import { suite } from './benchmarkSuite.js'
const benchmarks = await fs.readdir(new URL('./benchmarks', import.meta.url)).then((files) => files.filter((file) => file.endsWith('.js')))
await Promise.all(benchmarks.map(async (file) => await import(`./benchmarks/${file}`)))
suite
.on('cycle', function (event: any) {
console.log(String(event.target))
})
.run()

View File

@@ -1,32 +0,0 @@
import fs from 'node:fs/promises'
import type { DiscordGatewayPayload } from '@discordeno/types'
export const events: Array<{
shardId: number
payload: DiscordGatewayPayload
}> = []
try {
const files = await fs.readdir('db/events')
for await (const file of files) {
const eventsInFile: Array<
| {
shardId: number
payload: DiscordGatewayPayload
}
| string
> = Object.values(await fs.readFile(`db/events/${file}`, 'utf8').then((text) => JSON.parse(text)))
eventsInFile.forEach((eventInFile) => {
if (typeof eventInFile === 'string') return
events.push(eventInFile)
})
}
} catch {
const event = await fetch('https://raw.githubusercontent.com/discordeno/benchmarks/main/db/events/10.json')
.then(async (res) => await res.json())
.then((eventsInFile: any) => eventsInFile['0'])
for (let i = 0; i < 10; i++) {
events.push(event)
}
}

View File

@@ -1,159 +0,0 @@
export async function memoryBenchmark<O, E>(
name: string,
objectCreator: () => O,
objectFeeder: (object: O, event: E) => void,
events: E[],
options: { times: number; log: boolean; table: boolean } = {
times: 3,
log: false,
table: false,
},
): Promise<void> {
const garbageCollect = global.gc ?? (() => {})
const stages = ['start', 'loaded', 'end', 'cached'] as const
const typesOfMemUsages = ['rss', 'heapUsed', 'heapTotal'] as const
async function runTest(object: O) {
// Determine memory stats now before touching anything
const results: {
start: NodeJS.MemoryUsage
loaded?: NodeJS.MemoryUsage
end?: NodeJS.MemoryUsage
cached?: NodeJS.MemoryUsage
} = {
start: process.memoryUsage(),
}
garbageCollect()
results.start = process.memoryUsage()
if (options.log) console.log(`[INFO] Loading json files.`)
if (options.log) {
console.log(`[INFO] DB files loaded into memory.`, events.length)
}
// Set the memory stats for when files are loaded in.
results.loaded = process.memoryUsage()
// events.forEach((event, i) => {
// console.log('logging event', i)
// objectFeeder(object, event)
// })
for (const event of events) {
objectFeeder(object, event)
}
if (options.log) {
console.log(`[INFO] Processed ${events.length} events.`)
}
// Set results for data once all events are processed
results.end = process.memoryUsage()
// @ts-expect-error init the object
results.cached = {}
for (const typeOfMemUsage of typesOfMemUsages) {
results.cached![typeOfMemUsage] = results.end[typeOfMemUsage] - results.loaded[typeOfMemUsage]
}
return results
}
const allResults = {
start: {
rss: [] as number[],
heapUsed: [] as number[],
heapTotal: [] as number[],
},
loaded: {
rss: [] as number[],
heapUsed: [] as number[],
heapTotal: [] as number[],
},
end: {
rss: [] as number[],
heapUsed: [] as number[],
heapTotal: [] as number[],
},
cached: {
rss: [] as number[],
heapUsed: [] as number[],
heapTotal: [] as number[],
},
}
const BYTES = 1000000
for (let index = 0; index < options.times; index++) {
if (options.log) console.log('running the', index + 1, 'time')
const currentResult = await runTest(objectCreator())
for (const typeOfMemUsage of typesOfMemUsages) {
for (const stage of stages) {
allResults[stage][typeOfMemUsage].push(currentResult[stage]![typeOfMemUsage])
}
}
}
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends ReadonlyArray<infer ElementType> ? ElementType : never
const tableRows = ['Starting', 'Loaded', 'End', 'Cached'] as const
const tableFields = ['RSS', 'Heap Used', 'Heap Total'] as const
const preprocessedResults: {
[K in ArrayElement<typeof tableRows>]?: {
[K in ArrayElement<typeof tableFields>]?: {
value: number
min: number
max: number
}
}
} = {}
for (const [index, tableRow] of tableRows.entries()) {
for (const [index2, tableField] of tableFields.entries()) {
if (index2 === 0) preprocessedResults[tableRow] = {}
preprocessedResults[tableRow]![tableField] = {
value:
Math.round(
(allResults[stages[index]][typesOfMemUsages[index2]].reduce((acc, c) => acc + c, 0) / allResults.start.rss.length / BYTES) * 100,
) / 100,
min: Math.round((Math.min(...allResults[stages[index]][typesOfMemUsages[index2]]) / BYTES) * 100) / 100,
max: Math.round((Math.max(...allResults[stages[index]][typesOfMemUsages[index2]]) / BYTES) * 100) / 100,
}
}
}
const processedResults = preprocessedResults as {
[K in ArrayElement<typeof tableRows>]: {
[K in ArrayElement<typeof tableFields>]: {
value: number
min: number
max: number
}
}
}
const humanReadable: {
[K in ArrayElement<typeof tableRows>]?: {
[K in ArrayElement<typeof tableFields>]?: string
}
} = {}
for (const tableRow of tableRows) {
for (const [index, tableField] of tableFields.entries()) {
if (index === 0) humanReadable[tableRow] = {}
humanReadable[tableRow]![tableField] =
`${processedResults[tableRow][tableField].value} MB (${processedResults[tableRow][tableField].min} MB … ${processedResults[tableRow][tableField].max} MB)`
}
}
if (options.table) console.table(humanReadable)
for (const resultKey of Object.keys(processedResults.Cached) as Array<keyof typeof processedResults.Cached>) {
const range = Math.max(
Math.round((processedResults.Cached[resultKey].min / processedResults.Cached[resultKey].value) * 100) / 100,
Math.round((processedResults.Cached[resultKey].max / processedResults.Cached[resultKey].value) * 100) / 100,
)
console.log(`${name} ${resultKey.toString()} x ${processedResults.Cached[resultKey].value} MB ±${isFinite(range) ? range : 0}% (3 runs sampled)`)
}
}

View File

@@ -1,3 +0,0 @@
{
"extends": "tsconfig/base.json"
}

View File

@@ -1,11 +0,0 @@
---
sidebar_position: 10
---
# Benchmark
Benchmark runs on every commit pushed on the Discordeno's main branch
import Benchmark from '@site/src/components/Benchmark'
<Benchmark />

View File

@@ -25,11 +25,9 @@
"@easyops-cn/docusaurus-search-local": "^0.52.1",
"@mdx-js/react": "^3.1.0",
"@xyflow/react": "^12.8.2",
"chart.js": "^4.5.0",
"clsx": "^2.1.1",
"prism-react-renderer": "^2.4.1",
"react": "^19.1.1",
"react-chartjs-2": "^5.3.0",
"react-dom": "^19.1.1",
"styled-components": "^6.1.19"
},

View File

@@ -1,156 +0,0 @@
import { CategoryScale, Chart as ChartJS, Legend, LinearScale, LineController, LineElement, PointElement, Title, Tooltip } from 'chart.js'
import { useEffect, useState } from 'react'
import { Chart } from 'react-chartjs-2'
ChartJS.register(CategoryScale, LineController, LinearScale, PointElement, LineElement, Title, Tooltip, Legend)
const BenchmarkResultChart = ({
name,
dataset,
}: {
name: string
dataset: Array<{
bench: {
name: string
range: string | number
unit: string
value: string | number
extra: string | number | undefined
}
commit: {
author: {
email: string
name: string
username: string
}
committer: {
email: string
name: string
username: string
}
distinct: true
id: string
message: string
timestamp: string
tree_id: string
url: string
}
date: number
tool: string
}>
}) => {
const data = {
labels: dataset.map((d) => d.commit.id.slice(0, 7)),
datasets: [
{
label: name,
data: dataset.map((d) => d.bench.value),
borderColor: '#ff3838',
backgroundColor: '#ff383860', // Add alpha for #rrggbbaa
},
],
}
return (
<Chart
type="line"
data={data}
options={{
responsive: true,
scales: {
x: {
title: {
display: true,
text: 'commit',
},
},
y: {
title: {
display: true,
text: dataset.length > 0 ? dataset[0].bench.unit : '',
},
beginAtZero: true,
},
},
plugins: {
tooltip: {
callbacks: {
afterTitle: (items) => {
const index = items[0].dataIndex
const data = dataset[index]
return '\n' + data.commit.message + '\n\n' + data.commit.timestamp + ' committed by @' + data.commit.author.username + '\n'
},
label: (item) => {
let label = item.formattedValue
const { range, unit } = dataset[item.datasetIndex].bench
label += ` ${unit}`
if (range) {
label += ` (${range})`
}
return label
},
afterLabel: (item) => {
const { extra } = dataset[item.datasetIndex].bench
return extra ? `\n${extra}` : ''
},
},
},
},
onClick: (_mouseEvent, activeElems) => {
if (activeElems.length === 0) {
return
}
// XXX: Undocumented. How can we know the index?
const index = activeElems[0].index
const url = dataset[index].commit.url
window.open(url, '_blank')
},
}}
/>
)
}
export default function BenchmarkResultCharts(): JSX.Element {
const [data, setData] = useState<{ entries: { Benchmark: [] } }>()
useEffect(() => {
if (!data) {
void (async () => {
setData(
JSON.parse(
(await (await fetch('https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js')).text()).slice(24),
) as { entries: { Benchmark: [] } },
)
})()
}
}, [])
function collectBenchesPerTestCase(entries) {
const dataMap = new Map()
for (const entry of entries) {
const { commit, date, tool, benches } = entry
for (const bench of benches) {
const result = { commit, date, tool, bench }
const arr = dataMap.get(bench.name)
if (arr === undefined) {
dataMap.set(bench.name, [result])
} else {
arr.push(result)
}
}
}
return dataMap
}
return (
<div style={{ minHeight: '100vh' }}>
{data ? (
Array.from(collectBenchesPerTestCase(data.entries.Benchmark), ([key, value]) => ({ benchName: key, benches: value })).map((bench, index) => (
<BenchmarkResultChart key={index} name={bench.benchName} dataset={bench.benches} />
))
) : (
<></>
)}
</div>
)
}

View File

@@ -7128,13 +7128,6 @@ __metadata:
languageName: node
linkType: hard
"@kurkle/color@npm:^0.3.0":
version: 0.3.2
resolution: "@kurkle/color@npm:0.3.2"
checksum: 10c0/a9e8e3e35dcd59dec4dd4f0105919c05e24823a96347bcf152965c29e48d6290b66d5fb96c071875db752e10930724c48ce6d338fefbd65e0ce5082d5c78970e
languageName: node
linkType: hard
"@leichtgewicht/ip-codec@npm:^2.0.1":
version: 2.0.4
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
@@ -10276,15 +10269,6 @@ __metadata:
languageName: node
linkType: hard
"chart.js@npm:^4.5.0":
version: 4.5.0
resolution: "chart.js@npm:4.5.0"
dependencies:
"@kurkle/color": "npm:^0.3.0"
checksum: 10c0/f12c7f9a238ee7ce6d3f7111628e9daba86bb8ff8e54cfe63525fde6ded9003c72c4c8d2c7d5702539dc0aff7e682dfec058660ade8d03a970da002656d4ac91
languageName: node
linkType: hard
"cheerio-select@npm:^2.1.0":
version: 2.1.0
resolution: "cheerio-select@npm:2.1.0"
@@ -17628,16 +17612,6 @@ __metadata:
languageName: node
linkType: hard
"react-chartjs-2@npm:^5.3.0":
version: 5.3.0
resolution: "react-chartjs-2@npm:5.3.0"
peerDependencies:
chart.js: ^4.1.1
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/4415d40217c084a49f9a936fbd30f67e0e705148e6f8359bec65601033d1076f31085c45793839fc29ec833e6c427b0bf9861a0c54c432c08d35bc9590ffa41a
languageName: node
linkType: hard
"react-dev-utils@npm:^12.0.1":
version: 12.0.1
resolution: "react-dev-utils@npm:12.0.1"
@@ -20197,11 +20171,9 @@ __metadata:
"@mdx-js/react": "npm:^3.1.0"
"@types/react": "npm:^19.1.10"
"@xyflow/react": "npm:^12.8.2"
chart.js: "npm:^4.5.0"
clsx: "npm:^2.1.1"
prism-react-renderer: "npm:^2.4.1"
react: "npm:^19.1.1"
react-chartjs-2: "npm:^5.3.0"
react-dom: "npm:^19.1.1"
styled-components: "npm:^6.1.19"
typescript: "npm:5.9.2"

View File

@@ -766,13 +766,6 @@ __metadata:
languageName: node
linkType: hard
"@types/benchmark@npm:^2.1.5":
version: 2.1.5
resolution: "@types/benchmark@npm:2.1.5"
checksum: 10c0/31ca163891bea0dbe28ad517ae95d18531518049e95cfac218e082590b33edd75cda23fc3e4abf72112b3928e844488c9b029b33aa29f825a83a16d2ed202154
languageName: node
linkType: hard
"@types/chai-as-promised@npm:^8.0.2":
version: 8.0.2
resolution: "@types/chai-as-promised@npm:8.0.2"
@@ -1105,37 +1098,6 @@ __metadata:
languageName: node
linkType: hard
"benchmark@npm:^2.1.4":
version: 2.1.4
resolution: "benchmark@npm:2.1.4"
dependencies:
lodash: "npm:^4.17.4"
platform: "npm:^1.3.3"
checksum: 10c0/510224c01f7578e9aa60cef67ec3dd8f84ac6670007bcc96285f87865375122aca0853ab4e542cc80cfeeed436356dfdd63bb66cb5e72365abb912685b2139be
languageName: node
linkType: hard
"benchmarks@workspace:packages/benchmarks":
version: 0.0.0-use.local
resolution: "benchmarks@workspace:packages/benchmarks"
dependencies:
"@biomejs/biome": "npm:2.2.4"
"@discordeno/bot": "workspace:^"
"@discordeno/gateway": "workspace:^"
"@discordeno/rest": "workspace:^"
"@discordeno/types": "workspace:^"
"@discordeno/utils": "workspace:^"
"@swc/cli": "npm:^0.7.8"
"@swc/core": "npm:^1.13.5"
"@types/benchmark": "npm:^2.1.5"
"@types/node": "npm:^24.6.1"
benchmark: "npm:^2.1.4"
ts-node: "npm:^10.9.2"
tsconfig: "npm:*"
typescript: "npm:^5.9.2"
languageName: unknown
linkType: soft
"bin-version-check@npm:^5.1.0":
version: 5.1.0
resolution: "bin-version-check@npm:5.1.0"
@@ -2083,13 +2045,6 @@ __metadata:
languageName: node
linkType: hard
"lodash@npm:^4.17.4":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c
languageName: node
linkType: hard
"log-symbols@npm:^4.1.0":
version: 4.1.0
resolution: "log-symbols@npm:4.1.0"
@@ -2466,13 +2421,6 @@ __metadata:
languageName: node
linkType: hard
"platform@npm:^1.3.3":
version: 1.3.6
resolution: "platform@npm:1.3.6"
checksum: 10c0/69f2eb692e15f1a343dd0d9347babd9ca933824c8673096be746ff66f99f2bdc909fadd8609076132e6ec768349080babb7362299f2a7f885b98f1254ae6224b
languageName: node
linkType: hard
"punycode.js@npm:^2.3.1":
version: 2.3.1
resolution: "punycode.js@npm:2.3.1"