Skip to content

fix(compute): load a Temporal polyfill in the database templates - #8631

Merged
gregory-boch-prisma merged 2 commits into
latestfrom
greg/compute-temporal-polyfill
Oct 16, 2026
Merged

gregory-boch-prisma merged 2 commits into
latestfrom
greg/compute-temporal-polyfill

Conversation

@gregory-boch-prisma

@gregory-boch-prisma gregory-boch-prisma commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Loads temporal-polyfill/global in src/prisma/db.ts of the three database templates (compute/hono, compute/nextjs, compute/tanstack-start), so db:seed and the routes work once the database has rows. compute/personal-site has no database and is not touched.

Why

createdAt and updatedAt use the pg/timestamptz-temporal@1 codec (src/prisma/contract.json), which reads and writes Temporal.Instant values through the global Temporal. Node.js 22 and Bun 1.3.14 have none: typeof globalThis.Temporal is undefined on Node.js 22.23.3 and Bun 1.3.14. test.yaml runs Node.js 22.22.1 and Bun 1.3.14, and each template's prisma-deploy.yml sets Node.js 22.23.2.

On latest, with the templates' own pins (@prisma/orm-postgres 8.0.0-rc.8):

  • bun run db:seed exits 1 with RUNTIME.TEMPORAL_UNAVAILABLE: "Mutation default generator 'instantNow' cannot produce a value because this runtime has no global Temporal implementation."
  • Once the database has a row, GET /api/users returns 500 in all three templates, and so does GET / in hono and tanstack-start. The server log shows RUNTIME.TEMPORAL_UNAVAILABLE. With an empty database the pages render.

The ORM docs give this fix for Node.js 22: import the polyfill "before the first query (add temporal-polyfill as a dependency)".

Changes

File Change Source
compute/{hono,nextjs,tanstack-start}/package.json, bun.lock Adds temporal-polyfill 1.0.5, pinned exactly like the other dependencies. The lockfiles gain temporal-polyfill, temporal-spec 1.0.1 and temporal-utils 1.0.3 npm view temporal-polyfill: latest is 1.0.5, published 2026-09-11. Lockfile hashes match npm view <package>@<version> dist.integrity. @prisma/orm-postgres@8.0.0-rc.17 declares the peer range ^1.0.4
compute/{hono,nextjs,tanstack-start}/src/prisma/db.ts import 'temporal-polyfill/global' after dotenv/config, before the ORM runtime import. Every route and seed.ts reach the database through this module temporal-polyfill 1.0.5 README: the global entry point "uses native if available", so it changes nothing on a runtime that has Temporal. /global covers the ISO 8601 and Gregorian calendars, which is all Temporal.Instant needs; the ORM docs' /full/global adds other calendar systems
compute/tanstack-start/src/routes/index.tsx user.createdAt.toISOString() becomes user.createdAt.toString() createdAt is a Temporal.Instant, which has toString() and toJSON() but no toISOString() (MDN). With the polyfill and toISOString(), GET / still returns 500. toString() returns an ISO 8601 UTC string such as 2026-10-13T13:24:06.322Z

With #8629

This PR is based on latest, and either PR can merge first. Whichever lands second gets a one-line conflict in each of the three bun.lock files, at the terminal-size entry: #8629 drops that package, and this PR adds the temporal-* entries just above it. #8629's lockfiles already hold temporal-polyfill 1.0.5, temporal-spec 1.0.1 and temporal-utils 1.0.3 as peers of the ORM, and the workspace entry "temporal-polyfill": "1.0.5" merges without a conflict. Take #8629's side of the conflict (drop terminal-size); bun install --frozen-lockfile then passes in all three templates. Don't add the workspace line again, or the key is duplicated. The other files merge cleanly.

On latest, db:seed still fails after this PR, with ORM.COLUMN_UNKNOWN (Unknown column "posts" in table "user"): @prisma/orm-postgres 8.0.0-rc.8 rejects the nested posts in upsert({ create }). #8629 rewrites seed.ts with create(). On #8629's branch without this PR, db:seed exits 1 with RUNTIME.TEMPORAL_UNAVAILABLE (checked in tanstack-start). With both, it passes.

Verification

Local, Node.js 22.23.3 and Bun 1.3.14.

This branch:

  • npx vitest run tests/compute.test.ts: 1 test passed. Bundles answered HTTP 500 (hono: ECONNREFUSED on the placeholder DATABASE_URL), 200 (nextjs), 500 (tanstack-start: jsxDEV is not a function under vitest's NODE_ENV=test, as described in fix(compute): move Composer's config into the composer section of prisma.config.ts #8629), 200 (personal-site). No RUNTIME. code in the log.
  • bun install --frozen-lockfile, bun run build and tsc --noEmit pass in hono, nextjs and tanstack-start. The polyfill ends up in each build: in .output/server/_libs (tanstack-start), in the server chunk (nextjs), and as an import of the temporal-polyfill dependency in dist/prisma/db.js (hono).
  • Against a local Prisma Postgres from @prisma/dev (the repo's test dependency), after bun run db:init: a script that calls getDb() to create a user and a post and read them back fails on latest with RUNTIME.TEMPORAL_UNAVAILABLE and passes on this branch in each template; createdAt comes back as a Temporal.Instant. Then each template's start command with DATABASE_URL set, with those rows in the database:
Template latest: GET / latest: GET /api/users This branch: GET / This branch: GET /api/users
hono 500 500 200, lists the users 200, users and posts
nextjs 200 (static page) 500 200 200, users and posts
tanstack-start 500 500 200, lists the users 200, users and posts

bunx prisma dev module.ts with the latest pins (prisma 8.0.0-rc.12, Composer 0.16.0) brought the stack up, but its service did not answer requests here, even with an empty database. So the Composer path was checked on top of #8629.

On top of #8629 (a local merge of this branch into 88ed884, lockfiles resolved as above, not pushed):

  • npx vitest run tests/compute.test.ts: 1 test passed, same bundle statuses as above.
  • In each database template, bun run build, then bunx prisma dev module.ts. The service receives only COMPOSER_WEB_PORT, COMPOSER_WEB_ORIGIN and COMPOSER_WEB_DB_URL, so db.ts takes the service.load() path. Empty database: GET / 200 and GET /api/users []. Then bun run db:seed twice; both runs exit 0. Then GET / 200 (hono's page lists Marie and Alice with 1 post each) and GET /api/users 200 with both users and their posts.

Sources

Checked 2026-10-13.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Timestamp values are now supported across the Hono, Next.js, and TanStack Start apps in Node.js 22.
    • TanStack Start now serializes user creation timestamps as strings, providing consistent timestamp values when displaying or transferring them.

The hono, nextjs and tanstack-start templates store createdAt and
updatedAt with the pg/timestamptz-temporal@1 codec, which needs a global
Temporal. Node.js 22 and Bun 1.3.14 have none, so db:seed and any query
that reads a row failed with RUNTIME.TEMPORAL_UNAVAILABLE.

Load temporal-polyfill/global in src/prisma/db.ts and pin
temporal-polyfill 1.0.5. tanstack-start's index route called
toISOString() on createdAt, which is a Temporal.Instant; use toString().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: prisma/prisma-examples/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 5dd386ae-d264-44fb-89f9-357cfbd7cc1e
📥 Commits

Reviewing files that changed from the base of the PR and between 0a97ed4 and de0821e.

⛔ Files ignored due to path filters: 3
  • compute/hono/bun.lock is excluded by !**/*.lock
  • compute/nextjs/bun.lock is excluded by !**/*.lock
  • compute/tanstack-start/bun.lock is excluded by !**/*.lock
📒 Files selected for processing: 7
  • compute/hono/package.json
  • compute/hono/src/prisma/db.ts
  • compute/nextjs/package.json
  • compute/nextjs/src/prisma/db.ts
  • compute/tanstack-start/package.json
  • compute/tanstack-start/src/prisma/db.ts
  • compute/tanstack-start/src/routes/index.tsx

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Walkthrough

The Hono, Next.js, and TanStack Start examples add temporal-polyfill and import its global implementation in their Prisma database modules. The TanStack Start route changes createdAt serialization from toISOString() to toString().

Changes

Temporal support in compute examples

Layer / File(s) Summary
Add global Temporal support
compute/hono/package.json, compute/hono/src/prisma/db.ts, compute/nextjs/package.json, compute/nextjs/src/prisma/db.ts, compute/tanstack-start/package.json, compute/tanstack-start/src/prisma/db.ts
Each example adds temporal-polyfill and imports its global implementation in the Prisma database module.
Serialize TanStack Start timestamps
compute/tanstack-start/src/routes/index.tsx
The route serializes createdAt with toString() instead of toISOString().

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to de082

The templates now provide Temporal support for database timestamps, and TanStack Start sends its timestamp as a string. No concrete user-facing or build/runtime regression is established, so the PR appears ready to merge subject to normal checks.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the primary change: loading a Temporal polyfill in the compute database templates.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4…
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.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 4 files. (3 skipped: 3 unsupported.)

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Resolve the bun.lock conflicts in the hono, nextjs and tanstack-start
templates: keep the temporal-polyfill entries and drop terminal-size,
which latest no longer depends on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gregory-boch-prisma

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gregory-boch-prisma

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@gregory-boch-prisma

Copy link
Copy Markdown
Contributor Author

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

@gregory-boch-prisma
gregory-boch-prisma merged commit 51b3202 into latest Oct 16, 2026
9 of 10 checks passed
@gregory-boch-prisma
gregory-boch-prisma deleted the greg/compute-temporal-polyfill branch October 16, 2026 11:32
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