Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ jobs:
timeout-minutes: 10
strategy:
matrix:
node-version: [20.x, 22.x, 24.x]
# 22.22.2+ toolcache ships a broken global npm (missing promise-retry); pin until fixed upstream.
node-version: [20.x, 22.22.1, 24.x]

steps:
- name: Perform source code checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Setup Node version
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}

- name: Cache Package Node Modules
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.pnpm-store
Expand All @@ -39,8 +40,8 @@ jobs:

- name: Install
run: |
npm install -g npm@^11.2.0
npm install -g pnpm@latest-10
npm install -g npm@11.2.0
npm install -g pnpm@10.30.0
pnpm install

- name: Build
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"author": "Neo Financial Engineering <engineering@neofinancial.com>",
"license": "MIT",
"private": true,
"packageManager": "pnpm@10.6.5",
"packageManager": "pnpm@10.30.0",
"scripts": {
"clean": "pnpm --recursive run clean && rimraf node_modules",
"build": "pnpm --recursive run build",
Expand All @@ -22,16 +22,16 @@
"publish": "pnpm i && pnpm build && pnpm publish -r"
},
"devDependencies": {
"@biomejs/biome": "^2.4.7",
"@biomejs/biome": "^2.4.10",
"@faker-js/faker": "^9.9.0",
"@types/node": "^20.19.31",
"fishery": "^2.4.0",
"husky": "^9.1.7",
"lint-staged": "^16.4.0",
"rimraf": "^6.1.3",
"tsdown": "^0.21.2",
"tsdown": "^0.21.7",
"typescript": "^5.9.3",
"vitest": "^4.1.0",
"vitest-mock-extended": "^3.1.0"
"vitest": "^4.1.2",
"vitest-mock-extended": "^3.1.1"
}
}
2 changes: 1 addition & 1 deletion packages/chrono-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@neofinancial/chrono",
"version": "0.6.0",
"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.

👍

"description": "Core package for Chrono task scheduling system",
"private": false,
"publishConfig": {
Expand Down
21 changes: 20 additions & 1 deletion packages/chrono-core/src/chrono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,31 @@ export type RegisterTaskHandlerResponse<
TaskMapping extends TaskMappingBase,
> = EventEmitter<ProcessorEventsMap<TaskKind, TaskMapping>>;

/**
* A covariant interface exposing only task handler registration.
*
* Because `registerTaskHandler` only puts `TaskMapping` in covariant positions
* (task data flows *out* to the handler callback), this interface can be annotated
* `out TaskMapping`. This lets a `Chrono<BigMapping>` satisfy
* `ChronoHandlerRegistrar<SmallMapping>` whenever `BigMapping extends SmallMapping`,
* which is the key property needed to pass a single wide Chrono to multiple
* narrowly-typed outbox handlers without any casts.
*/
export interface ChronoHandlerRegistrar<out TaskMapping extends TaskMappingBase> {
registerTaskHandler<TaskKind extends Extract<keyof TaskMapping, string>>(
input: RegisterTaskHandlerInput<TaskKind, TaskMapping[TaskKind]>,
): RegisterTaskHandlerResponse<TaskKind, TaskMapping>;
}

/**
* The main class for scheduling and processing tasks.
* @param datastore - The datastore instance to use for storing and retrieving tasks.
* @returns The Chrono instance that can be used to start and stop the processors as well as receive chrono instance events.
*/
export class Chrono<TaskMapping extends TaskMappingBase, DatastoreOptions> extends EventEmitter<ChronoEventsMap> {
export class Chrono<TaskMapping extends TaskMappingBase, DatastoreOptions>
extends EventEmitter<ChronoEventsMap>
implements ChronoHandlerRegistrar<TaskMapping>
{
private readonly datastore: Datastore<TaskMapping, DatastoreOptions>;
private readonly processors: Map<keyof TaskMapping, Processor<keyof TaskMapping, TaskMapping>> = new Map();
private readonly pluginContexts: ChronoPluginContext<TaskMapping, DatastoreOptions>[] = [];
Expand Down
1 change: 1 addition & 0 deletions packages/chrono-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export {
Chrono,
type ChronoHandlerRegistrar,
type RegisterTaskHandlerInput,
type RegisterTaskHandlerResponse,
type ScheduleTaskInput,
Expand Down
2 changes: 1 addition & 1 deletion packages/chrono-mongo-datastore/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@neofinancial/chrono-mongo-datastore",
"version": "0.6.0",
"version": "0.7.0",
"description": "MongoDB datastore implementation for Chrono task scheduling system",
"private": false,
"publishConfig": {
Expand Down
Loading