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

@migrate-sdk/workflow-sdk

v0.14.0

Published

Workflow SDK execution adapter for `migrate-sdk`.

Downloads

1,622

Readme

@migrate-sdk/workflow-sdk

Workflow SDK execution adapter for migrate-sdk.

The package is named for Workflow SDK rather than Vercel because Workflow SDK runs on swappable worlds: Vercel, local, Postgres, Redis, and other providers. Vercel is a deployment/world choice, not the migration adapter boundary.

import {
  WorkflowSdkClient,
  WorkflowSdkMigrationExecutable,
} from "@migrate-sdk/workflow-sdk";
import { Effect, Layer } from "effect";
import { MigrationExecutable } from "migrate-sdk";
import { migrationExecutionWorkflow } from "./workflows/migration-execution";

const executableLayer = WorkflowSdkMigrationExecutable.layer({
  workflow: migrationExecutionWorkflow,
  startOptions: {
    deploymentId: "latest",
  },
}).pipe(Layer.provide(WorkflowSdkClient.layer));

const result = await Effect.runPromise(
  MigrationExecutable.startRun(plan).pipe(Effect.provide(executableLayer))
);

Workflow files should import the workflow-safe driver subpath, not the package root:

import { runMigrationExecutionWorkflow } from "@migrate-sdk/workflow-sdk/workflow";

export async function migrationExecutionWorkflow(envelope) {
  "use workflow";

  return await runMigrationExecutionWorkflow(envelope, steps);
}

This package currently implements the durable run boundary: allocate a migration run id, acquire definition locks, queue migration run state, start the Workflow SDK run, attach the Workflow SDK run id, then let the Workflow SDK workflow consume the locked run envelope through cursor-window steps. The executable can reattach to that Workflow SDK run id for native terminal observation. Each committed cursor window also publishes a checkpoint on the adapter's named progress stream. A checkpoint carries cumulative committed run counts, and reattachment begins with the most recent buffered checkpoint before following live updates. Clients can render those counts directly or refresh the affected migration in batches. The migration store remains authoritative for migration status and item progress. Processing concurrency from the executable plan is applied to item admission and per-item work inside every cursor-window step. A processBatch callback may separately choose the concurrency of its own destination requests.

Run requests support source identity selection, failed-only and skipped-only modes, update runs, rescans, and orphan rollback. Identity selections include composite identities and use the same registry input as inline execution. Included dependencies run with the same mode policy as inline execution.

Targeted runs look up the selected identities without scanning or changing the source cursor. Update runs schedule migrated items as needs-update, preserve their tracking evidence, reset discovery, and reprocess unchanged source items. Preparation happens once per definition inside its first cursor-work step. Subsequent steps carry an initialized marker alongside counts. After a failed or cancelled run, a normal run processes the persisted retry/update backlog before resuming discovery, including when a source cursor is already saved.

Run finalization does not re-plan the request. Provide the original MigrationStore layer in the step runtime (as in the example) so cleanup can still mark the run failed and release its locks after a definition or registry is removed in a later deployment. The store verifies ownership of the original lock lease before making changes.

For existing runtimes without a supplied store, finalization uses the store shared by surviving scoped definitions, or the registry's sole store layer when none survive. A mixed-store registry without surviving scoped definitions must supply the original store to its finalization steps; cleanup fails rather than guessing between stores. Store layers are compared by reference identity.

Why cursor-work steps should not retry automatically

Workflow SDK normally retries a step when the worker fails or its result is lost. That is useful for lifecycle work, but a cursor-window step has a special boundary: it can save item outcomes and the next source cursor before Workflow SDK stores the step's return value. Those two writes are not atomic. Repeating the step at that point could consume the next source window while the workflow still holds the previous window's counts.

Use disableWorkflowStepRetries on the two steps that consume cursor work:

import { disableWorkflowStepRetries } from "@migrate-sdk/workflow-sdk/steps";

disableWorkflowStepRetries(executeMigrationRunCursorWindowStep);
disableWorkflowStepRetries(executeMigrationRunRollbackOrphansPageStep);

Keep begin, complete, cancel, failure-finalization, and whole-run rollback steps on Workflow SDK's normal retry policy. Finalization releases migration locks, so it must remain retryable when its result is lost.

If an existing application defines its own Workflow SDK step functions, add the two calls above. This is not a breaking API change, but it deliberately changes retry behavior for those cursor-work steps: a failed step now fails the run, and the next migration run resumes from the item states and source cursor already saved in the Migration Store.

This reduces unsafe replay; it does not promise exactly-once delivery. A worker can still stop after a destination accepts work but before the item's outcome is saved. Migrations should use stable destination identities, tolerate replay, and journal accepted operation ids when they can be used to resume unfinished work.

processBatch follows the same cursor rule as process. One callback receives either eligible items from one source cursor window or items from the retry backlog, and it may divide them into any smaller requests it needs. The SDK waits for every item settlement before it commits the source cursor, and no unsettled item is carried into a later cursor window.

Local World test

The package includes a Workflow SDK Local World integration test that can be run from the CLI:

pnpm --filter @migrate-sdk/workflow-sdk test:workflow

The test starts a real adapter-backed Workflow SDK run in the in-process Local World, scans 100 source entries, asserts that the scan is split into two completed Workflow SDK steps of 50 entries each, and verifies planned Process Pipeline concurrency inside those steps. It also covers identity targeting, update runs, and recovery from an interrupted update after a cursor window has committed.