Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Jul 4, 2024
1 parent 719665e commit 85561da
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 53 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2017, Mapbox
Copyright (c) 2024, Mapbox
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
89 changes: 41 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,38 +33,26 @@ $ pbf example.proto > example.js
Then read and write objects using the module like this:

```js
var Pbf = require('pbf');
var Example = require('./example.js').Example;
import Pbf from 'pbf';
import {readExample, writeExample} from './example.js';

// read
var pbf = new Pbf(buffer);
var obj = Example.read(pbf);
var obj = readExample(new Pbf(buffer));

// write
var pbf = new Pbf();
Example.write(obj, pbf);
var buffer = pbf.finish();
```

Alternatively, you can compile a module directly in the code:

```js
var compile = require('pbf/compile');
var schema = require('protocol-buffers-schema');

var proto = schema.parse(fs.readFileSync('example.proto'));
var Test = compile(proto).Test;
const pbf = new Pbf();
writeExample(obj, pbf);
const buffer = pbf.finish();
```

If you use `webpack` as your module bundler, you can use [pbf-loader](https://github.com/trivago/pbf-loader)
to load .proto files directly. It returns a compiled module ready to be used.
Alternatively, you can compile a protobuf schema file directly in the code:

Given you already configured your `webpack.config.js`, the code above would look like:
```js
var Pbf = require('pbf');
var proto = require('./example.proto');
import compile from 'pbf/compile';
import schema from 'protocol-buffers-schema';

var Test = proto.Test;
const proto = schema.parse(fs.readFileSync('example.proto'));
const {readExample, writeExample} = compile(proto);
```

#### Custom Reading
Expand Down Expand Up @@ -103,32 +91,36 @@ function writeLayer(layer, pbf) {

## Install

Node and Browserify:
Install using NPM with `npm install pbf`, then import as a module:

```bash
npm install pbf
```js
import Pbf from 'pbf';
```

Making a browser build:
Or use as a module directly in the browser with [jsDelivr](https://www.jsdelivr.com/esm):

```bash
npm install
npm run build-dev # dist/pbf-dev.js (development build)
npm run build-min # dist/pbf.js (minified production build)
```html
<script type="module">
import Pbf from 'https://cdn.jsdelivr.net/npm/pbf/+esm';
</script>
```

CDN link: https://unpkg.com/[email protected]/dist/pbf.js
Alternatively, there's a browser bundle with a `Pbf` global variable:

```html
<script src="https://cdn.jsdelivr.net/npm/pbf"></script>
```

## API

Create a `Pbf` object, optionally given a `Buffer` or `Uint8Array` as input data:

```js
// parse a pbf file from disk in Node
var pbf = new Pbf(fs.readFileSync('data.pbf'));
const pbf = new Pbf(fs.readFileSync('data.pbf'));

// parse a pbf file in a browser after an ajax request with responseType="arraybuffer"
var pbf = new Pbf(new Uint8Array(xhr.response));
const pbf = new Pbf(new Uint8Array(xhr.response));
```

`Pbf` object properties:
Expand All @@ -143,7 +135,7 @@ pbf.pos; // current offset for reading or writing
Read a sequence of fields:

```js
pbf.readFields(function (tag) {
pbf.readFields((tag) => {
if (tag === 1) pbf.readVarint();
else if (tag === 2) pbf.readString();
else ...
Expand All @@ -154,9 +146,9 @@ It optionally accepts an object that will be passed to the reading function for
and also passes the `Pbf` object as a third argument:

```js
var result = pbf.readFields(callback, {})
const result = pbf.readFields(readField, {})

function callback(tag, result, pbf) {
function readField(tag, result, pbf) {
if (tag === 1) result.id = pbf.readVarint();
}
```
Expand All @@ -166,17 +158,17 @@ To read an embedded message, use `pbf.readMessage(fn[, obj])` (in the same way a
Read values:

```js
var value = pbf.readVarint();
var str = pbf.readString();
var numbers = pbf.readPackedVarint();
const value = pbf.readVarint();
const str = pbf.readString();
const numbers = pbf.readPackedVarint();
```

For lazy or partial decoding, simply save the position instead of reading a value,
then later set it back to the saved value and read:

```js
var fooPos = -1;
pbf.readFields(function (tag) {
const fooPos = -1;
pbf.readFields((tag) => {
if (tag === 1) fooPos = pbf.pos;
});
...
Expand Down Expand Up @@ -287,15 +279,16 @@ For an example of a real-world usage of the library, see [vector-tile-js](https:
If installed globally, `pbf` provides a binary that compiles `proto` files into JavaScript modules. Usage:

```bash
$ pbf <proto_path> [--no-write] [--no-read] [--browser]
$ pbf <proto_path> [--no-write] [--no-read] [--legacy]
```

The `--no-write` and `--no-read` switches remove corresponding code in the output.
The `--browser` switch makes the module work in browsers instead of Node.
The `--legacy` switch makes it generate a CommonJS module instead of ESM.

`Pbf` will generate `read<Identifier>` and `write<Identifier>` functions for every message in the schema. For nested messages, their names will be concatenated — e.g. `Message` inside `Test` will produce `readTestMessage` and `writeTestMessage` functions.

The resulting module exports each message by name with the following methods:

* `read(pbf)` - decodes an object from the given `Pbf` instance
* `write(obj, pbf)` - encodes an object into the given `Pbf` instance (usually empty)
* `read(pbf)` - decodes an object from the given `Pbf` instance.
* `write(obj, pbf)` - encodes an object into the given `Pbf` instance (usually empty).

The resulting code is clean and simple, so feel free to customize it.
The resulting code is clean and simple, so it's meant to be customized.
5 changes: 3 additions & 2 deletions bin/pbf
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import resolve from 'resolve-protobuf-schema';
import {compileRaw} from '../compile.js';

if (process.argv.length < 3) {
console.error('Usage: pbf [file.proto] [--browser] [--no-read] [--no-write]');
console.error('Usage: pbf [file.proto] [--no-read] [--no-write] [--legacy]');
process.exit(0);
}

const code = compileRaw(resolve.sync(process.argv[2]), {
noRead: process.argv.indexOf('--no-read') >= 0,
noWrite: process.argv.indexOf('--no-write') >= 0
noWrite: process.argv.indexOf('--no-write') >= 0,
legacy: process.argv.indexOf('--legacy') >= 0
});

process.stdout.write(code);
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"description": "a low-level, lightweight protocol buffers implementation in JavaScript",
"main": "index.js",
"type": "module",
"unpkg": "dist/pbf.js",
"jsdelivr": "dist/pbf.js",
"exports": {
".": "./index.js",
"./compile": "./compile.js"
},
"scripts": {
"bench": "node bench/bench.js",
"pretest": "eslint *.js compile.js test/*.js bench/vector_tile.js bin/pbf",
Expand Down

0 comments on commit 85561da

Please sign in to comment.