Compare commits

...

1 Commits

Author SHA1 Message Date
85efb0478c Baby's first websocket response 2025-02-06 13:02:34 -08:00
6 changed files with 285 additions and 53 deletions

View File

@ -59,7 +59,6 @@ export default function DayView({
return ( return (
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<div className="flex justify-between pr-4 flex-col gap-4 md:flex-row"> <div className="flex justify-between pr-4 flex-col gap-4 md:flex-row">
<div className="flex"> <div className="flex">
<Link <Link

View File

@ -1,7 +1,25 @@
"use client"; "use client";
import { createTRPCReact } from "@trpc/react-query"; import { createTRPCReact } from "@trpc/react-query";
import { createWSClient, httpBatchLink, splitLink, wsLink } from "@trpc/client";
import { appRouter } from "@lifetracker/trpc/routers/_app"; import { appRouter } from "@lifetracker/trpc/routers/_app";
import SuperJSON from "superjson";
export const api = createTRPCReact<typeof appRouter>(); export const api = createTRPCReact<typeof appRouter>();
const wsClient = createWSClient({
url: process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3000/api/ws',
});
export const trpcClient = api.createClient({
links: [
splitLink({
condition: (op) => op.type === 'subscription',
true: httpBatchLink({
url: '/api/ws',
transformer: SuperJSON,
}),
false: wsLink({ client: wsClient, transformer: SuperJSON }),
}),
],
});

View File

@ -5,7 +5,7 @@
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "next dev", "dev": "tsx server.ts",
"clean": "git clean -xdf .next .turbo node_modules", "clean": "git clean -xdf .next .turbo node_modules",
"build": "next build -d", "build": "next build -d",
"start": "next start", "start": "next start",
@ -71,6 +71,7 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"drizzle-orm": "^0.33.0", "drizzle-orm": "^0.33.0",
"express": "^4.21.2",
"fastest-levenshtein": "^1.0.16", "fastest-levenshtein": "^1.0.16",
"formidable": "^3.5.2", "formidable": "^3.5.2",
"lucide-react": "latest", "lucide-react": "latest",
@ -78,6 +79,7 @@
"next-auth": "^4.24.5", "next-auth": "^4.24.5",
"next-pwa": "^5.6.0", "next-pwa": "^5.6.0",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"next-ws": "^1.2.0",
"pg-dump-restore": "^1.0.12", "pg-dump-restore": "^1.0.12",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"react": "^18.2.0", "react": "^18.2.0",
@ -103,6 +105,7 @@
"superjson": "^2.2.1", "superjson": "^2.2.1",
"tailwind-merge": "^2.2.1", "tailwind-merge": "^2.2.1",
"title-case": "^4.3.2", "title-case": "^4.3.2",
"ws": "^8.18.0",
"zod": "^3.22.4", "zod": "^3.22.4",
"zustand": "^4.5.1" "zustand": "^4.5.1"
}, },
@ -113,11 +116,13 @@
"@lifetracker/typescript-config": "workspace:^0.1.0", "@lifetracker/typescript-config": "workspace:^0.1.0",
"@types/csv-parse": "^1.2.5", "@types/csv-parse": "^1.2.5",
"@types/emoji-mart": "^3.0.14", "@types/emoji-mart": "^3.0.14",
"@types/express": "^5.0.0",
"@types/react": "^18.2.55", "@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19", "@types/react-dom": "^18.2.19",
"@types/react-syntax-highlighter": "^15.5.13", "@types/react-syntax-highlighter": "^15.5.13",
"@types/regression": "^2.0.6", "@types/regression": "^2.0.6",
"@types/request-ip": "^0.0.41", "@types/request-ip": "^0.0.41",
"@types/ws": "^8.5.14",
"autoprefixer": "^10.4.17", "autoprefixer": "^10.4.17",
"postcss": "^8.4.35", "postcss": "^8.4.35",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",

86
apps/web/server.ts Normal file
View File

@ -0,0 +1,86 @@
// apps/web/server.js
import express from 'express';
import http from 'http';
import next from 'next';
import { WebSocketServer } from 'ws';
import { applyWSSHandler } from '@trpc/server/adapters/ws';
import { appRouter } from '@lifetracker/trpc/routers/_app';
import { createWSContext } from '@/server/api/ws';
import { parse } from 'url';
import { NextRequestHint } from 'next/dist/server/web/adapter';
const dev = process.env.NODE_ENV !== 'production';
// Create an Express app and HTTP server.
const app = express();
const server = http.createServer(app);
const nextApp = next({
dev,
customServer: true,
hostname: process.env.HOSTNAME || "localhost",
port: Number(process.env.PORT) || 3000,
});
const handle = nextApp.getRequestHandler();
nextApp.prepare().then(() => {
// Fallback to NextJS request handling for everything else.
app.all('*', (req: express.Request, res: express.Response) => {
return handle(req, res);
});
// Create a WebSocket server that shares the same HTTP server.
const wss = new WebSocketServer({
noServer: true,
path: '/api/ws',
});
// Attach the TRPC WebSocket handler.
const handler = applyWSSHandler({
wss,
router: appRouter,
createContext: createWSContext,
});
wss.on('connection', (ws) => {
console.log(` Got new websocket connection (now ${wss.clients.size})`);
ws.once('close', () => {
console.log(` Closed websocket connection (now ${wss.clients.size})`);
});
});
wss.on('error', function (error) {
console.log(error);
});
const port = process.env.PORT || 3000;
server.listen(port, () => {
console.log(`> Server listening on http://localhost:${port}`);
console.log(`> TRPC WebSocket server listening at ws://localhost:${port}/api/ws`);
});
app.all('*', (req: express.Request, res: express.Response) => {
return handle(req, res);
});
server.on('upgrade', (request, socket, head) => {
const { pathname } = parse(request.url!);
// Only handle WebSocket upgrades of the specific path(s) your application
// needs to handle
if (pathname === "/api/ws") {
wss.handleUpgrade(request, socket, head, function done(ws) {
console.log("Socket connected");
// At this point, you have the WebSocket in `ws`
// and the original HTTP request in `request` available
ws.send("Hello from Lifetracker!");
});
}
});
// Handle graceful shutdown.
process.on('SIGTERM', () => {
console.log('SIGTERM received, shutting down gracefully.');
handler.broadcastReconnectNotification();
server.close();
});
});

31
apps/web/server/api/ws.ts Normal file
View File

@ -0,0 +1,31 @@
import { inferAsyncReturnType } from '@trpc/server';
import { CreateWSSContextFnOptions } from '@trpc/server/adapters/ws';
import { Session } from 'next-auth';
// Base context - available in all requests
interface CreateContextOptions {
session: Session | null;
req?: Request;
}
// Helper to create base context
const createContextInner = async (opts: CreateContextOptions) => {
return {
session: opts.session,
// Add any other context properties you need
};
};
// Context for WebSocket connections
export const createWSContext = async (opts: CreateWSSContextFnOptions) => {
// Get session from WebSocket connection
// You'll need to implement your session extraction logic here
const session = null; // Replace with actual session extraction
return await createContextInner({
session,
req: opts.req,
});
};
export type Context = inferAsyncReturnType<typeof createWSContext>;

193
pnpm-lock.yaml generated
View File

@ -322,6 +322,9 @@ importers:
drizzle-orm: drizzle-orm:
specifier: ^0.33.0 specifier: ^0.33.0
version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7) version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7)
express:
specifier: ^4.21.2
version: 4.21.2
fastest-levenshtein: fastest-levenshtein:
specifier: ^1.0.16 specifier: ^1.0.16
version: 1.0.16 version: 1.0.16
@ -343,6 +346,9 @@ importers:
next-themes: next-themes:
specifier: ^0.3.0 specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-ws:
specifier: ^1.2.0
version: 1.2.0(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(ws@8.18.0)
pg-dump-restore: pg-dump-restore:
specifier: ^1.0.12 specifier: ^1.0.12
version: 1.0.12 version: 1.0.12
@ -418,6 +424,9 @@ importers:
title-case: title-case:
specifier: ^4.3.2 specifier: ^4.3.2
version: 4.3.2 version: 4.3.2
ws:
specifier: ^8.18.0
version: 8.18.0
zod: zod:
specifier: ^3.22.4 specifier: ^3.22.4
version: 3.23.8 version: 3.23.8
@ -443,6 +452,9 @@ importers:
'@types/emoji-mart': '@types/emoji-mart':
specifier: ^3.0.14 specifier: ^3.0.14
version: 3.0.14 version: 3.0.14
'@types/express':
specifier: ^5.0.0
version: 5.0.0
'@types/react': '@types/react':
specifier: ^18.2.55 specifier: ^18.2.55
version: 18.2.61 version: 18.2.61
@ -458,6 +470,9 @@ importers:
'@types/request-ip': '@types/request-ip':
specifier: ^0.0.41 specifier: ^0.0.41
version: 0.0.41 version: 0.0.41
'@types/ws':
specifier: ^8.5.14
version: 8.5.14
autoprefixer: autoprefixer:
specifier: ^10.4.17 specifier: ^10.4.17
version: 10.4.20(postcss@8.4.47) version: 10.4.20(postcss@8.4.47)
@ -4335,6 +4350,9 @@ packages:
'@types/express@4.17.21': '@types/express@4.17.21':
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
'@types/express@5.0.0':
resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==}
'@types/formidable@3.4.5': '@types/formidable@3.4.5':
resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==} resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==}
@ -4524,6 +4542,9 @@ packages:
'@types/ws@8.5.12': '@types/ws@8.5.12':
resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==}
'@types/ws@8.5.14':
resolution: {integrity: sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==}
'@types/yargs-parser@21.0.3': '@types/yargs-parser@21.0.3':
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
@ -5857,6 +5878,10 @@ packages:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
cookie@0.7.1:
resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
cookie@0.7.2: cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -7020,6 +7045,10 @@ packages:
resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==}
engines: {node: '>= 0.10.0'} engines: {node: '>= 0.10.0'}
express@4.21.2:
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
engines: {node: '>= 0.10.0'}
extend-shallow@2.0.1: extend-shallow@2.0.1:
resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -9261,6 +9290,13 @@ packages:
react: ^16.8 || ^17 || ^18 react: ^16.8 || ^17 || ^18
react-dom: ^16.8 || ^17 || ^18 react-dom: ^16.8 || ^17 || ^18
next-ws@1.2.0:
resolution: {integrity: sha512-cDyMZ4GxpRe3NrZ8fGIet7Q8IcXfU5PUZdYXVlvj9hQqiJlZsby98G8S++icOUfDuEAVyPSwy4de0tFmKBPL9w==}
peerDependencies:
next: '>=13.1.1'
react: '*'
ws: '*'
next@15.1.6: next@15.1.6:
resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==} resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
@ -9711,6 +9747,9 @@ packages:
path-to-regexp@0.1.10: path-to-regexp@0.1.10:
resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==}
path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
path-to-regexp@1.9.0: path-to-regexp@1.9.0:
resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==}
@ -16679,7 +16718,7 @@ snapshots:
'@jridgewell/trace-mapping@0.3.9': '@jridgewell/trace-mapping@0.3.9':
dependencies: dependencies:
'@jridgewell/resolve-uri': 3.1.1 '@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.5.0
'@juggle/resize-observer@3.4.0': {} '@juggle/resize-observer@3.4.0': {}
@ -18106,6 +18145,13 @@ snapshots:
'@types/qs': 6.9.16 '@types/qs': 6.9.16
'@types/serve-static': 1.15.7 '@types/serve-static': 1.15.7
'@types/express@5.0.0':
dependencies:
'@types/body-parser': 1.19.5
'@types/express-serve-static-core': 5.0.0
'@types/qs': 6.9.16
'@types/serve-static': 1.15.7
'@types/formidable@3.4.5': '@types/formidable@3.4.5':
dependencies: dependencies:
'@types/node': 20.11.24 '@types/node': 20.11.24
@ -18313,6 +18359,10 @@ snapshots:
dependencies: dependencies:
'@types/node': 20.11.24 '@types/node': 20.11.24
'@types/ws@8.5.14':
dependencies:
'@types/node': 20.11.24
'@types/yargs-parser@21.0.3': {} '@types/yargs-parser@21.0.3': {}
'@types/yargs@13.0.12': '@types/yargs@13.0.12':
@ -18893,9 +18943,9 @@ snapshots:
mime-types: 2.1.35 mime-types: 2.1.35
negotiator: 0.6.3 negotiator: 0.6.3
acorn-import-attributes@1.9.5(acorn@8.10.0): acorn-import-attributes@1.9.5(acorn@8.14.0):
dependencies: dependencies:
acorn: 8.10.0 acorn: 8.14.0
acorn-jsx@5.3.2(acorn@8.10.0): acorn-jsx@5.3.2(acorn@8.10.0):
dependencies: dependencies:
@ -19059,7 +19109,7 @@ snapshots:
array-buffer-byte-length@1.0.0: array-buffer-byte-length@1.0.0:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
is-array-buffer: 3.0.2 is-array-buffer: 3.0.2
array-buffer-byte-length@1.0.1: array-buffer-byte-length@1.0.1:
@ -19121,10 +19171,10 @@ snapshots:
arraybuffer.prototype.slice@1.0.2: arraybuffer.prototype.slice@1.0.2:
dependencies: dependencies:
array-buffer-byte-length: 1.0.0 array-buffer-byte-length: 1.0.0
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
is-array-buffer: 3.0.2 is-array-buffer: 3.0.2
is-shared-array-buffer: 1.0.2 is-shared-array-buffer: 1.0.2
@ -20082,6 +20132,8 @@ snapshots:
cookie@0.6.0: {} cookie@0.6.0: {}
cookie@0.7.1: {}
cookie@0.7.2: {} cookie@0.7.2: {}
cookie@1.0.1: {} cookie@1.0.1: {}
@ -20528,7 +20580,7 @@ snapshots:
define-data-property@1.1.1: define-data-property@1.1.1:
dependencies: dependencies:
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
gopd: 1.0.1 gopd: 1.0.1
has-property-descriptors: 1.0.1 has-property-descriptors: 1.0.1
@ -21673,6 +21725,42 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
express@4.21.2:
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
body-parser: 1.20.3
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.7.1
cookie-signature: 1.0.6
debug: 2.6.9
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 1.3.1
fresh: 0.5.2
http-errors: 2.0.0
merge-descriptors: 1.0.3
methods: 1.1.2
on-finished: 2.4.1
parseurl: 1.3.3
path-to-regexp: 0.1.12
proxy-addr: 2.0.7
qs: 6.13.0
range-parser: 1.2.1
safe-buffer: 5.2.1
send: 0.19.0
serve-static: 1.16.2
setprototypeof: 1.2.0
statuses: 2.0.1
type-is: 1.6.18
utils-merge: 1.0.1
vary: 1.1.2
transitivePeerDependencies:
- supports-color
extend-shallow@2.0.1: extend-shallow@2.0.1:
dependencies: dependencies:
is-extendable: 0.1.1 is-extendable: 0.1.1
@ -22005,7 +22093,7 @@ snapshots:
function.prototype.name@1.1.6: function.prototype.name@1.1.6:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
functions-have-names: 1.2.3 functions-have-names: 1.2.3
@ -22041,9 +22129,9 @@ snapshots:
dependencies: dependencies:
es-errors: 1.3.0 es-errors: 1.3.0
function-bind: 1.1.2 function-bind: 1.1.2
has-proto: 1.0.1 has-proto: 1.0.3
has-symbols: 1.0.3 has-symbols: 1.0.3
hasown: 2.0.0 hasown: 2.0.2
get-nonce@1.0.1: {} get-nonce@1.0.1: {}
@ -22067,8 +22155,8 @@ snapshots:
get-symbol-description@1.0.0: get-symbol-description@1.0.0:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
get-symbol-description@1.0.2: get-symbol-description@1.0.2:
dependencies: dependencies:
@ -22219,7 +22307,7 @@ snapshots:
gopd@1.0.1: gopd@1.0.1:
dependencies: dependencies:
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
got@12.6.1: got@12.6.1:
dependencies: dependencies:
@ -22295,8 +22383,7 @@ snapshots:
has-proto@1.0.1: {} has-proto@1.0.1: {}
has-proto@1.0.3: has-proto@1.0.3: {}
optional: true
has-symbols@1.0.3: {} has-symbols@1.0.3: {}
@ -22321,7 +22408,6 @@ snapshots:
hasown@2.0.2: hasown@2.0.2:
dependencies: dependencies:
function-bind: 1.1.2 function-bind: 1.1.2
optional: true
hast-util-from-parse5@8.0.1: hast-util-from-parse5@8.0.1:
dependencies: dependencies:
@ -22758,7 +22844,7 @@ snapshots:
dependencies: dependencies:
get-intrinsic: 1.2.2 get-intrinsic: 1.2.2
hasown: 2.0.0 hasown: 2.0.0
side-channel: 1.0.4 side-channel: 1.0.6
internal-slot@1.0.7: internal-slot@1.0.7:
dependencies: dependencies:
@ -22802,8 +22888,8 @@ snapshots:
is-array-buffer@3.0.2: is-array-buffer@3.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
is-typed-array: 1.1.12 is-typed-array: 1.1.12
is-array-buffer@3.0.4: is-array-buffer@3.0.4:
@ -22830,7 +22916,7 @@ snapshots:
is-boolean-object@1.1.2: is-boolean-object@1.1.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0
is-buffer@1.1.6: is-buffer@1.1.6:
@ -22878,7 +22964,7 @@ snapshots:
is-finalizationregistry@1.0.2: is-finalizationregistry@1.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@3.0.0: {}
@ -22971,7 +23057,7 @@ snapshots:
is-regex@1.1.4: is-regex@1.1.4:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0
is-regexp@1.0.0: {} is-regexp@1.0.0: {}
@ -22982,7 +23068,7 @@ snapshots:
is-shared-array-buffer@1.0.2: is-shared-array-buffer@1.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
is-shared-array-buffer@1.0.3: is-shared-array-buffer@1.0.3:
dependencies: dependencies:
@ -23030,12 +23116,12 @@ snapshots:
is-weakref@1.0.2: is-weakref@1.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
is-weakset@2.0.2: is-weakset@2.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
is-what@4.1.16: {} is-what@4.1.16: {}
@ -24536,6 +24622,12 @@ snapshots:
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
next-ws@1.2.0(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(ws@8.18.0):
dependencies:
next: 15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
ws: 8.18.0
next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
'@next/env': 15.1.6 '@next/env': 15.1.6
@ -24711,8 +24803,7 @@ snapshots:
object-inspect@1.13.1: {} object-inspect@1.13.1: {}
object-inspect@1.13.2: object-inspect@1.13.2: {}
optional: true
object-keys@1.1.1: {} object-keys@1.1.1: {}
@ -25076,6 +25167,8 @@ snapshots:
path-to-regexp@0.1.10: {} path-to-regexp@0.1.10: {}
path-to-regexp@0.1.12: {}
path-to-regexp@1.9.0: path-to-regexp@1.9.0:
dependencies: dependencies:
isarray: 0.0.1 isarray: 0.0.1
@ -26319,10 +26412,10 @@ snapshots:
reflect.getprototypeof@1.0.4: reflect.getprototypeof@1.0.4:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
globalthis: 1.0.3 globalthis: 1.0.3
which-builtin-type: 1.1.3 which-builtin-type: 1.1.3
@ -26699,8 +26792,8 @@ snapshots:
safe-regex-test@1.0.0: safe-regex-test@1.0.0:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
is-regex: 1.1.4 is-regex: 1.1.4
safe-regex-test@1.0.3: safe-regex-test@1.0.3:
@ -26866,7 +26959,7 @@ snapshots:
set-function-length@1.1.1: set-function-length@1.1.1:
dependencies: dependencies:
define-data-property: 1.1.1 define-data-property: 1.1.1
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
gopd: 1.0.1 gopd: 1.0.1
has-property-descriptors: 1.0.1 has-property-descriptors: 1.0.1
@ -26969,7 +27062,7 @@ snapshots:
call-bind: 1.0.7 call-bind: 1.0.7
es-errors: 1.3.0 es-errors: 1.3.0
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
object-inspect: 1.13.1 object-inspect: 1.13.2
siginfo@2.0.0: {} siginfo@2.0.0: {}
@ -27227,7 +27320,7 @@ snapshots:
string.prototype.trim@1.2.8: string.prototype.trim@1.2.8:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
@ -27241,7 +27334,7 @@ snapshots:
string.prototype.trimend@1.0.7: string.prototype.trimend@1.0.7:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
@ -27254,7 +27347,7 @@ snapshots:
string.prototype.trimstart@1.0.7: string.prototype.trimstart@1.0.7:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
define-properties: 1.2.1 define-properties: 1.2.1
es-abstract: 1.22.3 es-abstract: 1.22.3
@ -27692,8 +27785,8 @@ snapshots:
'@tsconfig/node14': 1.0.3 '@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4 '@tsconfig/node16': 1.0.4
'@types/node': 20.11.24 '@types/node': 20.11.24
acorn: 8.10.0 acorn: 8.14.0
acorn-walk: 8.2.0 acorn-walk: 8.3.4
arg: 4.1.3 arg: 4.1.3
create-require: 1.1.1 create-require: 1.1.1
diff: 4.0.2 diff: 4.0.2
@ -27806,8 +27899,8 @@ snapshots:
typed-array-buffer@1.0.0: typed-array-buffer@1.0.0:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
get-intrinsic: 1.2.2 get-intrinsic: 1.2.4
is-typed-array: 1.1.12 is-typed-array: 1.1.12
typed-array-buffer@1.0.2: typed-array-buffer@1.0.2:
@ -27819,7 +27912,7 @@ snapshots:
typed-array-byte-length@1.0.0: typed-array-byte-length@1.0.0:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
for-each: 0.3.3 for-each: 0.3.3
has-proto: 1.0.1 has-proto: 1.0.1
is-typed-array: 1.1.12 is-typed-array: 1.1.12
@ -27836,7 +27929,7 @@ snapshots:
typed-array-byte-offset@1.0.0: typed-array-byte-offset@1.0.0:
dependencies: dependencies:
available-typed-arrays: 1.0.5 available-typed-arrays: 1.0.5
call-bind: 1.0.5 call-bind: 1.0.7
for-each: 0.3.3 for-each: 0.3.3
has-proto: 1.0.1 has-proto: 1.0.1
is-typed-array: 1.1.12 is-typed-array: 1.1.12
@ -27853,7 +27946,7 @@ snapshots:
typed-array-length@1.0.4: typed-array-length@1.0.4:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
for-each: 0.3.3 for-each: 0.3.3
is-typed-array: 1.1.12 is-typed-array: 1.1.12
@ -27894,7 +27987,7 @@ snapshots:
unbox-primitive@1.0.2: unbox-primitive@1.0.2:
dependencies: dependencies:
call-bind: 1.0.5 call-bind: 1.0.7
has-bigints: 1.0.2 has-bigints: 1.0.2
has-symbols: 1.0.3 has-symbols: 1.0.3
which-boxed-primitive: 1.0.2 which-boxed-primitive: 1.0.2
@ -28421,13 +28514,13 @@ snapshots:
webpack@5.95.0: webpack@5.95.0:
dependencies: dependencies:
'@types/estree': 1.0.5 '@types/estree': 1.0.6
'@webassemblyjs/ast': 1.12.1 '@webassemblyjs/ast': 1.12.1
'@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-edit': 1.12.1
'@webassemblyjs/wasm-parser': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1
acorn: 8.10.0 acorn: 8.14.0
acorn-import-attributes: 1.9.5(acorn@8.10.0) acorn-import-attributes: 1.9.5(acorn@8.14.0)
browserslist: 4.22.1 browserslist: 4.24.2
chrome-trace-event: 1.0.4 chrome-trace-event: 1.0.4
enhanced-resolve: 5.17.1 enhanced-resolve: 5.17.1
es-module-lexer: 1.5.4 es-module-lexer: 1.5.4
@ -28524,7 +28617,7 @@ snapshots:
which-typed-array@1.1.13: which-typed-array@1.1.13:
dependencies: dependencies:
available-typed-arrays: 1.0.5 available-typed-arrays: 1.0.5
call-bind: 1.0.5 call-bind: 1.0.7
for-each: 0.3.3 for-each: 0.3.3
gopd: 1.0.1 gopd: 1.0.1
has-tostringtag: 1.0.0 has-tostringtag: 1.0.0