Adding with-ably example for realtime messaging in next apps (#37319)
* update from latest canary * lint-fix
This commit is contained in:
parent
4df0778ce8
commit
bbffaea755
15 changed files with 492 additions and 0 deletions
33
examples/with-ably/.gitignore
vendored
Normal file
33
examples/with-ably/.gitignore
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
.env
|
||||
|
||||
# vercel
|
||||
.vercel
|
136
examples/with-ably/README.md
Normal file
136
examples/with-ably/README.md
Normal file
|
@ -0,0 +1,136 @@
|
|||
# Realtime Edge Messaging with [Ably](https://ably.com/)
|
||||
|
||||
**Demo:** [https://next-and-ably.vercel.app/](https://next-and-ably.vercel.app/)
|
||||
|
||||
Add realtime data and interactive multi-user experiences to your Next.js apps with [Ably](https://ably.com/), without the infrastructure overhead.
|
||||
|
||||
Use Ably in your Next.js application using idiomatic, easy to use hooks.
|
||||
|
||||
Using this demo you can:
|
||||
|
||||
- [Send and receive](https://ably.com/docs/realtime/messages) realtime messages
|
||||
- Get notifications of [user presence](https://ably.com/docs/realtime/presence) on channels
|
||||
- Send [presence updates](https://ably.com/docs/api/realtime-sdk/presence#update) when a new client joins or leaves the demo
|
||||
|
||||
This demo is uses the [Ably React Hooks package](https://www.npmjs.com/package/@ably-labs/react-hooks), a simplified syntax for interacting with Ably, which manages the lifecycle of the Ably SDK instances for you taking care to subscribe and unsubscribe to channels and events when your components re-render).
|
||||
|
||||
## Deploy your own
|
||||
|
||||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-ably)
|
||||
|
||||
**You will need an Ably API key to run this demo, [see below for details](#ably-setup)**
|
||||
|
||||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-ably&project-name=with-ably&repository-name=with-ably)
|
||||
|
||||
## How to use
|
||||
|
||||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
|
||||
|
||||
```bash
|
||||
npx create-next-app --example with-ably with-ably-app
|
||||
# or
|
||||
yarn create next-app --example with-ably with-ably-app
|
||||
# or
|
||||
pnpm create next-app --example with-ably with-ably-app
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
|
||||
|
||||
**When deployed, ensure that you set your environment variables (the Ably API key and the deployed Vercel API root) in your Vercel settings**
|
||||
|
||||
## Notes
|
||||
|
||||
### Ably Setup
|
||||
|
||||
In order to send and receive messages you will need an Ably API key.
|
||||
If you are not already signed up, you can [sign up now for a free Ably account](https://www.ably.com/signup). Once you have an Ably account:
|
||||
|
||||
1. Log into your app dashboard.
|
||||
2. Under **“Your apps”**, click on **“Manage app”** for any app you wish to use for this tutorial, or create a new one with the “Create New App” button.
|
||||
3. Click on the **“API Keys”** tab.
|
||||
4. Copy the secret **“API Key”** value from your Root key.
|
||||
5. Create a .env file in the root of the demo repository
|
||||
6. Paste the API key into your new env file, along with a env variable for your localhost:
|
||||
|
||||
```bash
|
||||
ABLY_API_KEY=your-ably-api-key:goes-here
|
||||
API_ROOT=http://localhost:3000
|
||||
```
|
||||
|
||||
### How it Works/Using Ably
|
||||
|
||||
#### Configuration
|
||||
|
||||
[pages/\_app.js](pages/_app.js) is where the Ably SDK is configured:
|
||||
|
||||
```js
|
||||
import { configureAbly } from '@ably-labs/react-hooks'
|
||||
|
||||
const prefix = process.env.API_ROOT || ''
|
||||
const clientId =
|
||||
Math.random().toString(36).substring(2, 15) +
|
||||
Math.random().toString(36).substring(2, 15)
|
||||
|
||||
configureAbly({
|
||||
authUrl: `${prefix}/api/createTokenRequest?clientId=${clientId}`,
|
||||
clientId: clientId,
|
||||
})
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
export default MyApp
|
||||
```
|
||||
|
||||
`configureAbly` matches the method signature of the Ably SDK - and requires either a string or a [AblyClientOptions](https://ably.com/docs/api/realtime-sdk#client-options) object. You can use this configuration object to setup your [tokenAuthentication](https://ably.com/docs/core-features/authentication#token-authentication). If you want to use the usePresence function, you'll need to explicitly provide a `clientId`.
|
||||
|
||||
You can do this anywhere in your code before the rest of the library is used.
|
||||
|
||||
#### useChannel (Publishing and Subscribing to Messages)
|
||||
|
||||
The `useChannel` hook lets you subscribe to a channel and receive messages from it:
|
||||
|
||||
```js
|
||||
import { useState } from 'react'
|
||||
import { useChannel } from '@ably-labs/react-hooks'
|
||||
|
||||
export default function Home() {
|
||||
const [channel] = useChannel('your-channel', async (message) => {
|
||||
console.log('Received Ably message', message)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Every time a message is sent to `your-channel` it will be logged to the console. You can do whatever you need to with those messages.
|
||||
|
||||
##### Publishing a message
|
||||
|
||||
The `channel` instance returned by `useChannel` can be used to send messages to the channel. It is a regular Ably JavaScript SDK `channel` instance.
|
||||
|
||||
```javascript
|
||||
channel.publish('test-message', { text: 'message text' })
|
||||
```
|
||||
|
||||
#### usePresence
|
||||
|
||||
The `usePresence` hook lets you subscribe to presence events on a channel - this will allow you to get notified when a user joins or leaves the channel. The presence data is automatically updated and your component re-rendered when presence changes:
|
||||
|
||||
```js
|
||||
import { useState } from 'react'
|
||||
import { usePresence } from '@ably-labs/react-hooks'
|
||||
|
||||
export default function Home() {
|
||||
const [presenceData, updateStatus] = usePresence('your-channel-name')
|
||||
|
||||
const presentClients = presenceData.map((msg, index) => (
|
||||
<li key={index}>
|
||||
{msg.clientId}: {msg.data}
|
||||
</li>
|
||||
))
|
||||
|
||||
return <ul>{presentClients}</ul>
|
||||
}
|
||||
```
|
||||
|
||||
You can read more about the hooks available with the Ably Hooks package on the [@ably-labs/ably-hooks documentation on npm](https://www.npmjs.com/package/@ably-labs/react-hooks).
|
5
examples/with-ably/next-env.d.ts
vendored
Normal file
5
examples/with-ably/next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
21
examples/with-ably/package.json
Normal file
21
examples/with-ably/package.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ably-labs/react-hooks": "^2.0.4",
|
||||
"ably": "^1.2.22",
|
||||
"next": "latest",
|
||||
"react": "18.1.0",
|
||||
"react-dom": "18.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/react": "^18.0.12",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"typescript": "^4.7.3"
|
||||
}
|
||||
}
|
18
examples/with-ably/pages/_app.tsx
Normal file
18
examples/with-ably/pages/_app.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import '../styles/globals.css'
|
||||
import { configureAbly } from '@ably-labs/react-hooks'
|
||||
|
||||
const prefix = process.env.API_ROOT || ''
|
||||
const clientId =
|
||||
Math.random().toString(36).substring(2, 15) +
|
||||
Math.random().toString(36).substring(2, 15)
|
||||
|
||||
configureAbly({
|
||||
authUrl: `${prefix}/api/createTokenRequest?clientId=${clientId}`,
|
||||
clientId: clientId,
|
||||
})
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
export default MyApp
|
13
examples/with-ably/pages/api/createTokenRequest.ts
Normal file
13
examples/with-ably/pages/api/createTokenRequest.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Ably from 'ably/promises'
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const client = new Ably.Realtime(process.env.ABLY_API_KEY)
|
||||
const tokenRequestData = await client.auth.createTokenRequest({
|
||||
clientId: req.query.clientId as string,
|
||||
})
|
||||
res.status(200).json(tokenRequestData)
|
||||
}
|
19
examples/with-ably/pages/api/send-message.ts
Normal file
19
examples/with-ably/pages/api/send-message.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import Ably from 'ably/promises'
|
||||
import type { NextApiRequest, NextApiResponse } from 'next/types'
|
||||
import type { TextMessage } from '../../types'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const client = new Ably.Realtime(process.env.ABLY_API_KEY)
|
||||
|
||||
const channel = client.channels.get('some-channel-name')
|
||||
|
||||
const message: TextMessage = {
|
||||
text: `Server sent a message on behalf of ${req.body.sender}`,
|
||||
}
|
||||
channel.publish('test-message', message)
|
||||
|
||||
res.status(200)
|
||||
}
|
114
examples/with-ably/pages/index.tsx
Normal file
114
examples/with-ably/pages/index.tsx
Normal file
|
@ -0,0 +1,114 @@
|
|||
import { useState } from 'react'
|
||||
import { useChannel, usePresence } from '@ably-labs/react-hooks'
|
||||
import type { Types } from 'ably'
|
||||
import type { ProxyMessage, TextMessage } from '../types'
|
||||
|
||||
import Head from 'next/head'
|
||||
import Image from 'next/image'
|
||||
import styles from '../styles/Home.module.css'
|
||||
|
||||
export default function Home() {
|
||||
const [messages, setMessages] = useState<TextMessage[]>([])
|
||||
|
||||
const [channel, ably] = useChannel(
|
||||
'some-channel-name',
|
||||
async (message: Types.Message) => {
|
||||
console.log('Received Ably message', message)
|
||||
setMessages((messages) => [...messages, message.data])
|
||||
}
|
||||
)
|
||||
|
||||
const [presenceData, updateStatus] = usePresence('your-channel-name')
|
||||
|
||||
const messageList = messages.map((message, index) => {
|
||||
return <li key={index}>{message.text}</li>
|
||||
})
|
||||
|
||||
const presentClients = presenceData.map((msg, index) => (
|
||||
<li key={index}>
|
||||
{msg.clientId}: {msg.data}
|
||||
</li>
|
||||
))
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Head>
|
||||
<title>Create Next App</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<h1>Realtime Edge Messaging with Next and Ably</h1>
|
||||
<p>
|
||||
Use the buttons below to send and receive messages or to update your
|
||||
status.
|
||||
</p>
|
||||
|
||||
<main className={styles.main}>
|
||||
<h2>Present Clients</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
updateStatus('hello')
|
||||
}}
|
||||
>
|
||||
Update status to hello
|
||||
</button>
|
||||
<ul>{presentClients}</ul>
|
||||
|
||||
<h2>Ably Message Data</h2>
|
||||
<button
|
||||
className={styles.button}
|
||||
onClick={() => {
|
||||
const message: TextMessage = {
|
||||
text: `${ably.auth.clientId} sent a message`,
|
||||
}
|
||||
channel.publish('test-message', message)
|
||||
}}
|
||||
>
|
||||
Send A Message
|
||||
</button>
|
||||
<button
|
||||
className={styles.button}
|
||||
onClick={() => {
|
||||
const proxyMessage: ProxyMessage = {
|
||||
sender: `${ably.auth.clientId}`,
|
||||
}
|
||||
|
||||
fetch('/api/send-message', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(proxyMessage),
|
||||
})
|
||||
}}
|
||||
>
|
||||
Send A Message From the Server
|
||||
</button>
|
||||
<ul>{messageList}</ul>
|
||||
</main>
|
||||
|
||||
<footer className={styles.footer}>
|
||||
Powered by
|
||||
<a
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span>
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
width={100}
|
||||
height={32}
|
||||
/>
|
||||
</span>
|
||||
</a>
|
||||
and
|
||||
<a href="https://ably.com/">
|
||||
<img src="/ably.svg" alt="Ably Realtime" className={styles.logo} />
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
27
examples/with-ably/public/ably.svg
Normal file
27
examples/with-ably/public/ably.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg enable-background="new 0 0 204 64" version="1.1" viewBox="0 0 204 64" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css">
|
||||
.st0{fill:#03020D;}
|
||||
.st1{fill:url(#a);}
|
||||
.st2{fill:url(#SVGID_00000031166151110981865790000012490412721004567735_);}
|
||||
</style>
|
||||
<path class="st0" d="m125.8 50v-41.8h7.5v15.1c2.6-2.4 5.8-3.8 9.3-3.8 8.2 0 15.4 6.2 15.4 15.6s-7.2 15.6-15.4 15.6c-3.7 0-7.1-1.5-9.7-4.1v3.4h-7.1zm24.8-14.9c0-5.2-3.7-8.9-8.6-8.9-4.7 0-8.4 3.5-8.6 8.5v0.4c0 5.2 3.7 8.9 8.6 8.9s8.6-3.7 8.6-8.9zm11 14.9v-41.8h7.5v41.8h-7.5zm18.1 10.8 4.4-10.5-11.9-30h8.2l7.6 21 7.7-21h8.3l-16.2 40.6-8.1-0.1zm-65.8-40.5v3.7c-2.6-2.9-6.3-4.5-10-4.5-8.2 0-15.4 6.2-15.4 15.6s7.2 15.6 15.4 15.6c3.9 0 7.6-1.7 10.3-4.7v4h6.6v-29.7h-6.9zm-0.8 14.8c0 5.2-3.7 8.9-8.6 8.9s-8.6-3.7-8.6-8.9 3.7-8.9 8.6-8.9c4.7 0 8.4 3.5 8.6 8.5v0.4z"/>
|
||||
<linearGradient id="a" x1="10.947" x2="64.92" y1="-8.8433" y2="51.1" gradientTransform="matrix(1 0 0 -1 0 66)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF5416" offset="0"/>
|
||||
<stop stop-color="#FF5115" offset=".2535"/>
|
||||
<stop stop-color="#FF4712" offset=".461"/>
|
||||
<stop stop-color="#FF350E" offset=".6523"/>
|
||||
<stop stop-color="#FF1E08" offset=".8327"/>
|
||||
<stop stop-color="#f00" offset="1"/>
|
||||
</linearGradient>
|
||||
<path class="st1" d="M38.6,0L6.3,59.1L0,54.7L29.9,0H38.6z M39,0l32.3,59.1l6.3-4.4L47.7,0H39z"/>
|
||||
<linearGradient id="b" x1="21.419" x2="53.319" y1="-12.721" y2="22.708" gradientTransform="matrix(1 0 0 -1 0 66)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF5416" offset="0"/>
|
||||
<stop stop-color="#FF5115" offset=".2535"/>
|
||||
<stop stop-color="#FF4712" offset=".461"/>
|
||||
<stop stop-color="#FF350E" offset=".6523"/>
|
||||
<stop stop-color="#FF1E08" offset=".8327"/>
|
||||
<stop stop-color="#f00" offset="1"/>
|
||||
</linearGradient>
|
||||
<path d="m70.8 59.4-32-25.1-32.1 25.1 6.5 4.6 25.5-20 25.5 20 6.6-4.6z" fill="url(#b)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/with-ably/public/favicon.ico
Normal file
BIN
examples/with-ably/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
4
examples/with-ably/public/vercel.svg
Normal file
4
examples/with-ably/public/vercel.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
34
examples/with-ably/styles/Home.module.css
Normal file
34
examples/with-ably/styles/Home.module.css
Normal file
|
@ -0,0 +1,34 @@
|
|||
.container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-grow: 0;
|
||||
column-gap: 1em;
|
||||
align-items: flex-start;
|
||||
padding: 2em 0 0;
|
||||
border-top: 1px solid #eaeaea;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
margin-right: 1rem;
|
||||
}
|
46
examples/with-ably/styles/globals.css
Normal file
46
examples/with-ably/styles/globals.css
Normal file
|
@ -0,0 +1,46 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
ul,
|
||||
li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-right: 1rem;
|
||||
border-radius: 0.4rem;
|
||||
border: 0;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
padding: 10px 15px;
|
||||
font-size: large;
|
||||
color: white;
|
||||
background-color: #ff5416;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #ff2739;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
width: 100%;
|
||||
}
|
20
examples/with-ably/tsconfig.json
Normal file
20
examples/with-ably/tsconfig.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
2
examples/with-ably/types.d.ts
vendored
Normal file
2
examples/with-ably/types.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export type TextMessage = { text: string }
|
||||
export type ProxyMessage = { sender: string }
|
Loading…
Reference in a new issue