Skip to content

Commit

Permalink
Merge branch 'canary' into upload-deploy-trace
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk authored Jun 16, 2023
2 parents fcfb8dd + f7533e0 commit 887b8bc
Show file tree
Hide file tree
Showing 39 changed files with 532 additions and 489 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,60 @@ export async function GET(request, { params }) {

### Streaming

Streaming is commonly used in combination with Large Language Models (LLMs), such an OpenAI, for AI-generated content. Learn more about the [AI SDK](https://sdk.vercel.ai/docs).

```ts filename="app/api/completion/route.ts" switcher
import { Configuration, OpenAIApi } from 'openai-edge'
import { OpenAIStream, StreamingTextResponse } from 'ai'

const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
})
const openai = new OpenAIApi(config)

export const runtime = 'edge'

export async function POST(req: Request) {
const { prompt } = await req.json()
const response = await openai.createCompletion({
model: 'text-davinci-003',
stream: true,
temperature: 0.6,
prompt: 'What is Next.js?',
})

const stream = OpenAIStream(response)
return new StreamingTextResponse(stream)
}
```

```js filename="app/api/completion/route.js" switcher
import { Configuration, OpenAIApi } from 'openai-edge'
import { OpenAIStream, StreamingTextResponse } from 'ai'

const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
})
const openai = new OpenAIApi(config)

export const runtime = 'edge'

export async function POST(req) {
const { prompt } = await req.json()
const response = await openai.createCompletion({
model: 'text-davinci-003',
stream: true,
temperature: 0.6,
prompt: 'What is Next.js?',
})

const stream = OpenAIStream(response)
return new StreamingTextResponse(stream)
}
```

These abstractions use the Web APIs to create a stream. You can also use the underlying Web APIs directly.

```ts filename="app/api/route.ts" switcher
// https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#convert_async_iterator_to_stream
function iteratorToStream(iterator: any) {
Expand Down
12 changes: 12 additions & 0 deletions examples/with-redux/app/api/identity-count/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* Core */
import { NextResponse } from 'next/server'

export async function POST(req: Request, res: Response) {
const body = await req.json()
const { amount = 1 } = body

// simulate IO latency
await new Promise((r) => setTimeout(r, 500))

return NextResponse.json({ data: amount })
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
'use client'

/* Core */
import { useState } from 'react'

import { useAppSelector, useAppDispatch } from '../../hooks'
/* Instruments */
import {
decrement,
increment,
incrementByAmount,
incrementAsync,
incrementIfOdd,
counterSlice,
useSelector,
useDispatch,
selectCount,
} from './counterSlice'
import styles from './Counter.module.css'

function Counter() {
const dispatch = useAppDispatch()
const count = useAppSelector(selectCount)
const [incrementAmount, setIncrementAmount] = useState('2')
incrementAsync,
incrementIfOddAsync,
} from '@/lib/redux'
import styles from './counter.module.css'

const incrementValue = Number(incrementAmount) || 0
export const Counter = () => {
const dispatch = useDispatch()
const count = useSelector(selectCount)
const [incrementAmount, setIncrementAmount] = useState(2)

return (
<div>
<div className={styles.row}>
<button
className={styles.button}
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
onClick={() => dispatch(counterSlice.actions.decrement())}
>
-
</button>
<span className={styles.value}>{count}</span>
<button
className={styles.button}
aria-label="Increment value"
onClick={() => dispatch(increment())}
onClick={() => dispatch(counterSlice.actions.increment())}
>
+
</button>
Expand All @@ -42,29 +43,29 @@ function Counter() {
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={(e) => setIncrementAmount(e.target.value)}
onChange={(e) => setIncrementAmount(Number(e.target.value ?? 0))}
/>
<button
className={styles.button}
onClick={() => dispatch(incrementByAmount(incrementValue))}
onClick={() =>
dispatch(counterSlice.actions.incrementByAmount(incrementAmount))
}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(incrementValue))}
onClick={() => dispatch(incrementAsync(incrementAmount))}
>
Add Async
</button>
<button
className={styles.button}
onClick={() => dispatch(incrementIfOdd(incrementValue))}
onClick={() => dispatch(incrementIfOddAsync(incrementAmount))}
>
Add If Odd
</button>
</div>
</div>
)
}

export default Counter
31 changes: 31 additions & 0 deletions examples/with-redux/app/components/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

/* Core */
import Link from 'next/link'
import { usePathname } from 'next/navigation'

/* Instruments */
import styles from '../styles/layout.module.css'

export const Nav = () => {
const pathname = usePathname()

return (
<nav className={styles.nav}>
<Link
className={`${styles.link} ${pathname === '/' ? styles.active : ''}`}
href="/"
>
Home
</Link>
<Link
className={`${styles.link} ${
pathname === '/verify' ? styles.active : ''
}`}
href="/verify"
>
Verify
</Link>
</nav>
)
}
File renamed without changes.
66 changes: 66 additions & 0 deletions examples/with-redux/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* Components */
import { Providers } from '@/lib/providers'
import { Nav } from './components/Nav'

/* Instruments */
import styles from './styles/layout.module.css'
import './styles/globals.css'

export default function RootLayout(props: React.PropsWithChildren) {
return (
<Providers>
<html lang="en">
<body>
<section className={styles.container}>
<Nav />

<header className={styles.header}>
<img src="/logo.svg" className={styles.logo} alt="logo" />
</header>

<main className={styles.main}>{props.children}</main>

<footer className={styles.footer}>
<span>Learn </span>
<a
className={styles.link}
href="https://reactjs.org/"
target="_blank"
rel="noopener noreferrer"
>
React
</a>
<span>, </span>
<a
className={styles.link}
href="https://redux.js.org/"
target="_blank"
rel="noopener noreferrer"
>
Redux
</a>
<span>, </span>
<a
className={styles.link}
href="https://redux-toolkit.js.org/"
target="_blank"
rel="noopener noreferrer"
>
Redux Toolkit
</a>
,<span> and </span>
<a
className={styles.link}
href="https://react-redux.js.org/"
target="_blank"
rel="noopener noreferrer"
>
React Redux
</a>
</footer>
</section>
</body>
</html>
</Providers>
)
}
10 changes: 10 additions & 0 deletions examples/with-redux/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* Components */
import { Counter } from './components/Counter/Counter'

export default function IndexPage() {
return <Counter />
}

export const metadata = {
title: 'Redux Toolkit',
}
16 changes: 16 additions & 0 deletions examples/with-redux/app/styles/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
html,
body {
min-height: 100vh;
padding: 0;
margin: 0;
font-family: system-ui, sans-serif;
}

a {
color: inherit;
text-decoration: none;
}

* {
box-sizing: border-box;
}
77 changes: 77 additions & 0 deletions examples/with-redux/app/styles/layout.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.container {
display: grid;
grid-template-areas:
'nav'
'header'
'main'
'footer';
grid-template-rows: auto auto 1fr 36px;
align-items: center;
min-height: 100vh;
}

.logo {
height: 40vmin;
pointer-events: none;
}

.header {
grid-area: header;
}

.main {
grid-area: main;
}

.header,
.main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

.footer {
grid-area: footer;
justify-self: center;
}

.nav {
grid-area: nav;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px;
font-size: calc(10px + 2vmin);
}

.link:hover {
text-decoration: underline;
}

.link {
color: #704cb6;
}

.link.active {
text-decoration: underline;
}

@media (prefers-reduced-motion: no-preference) {
.logo {
animation: logo-float infinite 3s ease-in-out;
}
}

@keyframes logo-float {
0% {
transform: translateY(0);
}
50% {
transform: translateY(10px);
}
100% {
transform: translateY(0px);
}
}
11 changes: 11 additions & 0 deletions examples/with-redux/app/verify/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function VerifyPage() {
return (
<>
<h1>Verify page</h1>
<p>
This page is intended to verify that Redux state is persisted across
page navigations.
</p>
</>
)
}
Loading

0 comments on commit 887b8bc

Please sign in to comment.