72 Commits
Author SHA1 Message Date
Kenton Varda a2ed298d34 Merge pull request #68 from zenhack/module-stubs
Add .capnp.js stubs generated by capnpc-node-typescript.
2020-12-16 21:52:36 -06:00
Kenton Varda 8509161f7c Merge pull request #67 from zenhack/typescript-decl-fix
Small fix in the typescript declarations, and add some comments.
2020-12-14 16:53:50 -06:00
Ian Denhardt b88ab5a305 Add .capnp.js stubs generated by capnpc-node-typescript.
Per discussion in #62, this allows importing modules to use "normal"
imports, which is important for typescript since it doesn't understand
`capnp.importSystem()` and friends.

We could also merge in the type declarations themselves, but that isn't
strictly necessary, since typescript is built around being able to
supply your own stubs for other libraries. I may do something in that
vein in a follow-on pr, but I want to think a bit about how this
will all fit together.
2020-12-12 02:29:24 -05:00
Ian Denhardt ac4c2574a6 ts declarations: Add comments describing how the type parameters work. 2020-12-12 02:00:08 -05:00
Ian Denhardt 0ba69aec95 Fix a mistake in the type declaration file.
The argument to serialize() should be a builder, not a reader.
2020-12-12 01:54:15 -05:00
Kenton Varda 7ef8da3d79 Merge pull request #66 from zenhack/gitignore-capnp.node
Add capnp.node to .gitignore
2020-12-07 13:39:16 -06:00
Ian Denhardt 0e9376071e Add capnp.node to .gitignore 2020-12-07 10:42:43 -05:00
Kenton Varda d75642d0e8 Merge pull request #62 from zenhack/typescript-declaration-file
Add a typescript declaration file.
2020-11-30 16:05:15 -06:00
Ian Denhardt 6eb94df293 Add a typescript declaration file.
This covers most of the API that is documented in the README, though I
see that there are some things exposed in `capnp.js` but not documented
-- the declaration file does not currently cover those.

This is designed to work with the output of:

    https://github.com/zenhack/capnpc-node-typescript

...which is nearing completion.
2020-10-28 16:30:22 -04:00
Kenton Varda 544bf09271 Merge pull request #60 from ocdtrekkie/patch-1
Readme typos
2020-06-08 09:53:11 -05:00
Jacob Weisz b45f75c8f9 Readme typos 2020-06-08 07:38:12 -05:00
Kenton Varda 752d3cdffd Merge pull request #59 from zenhack/null-handle-cleanup
More defensive/sensible handling of a case that probably can't happen.
2020-05-11 10:03:05 -05:00
Ian Denhardt 0371c68bcd More defensive/sensible handling of a case that probably can't happen.
I found this by running clang-analyzer. With the previous version of the
code, if `handler` is null, then we assign `self = nullptr` and then
immediately call a method on it.

I'm pretty sure this can't actually happen -- I don't think
`uv_timer_start` will ever pass nullptr to the callback -- but the logic
is obviously bogus so let's replace it with something defensive.
2020-05-09 23:56:19 -04:00
Kenton Varda ae6f591602 Merge pull request #58 from zenhack/version-bump
Bump version in package.json
2020-03-24 13:03:16 -05:00
Ian Denhardt 81aeebf181 Bump version in package.json
I just published this to the npm registry, we should probably update the
version in the git repo too.

It seems to work on node 12, though node 10 is still failing. I actually
*can* reproduce the failures locally if:

- I start a fresh npm project and do `npm install
  `/path/to/node-canpnp/src`
- The working directory for `node-capnp` is clean.

I may try to troubleshoot this more later. Perhaps we should unpublish,
but having a version that works on node 12 is possibly an improvement,
so maybe not...

Npm insisted that 0.4.0 already existed and was refusing to re-publish
it (I assume there was a deleted failed attempt), so I had to bump the
version to get it to work.
2020-03-23 16:01:04 -04:00
Kenton Varda 0cc5054ea2 Merge branch 'node8' into node10 2020-03-14 18:24:46 -05:00
Kenton Varda cdda439e4a Merge pull request #57 from redsift/node12
Node12 support
2020-03-14 17:25:45 -05:00
Kenton Varda 932e589f36 Merge pull request #55 from zenhack/exception-docs
Document how exceptions work.
2020-01-08 17:50:15 -06:00
Ian Denhardt 46fd0a8b6e Document how exceptions work.
Fixes #53.
2020-01-08 17:53:10 -05:00
Kenton Varda 5e8c4c0b1b Merge pull request #51 from redsift/fix/build
Fix the build process.
2020-01-07 10:56:44 -06:00
Deepak Prabhakara 7ab91af445 pipe stdout and stderr from child process so we can see the logs 2019-12-22 23:32:31 +00:00
Deepak Prabhakara 05644ec31b v8 and nan compilation fixes for node12 2019-12-22 23:26:49 +00:00
Christos Vontas 28de5052c0 Merge pull request #1 from redsift/fix/build
afterBuild needs to run after all IO has finished
2019-12-11 13:50:24 +00:00
Christos Vontas c720781a5f afterBuild needs to run after all IO has finished 2019-12-11 13:42:05 +00:00
Kenton Varda d8de1b49ad Disambiguate getsockname() call. 2019-11-23 11:19:17 -08:00
Kenton Varda 4df200effa Implement KJ's new whenWriteDisconnected(). 2019-02-09 15:31:44 -08:00
Kenton Varda cbb3ab40fb Fix age-old bug with flag combining.
I guess it never cauased a problem because the result was 1 which just happened to map to TAKE_OWNERSHIP and the other flags are safe to skip (just inefficient)...
2019-02-09 15:29:42 -08:00
Kenton Varda eae9c1c54b Update for Node 10. 2019-01-07 13:44:26 -08:00
Kenton Varda 1abd120c12 Update to C++14 as required by Cap'n Proto 0.7. 2019-01-07 13:40:56 -08:00
Kenton Varda ca30a96c1c Merge pull request #43 from qm3ster/patch-1
update capnp-js link
2018-05-14 15:27:29 -07:00
Mihal Malostanidis d2f4c72d64 update capnp-js link
Reorganization in progress
2018-05-08 00:02:48 +03:00
Kenton Varda 202e13c66f Hack: For Sandstorm build, catch segfaults and print stack traces. 2018-04-15 17:28:00 -07:00
Kenton Varda a3e975d43c Bump version number and publish again because apparently npm went and published a 13MB scratch folder I had in the directory last time, wtf. 2018-02-09 08:43:47 -08:00
Kenton Varda f1e9306cd6 Release 0.3.0 which supports node 8+. 2018-02-04 14:17:42 -08:00
Kenton Varda c6fe3c2624 Revert "Add temporary code to count local capability types and support dumping them to stderr periodically."
This reverts commit 74958750f1.

This is no longer needed.
2018-02-04 14:16:01 -08:00
Kenton Varda 7fb9018515 Correctly handle pipelining on a Capability. 2018-02-04 14:12:01 -08:00
Kenton Varda 742d6b5b79 Fix obvious, glaring memory leak. I dunno what to say. 2018-01-06 12:17:56 -08:00
Kenton Varda ec1721f298 Node 8: Properly support capabilities defined using ES6 classes.
I'm not sure why this worked with Node 4 / Meteor 1.5, but behavior changed in Node 8 / Meteor 1.6.
2017-11-18 16:50:37 -08:00
Kenton Varda 5aeffa328a Node 8: Transition from V8 hidden values to V8 private values. 2017-11-18 16:49:55 -08:00
Kenton Varda 1609fa1155 Merge branch 'node4' of github.com:kentonv/node-capnp into node4 2017-09-30 12:05:53 -07:00
Kenton Varda f575e4013c Add the ability to listen on a unix socket delivering connections via SCM_RIGHTS. 2017-09-30 12:05:30 -07:00
Kenton Varda 6525163b1b Update for recent KJ changes. Fixes #36. 2017-09-30 12:04:57 -07:00
Kenton Varda 7afd129314 Merge pull request #31 from dwrensha/capnp-node-is-missing
Fix error message: 'capnp.node.node' -> 'capnp.node'
2017-09-30 12:03:17 -07:00
Kenton Varda f2bfd6f95f Release 0.2.0 which supports node 4+. 2017-09-19 09:25:56 -07:00
Kenton Varda 888f772ef3 Fix several v8 usage bugs that could be causing our memory leaks.
- You can't just call SetWeak() on a handle and then let the handle go out-of-scope. You have to Reset() it when the weak callback is called. Honestly unsure why this doesn't crash.
- The weak handle should have MarkIndependent() called on it, otherwise v8 is less aggressive about GCing it.
- OwnHandle's move semantics were broken. They created a copy (which actually creates a new v8 persistent handle), but then zero'd the original (which means it would never be cleaned up by v8). V8 provides a nice `Global` type which has the semantics we always wanted, so use that.
2017-04-29 15:46:07 -07:00
Kenton Varda fbdb9959a9 Revert "Work around apparent memory leak in Node?"
After deploying this change, the frequency of production problems seems to have increased rather than decreased. I don't know if this change is the reason for the increase, but since it did not accomplish its sole goal of decreasing the problem rate, I'm reverting it.

This reverts commit 8497d70320.
2017-03-01 14:20:44 -08:00
Kenton Varda 816cbc38e0 Add a chacha20() function for Sandstorm's use, and add #ifdefs so that Sandstorm-private code isn't included in non-Sandstorm builds. 2017-02-16 20:06:05 -08:00
Kenton Varda 8497d70320 Work around apparent memory leak in Node? 2017-02-14 02:51:54 -08:00
Kenton Varda 4f251bedc6 Merge pull request #32 from kentonv/powerbox-query
Implement Sandstorm powerbox query matching algorithm as a library function.
2016-12-07 23:03:56 -08:00
Kenton Varda 8dbc7e700d Update test per @dwrensha's review comments. 2016-12-05 10:43:52 -08:00
Kenton Varda 1d0caa3f30 Support 'null' appearing in pointer lists. 2016-12-05 10:43:27 -08:00
Kenton Varda 302ae1779f Implement Sandstorm powerbox query matching algorithm as a library function.
Algorithm documented here: https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/powerbox.capnp#L115

Although this is Sandstorm-specific, I'm putting it into node-capnp for convenience: this needs to be implemented in C++, and it would be surprisingly difficult to create a second Node module that shares the Cap'n Proto library with capnp.node.
2016-12-04 16:58:10 -08:00
Kenton Varda 8e001b1ff1 Update for change to wrapConnectingSocketFd() signature. 2016-11-30 18:34:06 -08:00
Kenton Varda 492b1c9905 Fix closeAll(). 2016-11-12 13:20:00 -08:00
David Renshaw dd23d9bc5c Fix error message: 'capnp.node.node' -> 'capnp.node' 2016-11-05 19:23:09 -04:00
Kenton Varda 74958750f1 Add temporary code to count local capability types and support dumping them to stderr periodically. 2016-11-03 15:33:07 -07:00
Kenton Varda 05d868bc8f Do type checking / unwrapping the right way.
GetAlignedPoniterFromInternalField() can crash if the internal field is not a pointer, so we can't use this trick of checking if the field contains a pointer to the type's type_info.

The correct thing to do is use FunctionTemplate::HasInstance() to type-check the value. To do that, we of course have to have a reference to the FunctionTemplate already. To make this lookup fast, I used template-static-singletons.
2016-08-08 19:55:52 -07:00
Kenton Varda f48e50e7ff Don't download/install ES6 Promise polyfill anymore. 2016-08-08 18:55:05 -07:00
Kenton Varda 674090dba2 Silence some warnings originating in macros. 2016-08-08 18:54:44 -07:00
Kenton Varda 2b241848f5 Fix RPC callbacks using node::MakeCallback(). 2016-08-08 18:33:08 -07:00
Kenton Varda 4f2ee9bb8f Fix random crashes during GC.
This switches from the (apparently deprecated) WeakCallbackData-based SetWeak() to the newer WeakCallbackInfo-based one.

I have no fucking idea what the difference is, or what the WeakCallbackType enum is supposed to mean, or why it didn't work before. There is no documentation. There are various pages around the internet that make reference to this API but no comprehensive explanation anywhere as to the details. You're supposed to just know, or something.
2016-07-04 02:32:48 -07:00
Kenton Varda 8d57b61bba Promise capabilities take ownership of the capability to which they resolve.
Make sure that the node-level capability is replaced with one that will throw an exception from calls, rather than segfault on null pointer.
2016-07-03 22:13:04 -07:00
Kenton Varda 0c60f1f777 Support "flat" encoding, and "packed-flat" too. 2016-07-03 22:09:33 -07:00
Kenton Varda e3ce43e2be Include Javascript stack when converting to KJ exception. 2016-07-03 22:09:33 -07:00
Drew Fisher f7066436e9 Make the overhead computation look less like it has an integer underflow 2016-07-03 21:58:04 -07:00
Drew Fisher 533aa8043d Compute a tighter upper bound on the buffer needed for packed encoding 2016-07-03 21:56:10 -07:00
Drew Fisher 22a56c1607 Add tests for packed encoding/decoding. 2016-07-03 21:55:28 -07:00
Drew Fisher 7965ca80f5 Add support for serializing structures to packed Cap'n Proto encoding 2016-07-03 21:55:13 -07:00
Drew Fisher 2bdf71bbe2 Add support for parsing structures in Cap'n Proto's packed encoding 2016-07-03 21:49:19 -07:00
Kenton Varda 3d5d0c9d38 Update package.json to reflect the node API chanage. (I'm not actually sure if this works with 0.12, but it definitely doesn't work with 0.10 anymore.) 2016-02-15 19:11:14 -08:00
Kenton Varda 4128f687a8 Expose expectedSizeFromPrefix to node. 2016-02-15 19:05:43 -08:00
Kenton Varda eba8a33e66 Port to Node 4. 2016-02-14 23:33:53 -08:00
17 changed files with 1122 additions and 548 deletions

No files matched your search

+38 -3
View File
@@ -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.
@@ -49,9 +49,9 @@ On Debian/Ubuntu, you can install these like so:
sudo apt-get install nodejs-dev nodejs-legacy capnproto-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.
+1
View File
@@ -0,0 +1 @@
capnp.node
+2 -2
View File
@@ -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',
+7 -3
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/c++.capnp");
+7 -7
View File
@@ -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"
}
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/persistent.capnp");
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/rpc-twoparty.capnp");
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/rpc.capnp");
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/schema.capnp");
+151 -29
View File
@@ -22,7 +22,6 @@
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;
@@ -88,11 +87,117 @@ for (var key in keys) {
assert.equal(parsed[key], parsedPackedFlat[key]);
}
// =======================================================================================
console.log("serialization: pass");
/*
// TODO(someday): Revive this test. The main problem is that it depends on calculator-server from
// the Cap'n Proto samples directory.
// =======================================================================================
// 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");
@@ -144,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;
@@ -158,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;
@@ -211,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");
+833 -455
View File
File diff suppressed because it is too large. Load diff
+45
View File
@@ -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;
+32 -16
View File
@@ -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,9 +260,16 @@ 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.expectedSizeFromPrefix = v8capnp.expectedSizeFromPrefix;
exports.parse = function (schema, buffer, options) {
var reader = v8capnp.fromBytes(buffer, schema, options || {});
return v8capnp.toJs(reader, Capability);
@@ -286,3 +300,5 @@ exports.bytesToPreorder = function(schema, buf, options) {
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
View File
@@ -1,3 +1,2 @@
capnp.node node_modules
capnp.js node_modules
es6-promise.js node_modules
+1
View File
@@ -0,0 +1 @@
module.exports = require("capnp").importSystem("capnp/stream.capnp");