A decentralized music tracking and discovery platform built on AT Protocol 🎵

feat: migrate to Bun and update dependencies for improved performance

+51 -64
+15 -14
apps/api/package.json
··· 6 6 "module": "dist/index.js", 7 7 "scripts": { 8 8 "lexgen": "lex gen-server ./src/lexicon ./src/tealfm/lexicons/teal/**/* ./lexicons/**/* ./lexicons/* ./src/tealfm/lexicons/**/*", 9 - "dev": "concurrently 'tsx --watch ./src/index.ts' 'tsx --watch ./src/server.ts'", 10 - "prod": "tsx ./src/index.ts", 9 + "dev": "concurrently 'bun --watch ./src/index.ts' 'bun --watch ./src/server.ts'", 10 + "prod": "bun ./src/index.ts", 11 11 "build": "pkgroll", 12 - "sync": "tsx ./src/scripts/sync.ts", 13 - "meili:sync": "tsx ./src/scripts/meili.ts", 14 - "sync:library": "tsx ./src/scripts/sync-library.ts", 15 - "avatar": "tsx ./src/scripts/avatar.ts", 16 - "genres": "tsx ./src/scripts/genres.ts", 12 + "sync": "bun ./src/scripts/sync.ts", 13 + "meili:sync": "bun ./src/scripts/meili.ts", 14 + "sync:library": "bun ./src/scripts/sync-library.ts", 15 + "avatar": "bun ./src/scripts/avatar.ts", 16 + "genres": "bun ./src/scripts/genres.ts", 17 17 "pkl:eval": "pkl eval -f json", 18 - "pkl:gen": "tsx ./scripts/pkl.ts", 19 - "dev:xrpc": "tsx --watch ./src/server.ts", 20 - "prod:xrpc": "tsx ./src/server.ts", 18 + "pkl:gen": "bun ./scripts/pkl.ts", 19 + "dev:xrpc": "bun --watch ./src/server.ts", 20 + "prod:xrpc": "bun ./src/server.ts", 21 21 "db:migrate": "drizzle-kit migrate", 22 22 "db:gen-migration": "drizzle-kit generate", 23 - "prod:all": "concurrently 'tsx ./src/index.ts' 'tsx ./src/server.ts'", 23 + "prod:all": "concurrently 'bun ./src/index.ts' 'bun ./src/server.ts'", 24 24 "format": "biome format src", 25 25 "lint": "biome lint src" 26 26 }, ··· 28 28 "@atproto/api": "^0.13.31", 29 29 "@atproto/common": "^0.4.6", 30 30 "@atproto/identity": "^0.4.5", 31 + "@atproto/jwk-jose": "0.1.8", 31 32 "@atproto/lex-cli": "^0.5.6", 32 33 "@atproto/lexicon": "^0.4.5", 33 34 "@atproto/oauth-client-node": "^0.2.14", ··· 44 45 "@opentelemetry/sdk-metrics": "^2.0.0", 45 46 "@opentelemetry/sdk-node": "^0.200.0", 46 47 "@opentelemetry/semantic-conventions": "^1.32.0", 47 - "@pyroscope/nodejs": "^0.4.5", 48 48 "assert": "^2.1.0", 49 49 "axios": "^1.7.9", 50 - "better-sqlite3": "^11.8.1", 51 50 "chalk": "^5.4.1", 52 51 "chanfana": "^2.0.2", 53 52 "cors": "^2.8.5", ··· 63 62 "http-proxy-middleware": "^3.0.5", 64 63 "iron-session": "^8.0.4", 65 64 "jsonwebtoken": "^9.0.2", 66 - "kysely": "^0.27.5", 65 + "kysely": "^0.28.8", 66 + "kysely-bun-sqlite": "^0.4.0", 67 67 "lodash": "^4.17.21", 68 68 "nats": "^2.29.2", 69 69 "pg": "^8.13.3", ··· 78 78 "devDependencies": { 79 79 "@biomejs/biome": "^2.2.3", 80 80 "@pkl-community/pkl": "^0.28.2", 81 + "@types/bun": "^1.3.0", 81 82 "@types/express": "^5.0.2", 82 83 "@types/lodash": "^4.17.17", 83 84 "@types/node": "^22.13.0",
+3 -3
apps/api/src/db.ts
··· 1 - import SqliteDb from "better-sqlite3"; 1 + import { Database as SqliteDb } from "bun:sqlite"; 2 2 import { 3 3 Kysely, 4 4 type Migration, 5 5 type MigrationProvider, 6 6 Migrator, 7 - SqliteDialect, 8 7 } from "kysely"; 8 + import { BunSqliteDialect } from "kysely-bun-sqlite"; 9 9 10 10 // Types 11 11 ··· 79 79 80 80 export const createDb = (location: string): Database => { 81 81 return new Kysely<DatabaseSchema>({ 82 - dialect: new SqliteDialect({ 82 + dialect: new BunSqliteDialect({ 83 83 database: new SqliteDb(location), 84 84 }), 85 85 });
+3 -4
apps/api/src/index.ts
··· 24 24 import googledrive from "./googledrive/app"; 25 25 import { env } from "./lib/env"; 26 26 import { requestCounter, requestDuration } from "./metrics"; 27 - import "./profiling"; 28 27 import albumTracks from "./schema/album-tracks"; 29 28 import albums from "./schema/albums"; 30 29 import artistTracks from "./schema/artist-tracks"; ··· 47 46 rateLimiter({ 48 47 limit: 1000, 49 48 window: 30, // 👈 30 seconds 50 - }), 49 + }) 51 50 ); 52 51 53 52 app.use("*", async (c, next) => { ··· 162 161 ctx.redis.get(`nowplaying:${user.did}:status`), 163 162 ]); 164 163 return c.json( 165 - nowPlaying ? { ...JSON.parse(nowPlaying), is_playing: status === "1" } : {}, 164 + nowPlaying ? { ...JSON.parse(nowPlaying), is_playing: status === "1" } : {} 166 165 ); 167 166 }); 168 167 ··· 314 313 listeners: 1, 315 314 sha256: item.track.sha256, 316 315 id: item.scrobble.id, 317 - })), 316 + })) 318 317 ); 319 318 }); 320 319
-13
apps/api/src/profiling.ts
··· 1 - import Pyroscope from "@pyroscope/nodejs"; 2 - 3 - Pyroscope.init({ 4 - serverAddress: "http://localhost:4040", 5 - appName: "rocksky-api", 6 - // Enable CPU time collection for wall profiles 7 - // This is required for CPU profiling functionality 8 - // wall: { 9 - // collectCpuTime: true 10 - // } 11 - }); 12 - 13 - Pyroscope.start();
+10 -9
apps/api/src/sqliteKv.ts
··· 1 - import Database from "better-sqlite3"; 2 - import { Kysely, SqliteDialect } from "kysely"; 1 + import { Database } from "bun:sqlite"; 2 + import { Kysely } from "kysely"; 3 + import { BunSqliteDialect } from "kysely-bun-sqlite"; 3 4 import { defineDriver } from "unstorage"; 4 5 5 6 interface TableSchema { ··· 38 39 throw new Error("SQLite location is required"); 39 40 } 40 41 41 - const sqlite = new Database(location, { fileMustExist: false }); 42 + const sqlite = new Database(location); 42 43 43 44 // Enable WAL mode 44 - sqlite.pragma("journal_mode = WAL"); 45 + sqlite.run("PRAGMA journal_mode = WAL;"); 45 46 46 47 _db = new Kysely<TableSchema>({ 47 - dialect: new SqliteDialect({ 48 + dialect: new BunSqliteDialect({ 48 49 database: sqlite, 49 50 }), 50 51 }); ··· 100 101 oc.column("id").doUpdateSet({ 101 102 value, 102 103 updated_at: now, 103 - }), 104 + }) 104 105 ) 105 106 .execute(); 106 107 }, ··· 125 126 oc.column("id").doUpdateSet({ 126 127 value, 127 128 updated_at: now, 128 - }), 129 + }) 129 130 ) 130 131 .execute(); 131 - }), 132 + }) 132 133 ); 133 134 }); 134 135 }, ··· 169 170 await getDb().destroy(); 170 171 }, 171 172 }; 172 - }, 173 + } 173 174 );
+1 -1
apps/api/tsconfig.json
··· 22 22 "target": "esnext", 23 23 "module": "esnext", 24 24 "types": [ 25 - "@types/node", 25 + "@types/bun", 26 26 "@types/service-worker-mock", 27 27 "@cloudflare/workers-types/2023-07-01" 28 28 ]
+18 -20
bun.lock
··· 5 5 "name": "rocksky", 6 6 "devDependencies": { 7 7 "@biomejs/biome": "^2.2.3", 8 + "@types/bun": "^1.3.0", 8 9 "prettier": "^3.5.3", 9 10 "turbo": "^2.5.8", 10 11 }, ··· 16 17 "@atproto/api": "^0.13.31", 17 18 "@atproto/common": "^0.4.6", 18 19 "@atproto/identity": "^0.4.5", 20 + "@atproto/jwk-jose": "0.1.8", 19 21 "@atproto/lex-cli": "^0.5.6", 20 22 "@atproto/lexicon": "^0.4.5", 21 23 "@atproto/oauth-client-node": "^0.2.14", ··· 32 34 "@opentelemetry/sdk-metrics": "^2.0.0", 33 35 "@opentelemetry/sdk-node": "^0.200.0", 34 36 "@opentelemetry/semantic-conventions": "^1.32.0", 35 - "@pyroscope/nodejs": "^0.4.5", 36 37 "assert": "^2.1.0", 37 38 "axios": "^1.7.9", 38 - "better-sqlite3": "^11.8.1", 39 39 "chalk": "^5.4.1", 40 40 "chanfana": "^2.0.2", 41 41 "cors": "^2.8.5", ··· 51 51 "http-proxy-middleware": "^3.0.5", 52 52 "iron-session": "^8.0.4", 53 53 "jsonwebtoken": "^9.0.2", 54 - "kysely": "^0.27.5", 54 + "kysely": "^0.28.8", 55 + "kysely-bun-sqlite": "^0.4.0", 55 56 "lodash": "^4.17.21", 56 57 "nats": "^2.29.2", 57 58 "pg": "^8.13.3", ··· 66 67 "devDependencies": { 67 68 "@biomejs/biome": "^2.2.3", 68 69 "@pkl-community/pkl": "^0.28.2", 70 + "@types/bun": "^1.3.0", 69 71 "@types/express": "^5.0.2", 70 72 "@types/lodash": "^4.17.17", 71 73 "@types/node": "^22.13.0", ··· 500 502 "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250620.0", "", {}, "sha512-EVvRB/DJEm6jhdKg+A4Qm4y/ry1cIvylSgSO3/f/Bv161vldDRxaXM2YoQQWFhLOJOw0qtrHsKOD51KYxV1XCw=="], 501 503 502 504 "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], 503 - 504 - "@datadog/pprof": ["@datadog/pprof@5.8.2", "", { "dependencies": { "delay": "^5.0.0", "node-gyp-build": "<4.0", "p-limit": "^3.1.0", "pprof-format": "^2.1.0", "source-map": "^0.7.4" } }, "sha512-M+bO4v4TaxYK6k2qJBxnhf7Vh25Wode64y4LfxzGs5kLTFr8eFTp6HJai3/af7U5gjTHX/4s+CHv2bxja97pbw=="], 505 505 506 506 "@date-io/core": ["@date-io/core@2.17.0", "", {}, "sha512-+EQE8xZhRM/hsY0CDTVyayMDDY5ihc4MqXCrPxooKw19yAzUIC6uUqsZeaOFNL9YKTNxYKrJP5DFgE8o5xRCOw=="], 507 507 ··· 919 919 920 920 "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], 921 921 922 - "@pyroscope/nodejs": ["@pyroscope/nodejs@0.4.5", "", { "dependencies": { "@datadog/pprof": "^5.4.1", "debug": "^4.3.3", "p-limit": "^3.1.0", "regenerator-runtime": "^0.13.11", "source-map": "^0.7.3" } }, "sha512-39YVwmLA2QhmLEd/yZjkjvAdU16kH0CiH6KY4wd1O4Lz7CszLW3/q2b33RAegdpnFmu8pPMhDcrPl/79mkjI0g=="], 923 - 924 922 "@redis/bloom": ["@redis/bloom@1.2.0", "", { "peerDependencies": { "@redis/client": "^1.0.0" } }, "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg=="], 925 923 926 924 "@redis/client": ["@redis/client@1.6.1", "", { "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", "yallist": "4.0.0" } }, "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw=="], ··· 1217 1215 1218 1216 "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], 1219 1217 1218 + "@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="], 1219 + 1220 1220 "@types/bunyan": ["@types/bunyan@1.8.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ=="], 1221 1221 1222 1222 "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], ··· 1411 1411 1412 1412 "better-opn": ["better-opn@3.0.2", "", { "dependencies": { "open": "^8.0.4" } }, "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ=="], 1413 1413 1414 - "better-sqlite3": ["better-sqlite3@11.10.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ=="], 1414 + "better-sqlite3": ["better-sqlite3@12.4.1", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ=="], 1415 1415 1416 1416 "bignumber.js": ["bignumber.js@9.3.0", "", {}, "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA=="], 1417 1417 ··· 1440 1440 "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], 1441 1441 1442 1442 "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], 1443 + 1444 + "bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="], 1443 1445 1444 1446 "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], 1445 1447 ··· 1479 1481 1480 1482 "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], 1481 1483 1482 - "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], 1484 + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], 1483 1485 1484 1486 "chromatic": ["chromatic@11.29.0", "", { "peerDependencies": { "@chromatic-com/cypress": "^0.*.* || ^1.0.0", "@chromatic-com/playwright": "^0.*.* || ^1.0.0" }, "optionalPeers": ["@chromatic-com/cypress", "@chromatic-com/playwright"], "bin": { "chroma": "dist/bin.js", "chromatic": "dist/bin.js", "chromatic-cli": "dist/bin.js" } }, "sha512-yisBlntp9hHVj19lIQdpTlcYIXuU9H/DbFuu6tyWHmj6hWT2EtukCCcxYXL78XdQt1vm2GfIrtgtKpj/Rzmo4A=="], 1485 1487 ··· 1650 1652 "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], 1651 1653 1652 1654 "delaunator": ["delaunator@4.0.1", "", {}, "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag=="], 1653 - 1654 - "delay": ["delay@5.0.0", "", {}, "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw=="], 1655 1655 1656 1656 "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], 1657 1657 ··· 2059 2059 2060 2060 "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 2061 2061 2062 - "kysely": ["kysely@0.27.6", "", {}, "sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ=="], 2062 + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], 2063 + 2064 + "kysely": ["kysely@0.28.8", "", {}, "sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA=="], 2065 + 2066 + "kysely-bun-sqlite": ["kysely-bun-sqlite@0.4.0", "", { "dependencies": { "bun-types": "^1.1.31" }, "peerDependencies": { "kysely": "^0.28.2" } }, "sha512-2EkQE5sT4ewiw7IWfJsAkpxJ/QPVKXKO5sRYI/xjjJIJlECuOdtG+ssYM0twZJySrdrmuildNPFYVreyu1EdZg=="], 2063 2067 2064 2068 "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], 2065 2069 ··· 2207 2211 2208 2212 "node-fetch-native": ["node-fetch-native@1.6.6", "", {}, "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ=="], 2209 2213 2210 - "node-gyp-build": ["node-gyp-build@3.9.0", "", { "bin": { "node-gyp-build": "./bin.js", "node-gyp-build-test": "./build-test.js", "node-gyp-build-optional": "./optional.js" } }, "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A=="], 2211 - 2212 2214 "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.1.1", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-test": "build-test.js", "node-gyp-build-optional-packages-optional": "optional.js" } }, "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw=="], 2213 2215 2214 2216 "node-mock-http": ["node-mock-http@1.0.0", "", {}, "sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ=="], ··· 2337 2339 2338 2340 "potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="], 2339 2341 2340 - "pprof-format": ["pprof-format@2.1.0", "", {}, "sha512-0+G5bHH0RNr8E5hoZo/zJYsL92MhkZjwrHp3O2IxmY8RJL9ooKeuZ8Tm0ZNBw5sGZ9TiM71sthTjWoR2Vf5/xw=="], 2341 - 2342 2342 "preact": ["preact@10.26.9", "", {}, "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA=="], 2343 2343 2344 2344 "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], ··· 2460 2460 "redent": ["redent@3.0.0", "", { "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg=="], 2461 2461 2462 2462 "redis": ["redis@4.7.1", "", { "dependencies": { "@redis/bloom": "1.2.0", "@redis/client": "1.6.1", "@redis/graph": "1.1.1", "@redis/json": "1.0.7", "@redis/search": "1.2.0", "@redis/time-series": "1.1.0" } }, "sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ=="], 2463 - 2464 - "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="], 2465 2463 2466 2464 "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], 2467 2465 ··· 3205 3203 3206 3204 "table/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], 3207 3205 3208 - "tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], 3209 - 3210 3206 "tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], 3211 3207 3212 3208 "tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], 3209 + 3210 + "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], 3213 3211 3214 3212 "tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], 3215 3213
+1
package.json
··· 3 3 "version": "0.0.0", 4 4 "devDependencies": { 5 5 "@biomejs/biome": "^2.2.3", 6 + "@types/bun": "^1.3.0", 6 7 "prettier": "^3.5.3", 7 8 "turbo": "^2.5.8" 8 9 },