new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Cloudflare Workers · all subjects

code-patterns

261 notes in this subject, read out of this brain and free to use. This is page 4 of 5.

CompressionStream and DecompressionStream implementation

As of 2022-03-11, implementations of CompressionStream and DecompressionStream are available.

ReadableStream pipeTo/pipeThrough support

As of 2022-03-04, initial pipeTo/pipeThrough support on ReadableStreams constructed using the new ReadableStream() constructor is available.

URLPattern implementation available

As of 2022-03-04, an implementation of URLPattern is available.

TextDecoder full encoding support

As of 2022-02-25, the TextDecoder class supports the full range of text encodings defined by the WHATWG Encoding Standard.

crypto.getRandomValues BigInt array support

As of 2022-02-05, crypto.getRandomValues now supports BigInt64Array and BigUint64Array.

HTMLRewriter end tag support

As of 2022-01-17, HTMLRewriter now supports inspecting and modifying end tags, not just start tags.

ReadableStream async iteration

As of 2021-12-22, async iteration (using for and await) on instances of ReadableStream is available.

AbortSignal.timeout method

As of 2021-12-10, AbortSignal.timeout(delay) returns an AbortSignal that will be triggered after the given number of milliseconds.

crypto.DigestStream for streaming hash

As of 2021-12-10, crypto.DigestStream is a non-standard extension supporting hash digest generation from streaming data. It is a WritableStream that does not retain written data but generates a digest hash when data flow ends. It supports the same hash algorithms as crypto.subtle.digest().

scheduler.wait API for await-able delays

As of 2021-12-10, early support for the scheduler.wait() API is available, providing an await-able alternative to setTimeout().

structuredClone support

As of 2021-11-19, structuredClone() is supported.

AbortSignal reason property

As of 2021-11-12, the AbortSignal object has a reason property indicating the reason for cancellation. The reason can be specified when the AbortSignal is triggered or created.

WebAssembly reference types support

As of 2021-11-05, V8 9.6 upgrade adds support for WebAssembly reference types.

EventTarget addEventListener signal option

As of 2021-10-21, the signal option in EventTarget.addEventListener() allows removing an event listener in response to an AbortSignal.

unhandledrejection and rejectionhandled events

As of 2021-10-21, unhandledrejection and rejectionhandled events are supported.

ReadableStreamDefaultReader and ReadableStreamBYOBReader constructors

As of 2021-10-21, ReadableStreamDefaultReader and ReadableStreamBYOBReader constructors are supported.

ReadableStreamBYOBReader readAtLeast method

As of 2021-10-21, the non-standard ReadableStreamBYOBReader method readAtLeast(size, buffer) returns a buffer with at least size bytes. The buffer parameter must be an ArrayBufferView. Returns fewer only if EOF is encountered. One final call is needed to get back done=true. It always detaches the ArrayBuffer and is unaffected by streams_byob_reader_detaches_buffer flag.

WebCrypto HMAC JWK import/export

As of 2021-04-19, WebCrypto supports importing and exporting HMAC keys in JWK format.

WebCrypto AES JWK import/export

As of 2021-04-19, WebCrypto supports importing and exporting AES keys in JWK format.

WebCrypto AES key generation for CTR, CBC, KW

As of 2021-04-19, WebCrypto supports AES key generation for CTR, CBC, and KW modes.

WebCrypto ECDH key derivation

As of 2021-04-19, WebCrypto supports key derivation for ECDH.

WebCrypto ECDH key generation and import

As of 2021-04-19, WebCrypto supports ECDH key generation and import.

WebCrypto ECDSA key generation

As of 2021-04-19, WebCrypto supports ECDSA key generation.

AbortController and AbortSignal availability

As of 2021-09-24, AbortController and AbortSignal objects are available.

queueMicrotask Web Platform API

As of 2021-09-24, the Web Platform queueMicrotask API is available.

Custom EventTarget subclasses

As of 2021-09-24, it is possible to use new EventTarget() and create custom EventTarget subclasses.

addEventListener once option

As of 2021-09-24, the once option is supported on addEventListener to register event handlers that invoke only once.

WebCrypto AES-CTR encrypt/decrypt

As of 2021-04-23, in the WebCrypto API, encrypt and decrypt operations are supported for the AES-CTR encryption algorithm.

crypto.randomUUID for UUID generation

As of 2021-09-03, the crypto.randomUUID() method generates a new random version 4 UUID.

File and Blob API support

As of 2021-01-14, File and Blob APIs are implemented for use when constructing FormData in outgoing requests. FormData from incoming requests still uses strings even when file metadata is present.

Headers forEach method

As of 2021-07-01, the forEach() method is supported for Headers, URLSearchParameters, and FormData.

Streams spec compliance for promise-returning methods

As of 2021-12-02, methods returning promises in Streams spec must not throw synchronous errors. Workers is converting sync throws to async rejections for spec compliance.

HTMLRewriter CSS pseudo-selector support

As of 2020-07-09, HTMLRewriter supports :nth-child, :first-child, :nth-of-type, and :first-of-type selectors.

setTimeout/setInterval additional arguments

As of 2020-07-09, setTimeout/setInterval can take additional arguments which are passed to the callback, as required by spec.

Canceling response body to free memory

If you use fetch() but do not need the response body, calling response.body.cancel() is still good practice to free memory: ```ts const response = await fetch(url); // Only read the response body for successful responses if (response.status <= 299) { // Call response.json(), response.text() or otherwise process the body } else { // Explicitly cancel it response.body.cancel(); } ```

Playground default worker example

The Playground provides default code showing a multi-module Worker that imports welcome.html, logs 'Hello Cloudflare Workers!' to the console, and returns a Response with the welcome.html content and a content-type: text/html header. The Worker receives a Request object, Env object, and ExecutionContext object in its fetch handler.

Do not store mutable global state

You should not store mutable state in your global scope unless you have accounted for the fact that isolates may be spun down and evicted at any time due to resource limitations, suspicious scripts, or individual resource limits.

No guarantee of same instance for multiple requests

There is no guarantee that any two user requests will be routed to the same or a different instance of your Worker. Cloudflare recommends you do not use or mutate global state.

Static sites on Workers project structure

When deploying a static site on Workers, the project is created with C3 and can be developed locally with `wrangler dev`, then deployed with `wrangler deploy`.

Full-stack SSR applications on Workers

Full-stack server-side rendered (SSR) applications can be built on Cloudflare Workers. These dynamic and interactive applications can use any Workers bindings, including assets' own binding, to interact with resources on the Cloudflare Developer Platform.

Full-stack app project file structure

In a full-stack Workers project, the `src/index.ts` file contains sample code that controls the server-side behavior of your Worker. The `public/index.html` file and other files in `public/` contain the static assets. Modify these files and reload the page in `wrangler dev` to see changes.

Worker code example serving static assets and API

Example showing how to serve static assets via binding while handling API routes: export default { async fetch(request, env) { const url = new URL(request.url); if (url.pathname.startsWith('/api/')) { return new Response(JSON.stringify({ name: 'Cloudflare' }), { headers: { 'Content-Type': 'application/json' } }); } return env.ASSETS.fetch(request); } }

WorkerEntrypoint pattern for new Workers scripts

When starting a new Worker script from scratch, use the WorkerEntrypoint class pattern: import { WorkerEntrypoint } from "cloudflare:workers"; export default class extends WorkerEntrypoint { async fetch(request: Request) { return new Response("Hello, world!"); } }. This provides access to latest runtime features including TypeScript support and bundling.

SPA shell with bootstrap data pattern

For advanced SPA patterns, run_worker_first can be used to inject data into the SPA shell before it reaches the browser. An example using HTMLRewriter to prefetch API data and embed it in the HTML stream is documented in the SPA shell with bootstrap data guide.

SPA Worker script handling matched routes

A Worker script can handle routes matched by run_worker_first patterns and serve dynamic content. The Worker script can optionally use the assets binding to serve static assets. Example showing an API endpoint response: ```ts export default { async fetch(request, env): Promise<Response> { const url = new URL(request.url); if (url.pathname === "/api/name") { return new Response(JSON.stringify({ name: "Cloudflare" }), { headers: { "Content-Type": "application/json" }, }); } return new Response(null, { status: 404 }); }, } satisfies ExportedHandler; ```

run_worker_first with Worker code example

Example Worker script that uses run_worker_first to authenticate requests before serving assets: ```ts import { WorkerEntrypoint } from "cloudflare:workers"; export default class extends WorkerEntrypoint<Env> { async fetch(request: Request) { // You can perform checks before fetching assets const user = await checkIfRequestIsAuthenticated(request); if (!user) { return new Response("Unauthorized", { status: 401 }); } // Fetch the assets as normal const assetResponse = await this.env.ASSETS.fetch(request); // You can return static asset response as-is, or transform them return new HTMLRewriter() .on("#user", { element(element) { element.setInnerContent(JSON.stringify({ name: user.name })); }, }) .transform(assetResponse); } } ``` This example demonstrates performing authentication checks, fetching assets via this.env.ASSETS.fetch(), and using HTMLRewriter to transform the asset response before returning it.

Use cases for run_worker_first

Common use cases for setting run_worker_first to true include logging requests, performing authentication checks, using HTMLRewriter to transform assets before serving, and implementing middleware for requests.

run_worker_first selective routing Worker code example

Example Worker script for handling selective routing with run_worker_first as an array: ```ts import { WorkerEntrypoint } from "cloudflare:workers"; export default class extends WorkerEntrypoint<Env> { async fetch(request: Request) { // The Worker script only handles an OAuth callback. // All other requests either serve an asset that matches or serve the index.html fallback. const url = new URL(request.url); const code = url.searchParams.get("code"); const state = url.searchParams.get("state"); const accessToken = await exchangeCodeForToken(code, state); const sessionIdentifier = await storeTokenAndGenerateSession(accessToken); // Redirect back to the index, but set a cookie that the front-end will use. return new Response(null, { headers: { Location: "/", "Set-Cookie": `session_token=${sessionIdentifier}; HttpOnly; Secure; SameSite=Lax; Path=/`, }, }); } } ``` This example demonstrates using run_worker_first for a specific route (/oauth/callback) to handle OAuth token exchange while other requests are handled by the asset-first behavior.

Workers support modern JavaScript tooling

Workers projects support ES modules, npm packages, and async/await functions. This allows building full-featured applications using modern JavaScript development patterns and practices.

HTML escaping in JSON embedded in JavaScript

When embedding JSON data in HTML script tags, escape less-than signs to prevent HTML tag interpretation: JSON.stringify(data).replace(/</g, '\u003c'). This prevents injected content from being interpreted as HTML.

QR code generator example using qrcode-svg

This example shows how to generate a QR code with qrcode-svg and return it as an SVG response: import QRCode from 'qrcode-svg'; async function generateQRCode(request) { const { text } = await request.json(); const qr = new QRCode({ content: text || 'https://workers.dev' }); return new Response(qr.svg(), { headers: { 'Content-Type': 'image/svg+xml' } }); }

POST request with fetch from browser

To make a POST request from browser JavaScript to a Worker, use: fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }). The response can be read as a blob with response.blob() or as text with response.text().

Cache libSQL client and router in Env interface

In your Worker's Env interface, include optional properties to cache the libSQL client and router objects. These objects should be created on first use, then stored in the Env for reuse across subsequent requests to improve performance.

Import @libsql/client/web for Workers compatibility

When working with Cloudflare Workers, you must import the libSQL client library as '@libsql/client/web'. The non-web import will not work in the Workers environment.

Turso database execution with parameterized queries

Use the libSQL client's execute method with parameterized queries to prevent SQL injection. Example: await client.execute({ sql: "insert into example_users values (?)", args: [email] }). The args array contains the values to be substituted for the ? placeholders.

Turso ResultSet JSON serialization

The libSQL client's execute method returns a ResultSet object with properties: columns (array of column names), rows (array of row objects), and rowsAffected (number of rows affected). This can be directly serialized to JSON using Response.json().

Turso database tutorial example code with routing

Complete example Worker code using @libsql/client/web and itty-router: ```ts import { Client as LibsqlClient, createClient } from "@libsql/client/web"; import { Router, RouterType } from "itty-router"; export interface Env { LIBSQL_DB_URL?: string; LIBSQL_DB_AUTH_TOKEN?: string; router?: RouterType; } export default { async fetch(request, env): Promise<Response> { if (env.router === undefined) { env.router = buildRouter(env); } return env.router.fetch(request); }, } satisfies ExportedHandler<Env>; function buildLibsqlClient(env: Env): LibsqlClient { const url = env.LIBSQL_DB_URL?.trim(); if (url === undefined) { throw new Error("LIBSQL_DB_URL env var is not defined"); } const authToken = env.LIBSQL_DB_AUTH_TOKEN?.trim(); if (authToken === undefined) { throw new Error("LIBSQL_DB_AUTH_TOKEN env var is not defined"); } return createClient({ url, authToken }); } function buildRouter(env: Env): RouterType { const router = Router(); router.get("/users", async () => { const client = buildLibsqlClient(env); const rs = await client.execute("select * from example_users"); return Response.json(rs); }); router.get("/add-user", async (request) => { const client = buildLibsqlClient(env); const email = request.query.email; if (email === undefined) { return new Response("Missing email", { status: 400 }); } if (typeof email !== "string") { return new Response("email must be a single string", { status: 400 }); } if (email.length === 0) { return new Response("email length must be > 0", { status: 400 }); } try { await client.execute({ sql: "insert into example_users values (?)", args: [email], }); } catch (e) { console.error(e); return new Response("database insert failed"); } return new Response("Added"); }); router.all("*", () => new Response("Not Found.", { status: 404 })); return router; } ``` This example demonstrates a Worker that connects to Turso, provides GET endpoints to list users and add users, and caches the client and router for performance.

List fine-tuning jobs

Use `openai.fineTuning.jobs.list()` to retrieve a list of all fine-tuning jobs. The response contains a `.data` array with job details.

Fine-tune document format

Fine-tune documents must be structured as JSON Lines format (.jsonl files). Refer to https://jsonlines.org/ for the format specification.

Access query parameters in Hono

Use `c.req.query('paramName')` to retrieve query parameters from a Hono request. Returns the query parameter value as a string or undefined if not present.

Give your agent this brain