@js-temporal/polyfill

repository·main·Indexed 20 days ago

https://github.com/js-temporal/temporal-polyfill

A production-ready polyfill for the ECMA TC39 Stage 4 Temporal proposal. It provides a robust implementation of the Temporal API, including Temporal.Instant, Temporal.ZonedDateTime, Temporal.PlainDate, Temporal.PlainTime, Temporal.PlainDateTime, Temporal.PlainYearMonth, Temporal.PlainMonthDay, and Temporal.Duration. The polyfill extends Intl.DateTimeFormat for localized formatting and includes a utility to convert standard JavaScript Date objects to Temporal.Instant.

Tokens
7.2K
Snippets
32
Records
40
Agent score
73%

What's inside @js-temporal/polyfill

  1. Rebasing Guidelines and Best Practices

    main

    When rebasing changes from the spec repository, adhere to these rules:

    • Minimize Runtime Changes: Prefer adapting TypeScript types over changing code behavior. If type-checking is impossible, use assertExists or uncheckedAssertNarrowedType.
    • Parameter Renaming: To avoid TypeScript issues with re-assigning function parameters, rename the parameter with a Param suffix and create a local variable with the original name.
    • Avoid New Dependencies: Do not add new dependencies to the polyfill.
    • File Structure: Keep code organized in the same files as upstream. Do not create arbitrary new files for organization.
    • BigInt Handling: Use JSBI for bigint compatibility instead of upstream's big-integer to ensure correct type-checking and build-time transpilation.
    • Ecmascript Module Differences: Note that polyfill/lib/ecmascript.ts uses regular module exports, whereas upstream ecmascript.mjs uses object properties; direct rebasing of these files will fail and requires manual intervention.
  2. Understand Temporal polyfill global object behavior

    main
    Unlike a native implementation, this polyfill does not install a global Temporal object. This design choice prevents overwriting a native Temporal implementation if one is already present in the environment. You must explicitly import Temporal from the package to use it.
  3. Prepare for rebasing commits from upstream

    main

    Before rebasing, ensure your local copies of the pub and spec-pub repositories are up to date and your main branch is synchronized with pub/main. You must also initialize the test262 submodule.

    To identify the starting point for rebasing, find the most recent upstream commit that was successfully migrated by searching for the UPSTREAM_COMMIT= tag in the commit descriptions of the pub/main branch.

    # Update repositories
    git fetch pub && git fetch spec-pub
    
    # Sync main branch
    git checkout main && git merge --ff-only pub/main
    
    # Initialize submodule
    git submodule update
    
    # Find the last migrated upstream commit
    git log --grep 'UPSTREAM_COMMIT=' pub/main
    # Note the hash following 'UPSTREAM_COMMIT=' (e.g., 9a0565a8cba336a6dabbf10cc58ccbf665bfe023)
    export LATEST_UPSTREAMED_COMMIT=<hash>
  4. Install and configure the rebase tool (trt)

    main

    The rebasing process uses a custom tool located in the tools directory. You need to install its dependencies and it is highly recommended to set up a terminal alias named trt to simplify usage.

    # Install dependencies
    cd tools && npm ci && cd ..
    
    # Verify installation (should print help)
    npx ts-node tools/rebase-upstream-commits.ts
    
    # Set up the 'trt' alias
    alias trt="$(npx ts-node tools/rebase-upstream-commits.ts realcmd)"
  5. Rebase upstream commits using trt

    main

    To rebase a range of commits from the spec repository into the polyfill, follow these steps:

    1. Identify target commits: List outstanding commits using git log $LATEST_UPSTREAMED_COMMIT..spec-pub/main --oneline -- ./polyfill/. Pick a TARGET_UPSTREAM_COMMIT hash.
    2. Create a test script: (Optional but recommended) Create a script (e.g., test.sh) to run builds, linting, and tests between commits.
    3. Run the rebase: Use the trt command with the --exec flag to automate testing after each change.
    4. Handle conflicts: If conflicts occur, resolve them manually. Once resolved, always use trt continue to resume the rebase rather than standard git commands.

    Useful trt commands during rebase:

    • trt showupstream: Shows the full upstream change (files and description).
    • trt basediff: Shows only the file diffs from the upstream change (useful for large files like ecmascript.mjs).
    • trt finish: Stops the rebase at the current state (useful for splitting a large rebase into multiple PRs).
    • trt abort: Aborts the rebase and throws away work.
    # 1. Identify target
    export TARGET_UPSTREAM_COMMIT=<hash>
    
    # 2. Start rebase with automated testing
    trt $LATEST_UPSTREAMED_COMMIT $TARGET_UPSTREAM_COMMIT --onto pub/main --exec=./test.sh
    
    # 3. If you need to stop and save progress
    trt finish
    git checkout -b <new-branch-name>
  6. Configure git remotes for rebasing from upstream

    main

    To rebase changes from the official Temporal specification into your local polyfill repository, you must configure two specific remotes: pub (the polyfill repository) and spec-pub (the upstream TC39 proposal repository).

    Note that pub refers to the js-temporal/temporal-polyfill repository, while spec-pub refers to the tc39/proposal-temporal repository. These are distinct from your personal fork's remote.

    # Add the polyfill repository as the 'pub' remote
    git remote add pub git@github.com:js-temporal/temporal-polyfill.git
    
    # Add the upstream TC39 proposal repository as the 'spec-pub' remote
    git remote add spec-pub https://github.com/tc39/proposal-temporal.git
  7. Configure overflow behavior for assignments and arithmetic

    main

    When using methods like with(), from(), add(), or subtract(), you can control how out-of-range values are handled using the overflow option.

    • 'constrain' (default): Clamps the value to the nearest in-range value.
    • 'reject': Throws a RangeError if the value is out of range.
    • For Duration arithmetic, 'balance' is also an option that resolves out-of-range values by balancing them with the next highest unit.
  8. Configure disambiguation for time zone transitions

    main

    When converting PlainDateTime to Instant (via toZonedDateTime), you can specify how to handle ambiguous or non-existent times caused by Daylight Saving Time (DST) transitions using the disambiguation option:

    • 'compatible' (default): Matches legacy Date behavior (e.g., 'earlier' for Spring forward, 'later' for Fall back).
    • 'earlier': Returns the earlier of the two possible times.
    • 'later': Returns the later of the two possible times.
    • 'reject': Throws a RangeError.
  9. Manage Test262 failures during rebase

    main

    If a rebased commit fixes a Test262 test, npm run test262 will fail because the test is still listed in the expected-failure files. To fix this, run the following command to automatically update the expected-failure files:

    npm run test262 -- --update-expected-failure-files

    Warning: Do not include this command in your automated --exec rebase script, as it might accidentally clean up tests that are intended to fail.

    npm run test262 -- --update-expected-failure-files