Flareutils
website·Indexed 30 days ago
https://flareutils.pages.devA collection of utility classes and functions for Cloudflare Workers, including BetterKV for KV v2 caching, Temra templating engine, Stubby for Durable Object Stub memory storage, PromiseQueue for I/O concurrency management, and the Resizer utility for the Image Resizing API.
What's inside Flareutils
- Flareutils is a collection of utility classes and functions designed to streamline Cloudflare development. It is released under the MIT License. The library consists of 8 separate utilities: BetterKV, Isaac, MailChannels, Phonetic, Stubby, Temra, PromiseQueue, and Resizer.
Manually implement Durable Object Jurisdiction with Stubby
Stubby does not natively support the Durable Object Jurisdiction API. To implement jurisdiction manually, pass the jurisdiction-restricted namespace (e.g.,env.DO.jurisdiction("eu")) to the Stubby setup function instead of the standard Durable Object Namespace Binding.const stubby = new Stubby( env.DO.jurisdiction("eu"), env.KV, ctx.waitUntil.bind(ctx) );Generate random phonetic strings using Phonetic
ThePhoneticclass generates random phonetic strings. It requires a random number generator function that returns a value between 0 and 1. For cryptographic security, it is recommended to use a secure generator likecrypto.getRandomValuesor theIsaacgenerator; otherwise,Math.randomcan be used for non-secure purposes.import { Phonetic } from "flareutils"; // Use Math.random for non-secure needs, or a secure RNG for cryptographic security const random = Math.random; const generator = new Phonetic(random); // Generate a phonetic string with default length console.log(generator.rand()); // Generate a phonetic string with a specific length (e.g., 10 characters) console.log(generator.rand(10));Manage I/O concurrency with PromiseQueue
PromiseQueue is a utility used to bulk-queue I/O-related promises to avoid hitting concurrency limits (such as those found in Cloudflare Workers).
Crucially, both
queue.addandqueue.flushreturn promises and must be awaited. Failing to awaitqueue.addcan lead to the queue processing more than 6 promises simultaneously, defeating the purpose of the concurrency limit.const queue = new PromiseQueue(); for (let i = 0; i < 100; i++) { await queue.add(env.KV.delete("key" + i)); } await queue.flush();Set up Cloudflare infrastructure for Resizer
To use the Resizer utility, you must meet the following infrastructure requirements:
- Zone Requirements: Your Cloudflare Zone must be on a Pro plan or higher and have Image Resizing enabled.
- R2 Storage: Create a dedicated R2 bucket (or a specific filename prefix/directory) to store images temporarily. This storage should not be shared with other services.
- Public Access: Configure a Custom Domain for the R2 bucket.
Optional Security and Maintenance:
- Firewall: Create a firewall rule to block all incoming requests to the bucket except those originating from your Workers (using
cf.worker.upstream_zone). - Lifecycle Policy: Configure an R2 Lifecycle rule to automatically delete old images to prevent unexpected billing if the utility's internal cleanup fails.
Initialize BetterKV (v1) in a Cloudflare Worker
BetterKV (v1) provides a storage namespace that uses the Cloudflare Workers KV API backed by the Cache API to reduce billable reads. It largely follows theKVNamespacestandard, but requires specific instantiation parameters. Note that this version is specifically for KV v1.import { BetterKV } from "flareutils"; export default <ExportedHandler>{ async fetch(req, env, ctx) { // Parameters: // 1. The KV Namespace from env // 2. The bound waitUntil function from ctx // 3. (Optional) A string identifying the Cache Space to avoid collisions between multiple namespaces const bKv = new BetterKV(env.KV, ctx.waitUntil.bind(ctx), "cachespace"); // ... }, };Send emails using the MailChannels helper in flareutils
The
sendMailfunction fromflareutilsis a simplefetchwrapper designed to send emails quickly using the MailChannels API.Important Requirements:
- DKIM Setup: This helper must not be used without a proper DKIM configuration. Refer to the MailChannels documentation for adding DKIM signatures.
- Input Validation: This function performs no input verification and is intended primarily to provide type safety for MailChannels API requests.
import { sendMail } from "flareutils"; export default <ExportedHandler>{ async fetch(req) { await sendMail({ from: { name: "John Foobar", email: "john@foobar.baz", }, personalizations: { to: [ { name: "Jane Foobar", email: "jane@foobar.baz", }, ], subject: "Where do I find that blue shark plushy?", }, content: [ { type: "text/plain", value: "I've been looking for that blue shark plushy for ages, but I can't find it anywhere. Do you know where I can find it?", }, ], }); // ... }, };Reuse BetterKV instance across requests
A BetterKV Namespace must be initiated during a Request (not at startup), but once created, it can be hoisted into the global scope. However, because thewaitUntilfunction is request-specific, it must be updated for every new request usingsetWaitUntil.bKv.setWaitUntil(ctx.waitUntil.bind(ctx));Initialize and use the Isaac random number generator
TheIsaacclass provides a cryptographically-secure random number generator based on the ISAAC algorithm. It is backed bycrypto.getRandomValuesand the DRAND network. To instantiate it, provide a seed string (preferably unique or random) and an optional number of times to run the seed through the mixer (defaults to 1).import { Isaac } from "flareutils"; export default <ExportedHandler>{ async fetch(req) { const isaac = new Isaac("my seed", 2); // ... }, };Reuse BetterKV instance across requests
While a BetterKV Namespace must be initiated during a Request (not at startup), it can be hoisted into the global scope for reuse. However, because thewaitUntilfunction is request-specific, you must update it for every new request using thesetWaitUntilmethod.bKv.setWaitUntil(ctx.waitUntil.bind(ctx));Initialize the Temra templating engine
TheTemraconstructor initializes the engine with optional settings to handle tag prefixes and HTML comments. It is recommended to cache the resulting HTML before returning it to the user.import { Temra } from "flareutils"; // Parameters: // 1. prefix: Default prefix for template tags (e.g., "@" means @name is read as name). // 2. deleteComments: Boolean. If true, removes all HTML comments before parsing. const temra = new Temra("@", true);Handle asynchronous seeding in Isaac
The seeding process for theIsaacinstance occurs asynchronously. To prevent errors, you should create a single instance at startup and await theseedingproperty before calling random number methods.if (isaac.seeding) { await isaac.seeding; }