feat: add CronIterator — ECMAScript-native stateful iterator for Cron schedules#365
feat: add CronIterator — ECMAScript-native stateful iterator for Cron schedules#365
Conversation
…native iteration Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com>
|
@copilot Just to check. Does this follow common practice? Does this fallow croner practice? Is this documented the same way as existing features? Are the changes minimal? Is it documented the same way as existing features? Is it tested properly and efficient? |
Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com>
Reviewed everything against the existing codebase — here's what was corrected in commit Common practice: Croner practice:
Documentation: Consistent with existing features — single-line entry in the Minimal changes: Testing: All tests now use exact |
There was a problem hiding this comment.
Pull request overview
Adds an enumerate() API to produce a stateful, ECMAScript-native iterator over upcoming cron occurrences, along with tests and documentation updates to demonstrate usage across the library.
Changes:
- Added
CronIterator<T>(Iterator + Iterable) withnext(),peek(), andreset()insrc/croner.ts, plusCron.prototype.enumerate(startAt?). - Added a new iterator-focused test suite covering iterator protocol behavior and parity with
nextRuns(). - Updated docs/README to document the new
enumerate()API and provide examples.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/croner.ts |
Introduces CronIterator and Cron.enumerate() factory, and exports the iterator. |
test/iterator.test.ts |
Adds coverage for iterator semantics (next/peek/reset, iterable behavior, stopAt exhaustion). |
docs/src/usage/basics.md |
Documents enumerate() in the “Status” API list. |
docs/src/usage/examples.md |
Adds example usage for enumerate() with for...of, destructuring, peek, reset, and stopAt. |
README.md |
Adds enumerate() to the README “Status” section API list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com>
Both issues from the review thread are addressed in commit Cursor drift with const dayOffset = this.cron.options.dayOffset;
this.cursor = (dayOffset !== undefined && dayOffset !== 0)
? new Date(nextDate.getTime() - dayOffset * 24 * 60 * 60 * 1000)
: nextDate;Missing |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/croner.ts
Outdated
| private static _normalizeDate(d?: Date | string | null): Date | undefined { | ||
| if (d === undefined || d === null) return undefined; | ||
| return d instanceof Date ? new Date(d.getTime()) : new Date(d); | ||
| } |
There was a problem hiding this comment.
CronIterator._normalizeDate() converts string inputs to new Date(d), which changes semantics when the Cron instance is configured with timezone (CronDate.fromString uses fromTZISO(str, tz) to interpret the string in that timezone, while new Date(str) interprets it in the host environment timezone). This makes enumerate("...") potentially diverge from nextRun("...") / nextRuns(..., "...") for timezone-aware schedules. Consider preserving string inputs (store cursor as Date | string | undefined), or normalizing via CronDate with cron's tz so string parsing matches the rest of the API; adding a regression test with { timezone: "Europe/Stockholm" } would help.
|
@copilot apply changes based on the comments in this thread |
Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com>
Fixed in commit
Added |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot verify that formatting and tests are ok |
Co-authored-by: Hexagon <419737+Hexagon@users.noreply.github.com>
Fixed in commit |
CronIterator<T>class insrc/croner.tswith Iterator + Iterable protocols,.next(),.peek(),.reset(), and private_normalizeCursor()helperCron.prototype.enumerate(startAt?)factory method — placed alongsidenextRun()/nextRuns()/previousRuns()as a query methodCronIteratorfromsrc/croner.tsCronIterator.next()cursor drift whendayOffsetis set — cursor is stored as the un-offset schedule time; yielded Date is always a fresh cloneCronIteratorstringstartAttimezone parsing — strings are now preserved as-is sonextRun()can parse them viaCronDate/fromTZISOusing the Cron instance's configured timezonetest/iterator.test.tsincludingdayOffsetandtimezonestring-startAt consistency tests againstnextRuns()docs/src/usage/basics.mdwith enumerate APIdocs/src/usage/examples.mdwith iterator examplesREADME.mdwith enumerate entry in the status section💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.