Skip to content

Introduce chrono handler registrar#64

Merged
darrenpicard25 merged 8 commits intomasterfrom
introduce-ChronoHandlerRegistrar
Apr 7, 2026
Merged

Introduce chrono handler registrar#64
darrenpicard25 merged 8 commits intomasterfrom
introduce-ChronoHandlerRegistrar

Conversation

@darrenpicard25
Copy link
Copy Markdown
Collaborator

@darrenpicard25 darrenpicard25 commented Apr 6, 2026

Introduce ChronoHandlerRegistrar interface

Adds a new covariant interface that represents the handler-registration surface of Chrono:

export interface ChronoHandlerRegistrar<out TaskMapping extends TaskMappingBase> {
  registerTaskHandler<K extends Extract<keyof TaskMapping, string>>(
    input: RegisterTaskHandlerInput<K, TaskMapping[K]>
  ): RegisterTaskHandlerResponse<K, TaskMapping>;
}

Chrono now declares implements ChronoHandlerRegistrar.

Why this is needed

Chrono is invariant in TaskMapping because TaskMapping flows into scheduleTask (contravariant) and out through registerTaskHandler callbacks (covariant). This means Chrono is not assignable to Chrono even when BigMapping is a strict superset — TypeScript correctly rejects it.

ChronoHandlerRegistrar isolates the covariant half: it only exposes registerTaskHandler, where TaskMapping flows exclusively into handler callbacks (doubly contravariant = covariant). The out T annotation makes this explicit and allows a Chrono instance to be safely narrowed to ChronoHandlerRegistrar without any type assertions.

This is a breaking change (1.0.0) because it adds a new exported type to the public API surface that consumers of Chrono may need to implement or reference.

Also fixed

A latent bug in RegisterTaskHandlerResponse: the type was passing TaskMapping[TaskKind] (the task data type) as the second argument to ProcessorEventsMap where it expected the full TaskMapping. This was harmless before stricter variance checking surfaced it.

Summary by CodeRabbit

  • Chores

    • Updated development dependencies and package manager range.
    • Bumped package versions to 0.7.0.
    • CI workflow updated to newer actions and simplified package manager provisioning.
    • Updated tooling/schema reference in project manifest.
  • New Features

    • Improved type safety for task handler registration API.

…on surface of Chrono. Chrono<TaskMapping> is invariant in TaskMapping because TaskMapping flows into scheduleTask (contravariant) and out through registerTaskHandler callbacks (covariant). This means Chrono<BigMapping> is not assignable to Chrono<SmallMapping> even when BigMapping is a strict superset — TypeScript correctly rejects it.

ChronoHandlerRegistrar isolates the covariant half: it only exposes registerTaskHandler, where TaskMapping flows exclusively into handler callbacks (doubly contravariant = covariant). The out T annotation makes this explicit and allows a Chrono<BigMapping> instance to be safely narrowed to ChronoHandlerRegistrar<SmallMapping> without any type assertions.

This is a breaking change (1.0.0) because it adds a new exported type to the public API surface that consumers of Chrono may need to implement or reference.

Also fixed

A latent bug in RegisterTaskHandlerResponse: the type was passing TaskMapping[TaskKind] (the task data type) as the second argument to ProcessorEventsMap where it expected the full TaskMapping. This was harmless before stricter variance checking surfaced it.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updated dev tooling and CI, bumped package versions, and added a type-only exporter/interface (ChronoHandlerRegistrar) which Chrono implements; no runtime behavior changes.

Changes

Cohort / File(s) Summary
Tooling manifest & dev deps
biome.json, package.json
Bumped Biome $schema (2.4.72.4.10); updated packageManager to pnpm@10.30.0; bumped devDependency ranges for @biomejs/biome, tsdown, vitest, vitest-mock-extended.
Package version bumps
packages/chrono-core/package.json, packages/chrono-mongo-datastore/package.json
Incremented package versions from 0.6.00.7.0 in both packages; no other metadata changed.
Type interface & exports
packages/chrono-core/src/chrono.ts, packages/chrono-core/src/index.ts
Added exported type-only ChronoHandlerRegistrar<out TaskMapping extends TaskMappingBase> and declared Chrono as implements ChronoHandlerRegistrar<TaskMapping>; re-exported the type from the package index. No runtime behavior changes.
CI workflow & install steps
.github/workflows/ci.yml
Upgraded GitHub Action versions (actions/checkout v4→v6, actions/setup-node v4→v6, actions/cache v4→v5); replaced global npm/pnpm installs with corepack enable then pnpm install.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged a schema, hopped a version gate,
A type appeared to link the crate,
CI learned corepack and fetched the herd,
Two packages grew a tiny spurt—
I nibble crumbs of tidy fate.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Introduce chrono handler registrar' directly and accurately reflects the main change: adding a new ChronoHandlerRegistrar interface and having Chrono implement it.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch introduce-ChronoHandlerRegistrar

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

Copy link
Copy Markdown

@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/chrono-core/package.json`:
- Line 3: The package.json "version" field in packages/chrono-core (the
"version" key currently "0.6.1") is incorrect for a breaking change release;
update the "version" value to "1.0.0" in packages/chrono-core/package.json and
ensure any release metadata (changelog/release notes) reflects the 1.0.0
breaking-change bump so the published package matches the contract.

In `@packages/chrono-mongo-datastore/package.json`:
- Line 3: Update the package version in chrono-mongo-datastore by changing the
"version" field from "0.6.1" to "1.0.0" in package.json so the package release
aligns with the breaking-change rollout and the PR's intended major version
bump.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46520bbf-fb02-4e71-ba14-5bcb8877a568

📥 Commits

Reviewing files that changed from the base of the PR and between bd4d23a and ef03f5d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • biome.json
  • package.json
  • packages/chrono-core/package.json
  • packages/chrono-core/src/chrono.ts
  • packages/chrono-core/src/index.ts
  • packages/chrono-mongo-datastore/package.json

Comment thread packages/chrono-core/package.json Outdated
{
"name": "@neofinancial/chrono",
"version": "0.6.0",
"version": "0.6.1",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Versioning does not match the stated breaking-change policy.

Line 3 applies a patch bump (0.6.1), but this PR is described as a breaking change targeting 1.0.0. Please align the published version with that contract before release.

📦 Proposed fix
-  "version": "0.6.1",
+  "version": "1.0.0",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"version": "0.6.1",
"version": "1.0.0",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/chrono-core/package.json` at line 3, The package.json "version"
field in packages/chrono-core (the "version" key currently "0.6.1") is incorrect
for a breaking change release; update the "version" value to "1.0.0" in
packages/chrono-core/package.json and ensure any release metadata
(changelog/release notes) reflects the 1.0.0 breaking-change bump so the
published package matches the contract.

{
"name": "@neofinancial/chrono-mongo-datastore",
"version": "0.6.0",
"version": "0.6.1",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Release version should align with the breaking-change rollout.

Line 3 is a patch bump (0.6.1), but the PR is treated as a breaking change (1.0.0). This package version should be aligned with that release decision as well.

📦 Proposed fix
-  "version": "0.6.1",
+  "version": "1.0.0",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"version": "0.6.1",
"version": "1.0.0",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/chrono-mongo-datastore/package.json` at line 3, Update the package
version in chrono-mongo-datastore by changing the "version" field from "0.6.1"
to "1.0.0" in package.json so the package release aligns with the
breaking-change rollout and the PR's intended major version bump.

@wiz-a38520980d
Copy link
Copy Markdown

wiz-a38520980d Bot commented Apr 6, 2026

Wiz Scan Summary

Scanner Findings
Vulnerability Finding Vulnerabilities -
Data Finding Sensitive Data -
Secret Finding Secrets -
IaC Misconfiguration IaC Misconfigurations -
SAST Finding SAST Findings -
Total -

View scan details in Wiz

To detect these findings earlier in the dev lifecycle, try using Wiz Code VS Code Extension.

Copy link
Copy Markdown

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

29-38: ⚠️ Potential issue | 🟠 Major

Include Node version in cache key to prevent cross-version restoration.

The cache key at lines 36–38 does not differentiate between Node versions (20.x, 22.x, 24.x). This allows matrix jobs to restore node_modules built for a different Node ABI, causing native module failures and flaky CI.

Suggested fix
       - name: Cache Package Node Modules
         uses: actions/cache@v5
         with:
           path: |
             ~/.pnpm-store
-            node_modules
-            packages/*/node_modules
-          key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
+          key: pnpm-${{ runner.os }}-${{ matrix.node-version }}-${{ hashFiles('pnpm-lock.yaml') }}
           restore-keys: |
-            pnpm-
+            pnpm-${{ runner.os }}-${{ matrix.node-version }}-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 29 - 38, The cache key for the "Cache
Package Node Modules" step doesn't include the Node version, allowing
cross-version restores; update the cache key and restore-keys to incorporate the
Node version identifier used in the matrix (e.g., matrix.node-version or the
node-version variable) so the key becomes version-specific (for example
prefixing or interpolating ${ { matrix.node-version } } into the existing
pnpm-${{ hashFiles('pnpm-lock.yaml') }} key and similarly updating
restore-keys), leaving the path and actions/cache@v5 usage unchanged.
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

22-30: Pin Actions to immutable SHAs instead of mutable major tags.

Lines 22, 25, and 30 use floating major tags (@v6, @v6, @v5). For CI supply-chain hardening, pin each action to a full commit SHA with a comment noting the intended major/minor version.

Reference docs:

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 22 - 30, Replace the mutable action
tags with immutable commit SHAs: change uses: actions/checkout@v6, uses:
actions/setup-node@v6, and uses: actions/cache@v5 to pinned references using the
full commit SHA for each repo, and add an inline comment next to each use
stating the intended major/minor version (e.g., // intended: v6.x) so reviewers
know the intended version while ensuring supply-chain immutability; locate these
usages in the workflow steps for Checkout, Setup Node, and Cache Package Node
Modules and update them accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 29-38: The cache key for the "Cache Package Node Modules" step
doesn't include the Node version, allowing cross-version restores; update the
cache key and restore-keys to incorporate the Node version identifier used in
the matrix (e.g., matrix.node-version or the node-version variable) so the key
becomes version-specific (for example prefixing or interpolating ${ {
matrix.node-version } } into the existing pnpm-${{ hashFiles('pnpm-lock.yaml')
}} key and similarly updating restore-keys), leaving the path and
actions/cache@v5 usage unchanged.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 22-30: Replace the mutable action tags with immutable commit SHAs:
change uses: actions/checkout@v6, uses: actions/setup-node@v6, and uses:
actions/cache@v5 to pinned references using the full commit SHA for each repo,
and add an inline comment next to each use stating the intended major/minor
version (e.g., // intended: v6.x) so reviewers know the intended version while
ensuring supply-chain immutability; locate these usages in the workflow steps
for Checkout, Setup Node, and Cache Package Node Modules and update them
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d2656b1-907f-4e1c-9853-9af17c19ae86

📥 Commits

Reviewing files that changed from the base of the PR and between ef03f5d and d9d00a4.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml

Comment thread .github/workflows/ci.yml
- name: Install
run: |
npm install -g npm@^11.2.0
npm install -g pnpm@latest-10
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

so discovered node has this built in thing called corepack that does:

Corepack is a zero-runtime-dependency Node.js script that acts as a bridge between Node.js projects and the package managers they are intended to be used with during development. In practical terms, Corepack lets you use Yarn, npm, and pnpm without having to install them.

so thought that was cool

https://github.com/nodejs/corepack

Comment thread package.json Outdated
maiahneo
maiahneo previously approved these changes Apr 6, 2026
{
"name": "@neofinancial/chrono",
"version": "0.6.1",
"version": "0.7.0",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

👍

Copy link
Copy Markdown
Collaborator

@maiahneo maiahneo left a comment

Choose a reason for hiding this comment

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

I have some concern in the corepack usage below.

Comment thread .github/workflows/ci.yml Outdated
maiahneo
maiahneo previously approved these changes Apr 7, 2026
@maiahneo
Copy link
Copy Markdown
Collaborator

maiahneo commented Apr 7, 2026

Weird that CI build for v22.x is failing w/ following error:

npm error Cannot find module 'promise-retry'

@darrenpicard25
Copy link
Copy Markdown
Collaborator Author

Weird that CI build for v22.x is failing w/ following error:

npm error Cannot find module 'promise-retry'

yeah something happened in newest node 22 bundle. So just going to pin version in CI to avoid this

@darrenpicard25 darrenpicard25 requested a review from maiahneo April 7, 2026 16:25
Copy link
Copy Markdown
Collaborator

@maiahneo maiahneo left a comment

Choose a reason for hiding this comment

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

🚀

@darrenpicard25 darrenpicard25 merged commit e2f583e into master Apr 7, 2026
9 checks passed
darrenpicard25 added a commit that referenced this pull request Apr 14, 2026
…#65)

This is a follow up to PR: #64 that intorduced ChronoHandlerRegistrar type

Add ChronoTaskScheduler interface to solve TypeScript variance issues when passing a wide Chrono to code that only needs a subset of the task mapping. ChronoTaskScheduler exposes only scheduleTask() for producers, while ChronoHandlerRegistrar (with out variance annotation) exposes only registerTaskHandler() for consumers. The Chrono class now implements both interfaces.
Update the example app to demonstrate the new narrower types by extracting registerHandlers(registrar: ChronoHandlerRegistrar) and scheduleTasks(scheduler: ChronoTaskScheduler) helper functions, showing that a full Chrono instance satisfies both interfaces.
Update chrono-core documentation to list ChronoTaskScheduler and ChronoHandlerRegistrar in the Exported Types table and add a note to the Chrono Class API section explaining how the narrow interfaces can be used.
Add publish:alpha root script for publishing prerelease versions with --tag alpha.
Bump package versions to 0.7.1-alpha.0 for @neofinancial/chrono and @neofinancial/chrono-mongo-datastore.
Dev-dependency bumps: @biomejs/biome 2.4.10 -> 2.4.11, vitest 4.1.2 -> 4.1.4, vitest-mock-extended 3.1.1 -> 4.0.0
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.

2 participants