Skip to content

Commit

Permalink
feat: get the official "addressbook" example working in JS (#56)
Browse files Browse the repository at this point in the history
This introduces capnpc-js, and a new js-examples package that should be prominent within the repo, and have minimal dependencies to serve as a reference. It doubles as a full integration test of the system (although it's a little light on validation, as is the original in the C++ repo).
  • Loading branch information
efokschaner authored and jdiaz5513 committed Nov 19, 2017
1 parent e57ae0d commit 952b21d
Show file tree
Hide file tree
Showing 33 changed files with 877 additions and 138 deletions.
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ node_js:
- "4"

before_install:
- bash ci/install-capnproto.sh
- curl -o- -L https://yarnpkg.com/install.sh | bash -s
- export PATH="$HOME/.yarn/bin:$PATH"
- export PATH="$HOME/opt/bin:$HOME/.yarn/bin:$PATH"
install:
- yarn --frozen-lockfile
- yarn run bootstrap -- --frozen-lockfile

script: yarn run ci

cache:
yarn: true
directories:
- node_modules
- js-examples/node_modules
- packages/capnp-ts/node_modules
- packages/capnpc-ts/node_modules
- packages/capnpc-js/node_modules
10 changes: 7 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
"**/CVS": true,
"**/.DS_Store": true,
".nyc_output": true,
"coverage": true,
"packages/**/lib": true,
"packages/**/lib-test": true
"coverage": true
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/lib": true,
"**/lib-test": true
}
}
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "make",
"command": "gulp",
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": false,
Expand Down
2 changes: 2 additions & 0 deletions HUMANS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

- Code ninja: [ishitatsuyuki](https://github.com/ishitatsuyuki)

- Code ninja: [efokschaner](https://github.com/efokschaner)

## SPECIAL THANKS

- Microsoft's dev team (VSCode, TypeScript)
Expand Down
41 changes: 28 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ This repository is managed as a monorepo composed of separate packages.
|:--------|:--------|:-------------|
| [`capnp-ts`](/packages/capnp-ts) | [![npm](https://img.shields.io/npm/v/capnp-ts.svg?maxAge=2592000)](https://www.npmjs.com/package/capnp-ts) | [![Dependency Status](https://david-dm.org/jdiaz5513/capnp-ts.svg?path=packages/capnp-ts)](https://david-dm.org/jdiaz5513/capnp-ts?path=packages/capnp-ts) |
| [`capnpc-ts`](/packages/capnpc-ts) | [![npm](https://img.shields.io/npm/v/capnpc-ts.svg?maxAge=2592000)](https://www.npmjs.com/package/capnpc-ts) | [![Dependency Status](https://david-dm.org/jdiaz5513/capnpc-ts.svg?path=packages/capnpc-ts)](https://david-dm.org/jdiaz5513/capnpc-ts?path=packages/capnpc-ts) |
| [`capnpc-js`](/packages/capnpc-js) | [![npm](https://img.shields.io/npm/v/capnpc-js.svg?maxAge=2592000)](https://www.npmjs.com/package/capnpc-js) | [![Dependency Status](https://david-dm.org/jdiaz5513/capnpc-js.svg?path=packages/capnpc-js)](https://david-dm.org/jdiaz5513/capnpc-js?path=packages/capnpc-js) |

- `capnp-ts` is the core Cap'n Proto library for Typescript. It is a required import for all compiled schema files, and the starting point for reading/writing a Cap'n Proto message.
- `capnpc-ts` is the schema compiler. It is intended to be invoked by the [`capnp`](https://capnproto.org/capnp-tool.html) tool.
- `capnpc-ts` is the schema compiler plugin for TypeScript. It is intended to be invoked by the [`capnp`](https://capnproto.org/capnp-tool.html) tool.
- `capnpc-js` is the schema compiler plugin for JavaScript. It is intended to be invoked by the [`capnp`](https://capnproto.org/capnp-tool.html) tool.

## Project Status

Expand All @@ -73,20 +75,27 @@ npm install --save capnp-ts
You may want the schema compiler as well (can also be installed locally):

```shell
npm install -g capnpc-ts
npm install -g capnpc-ts # For TypeScript
# OR
npm install -g capnpc-js # For JavaScript
```

The schema compiler is a [Cap'n Proto plugin](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins) and requires the `capnpc` binary in order to do anything useful; follow the [Cap'n Proto installation instructions](https://capnproto.org/install.html) to install it on your system.

## Usage

Run the following to compile a schema file into Typescript source code:
Run the following to compile a schema file into TypeScript source code:

```shell
capnpc -ots path/to/myschema.capnp
```

Running that command will create a file named `path/to/myschema.capnp.ts`.
Or for JavaScript:
```shell
capnpc -ojs path/to/myschema.capnp
```

Running that command will create a file named `path/to/myschema.capnp.ts` (or `.js`).

> This assumes `capnpc-ts` was installed globally and is available from `$PATH`. If not, change the `-o` option to something like `-onode_modules/.bin/capnpc-ts` so it points to your local `capnpc-ts` install.
Expand All @@ -108,7 +117,19 @@ export function loadMessage(buffer: ArrayBuffer): MyStruct {

### Usage with JavaScript

JavaScript is not **yet** fully supported; the `capnp-ts` library itself can be imported as ES5 JavaScript, but the schema compiler is not yet able to transpile the emitted TypeScript schema file into JavaScript. One may do so manually, if feeling particularly adventurous.
```javascript
const capnp = require('capnp-ts');

const MyStruct = require('./myschema.capnp').MyStruct;

function loadMessage(buffer) {

const message = capnp.Message.fromArrayBuffer(buffer);

return message.getRoot(MyStruct);

}
```

### Usage in a Web Browser

Expand All @@ -131,14 +152,7 @@ Before building the source you will need a few prerequisites:
### Initial Setup

Run the following commands to set up the **node_modules** directories for the monorepo and each package:

```shell
yarn install
npm run bootstrap
```

Bootstrap only needs to be run once; run `yarn install` again any time the packages are updated.
Run `yarn install` to set up the **node_modules** directories for the monorepo and each package.

### Build Tasks

Expand All @@ -153,6 +167,7 @@ npm run build
Or (preferred) using [gulp-cli](https://github.com/gulpjs/gulp-cli):

```shell
npm install --global gulp-cli # If you don't already have gulp-cli
gulp build
```

Expand Down
12 changes: 12 additions & 0 deletions ci/install-capnproto.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#! /usr/bin/env bash
#
# Installs capnproto from a release tarball (because the versions in apt is too old)

set -exuo pipefail

curl -O https://capnproto.org/capnproto-c++-0.6.1.tar.gz
tar zxf capnproto-c++-0.6.1.tar.gz
cd capnproto-c++-0.6.1
./configure --prefix=$HOME/opt
make -j6
make install
10 changes: 10 additions & 0 deletions configs/capnpc-js/tsconfig-lib-test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"outDir": "../../packages/capnpc-js/lib-test",
"rootDir": "../../packages/capnpc-js/test"
},
"extends": "../tsconfig-base",
"include": [
"../../packages/capnpc-js/test/**/*.ts"
]
}
11 changes: 11 additions & 0 deletions configs/capnpc-js/tsconfig-lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"declaration": true,
"outDir": "../../packages/capnpc-js/lib",
"rootDir": "../../packages/capnpc-js/src"
},
"extends": "../tsconfig-base",
"include": [
"../../packages/capnpc-js/src/**/*.ts"
]
}
23 changes: 19 additions & 4 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ gulp.task('build:capnpc-ts:lib', ['build:capnp-ts:lib'], function () {
return build('configs/capnpc-ts/tsconfig-lib.json');
});

/** Build the capnpc-js schema compiler. */
gulp.task('build:capnpc-js:lib', ['build:capnp-ts:lib', 'build:capnpc-ts:lib'], function () {
return build('configs/capnpc-js/tsconfig-lib.json');
});

/** Build tests for capnp-ts. */
gulp.task('build:capnp-ts:test', ['build:capnp-ts:lib'], function () {
return build('configs/capnp-ts/tsconfig-lib-test.json');
Expand All @@ -35,11 +40,16 @@ gulp.task('build:capnpc-ts:test', ['build:capnpc-ts:lib'], function () {
return build('configs/capnpc-ts/tsconfig-lib-test.json');
});

/** Build tests for capnpc-js. */
gulp.task('build:capnpc-js:test', ['build:capnpc-js:lib'], function () {
return build('configs/capnpc-js/tsconfig-lib-test.json');
});

/** Main build task (does not build tests). */
gulp.task('build', ['build:capnp-ts:lib', 'build:capnpc-ts:lib']);
gulp.task('build', ['build:capnp-ts:lib', 'build:capnpc-ts:lib', 'build:capnpc-js:lib']);

/** Build all tests. */
gulp.task('build-test', ['build:capnp-ts:test', 'build:capnpc-ts:test']);
gulp.task('build-test', ['build:capnp-ts:test', 'build:capnpc-ts:test', 'build:capnpc-js:test']);

function test(src, coverage) {
var options = glob.sync(src).concat('-J');
Expand All @@ -62,11 +72,16 @@ gulp.task('test:capnpc-ts', ['build:capnpc-ts:test'], function () {
return test('packages/capnpc-ts/lib-test/**/*.spec.js', false);
});

/** Run tests for the capnpc-js schema compiler. */
gulp.task('test:capnpc-js', ['build:capnpc-js:test'], function () {
return test('packages/capnpc-js/lib-test/**/*.spec.js', false);
});

/** Run all tests. */
gulp.task('test', ['test:capnp-ts', 'test:capnpc-ts']);
gulp.task('test', ['test:capnp-ts', 'test:capnpc-ts', 'test:capnpc-ts']);

/** Run all tests with test coverage. */
gulp.task('test-cov', ['build:capnp-ts:test', 'build:capnpc-ts:test'], function () {
gulp.task('test-cov', ['build:capnp-ts:test', 'build:capnpc-ts:test', 'build:capnpc-js:test'], function () {
return test('packages/*/lib-test/**/*.spec.js', true);
});

Expand Down
3 changes: 3 additions & 0 deletions js-examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Example of using `capnp-ts` in a JavaScript project. This is just a JavaScript version of [the official C++ samples](https://github.com/capnproto/capnproto/tree/master/c%2B%2B/samples)

See `test.sh` for how to run them.
52 changes: 52 additions & 0 deletions js-examples/addressbook.capnp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
# Licensed under the MIT License:
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

@0xef1b5abe02e1f8d4;

struct Person {
id @0 :UInt32;
name @1 :Text;
email @2 :Text;
phones @3 :List(PhoneNumber);

struct PhoneNumber {
number @0 :Text;
type @1 :Type;

enum Type {
mobile @0;
home @1;
work @2;
}
}

employment :union {
unemployed @4 :Void;
employer @5 :Text;
school @6 :Text;
selfEmployed @7 :Void;
# We assume that a person is only one of these.
}
}

struct AddressBook {
people @0 :List(Person);
}
Loading

0 comments on commit 952b21d

Please sign in to comment.