mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-21 02:40:08 +00:00
Remove benchmarks page & package (#4479)
* Remove benchmarks package and page * Remove benchmarks CI
This commit is contained in:
107
.github/workflows/benchmark.yml
vendored
107
.github/workflows/benchmark.yml
vendored
@@ -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
|
||||
114
.github/workflows/commentBenchResult.yml
vendored
114
.github/workflows/commentBenchResult.yml
vendored
@@ -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 }}`
|
||||
});
|
||||
}
|
||||
}
|
||||
91
.github/workflows/retryBenchmark.yml
vendored
91
.github/workflows/retryBenchmark.yml
vendored
@@ -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 }}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import Benchmark from 'benchmark'
|
||||
|
||||
export const suite = new Benchmark.Suite()
|
||||
@@ -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])
|
||||
})
|
||||
@@ -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),
|
||||
)
|
||||
@@ -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')
|
||||
})
|
||||
@@ -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 },
|
||||
)
|
||||
@@ -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('`', '\\`'))
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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)`)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "tsconfig/base.json"
|
||||
}
|
||||
@@ -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 />
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
52
yarn.lock
52
yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user