Skip to content

feat: type-safe labels via TLabels generic#75

Merged
coji merged 4 commits into
mainfrom
feat/type-safe-labels
Mar 6, 2026
Merged

feat: type-safe labels via TLabels generic#75
coji merged 4 commits into
mainfrom
feat/type-safe-labels

Conversation

@coji
Copy link
Copy Markdown
Owner

@coji coji commented Mar 5, 2026

Summary

  • Add optional labels Zod schema to DurablyOptions for compile-time type checking and runtime validation
  • Add TLabels generic parameter to Run, RunFilter, TriggerOptions, TriggerAndWaitOptions, JobHandle, Durably, and related types
  • All generics default to Record<string, string> — fully backward compatible

Details

When a labels schema is provided to createDurably():

  • trigger() and batchTrigger() validate labels at runtime
  • TypeScript enforces correct label keys/values at compile time
  • RunFilter.labels becomes Partial<TLabels> for type-safe filtering
  • Label types propagate through register()JobHandletrigger()
const durably = createDurably({
  dialect,
  labels: z.object({ organizationId: z.string(), env: z.string() }),
})

// Type error: missing 'env'
await job.trigger(input, { labels: { organizationId: 'org_1' } })

// Type-safe filtering
await durably.getRuns({ labels: { organizationId: 'org_1' } }) // OK, partial

Changes

  • packages/durably/src/storage.tsRun<TLabels>, RunFilter<TLabels>, CreateRunInput<TLabels>, ClientRun<TLabels>, generic toClientRun()
  • packages/durably/src/job.tsTriggerOptions<TLabels>, TriggerAndWaitOptions<TLabels>, JobHandle<..., TLabels>, labels validation in trigger() and batchTrigger()
  • packages/durably/src/durably.tsDurablyOptions<TLabels>, Durably<TJobs, TLabels>, labels schema propagation
  • packages/durably/src/index.ts — Export TriggerOptions
  • packages/durably/tests/node/types.test.ts — 8 type-level tests
  • Docs: llms.md, create-durably.md, define-job.md, index.md, llms.txt

Test plan

  • All 141 tests pass (pnpm validate)
  • 8 new type tests verify generic inference and propagation
  • Backward compatible — no changes needed for existing code without labels schema

Closes #66

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added generic, type-safe labels across the public API with optional schema-based runtime validation for trigger and batch operations.
  • Improvements

    • Job/run APIs now preserve label types through triggers, batch operations, retrievals, and filters for stronger compile-time safety.
    • Run fields refined to consistently represent nullable outputs, errors, and progress.
  • Tests

    • Added tests validating label schema enforcement and acceptance on trigger and batchTrigger.
  • Documentation

    • Updated API docs and examples to show label typing and schema options.

Add optional `labels` Zod schema to `DurablyOptions` for compile-time
type checking and runtime validation of labels on trigger().

- Add `TLabels` generic to `Run`, `RunFilter`, `TriggerOptions`,
  `TriggerAndWaitOptions`, `JobHandle`, `Durably`, and related types
- All generics default to `Record<string, string>` for backward compat
- Runtime validation in trigger() and batchTrigger() when schema provided
- Skip undefined values in RunFilter labels (partial filter safety)
- Make toClientRun generic to preserve label types
- Add type tests for TLabels inference and propagation
- Update docs: llms.md, create-durably.md, define-job.md, index.md

Closes #66

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
durably-demo Ready Ready Preview Mar 6, 2026 0:30am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 5, 2026

Warning

Rate limit exceeded

@coji has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d499e7c-52ce-40ce-944f-6c7ab2dd9cc4

📥 Commits

Reviewing files that changed from the base of the PR and between 964801e and 8c8c768.

📒 Files selected for processing (1)
  • packages/durably/src/index.ts
📝 Walkthrough

Walkthrough

Adds generic, type-safe label support (TLabels) across the Durably public and internal type surfaces. Labels can now be defined via an optional Zod schema in createDurably and are propagated to Run, TypedRun, JobHandle, TriggerOptions, TriggerAndWaitOptions, RunFilter, storage types, and related APIs; runtime label validation wired into trigger/batch flows.

Changes

Cohort / File(s) Summary
Core runtime & API types
packages/durably/src/durably.ts, packages/durably/src/job.ts, packages/durably/src/storage.ts
Introduced TLabels generic everywhere (DurablyOptions, Durably, Run, TypedRun, CreateRunInput, RunFilter, JobHandle, TriggerOptions, TriggerAndWaitOptions, BatchTriggerInput). Threaded labelsSchema (Zod) through state and instance creation and added runtime label validation in trigger/batch flows.
Public exports
packages/durably/src/index.ts
Export surface updated to include TriggerOptions generic and related type exports reflecting TLabels changes.
Tests (types + runtime)
packages/durably/tests/node/types.test.ts, packages/durably/tests/shared/run-api.shared.ts
Added/updated type tests to assert schema inference and typed labels; added runtime tests verifying label schema validation on trigger and batchTrigger.
Documentation & website
website/api/create-durably.md, website/api/define-job.md, website/api/index.md, packages/durably/docs/llms.md, website/public/llms.txt
Updated docs and API reference to show generic TLabels, labels option in DurablyOptions (z.ZodType), updated getRun/getRuns/trigger signatures, and explained Partial filtering semantics.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I nibble schemas in the night,

labels stitched with typed delight.
No more typos hiding in the hay,
runs and triggers now obey—
hop, validate, and run away! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: type-safe labels via TLabels generic' is concise and clearly describes the main change: introducing type-safe labels through a new TLabels generic parameter.
Linked Issues check ✅ Passed The PR fully implements all coding requirements from issue #66: TLabels generic added to Run/RunFilter/TriggerOptions/JobHandle/Durably, runtime validation of labels in trigger/batchTrigger, type-safe label filtering, and backward compatibility maintained.
Out of Scope Changes check ✅ Passed All changes are in scope: documentation updates (llms.md, create-durably.md, define-job.md, index.md, llms.txt), type tests for label generics, and implementation code for label schema support across storage, job, and durably modules.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/type-safe-labels

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Add 3 runtime tests: reject invalid labels on trigger(), reject on
  batchTrigger(), accept valid labels
- Add TypedRun type definition to llms.md
- Regenerate llms.txt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/durably/docs/llms.md`:
- Around line 471-498: Update the generic constraints in the doc interfaces to
match the real API by adding "extends Record<string, string>" to the TLabels
generic on JobHandle, TriggerOptions, TriggerAndWaitOptions (and the other
similar occurrences noted) so the signatures read e.g. JobHandle<TName, TInput,
TOutput, TLabels extends Record<string, string> = Record<string, string>> and
TriggerOptions<TLabels extends Record<string, string> = Record<string, string>>;
locate these types by name in the docs and apply the same constraint to the
matching generic declarations around the other referenced lines.
- Around line 36-37: The example uses Zod's z but doesn't import it; add an
import for Zod (e.g., import { z } from "zod") near the top of the snippet so
that the labels: z.object({ organizationId: z.string(), env: z.string() }) line
compiles; locate the example by the labels symbol or the z.object usage and
insert the z import alongside the other imports in the snippet.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c7fe0e9-5675-4a6f-856d-02fdce29eb9f

📥 Commits

Reviewing files that changed from the base of the PR and between bd30667 and 3d77fe8.

📒 Files selected for processing (10)
  • packages/durably/docs/llms.md
  • packages/durably/src/durably.ts
  • packages/durably/src/index.ts
  • packages/durably/src/job.ts
  • packages/durably/src/storage.ts
  • packages/durably/tests/node/types.test.ts
  • website/api/create-durably.md
  • website/api/define-job.md
  • website/api/index.md
  • website/public/llms.txt

Comment thread packages/durably/docs/llms.md
Comment thread packages/durably/docs/llms.md Outdated
- Add missing `z` import to createDurably example snippet
- Add `extends Record<string, string>` constraints to all TLabels
  generics in doc type definitions (JobHandle, TriggerOptions,
  TriggerAndWaitOptions, RunFilter, TypedRun)
- Add TypedRun type definition
- Add 3 runtime tests for labels schema validation
- Regenerate llms.txt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/durably/docs/llms.md`:
- Around line 494-496: The package's main entry does not re-export the
BatchTriggerInput type used in JobHandle.batchTrigger, so consumers can't import
that type; update the package's main export file to re-export BatchTriggerInput
(e.g., add BatchTriggerInput to the export list or add an explicit export {
BatchTriggerInput } from its defining module) alongside the existing JobHandle
export so the documented signature is accessible to consumers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aad899df-7124-4830-9ab2-374465095e4f

📥 Commits

Reviewing files that changed from the base of the PR and between 3d77fe8 and 964801e.

📒 Files selected for processing (3)
  • packages/durably/docs/llms.md
  • packages/durably/tests/shared/run-api.shared.ts
  • website/public/llms.txt

Comment thread packages/durably/docs/llms.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coji coji merged commit 0b36cdb into main Mar 6, 2026
4 checks passed
@coji coji deleted the feat/type-safe-labels branch March 6, 2026 03:49
@coji coji mentioned this pull request Mar 6, 2026
5 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Mar 26, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Type-safe labels via schema definition

1 participant