diff options
author | 2023-07-26 14:59:39 -0700 | |
---|---|---|
committer | 2023-07-26 14:59:39 -0700 | |
commit | 4c89c60867591b50e0b31bf5009fd5ad6a3cebe1 (patch) | |
tree | fc1d2f47309c0345a850933496baa40d94bfdcbb | |
parent | 6bfee02301a2e2a0b79339974af0445eb5a2688f (diff) | |
download | bun-4c89c60867591b50e0b31bf5009fd5ad6a3cebe1.tar.gz bun-4c89c60867591b50e0b31bf5009fd5ad6a3cebe1.tar.zst bun-4c89c60867591b50e0b31bf5009fd5ad6a3cebe1.zip |
Add files (#3826)
90 files changed, 2246 insertions, 0 deletions
diff --git a/docs/guides/binary/arraybuffer-to-array.md b/docs/guides/binary/arraybuffer-to-array.md new file mode 100644 index 000000000..688030b0a --- /dev/null +++ b/docs/guides/binary/arraybuffer-to-array.md @@ -0,0 +1,27 @@ +--- +name: Convert an ArrayBuffer to an array of numbers +--- + +To retrieve the contents of an `ArrayBuffer` as an array of numbers, create a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) over of the buffer. and use the [`Array.from()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method to convert it to an array. + +```ts +const buf = new ArrayBuffer(64); +const arr = new Uint8Array(buf); +arr.length; // 64 +arr[0]; // 0 (instantiated with all zeros) +``` + +--- + +The `Uint8Array` class supports array indexing and iteration. However if you wish to convert the instance to a regular `Array`, use `Array.from()`. (This will likely be slower than using the `Uint8Array` directly.) + +```ts +const buf = new ArrayBuffer(64); +const uintArr = new Uint8Array(buf); +const regularArr = Array.from(uintArr); +// number[] +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/arraybuffer-to-blob.md b/docs/guides/binary/arraybuffer-to-blob.md new file mode 100644 index 000000000..53795282e --- /dev/null +++ b/docs/guides/binary/arraybuffer-to-blob.md @@ -0,0 +1,24 @@ +--- +name: Convert an ArrayBuffer to a Blob +--- + +A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure, or another `Blob`. + +```ts +const buf = new ArrayBuffer(64); +const blob = new Blob([buf]); +``` + +--- + +By default the `type` of the resulting `Blob` will be unset. This can be set manually. + +```ts +const buf = new ArrayBuffer(64); +const blob = new Blob([buf], { type: "application/octet-stream" }); +blob.type; // => "application/octet-stream" +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/arraybuffer-to-buffer.md b/docs/guides/binary/arraybuffer-to-buffer.md new file mode 100644 index 000000000..2737ebb4e --- /dev/null +++ b/docs/guides/binary/arraybuffer-to-buffer.md @@ -0,0 +1,25 @@ +--- +name: Convert an ArrayBuffer to a Uint8Array +--- + +The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) API predates the introduction of `ArrayBuffer` into the JavaScript language. Bun implements both. + +Use the static `Buffer.from()` method to create a `Buffer` from an `ArrayBuffer`. + +```ts +const arrBuffer = new ArrayBuffer(64); +const nodeBuffer = Buffer.from(arrBuffer); +``` + +--- + +To create a `Buffer` that only views a portion of the underlying buffer, pass the offset and length to the constructor. + +```ts +const arrBuffer = new ArrayBuffer(64); +const nodeBuffer = Buffer.from(arrBuffer, 0, 16); // view first 16 bytes +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/arraybuffer-to-string.md b/docs/guides/binary/arraybuffer-to-string.md new file mode 100644 index 000000000..13bb83122 --- /dev/null +++ b/docs/guides/binary/arraybuffer-to-string.md @@ -0,0 +1,15 @@ +--- +name: Convert an ArrayBuffer to a string +--- + +Bun implements the Web-standard [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class for converting between binary data types and strings. + +```ts +const buf = new ArrayBuffer(64); +const decoder = new TextDecoder(); +const str = decoder.decode(buf); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/arraybuffer-to-typedarray.md b/docs/guides/binary/arraybuffer-to-typedarray.md new file mode 100644 index 000000000..a4e823d8f --- /dev/null +++ b/docs/guides/binary/arraybuffer-to-typedarray.md @@ -0,0 +1,39 @@ +--- +name: Convert an ArrayBuffer to a Uint8Array +--- + +A `Uint8Array` is a _typed array_, meaning it is a mechanism for viewing the data in an underlying `ArrayBuffer`. + +```ts +const buffer = new ArrayBuffer(64); +const arr = new Uint8Array(buffer); +``` + +--- + +Instances of other typed arrays can be created similarly. + +```ts +const buffer = new ArrayBuffer(64); + +const arr1 = new Uint8Array(buffer); +const arr2 = new Uint16Array(buffer); +const arr3 = new Uint32Array(buffer); +const arr4 = new Float32Array(buffer); +const arr5 = new Float64Array(buffer); +const arr6 = new BigInt64Array(buffer); +const arr7 = new BigUint64Array(buffer); +``` + +--- + +To create a typed array that only views a portion of the underlying buffer, pass the offset and length to the constructor. + +```ts +const buffer = new ArrayBuffer(64); +const arr = new Uint8Array(buffer, 0, 16); // view first 16 bytes +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/binary/blob-to-arraybuffer.md b/docs/guides/binary/blob-to-arraybuffer.md new file mode 100644 index 000000000..18e3f1235 --- /dev/null +++ b/docs/guides/binary/blob-to-arraybuffer.md @@ -0,0 +1,14 @@ +--- +name: Convert a Blob to an ArrayBuffer +--- + +The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, including `.arrayBuffer()`. + +```ts +const blob = new Blob(["hello world"]); +const buf = await blob.arrayBuffer(); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/blob-to-dataview.md b/docs/guides/binary/blob-to-dataview.md new file mode 100644 index 000000000..7d874c1f6 --- /dev/null +++ b/docs/guides/binary/blob-to-dataview.md @@ -0,0 +1,14 @@ +--- +name: Convert a Blob to a DataView +--- + +The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats. This snippets reads the contents to an `ArrayBuffer`, then creates a `DataView` from the buffer. + +```ts +const blob = new Blob(["hello world"]); +const arr = new DataView(await blob.arrayBuffer()); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/blob-to-stream.md b/docs/guides/binary/blob-to-stream.md new file mode 100644 index 000000000..37a916ab3 --- /dev/null +++ b/docs/guides/binary/blob-to-stream.md @@ -0,0 +1,14 @@ +--- +name: Convert a Blob to a ReadableStream +--- + +The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.stream()`. This returns `Promise<ReadableStream>`. + +```ts +const blob = new Blob(["hello world"]); +const stream = await blob.stream(); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/blob-to-string.md b/docs/guides/binary/blob-to-string.md new file mode 100644 index 000000000..05692c32e --- /dev/null +++ b/docs/guides/binary/blob-to-string.md @@ -0,0 +1,15 @@ +--- +name: Convert a Blob to a string +--- + +The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.text()`. + +```ts +const blob = new Blob(["hello world"]); +const str = await blob.text(); +// => "hello world" +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/blob-to-typedarray.md b/docs/guides/binary/blob-to-typedarray.md new file mode 100644 index 000000000..efedad02f --- /dev/null +++ b/docs/guides/binary/blob-to-typedarray.md @@ -0,0 +1,14 @@ +--- +name: Convert a Blob to a Uint8Array +--- + +The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats. This snippets reads the contents to an `ArrayBuffer`, then creates a `Uint8Array` from the buffer. + +```ts +const blob = new Blob(["hello world"]); +const arr = new Uint8Array(await blob.arrayBuffer()); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/buffer-to-arraybuffer.md b/docs/guides/binary/buffer-to-arraybuffer.md new file mode 100644 index 000000000..56ba78a00 --- /dev/null +++ b/docs/guides/binary/buffer-to-arraybuffer.md @@ -0,0 +1,14 @@ +--- +name: Convert a Buffer to an ArrayBuffer +--- + +The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) class provides a way to view and manipulate data in an underlying `ArrayBuffer`, which is available via the `buffer` property. + +```ts +const nodeBuf = Buffer.alloc(64); +const arrBuf = nodeBuf.buffer; +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/buffer-to-blob.md b/docs/guides/binary/buffer-to-blob.md new file mode 100644 index 000000000..9f59c9f68 --- /dev/null +++ b/docs/guides/binary/buffer-to-blob.md @@ -0,0 +1,14 @@ +--- +name: Convert a Buffer to a blob +--- + +A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure (including `Buffer`), or another `Blob`. + +```ts +const buf = Buffer.from("hello"); +const blob = new Blob([buf]); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/buffer-to-readablestream.md b/docs/guides/binary/buffer-to-readablestream.md new file mode 100644 index 000000000..fbb03df50 --- /dev/null +++ b/docs/guides/binary/buffer-to-readablestream.md @@ -0,0 +1,41 @@ +--- +name: Convert a Buffer to a ReadableStream +--- + +The naive approach to creating a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) from a [`Buffer`](https://nodejs.org/api/buffer.html) is to use the `ReadableStream` constructor and enqueue the entire array as a single chunk. For a large buffer, this may be undesirable as this approach does not "streaming" the data in smaller chunks. + +```ts +const buf = Buffer.from("hello world"); +const stream = new ReadableStream({ + start(controller) { + controller.enqueue(buf); + controller.close(); + }, +}); +``` + +--- + +To stream the data in smaller chunks, first create a `Blob` instance from the `Buffer`. Then use the [`Blob.stream()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) method to create a `ReadableStream` that streams the data in chunks of a specified size. + +```ts +const buf = Buffer.from("hello world"); +const blob = new Blob([buf]); +const stream = blob.stream(); +``` + +--- + +The chunk size can be set by passing a number to the `.stream()` method. + +```ts +const buf = Buffer.from("hello world"); +const blob = new Blob([buf]); + +// set chunk size of 1024 bytes +const stream = blob.stream(1024); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/buffer-to-string.md b/docs/guides/binary/buffer-to-string.md new file mode 100644 index 000000000..f900cd6a3 --- /dev/null +++ b/docs/guides/binary/buffer-to-string.md @@ -0,0 +1,25 @@ +--- +name: Convert a Buffer to a string +--- + +The [`Buffer`](https://nodejs.org/api/buffer.html) class provides a built-in `.toString()` method that converts a `Buffer` to a string. + +```ts +const buf = Buffer.from("hello"); +const str = buf.toString(); +// => "hello" +``` + +--- + +You can optionally specify an encoding and byte range. + +```ts +const buf = Buffer.from("hello world!"); +const str = buf.toString("utf8", 0, 5); +// => "hello" +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/buffer-to-typedarray.md b/docs/guides/binary/buffer-to-typedarray.md new file mode 100644 index 000000000..c59d77218 --- /dev/null +++ b/docs/guides/binary/buffer-to-typedarray.md @@ -0,0 +1,14 @@ +--- +name: Convert a Buffer to a Uint8Array +--- + +The Node.js [`Buffer`](https://nodejs.org/api/buffer.html) class extends [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array), so no conversion is needed. All properties and methods on `Uint8Array` are available on `Buffer`. + +```ts +const buf = Buffer.alloc(64); +buf instanceof Uint8Array; // => true +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/dataview-to-string.md b/docs/guides/binary/dataview-to-string.md new file mode 100644 index 000000000..0151eaa58 --- /dev/null +++ b/docs/guides/binary/dataview-to-string.md @@ -0,0 +1,15 @@ +--- +name: Convert a Uint8Array to a string +--- + +If a [`DataView`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) contains ASCII-encoded text, you can convert it to a string using the [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class. + +```ts +const dv: DataView = ...; +const decoder = new TextDecoder(); +const str = decoder.decode(dv); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/index.json b/docs/guides/binary/index.json new file mode 100644 index 000000000..0ddf3da49 --- /dev/null +++ b/docs/guides/binary/index.json @@ -0,0 +1,4 @@ +{ + "name": "Binary data", + "description": "A collection of guides for converting between binary data formats with Bun" +} diff --git a/docs/guides/binary/typedarray-to-arraybuffer.md b/docs/guides/binary/typedarray-to-arraybuffer.md new file mode 100644 index 000000000..2458b21c0 --- /dev/null +++ b/docs/guides/binary/typedarray-to-arraybuffer.md @@ -0,0 +1,25 @@ +--- +name: Convert a Uint8Array to an ArrayBuffer +--- + +A [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is a _typed array_ class, meaning it is a mechanism for viewing data in an underlying `ArrayBuffer`. The underlying `ArrayBuffer` is accessible via the `buffer` property. + +```ts +const arr = new Uint8Array(64); +arr.buffer; // => ArrayBuffer(64) +``` + +--- + +The `Uint8Array` may be a view over a _subset_ of the data in the underlying `ArrayBuffer`. In this case, the `buffer` property will return the entire buffer, and the `byteOffset` and `byteLength` properties will indicate the subset. + +```ts +const arr = new Uint8Array(64, 16, 32); +arr.buffer; // => ArrayBuffer(64) +arr.byteOffset; // => 16 +arr.byteLength; // => 32 +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/typedarray-to-blob.md b/docs/guides/binary/typedarray-to-blob.md new file mode 100644 index 000000000..e2ca301b8 --- /dev/null +++ b/docs/guides/binary/typedarray-to-blob.md @@ -0,0 +1,16 @@ +--- +name: Convert a Uint8Array to a Blob +--- + +A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) can be constructed from an array of "chunks", where each chunk is a string, binary data structure (including `Uint8Array`), or another `Blob`. + +```ts +const arr = new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f]); +const blob = new Blob([arr]); +console.log(await blob.text()); +// => "hello" +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/typedarray-to-buffer.md b/docs/guides/binary/typedarray-to-buffer.md new file mode 100644 index 000000000..e4013644a --- /dev/null +++ b/docs/guides/binary/typedarray-to-buffer.md @@ -0,0 +1,14 @@ +--- +name: Convert a Uint8Array to a Buffer +--- + +The [`Buffer`](https://nodejs.org/api/buffer.html) class extends [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) with a number of additional methods. Use `Buffer.from()` to create a `Buffer` instance from a `Uint8Array`. + +```ts +const arr: Uint8Array = ... +const buf = Buffer.from(arr); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/typedarray-to-dataview.md b/docs/guides/binary/typedarray-to-dataview.md new file mode 100644 index 000000000..dfef2166b --- /dev/null +++ b/docs/guides/binary/typedarray-to-dataview.md @@ -0,0 +1,14 @@ +--- +name: Convert a Uint8Array to a DataView +--- + +A [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is a _typed array_ class, meaning it is a mechanism for viewing data in an underlying `ArrayBuffer`. The following snippet creates a [`DataView`] instance over the same range of data as the `Uint8Array`. + +```ts +const arr: Uint8Array = ... +const dv = new DataView(arr.buffer, arr.byteOffset, arr.byteLength); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/typedarray-to-readablestream.md b/docs/guides/binary/typedarray-to-readablestream.md new file mode 100644 index 000000000..e60b6df2e --- /dev/null +++ b/docs/guides/binary/typedarray-to-readablestream.md @@ -0,0 +1,41 @@ +--- +name: Convert a Uint8Array to a ReadableStream +--- + +The naive approach to creating a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) from a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) is to use the [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) constructor and enqueue the entire array as a single chunk. For larger chunks, this may be undesirable as it isn't actually "streaming" the data. + +```ts +const arr = new Uint8Array(64); +const stream = new ReadableStream({ + start(controller) { + controller.enqueue(arr); + controller.close(); + }, +}); +``` + +--- + +To stream the data in smaller chunks, first create a `Blob` instance from the `Uint8Array`. Then use the [`Blob.stream()`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/stream) method to create a `ReadableStream` that streams the data in chunks of a specified size. + +```ts +const arr = new Uint8Array(64); +const blob = new Blob([arr]); +const stream = blob.stream(); +``` + +--- + +The chunk size can be set by passing a number to the `.stream()` method. + +``` +const arr = new Uint8Array(64); +const blob = new Blob([arr]); + +// set chunk size of 1024 bytes +const stream = blob.stream(1024); +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/binary/typedarray-to-string.md b/docs/guides/binary/typedarray-to-string.md new file mode 100644 index 000000000..9c5703420 --- /dev/null +++ b/docs/guides/binary/typedarray-to-string.md @@ -0,0 +1,16 @@ +--- +name: Convert a Uint8Array to a string +--- + +Bun implements the Web-standard [`TextDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) class for converting from binary data types like `Uint8Array` and strings. + +```ts +const arr = new Uint8Array([104, 101, 108, 108, 111]); +const decoder = new TextDecoder(); +const str = decoder.decode(buf); +// => "hello" +``` + +--- + +See [Docs > API > Binary Data](/docs/api/binary-data#conversion) for complete documentation on manipulating binary data with Bun. diff --git a/docs/guides/ecosystem/discordjs.md b/docs/guides/ecosystem/discordjs.md new file mode 100644 index 000000000..7d9541861 --- /dev/null +++ b/docs/guides/ecosystem/discordjs.md @@ -0,0 +1,77 @@ +--- +name: Create a Discord bot +--- + +Discord.js works [out of the box](https://bun.sh/blog/bun-v0.6.7) with Bun. Let's write a simple bot. First create a directory and initialize it with `bun init`. + +```bash +mkdir my-bot +cd my-bot +bun init +``` + +--- + +Now install Discord.js. + +```bash +bun add discord.js +``` + +--- + +Before we go further, we need to go to the [Discord developer portal](https://discord.com/developers/applications), login/signup, create a new _Application_, then create a new _Bot_ within that application. Follow the [official guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot) for step-by-step instructions. + +--- + +Once complete, you'll be presented with your bot's _private key_. Let's add this to a file called `.env.local`. Bun automatically reads this file and loads it into `process.env`. + +{% callout %} +This is an example token that has already been invalidated. +{% /callout %} + +```txt#.env.local +DISCORD_TOKEN=NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I +``` + +--- + +Be sure to add `.env.local` to your `.gitignore`! It is dangerous to check your bot's private key into version control. + +```txt#.gitignore +node_modules +.env.local +``` + +--- + +Now let's actually write our bot in a new file called `bot.ts`. + +```ts#bot.ts +// import discord.js +import {Client, Events, GatewayIntentBits} from 'discord.js'; + +// create a new Client instance +const client = new Client({intents: [GatewayIntentBits.Guilds]}); + +// listen for the client to be ready +client.once(Events.ClientReady, (c) => { + console.log(`Ready! Logged in as ${c.user.tag}`); +}); + +// login with the token from .env.local +client.login(process.env.DISCORD_TOKEN); +``` + +--- + +Now we can run our bot with `bun run`. It may take a several seconds for the client to initialize the first time you run the file. + +```bash +$ bun run bot.ts +Ready! Logged in as my-bot#1234 +``` + +--- + +You're up and running with a bare-bones Discord.js bot! This is a basic guide to setting up your bot with Bun; we recommend the [official Discord docs](https://discordjs.guide/) for complete information on the `discord.js` API. diff --git a/docs/guides/ecosystem/index.json b/docs/guides/ecosystem/index.json new file mode 100644 index 000000000..4099acec3 --- /dev/null +++ b/docs/guides/ecosystem/index.json @@ -0,0 +1,4 @@ +{ + "name": "Ecosystem", + "description": "A collection of guides for using various tools and frameworks with Bun" +} diff --git a/docs/guides/ecosystem/mongoose.md b/docs/guides/ecosystem/mongoose.md new file mode 100644 index 000000000..c2916ce82 --- /dev/null +++ b/docs/guides/ecosystem/mongoose.md @@ -0,0 +1,80 @@ +--- +name: Use MongoDB and Mongoose +--- + +MongoDB and Mongoose work out of the box with Bun. This guide assumes you've already installed MongoDB and are running it as background process/service on your development machine. Follow [this guide](https://www.mongodb.com/docs/manual/installation/) for details. + +--- + +Once MongoDB is running, create a directory and initialize it with `bun init`. + +```bash +mkdir mongoose-app +cd mongoose-app +bun init +``` + +--- + +Then add Mongoose as a dependency. + +```bash +bun add mongoose +``` + +--- + +In `schema.ts` we'll declare and export a simple `Animal` model. + +```ts#schema.ts +import * as mongoose from 'mongoose'; + +const animalSchema = new mongoose.Schema( + { + name: {type: String, required: true}, + sound: {type: String, required: true}, + } +); + +export type Animal = mongoose.InferSchemaType<typeof animalSchema>; +export const Animal = mongoose.model('Kitten', animalSchema); +``` + +--- + +Now from `index.ts` we can import `Animal`, connect to MongoDB, and add some data to our database. + +```ts#index.ts +import * as mongoose from 'mongoose'; +import {Animal} from './schema'; + +// connect to database +await mongoose.connect('mongodb://127.0.0.1:27017/mongoose-app'); + +// create new Animal +const cow = new Animal({ + name: 'Cow', + sound: 'Moo', +}); +await cow.save(); // saves to the database + +// read all Animals +const animals = await Animal.find(); +animals[0].speak(); // logs "Moo!" + +// disconect +await mongoose.disconnect(); +``` + +--- + +Lets run this with `bun run`. + +```bash +$ bun run index.ts +Moo! +``` + +--- + +This is a simple introduction to using Mongoose with TypeScript and Bun. As you build your application, refer to the official [MongoDB](https://docs.mongodb.com/) and [Mongoose](https://mongoosejs.com/docs/) sites for complete documentation. diff --git a/docs/guides/ecosystem/prisma.md b/docs/guides/ecosystem/prisma.md new file mode 100644 index 000000000..39627b806 --- /dev/null +++ b/docs/guides/ecosystem/prisma.md @@ -0,0 +1,110 @@ +--- +name: Use Prisma +--- + +Prisma works our of the box with Bun. First, create a directory and initialize it with `bun init`. + +```bash +mkdir prisma-app +cd prisma-app +bun init +``` + +--- + +Then add Prisma as a dependency. + +```bash +bun add prisma +``` + +--- + +We'll use the Prisma CLI with `bunx` to initialize our schema and migration directory. For simplicity we'll be using an in-memory SQLite database. + +```bash +bunx prisma init --datasource-provider sqlite +``` + +--- + +Open `prisma/schema.prisma` and add a simple `User` model. + +```prisma-diff#prisma/schema.prisma + generator client { + provider = "prisma-client-js" + } + + datasource db { + provider = "sqlite" + url = env("DATABASE_URL") + } + ++ model User { ++ id Int @id @default(autoincrement()) ++ email String @unique ++ name String? ++ } +``` + +--- + +Then generate and run initial migration. + +This will generate a `.sql` migration file in `prisma/migrations`, create a new SQLite instance, and execute the migration against the new instance. + +```bash +bunx prisma migrate dev --name init +``` + +--- + +Prisma automatically generates our _Prisma client_ whenever we execute a new migration. The client provides a fully typed API for reading and writing from our database. + +It can be imported from `@prisma/client`. + +```ts#src/index.ts +import {PrismaClient} from "@prisma/client"; +``` + +--- + +Let's write a simple script to create a new user, then count the number of users in the database. + +```ts#index.ts +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +// create a new user +await prisma.user.create({ + data: { + name: "John Dough", + email: `john-${Math.random()}@example.com`, + }, +}); + +// count the number of users +const count = await prisma.user.count(); +console.log(`There are ${count} users in the database.`); +``` + +--- + +Let's run this script with `bun run`. Each time we run it, a new user is created. + +```bash +$ bun run index.ts +Created john-0.12802932895402364@example.com +There are 1 users in the database. +$ bun run index.ts +Created john-0.8671308799782803@example.com +There are 2 users in the database. +$ bun run index.ts +Created john-0.4465968383115295@example.com +There are 3 users in the database. +``` + +--- + +That's it! Now that you've set up Prisma using Bun, we recommend referring to the [official Prisma docs](https://www.prisma.io/docs/concepts/components/prisma-client) as you continue to develop your application. diff --git a/docs/guides/ecosystem/vite.md b/docs/guides/ecosystem/vite.md new file mode 100644 index 000000000..cee5e6013 --- /dev/null +++ b/docs/guides/ecosystem/vite.md @@ -0,0 +1,71 @@ +--- +name: Use Vite +--- + +{% callout %} +While Vite currently works with Bun, it has not been heavily optimized, nor has Vite been adapted to use Bun's bundler, module resolver, or transpiler. +{% /callout %} + +--- + +Vite works out of the box with Bun (v0.7 and later). Get started with one of Vite's templates. + +```bash +$ bunx create-vite my-app +✔ Select a framework: › React +✔ Select a variant: › TypeScript + SWC +Scaffolding project in /path/to/my-app... +``` + +--- + +Then `cd` into the project directory and install dependencies. + +```bash +cd my-app +bun install +``` + +--- + +Start the development server with the `vite` CLI using `bunx`. + +The `--bun` flag tells Bun to run Vite's CLI using `bun` instead of `node`; by default Bun respects Vite's `#!/usr/bin/env node` [shebang line](<https://en.wikipedia.org/wiki/Shebang_(Unix)>). After Bun 1.0 this flag will no longer be necessary. + +```bash +bunx --bun vite +``` + +--- + +To simplify this command, update the `"dev"` script in `package.json` to the following. + +```json-diff#package.json + "scripts": { +- "dev": "vite", ++ "dev": "bunx --bun vite", + "build": "vite build", + "serve": "vite preview" + }, + // ... +``` + +--- + +Now you can start the development server with `bun run dev`. + +```bash +bun run dev +``` + +--- + +The following command will build your app for production. + +```sh +$ bunx --bun vite build +``` + +--- + +This is a stripped down guide to get you started with Vite + Bun. For more information, see the [Vite documentation](https://vitejs.dev/guide/). diff --git a/docs/guides/http/hot.md b/docs/guides/http/hot.md new file mode 100644 index 000000000..c033e5be5 --- /dev/null +++ b/docs/guides/http/hot.md @@ -0,0 +1,55 @@ +--- +name: Hot reload an HTTP server +--- + +Bun supports the [`--hot`](/docs/runtime/hot#hot-mode) flag to run a file with hot reloading enabled. When any module or file changes, Bun re-runs the file. + +```sh +bun --hot run index.ts +``` + +--- + +To avoid re-running `Bun.serve()` during `--hot` reloads, you should assign the `Server` instance as a property of `globalThis`. The `globalThis` object survives hot reloads. + +```ts +import { type Serve, type Server } from "bun"; + +// make TypeScript happy +declare global { + var server: Server; +} + +// define server parameters +const serveOptions: Serve = { + port: 3000, + fetch(req) { + return new Response(`Hello world`); + }, +}; + +if (!globalThis.server) { + globalThis.server = Bun.serve(serveOptions); +} else { + globalThis.server.reload(serveOptions); +} +``` + +--- + +To avoid manually calling `server.reload()`, you can use start a server with Bun's [object syntax](/docs/runtime/hot#http-servers). If you `export default` a plain object with a `fetch` handler defined, then run this file with Bun, Bun will start an HTTP server as if you'd passed this object into `Bun.serve()`. + +With this approach, Bun automatically reloads the server when reloads happen. + +See [HTTP > Hot Reloading](<[/docs/api/http](https://bun.sh/docs/api/http#hot-reloading)>) for full docs. + +```ts +import { type Serve } from "bun"; + +export default { + port: 3000, + fetch(req) { + return new Response(`Hello world`); + }, +} satisfies Serve; +``` diff --git a/docs/guides/http/index.json b/docs/guides/http/index.json new file mode 100644 index 000000000..d018e1bdd --- /dev/null +++ b/docs/guides/http/index.json @@ -0,0 +1,4 @@ +{ + "name": "HTTP", + "description": "A collection of guides for building HTTP servers with Bun" +} diff --git a/docs/guides/http/simple.md b/docs/guides/http/simple.md new file mode 100644 index 000000000..be5147541 --- /dev/null +++ b/docs/guides/http/simple.md @@ -0,0 +1,18 @@ +--- +name: Write a simple HTTP server +--- + +This starts an HTTP server listening on port `3000`. It responds to all requests with a `Response` with status `200` and body `"Welcome to Bun!"`. + +See [`Bun.serve`](/docs/api/http) for details. + +```ts +const server = Bun.serve({ + port: 3000, + fetch(request) { + return new Response("Welcome to Bun!"); + }, +}); + +console.log(`Listening on localhost:\${server.port}`); +``` diff --git a/docs/guides/http/stream-file.md b/docs/guides/http/stream-file.md new file mode 100644 index 000000000..66c8c247b --- /dev/null +++ b/docs/guides/http/stream-file.md @@ -0,0 +1,48 @@ +--- +name: Stream a file as an HTTP Response +--- + +This snippet reads a file from disk using [`Bun.file()`](/docs/api/file-io#reading-files-bun-file). This returns a `BunFile` instance, which can be passed directly into the `new Response` constructor. + +```ts +const path = "/path/to/file.txt"; +const file = Bun.file(path); +const resp = new Response(file); +``` + +--- + +The `Content-Type` is read from the file and automatically set on the `Response`. + +```ts +new Response(Bun.file("./package.json")).headers.get("Content-Type"); +// => application/json;charset=utf-8 + +new Response(Bun.file("./test.txt")).headers.get("Content-Type"); +// => text/plain;charset=utf-8 + +new Response(Bun.file("./index.tsx")).headers.get("Content-Type"); +// => text/javascript;charset=utf-8 + +new Response(Bun.file("./img.png")).headers.get("Content-Type"); +// => image/png +``` + +--- + +Putting it all together with [`Bun.serve()`](/docs/api/http#serving-files-bun-serve). + +```ts +// static file server +Bun.serve({ + async fetch(req) { + const path = new URL(req.url).pathname; + const file = Bun.file(path); + return new Response(file); + }, +}); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/http/tls.md b/docs/guides/http/tls.md new file mode 100644 index 000000000..a7e59dfea --- /dev/null +++ b/docs/guides/http/tls.md @@ -0,0 +1,30 @@ +--- +name: Configure TLS on an HTTP server +--- + +Set the `tls` key to configure TLS. Both `key` and `cert` are required. The `key` should be the contents of your private key; `cert` should be the contents of your issued certificate. Use [`Bun.file()`](/docs/api/file-io#reading-files-bun-file) to read the contents. + +```ts +const server = Bun.serve({ + fetch: (request) => new Response("Welcome to Bun!"), + tls: { + cert: Bun.file("cert.pem"), + key: Bun.file("key.pem"), + }, +}); +``` + +--- + +By default Bun trusts the default Mozilla-curated list of well-known root CAs. To override this list, pass an array of certificates as `ca`. + +```ts +const server = Bun.serve({ + fetch: (request) => new Response("Welcome to Bun!"), + tls: { + cert: Bun.file("cert.pem"), + key: Bun.file("key.pem"), + ca: [Bun.file("ca1.pem"), Bun.file("ca2.pem")], + }, +}); +``` diff --git a/docs/guides/process/argv.md b/docs/guides/process/argv.md new file mode 100644 index 000000000..f9f3c77e4 --- /dev/null +++ b/docs/guides/process/argv.md @@ -0,0 +1,22 @@ +--- +name: Parse command-line arguments +--- + +The _argument vector_ is the list of arguments passed to the program when it is run. It is available as `Bun.argv`. + +```ts#cli.ts +console.log(Bun.argv); +``` + +--- + +Running this file with arguments results in the following: + +```sh +$ bun run cli.tsx --flag1 --flag2 value +[ '/path/to/bun', '/path/to/cli.ts', '--flag1', '--flag2', 'value' ] +``` + +--- + +To parse `argv` into a more useful format, consider using [minimist](https://github.com/minimistjs/minimist) or [commander](https://github.com/tj/commander.js). diff --git a/docs/guides/process/ctrl-c.md b/docs/guides/process/ctrl-c.md new file mode 100644 index 000000000..b880cf62c --- /dev/null +++ b/docs/guides/process/ctrl-c.md @@ -0,0 +1,16 @@ +--- +name: Listen for CTRL+C +--- + +The `ctrl+c` shortcut sends an _interrupt signal_ to the running process. This signal can be intercepted by listening for the `SIGINT` event. If you want to close the process, you must explicitly call `process.exit()`. + +```ts +process.on("SIGINT", () => { + console.log("Ctrl-C was pressed"); + process.exit(); +}); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/process/index.json b/docs/guides/process/index.json new file mode 100644 index 000000000..df0384544 --- /dev/null +++ b/docs/guides/process/index.json @@ -0,0 +1,4 @@ +{ + "name": "Processes", + "description": "A collection of guides for inspecting the current process and creating child processes with Bun" +} diff --git a/docs/guides/process/nanoseconds.md b/docs/guides/process/nanoseconds.md new file mode 100644 index 000000000..b8aee8123 --- /dev/null +++ b/docs/guides/process/nanoseconds.md @@ -0,0 +1,13 @@ +--- +name: Get the process uptime in nanoseconds +--- + +Use `Bun.nanoseconds()` to get the total number of nanoseconds the `bun` process has been alive. + +```ts +Bun.nanoseconds(); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/process/os-signals.md b/docs/guides/process/os-signals.md new file mode 100644 index 000000000..ae7b9896f --- /dev/null +++ b/docs/guides/process/os-signals.md @@ -0,0 +1,39 @@ +--- +name: Listen to OS signals +--- + +Bun supports the Node.js `process` global, including the `process.on()` method for listening to OS signals. + +```ts +process.on("SIGINT", () => { + console.log("Received SIGINT"); +}); +``` + +--- + +If you don't know which signal to listen for, you listen to the umbrella `"exit"` event. + +```ts +process.on("exit", (code) => { + console.log(`Process exited with code ${code}`); +}); +``` + +--- + +If you don't know which signal to listen for, you listen to the [`"beforeExit"`](https://nodejs.org/api/process.html#event-beforeexit) and [`"exit"`](https://nodejs.org/api/process.html#event-exit) events. + +```ts +process.on("beforeExit", (code) => { + console.log(`Event loop is empty!`); +}); + +process.on("exit", (code) => { + console.log(`Process is exiting with code ${code}`); +}); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/process/spawn-stderr.md b/docs/guides/process/spawn-stderr.md new file mode 100644 index 000000000..3ea56b24e --- /dev/null +++ b/docs/guides/process/spawn-stderr.md @@ -0,0 +1,31 @@ +--- +name: Read stderr from a child process +--- + +When using [`Bun.spawn()`](/docs/api/spawn), the child process inherits the `stderr` of the spawning process. If instead you'd prefer to read and handle `stderr`, set the `stderr` option to `"pipe"`. + +```ts +const proc = Bun.spawn(["echo", "hello"], { + stderr: "pipe", +}); +proc.stderr; // => ReadableStream +``` + +--- + +To read `stderr` until the child process exits, use the [`Bun.readableStreamToText()`](/docs/api/utils#bun-readablestreamto) convenience function. + +```ts +const proc = Bun.spawn(["echo", "hello"], { + stderr: "pipe", +}); + +const errors: string = await Bun.readableStreamToText(proc.stderr); +if (errors) { + // handle errors +} +``` + +--- + +See [Docs > API > Child processes](/docs/api/spawn) for complete documentation.. diff --git a/docs/guides/process/spawn-stdout.md b/docs/guides/process/spawn-stdout.md new file mode 100644 index 000000000..490e8b143 --- /dev/null +++ b/docs/guides/process/spawn-stdout.md @@ -0,0 +1,26 @@ +--- +name: Read stdout from a child process +--- + +When using [`Bun.spawn()`](/docs/api/spawn), the `stdout` of the child process can be consumed as a `ReadableStream` via `proc.stdout`. + +```ts +const proc = Bun.spawn(["echo", "hello"]); + +const output = await new Response(proc.stdout).text(); +output; // => "hello" +``` + +--- + +To instead pipe the `stdout` of the child process to `stdout` of the parent process, set "inherit". + +```ts +const proc = Bun.spawn(["echo", "hello"], { + stdout: "inherit", +}); +``` + +--- + +See [Docs > API > Child processes](/docs/api/spawn) for complete documentation.. diff --git a/docs/guides/process/spawn.md b/docs/guides/process/spawn.md new file mode 100644 index 000000000..2a6589458 --- /dev/null +++ b/docs/guides/process/spawn.md @@ -0,0 +1,41 @@ +--- +name: Spawn a child process +--- + +Use [`Bun.spawn()`](/docs/api/spawn) to spawn a child process. + +```ts +const proc = Bun.spawn(["echo", "hello"]); + +// await completion +await proc.exited; +``` + +--- + +The second argument accepts a configuration object. + +```ts +const proc = Bun.spawn("echo", ["Hello, world!"], { + cwd: "/tmp", + env: { FOO: "bar" }, + onExit(proc, exitCode, signalCode, error) { + // exit handler + }, +}); +``` + +--- + +By default, the `stdout` of the child process can be consumed as a `ReadableStream` using `proc.stdout`. + +```ts +const proc = Bun.spawn(["echo", "hello"]); + +const output = await new Response(proc.stdout).text(); +output; // => "hello" +``` + +--- + +See [Docs > API > Child processes](/docs/api/spawn) for complete documentation.. diff --git a/docs/guides/process/stdin.md b/docs/guides/process/stdin.md new file mode 100644 index 000000000..c19c9e106 --- /dev/null +++ b/docs/guides/process/stdin.md @@ -0,0 +1,54 @@ +--- +name: Read from stdin +--- + +For CLI tools, it's often useful to read from `stdin`. In Bun, the `console` object is an `AsyncIterable` that yields lines from `stdin`. + +```ts#index.ts +const prompt = "Type something: "; +process.stdout.write(prompt); +for await (const line of console) { + console.log(`You typed: ${line}`); + process.stdout.write(prompt); +} +``` + +--- + +Running this file results in a never-ending interactive prompt that echoes whatever the user types. + +```sh +$ bun run index.tsx +Type something: hello +You typed: hello +Type something: hello again +You typed: hello again +``` + +--- + +Bun also exposes stdin as a `BunFile` via `Bun.stdin`. This is useful for incrementally reading large inputs that are piped into the `bun` process. + +There is no guarantee that the chunks will be split line-by-line. + +```ts#stdin.ts +for await (const chunk of Bun.stdin.stream()) { + // chunk is Uint8Array + // this converts it to text (assumes ASCII encoding) + const chunkText = Buffer.from(chunk).toString(); + console.log(`Chunk: ${chunkText}`); +} +``` + +--- + +This will print the input that is piped into the `bun` process. + +```sh +$ echo "hello" | bun run stdin.ts +Chunk: hello +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/read-file/arraybuffer.md b/docs/guides/read-file/arraybuffer.md new file mode 100644 index 000000000..149b08d8e --- /dev/null +++ b/docs/guides/read-file/arraybuffer.md @@ -0,0 +1,28 @@ +--- +name: Read a file to an ArrayBuffer +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.arrayBuffer()` to read the file as an `ArrayBuffer`. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +const buffer = await file.arrayBuffer(); +``` + +--- + +The binary content in the `ArrayBuffer` can then be read as a typed array, such as `Uint8Array`. + +```ts +const buffer = await file.arrayBuffer(); +const bytes = new Uint8Array(buffer); + +bytes[0]; +bytes.length; +``` + +--- + +Refer to the [Typed arrays](/docs/api/binary-data#typedarray) docs for more information on working with typed arrays in Bun. diff --git a/docs/guides/read-file/buffer.md b/docs/guides/read-file/buffer.md new file mode 100644 index 000000000..d27fa1489 --- /dev/null +++ b/docs/guides/read-file/buffer.md @@ -0,0 +1,19 @@ +--- +name: Read a file to a Buffer +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. + +To read the file into a `Buffer` instance, first use `.arrayBuffer()` to consume the file as an `ArrayBuffer`, then use `Buffer.from()` to create a `Buffer` from the `ArrayBuffer`. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +const arrbuf = await file.arrayBuffer(); +const buffer = Buffer.from(arrbuf); +``` + +--- + +Refer to [Binary data > Buffer](/docs/api/binary-data#buffer) for more information on working with `Buffer` and other binary data formats in Bun. diff --git a/docs/guides/read-file/exists.md b/docs/guides/read-file/exists.md new file mode 100644 index 000000000..fd6cbbf9a --- /dev/null +++ b/docs/guides/read-file/exists.md @@ -0,0 +1,16 @@ +--- +name: Check if a file exists +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. Use the `.exists()` method to check if a file exists at the given path. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +file.exists(); // boolean; +``` + +--- + +Refer to [API > File I/O](/docs/api/file-io) for more information on working with `BunFile`. diff --git a/docs/guides/read-file/index.json b/docs/guides/read-file/index.json new file mode 100644 index 000000000..321fd96e2 --- /dev/null +++ b/docs/guides/read-file/index.json @@ -0,0 +1,4 @@ +{ + "name": "Reading files", + "description": "A collection of guides for reading files with Bun" +} diff --git a/docs/guides/read-file/json.md b/docs/guides/read-file/json.md new file mode 100644 index 000000000..3b7488472 --- /dev/null +++ b/docs/guides/read-file/json.md @@ -0,0 +1,34 @@ +--- +name: Read a JSON file +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.json()` to read and parse the contents of a `.json` file as a plain object. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +const contents = await file.json(); +// { name: "my-package" } +``` + +--- + +The MIME type of the `BunFile` will be set accordingly. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +file.type; // => "application/json;charset=utf-8"; +``` + +--- + +If the path to the `.json` file is static, it can be directly imported as a module. + +```ts +import pkg from "./package.json"; + +pkg.name; // => "my-package" +``` diff --git a/docs/guides/read-file/mime.md b/docs/guides/read-file/mime.md new file mode 100644 index 000000000..44a8e6860 --- /dev/null +++ b/docs/guides/read-file/mime.md @@ -0,0 +1,20 @@ +--- +name: Get the MIME type of a file +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob`, so use the `.type` property to read the MIME type. + +```ts +const file = Bun.file("./package.json"); +file.type; // application/json + +const file = Bun.file("./index.html"); +file.type; // text/html + +const file = Bun.file("./image.png"); +file.type; // image/png +``` + +--- + +Refer to [API > File I/O](/docs/api/file-io) for more information on working with `BunFile`. diff --git a/docs/guides/read-file/stream.md b/docs/guides/read-file/stream.md new file mode 100644 index 000000000..6b88c3672 --- /dev/null +++ b/docs/guides/read-file/stream.md @@ -0,0 +1,26 @@ +--- +name: Read a file as a ReadableStream +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.stream()` to consume the file incrementally as a `ReadableStream`. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +const stream = await file.stream(); +``` + +--- + +The chunks of the stream can be consumed with `for await`. + +```ts +for await (const chunk of stream.values()) { + chunk; // => Uint8Array +} +``` + +--- + +Refer to the [Streams](/docs/api/streams) documentation for more information on working with streams in Bun. diff --git a/docs/guides/read-file/string.md b/docs/guides/read-file/string.md new file mode 100644 index 000000000..08cdfd952 --- /dev/null +++ b/docs/guides/read-file/string.md @@ -0,0 +1,22 @@ +--- +name: Read a file as a string +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. Use `.text()` to read the contents as a string. + +```ts +const path = "/path/to/file.txt"; +const file = Bun.file(path); + +const text = await file.text(); +// string +``` + +--- + +Any relative paths will be resolved relative to the project root (the nearest directory containing a `package.json` file). + +```ts +const path = "./file.txt"; +const file = Bun.file(path); +``` diff --git a/docs/guides/read-file/uint8array.md b/docs/guides/read-file/uint8array.md new file mode 100644 index 000000000..1afcaa797 --- /dev/null +++ b/docs/guides/read-file/uint8array.md @@ -0,0 +1,22 @@ +--- +name: Read a file to a Uint8Array +--- + +The `Bun.file()` function accepts a path and returns a `BunFile` instance. The `BunFile` class extends `Blob` and allows you to lazily read the file in a variety of formats. + +To read the file into a `Uint8Array` instance, retrieve the contents of the `BunFile` as an `ArrayBuffer` with `.arrayBuffer()`, then pass it into the `Uint8Array` constructor. + +```ts +const path = "/path/to/package.json"; +const file = Bun.file(path); + +const arrBuffer = await file.arrayBuffer(); +const byteArray = new Uint8Array(arrBuffer); + +byteArray[0]; // first byteArray +byteArray.length; // length of byteArray +``` + +--- + +Refer to [API > Binary data > Typed arrays](/docs/api/binary-data#typedarray) for more information on working with `Uint8Array` and other binary data formats in Bun. diff --git a/docs/guides/read-file/watch.md b/docs/guides/read-file/watch.md new file mode 100644 index 000000000..0c38a0ece --- /dev/null +++ b/docs/guides/read-file/watch.md @@ -0,0 +1,68 @@ +--- +name: Watch a directory for changes +--- + +Bun implements the `node:fs` module, including the `fs.watch` function for listening for file system changes. + +This code block listens for changes to files in the current directory. By default this operation is _shallow_, meaning that changes to files in subdirectories will not be detected. + +```ts +import { watch } from "fs"; + +const watcher = watch(import.meta.dir, (event, filename) => { + console.log(`Detected ${event} in ${filename}`); +}); +``` + +--- + +To listen to changes in subdirectories, pass the `recursive: true` option to `fs.watch`. + +```ts +import { watch } from "fs"; + +const watcher = watch( + import.meta.dir, + { recursive: true }, + (event, filename) => { + console.log(`Detected ${event} in ${filename}`); + }, +); +``` + +--- + +Using the `node:fs/promises` module, you can listen for changes using `for await...of` instead of a callback. + +```ts +import { watch } from "fs/promises"; + +const watcher = watch(import.meta.dir); +for await (const event of watcher) { + console.log(`Detected ${event.eventType} in ${event.filename}`); +} +``` + +--- + +To stop listening for changes, call `watcher.close()`. It's common to do this when the process receives a `SIGINT` signal, such as when the user presses Ctrl-C. + +```ts +import { watch } from "fs"; + +const watcher = watch(import.meta.dir, (event, filename) => { + console.log(`Detected ${event} in ${filename}`); +}); + +process.on("SIGINT", () => { + // close watcher when Ctrl-C is pressed + console.log("Closing watcher..."); + watcher.close(); + + process.exit(0); +}); +``` + +--- + +Refer to [API > Binary data > Typed arrays](/docs/api/binary-data#typedarray) for more information on working with `Uint8Array` and other binary data formats in Bun. diff --git a/docs/guides/streams/index.json b/docs/guides/streams/index.json new file mode 100644 index 000000000..da6ff2629 --- /dev/null +++ b/docs/guides/streams/index.json @@ -0,0 +1,4 @@ +{ + "name": "Streams", + "description": "A collection of guides for manipulating streams with Bun" +} diff --git a/docs/guides/streams/to-array.md b/docs/guides/streams/to-array.md new file mode 100644 index 000000000..bca40cf12 --- /dev/null +++ b/docs/guides/streams/to-array.md @@ -0,0 +1,14 @@ +--- +name: Convert a ReadableStream to an array of chunks +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. The `Bun.readableStreamToArray` function reads the contents of a `ReadableStream` to an array of chunks. + +```ts +const stream = new ReadableStream(); +const str = await Bun.readableStreamToArray(stream); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-arraybuffer.md b/docs/guides/streams/to-arraybuffer.md new file mode 100644 index 000000000..b20d96a04 --- /dev/null +++ b/docs/guides/streams/to-arraybuffer.md @@ -0,0 +1,14 @@ +--- +name: Convert a ReadableStream to an ArrayBuffer +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. + +```ts +const stream = new ReadableStream(); +const buf = await Bun.readableStreamToArrayBuffer(stream); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-blob.md b/docs/guides/streams/to-blob.md new file mode 100644 index 000000000..3380dca38 --- /dev/null +++ b/docs/guides/streams/to-blob.md @@ -0,0 +1,14 @@ +--- +name: Convert a ReadableStream to a Blob +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. + +```ts +const stream = new ReadableStream(); +const blob = await Bun.readableStreamToBlob(stream); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-buffer.md b/docs/guides/streams/to-buffer.md new file mode 100644 index 000000000..d6450d644 --- /dev/null +++ b/docs/guides/streams/to-buffer.md @@ -0,0 +1,15 @@ +--- +name: Convert a ReadableStream to a Buffer +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. This snippet reads the contents of a `ReadableStream` to an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), then creates a [`Buffer`](https://nodejs.org/api/buffer.html) that points to it. + +```ts +const stream = new ReadableStream(); +const arrBuf = await Bun.readableStreamToArrayBuffer(stream); +const nodeBuf = Buffer.from(arrBuf); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-json.md b/docs/guides/streams/to-json.md new file mode 100644 index 000000000..cf9e7c71e --- /dev/null +++ b/docs/guides/streams/to-json.md @@ -0,0 +1,14 @@ +--- +name: Convert a ReadableStream to a JSON +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. + +```ts +const stream = new ReadableStream(); +const json = await Bun.readableStreamToJSON(stream); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-string.md b/docs/guides/streams/to-string.md new file mode 100644 index 000000000..a5963ae14 --- /dev/null +++ b/docs/guides/streams/to-string.md @@ -0,0 +1,14 @@ +--- +name: Convert a ReadableStream to a string +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. + +```ts +const stream = new ReadableStream(); +const str = await Bun.readableStreamToString(stream); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/streams/to-typedarray.md b/docs/guides/streams/to-typedarray.md new file mode 100644 index 000000000..faa18e4ad --- /dev/null +++ b/docs/guides/streams/to-typedarray.md @@ -0,0 +1,15 @@ +--- +name: Convert a ReadableStream to a Uint8Array +--- + +Bun provides a number of convenience functions for reading the contents of a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) into different formats. This snippet reads the contents of a `ReadableStream` to an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), then creates a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) that points to the buffer. + +```ts +const stream = new ReadableStream(); +const buf = await Bun.readableStreamToArrayBuffer(stream); +const uint8 = new Uint8Array(buf); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils#bun-readablestreamto) for documentation on Bun's other `ReadableStream` conversion functions. diff --git a/docs/guides/util/deep-equals.md b/docs/guides/util/deep-equals.md new file mode 100644 index 000000000..9d8dc74d4 --- /dev/null +++ b/docs/guides/util/deep-equals.md @@ -0,0 +1,39 @@ +--- +name: Check if two objects are deeply equal +--- + +Check if two objects are deeply equal. This is used internally by `expect().toEqual()` in Bun's [test runner](/docs/test/writing). + +```ts#index.ts +const a = { a: 1, b: 2, c: { d: 3 } }; +const b = { a: 1, b: 2, c: { d: 3 } }; + +Bun.deepEquals(a, b); // true +``` + +--- + +Pass `true` as a third argument to enable strict mode. This is used internally by `expect().toStrictEqual()` in Bun's [test runner](/docs/test/writing). + +The following examples would return `true` in non-strict mode but `false` in strict mode. + +```ts +// undefined values +Bun.deepEquals({}, { a: undefined }, true); // false + +// undefined in arrays +Bun.deepEquals(["asdf"], ["asdf", undefined], true); // false + +// sparse arrays +Bun.deepEquals([, 1], [undefined, 1], true); // false + +// object literals vs instances w/ same properties +class Foo { + a = 1; +} +Bun.deepEquals(new Foo(), { a: 1 }, true); // false +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/deflate.md b/docs/guides/util/deflate.md new file mode 100644 index 000000000..91dd8925a --- /dev/null +++ b/docs/guides/util/deflate.md @@ -0,0 +1,18 @@ +--- +name: Compress and decompress data with DEFLATE +--- + +Use `Bun.deflateSync()` to compress a `Uint8Array` with DEFLATE. + +```ts +const data = Buffer.from("Hello, world!"); +const compressed = Bun.deflateSync("Hello, world!"); +// => Uint8Array + +const decompressed = Bun.inflateSync(compressed); +// => Uint8Array +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/entrypoint.md b/docs/guides/util/entrypoint.md new file mode 100644 index 000000000..e53d4c9a1 --- /dev/null +++ b/docs/guides/util/entrypoint.md @@ -0,0 +1,17 @@ +--- +name: Check if the current file is the entrypoint +--- + +Bun provides a handful of module-specific utilities on the [`import.meta`](/docs/api/import-meta) object. Use `import.meta.main` to check if the current file is the entrypoint of the current process. + +```ts#index.ts +if(import.meta.main){ + // this file is directly executed with `bun run` +}else{ + // this file is being imported by another file +} +``` + +--- + +See [Docs > API > import.meta](/docs/api/import-meta) for complete documentation. diff --git a/docs/guides/util/escape-html.md b/docs/guides/util/escape-html.md new file mode 100644 index 000000000..4d88fb857 --- /dev/null +++ b/docs/guides/util/escape-html.md @@ -0,0 +1,22 @@ +--- +name: Escape an HTML string +--- + +The `Bun.escapeHTML()` utility can be used to escape HTML characters in a string. The following replacements are made. + +- `"` becomes `"""` +- `&` becomes `"&"` +- `'` becomes `"'"` +- `<` becomes `"<"` +- `>` becomes `">"` + +This function is optimized for large input. Non-string types will be converted to a string before escaping. + +```ts +Bun.escapeHTML("<script>alert('Hello World!')</script>"); +// <script>alert('Hello World!')</script> +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/file-url-to-path.md b/docs/guides/util/file-url-to-path.md new file mode 100644 index 000000000..0464504a6 --- /dev/null +++ b/docs/guides/util/file-url-to-path.md @@ -0,0 +1,14 @@ +--- +name: Convert a file URL to an absolute path +--- + +Use `Bun.fileURLToPath()` to convert a `file://` URL to an absolute path. + +```ts +Bun.fileURLToPath("file:///path/to/file.txt"); +// => "/path/to/file.txt" +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/gzip.md b/docs/guides/util/gzip.md new file mode 100644 index 000000000..c755b7c8b --- /dev/null +++ b/docs/guides/util/gzip.md @@ -0,0 +1,18 @@ +--- +name: Compress and decompress data with gzip +--- + +Use `Bun.gzipSync()` to compress a `Uint8Array` with gzip. + +```ts +const data = Buffer.from("Hello, world!"); +const compressed = Bun.gzipSync("Hello, world!"); +// => Uint8Array + +const decompressed = Bun.gunzipSync(compressed); +// => Uint8Array +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/import-meta-dir.md b/docs/guides/util/import-meta-dir.md new file mode 100644 index 000000000..edfa02372 --- /dev/null +++ b/docs/guides/util/import-meta-dir.md @@ -0,0 +1,13 @@ +--- +name: Get the directory of the current file +--- + +Bun provides a handful of module-specific utilities on the [`import.meta`](/docs/api/import-meta) object. + +```ts#/a/b/c.ts +import.meta.dir; // => "/a/b" +``` + +--- + +See [Docs > API > import.meta](/docs/api/import-meta) for complete documentation. diff --git a/docs/guides/util/import-meta-file.md b/docs/guides/util/import-meta-file.md new file mode 100644 index 000000000..8edf262b2 --- /dev/null +++ b/docs/guides/util/import-meta-file.md @@ -0,0 +1,13 @@ +--- +name: Get the file name of the current file +--- + +Bun provides a handful of module-specific utilities on the [`import.meta`](/docs/api/import-meta) object. Use `import.meta.file` to retreive the name of the current file. + +```ts#/a/b/c.ts +import.meta.file; // => "c.ts" +``` + +--- + +See [Docs > API > import.meta](/docs/api/import-meta) for complete documentation. diff --git a/docs/guides/util/import-meta-path.md b/docs/guides/util/import-meta-path.md new file mode 100644 index 000000000..b93670a38 --- /dev/null +++ b/docs/guides/util/import-meta-path.md @@ -0,0 +1,13 @@ +--- +name: Get the absolute path of the current file +--- + +Bun provides a handful of module-specific utilities on the [`import.meta`](/docs/api/import-meta) object. Use `import.meta.path` to retreive the absolute path of the current file. + +```ts#/a/b/c.ts +import.meta.path; // => "/a/b/c.ts" +``` + +--- + +See [Docs > API > import.meta](/docs/api/import-meta) for complete documentation. diff --git a/docs/guides/util/index.json b/docs/guides/util/index.json new file mode 100644 index 000000000..7e988ae25 --- /dev/null +++ b/docs/guides/util/index.json @@ -0,0 +1,4 @@ +{ + "name": "Utilities", + "description": "A collection of guides relating to Bun's array of built-in utility functions" +} diff --git a/docs/guides/util/main.md b/docs/guides/util/main.md new file mode 100644 index 000000000..e34fcd8f7 --- /dev/null +++ b/docs/guides/util/main.md @@ -0,0 +1,32 @@ +--- +name: Get the absolute path to the current entrypoint +--- + +The `Bun.main` property contains the absolute path to the current entrypoint. + +{% codetabs %} + +```ts#foo.ts +console.log(Bun.main); +``` + +```ts#index.ts +import "./foo.ts"; +``` + +{% /codetabs %} + +--- + +The printed path corresponds to the file that is executed with `bun run`. + +```sh +$ bun run index.ts +/path/to/index.ts +$ bun run foo.ts +/path/to/foo.ts +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/path-to-file-url.md b/docs/guides/util/path-to-file-url.md new file mode 100644 index 000000000..202be61eb --- /dev/null +++ b/docs/guides/util/path-to-file-url.md @@ -0,0 +1,14 @@ +--- +name: Convert an absolute path to a file URL +--- + +Use `Bun.pathToFileURL()` to convert an absolute path to a `file://` URL. + +```ts +Bun.pathToFileURL("/path/to/file.txt"); +// => "file:///path/to/file.txt" +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/sleep.md b/docs/guides/util/sleep.md new file mode 100644 index 000000000..dbc39c057 --- /dev/null +++ b/docs/guides/util/sleep.md @@ -0,0 +1,22 @@ +--- +name: Sleep for a fixed number of milliseconds +--- + +The `Bun.sleep` method provides a convenient way to create a void `Promise` that resolves in a fixed number of milliseconds. + +```ts +// sleep for 1 second +await Bun.sleep(1000); +``` + +--- + +Internally, this is equivalent to the following snippet that uses [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout). + +```ts +await new Promise((resolve) => setTimeout(resolve, ms)); +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/util/version.md b/docs/guides/util/version.md new file mode 100644 index 000000000..c1f5b8bfa --- /dev/null +++ b/docs/guides/util/version.md @@ -0,0 +1,21 @@ +--- +name: Get the current Bun version +--- + +Get the current version of Bun in a semver format. + +```ts#index.ts +Bun.version; // => "0.6.15" +``` + +--- + +Get the exact `git` commit of [`oven-sh/bun`](https://github.com/oven-sh/bun) that was compiled to produce this Bun binary. + +```ts#index.ts +Bun.revision; // => "49231b2cb9aa48497ab966fc0bb6b742dacc4994" +``` + +--- + +See [Docs > API > Utils](/docs/api/utils) for more useful utilities. diff --git a/docs/guides/websocket/compression.md b/docs/guides/websocket/compression.md new file mode 100644 index 000000000..e98d8f0c9 --- /dev/null +++ b/docs/guides/websocket/compression.md @@ -0,0 +1,31 @@ +--- +name: Enable compression for WebSocket messages +--- + +Per-message compression can be enabled with the `perMessageDeflate` parameter. When set, all messages will be compressed using the [permessage-deflate](https://tools.ietf.org/html/rfc7692) WebSocket extension. + +```ts +Bun.serve({ + // ... + websocket: { + // enable compression + perMessageDeflate: true, + }, +}); +``` + +--- + +To enable compression for individual messages, pass `true` as the second parameter to `ws.send()`. + +```ts +Bun.serve({ + // ... + websocket: { + async message(ws, message) { + // send a compressed message + ws.send("Hello world!", true); + }, + }, +}); +``` diff --git a/docs/guides/websocket/context.md b/docs/guides/websocket/context.md new file mode 100644 index 000000000..9e387d685 --- /dev/null +++ b/docs/guides/websocket/context.md @@ -0,0 +1,72 @@ +--- +name: Set per-socket contextual data on a WebSocket +--- + +When building a WebSocket server, it's typically necessary to store some identifying information or context associated with each connected client. + +With [Bun.serve()](/docs/api/websockets#contextual-data), this "contextual data" is set when the connection is initially upgraded by passing a `data` parameter in the `server.upgrade()` call. + +```ts +Bun.serve<{ socketId: number }>({ + fetch(req, server) { + const success = server.upgrade(req, { + data: { + socketId: Math.random(), + }, + }); + if (success) return undefined; + + // handle HTTP request normally + // ... + }, + websocket: { + // define websocket handlers + async message(ws, message) { + // the contextual dta is available as the `data` property + // on the WebSocket instance + console.log(`Received ${message} from ${ws.data.socketId}}`); + }, + }, +}); +``` + +--- + +It's common to read cookies/headers from the incoming request to identify the connecting client. + +```ts +type WebSocketData = { + createdAt: number; + token: string; + userId: string; +}; + +// TypeScript: specify the type of `data` +Bun.serve<WebSocketData>({ + async fetch(req, server) { + // use a library to parse cookies + const cookies = parseCookies(req.headers.get("Cookie")); + const token = cookies["X-Token"]; + const user = await getUserFromToken(ws.data.authToken); + + const upgraded = server.upgrade(req, { + data: { + createdAt: Date.now(), + token: cookies["X-Token"], + userId: user.id, + }, + }); + + if (upgraded) return undefined; + }, + websocket: { + async message(ws, message) { + // save the message to a database + await saveMessageToDatabase({ + message: String(message), + userId: ws.data.userId, + }); + }, + }, +}); +``` diff --git a/docs/guides/websocket/index.json b/docs/guides/websocket/index.json new file mode 100644 index 000000000..cb4d71b1a --- /dev/null +++ b/docs/guides/websocket/index.json @@ -0,0 +1,4 @@ +{ + "name": "WebSocket", + "description": "A collection of guides relating to building WebSocket servers with Bun" +} diff --git a/docs/guides/websocket/pubsub.md b/docs/guides/websocket/pubsub.md new file mode 100644 index 000000000..7403d4d2f --- /dev/null +++ b/docs/guides/websocket/pubsub.md @@ -0,0 +1,38 @@ +--- +name: Build a publish-subscribe WebSocket server +--- + +Bun's server-side `WebSocket` API provides a native pub-sub API. Sockets can be subscribed to a set of named channels using `socket.subscribe(<name>)`; messages can be published to a channel using `socket.publish(<name>, <message>)`. + +This code snippet implements a simple single-channel chat server. + +```ts +const server = Bun.serve<{ username: string }>({ + fetch(req, server) { + const cookies = req.headers.get("cookie"); + const username = getUsernameFromCookies(cookies); + const success = server.upgrade(req, { data: { username } }); + if (success) return undefined; + + return new Response("Hello world"); + }, + websocket: { + open(ws) { + const msg = `${ws.data.username} has entered the chat`; + ws.subscribe("the-group-chat"); + ws.publish("the-group-chat", msg); + }, + message(ws, message) { + // the server re-broadcasts incoming messages to everyone + ws.publish("the-group-chat", `${ws.data.username}: ${message}`); + }, + close(ws) { + const msg = `${ws.data.username} has left the chat`; + ws.publish("the-group-chat", msg); + ws.unsubscribe("the-group-chat"); + }, + }, +}); + +console.log(`Listening on ${server.hostname}:${server.port}`); +``` diff --git a/docs/guides/websocket/simple.md b/docs/guides/websocket/simple.md new file mode 100644 index 000000000..5aabf2fdf --- /dev/null +++ b/docs/guides/websocket/simple.md @@ -0,0 +1,33 @@ +--- +name: Build a simple WebSocket server +--- + +Start a simple WebSocket server using [`Bun.serve`](/docs/api/http). + +Inside `fetch`, we attempt to upgrade incoming `ws:` or `wss:` requests to WebSocket connections. + +```ts +const server = Bun.serve<{ authToken: string }>({ + fetch(req, server) { + const success = server.upgrade(req); + if (success) { + // Bun automatically returns a 101 Switching Protocols + // if the upgrade succeeds + return undefined; + } + + // handle HTTP request normally + return new Response("Hello world!"); + }, + websocket: { + // this is called when a message is received + async message(ws, message) { + console.log(`Received ${message}`); + // send back a message + ws.send(`You said: ${message}`); + }, + }, +}); + +console.log(`Listening on localhost:\${server.port}`); +``` diff --git a/docs/guides/websocket/upgrade.md b/docs/guides/websocket/upgrade.md new file mode 100644 index 000000000..cec8c3802 --- /dev/null +++ b/docs/guides/websocket/upgrade.md @@ -0,0 +1,28 @@ +--- +name: Upgrade an HTTP request to a WebSocket connection +--- + +Inside `fetch`, use the `server.upgrade()` function to upgrade an incoming `Request` to a WebSocket connection. Bun automatically returns a 101 Switching Protocols response if the upgrade succeeds. + +Refer to the [WebSocket docs](/docs/api/websockets) for more information on building WebSocket servers. + +```ts +const server = Bun.serve<{ authToken: string }>({ + fetch(req, server) { + const success = server.upgrade(req); + if (success) { + // Bun automatically returns a 101 Switching Protocols + // if the upgrade succeeds + return undefined; + } + + // handle HTTP request normally + return new Response("Hello world!"); + }, + websocket: { + // define websocket handlers + }, +}); + +console.log(`Listening on localhost:\${server.port}`); +``` diff --git a/docs/guides/write-file/basic.md b/docs/guides/write-file/basic.md new file mode 100644 index 000000000..66f180a40 --- /dev/null +++ b/docs/guides/write-file/basic.md @@ -0,0 +1,44 @@ +--- +name: Write a string to a file +--- + +This code snippet writes a string to disk at a particular _absolute path_. + +It uses the fast [`Bun.write()`](/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_; the second is the _data_ to write. + +```ts +const path = "/path/to/file.txt"; +await Bun.write(path, "Lorem ipsum"); +``` + +--- + +Any relative paths will be resolved relative to the project root (the nearest directory containing a `package.json` file). + +```ts +const path = "./file.txt"; +await Bun.write(path, "Lorem ipsum"); +``` + +--- + +You can pass a `BunFile` as the destination. `Bun.write()` will write the data to its associated path. + +```ts +const path = Bun.file("./file.txt"); +await Bun.write(path, "Lorem ipsum"); +``` + +--- + +`Bun.write()` returns the number of bytes written to disk. + +```ts +const path = "./file.txt"; +const bytes = await Bun.write(path, "Lorem ipsum"); +// => 11 +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/blob.md b/docs/guides/write-file/blob.md new file mode 100644 index 000000000..a923190bf --- /dev/null +++ b/docs/guides/write-file/blob.md @@ -0,0 +1,28 @@ +--- +name: Write a Blob to a file +--- + +This code snippet writes a `Blob` to disk at a particular path. + +It uses the fast [`Bun.write()`](/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. + +```ts +const path = "/path/to/file.txt"; +await Bun.write(path, "Lorem ipsum"); +``` + +--- + +The `BunFile` class extends `Blob`, so you can pass a `BunFile` directly into `Bun.write()` as well. + +```ts +const path = "./out.txt"; +const data = Bun.file("./in.txt"); + +// write the contents of ./in.txt to ./out.txt +await Bun.write(path, data); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/cat.md b/docs/guides/write-file/cat.md new file mode 100644 index 000000000..a9f9a0ba6 --- /dev/null +++ b/docs/guides/write-file/cat.md @@ -0,0 +1,17 @@ +--- +name: Write a file to stdout +--- + +Bun exposes `stdout` as a `BunFile` with the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](/docs/api/file-io#writing-files-bun-write). + +This code writes a file to `stdout` similar to the `cat` command in Unix. + +```ts#cat.ts +const path = "/path/to/file.txt"; +const file = Bun.file(path); +await Bun.write(Bun.stdout, file); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/file-cp.md b/docs/guides/write-file/file-cp.md new file mode 100644 index 000000000..b8910e269 --- /dev/null +++ b/docs/guides/write-file/file-cp.md @@ -0,0 +1,16 @@ +--- +name: Copy a file to another location +--- + +This code snippet copies a file to another location on disk. + +It uses the fast [`Bun.write()`](/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. + +```ts +const file = Bun.file("/path/to/original.txt"); +await Bun.write("/path/to/copy.txt", file); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/filesink.md b/docs/guides/write-file/filesink.md new file mode 100644 index 000000000..10ea792ee --- /dev/null +++ b/docs/guides/write-file/filesink.md @@ -0,0 +1,52 @@ +--- +name: Write a file incrementally +--- + +Bun provides an API for incrementally writing to a file. This is useful for writing large files, or for writing to a file over a long period of time. + +Call `.writer()` on a `BunFile` to retrieve a `FileSink` instance. This instance can be used to efficiently buffer data and periodically "flush" it to disk. You can write & flush many times. + +```ts +const file = Bun.file("/path/to/file.txt"); +const writer = file.writer(); + +writer.write("lorem"); +writer.write("ipsum"); +writer.write("dolor"); + +writer.flush(); + +// continue writing & flushing +``` + +--- + +The `.write()` method can accept strings or binary data. + +```ts +w.write("hello"); +w.write(Buffer.from("there")); +w.write(new Uint8Array([0, 255, 128])); +writer.flush(); +``` + +--- + +The `FileSink` will also auto-flush when its internal buffer is full. You can configure the buffer size with the `highWaterMark` option. + +```ts +const file = Bun.file("/path/to/file.txt"); +const writer = file.writer({ highWaterMark: 1024 * 1024 }); // 1MB +``` + +--- + +When you're done writing to the file, call `.end()` to auto-flush the buffer and close the file. + +```ts +writer.end(); +``` + +--- + +Full documentation: [FileSink](/docs/api/file-io#incremental-writing-with-filesink). diff --git a/docs/guides/write-file/index.json b/docs/guides/write-file/index.json new file mode 100644 index 000000000..dea48e215 --- /dev/null +++ b/docs/guides/write-file/index.json @@ -0,0 +1,4 @@ +{ + "name": "Writing files", + "description": "A collection of guides for writing files with Bun" +} diff --git a/docs/guides/write-file/response.md b/docs/guides/write-file/response.md new file mode 100644 index 000000000..fb2bd79eb --- /dev/null +++ b/docs/guides/write-file/response.md @@ -0,0 +1,17 @@ +--- +name: Write a Response to a file +--- + +This code snippet writes a `Response` to disk at a particular path. Bun will consume the `Response` body according to its `Content-Type` header. + +It uses the fast [`Bun.write()`](/docs/api/file-io#writing-files-bun-write) API to efficiently write data to disk. The first argument is a _destination_, like an absolute path or `BunFile` instance. The second argument is the _data_ to write. + +```ts +const result = await fetch("https://bun.sh"); +const path = "./file.txt"; +await Bun.write(path, result); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/stdout.md b/docs/guides/write-file/stdout.md new file mode 100644 index 000000000..00fa11a60 --- /dev/null +++ b/docs/guides/write-file/stdout.md @@ -0,0 +1,21 @@ +--- +name: Write to stdout +--- + +The `console.log` function writes to `stdout`. It will automatically append a line break at the end of the printed data. + +```ts +console.log("Lorem ipsum"); +``` + +--- + +For more advanced use cases, Bun exposes `stdout` as a `BunFile` via the `Bun.stdout` property. This can be used as a destination for [`Bun.write()`](/docs/api/file-io#writing-files-bun-write). + +```ts +await Bun.write(Bun.stdout, "Lorem ipsum"); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/guides/write-file/stream.md b/docs/guides/write-file/stream.md new file mode 100644 index 000000000..efb7efd8a --- /dev/null +++ b/docs/guides/write-file/stream.md @@ -0,0 +1,17 @@ +--- +name: Write a ReadableStream to a file +--- + +To write a `ReadableStream` to disk, first create a `Response` instance from the stream. This `Response` can then be written to disk using [`Bun.write()`](/docs/api/file-io#writing-files-bun-write). + +```ts +const stream: ReadableStream = ...; +const path = "./file.txt"; +const response = new Response(stream); + +await Bun.write(path, response); +``` + +--- + +See [Docs > API > File I/O](/docs/api/file-io#writing-files-bun-write) for complete documentation of `Bun.write()`. diff --git a/docs/nav.ts b/docs/nav.ts index 13af7b20e..b5111220a 100644 --- a/docs/nav.ts +++ b/docs/nav.ts @@ -38,6 +38,10 @@ export default { page("templates", "Templates", { description: "Hit the ground running with one of Bun's official templates, or download a template from GitHub.", }), + page("templates", "Guides", { + description: "A set of walkthrough guides and code snippets for performing common tasks with Bun", + href: "/guides", + }), // page("typescript", "TypeScript"), // divider("CLI"), |