fix: deserialize protobuf longs as numbers (#844) - #845
fix: deserialize protobuf longs as numbers (#844)#845Tsuyoshi Ushio (TsuyoshiUshio) wants to merge 2 commits into
Conversation
Fixes #844 Co-authored-by: Dobby <dobby@microsoft.com>
| objects: true, | ||
| defaults: true, | ||
| oneofs: true, | ||
| longs: Number, |
There was a problem hiding this comment.
longs: Number is the correct backward-compatible fix, but we should explicitly define all supported proto-loader options instead of relying on defaults.
The protobufjs update made Long available to webpack, changing decoded values from numbers to { low, high, unsigned } objects.
Add wire-level tests for TypedData.int, CollectionSInt64, shared-memory offsets/counts, and timestamps.
Run these tests against the production webpack bundle, since bundling caused the regression.
Document that values above Number.MAX_SAFE_INTEGER require a future string or BigInt contract.
const rpcLoaderOptions: grpcloader.Options = {
keepCase: false,
longs: Number,
defaults: true,
arrays: true,
objects: true,
oneofs: true,
json: false,
};
const packageDef = grpcloader.fromJSON(
jsonModule as protobuf.INamespace,
rpcLoaderOptions
);```
Follow-up compatibility audit: protobufjs 7.5.6 to 7.6.0I reviewed the published package diff and the relevant transitive dependency changes to check for other breaking behavior beyond #844. Findings
Production descriptor comparisonI loaded the same generated Functions RPC descriptor in isolated environments pinned to protobufjs 7.5.6 and 7.6.0, using the production proto-loader options, and compared:
The normalized results were identical: both were 8,048 bytes with SHA-256 Conclusion and follow-upI did not find another protobufjs 7.6.0 change that breaks the current Node.js worker contract. The Long default was the material regression, and this PR fixes it at the correct boundary by making the expected representation explicit. For future updates, I recommend risk-based compatibility comparison rather than exhaustive comparison for every minor dependency update. Dependencies affecting wire formats, serialization, generated descriptors, public value shapes, or bundling should be compared before and after using the same production inputs and bundle configuration. I opened #846 to track that policy, a dependency-update checklist, future |
Summary
Explicitly decode protobuf 64-bit integer fields as JavaScript numbers so Worker bundle dependency resolution cannot change the public trigger metadata shape.
Issue
Fixes #844
Changes
longs: Numberin the worker's@grpc/proto-loaderoptions.TypedData.intandCollectionSInt64trigger metadata.GrpcClientpath.Breaking Changes
None. This restores the established JavaScript
numberbehavior from Worker 3.14.1 and earlier.Testing
intdecoded to{ low, high, unsigned }.GrpcClienttests pass, 6 passing.npm run build: pass.npm test: pass, 150 passing and 8 pending.npm run lint: pass; existing TypeScript parser compatibility warning only.npm run webpack: pass; production worker bundle compiled successfully.npm audit --audit-level=high: reports the existing dependency baseline (4 high, 1 moderate, 1 low); this PR does not modify dependency manifests or the lockfile.Self-Review
src/GrpcClient.tsandtest/GrpcClient.test.tsare changed.