basant307/AI_Governance_Project
045
1<h1><p align="center"><img alt="protobuf.js" src="https://github.com/protobufjs/protobuf.js/raw/master/pbjs.svg" height="100" /><br/>protobuf.js</p></h1>2<p align="center">3 <a href="https://github.com/protobufjs/protobuf.js/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/protobufjs/protobuf.js/test.yml?branch=master&label=build&logo=github" alt=""></a>4 <a href="https://github.com/protobufjs/protobuf.js/actions/workflows/release.yaml"><img src="https://img.shields.io/github/actions/workflow/status/protobufjs/protobuf.js/release.yaml?branch=master&label=release&logo=github" alt=""></a>5 <a href="https://npmjs.org/package/protobufjs"><img src="https://img.shields.io/npm/v/protobufjs.svg?logo=npm" alt=""></a>6 <a href="https://npmjs.org/package/protobufjs"><img src="https://img.shields.io/npm/dm/protobufjs.svg?label=downloads&logo=npm" alt=""></a>7 <a href="https://www.jsdelivr.com/package/npm/protobufjs"><img src="https://img.shields.io/jsdelivr/npm/hm/protobufjs?label=requests&logo=jsdelivr" alt=""></a>8</p>9 10**Protocol Buffers** are a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols, data storage, and more, originally designed at Google ([see](https://protobuf.dev/)).11 12**protobuf.js** is a pure JavaScript implementation with [TypeScript](https://www.typescriptlang.org) support for [Node.js](https://nodejs.org) and the browser. It's easy to use, does not sacrifice on performance, has good conformance and works out of the box with [.proto](https://protobuf.dev/programming-guides/proto3/) files!13 14Contents15--------16 17* [Installation](#installation)<br />18 How to include protobuf.js in your project.19 20* [Usage](#usage)<br />21 A brief introduction to using the toolset.22 23 * [Valid Message](#valid-message)24 * [Toolset](#toolset)<br />25 26* [Examples](#examples)<br />27 A few examples to get you started.28 29 * [Using .proto files](#using-proto-files)30 * [Using JSON descriptors](#using-json-descriptors)31 * [Using reflection only](#using-reflection-only)32 * [Using custom classes](#using-custom-classes)33 * [Using services](#using-services)34 * [Usage with TypeScript](#usage-with-typescript)<br />35 36* [Additional documentation](#additional-documentation)<br />37 A list of available documentation resources.38 39* [Performance](#performance)<br />40 A few internals and a benchmark on performance.41 42* [Compatibility](#compatibility)<br />43 Notes on compatibility regarding browsers and optional libraries.44 45* [Building](#building)<br />46 How to build the library and its components yourself.47 48Installation49---------------50 51### Node.js52 53```sh54npm install protobufjs --save55```56 57```js58// Static code + Reflection + .proto parser59var protobuf = require("protobufjs");60 61// Static code + Reflection62var protobuf = require("protobufjs/light");63 64// Static code only65var protobuf = require("protobufjs/minimal");66```67 68The optional [command line utility](./cli/) to generate static code and reflection bundles lives in the `protobufjs-cli` package and can be installed separately:69 70```sh71npm install protobufjs-cli --save-dev72```73 74### Browsers75 76Pick the variant matching your needs and replace the version tag with the exact [release](https://github.com/protobufjs/protobuf.js/tags) your project depends upon. For example, to use the minified full variant:77 78```html79<script src="//cdn.jsdelivr.net/npm/protobufjs@7.X.X/dist/protobuf.min.js"></script>80```81 82| Distribution | Location83|--------------|--------------------------------------------------------84| Full | <https://cdn.jsdelivr.net/npm/protobufjs/dist/>85| Light | <https://cdn.jsdelivr.net/npm/protobufjs/dist/light/>86| Minimal | <https://cdn.jsdelivr.net/npm/protobufjs/dist/minimal/>87 88All variants support CommonJS and AMD loaders and export globally as `window.protobuf`.89 90Usage91-----92 93Because JavaScript is a dynamically typed language, protobuf.js utilizes the concept of a **valid message** in order to provide the best possible [performance](#performance) (and, as a side product, proper typings):94 95### Valid message96 97> A valid message is an object (1) not missing any required fields and (2) exclusively composed of JS types understood by the wire format writer.98 99There are two possible types of valid messages and the encoder is able to work with both of these for convenience:100 101* **Message instances** (explicit instances of message classes with default values on their prototype) naturally satisfy the requirements of a valid message and102* **Plain JavaScript objects** that just so happen to be composed in a way satisfying the requirements of a valid message as well.103 104In a nutshell, the wire format writer understands the following types:105 106| Field type | Expected JS type (create, encode) | Conversion (fromObject)107|------------|-----------------------------------|------------------------108| s-/u-/int32<br />s-/fixed32 | `number` (32 bit integer) | <code>value | 0</code> if signed<br />`value >>> 0` if unsigned109| s-/u-/int64<br />s-/fixed64 | `Long`-like (optimal)<br />`number` (53 bit integer) | `Long.fromValue(value)` with long.js<br />`parseInt(value, 10)` otherwise110| float<br />double | `number` | `Number(value)`111| bool | `boolean` | `Boolean(value)`112| string | `string` | `String(value)`113| bytes | `Uint8Array` (optimal)<br />`Buffer` (optimal under node)<br />`Array.<number>` (8 bit integers) | `base64.decode(value)` if a `string`<br />`Object` with non-zero `.length` is assumed to be buffer-like114| enum | `number` (32 bit integer) | Looks up the numeric id if a `string`115| message | Valid message | `Message.fromObject(value)`116| repeated T | `Array<T>` | Copy117| map<K, V> | `Object<K,V>` | Copy118 119* Explicit `undefined` and `null` are considered as not set if the field is optional.120* Maps are objects where the key is the string representation of the respective value or an 8 characters long hash string for `Long`-likes.121 122### Toolset123 124With that in mind and again for performance reasons, each message class provides a distinct set of methods with each method doing just one thing. This avoids unnecessary assertions / redundant operations where performance is a concern but also forces a user to perform verification (of plain JavaScript objects that *might* just so happen to be a valid message) explicitly where necessary - for example when dealing with user input.125 126**Note** that `Message` below refers to any message class.127 128* **Message.verify**(message: `Object`): `null|string`<br />129 verifies that a **plain JavaScript object** satisfies the requirements of a valid message and thus can be encoded without issues. Instead of throwing, it returns the error message as a string, if any.130 131 ```js132 var payload = "invalid (not an object)";133 var err = AwesomeMessage.verify(payload);134 if (err)135 throw Error(err);136 ```137 138* **Message.encode**(message: `Message|Object` [, writer: `Writer`]): `Writer`<br />139 encodes a **message instance** or valid **plain JavaScript object**. This method does not implicitly verify the message and it's up to the user to make sure that the payload is a valid message.140 141 ```js142 var buffer = AwesomeMessage.encode(message).finish();143 ```144 145* **Message.encodeDelimited**(message: `Message|Object` [, writer: `Writer`]): `Writer`<br />146 works like `Message.encode` but additionally prepends the length of the message as a varint.147 148* **Message.decode**(reader: `Reader|Uint8Array`): `Message`<br />149 decodes a buffer to a **message instance**. If required fields are missing, it throws a `util.ProtocolError` with an `instance` property set to the so far decoded message. If the wire format is invalid, it throws an `Error`.150 151 ```js152 try {153 var decodedMessage = AwesomeMessage.decode(buffer);154 } catch (e) {155 if (e instanceof protobuf.util.ProtocolError) {156 // e.instance holds the so far decoded message with missing required fields157 } else {158 // wire format is invalid159 }160 }161 ```162 163* **Message.decodeDelimited**(reader: `Reader|Uint8Array`): `Message`<br />164 works like `Message.decode` but additionally reads the length of the message prepended as a varint.165 166* **Message.create**(properties: `Object`): `Message`<br />167 creates a new **message instance** from a set of properties that satisfy the requirements of a valid message. Where applicable, it is recommended to prefer `Message.create` over `Message.fromObject` because it doesn't perform possibly redundant conversion.168 169 ```js170 var message = AwesomeMessage.create({ awesomeField: "AwesomeString" });171 ```172 173* **Message.fromObject**(object: `Object`): `Message`<br />174 converts any non-valid **plain JavaScript object** to a **message instance** using the conversion steps outlined within the table above.175 176 ```js177 var message = AwesomeMessage.fromObject({ awesomeField: 42 });178 // converts awesomeField to a string179 ```180 181* **Message.toObject**(message: `Message` [, options: `ConversionOptions`]): `Object`<br />182 converts a **message instance** to an arbitrary **plain JavaScript object** for interoperability with other libraries or storage. The resulting plain JavaScript object *might* still satisfy the requirements of a valid message depending on the actual conversion options specified, but most of the time it does not.183 184 ```js185 var object = AwesomeMessage.toObject(message, {186 enums: String, // enums as string names187 longs: String, // longs as strings (or BigInt for bigint values)188 bytes: String, // bytes as base64 encoded strings189 defaults: true, // includes default values190 arrays: true, // populates empty arrays (repeated fields) even if defaults=false191 objects: true, // populates empty objects (map fields) even if defaults=false192 oneofs: true // includes virtual oneof fields set to the present field's name193 });194 ```195 196For reference, the following diagram aims to display relationships between the different methods and the concept of a valid message:197 198<p align="center"><img alt="Toolset Diagram" src="https://protobufjs.github.io/protobuf.js/toolset.svg" /></p>199 200> In other words: `verify` indicates that calling `create` or `encode` directly on the plain object will [result in a valid message respectively] succeed. `fromObject`, on the other hand, does conversion from a broader range of plain objects to create valid messages. ([ref](https://github.com/protobufjs/protobuf.js/issues/748#issuecomment-291925749))201 202Examples203--------204 205### Using .proto files206 207It is possible to load existing .proto files using the full library, which parses and compiles the definitions to ready to use (reflection-based) message classes:208 209```protobuf210// awesome.proto211package awesomepackage;212syntax = "proto3";213 214message AwesomeMessage {215 string awesome_field = 1; // becomes awesomeField216}217```218 219```js220protobuf.load("awesome.proto", function(err, root) {221 if (err)222 throw err;223 224 // Obtain a message type225 var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");226 227 // Exemplary payload228 var payload = { awesomeField: "AwesomeString" };229 230 // Verify the payload if necessary (i.e. when possibly incomplete or invalid)231 var errMsg = AwesomeMessage.verify(payload);232 if (errMsg)233 throw Error(errMsg);234 235 // Create a new message236 var message = AwesomeMessage.create(payload); // or use .fromObject if conversion is necessary237 238 // Encode a message to an Uint8Array (browser) or Buffer (node)239 var buffer = AwesomeMessage.encode(message).finish();240 // ... do something with buffer241 242 // Decode an Uint8Array (browser) or Buffer (node) to a message243 var message = AwesomeMessage.decode(buffer);244 // ... do something with message245 246 // If the application uses length-delimited buffers, there is also encodeDelimited and decodeDelimited.247 248 // Maybe convert the message back to a plain object249 var object = AwesomeMessage.toObject(message, {250 longs: String,251 enums: String,252 bytes: String,253 // see ConversionOptions254 });255});256```257 258Additionally, promise syntax can be used by omitting the callback, if preferred:259 260```js261protobuf.load("awesome.proto")262 .then(function(root) {263 ...264 });265```266 267### Using JSON descriptors268 269The library utilizes JSON descriptors that are equivalent to a .proto definition. For example, the following is identical to the .proto definition seen above:270 271```json272// awesome.json273{274 "nested": {275 "awesomepackage": {276 "nested": {277 "AwesomeMessage": {278 "fields": {279 "awesomeField": {280 "type": "string",281 "id": 1282 }283 }284 }285 }286 }287 }288}289```290 291JSON descriptors closely resemble the internal reflection structure:292 293| Type (T) | Extends | Type-specific properties294|--------------------|--------------------|-------------------------295| *ReflectionObject* | | options296| *Namespace* | *ReflectionObject* | nested297| Root | *Namespace* | **nested**298| Type | *Namespace* | **fields**299| Enum | *ReflectionObject* | **values**300| Field | *ReflectionObject* | rule, **type**, **id**301| MapField | Field | **keyType**302| OneOf | *ReflectionObject* | **oneof** (array of field names)303| Service | *Namespace* | **methods**304| Method | *ReflectionObject* | type, **requestType**, **responseType**, requestStream, responseStream305 306* **Bold properties** are required. *Italic types* are abstract.307* `T.fromJSON(name, json)` creates the respective reflection object from a JSON descriptor308* `T#toJSON()` creates a JSON descriptor from the respective reflection object (its name is used as the key within the parent)309 310Exclusively using JSON descriptors instead of .proto files enables the use of just the light library (the parser isn't required in this case).311 312A JSON descriptor can either be loaded the usual way:313 314```js315protobuf.load("awesome.json", function(err, root) {316 if (err) throw err;317 318 // Continue at "Obtain a message type" above319});320```321 322Or it can be loaded inline:323 324```js325var jsonDescriptor = require("./awesome.json"); // exemplary for node326 327var root = protobuf.Root.fromJSON(jsonDescriptor);328 329// Continue at "Obtain a message type" above330```331 332### Using reflection only333 334Both the full and the light library include full reflection support. One could, for example, define the .proto definitions seen in the examples above using just reflection:335 336```js337...338var Root = protobuf.Root,339 Type = protobuf.Type,340 Field = protobuf.Field;341 342var AwesomeMessage = new Type("AwesomeMessage").add(new Field("awesomeField", 1, "string"));343 344var root = new Root().define("awesomepackage").add(AwesomeMessage);345 346// Continue at "Create a new message" above347...348```349 350Detailed information on the reflection structure is available within the [API documentation](#additional-documentation).351 352### Using custom classes353 354Message classes can also be extended with custom functionality and it is also possible to register a custom constructor with a reflected message type:355 356```js357...358 359// Define a custom constructor360function AwesomeMessage(properties) {361 // custom initialization code362 ...363}364 365// Register the custom constructor with its reflected type (*)366root.lookupType("awesomepackage.AwesomeMessage").ctor = AwesomeMessage;367 368// Define custom functionality369AwesomeMessage.customStaticMethod = function() { ... };370AwesomeMessage.prototype.customInstanceMethod = function() { ... };371 372// Continue at "Create a new message" above373```374 375(*) Besides referencing its reflected type through `AwesomeMessage.$type` and `AwesomeMesage#$type`, the respective custom class is automatically populated with:376 377* `AwesomeMessage.create`378* `AwesomeMessage.encode` and `AwesomeMessage.encodeDelimited`379* `AwesomeMessage.decode` and `AwesomeMessage.decodeDelimited`380* `AwesomeMessage.verify`381* `AwesomeMessage.fromObject`, `AwesomeMessage.toObject` and `AwesomeMessage#toJSON`382 383Afterwards, decoded messages of this type are `instanceof AwesomeMessage`.384 385Alternatively, it is also possible to reuse and extend the internal constructor if custom initialization code is not required:386 387```js388...389 390// Reuse the internal constructor391var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage").ctor;392 393// Define custom functionality394AwesomeMessage.customStaticMethod = function() { ... };395AwesomeMessage.prototype.customInstanceMethod = function() { ... };396 397// Continue at "Create a new message" above398```399 400### Using services401 402The library also supports consuming services but it doesn't make any assumptions about the actual transport channel. Instead, a user must provide a suitable RPC implementation, which is an asynchronous function that takes the reflected service method, the binary request and a node-style callback as its parameters:403 404```js405function rpcImpl(method, requestData, callback) {406 // perform the request using an HTTP request or a WebSocket for example407 var responseData = ...;408 // and call the callback with the binary response afterwards:409 callback(null, responseData);410}411```412 413Below is a working example with a typescript implementation using grpc npm package.414```ts415const grpc = require('grpc')416 417const Client = grpc.makeGenericClientConstructor({})418const client = new Client(419 grpcServerUrl,420 grpc.credentials.createInsecure()421)422 423const rpcImpl = function(method, requestData, callback) {424 client.makeUnaryRequest(425 method.name,426 arg => arg,427 arg => arg,428 requestData,429 callback430 )431}432```433 434Example:435 436```protobuf437// greeter.proto438syntax = "proto3";439 440service Greeter {441 rpc SayHello (HelloRequest) returns (HelloReply) {}442}443 444message HelloRequest {445 string name = 1;446}447 448message HelloReply {449 string message = 1;450}451```452 453```js454...455var Greeter = root.lookup("Greeter");456var greeter = Greeter.create(/* see above */ rpcImpl, /* request delimited? */ false, /* response delimited? */ false);457 458greeter.sayHello({ name: 'you' }, function(err, response) {459 console.log('Greeting:', response.message);460});461```462 463Services also support promises:464 465```js466greeter.sayHello({ name: 'you' })467 .then(function(response) {468 console.log('Greeting:', response.message);469 });470```471 472There is also an [example for streaming RPC](https://github.com/protobufjs/protobuf.js/blob/master/examples/streaming-rpc.js).473 474Note that the service API is meant for clients. Implementing a server-side endpoint pretty much always requires transport channel (i.e. http, websocket, etc.) specific code with the only common denominator being that it decodes and encodes messages.475 476### Usage with TypeScript477 478The library ships with its own [type definitions](https://github.com/protobufjs/protobuf.js/blob/master/index.d.ts) and modern editors like [Visual Studio Code](https://code.visualstudio.com/) will automatically detect and use them for code completion.479 480The npm package depends on [@types/node](https://www.npmjs.com/package/@types/node) because of `Buffer` and [@types/long](https://www.npmjs.com/package/@types/long) because of `Long`. If you are not building for node and/or not using long.js, it should be safe to exclude them manually.481 482#### Using the JS API483 484The API shown above works pretty much the same with TypeScript. However, because everything is typed, accessing fields on instances of dynamically generated message classes requires either using bracket-notation (i.e. `message["awesomeField"]`) or explicit casts. Alternatively, it is possible to use a [typings file generated for its static counterpart](#pbts-for-typescript).485 486```ts487import { load } from "protobufjs"; // respectively "./node_modules/protobufjs"488 489load("awesome.proto", function(err, root) {490 if (err)491 throw err;492 493 // example code494 const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");495 496 let message = AwesomeMessage.create({ awesomeField: "hello" });497 console.log(`message = ${JSON.stringify(message)}`);498 499 let buffer = AwesomeMessage.encode(message).finish();500 console.log(`buffer = ${Array.prototype.toString.call(buffer)}`);501 502 let decoded = AwesomeMessage.decode(buffer);503 console.log(`decoded = ${JSON.stringify(decoded)}`);504});505```506 507#### Using generated static code508 509If you generated static code to `bundle.js` using the CLI and its type definitions to `bundle.d.ts`, then you can just do:510 511```ts512import { AwesomeMessage } from "./bundle.js";513 514// example code515let message = AwesomeMessage.create({ awesomeField: "hello" });516let buffer = AwesomeMessage.encode(message).finish();517let decoded = AwesomeMessage.decode(buffer);518```519 520#### Using decorators521 522The library also includes an early implementation of [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html).523 524**Note** that decorators are an experimental feature in TypeScript and that declaration order is important depending on the JS target. For example, `@Field.d(2, AwesomeArrayMessage)` requires that `AwesomeArrayMessage` has been defined earlier when targeting `ES5`.525 526```ts527import { Message, Type, Field, OneOf } from "protobufjs/light"; // respectively "./node_modules/protobufjs/light.js"528 529export class AwesomeSubMessage extends Message<AwesomeSubMessage> {530 531 @Field.d(1, "string")532 public awesomeString: string;533 534}535 536export enum AwesomeEnum {537 ONE = 1,538 TWO = 2539}540 541@Type.d("SuperAwesomeMessage")542export class AwesomeMessage extends Message<AwesomeMessage> {543 544 @Field.d(1, "string", "optional", "awesome default string")545 public awesomeField: string;546 547 @Field.d(2, AwesomeSubMessage)548 public awesomeSubMessage: AwesomeSubMessage;549 550 @Field.d(3, AwesomeEnum, "optional", AwesomeEnum.ONE)551 public awesomeEnum: AwesomeEnum;552 553 @OneOf.d("awesomeSubMessage", "awesomeEnum")554 public which: string;555 556}557 558// example code559let message = new AwesomeMessage({ awesomeField: "hello" });560let buffer = AwesomeMessage.encode(message).finish();561let decoded = AwesomeMessage.decode(buffer);562```563 564Supported decorators are:565 566* **Type.d(typeName?: `string`)** *(optional)*<br />567 annotates a class as a protobuf message type. If `typeName` is not specified, the constructor's runtime function name is used for the reflected type.568 569* **Field.d<T>(fieldId: `number`, fieldType: `string | Constructor<T>`, fieldRule?: `"optional" | "required" | "repeated"`, defaultValue?: `T`)**<br />570 annotates a property as a protobuf field with the specified id and protobuf type.571 572* **MapField.d<T extends { [key: string]: any }>(fieldId: `number`, fieldKeyType: `string`, fieldValueType. `string | Constructor<{}>`)**<br />573 annotates a property as a protobuf map field with the specified id, protobuf key and value type.574 575* **OneOf.d<T extends string>(...fieldNames: `string[]`)**<br />576 annotates a property as a protobuf oneof covering the specified fields.577 578Other notes:579 580* Decorated types reside in `protobuf.roots["decorated"]` using a flat structure, so no duplicate names.581* Enums are copied to a reflected enum with a generic name on decorator evaluation because referenced enum objects have no runtime name the decorator could use.582* Default values must be specified as arguments to the decorator instead of using a property initializer for proper prototype behavior.583* Property names on decorated classes must not be renamed on compile time (i.e. by a minifier) because decorators just receive the original field name as a string.584 585**ProTip!** Not as pretty, but you can [use decorators in plain JavaScript](https://github.com/protobufjs/protobuf.js/blob/master/examples/js-decorators.js) as well.586 587Additional documentation588------------------------589 590#### Protocol Buffers591* [Google's Developer Guide](https://protobuf.dev/overview/)592 593#### protobuf.js594* [API Documentation](https://protobufjs.github.io/protobuf.js)595* [CHANGELOG](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)596* [Frequently asked questions](https://github.com/protobufjs/protobuf.js/wiki) on our wiki597 598#### Community599* [Questions and answers](http://stackoverflow.com/search?tab=newest&q=protobuf.js) on StackOverflow600 601Performance602-----------603The package includes a benchmark that compares protobuf.js performance to native JSON (as far as this is possible) and [Google's JS implementation](https://github.com/google/protobuf/tree/master/js). On an i7-2600K running node 6.9.1 it yields:604 605```606benchmarking encoding performance ...607 608protobuf.js (reflect) x 541,707 ops/sec ±1.13% (87 runs sampled)609protobuf.js (static) x 548,134 ops/sec ±1.38% (89 runs sampled)610JSON (string) x 318,076 ops/sec ±0.63% (93 runs sampled)611JSON (buffer) x 179,165 ops/sec ±2.26% (91 runs sampled)612google-protobuf x 74,406 ops/sec ±0.85% (86 runs sampled)613 614 protobuf.js (static) was fastest615 protobuf.js (reflect) was 0.9% ops/sec slower (factor 1.0)616 JSON (string) was 41.5% ops/sec slower (factor 1.7)617 JSON (buffer) was 67.6% ops/sec slower (factor 3.1)618 google-protobuf was 86.4% ops/sec slower (factor 7.3)619 620benchmarking decoding performance ...621 622protobuf.js (reflect) x 1,383,981 ops/sec ±0.88% (93 runs sampled)623protobuf.js (static) x 1,378,925 ops/sec ±0.81% (93 runs sampled)624JSON (string) x 302,444 ops/sec ±0.81% (93 runs sampled)625JSON (buffer) x 264,882 ops/sec ±0.81% (93 runs sampled)626google-protobuf x 179,180 ops/sec ±0.64% (94 runs sampled)627 628 protobuf.js (reflect) was fastest629 protobuf.js (static) was 0.3% ops/sec slower (factor 1.0)630 JSON (string) was 78.1% ops/sec slower (factor 4.6)631 JSON (buffer) was 80.8% ops/sec slower (factor 5.2)632 google-protobuf was 87.0% ops/sec slower (factor 7.7)633 634benchmarking combined performance ...635 636protobuf.js (reflect) x 275,900 ops/sec ±0.78% (90 runs sampled)637protobuf.js (static) x 290,096 ops/sec ±0.96% (90 runs sampled)638JSON (string) x 129,381 ops/sec ±0.77% (90 runs sampled)639JSON (buffer) x 91,051 ops/sec ±0.94% (90 runs sampled)640google-protobuf x 42,050 ops/sec ±0.85% (91 runs sampled)641 642 protobuf.js (static) was fastest643 protobuf.js (reflect) was 4.7% ops/sec slower (factor 1.0)644 JSON (string) was 55.3% ops/sec slower (factor 2.2)645 JSON (buffer) was 68.6% ops/sec slower (factor 3.2)646 google-protobuf was 85.5% ops/sec slower (factor 6.9)647```648 649These results are achieved by650 651* generating type-specific encoders, decoders, verifiers and converters at runtime652* configuring the reader/writer interface according to the environment653* using node-specific functionality where beneficial and, of course654* avoiding unnecessary operations through splitting up [the toolset](#toolset).655 656You can also run [the benchmark](https://github.com/protobufjs/protobuf.js/blob/master/bench/index.js) ...657 658```659$> npm run bench660```661 662and [the profiler](https://github.com/protobufjs/protobuf.js/blob/master/bench/prof.js) yourself (the latter requires a recent version of node):663 664```665$> npm run prof <encode|decode|encode-browser|decode-browser> [iterations=10000000]666```667 668Note that as of this writing, the benchmark suite performs significantly slower on node 7.2.0 compared to 6.9.1 because moths.669 670Compatibility671-------------672 673* Works in all modern and not-so-modern browsers except IE8.674* Because the internals of this package do not rely on `google/protobuf/descriptor.proto`, options are parsed and presented literally.675* If typed arrays are not supported by the environment, plain arrays will be used instead.676* Support for pre-ES5 environments (except IE8) can be achieved by [using a polyfill](https://github.com/protobufjs/protobuf.js/blob/master/lib/polyfill.js).677* Support for [Content Security Policy](https://w3c.github.io/webappsec-csp/)-restricted environments (like Chrome extensions without unsafe-eval) can be achieved by generating and using static code instead.678* If a proper way to work with 64 bit values (uint64, int64 etc.) is required, just install [long.js](https://github.com/dcodeIO/long.js) alongside this library. All 64 bit numbers will then be returned as a `Long` instance instead of a possibly unsafe JavaScript number ([see](https://github.com/dcodeIO/long.js)).679* For descriptor.proto interoperability, see [ext/descriptor](https://github.com/protobufjs/protobuf.js/tree/master/ext/descriptor)680 681Building682--------683 684To build the library or its components yourself, clone it from GitHub and install the development dependencies:685 686```687$> git clone https://github.com/protobufjs/protobuf.js.git688$> cd protobuf.js689$> npm install690```691 692Building the respective development and production versions with their respective source maps to `dist/`:693 694```695$> npm run build696```697 698Building the documentation to `docs/`:699 700```701$> npm run docs702```703 704Building the TypeScript definition to `index.d.ts`:705 706```707$> npm run build:types708```709 710### Browserify integration711 712By default, protobuf.js integrates into any browserify build-process without requiring any optional modules. Hence:713 714* If int64 support is required, explicitly require the `long` module somewhere in your project as it will be excluded otherwise. This assumes that a global `require` function is present that protobuf.js can call to obtain the long module.715 716 If there is no global `require` function present after bundling, it's also possible to assign the long module programmatically:717 718 ```js719 var Long = ...;720 721 protobuf.util.Long = Long;722 protobuf.configure();723 ```724 725* If you have any special requirements, there is [the bundler](https://github.com/protobufjs/protobuf.js/blob/master/scripts/bundle.js) for reference.726 727**License:** [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)728 