Flareutils

website·Indexed 30 days ago

https://flareutils.pages.dev

A 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.

Tokens
3.9K
Snippets
29
Records
34
Agent score
75%

What's inside Flareutils

  1. Overview of Flareutils utilities

    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.
  2. 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)
    );
  3. Generate random phonetic strings using Phonetic

    The Phonetic class 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 like crypto.getRandomValues or the Isaac generator; otherwise, Math.random can 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));
  4. 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.add and queue.flush return promises and must be awaited. Failing to await queue.add can 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();
  5. Set up Cloudflare infrastructure for Resizer

    To use the Resizer utility, you must meet the following infrastructure requirements:

    1. Zone Requirements: Your Cloudflare Zone must be on a Pro plan or higher and have Image Resizing enabled.
    2. 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.
    3. 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.
  6. 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 the KVNamespace standard, 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");
    		// ...
    	},
    };
  7. Send emails using the MailChannels helper in flareutils

    The sendMail function from flareutils is a simple fetch wrapper 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?",
    				},
    			],
    		});
    		// ...
    	},
    };
  8. 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 the waitUntil function is request-specific, it must be updated for every new request using setWaitUntil.
    bKv.setWaitUntil(ctx.waitUntil.bind(ctx));
  9. Initialize and use the Isaac random number generator

    The Isaac class provides a cryptographically-secure random number generator based on the ISAAC algorithm. It is backed by crypto.getRandomValues and 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);
    		// ...
    	},
    };
  10. 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 the waitUntil function is request-specific, you must update it for every new request using the setWaitUntil method.
    bKv.setWaitUntil(ctx.waitUntil.bind(ctx));
  11. Initialize the Temra templating engine

    The Temra constructor 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);
  12. Handle asynchronous seeding in Isaac

    The seeding process for the Isaac instance occurs asynchronously. To prevent errors, you should create a single instance at startup and await the seeding property before calling random number methods.
    if (isaac.seeding) {
    	await isaac.seeding;
    }