Skip to content
Open
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
16 changes: 15 additions & 1 deletion packages/typescript-client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,19 @@ export type NormalizedPgSnapshot = {
}

interface Header {
[key: Exclude<string, `operation` | `control` | `event`>]: Value
[
key: Exclude<
string,
| `operation`
| `control`
| `event`
| `txids`
| `lsn`
| `op_position`
| `tags`
| `removed_tags`
>
]: Value
}

export type Operation = `insert` | `update` | `delete`
Expand Down Expand Up @@ -125,6 +137,8 @@ export type ChangeMessage<T extends Row<unknown> = Row> = {
headers: Header & {
operation: Operation
txids?: number[]
lsn?: `${bigint}`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went with bigint given this is used for xip_list in the PostgresSnapshot

But then txids above is a number so not sure which is better 🤷

op_position?: number
Comment on lines 139 to +141
Copy link

@coderabbitai coderabbitai bot Jan 18, 2026

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Verify op_position won’t exceed JS safe integer.
If op_position can be 64‑bit (e.g., WAL positions), number risks precision loss. Please confirm the range; if it can exceed 2^53‑1, prefer a string/${bigint} type.

✅ Suggested change if 64‑bit values are possible
-    op_position?: number
+    op_position?: `${bigint}`
📝 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
txids?: number[]
lsn?: `${bigint}`
op_position?: number
txids?: number[]
lsn?: `${bigint}`
op_position?: `${bigint}`
🤖 Prompt for AI Agents
In `@packages/typescript-client/src/types.ts` around lines 139 - 141, Confirm
whether the field op_position (in packages/typescript-client/src/types.ts) can
exceed JavaScript's safe integer (2^53-1); if it can, change its TypeScript type
from number to either string or a template literal type like `${bigint}` and
update any related parse/serialize logic that reads/writes op_position (e.g.,
functions that construct or consume the containing interface) to
stringify/BigInt-handle values consistently; if it cannot exceed the safe
integer, add a comment/documentation on op_position explaining the guaranteed
range to prevent future regressions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a number in the api

Does seem a bit strange to me how sometimes we have number and sometimes string

Copy link

Choose a reason for hiding this comment

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

@tjenkinson Thanks for clarifying! If the API sends op_position as a JSON number, then number is the correct TypeScript type here.

You're right that the mix is a bit unusual—lsn as a string makes sense since LSNs (Log Sequence Numbers) in Postgres are 64-bit and can exceed JavaScript's safe integer limit (2^53-1). If op_position represents a position within a single transaction or batch and stays well within safe integer bounds, then keeping it as number is fine and matches the API contract.

The types look good as-is! 👍


🧠 Learnings used
Learnt from: CR
Repo: electric-sql/electric PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-14T14:45:05.838Z
Learning: Applies to **/{api,server,routes,db}/**/*.{ts,tsx} : Backend API endpoints must return Postgres txid (via `SELECT pg_current_xact_id()::xid::text as txid`) as an integer for client-side synchronization

/** Tags will always be present for changes if the shape has a subquery in its where clause, and are omitted otherwise.*/
tags?: MoveTag[]
removed_tags?: MoveTag[]
Expand Down
4 changes: 2 additions & 2 deletions website/electric-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ paths:
value:
- headers:
operation: insert
lsn: 1234
lsn: '1234'
op_position: 0
key: issue-1
value:
Expand All @@ -697,7 +697,7 @@ paths:
status: backlog
- headers:
operation: insert
lsn: 1234
lsn: '1234'
op_position: 7
key: issue-2
value:
Expand Down