npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pgflow/edge-worker

v0.15.0

Published

A reliable task queue worker for Supabase Edge Functions that enhances Background Tasks with powerful features.

Readme

@pgflow/edge-worker

A reliable task queue worker for Supabase Edge Functions that enhances Background Tasks with powerful features.

[!NOTE] This project and all its components are licensed under Apache 2.0 license.

Overview

Edge Worker processes messages from a PostgreSQL queue and executes handler functions in Supabase Edge Functions, with built-in reliability features:

  • Reliable Processing - Automatic retries with configurable delays
  • 🔄 Concurrency Control - Process multiple tasks in parallel with limits
  • 🔁 Auto Restarts - Handles Edge Function CPU/memory limits gracefully
  • 📈 Horizontal Scaling - Deploy multiple instances for the same queue

Installation

// Import directly from JSR in your Edge Function
import { EdgeWorker } from 'jsr:@pgflow/edge-worker';

Package Registries

@pgflow/edge-worker is published to both registries:

  • Use JSR for Supabase Edge Functions.
  • Use npm for Node and Bun long-running process deployments.

Supabase Edge Functions remain the primary deployment path. Node and Bun process hosting is intended for Railway, Docker, and similar hosts that run workers as normal long-running processes.

For database setup, see pgflow installation docs.

Basic Usage

Simple message processor

You can use Edge Worker as a simple single-handler message processor. Just pass it a handler function to .start():

import { EdgeWorker } from 'jsr:@pgflow/edge-worker';

// Start a worker that processes messages from the 'tasks' queue
EdgeWorker.start(async (payload, context) => {
  console.log('Processing message:', payload);

  // Access platform resources through context
  const result = await context.sql`
    INSERT INTO processed_tasks (data) 
    VALUES (${JSON.stringify(payload)}) 
    RETURNING id
  `;

  return { processed: true, id: result[0].id };
});

Flow step processor

You can also use Edge Worker as a processor for Flow steps. This will change how it polls and acknowledges messages. Just pass it a Flow definition to .start():

import { EdgeWorker } from 'jsr:@pgflow/edge-worker';
import { Flow } from 'jsr:@pgflow/dsl/supabase';

// Define a flow using Supabase preset for Supabase resources
const AnalyzeWebsite = new Flow<{ url: string }>({
  slug: 'analyzeWebsite',
})
  .step({ slug: 'fetch' }, async (flowInput, context) => {
    // Access Supabase resources through context
    const response = await fetch(flowInput.url, {
      signal: context.shutdownSignal,
    });
    return { html: await response.text() };
  })
  .step({ slug: 'save', dependsOn: ['fetch'] }, async (deps, context) => {
    // Use Supabase client from context
    const { data } = await context.supabase
      .from('websites')
      .insert({ url: context.flowInput.url, html: deps.fetch.html })
      .select()
      .single();
    return data;
  });

// Start the worker
EdgeWorker.start(AnalyzeWebsite);

Context Resources

EdgeWorker automatically provides a context object as the second parameter to all handlers. The context contains platform resources and runtime information.

Core Resources (Always Available)

These resources are provided regardless of platform:

  • env - Environment variables (Record<string, string | undefined>)
  • shutdownSignal - AbortSignal for graceful shutdown handling
  • rawMessage - Original pgmq message with metadata
    interface PgmqMessageRecord<T> {
      msg_id: number;
      read_ct: number;
      enqueued_at: Date;
      vt: Date;
      message: T;
    }
  • stepTask - Current step task details (flow handlers only)
    interface StepTaskRecord<TFlow> {
      flow_slug: string;
      run_id: string;
      step_slug: string;
      input: StepInput<TFlow, StepSlug>;
      msg_id: number;
    }

Supabase Platform Resources

When running on Supabase (the default), these additional resources are available:

  • sql - PostgreSQL client (postgres.Sql) for database queries
  • supabase - Supabase client (SupabaseClient) with service role key for full database access

Required Environment Variables

The Supabase platform adapter requires these environment variables:

  • EDGE_WORKER_DB_URL - PostgreSQL connection string (automatically set by Supabase)
  • SUPABASE_URL - Your Supabase project URL (automatically set)
  • SUPABASE_ANON_KEY - Anonymous key (automatically set, available for autocomplete)
  • SUPABASE_SERVICE_ROLE_KEY - Service role key (automatically set)
  • SB_EXECUTION_ID - Execution ID for the Edge Function (automatically set)

All these variables are automatically populated by Supabase Edge Functions runtime.

[!NOTE] While SUPABASE_ANON_KEY is required in the environment, the edge worker only uses the service role key for creating the Supabase client.

Using Context in Handlers

// Queue handler with context
EdgeWorker.start(async (payload, context) => {
  // Check environment variables
  if (context.env.FEATURE_FLAG === 'enabled') {
    // Use SQL client
    await context.sql`UPDATE tasks SET processed = true WHERE id = ${payload.id}`;
  }

  // Handle graceful shutdown
  if (context.shutdownSignal.aborted) {
    return { status: 'aborted' };
  }

  // Use Supabase client
  const { data } = await context.supabase
    .from('results')
    .insert({ task_id: payload.id })
    .select();

  return data;
});

Using Supabase Flow Preset for Type Safety

When defining flows that use Supabase resources, import Flow from the Supabase preset:

import { Flow } from 'jsr:@pgflow/dsl/supabase';

const MyFlow = new Flow<InputType>({ slug: 'myFlow' }).step(
  { slug: 'process' },
  async (input, context) => {
    // TypeScript knows context includes all Supabase resources
    const users = await context.sql`SELECT * FROM users`;
    return users;
  }
);

[!NOTE] Context is optional for backward compatibility. Handlers that don't need platform resources can omit the second parameter.

For more details on the context object and available resources, see the Context documentation.

Documentation

For complete documentation, visit:

Manual E2E Testing

For manual end-to-end testing of edge-worker features, we maintain example edge functions in the supabase/functions directory.

Available Tests

  • Retry Demo - Demonstrates exponential backoff retry mechanism

To run a manual test:

  1. Start Supabase: pnpm nx supabase:start edge-worker
  2. Follow the instructions in the specific test's README

Dependencies

PostgreSQL Client

This package uses jsr:@oscar6echo/postgres - a JSR-compatible fork of the popular postgres package.

Why a fork? The official npm:postgres package uses CommonJS exports (export =) which are incompatible with JSR's ES Module requirements. The npm version also fails to parse database URLs correctly in Supabase Edge Runtime, causing CONNECT_TIMEOUT errors. See porsager/postgres#839 for details.

The fork is functionally identical to postgres v3.4.5, with only the export syntax changed for Deno/JSR compatibility.

Building

Run nx build edge-worker to build the library.