This repository has been archived by the owner on Jul 5, 2024. It is now read-only.
generated from JoshuaKGoldberg/create-typescript-app
-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
698 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "@examples/minimal", | ||
"version": "10.38.5", | ||
"private": true, | ||
"module": "module", | ||
"workspaces": [ | ||
"client", | ||
"server" | ||
], | ||
"scripts": { | ||
"build": "tsc", | ||
"dev:server": "tsx watch src/server", | ||
"dev:client": "wait-port 3000 && tsx watch src/client", | ||
"dev": "run-p dev:* --print-label", | ||
"lint": "eslint --ext \".js,.ts,.tsx\" --report-unused-disable-directives */*.ts", | ||
"test-dev": "start-server-and-test 'tsx src/server' 3000 'tsx src/client'" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.16.16", | ||
"eslint": "^8.40.0", | ||
"npm-run-all": "^4.1.5", | ||
"start-server-and-test": "^1.12.0", | ||
"tsx": "^3.12.7", | ||
"tupleson": "latest", | ||
"typescript": "^5.1.3", | ||
"wait-port": "^1.0.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import type { ResponseShape } from "./server"; | ||
|
||
import { mapIterable, readableStreamToAsyncIterable } from "./iteratorUtils"; | ||
import { tsonAsync } from "./shared"; | ||
|
||
async function main() { | ||
// do a streamed fetch request | ||
const port = 3000; | ||
const response = await fetch(`http://localhost:${port}`); | ||
|
||
if (!response.body) { | ||
throw new Error("Response body is empty"); | ||
} | ||
|
||
const textDecoder = new TextDecoder(); | ||
|
||
// convert the response body to an async iterable | ||
const stringIterator = mapIterable( | ||
readableStreamToAsyncIterable(response.body), | ||
(v) => textDecoder.decode(v), | ||
); | ||
|
||
const parsedRaw = await tsonAsync.parse(stringIterator); | ||
Check failure on line 23 in examples/async/src/client.ts GitHub Actions / lint
|
||
const parsed = parsedRaw as ResponseShape; | ||
|
||
const printBigInts = async () => { | ||
for await (const value of parsed.bigints) { | ||
console.log(`Received bigint:`, value); | ||
} | ||
}; | ||
|
||
const printNumbers = async () => { | ||
for await (const value of parsed.numbers) { | ||
console.log(`Received number:`, value); | ||
} | ||
}; | ||
|
||
await Promise.all([printBigInts(), printNumbers()]); | ||
|
||
console.log("Output ended"); | ||
} | ||
|
||
main().catch((err) => { | ||
console.error(err); | ||
throw err; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export async function* readableStreamToAsyncIterable<T>( | ||
stream: ReadableStream<T>, | ||
): AsyncIterable<T> { | ||
// Get a lock on the stream | ||
const reader = stream.getReader(); | ||
|
||
try { | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
while (true) { | ||
// Read from the stream | ||
const result = await reader.read(); | ||
|
||
// Exit if we're done | ||
if (result.done) { | ||
return; | ||
} | ||
|
||
// Else yield the chunk | ||
yield result.value; | ||
} | ||
} finally { | ||
reader.releaseLock(); | ||
} | ||
} | ||
|
||
export async function* mapIterable<T, TValue>( | ||
iterable: AsyncIterable<T>, | ||
fn: (v: T) => TValue, | ||
): AsyncIterable<TValue> { | ||
for await (const value of iterable) { | ||
yield fn(value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import http from "node:http"; | ||
|
||
import { tsonAsync } from "./shared"; | ||
|
||
const randomNumber = (min: number, max: number) => { | ||
return Math.floor(Math.random() * (max - min + 1) + min); | ||
}; | ||
|
||
export function getResponseShape() { | ||
async function* bigintGenerator() { | ||
const iterate = new Array(10).fill(0).map((_, i) => BigInt(i)); | ||
for (const number of iterate) { | ||
await new Promise((resolve) => setTimeout(resolve, randomNumber(1, 400))); | ||
yield number; | ||
} | ||
} | ||
|
||
async function* numberGenerator() { | ||
const iterate = new Array(10).fill(0).map((_, i) => i); | ||
for (const number of iterate) { | ||
await new Promise((resolve) => setTimeout(resolve, randomNumber(1, 400))); | ||
yield number; | ||
} | ||
} | ||
|
||
return { | ||
bigints: bigintGenerator(), | ||
foo: "bar", | ||
numbers: numberGenerator(), | ||
promise: Promise.resolve(42), | ||
rejectedPromise: Promise.reject(new Error("rejected promise")), | ||
}; | ||
} | ||
|
||
export type ResponseShape = ReturnType<typeof getResponseShape>; | ||
async function handleRequest( | ||
req: http.IncomingMessage, | ||
res: http.ServerResponse, | ||
) { | ||
res.writeHead(200, { "Content-Type": "application/json" }); | ||
|
||
const obj = getResponseShape(); | ||
|
||
for await (const chunk of tsonAsync.stringify(obj)) { | ||
res.write(chunk); | ||
} | ||
} | ||
|
||
const server = http.createServer( | ||
(req: http.IncomingMessage, res: http.ServerResponse) => { | ||
handleRequest(req, res).catch((err) => { | ||
console.error(err); | ||
res.writeHead(500, { "Content-Type": "text/plain" }); | ||
res.end("Internal Server Error\n"); | ||
}); | ||
}, | ||
); | ||
|
||
const port = 3000; | ||
server.listen(port); | ||
|
||
console.log(`Server running at http://localhost:${port}`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { | ||
createTsonAsync, | ||
tsonAsyncIterator, | ||
tsonBigint, | ||
tsonPromise, | ||
} from "tupleson"; | ||
|
||
export const tsonAsync = createTsonAsync({ | ||
Check failure on line 8 in examples/async/src/shared.ts GitHub Actions / lint
|
||
types: [tsonPromise, tsonAsyncIterator, tsonBigint], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "esnext", | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"esModuleInterop": true, | ||
"strict": true, | ||
"outDir": "dist" | ||
}, | ||
"include": ["src"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,5 +81,10 @@ | |
}, | ||
"publishConfig": { | ||
"provenance": true | ||
}, | ||
"pnpm": { | ||
"overrides": { | ||
"@trpc/server": "link:./" | ||
} | ||
} | ||
} |
Oops, something went wrong.