Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18c54885f4 | ||
|
|
644e5e4a4d | ||
|
|
ca17e686f2 | ||
|
|
a2ed298d34 | ||
|
|
8509161f7c | ||
|
|
b88ab5a305 | ||
|
|
ac4c2574a6 | ||
|
|
0ba69aec95 | ||
|
|
7ef8da3d79 | ||
|
|
0e9376071e | ||
|
|
d75642d0e8 | ||
|
|
6eb94df293 | ||
|
|
544bf09271 | ||
|
|
b45f75c8f9 | ||
|
|
752d3cdffd | ||
|
|
0371c68bcd | ||
|
|
ae6f591602 | ||
|
|
81aeebf181 | ||
|
|
0cc5054ea2 | ||
|
|
cdda439e4a | ||
|
|
932e589f36 | ||
|
|
46fd0a8b6e | ||
|
|
5e8c4c0b1b | ||
|
|
7ab91af445 | ||
|
|
05644ec31b | ||
|
|
28de5052c0 | ||
|
|
c720781a5f | ||
|
|
d8de1b49ad | ||
|
|
4df200effa | ||
|
|
cbb3ab40fb | ||
|
|
eae9c1c54b | ||
|
|
1abd120c12 | ||
|
|
ca30a96c1c | ||
|
|
d2f4c72d64 | ||
|
|
202e13c66f | ||
|
|
a3e975d43c | ||
|
|
f1e9306cd6 | ||
|
|
c6fe3c2624 | ||
|
|
7fb9018515 | ||
|
|
742d6b5b79 | ||
|
|
ec1721f298 | ||
|
|
5aeffa328a | ||
|
|
1609fa1155 | ||
|
|
f575e4013c | ||
|
|
6525163b1b | ||
|
|
7afd129314 | ||
|
|
f2bfd6f95f | ||
|
|
888f772ef3 | ||
|
|
fbdb9959a9 | ||
|
|
816cbc38e0 | ||
|
|
8497d70320 | ||
|
|
4f251bedc6 | ||
|
|
8dbc7e700d | ||
|
|
1d0caa3f30 | ||
|
|
302ae1779f | ||
|
|
8e001b1ff1 | ||
|
|
492b1c9905 | ||
|
|
dd23d9bc5c | ||
|
|
74958750f1 | ||
|
|
05d868bc8f | ||
|
|
f48e50e7ff | ||
|
|
674090dba2 | ||
|
|
2b241848f5 | ||
|
|
4f2ee9bb8f | ||
|
|
8d57b61bba | ||
|
|
0c60f1f777 | ||
|
|
e3ce43e2be | ||
|
|
f7066436e9 | ||
|
|
533aa8043d | ||
|
|
22a56c1607 | ||
|
|
7965ca80f5 | ||
|
|
2bdf71bbe2 | ||
|
|
3d5d0c9d38 | ||
|
|
4128f687a8 | ||
|
|
eba8a33e66 |
No files matched your search
@@ -22,7 +22,7 @@ messages from complete Javascript objects. This actually makes the library
|
||||
somewhat nicer syntactically than it would be otherwise, but it is not fast.
|
||||
|
||||
A pure-Javascript implementation would likely be much faster. See
|
||||
[capnp-js](https://github.com/capnp-js/serialization) for such an
|
||||
[capnp-js](https://github.com/capnp-js) for such an
|
||||
implementation. Unfortunately, that implementation is incomplete and does not
|
||||
support [RPC](https://github.com/capnp-js/rpc) just yet. Hence, this hack was
|
||||
created for short-term use.
|
||||
@@ -47,11 +47,11 @@ you must have development headers for Cap'n Proto and Node.js installed, along
|
||||
with the `node-gyp` tool and a GCC new enough for Cap'n Proto (at least 4.7).
|
||||
On Debian/Ubuntu, you can install these like so:
|
||||
|
||||
sudo apt-get install nodejs-dev nodejs-legacy capnproto-dev g++
|
||||
sudo apt-get install nodejs-dev nodejs-legacy libcapnp-dev g++
|
||||
|
||||
### Form source
|
||||
### From source
|
||||
|
||||
git clone git://github.com/kenton/node-capnp.git
|
||||
git clone git://github.com/capnproto/node-capnp.git
|
||||
cd node-capnp
|
||||
npm install
|
||||
|
||||
@@ -118,6 +118,25 @@ we copied.)
|
||||
// object containing the results by name.
|
||||
promise.then(function(response) {
|
||||
console.log(response.namedResult);
|
||||
})
|
||||
// If the remote object throws an rpc exception, the promise will be
|
||||
// rejected. The error returned will have a property `kjType`, which
|
||||
// will be a string representation of the exception's `type` field.
|
||||
.catch(function(error) {
|
||||
switch(error.kjType) {
|
||||
case 'failed':
|
||||
console.log("A generic problem occurred:", error.message);
|
||||
break;
|
||||
case 'overloaded':
|
||||
console.log("Resource overload on the remote end:", error.message);
|
||||
break;
|
||||
case 'disconnected':
|
||||
// ...
|
||||
break;
|
||||
case 'unimplemented':
|
||||
// ...
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
### Pipelining
|
||||
@@ -196,6 +215,22 @@ then use that:
|
||||
In this case, the library only wraps `myFoo` as a capability once, and then
|
||||
calls `close()` once all copies of that reference have been dropped.
|
||||
|
||||
If one of your methods throws an exception, or returns a promise which
|
||||
is subsequently rejected, it will be converted to a capnproto rpc
|
||||
exception. If the exception has a `kjType` property, that will be used
|
||||
for the exception's `type` field, otherwise the type will be `failed`.
|
||||
|
||||
var myBar = {
|
||||
bar: function(foo) {
|
||||
if(!bazAvailable()) {
|
||||
var err = new Error("The baz is busy; try again later.");
|
||||
err.kjType = 'overloaded';
|
||||
throw(err);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
### Exporting a bootstrap capability
|
||||
|
||||
// Connect to another server and export `myFoo` as a bootstrap capability.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
capnp.node
|
||||
+2
-2
@@ -4,12 +4,12 @@
|
||||
'target_name': 'capnp',
|
||||
'sources': ['src/node-capnp/capnp.cc'],
|
||||
'libraries': ['-lkj', '-lkj-async', '-lcapnp', '-lcapnpc', '-lcapnp-rpc'],
|
||||
'cflags_cc': ['-std=c++11'],
|
||||
'cflags_cc': ['-std=c++14'],
|
||||
'cflags_cc!': ['-fno-rtti', '-fno-exceptions'],
|
||||
'conditions': [
|
||||
[ 'OS=="mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS' : ['-std=c++11','-stdlib=libc++'],
|
||||
'OTHER_CPLUSPLUSFLAGS' : ['-std=c++14','-stdlib=libc++'],
|
||||
'OTHER_LDFLAGS': ['-stdlib=libc++'],
|
||||
'GCC_ENABLE_CPP_RTTI': 'YES',
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
||||
|
||||
@@ -72,10 +72,13 @@ if (!force) {
|
||||
|
||||
// Build it
|
||||
function build() {
|
||||
cp.spawn(
|
||||
var sp = cp.spawn(
|
||||
process.platform === 'win32' ? 'node-gyp.cmd' : 'node-gyp',
|
||||
['rebuild'].concat(args),
|
||||
{customFds: [0, 1, 2]})
|
||||
{customFds: [0, 1, 2]});
|
||||
|
||||
sp
|
||||
.on('close', function(){ afterBuild(); })
|
||||
.on('exit', function(err) {
|
||||
if (err) {
|
||||
if (err === 127) {
|
||||
@@ -88,8 +91,9 @@ function build() {
|
||||
}
|
||||
return process.exit(err);
|
||||
}
|
||||
afterBuild();
|
||||
});
|
||||
sp.stdout.pipe(process.stdout);
|
||||
sp.stderr.pipe(process.stderr);
|
||||
}
|
||||
|
||||
// Move it to expected location
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/c++.capnp");
|
||||
+7
-7
@@ -1,8 +1,11 @@
|
||||
{
|
||||
"name": "capnp",
|
||||
"version": "0.1.11",
|
||||
"version": "0.5.0",
|
||||
"description": "A wrapper for the C++ Cap'n Proto library",
|
||||
"keywords": [ "capnproto", "serialization" ],
|
||||
"keywords": [
|
||||
"capnproto",
|
||||
"serialization"
|
||||
],
|
||||
"homepage": "http://capnproto.org",
|
||||
"author": {
|
||||
"name": "Kenton Varda",
|
||||
@@ -15,11 +18,8 @@
|
||||
"email": "jparyani@gmail.com"
|
||||
}
|
||||
],
|
||||
|
||||
"main": "src/node-capnp/capnp.js",
|
||||
"peerDependencies": {
|
||||
"es6-promise": "1.x"
|
||||
},
|
||||
"types": "src/node-capnp/capnp.d.ts",
|
||||
"scripts": {
|
||||
"install": "node ./build.js",
|
||||
"test": "node src/node-capnp/capnp-test.js"
|
||||
@@ -29,7 +29,7 @@
|
||||
"url": "git://github.com/kentonv/node-capnp.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": "0.10.x"
|
||||
"node": ">=10.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/persistent.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/rpc-twoparty.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/rpc.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/schema.capnp");
|
||||
+185
-29
@@ -22,16 +22,24 @@
|
||||
var fs = require("fs");
|
||||
var capnp = require("./capnp");
|
||||
var assert = require("assert");
|
||||
var Promise = require("es6-promise").Promise;
|
||||
var spawn = require("child_process").spawn;
|
||||
|
||||
var goldenBinary;
|
||||
var goldenPackedBinary;
|
||||
var goldenFlatBinary;
|
||||
var goldenPackedFlatBinary;
|
||||
try {
|
||||
// Works in Ekam build.
|
||||
goldenBinary = fs.readFileSync("node-capnp/testdata/binary");
|
||||
goldenPackedBinary = fs.readFileSync("node-capnp/testdata/packedbinary");
|
||||
goldenFlatBinary = fs.readFileSync("node-capnp/testdata/flat");
|
||||
goldenPackedFlatBinary = fs.readFileSync("node-capnp/testdata/packedflat");
|
||||
} catch (ex) {
|
||||
// Works in npm build.
|
||||
goldenBinary = fs.readFileSync("src/node-capnp/testdata/binary");
|
||||
goldenPackedBinary = fs.readFileSync("src/node-capnp/testdata/packedbinary");
|
||||
goldenFlatBinary = fs.readFileSync("src/node-capnp/testdata/flat");
|
||||
goldenPackedFlatBinary = fs.readFileSync("src/node-capnp/testdata/packedflat");
|
||||
}
|
||||
|
||||
var test = require("./test.capnp");
|
||||
@@ -54,11 +62,142 @@ assert.equal("foo", test.TestConstants.textConst);
|
||||
assert.equal("baz", test.TestConstants.structConst.textField);
|
||||
assert.equal("xyzzy", test.TestConstants.textListConst[1]);
|
||||
|
||||
// =======================================================================================
|
||||
// Test packed serialization/deserialization
|
||||
|
||||
/*
|
||||
// TODO(someday): Revive this test. The main problem is that it depends on calculator-server from
|
||||
// the Cap'n Proto samples directory.
|
||||
var parsedPacked = capnp.parsePacked(test.TestAllTypes, goldenPackedBinary);
|
||||
var roundTrippedPacked = capnp.serializePacked(test.TestAllTypes, parsedPacked);
|
||||
assert.equal(goldenPackedBinary.length, roundTrippedPacked.length, "Round trip changed size?");
|
||||
assert.equal(goldenPackedBinary.toString("base64"), roundTrippedPacked.toString("base64"), "Round trip lost data?");
|
||||
|
||||
var parsedFlat = capnp.parse(test.TestAllTypes, goldenFlatBinary, {flat: true});
|
||||
var roundTrippedFlat = capnp.serialize(test.TestAllTypes, parsedFlat, {flat: true});
|
||||
assert.equal(goldenFlatBinary.length, roundTrippedFlat.length, "Round trip changed size?");
|
||||
assert.equal(goldenFlatBinary.toString("base64"), roundTrippedFlat.toString("base64"), "Round trip lost data?");
|
||||
|
||||
var parsedPackedFlat = capnp.parse(test.TestAllTypes, goldenPackedFlatBinary, {packed: true, flat: true});
|
||||
var roundTrippedPackedFlat = capnp.serialize(test.TestAllTypes, parsedPackedFlat, {packed: true, flat: true});
|
||||
assert.equal(goldenPackedFlatBinary.length, roundTrippedPackedFlat.length, "Round trip changed size?");
|
||||
assert.equal(goldenPackedFlatBinary.toString("base64"), roundTrippedPackedFlat.toString("base64"), "Round trip lost data?");
|
||||
|
||||
// TODO(someday): do a more thorough deep equality comparison of parsed and parsedPacked
|
||||
var keys = ["voidField", "boolField", "int8Field", "int16Field", "int32Field", "int64Field"];
|
||||
for (var key in keys) {
|
||||
assert.equal(parsed[key], parsedPacked[key]);
|
||||
assert.equal(parsed[key], parsedFlat[key]);
|
||||
assert.equal(parsed[key], parsedPackedFlat[key]);
|
||||
}
|
||||
|
||||
console.log("serialization: pass");
|
||||
|
||||
// =======================================================================================
|
||||
// Test matchPowerboxQuery
|
||||
|
||||
if (capnp.matchPowerboxQuery) {
|
||||
|
||||
var tag1 = capnp.serialize(test.TestAllTypes, {int32Field: 123});
|
||||
var tag2 = capnp.serialize(test.TestAllTypes, {int32Field: 321});
|
||||
var tag3 = capnp.serialize(test.TestAllTypes, {});
|
||||
|
||||
assert(capnp.matchPowerboxQuery(tag1, tag1));
|
||||
assert(capnp.matchPowerboxQuery(tag2, tag2));
|
||||
assert(capnp.matchPowerboxQuery(tag3, tag3));
|
||||
|
||||
assert(!capnp.matchPowerboxQuery(tag1, tag2));
|
||||
assert(!capnp.matchPowerboxQuery(tag2, tag3));
|
||||
assert(!capnp.matchPowerboxQuery(tag3, tag1));
|
||||
|
||||
var emptyTag = capnp.serialize(test.TestEmptyStruct, {});
|
||||
assert(!capnp.matchPowerboxQuery(emptyTag, tag1));
|
||||
assert(!capnp.matchPowerboxQuery(emptyTag, tag2));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tag3));
|
||||
assert(!capnp.matchPowerboxQuery(tag1, emptyTag));
|
||||
assert(!capnp.matchPowerboxQuery(tag2, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(tag3, emptyTag));
|
||||
|
||||
// Test comparing pointers.
|
||||
var tagStr1 = capnp.serialize(test.TestAllTypes, {textField: "foo"});
|
||||
var tagStr2 = capnp.serialize(test.TestAllTypes, {textField: "bar"});
|
||||
var tagStr3 = capnp.serialize(test.TestAllTypes, {textField: ""});
|
||||
assert(capnp.matchPowerboxQuery(tagStr1, tagStr1));
|
||||
assert(capnp.matchPowerboxQuery(tagStr2, tagStr2));
|
||||
assert(capnp.matchPowerboxQuery(tagStr3, tagStr3));
|
||||
assert(!capnp.matchPowerboxQuery(tagStr1, tagStr2));
|
||||
assert(!capnp.matchPowerboxQuery(tagStr2, tagStr3));
|
||||
assert(!capnp.matchPowerboxQuery(tagStr3, tagStr1));
|
||||
assert(capnp.matchPowerboxQuery(tagStr1, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(tagStr2, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(tagStr3, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagStr1));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagStr2));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagStr3));
|
||||
|
||||
// Note that string comparisons are actually list comparisons. But let's make sure an exact match
|
||||
// is required (which is not the case for list-of-structs).
|
||||
var tagStr4 = capnp.serialize(test.TestAllTypes, {textField: "oof"});
|
||||
assert(!capnp.matchPowerboxQuery(tagStr1, tagStr4));
|
||||
|
||||
// Test list-of-structs.
|
||||
var tagFooBar = capnp.serialize(test.TestAllTypes,
|
||||
{structList: [{textField: "foo"}, {textField: "bar"}]});
|
||||
var tagBarFoo = capnp.serialize(test.TestAllTypes,
|
||||
{structList: [{textField: "bar"}, {textField: "foo"}]});
|
||||
var tagFooOnly = capnp.serialize(test.TestAllTypes,
|
||||
{structList: [{textField: "foo"}]});
|
||||
var tagBarOnly = capnp.serialize(test.TestAllTypes,
|
||||
{structList: [{textField: "bar"}]});
|
||||
var tagEmptyList = capnp.serialize(test.TestAllTypes,
|
||||
{structList: []});
|
||||
|
||||
assert(capnp.matchPowerboxQuery(tagFooBar, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(tagFooBar, tagBarFoo));
|
||||
assert(capnp.matchPowerboxQuery(tagBarFoo, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(tagFooOnly, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(tagBarOnly, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(tagFooOnly, tagBarFoo));
|
||||
assert(capnp.matchPowerboxQuery(tagBarOnly, tagBarFoo));
|
||||
assert(!capnp.matchPowerboxQuery(tagFooBar, tagFooOnly));
|
||||
assert(!capnp.matchPowerboxQuery(tagFooBar, tagBarOnly));
|
||||
assert(!capnp.matchPowerboxQuery(tagBarFoo, tagFooOnly));
|
||||
assert(!capnp.matchPowerboxQuery(tagBarFoo, tagBarOnly));
|
||||
|
||||
assert(capnp.matchPowerboxQuery(tagFooBar, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(tagFooOnly, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(tagBarOnly, emptyTag));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagFooOnly));
|
||||
assert(capnp.matchPowerboxQuery(emptyTag, tagBarOnly));
|
||||
|
||||
assert(!capnp.matchPowerboxQuery(tagFooBar, tagEmptyList));
|
||||
assert(!capnp.matchPowerboxQuery(tagFooOnly, tagEmptyList));
|
||||
assert(!capnp.matchPowerboxQuery(tagBarOnly, tagEmptyList));
|
||||
assert(capnp.matchPowerboxQuery(tagEmptyList, tagFooBar));
|
||||
assert(capnp.matchPowerboxQuery(tagEmptyList, tagFooOnly));
|
||||
assert(capnp.matchPowerboxQuery(tagEmptyList, tagBarOnly));
|
||||
|
||||
// Test list-of-pointers.
|
||||
var tagStrList1 = capnp.serialize(test.TestAllTypes, {textList: ["foo", "bar"]});
|
||||
var tagStrList2 = capnp.serialize(test.TestAllTypes, {textList: ["bar", "foo"]});
|
||||
var tagStrList3 = capnp.serialize(test.TestAllTypes, {textList: ["foo"]});
|
||||
var tagStrList4 = capnp.serialize(test.TestAllTypes, {textList: ["foo", null]});
|
||||
|
||||
assert(capnp.matchPowerboxQuery(tagStrList1, tagStrList1));
|
||||
assert(capnp.matchPowerboxQuery(tagStrList2, tagStrList2));
|
||||
assert(!capnp.matchPowerboxQuery(tagStrList1, tagStrList2));
|
||||
assert(!capnp.matchPowerboxQuery(tagStrList2, tagStrList1));
|
||||
assert(!capnp.matchPowerboxQuery(tagStrList3, tagStrList1));
|
||||
assert(capnp.matchPowerboxQuery(tagStrList4, tagStrList1));
|
||||
|
||||
console.log("matchPowerboxQuery: pass");
|
||||
|
||||
}
|
||||
|
||||
// =======================================================================================
|
||||
// Test RPC, if possible.
|
||||
|
||||
if (!fs.existsSync("capnp-samples")) {
|
||||
console.warn("skipping RPC because capnp-samples not present");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
var Fiber = require("fibers");
|
||||
|
||||
@@ -110,7 +249,7 @@ child.stdio[1].once("readable", function() {
|
||||
doFiber(function() {
|
||||
var conn = capnp.connect("127.0.0.1:21311");
|
||||
var Calculator = capnp.import("capnp-samples/calculator.capnp").Calculator;
|
||||
var calc = conn.restore("calculator", Calculator);
|
||||
var calc = conn.restore(null, Calculator);
|
||||
|
||||
var add = calc.getOperator("add").func;
|
||||
var subtract = calc.getOperator("subtract").func;
|
||||
@@ -124,28 +263,48 @@ child.stdio[1].once("readable", function() {
|
||||
closed: false
|
||||
};
|
||||
|
||||
var localCap = new capnp.Capability(pow, Calculator.Function);
|
||||
assert.equal(9, wait(localCap.call([3, 2])).value);
|
||||
assert(!pow.closed);
|
||||
localCap.close();
|
||||
assert(pow.closed);
|
||||
function usePow(pow) {
|
||||
var localCap = new capnp.Capability(pow, Calculator.Function);
|
||||
assert.equal(9, wait(localCap.call([3, 2])).value);
|
||||
assert(!pow.closed);
|
||||
localCap.close();
|
||||
assert(pow.closed);
|
||||
|
||||
var promise = calc.evaluate(
|
||||
{call: {"function": subtract, params: [
|
||||
{call: {"function": add, params: [
|
||||
{literal: 123}, {literal: 456}]}},
|
||||
{literal: 321}]}});
|
||||
var promise = calc.evaluate(
|
||||
{call: {"function": subtract, params: [
|
||||
{call: {"function": add, params: [
|
||||
{literal: 123}, {literal: 456}]}},
|
||||
{literal: 321}]}});
|
||||
|
||||
var value = promise.value;
|
||||
assert.equal(258, wait(value.read()).value);
|
||||
value.close();
|
||||
var value = promise.value;
|
||||
assert.equal(258, wait(value.read()).value);
|
||||
value.close();
|
||||
|
||||
pow.closed = false;
|
||||
value = calc.evaluate(
|
||||
{call: {"function": pow, params: [{literal: 2}, {literal: 4}]}}).value;
|
||||
assert.equal(16, wait(value.read()).value);
|
||||
assert(pow.closed); // Not kept past return.
|
||||
value.close();
|
||||
pow.closed = false;
|
||||
value = calc.evaluate(
|
||||
{call: {"function": pow, params: [{literal: 2}, {literal: 4}]}}).value;
|
||||
assert.equal(16, wait(value.read()).value);
|
||||
|
||||
// Wait a moment to give the capability a chance to be dropped.
|
||||
wait(new Promise((resolve, reject) => setTimeout(resolve, 10)));
|
||||
assert(pow.closed);
|
||||
value.close();
|
||||
}
|
||||
usePow(pow);
|
||||
|
||||
// Try using a class.
|
||||
class PowClass {
|
||||
constructor() {
|
||||
this.closed = false
|
||||
}
|
||||
call(params) {
|
||||
return Math.pow(params[0], params[1]);
|
||||
}
|
||||
close() {
|
||||
this.closed = true;
|
||||
}
|
||||
};
|
||||
usePow(new PowClass());
|
||||
|
||||
// Try wrapping a promise as a capability -- calls are queued until resolution.
|
||||
var resolvePromisedCalc;
|
||||
@@ -177,12 +336,9 @@ child.stdio[1].once("readable", function() {
|
||||
|
||||
add.close();
|
||||
subtract.close();
|
||||
calc.close();
|
||||
conn.close();
|
||||
|
||||
console.log("rpc: pass");
|
||||
}, child);
|
||||
});
|
||||
*/
|
||||
|
||||
console.log("pass");
|
||||
|
||||
+1031
-476
File diff suppressed because it is too large.
Load diff
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
declare module Capnp {
|
||||
type Id = string;
|
||||
|
||||
abstract class StructSchema<Builder, Reader> {
|
||||
// A schema for a struct type. The `Builder` parameter is what users of
|
||||
// the library specify in order to create a value; it may be missing fields,
|
||||
// which will be filled in with defaults. A `Reader` is what is is returned
|
||||
// when parsing a value, and is guaranteed to have all known fields set.
|
||||
|
||||
typeId: Id;
|
||||
}
|
||||
|
||||
abstract class InterfaceSchema<Server, Client> {
|
||||
// A schema for an interface type. Similarly to `StructSchema`, the `Server`
|
||||
// and `Client` parameters represent objects which may have missing
|
||||
// methods (for servers), and ones which do not (for clients, though calling
|
||||
// the method may still throw unimplemented).
|
||||
|
||||
typeId: Id;
|
||||
}
|
||||
|
||||
interface AnyServer {
|
||||
close?: () => void;
|
||||
}
|
||||
|
||||
interface AnyClient {
|
||||
close(): void;
|
||||
closed: boolean;
|
||||
castAs<Server, Client>(schema: InterfaceSchema<Server, Client>): Client;
|
||||
}
|
||||
|
||||
const Capability: {
|
||||
new<Server, Client>(server: Server, schema: InterfaceSchema<Server, Client>): Client;
|
||||
}
|
||||
|
||||
abstract class Connection {
|
||||
restore<Server, Client>(exportName: string, type: InterfaceSchema<Server, Client>): Client;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
function parse<Builder, Reader>(type: StructSchema<Builder, Reader>, buffer: Buffer): Reader;
|
||||
function serialize<Builder, Reader>(type: StructSchema<Builder, Reader>, builder: Builder): Buffer;
|
||||
function connect(addr: string): Connection;
|
||||
}
|
||||
export default Capnp;
|
||||
+49
-23
@@ -40,12 +40,11 @@ try {
|
||||
} catch (ex) {
|
||||
// Give up.
|
||||
throw new Error(
|
||||
"`" + modPath+ ".node` is missing. Try reinstalling `node-capnp`?");
|
||||
"`capnp.node` is missing. Try reinstalling `node-capnp`?");
|
||||
}
|
||||
}
|
||||
|
||||
var v8capnp = require(modPath);
|
||||
var Promise = require("es6-promise").Promise;
|
||||
|
||||
var importPath = [];
|
||||
for (var i in module.paths) {
|
||||
@@ -100,7 +99,7 @@ function closeAll(obj) {
|
||||
var member = obj[name];
|
||||
if (member instanceof Capability) {
|
||||
member.close();
|
||||
} else {
|
||||
} else if (typeof member === "object") {
|
||||
closeAll(member);
|
||||
}
|
||||
}
|
||||
@@ -167,9 +166,13 @@ function makeMethod(cap, method) {
|
||||
|
||||
function wrapLocalMethod(self, method) {
|
||||
return function (request) {
|
||||
var params = v8capnp.toJsParams(request, Capability);
|
||||
v8capnp.releaseParams(request);
|
||||
Promise.resolve(method.apply(self, params)).then(function (results) {
|
||||
// We start with Promise.resolve().then(...) so that any exceptions thrown immediately
|
||||
// propagate through the promise chain.
|
||||
Promise.resolve().then(function () {
|
||||
var params = v8capnp.toJsParams(request, Capability);
|
||||
v8capnp.releaseParams(request);
|
||||
return method.apply(self, params);
|
||||
}).then(function (results) {
|
||||
if (typeof results !== "object") {
|
||||
if (results === undefined) {
|
||||
results = [];
|
||||
@@ -189,16 +192,20 @@ function wrapLocalMethod(self, method) {
|
||||
}
|
||||
|
||||
function LocalCapWrapper(obj) {
|
||||
for (var name in obj) {
|
||||
if (name === "close") {
|
||||
// Not an RPC method. Called when the capability has no clients.
|
||||
this.close = obj.close.bind(obj);
|
||||
} else {
|
||||
var method = obj[name];
|
||||
if (typeof method === "function") {
|
||||
this[name] = wrapLocalMethod(obj, method);
|
||||
var type = obj;
|
||||
while (type && type !== Object.prototype) {
|
||||
Object.getOwnPropertyNames(type).forEach(name => {
|
||||
if (name === "close") {
|
||||
// Not an RPC method. Called when the capability has no clients.
|
||||
this.close = obj.close.bind(obj);
|
||||
} else {
|
||||
var method = obj[name];
|
||||
if (typeof method === "function") {
|
||||
this[name] = wrapLocalMethod(obj, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
type = Object.getPrototypeOf(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,26 +260,45 @@ exports.connect = function (addr, bootstrapCap) {
|
||||
if (bootstrapCap && !v8capnp.isCap(bootstrapCap)) {
|
||||
throw new Error("Invalid bootstrap capability.");
|
||||
}
|
||||
return new Connection(v8capnp.connect(addr, bootstrapCap));
|
||||
|
||||
if (addr.capabilityStreamFd) {
|
||||
return new Connection(v8capnp.connectUnixFd(addr.capabilityStreamFd, bootstrapCap));
|
||||
} else {
|
||||
return new Connection(v8capnp.connect(addr, bootstrapCap));
|
||||
}
|
||||
}
|
||||
|
||||
exports.parse = function (schema, buffer) {
|
||||
var reader = v8capnp.fromBytes(buffer, schema);
|
||||
exports.expectedSizeFromPrefix = v8capnp.expectedSizeFromPrefix;
|
||||
|
||||
exports.parse = function (schema, buffer, options) {
|
||||
var reader = v8capnp.fromBytes(buffer, schema, options || {});
|
||||
return v8capnp.toJs(reader, Capability);
|
||||
}
|
||||
|
||||
exports.serialize = function (schema, value) {
|
||||
exports.parsePacked = function (schema, buffer) {
|
||||
// TODO(cleanup): Remove in favor of options.
|
||||
return exports.parse(schema, buffer, {packed: true});
|
||||
}
|
||||
|
||||
exports.serialize = function (schema, value, options) {
|
||||
var builder = v8capnp.newBuilder(schema);
|
||||
v8capnp.fromJs(builder, value, LocalCapWrapper);
|
||||
return v8capnp.toBytes(builder);
|
||||
return v8capnp.toBytes(builder, options || {});
|
||||
}
|
||||
|
||||
exports.serializePacked = function (schema, value) {
|
||||
// TODO(cleanup): Remove in favor of options.
|
||||
return exports.serialize(schema, value, {packed: true});
|
||||
}
|
||||
|
||||
exports.Capability = Capability;
|
||||
|
||||
exports.bytesToPreorder = function(schema, buf) {
|
||||
exports.bytesToPreorder = function(schema, buf, options) {
|
||||
// Parse, copy, serialize, to get a preorder traversal.
|
||||
var reader = v8capnp.fromBytes(buf, schema);
|
||||
var reader = v8capnp.fromBytes(buf, schema, options || {});
|
||||
var builder = v8capnp.copyBuilder(reader);
|
||||
return v8capnp.toBytes(builder);
|
||||
return v8capnp.toBytes(builder, options || {});
|
||||
}
|
||||
|
||||
if (v8capnp.matchPowerboxQuery) exports.matchPowerboxQuery = v8capnp.matchPowerboxQuery;
|
||||
if (v8capnp.chacha20) exports.chacha20 = v8capnp.chacha20;
|
||||
@@ -1,32 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Copyright (c) 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.
|
||||
|
||||
set -eu
|
||||
|
||||
echo newOutput node-capnp/es6-promise.js
|
||||
read OUTPUT
|
||||
|
||||
curl -s https://es6-promises.s3.amazonaws.com/es6-promise-2.0.1.min.js > "$OUTPUT"
|
||||
|
||||
echo "4f423e916c1ced14fc56c83478bd1ff17000f32ea399fda24fd131989265719c $OUTPUT" | sha256sum --quiet --strict -c - >&2
|
||||
|
||||
echo $OUTPUT >&2
|
||||
@@ -1,3 +1,2 @@
|
||||
capnp.node node_modules
|
||||
capnp.js node_modules
|
||||
es6-promise.js node_modules
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/stream.capnp");
|
||||
Reference in new issue
Block a user