Skip to content

feat: add ponyfill-temporal package - #73

Merged
macalinao merged 6 commits into
masterfrom
ponyfill-temporal
Jul 28, 2026
Merged

feat: add ponyfill-temporal package#73
macalinao merged 6 commits into
masterfrom
ponyfill-temporal

Conversation

@macalinao

@macalinao macalinao commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

Adds ponyfill-temporal — a ponyfill for the TC39 Temporal API — and migrates the entire monorepo to consume Temporal through it. ponyfill-temporal is now the sole owner of the temporal-polyfill / temporal-spec dependencies.

ponyfill-temporal

  • Uses native globalThis.Temporal when present; otherwise conditionally loads temporal-polyfill via a lazy dynamic import() (never a static import, so native runtimes never load the polyfill chunk).
  • Provides a synchronous Temporal / Intl / toTemporalInstant, resolved once via top-level await (const api = await loadTemporal() in temporal.ts). Consumers use them synchronously — new Temporal.PlainDate(...), Temporal.Now.instant() — with no await at the call site.
  • These are exported as both runtime values and temporal-spec type namespaces (a value const merged with a declare namespace), so Temporal.PlainDate works in value and type positions and import type { Temporal } from "ponyfill-temporal" works — mirroring how temporal-polyfill exports them. The type namespaces are generated from temporal-spec's public surface (generic option helper types are omitted).
  • Retains the async API: loadTemporal(), installTemporal() (opt-in global install), isNativeTemporalAvailable(), plus types TemporalApi / TemporalIntl / TemporalSpecModule.

Dependency stack (unchanged rationale)

  • Types: temporal-spec@^1.0.0 — runtime-free, models native Temporal, ships index.d.ts + global.d.ts.
  • Runtime fallback: temporal-polyfill@^1.0.1 — lightweight, active; typed via temporal-spec.

Repo migration (all packages)

parse-temporal, format-temporal, interval-temporal, temporal-quarter-fns, superjson-temporal, temporal-zod:

  • Runtime imports import { Temporal } from "temporal-polyfill" and type imports import type { Temporal } from "temporal-spec"... from "ponyfill-temporal" (28 source + test files). Synchronous usages are unchanged.
  • package.json: removed direct temporal-polyfill / temporal-spec (dependencies, devDependencies, and peerDependencies); added "ponyfill-temporal": "workspace:*" as a dependency. Only ponyfill-temporal now depends on temporal-polyfill / temporal-spec.
  • Tests were repointed too, so they exercise the real consumption path.

Two adjustments required by the temporal-spec 0.3 → 1.0 bump (flagged, not forced)

  • interval-temporal/comparators.ts: Temporal.X.compare is now typed number (temporal-spec dropped ComparisonResult); narrowed the 5 comparator returns to -1 | 0 | 1 (runtime behavior unchanged).
  • format-temporal.ts: Intl.FormattableTemporalObject now excludes ZonedDateTime; the default switch branch (which only receives directly-formattable types) asserts to Intl.FormattableTemporalObject. Also, ponyfill-temporal's Intl value is typed as the Temporal-aware DateTimeFormat (mirrored from temporal-spec, since it declares Intl type-only) so new Intl.DateTimeFormat(...) is assignable to format-temporal's parameter.

Verification (CI-relevant)

  • bun install — workspace dep wired, lockfile updated.
  • bun run build — all 7 packages build, emit dist/, satisfy isolatedDeclarations; TLA emits natively under NodeNext/ES2024.
  • bun run lint — exit 0 (biome + turbo eslint).
  • Tests — all green except the known pre-existing format-temporal ICU failure ("2023 May" vs "May 2023" for PlainYearMonth), which is a locale-data quirk unrelated to this change. Counts: ponyfill 5, parse 11, superjson 1, interval 11, quarter-fns 3, format 6/7 (1 known ICU fail), temporal-zod 103.
  • Dynamic-import chunking confirmed: the emitted dist/ contains no static from "temporal-polyfill" — only await import("temporal-polyfill") inside loadTemporal's fallback branch — so a native-Temporal runtime never loads the polyfill.

Changesets

  • ponyfill-temporal — minor (updated to describe the sync TLA exports).
  • parse-temporal, format-temporal, interval-temporal, temporal-quarter-fns, superjson-temporal, temporal-zod — minor (consume Temporal via ponyfill-temporal; direct temporal-polyfill/temporal-spec deps removed).

npm publish + trusted publishing

  • ponyfill-temporal@0.0.1 is already published (reserves the name); not republished for this change — future versions publish via CI.

  • Pending user action (2FA-gated, could not run from this environment — npm trust needs an interactive OTP session; token returned 403):

    npm login
    npm trust github ponyfill-temporal \
      --file release.yml \
      --repo macalinao/temporal-utils \
      --allow-publish

Summary by CodeRabbit

  • New Features
    • Added ponyfill-temporal, a TC39 Temporal ponyfill that prefers native globalThis.Temporal and conditionally loads a polyfill when missing.
    • Provides loadTemporal() (non-global access), isNativeTemporalAvailable() (capability detection), and installTemporal() (opt-in global install).
  • Documentation
    • Added README with install/usage guidance and ponyfill vs polyfill behavior.
  • Tests
    • Added Bun test suites covering native detection, conditional loading, and optional global installation.
  • Chores
    • Updated related Temporal utilities to consume Temporal via ponyfill-temporal instead of direct polyfill/spec usage.

@sourcery-ai

sourcery-ai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a new ponyfill-temporal package that provides a typed Temporal ponyfill API, preferring native globalThis.Temporal when available and lazily loading @js-temporal/polyfill otherwise, along with an optional global installer, tests, lint/build config, and a changeset for publishing.

Sequence diagram for loadTemporal ponyfill behavior

sequenceDiagram
  actor App
  participant ponyfill_temporal as ponyfill_temporal
  participant globalThis as globalThis
  participant js_temporal_polyfill as js_temporal_polyfill

  App->>ponyfill_temporal: loadTemporal()
  ponyfill_temporal->>globalThis: isNativeTemporalAvailable()
  alt [native Temporal available]
    ponyfill_temporal->>globalThis: read Temporal, Intl, Date.prototype.toTemporalInstant
    ponyfill_temporal-->>App: TemporalApi (native)
  else [native Temporal not available]
    ponyfill_temporal->>js_temporal_polyfill: import("@js-temporal/polyfill")
    js_temporal_polyfill-->>ponyfill_temporal: Temporal, Intl, toTemporalInstant
    ponyfill_temporal-->>App: TemporalApi (polyfill)
  end
Loading

Sequence diagram for installTemporal global polyfill behavior

sequenceDiagram
  actor App
  participant ponyfill_temporal as ponyfill_temporal
  participant globalThis as globalThis

  App->>ponyfill_temporal: installTemporal()
  ponyfill_temporal->>ponyfill_temporal: loadTemporal()
  ponyfill_temporal->>globalThis: isNativeTemporalAvailable()
  alt [native Temporal available]
    ponyfill_temporal-->>App: TemporalApi (native, no mutation)
  else [native Temporal not available]
    ponyfill_temporal->>globalThis: set Temporal = api.Temporal
    ponyfill_temporal->>globalThis: set Date.prototype.toTemporalInstant = api.toTemporalInstant
    ponyfill_temporal-->>App: TemporalApi (polyfill installed globally)
  end
Loading

File-Level Changes

Change Details Files
Implement Temporal ponyfill loader that prefers native Temporal and lazily imports the polyfill without mutating globals.
  • Define TemporalPolyfillModule and TemporalApi types based on @js-temporal/polyfill exports to ensure identical typing for native and polyfilled paths.
  • Add isNativeTemporalAvailable helper that checks for the presence of globalThis.Temporal.
  • Implement loadTemporal to return native Temporal/Intl/toTemporalInstant when available and otherwise dynamically import @js-temporal/polyfill and return its exports.
packages/ponyfill-temporal/src/load-temporal.ts
Provide an opt-in polyfill-style installer that writes the Temporal API onto globalThis only when native Temporal is absent.
  • Introduce MutableTemporalGlobal view of globalThis for safe typed mutation.
  • Implement installTemporal to call loadTemporal, then conditionally assign globalThis.Temporal and Date.prototype.toTemporalInstant when no native Temporal is present, returning the API either way.
packages/ponyfill-temporal/src/install-temporal.ts
Add tests validating native-vs-polyfill behavior, purity of the ponyfill loader, and installer semantics.
  • Test isNativeTemporalAvailable for correct detection of globalThis.Temporal presence.
  • Test loadTemporal returning native Temporal unchanged when present and falling back to the polyfill without mutating globals when absent.
  • Test installTemporal installing the polyfill onto globalThis only when native Temporal is missing and leaving an existing native Temporal untouched.
packages/ponyfill-temporal/src/load-temporal.test.ts
packages/ponyfill-temporal/src/install-temporal.test.ts
Wire up the new ponyfill-temporal package entrypoints and tooling configuration.
  • Export installTemporal and loadTemporal from the package root index.
  • Configure package metadata, dependencies (including @js-temporal/polyfill), build, lint, and test scripts in package.json.
  • Add TypeScript configuration extending the shared base, plus package-local ESLint config and .gitignore.
  • Document usage, API surface, and conditional loading behavior in README.
packages/ponyfill-temporal/src/index.ts
packages/ponyfill-temporal/package.json
packages/ponyfill-temporal/tsconfig.json
packages/ponyfill-temporal/eslint.config.js
packages/ponyfill-temporal/.gitignore
packages/ponyfill-temporal/README.md
Register the new package in release automation with an initial changeset.
  • Add a changeset marking a minor bump for ponyfill-temporal with a description of the new ponyfill API.
  • Update lockfile to capture new dependencies and package metadata.
.changeset/ponyfill-temporal.md
bun.lock

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@macalinao, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ca3cbb65-a350-4a26-aaa6-c604c79f6f22

📥 Commits

Reviewing files that changed from the base of the PR and between d37303c and f68bf5c.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • .oxlintrc.json
  • packages/format-temporal/package.json
  • packages/format-temporal/src/format-temporal.test.ts
  • packages/format-temporal/src/format-temporal.ts
  • packages/interval-temporal/package.json
  • packages/parse-temporal/package.json
  • packages/parse-temporal/src/parse-plain-date.ts
  • packages/ponyfill-temporal/package.json
  • packages/ponyfill-temporal/src/load-temporal.ts
  • packages/superjson-temporal/package.json
  • packages/temporal-quarter-fns/package.json
  • packages/temporal-zod/package.json

Walkthrough

Adds the ponyfill-temporal package with native detection, lazy temporal-polyfill loading, optional global installation, synchronous exports, and migration of related packages to its runtime and type surface.

Changes

Temporal ponyfill

Layer / File(s) Summary
Native detection, lazy loading, and synchronous exports
packages/ponyfill-temporal/src/load-temporal.ts, packages/ponyfill-temporal/src/temporal.ts, packages/ponyfill-temporal/src/index.ts, packages/ponyfill-temporal/src/load-temporal.test.ts
Defines typed native and polyfill branches, lazy loading, top-level-await exports, merged Temporal and Intl type namespaces, and loader tests.
Optional global installation
packages/ponyfill-temporal/src/install-temporal.ts, packages/ponyfill-temporal/src/install-temporal.test.ts
Adds installTemporal() and verifies installation when native Temporal is absent while preserving an existing native implementation.
Package wiring and documentation
packages/ponyfill-temporal/package.json, packages/ponyfill-temporal/tsconfig.json, packages/ponyfill-temporal/eslint.config.js, packages/ponyfill-temporal/.gitignore, packages/ponyfill-temporal/README.md, .changeset/ponyfill-temporal.md
Configures publishing, tooling, ignored build output, release metadata, and API usage documentation.
Consumer dependency and import migration
packages/{format-temporal,interval-temporal,parse-temporal,superjson-temporal,temporal-quarter-fns,temporal-zod}/..., .changeset/consume-ponyfill-temporal.md
Adds ponyfill-temporal dependencies, removes direct Temporal package dependencies and peers, and switches runtime and type imports while retaining existing behavior and tests.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ConsumerPackage
  participant PonyfillTemporal
  participant globalThis
  participant temporalPolyfill
  ConsumerPackage->>PonyfillTemporal: import Temporal API
  PonyfillTemporal->>globalThis: check native Temporal
  alt native Temporal exists
    globalThis-->>PonyfillTemporal: provide native Temporal surface
  else native Temporal absent
    PonyfillTemporal->>temporalPolyfill: dynamically import fallback
    temporalPolyfill-->>PonyfillTemporal: provide polyfill surface
  end
  PonyfillTemporal-->>ConsumerPackage: expose Temporal, Intl, and helpers
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding the new ponyfill-temporal package.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ponyfill-temporal

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In loadTemporal, the native path assumes Date.prototype.toTemporalInstant exists and is compatible with the polyfill’s type; consider defensively handling runtimes that ship Temporal but not toTemporalInstant or where its signature diverges.
  • The TemporalGlobal/MutableTemporalGlobal interfaces model Intl and Date as always present on globalThis; if this package is intended to be used in non-browser/non-Node environments, it may be worth narrowing these typings or guarding property access to avoid unsafe assumptions.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `loadTemporal`, the native path assumes `Date.prototype.toTemporalInstant` exists and is compatible with the polyfill’s type; consider defensively handling runtimes that ship `Temporal` but not `toTemporalInstant` or where its signature diverges.
- The `TemporalGlobal`/`MutableTemporalGlobal` interfaces model `Intl` and `Date` as always present on `globalThis`; if this package is intended to be used in non-browser/non-Node environments, it may be worth narrowing these typings or guarding property access to avoid unsafe assumptions.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ponyfill-temporal/src/install-temporal.test.ts`:
- Around line 5-33: Update the installTemporal test setup to snapshot the
Date.prototype.toTemporalInstant property descriptor and restore it in cleanup
alongside globalRef.Temporal. In the native-absent test, assert that
Date.prototype.toTemporalInstant equals api.toTemporalInstant after
installTemporal completes.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9adbfec4-f3e7-4ae7-a0e4-cf89ab342e57

📥 Commits

Reviewing files that changed from the base of the PR and between 37092b0 and 1798ec5.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • .changeset/ponyfill-temporal.md
  • packages/ponyfill-temporal/.gitignore
  • packages/ponyfill-temporal/README.md
  • packages/ponyfill-temporal/eslint.config.js
  • packages/ponyfill-temporal/package.json
  • packages/ponyfill-temporal/src/index.ts
  • packages/ponyfill-temporal/src/install-temporal.test.ts
  • packages/ponyfill-temporal/src/install-temporal.ts
  • packages/ponyfill-temporal/src/load-temporal.test.ts
  • packages/ponyfill-temporal/src/load-temporal.ts
  • packages/ponyfill-temporal/tsconfig.json

Comment on lines +5 to +33
const globalRef = globalThis as { Temporal?: unknown };
const originalTemporal = globalRef.Temporal;

function restoreTemporal(): void {
if (originalTemporal === undefined) {
delete globalRef.Temporal;
} else {
globalRef.Temporal = originalTemporal;
}
}

afterEach(() => {
restoreTemporal();
});

describe("installTemporal", () => {
test("installs the polyfill onto globalThis when native is absent", async () => {
delete globalRef.Temporal;
expect(isNativeTemporalAvailable()).toBe(false);

const api = await installTemporal();

// Temporal is now globally available.
expect(isNativeTemporalAvailable()).toBe(true);
expect(globalRef.Temporal).toBe(api.Temporal);

const date = api.Temporal.PlainDate.from("2021-06-30");
expect(date.year).toBe(2021);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Restore and verify Date.prototype.toTemporalInstant.

The polyfill-install test leaks this prototype mutation into later tests, while never asserting the documented installation behavior. Snapshot and restore its property descriptor alongside Temporal, then assert it equals api.toTemporalInstant.

Proposed fix
 const globalRef = globalThis as { Temporal?: unknown };
 const originalTemporal = globalRef.Temporal;
+const originalToTemporalInstant = Object.getOwnPropertyDescriptor(
+  Date.prototype,
+  "toTemporalInstant",
+);
 
 function restoreTemporal(): void {
   if (originalTemporal === undefined) {
     delete globalRef.Temporal;
   } else {
     globalRef.Temporal = originalTemporal;
   }
+
+  if (originalToTemporalInstant === undefined) {
+    delete (Date.prototype as { toTemporalInstant?: unknown }).toTemporalInstant;
+  } else {
+    Object.defineProperty(
+      Date.prototype,
+      "toTemporalInstant",
+      originalToTemporalInstant,
+    );
+  }
 }
@@
     expect(isNativeTemporalAvailable()).toBe(true);
     expect(globalRef.Temporal).toBe(api.Temporal);
+    expect(
+      (Date.prototype as { toTemporalInstant?: unknown }).toTemporalInstant,
+    ).toBe(api.toTemporalInstant);
📝 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
const globalRef = globalThis as { Temporal?: unknown };
const originalTemporal = globalRef.Temporal;
function restoreTemporal(): void {
if (originalTemporal === undefined) {
delete globalRef.Temporal;
} else {
globalRef.Temporal = originalTemporal;
}
}
afterEach(() => {
restoreTemporal();
});
describe("installTemporal", () => {
test("installs the polyfill onto globalThis when native is absent", async () => {
delete globalRef.Temporal;
expect(isNativeTemporalAvailable()).toBe(false);
const api = await installTemporal();
// Temporal is now globally available.
expect(isNativeTemporalAvailable()).toBe(true);
expect(globalRef.Temporal).toBe(api.Temporal);
const date = api.Temporal.PlainDate.from("2021-06-30");
expect(date.year).toBe(2021);
});
const globalRef = globalThis as { Temporal?: unknown };
const originalTemporal = globalRef.Temporal;
const originalToTemporalInstant = Object.getOwnPropertyDescriptor(
Date.prototype,
"toTemporalInstant",
);
function restoreTemporal(): void {
if (originalTemporal === undefined) {
delete globalRef.Temporal;
} else {
globalRef.Temporal = originalTemporal;
}
if (originalToTemporalInstant === undefined) {
delete (Date.prototype as { toTemporalInstant?: unknown }).toTemporalInstant;
} else {
Object.defineProperty(
Date.prototype,
"toTemporalInstant",
originalToTemporalInstant,
);
}
}
afterEach(() => {
restoreTemporal();
});
describe("installTemporal", () => {
test("installs the polyfill onto globalThis when native is absent", async () => {
delete globalRef.Temporal;
expect(isNativeTemporalAvailable()).toBe(false);
const api = await installTemporal();
// Temporal is now globally available.
expect(isNativeTemporalAvailable()).toBe(true);
expect(globalRef.Temporal).toBe(api.Temporal);
expect(
(Date.prototype as { toTemporalInstant?: unknown }).toTemporalInstant,
).toBe(api.toTemporalInstant);
const date = api.Temporal.PlainDate.from("2021-06-30");
expect(date.year).toBe(2021);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ponyfill-temporal/src/install-temporal.test.ts` around lines 5 - 33,
Update the installTemporal test setup to snapshot the
Date.prototype.toTemporalInstant property descriptor and restore it in cleanup
alongside globalRef.Temporal. In the native-absent test, assert that
Date.prototype.toTemporalInstant equals api.toTemporalInstant after
installTemporal completes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/ponyfill-temporal/src/temporal.ts (1)

23-28: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Preserve or document the complete public type surface.

The implementation explicitly omits types such as Temporal.RoundingOptions<Units>, so this is not a drop-in type replacement for consumers using those public names. Re-export the complete temporal-spec surface or document and test the intentional incompatibility.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ponyfill-temporal/src/temporal.ts` around lines 23 - 28, Update the
generated ambient type bindings near the Temporal/Intl namespace merge to
preserve the complete public temporal-spec surface, including generic helper
types such as Temporal.RoundingOptions<Units>; alternatively, explicitly
document and add tests for the intentional incompatibility if those types must
remain omitted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ponyfill-temporal/src/temporal.ts`:
- Around line 23-28: Update the generated ambient type bindings near the
Temporal/Intl namespace merge to preserve the complete public temporal-spec
surface, including generic helper types such as Temporal.RoundingOptions<Units>;
alternatively, explicitly document and add tests for the intentional
incompatibility if those types must remain omitted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 74f318a3-0d44-44d6-9052-3380bfa4613d

📥 Commits

Reviewing files that changed from the base of the PR and between 8df5ad9 and d37303c.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (39)
  • .changeset/consume-ponyfill-temporal.md
  • .changeset/ponyfill-temporal.md
  • packages/format-temporal/package.json
  • packages/format-temporal/src/format-temporal.test.ts
  • packages/format-temporal/src/format-temporal.ts
  • packages/interval-temporal/package.json
  • packages/interval-temporal/src/are-intervals-overlapping.test.ts
  • packages/interval-temporal/src/comparators.test.ts
  • packages/interval-temporal/src/comparators.ts
  • packages/interval-temporal/src/normalize-intervals.test.ts
  • packages/parse-temporal/package.json
  • packages/parse-temporal/src/parse-plain-date-time-yyyymmddhhmmp.test.ts
  • packages/parse-temporal/src/parse-plain-date-time-yyyymmddhhmmp.ts
  • packages/parse-temporal/src/parse-plain-date.test.ts
  • packages/parse-temporal/src/parse-plain-date.ts
  • packages/parse-temporal/src/parse-plain-time-hhmm.test.ts
  • packages/parse-temporal/src/parse-plain-time-hhmm.ts
  • packages/ponyfill-temporal/src/index.ts
  • packages/ponyfill-temporal/src/load-temporal.ts
  • packages/ponyfill-temporal/src/temporal.ts
  • packages/superjson-temporal/package.json
  • packages/superjson-temporal/src/register-super-json-temporal.test.ts
  • packages/superjson-temporal/src/register-super-json-temporal.ts
  • packages/temporal-quarter-fns/package.json
  • packages/temporal-quarter-fns/src/get-quarter.test.ts
  • packages/temporal-quarter-fns/src/get-quarter.ts
  • packages/temporal-quarter-fns/src/temporal-with-year-month.ts
  • packages/temporal-zod/package.json
  • packages/temporal-zod/src/base/duration.ts
  • packages/temporal-zod/src/base/index.test.ts
  • packages/temporal-zod/src/base/instant.ts
  • packages/temporal-zod/src/base/plain-date-time.ts
  • packages/temporal-zod/src/base/plain-date.ts
  • packages/temporal-zod/src/base/plain-month-day.ts
  • packages/temporal-zod/src/base/plain-time.ts
  • packages/temporal-zod/src/base/plain-year-month.ts
  • packages/temporal-zod/src/base/zoned-date-time.ts
  • packages/temporal-zod/src/json-schema.test.ts
  • packages/temporal-zod/src/json-schemas.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • .changeset/ponyfill-temporal.md
  • packages/ponyfill-temporal/src/index.ts
  • packages/ponyfill-temporal/src/load-temporal.ts

Adopt the oxlint + oxfmt toolchain (replacing Biome/ESLint) from master.
- Migrate the new ponyfill-temporal package off ESLint (remove eslint.config.js,
  eslint deps, per-package lint script).
- Keep this branch's ponyfill-temporal consumption: packages depend on
  ponyfill-temporal instead of temporal-polyfill/temporal-spec directly.
- Fix an oxlint finding in load-temporal.ts (import() type annotation -> import type).
- Port the full @macalinao/biome-config/base rule set into .oxlintrc.json so the
  previous lint surface is preserved under oxlint.
temporal-polyfill 0.3 rendered `{ year: "numeric", month: "long" }` for
en-US as "2023 May"; 1.x produces the correct "May 2023".
@macalinao
macalinao merged commit 311cb7a into master Jul 28, 2026
12 checks passed
@macalinao
macalinao deleted the ponyfill-temporal branch July 28, 2026 12:08
macalinao added a commit that referenced this pull request Jul 28, 2026
Master merged #73 (ponyfill-temporal), which swaps temporal-zod's Temporal
import to the ponyfill and drops the direct temporal-polyfill dependency.

- Resolve import conflicts in the six base files: keep master's
  ponyfill-temporal import alongside this branch's iso-pattern-parts
  imports; migrate orpc.test.ts off temporal-polyfill too.
- Preload temporal-polyfill/full/global in bun tests (bunfig.toml):
  Bun has no native Temporal and the ponyfill's default fallback omits
  non-ISO calendar data, which the calendar-annotation tests exercise.
- Satisfy oxlint x isolatedDeclarations on the exported patterns:
  template-literal exports need an explicit type (TS9010), so widen with
  'as string'; where the interpolated parts are already string-typed,
  oxlint flags the assertion as unnecessary, so those sites carry a
  disable comment.
- Regenerate bun.lock via bun install.
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.

1 participant