Skip to content

Commit 40074bb

Browse files
committed
New: Added an asJSON-option to always populate array fields, even if defaults=false, see #597
1 parent 961dd03 commit 40074bb

17 files changed

+102
-73
lines changed

README.md

+27-28
Original file line numberDiff line numberDiff line change
@@ -237,25 +237,16 @@ There is also an [example for streaming RPC](https://github.com/dcodeIO/protobuf
237237

238238
### Usage with TypeScript
239239

240-
Under node.js:
241-
242240
```ts
243241
import * as protobuf from "protobufjs";
242+
import * as Long from "long"; // optional
244243
...
245244
```
246245

247-
In the browser:
248-
249-
```ts
250-
/// <reference path="path/to/protobuf/index.d.ts" />
251-
import * as protobuf from "path/to/protobuf.js";
252-
...
253-
```
254-
255-
If you need long support, there is also a [TypeScript definition](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types-2.0/long/index.d.ts) for that (on npm: [@types/long](https://www.npmjs.com/package/@types/long)).
256-
257246
See also: [Generating your own TypeScript definitions](https://github.com/dcodeIO/protobuf.js#generating-typescript-definitions-from-static-modules)
258247

248+
Additional configuration might be necessary when not utilizing node, i.e. reference [protobuf.js.d.ts](https://github.com/dcodeIO/protobuf.js/blob/master/index.d.ts) and [long.js.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types-2.0/long/index.d.ts).
249+
259250
Module Structure
260251
----------------
261252
The library exports a flat `protobuf` namespace including but not restricted to the following members, ordered by category:
@@ -483,37 +474,45 @@ The package includes a benchmark that tries to compare performance to native JSO
483474
```
484475
benchmarking encoding performance ...
485476
486-
Type.encode to buffer x 521,803 ops/sec ±0.84% (88 runs sampled)
487-
JSON.stringify to string x 300,362 ops/sec ±1.11% (86 runs sampled)
488-
JSON.stringify to buffer x 169,413 ops/sec ±1.49% (86 runs sampled)
477+
Type.encode to buffer x 553,499 ops/sec ±0.33% (91 runs sampled)
478+
JSON.stringify to string x 313,354 ops/sec ±0.84% (89 runs sampled)
479+
JSON.stringify to buffer x 177,932 ops/sec ±0.78% (88 runs sampled)
489480
490481
Type.encode to buffer was fastest
491-
JSON.stringify to string was 42.6% slower
492-
JSON.stringify to buffer was 67.7% slower
482+
JSON.stringify to string was 43.7% slower
483+
JSON.stringify to buffer was 68.0% slower
493484
494485
benchmarking decoding performance ...
495486
496-
Type.decode from buffer x 1,325,308 ops/sec ±1.46% (88 runs sampled)
497-
JSON.parse from string x 283,907 ops/sec ±1.39% (86 runs sampled)
498-
JSON.parse from buffer x 255,372 ops/sec ±1.28% (88 runs sampled)
487+
Type.decode from buffer x 1,352,868 ops/sec ±0.66% (89 runs sampled)
488+
JSON.parse from string x 293,883 ops/sec ±0.55% (92 runs sampled)
489+
JSON.parse from buffer x 267,287 ops/sec ±0.83% (91 runs sampled)
499490
500491
Type.decode from buffer was fastest
501-
JSON.parse from string was 78.6% slower
502-
JSON.parse from buffer was 80.7% slower
492+
JSON.parse from string was 78.3% slower
493+
JSON.parse from buffer was 80.3% slower
503494
504495
benchmarking combined performance ...
505496
506-
Type to/from buffer x 269,719 ops/sec ±0.87% (91 runs sampled)
507-
JSON to/from string x 122,878 ops/sec ±1.59% (87 runs sampled)
508-
JSON to/from buffer x 89,310 ops/sec ±1.01% (88 runs sampled)
497+
Type to/from buffer x 267,534 ops/sec ±0.88% (91 runs sampled)
498+
JSON to/from string x 129,143 ops/sec ±0.66% (92 runs sampled)
499+
JSON to/from buffer x 91,789 ops/sec ±0.73% (87 runs sampled)
509500
510501
Type to/from buffer was fastest
511-
JSON to/from string was 54.8% slower
512-
JSON to/from buffer was 66.9% slower
502+
JSON to/from string was 51.6% slower
503+
JSON to/from buffer was 65.6% slower
513504
514505
benchmarking verifying performance ...
515506
516-
Type.verify x 5,857,856 ops/sec ±0.82% (91 runs sampled)
507+
Type.verify x 6,431,917 ops/sec ±0.49% (91 runs sampled)
508+
509+
benchmarking converting performance ...
510+
511+
Message.from x 629,785 ops/sec ±0.62% (94 runs sampled)
512+
Message#asJSON x 609,017 ops/sec ±0.74% (93 runs sampled)
513+
514+
Message.from was fastest
515+
Message#asJSON was 3.4% slower
517516
```
518517

519518
Note that JSON is a native binding nowadays and as such is about as fast as it possibly can get. So, how can protobuf.js be faster?

dist/noparse/protobuf.js

+18-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/noparse/protobuf.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/noparse/protobuf.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/noparse/protobuf.min.js.gz

66 Bytes
Binary file not shown.

dist/noparse/protobuf.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/protobuf.js

+18-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/protobuf.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/protobuf.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/protobuf.min.js.gz

55 Bytes
Binary file not shown.

dist/protobuf.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/runtime/protobuf.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/runtime/protobuf.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/runtime/protobuf.min.js.gz

0 Bytes
Binary file not shown.

index.d.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// $> pbts --name protobuf --out index.d.ts src
2-
// Generated Fri, 30 Dec 2016 15:32:08 UTC
2+
// Generated Fri, 30 Dec 2016 16:29:57 UTC
33

44
export = protobuf;
55
export as namespace protobuf;
@@ -122,24 +122,26 @@ declare namespace protobuf {
122122
* JSON conversion options as used by {@link Message#asJSON} with {@link convert}.
123123
* @typedef JSONConversionOptions
124124
* @type {Object}
125-
* @property {boolean} [fieldsOnly=false] Keeps only properties that reference a field
125+
* @property {boolean} [fieldsOnly=false] If `true`, keeps only properties that reference a field.
126126
* @property {*} [longs] Long conversion type. Only relevant with a long library.
127127
* Valid values are `String` and `Number` (the global types).
128128
* Defaults to a possibly unsafe number without, and a `Long` with a long library.
129129
* @property {*} [enums=Number] Enum value conversion type.
130130
* Valid values are `String` and `Number` (the global types).
131-
* Defaults to the numeric ids.
131+
* Defaults to `Number`, which sets the numeric ids.
132132
* @property {*} [bytes] Bytes value conversion type.
133133
* Valid values are `Array` and `String` (the global types).
134-
* Defaults to return the underlying buffer type.
135-
* @property {boolean} [defaults=false] Also sets default values on the resulting object
134+
* Defaults to return the underlying buffer type, which usually is an `Uint8Array` in the browser and a `Buffer` under node.
135+
* @property {boolean} [defaults=false] If `true`, sets default values on the resulting object including empty arrays for repeated fields
136+
* @property {boolean} [arrays=false] If `true`, always initializes empty arrays for repeated fields. Only relevant with `defaults=false`.
136137
*/
137138
interface JSONConversionOptions {
138139
fieldsOnly?: boolean;
139140
longs?: any;
140141
enums?: any;
141142
bytes?: any;
142143
defaults?: boolean;
144+
arrays?: boolean;
143145
}
144146

145147
/**

src/convert.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function convert(type, source, destination, options, converter) {
4444
value = source[key];
4545
if (field) {
4646
if (field.repeated) {
47-
if (value || options.defaults) {
47+
if (value || options.defaults || options.arrays) {
4848
destination[key] = [];
4949
if (value)
5050
for (var j = 0, l = value.length; j < l; ++j)
@@ -62,17 +62,18 @@ function convert(type, source, destination, options, converter) {
6262
* JSON conversion options as used by {@link Message#asJSON} with {@link convert}.
6363
* @typedef JSONConversionOptions
6464
* @type {Object}
65-
* @property {boolean} [fieldsOnly=false] Keeps only properties that reference a field
65+
* @property {boolean} [fieldsOnly=false] If `true`, keeps only properties that reference a field.
6666
* @property {*} [longs] Long conversion type. Only relevant with a long library.
6767
* Valid values are `String` and `Number` (the global types).
6868
* Defaults to a possibly unsafe number without, and a `Long` with a long library.
6969
* @property {*} [enums=Number] Enum value conversion type.
7070
* Valid values are `String` and `Number` (the global types).
71-
* Defaults to the numeric ids.
71+
* Defaults to `Number`, which sets the numeric ids.
7272
* @property {*} [bytes] Bytes value conversion type.
7373
* Valid values are `Array` and `String` (the global types).
74-
* Defaults to return the underlying buffer type.
75-
* @property {boolean} [defaults=false] Also sets default values on the resulting object
74+
* Defaults to return the underlying buffer type, which usually is an `Uint8Array` in the browser and a `Buffer` under node.
75+
* @property {boolean} [defaults=false] If `true`, sets default values on the resulting object including empty arrays for repeated fields
76+
* @property {boolean} [arrays=false] If `true`, always initializes empty arrays for repeated fields. Only relevant with `defaults=false`.
7677
*/
7778
/**/
7879
convert.toJson = function toJson(field, value, options) {

tests/typescript.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import * as protobuf from "..";
2+
import * as Long from "long";
23

34
export const proto = {
45
nested: {
56
Hello: {
67
fields: {
7-
value: {
8+
aString: {
89
rule: "required",
910
type: "string",
10-
id:1
11+
id: 1
12+
},
13+
aLong: {
14+
type: "uint64",
15+
id: 2
1116
}
1217
}
1318
}
@@ -20,17 +25,15 @@ export class Hello extends protobuf.Message {
2025
constructor (properties?: { [k: string]: any }) {
2126
super(properties);
2227
}
23-
24-
foo() {
25-
this["value"] = "hi";
26-
return this;
27-
}
2828
}
29-
protobuf.Class.create(root.lookup("Hello") as protobuf.Type, Hello);
29+
protobuf.Class.create(root.lookupType("Hello"), Hello);
3030

31-
var hello = new Hello();
31+
var hello = new Hello({
32+
aString: "hi",
33+
aLong: Long.fromNumber(123)
34+
});
3235

33-
var buf = Hello.encode(hello.foo()).finish();
36+
var buf = Hello.encode(hello).finish();
3437

3538
var hello2 = Hello.decode(buf) as Hello;
36-
console.log(hello2.foo().asJSON());
39+
console.log(hello2.asJSON());

0 commit comments

Comments
 (0)