From 85efb0478ccc8290e5990f568a34b78ba423c51b Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 6 Feb 2025 13:02:34 -0800 Subject: [PATCH] Baby's first websocket response --- .../web/components/dashboard/days/DayView.tsx | 1 - apps/web/lib/trpc.tsx | 20 +- apps/web/package.json | 7 +- apps/web/server.ts | 86 ++++++++ apps/web/server/api/ws.ts | 31 +++ pnpm-lock.yaml | 193 +++++++++++++----- 6 files changed, 285 insertions(+), 53 deletions(-) create mode 100644 apps/web/server.ts create mode 100644 apps/web/server/api/ws.ts diff --git a/apps/web/components/dashboard/days/DayView.tsx b/apps/web/components/dashboard/days/DayView.tsx index bf1d188..8491369 100644 --- a/apps/web/components/dashboard/days/DayView.tsx +++ b/apps/web/components/dashboard/days/DayView.tsx @@ -59,7 +59,6 @@ export default function DayView({ return (
-
(); + +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 }), + }), + ], +}); diff --git a/apps/web/package.json b/apps/web/package.json index 48eebf0..5afd485 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -5,7 +5,7 @@ "private": true, "type": "module", "scripts": { - "dev": "next dev", + "dev": "tsx server.ts", "clean": "git clean -xdf .next .turbo node_modules", "build": "next build -d", "start": "next start", @@ -71,6 +71,7 @@ "date-fns": "^4.1.0", "dayjs": "^1.11.13", "drizzle-orm": "^0.33.0", + "express": "^4.21.2", "fastest-levenshtein": "^1.0.16", "formidable": "^3.5.2", "lucide-react": "latest", @@ -78,6 +79,7 @@ "next-auth": "^4.24.5", "next-pwa": "^5.6.0", "next-themes": "^0.3.0", + "next-ws": "^1.2.0", "pg-dump-restore": "^1.0.12", "prettier": "^3.2.5", "react": "^18.2.0", @@ -103,6 +105,7 @@ "superjson": "^2.2.1", "tailwind-merge": "^2.2.1", "title-case": "^4.3.2", + "ws": "^8.18.0", "zod": "^3.22.4", "zustand": "^4.5.1" }, @@ -113,11 +116,13 @@ "@lifetracker/typescript-config": "workspace:^0.1.0", "@types/csv-parse": "^1.2.5", "@types/emoji-mart": "^3.0.14", + "@types/express": "^5.0.0", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@types/react-syntax-highlighter": "^15.5.13", "@types/regression": "^2.0.6", "@types/request-ip": "^0.0.41", + "@types/ws": "^8.5.14", "autoprefixer": "^10.4.17", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", diff --git a/apps/web/server.ts b/apps/web/server.ts new file mode 100644 index 0000000..1470302 --- /dev/null +++ b/apps/web/server.ts @@ -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(); + }); +}); diff --git a/apps/web/server/api/ws.ts b/apps/web/server/api/ws.ts new file mode 100644 index 0000000..61cf5a8 --- /dev/null +++ b/apps/web/server/api/ws.ts @@ -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; \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c97058..9550867 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -322,6 +322,9 @@ importers: drizzle-orm: 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) + express: + specifier: ^4.21.2 + version: 4.21.2 fastest-levenshtein: specifier: ^1.0.16 version: 1.0.16 @@ -343,6 +346,9 @@ importers: next-themes: specifier: ^0.3.0 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: specifier: ^1.0.12 version: 1.0.12 @@ -418,6 +424,9 @@ importers: title-case: specifier: ^4.3.2 version: 4.3.2 + ws: + specifier: ^8.18.0 + version: 8.18.0 zod: specifier: ^3.22.4 version: 3.23.8 @@ -443,6 +452,9 @@ importers: '@types/emoji-mart': specifier: ^3.0.14 version: 3.0.14 + '@types/express': + specifier: ^5.0.0 + version: 5.0.0 '@types/react': specifier: ^18.2.55 version: 18.2.61 @@ -458,6 +470,9 @@ importers: '@types/request-ip': specifier: ^0.0.41 version: 0.0.41 + '@types/ws': + specifier: ^8.5.14 + version: 8.5.14 autoprefixer: specifier: ^10.4.17 version: 10.4.20(postcss@8.4.47) @@ -4335,6 +4350,9 @@ packages: '@types/express@4.17.21': resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + '@types/express@5.0.0': + resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==} + '@types/formidable@3.4.5': resolution: {integrity: sha512-s7YPsNVfnsng5L8sKnG/Gbb2tiwwJTY1conOkJzTMRvJAlLFW1nEua+ADsJQu8N1c0oTHx9+d5nqg10WuT9gHQ==} @@ -4524,6 +4542,9 @@ packages: '@types/ws@8.5.12': 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': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -5857,6 +5878,10 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -7020,6 +7045,10 @@ packages: resolution: {integrity: sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==} 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: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -9261,6 +9290,13 @@ packages: react: ^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: resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} @@ -9711,6 +9747,9 @@ packages: path-to-regexp@0.1.10: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@1.9.0: resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} @@ -16679,7 +16718,7 @@ snapshots: '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@juggle/resize-observer@3.4.0': {} @@ -18106,6 +18145,13 @@ snapshots: '@types/qs': 6.9.16 '@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': dependencies: '@types/node': 20.11.24 @@ -18313,6 +18359,10 @@ snapshots: dependencies: '@types/node': 20.11.24 + '@types/ws@8.5.14': + dependencies: + '@types/node': 20.11.24 + '@types/yargs-parser@21.0.3': {} '@types/yargs@13.0.12': @@ -18893,9 +18943,9 @@ snapshots: mime-types: 2.1.35 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: - acorn: 8.10.0 + acorn: 8.14.0 acorn-jsx@5.3.2(acorn@8.10.0): dependencies: @@ -19059,7 +19109,7 @@ snapshots: array-buffer-byte-length@1.0.0: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-array-buffer: 3.0.2 array-buffer-byte-length@1.0.1: @@ -19121,10 +19171,10 @@ snapshots: arraybuffer.prototype.slice@1.0.2: dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 @@ -20082,6 +20132,8 @@ snapshots: cookie@0.6.0: {} + cookie@0.7.1: {} + cookie@0.7.2: {} cookie@1.0.1: {} @@ -20528,7 +20580,7 @@ snapshots: define-data-property@1.1.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -21673,6 +21725,42 @@ snapshots: transitivePeerDependencies: - 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: dependencies: is-extendable: 0.1.1 @@ -22005,7 +22093,7 @@ snapshots: function.prototype.name@1.1.6: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 functions-have-names: 1.2.3 @@ -22041,9 +22129,9 @@ snapshots: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.2 get-nonce@1.0.1: {} @@ -22067,8 +22155,8 @@ snapshots: get-symbol-description@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 get-symbol-description@1.0.2: dependencies: @@ -22219,7 +22307,7 @@ snapshots: gopd@1.0.1: dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 got@12.6.1: dependencies: @@ -22295,8 +22383,7 @@ snapshots: has-proto@1.0.1: {} - has-proto@1.0.3: - optional: true + has-proto@1.0.3: {} has-symbols@1.0.3: {} @@ -22321,7 +22408,6 @@ snapshots: hasown@2.0.2: dependencies: function-bind: 1.1.2 - optional: true hast-util-from-parse5@8.0.1: dependencies: @@ -22758,7 +22844,7 @@ snapshots: dependencies: get-intrinsic: 1.2.2 hasown: 2.0.0 - side-channel: 1.0.4 + side-channel: 1.0.6 internal-slot@1.0.7: dependencies: @@ -22802,8 +22888,8 @@ snapshots: is-array-buffer@3.0.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 is-array-buffer@3.0.4: @@ -22830,7 +22916,7 @@ snapshots: is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.0 is-buffer@1.1.6: @@ -22878,7 +22964,7 @@ snapshots: is-finalizationregistry@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-fullwidth-code-point@3.0.0: {} @@ -22971,7 +23057,7 @@ snapshots: is-regex@1.1.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-tostringtag: 1.0.0 is-regexp@1.0.0: {} @@ -22982,7 +23068,7 @@ snapshots: is-shared-array-buffer@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-shared-array-buffer@1.0.3: dependencies: @@ -23030,12 +23116,12 @@ snapshots: is-weakref@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 is-weakset@2.0.2: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-what@4.1.16: {} @@ -24536,6 +24622,12 @@ snapshots: 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): dependencies: '@next/env': 15.1.6 @@ -24711,8 +24803,7 @@ snapshots: object-inspect@1.13.1: {} - object-inspect@1.13.2: - optional: true + object-inspect@1.13.2: {} object-keys@1.1.1: {} @@ -25076,6 +25167,8 @@ snapshots: path-to-regexp@0.1.10: {} + path-to-regexp@0.1.12: {} + path-to-regexp@1.9.0: dependencies: isarray: 0.0.1 @@ -26319,10 +26412,10 @@ snapshots: reflect.getprototypeof@1.0.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 @@ -26699,8 +26792,8 @@ snapshots: safe-regex-test@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-regex: 1.1.4 safe-regex-test@1.0.3: @@ -26866,7 +26959,7 @@ snapshots: set-function-length@1.1.1: dependencies: define-data-property: 1.1.1 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -26969,7 +27062,7 @@ snapshots: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - object-inspect: 1.13.1 + object-inspect: 1.13.2 siginfo@2.0.0: {} @@ -27227,7 +27320,7 @@ snapshots: string.prototype.trim@1.2.8: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -27241,7 +27334,7 @@ snapshots: string.prototype.trimend@1.0.7: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -27254,7 +27347,7 @@ snapshots: string.prototype.trimstart@1.0.7: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.3 @@ -27692,8 +27785,8 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 20.11.24 - acorn: 8.10.0 - acorn-walk: 8.2.0 + acorn: 8.14.0 + acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -27806,8 +27899,8 @@ snapshots: typed-array-buffer@1.0.0: dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-typed-array: 1.1.12 typed-array-buffer@1.0.2: @@ -27819,7 +27912,7 @@ snapshots: typed-array-byte-length@1.0.0: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -27836,7 +27929,7 @@ snapshots: typed-array-byte-offset@1.0.0: dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -27853,7 +27946,7 @@ snapshots: typed-array-length@1.0.4: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 is-typed-array: 1.1.12 @@ -27894,7 +27987,7 @@ snapshots: unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -28421,13 +28514,13 @@ snapshots: webpack@5.95.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 '@webassemblyjs/ast': 1.12.1 '@webassemblyjs/wasm-edit': 1.12.1 '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.10.0 - acorn-import-attributes: 1.9.5(acorn@8.10.0) - browserslist: 4.22.1 + acorn: 8.14.0 + acorn-import-attributes: 1.9.5(acorn@8.14.0) + browserslist: 4.24.2 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.1 es-module-lexer: 1.5.4 @@ -28524,7 +28617,7 @@ snapshots: which-typed-array@1.1.13: dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0