diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/README.md b/README.md index d989cc1..2f651e4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ -> [!IMPORTANT] -> This repository uses the Ably Pub/Sub approach for building chat apps. We now offer Ably Chat—a new family of SDKs and APIs that streamline development and manage realtime chat complexity for you. For a modern, easier way to create chat experiences, visit our [Ably Chat documentation](https://ably.com/docs/chat). - -# Building a Realtime Chat App with Next.js, Ably, and Vercel +# Building a realtime chat app with Next.js, Ably Chat, and Vercel Live example at: @@ -13,8 +10,8 @@ This is a demo chat application with [Next.js](https://nextjs.org/) using [Ably] It demonstrates the use of: -- Pub/sub messaging -- Ably's React Hooks +- [Ably Chat SDK](https://github.com/ably/ably-chat-js) for messaging +- [Ably Chat React hooks](https://ably.com/docs/chat/setup?lang=react) (`useMessages`, `useChatClient`) - Token authentication with Ably ## Tech stack @@ -23,7 +20,7 @@ The project uses the following components: - [Next.js](https://nextjs.org/) is a React framework from [Vercel](https://vercel.com/). It is used to build static web applications with server side rendering, serverless functions and seamless hosting. It's a framework that takes the React knowledge you already have, and puts some structure and conventions in place. -- [Ably](https://ably.com/) is realtime, pub/sub messaging platform with a suite of integrated services to deliver complete realtime functionality directly to end-users. +- [Ably Chat](https://ably.com/docs/chat) is a set of SDKs built on top of Ably's realtime platform, designed for building chat experiences with minimal setup. - [Vercel](https://vercel.com/) is a hosting platform, built from the ground up to host Next.js apps, and Serverless Functions with them. @@ -34,7 +31,7 @@ The project uses the following components: ![The UI of the chat app we'll build. It is a window with speech bubbles for text.](https://cdn.glitch.com/0cb30add-c9ef-4c00-983c-e12deb0d4080%2Fchatapp.png?v=1612279601157) *The UI of the app we'll build with this walkthrough* -We'll build a realtime chat app that runs in the browser. It will be built upon the Next.js [create-next-app](https://nextjs.org/docs/api-reference/create-next-app) template, it will contain a React component which will use Ably to send and receive messages. We'll also write a Next.js serverless function which will be used to connect to Ably. +We'll build a realtime chat app that runs in the browser. It will be built upon the Next.js [create-next-app](https://nextjs.org/docs/api-reference/create-next-app) template, it will contain a React component which will use the Ably Chat SDK to send and receive messages. We'll also write a Next.js [Route Handler](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) which will be used to authenticate with Ably. ## Building & running locally @@ -44,7 +41,7 @@ In order to build and deploy this app, you will need: - **An Ably account** for sending messages: [Create an account with Ably for free](https://ably.com/signup). - **A Vercel Account** for hosting on production: [Create an account with Vercel for free](https://vercel.com/signup). -- **Node 16** or greater: [Install Node](https://nodejs.org/en/). +- **Node 20** or greater: [Install Node](https://nodejs.org/en/). You'll also need an API key from Ably to authenticate with the Ably Service. To get an API key, once you have [created an Ably account](https://ably.com/signup): diff --git a/app/layout.js b/app/layout.js index 6e26cc1..eab61d0 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,8 +1,11 @@ import './globals.css'; export const metadata = { - title: 'Next.js', - description: 'Generated by Next.js', + title: 'Realtime Chat App with Ably, NextJS and Vercel', + description: 'A demo chat application with Next.js using Ably Chat', + icons: { + icon: { url: 'https://static.ably.dev/motif-red.svg?nextjs-vercel', type: 'image/svg+xml' }, + }, }; export default function RootLayout({ children }) { diff --git a/app/page.js b/app/page.js index ceb0612..9f39c7d 100644 --- a/app/page.js +++ b/app/page.js @@ -1,18 +1,8 @@ -import Head from 'next/head'; -import dynamic from 'next/dynamic'; - -const Chat = dynamic(() => import('../components/Chat'), { - ssr: false, -}); +import Chat from '../components/Chat'; export default function Home() { return (
- - Realtime Chat App with Ably, NextJS and Vercel - - -

Next.js Chat Demo

diff --git a/components/Chat.jsx b/components/Chat.jsx index d8f64fd..571c6fc 100644 --- a/components/Chat.jsx +++ b/components/Chat.jsx @@ -1,21 +1,30 @@ 'use client'; +import { useEffect, useState } from 'react'; import * as Ably from 'ably'; import { ChatClient } from '@ably/chat'; import { ChatClientProvider, ChatRoomProvider } from '@ably/chat/react'; import ChatBox from './ChatBox.jsx'; -const roomOptions = { - history: { limit: 50 }, -}; +const roomOptions = {}; export default function Chat() { - const realtimeClient = new Ably.Realtime({ authUrl: '/api' }); - const chatClient = new ChatClient(realtimeClient); + const [chatClient, setChatClient] = useState(null); + + useEffect(() => { + const realtimeClient = new Ably.Realtime({ authUrl: '/api' }); + const client = new ChatClient(realtimeClient); + setChatClient(client); + return () => { + realtimeClient.close(); + }; + }, []); + + if (!chatClient) return
Loading...
; return ( - + diff --git a/components/ChatBox.jsx b/components/ChatBox.jsx index 83a5a0a..58807af 100644 --- a/components/ChatBox.jsx +++ b/components/ChatBox.jsx @@ -10,23 +10,14 @@ export default function ChatBox() { const [messages, setMessages] = useState([]); const messageTextIsEmpty = messageText.trim().length === 0; - const { send: sendMessage } = useMessages({ + const { sendMessage } = useMessages({ listener: (payload) => { const newMessage = payload.message; setMessages((prevMessages) => { - if (prevMessages.some((existingMessage) => existingMessage.isSameAs(newMessage))) { + if (prevMessages.some((existingMessage) => existingMessage.serial === newMessage.serial)) { return prevMessages; } - - const index = prevMessages.findIndex((existingMessage) => existingMessage.after(newMessage)); - - const newMessages = [...prevMessages]; - if (index === -1) { - newMessages.push(newMessage); - } else { - newMessages.splice(index, 0, newMessage); - } - return newMessages; + return [...prevMessages, newMessage].sort((a, b) => (a.serial < b.serial ? -1 : b.serial < a.serial ? 1 : 0)); }); }, }); diff --git a/package-lock.json b/package-lock.json index 69087d7..12b9c7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "ably-nextjs-vercel-demo", "version": "0.1.0", "dependencies": { - "@ably/chat": "^0.6.0", - "ably": "2.8.0", + "@ably/chat": "^1.3.1", + "ably": "^2.21.0", "next": "^14.2.3", "react": "^18.2.0", "react-dom": "^18.2.0" @@ -21,9 +21,9 @@ } }, "node_modules/@ably/chat": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@ably/chat/-/chat-0.6.0.tgz", - "integrity": "sha512-LS44zVRJkp05i0nRJ31JBOR+Usqp9hUtsaLZ0FroW/FrnXOMoKh0XHywGthLjmRWqH0LUmCaGvomM3pfZ/Rwxw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ably/chat/-/chat-1.3.1.tgz", + "integrity": "sha512-dbhsIz9g2cDzAWv7TvTpEZlKD+xGh+SedZw74QwhmaNjZA/ieB4401ScN/poWLAaGahkXzB2hP2DzeSl4qkDOA==", "license": "Apache-2.0", "dependencies": { "async-mutex": "^0.5.0", @@ -31,14 +31,14 @@ "lodash.clonedeep": "^4.5.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "optionalDependencies": { "@rollup/rollup-darwin-arm64": "^4.18", "@rollup/rollup-linux-x64-gnu": "^4.18" }, "peerDependencies": { - "ably": "^2.6.3", + "ably": "^2.19.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, @@ -52,9 +52,10 @@ } }, "node_modules/@ably/msgpack-js": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@ably/msgpack-js/-/msgpack-js-0.4.0.tgz", - "integrity": "sha512-IPt/BoiQwCWubqoNik1aw/6M/DleMdrxJOUpSja6xmMRbT2p1TA8oqKWgfZabqzrq8emRNeSl/+4XABPNnW5pQ==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@ably/msgpack-js/-/msgpack-js-0.4.1.tgz", + "integrity": "sha512-Sjxj6SOr17hExAVrsycN7u6oV4PhZcK7Z2S8dM71CH/butgO47cSo/TL6FJPCXUyDAzKkOWjMUpJGyZkEpyu4Q==", + "license": "Apache-2.0", "dependencies": { "bops": "^1.0.1" } @@ -380,6 +381,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -405,6 +407,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -416,6 +419,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "license": "MIT", "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", @@ -424,9 +428,10 @@ } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "license": "MIT" }, "node_modules/@types/json5": { "version": "0.0.29", @@ -438,22 +443,25 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.19.0" } }, "node_modules/@types/responselike": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -592,12 +600,13 @@ "dev": true }, "node_modules/ably": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/ably/-/ably-2.8.0.tgz", - "integrity": "sha512-JhOwtrbqtUR+n95jsY0syS8rIPhI1vDNfcNE1kxPhNkPaxzmYmGCo7g2xjuLZ/d4OoCuhHzX73+AVYAL70L70g==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/ably/-/ably-2.21.0.tgz", + "integrity": "sha512-Zgs3O/hqhnTEoXeV1WxoQeLaww58JbnDVFbVeEDj2kCHeuLPeavTbyf2NQBkxAM3jooN5mILaP0PDm79NOcpKw==", "license": "Apache-2.0", "dependencies": { "@ably/msgpack-js": "^0.4.0", + "dequal": "^2.0.3", "fastestsmallesttextencoderdecoder": "^1.0.22", "got": "^11.8.5", "ulid": "^2.3.0", @@ -921,6 +930,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.2.tgz", "integrity": "sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -929,6 +939,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/bops/-/bops-1.0.1.tgz", "integrity": "sha512-qCMBuZKP36tELrrgXpAfM+gHzqa0nLsWZ+L37ncsb8txYlnAoxOPpVp+g7fK0sGkMXfA0wl8uQkESqw3v4HNag==", + "license": "MIT", "dependencies": { "base64-js": "1.0.2", "to-utf8": "0.0.1" @@ -971,6 +982,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "license": "MIT", "engines": { "node": ">=10.6.0" } @@ -979,6 +991,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "license": "MIT", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -1064,6 +1077,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" }, @@ -1187,6 +1201,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -1201,6 +1216,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -1218,6 +1234,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", "engines": { "node": ">=10" } @@ -1295,9 +1312,10 @@ "dev": true }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -1946,7 +1964,8 @@ "node_modules/fastestsmallesttextencoderdecoder": { "version": "1.0.22", "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", - "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==" + "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", + "license": "CC0-1.0" }, "node_modules/fastq": { "version": "1.17.1", @@ -2091,6 +2110,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -2229,6 +2249,7 @@ "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.0.0", "@szmarczak/http-timer": "^4.0.5", @@ -2342,14 +2363,16 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.0.0" @@ -2936,6 +2959,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "license": "MIT", "engines": { "node": ">=8" } @@ -2966,6 +2990,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "license": "MIT", "engines": { "node": ">=4" } @@ -3073,6 +3098,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3234,6 +3260,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -3411,9 +3438,10 @@ } }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -3452,6 +3480,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3553,7 +3582,8 @@ "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", @@ -3577,6 +3607,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "license": "MIT", "dependencies": { "lowercase-keys": "^2.0.0" }, @@ -3967,7 +3998,8 @@ "node_modules/to-utf8": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", - "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==" + "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==", + "license": "MIT" }, "node_modules/ts-api-utils": { "version": "1.3.0", @@ -4134,9 +4166,10 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", @@ -4256,9 +4289,9 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 859bafb..dd2ed85 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "ably-nextjs-vercel-demo", "version": "0.1.0", "private": true, + "engines": { + "node": ">=20" + }, "scripts": { "dev": "next dev", "build": "next build", @@ -12,8 +15,8 @@ "format:check": "prettier --check --ignore-path .gitignore app components" }, "dependencies": { - "@ably/chat": "^0.6.0", - "ably": "2.8.0", + "@ably/chat": "^1.3.1", + "ably": "^2.21.0", "next": "^14.2.3", "react": "^18.2.0", "react-dom": "^18.2.0"