diff --git a/packages/bundle-size/README.md b/packages/bundle-size/README.md index 819170e1b..5d4099fbb 100644 --- a/packages/bundle-size/README.md +++ b/packages/bundle-size/README.md @@ -15,11 +15,11 @@ usually do. We repeat this for an increasing number of files. | code generator | files | bundle size | minified | compressed | |-----------------|----------|------------------------:|-----------------------:|-------------------:| -| protobuf-es | 1 | 79,466 b | 34,303 b | 9,800 b | -| protobuf-es | 4 | 92,563 b | 37,277 b | 10,113 b | -| protobuf-es | 8 | 101,904 b | 41,775 b | 10,824 b | -| protobuf-es | 16 | 165,584 b | 67,020 b | 13,312 b | -| protobuf-es | 32 | 344,962 b | 147,972 b | 20,177 b | +| protobuf-es | 1 | 79,463 b | 34,300 b | 9,781 b | +| protobuf-es | 4 | 92,560 b | 37,274 b | 10,114 b | +| protobuf-es | 8 | 101,901 b | 41,772 b | 10,808 b | +| protobuf-es | 16 | 165,581 b | 67,017 b | 13,320 b | +| protobuf-es | 32 | 344,959 b | 147,969 b | 20,175 b | | protobuf-javascript | 1 | 339,613 b | 255,820 b | 42,481 b | | protobuf-javascript | 4 | 366,281 b | 271,092 b | 43,912 b | | protobuf-javascript | 8 | 388,324 b | 283,409 b | 45,038 b | diff --git a/packages/bundle-size/chart.svg b/packages/bundle-size/chart.svg index 57e6de001..e38dc5bbf 100644 --- a/packages/bundle-size/chart.svg +++ b/packages/bundle-size/chart.svg @@ -43,14 +43,14 @@ 0 KiB - + protobuf-es -protobuf-es 9.57 KiB for 1 files -protobuf-es 9.88 KiB for 4 files -protobuf-es 10.57 KiB for 8 files -protobuf-es 13 KiB for 16 files -protobuf-es 19.7 KiB for 32 files +protobuf-es 9.55 KiB for 1 files +protobuf-es 9.88 KiB for 4 files +protobuf-es 10.55 KiB for 8 files +protobuf-es 13.01 KiB for 16 files +protobuf-es 19.7 KiB for 32 files diff --git a/packages/protobuf-test/src/constructor.test.ts b/packages/protobuf-test/src/constructor.test.ts index 6db23360a..e241e6092 100644 --- a/packages/protobuf-test/src/constructor.test.ts +++ b/packages/protobuf-test/src/constructor.test.ts @@ -21,6 +21,8 @@ import { TestAllTypesProto3 as JS_TestAllTypesProto3 } from "./gen/js/google/pro import { JSTypeStringMessage as TS_JSTypeStringMessage } from "./gen/ts/extra/jstype_pb.js"; import { JSTypeStringMessage as JS_JSTypeStringMessage } from "./gen/js/extra/jstype_pb.js"; import { testMT } from "./helpers.js"; +import { Proto3OptionalMessage as TS_Proto3OptionalMessage } from "./gen/ts/extra/proto3_pb.js"; +import { Proto3OptionalMessage as JS_Proto3OptionalMessage } from "./gen/js/extra/proto3_pb.js"; describe("constructor initializes jstype=JS_STRING with string", function () { testMT( @@ -179,3 +181,47 @@ describe("constructor takes partial message for map value", function () { }, ); }); + +describe("constructor skips undefined values", () => { + testMT( + { ts: TS_Proto3OptionalMessage, js: JS_Proto3OptionalMessage }, + (messageType) => { + const m = new messageType({ + stringField: undefined, + }); + expect(m.stringField).toBeUndefined(); + }, + ); + testMT( + { ts: TS_TestAllTypesProto3, js: JS_TestAllTypesProto3 }, + (messageType) => { + const m = new messageType({ + optionalInt32: undefined, + }); + expect(m.optionalInt32).toBe(0); + }, + ); +}); + +describe("constructor skips null values", () => { + testMT( + { ts: TS_Proto3OptionalMessage, js: JS_Proto3OptionalMessage }, + (messageType) => { + const m = new messageType({ + // @ts-expect-error TS 2322 + stringField: null, + }); + expect(m.stringField).toBeUndefined(); + }, + ); + testMT( + { ts: TS_TestAllTypesProto3, js: JS_TestAllTypesProto3 }, + (messageType) => { + const m = new messageType({ + // @ts-expect-error TS 2322 + optionalInt32: null, + }); + expect(m.optionalInt32).toBe(0); + }, + ); +}); diff --git a/packages/protobuf/src/private/util-common.ts b/packages/protobuf/src/private/util-common.ts index 42f4e6340..c03bc5d00 100644 --- a/packages/protobuf/src/private/util-common.ts +++ b/packages/protobuf/src/private/util-common.ts @@ -38,7 +38,7 @@ export function makeUtilCommon(): Omit { const localName = member.localName, t = target as AnyMessage, s = source as PartialMessage; - if (s[localName] === undefined) { + if (s[localName] == null) { // TODO if source is a Message instance, we should use isFieldSet() here to support future field presence continue; }