You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by fa...@apache.org on 2014/05/02 19:30:42 UTC

svn commit: r1591980 - in /qpid/proton/branches/fadams-javascript-binding: examples/messenger/c/ examples/messenger/javascript/ proton-c/bindings/javascript/ proton-c/bindings/javascript/qpid-proton/ proton-c/bindings/javascript/qpid-proton/lib/ proton...

Author: fadams
Date: Fri May  2 17:30:42 2014
New Revision: 1591980

URL: http://svn.apache.org/r1591980
Log:
Add packaging for npm and improve serialisation of numerical types

Added:
    qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/
    qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js   (with props)
    qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js   (with props)
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE   (with props)
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md   (with props)
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/lib/
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/package.json
Removed:
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/drain.js
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/spout.js
Modified:
    qpid/proton/branches/fadams-javascript-binding/examples/messenger/c/CMakeLists.txt
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/CMakeLists.txt
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/README
    qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/binding.js
    qpid/proton/branches/fadams-javascript-binding/proton-c/src/messenger/messenger.c
    qpid/proton/branches/fadams-javascript-binding/tools/cmake/Modules/FindNodePackages.cmake

Modified: qpid/proton/branches/fadams-javascript-binding/examples/messenger/c/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/examples/messenger/c/CMakeLists.txt?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/examples/messenger/c/CMakeLists.txt (original)
+++ qpid/proton/branches/fadams-javascript-binding/examples/messenger/c/CMakeLists.txt Fri May  2 17:30:42 2014
@@ -21,8 +21,12 @@ find_package(Proton REQUIRED)
 
 add_executable(recv recv.c)
 add_executable(send send.c)
+add_executable(recv-async recv-async.c)
+add_executable(send-async send-async.c)
 
 include_directories(${Proton_INCLUDE_DIRS})
 
 target_link_libraries(recv ${Proton_LIBRARIES})
 target_link_libraries(send ${Proton_LIBRARIES})
+target_link_libraries(recv-async ${Proton_LIBRARIES})
+target_link_libraries(send-async ${Proton_LIBRARIES})

Added: qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js?rev=1591980&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js (added)
+++ qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js Fri May  2 17:30:42 2014
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if so import the required library.
+if (typeof exports !== "undefined" && exports !== null) {
+    proton = require("qpid-proton");
+}
+
+try {
+    var address = "amqp://~0.0.0.0";
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    function _process() {
+//        console.log("                          *** process ***");
+
+        // Process incoming messages
+
+        while (messenger.incoming()) {
+console.log("in while loop\n");
+
+            var tracker = messenger.get(message);
+console.log("tracker = " + tracker);
+
+            console.log("Address: " + message.getAddress());
+            console.log("Subject: " + message.getSubject());
+            console.log("Content: " + message.body);
+
+            messenger.accept(tracker);
+        }
+    };
+
+    //messenger.setIncomingWindow(1024);
+
+    messenger.setNetworkCallback(_process);
+    messenger.start();
+
+    messenger.subscribe(address);
+    messenger.recv(); // Receive as many messages as messenger can buffer.
+
+} catch(e) {
+    console.log("Caught Exception " + e);
+}
+
+

Propchange: qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/drain.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js?rev=1591980&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js (added)
+++ qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js Fri May  2 17:30:42 2014
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+// Check if the environment is Node.js and if so import the required library.
+if (typeof exports !== "undefined" && exports !== null) {
+    proton = require("qpid-proton");
+}
+
+try {
+    var address = "amqp://0.0.0.0";
+    var subject = "UK.WEATHER";
+    var msgtext = "Hello World!";
+    var tracker = null;
+    var running = true;
+
+    var message = new proton.Message();
+    var messenger = new proton.Messenger();
+
+    function _process() {
+//        console.log("                          *** process ***");
+
+        // Process outgoing messages
+        var status = messenger.status(tracker);
+        if (status != proton.Status.PENDING) {
+console.log("status = " + status);
+
+            //messenger.settle(tracker);
+            //tracked--;
+
+            if (running) {
+console.log("stopping");
+                messenger.stop();
+                running = false;
+            } 
+        }
+
+        if (messenger.isStopped()) {
+console.log("exiting");
+            message.free();
+            messenger.free();
+            //exit(0);
+        }
+    };
+
+
+    messenger.setOutgoingWindow(1024);
+
+    messenger.setNetworkCallback(_process);
+    messenger.start();
+
+    message.setAddress(address);
+    message.setSubject(subject);
+    //message.body = msgtext;
+    //message.body = new proton.Data.UUID();
+    //message.body = new proton.Data.Symbol("My Symbol");
+    //message.body = new proton.Data.Binary("Monkey Bathпогромзхцвбнм");
+
+    /*message.body = new proton.Data.Binary(4);
+    var buffer = message.body.getBuffer();
+    buffer[0] = 65;
+    buffer[1] = 77;
+    buffer[2] = 81;
+    buffer[3] = 80;*/
+
+
+    //message.body = true;
+    //message.body = "   \"127.0\"  ";
+
+    //message.body = 2147483647; // int
+    //message.body = -2147483649; // long
+    //message.body = 12147483649; // long
+
+
+    message.body = (121474.836490).asFloat(); // float TODO check me
+    //message.body = 12147483649.0.asFloat(); // float TODO check me
+    //message.body = (4294967296).asUnsignedInteger();
+    //message.body = (255).asUnsignedByte();
+
+
+    //message.body = ['Rod', 'Jane', 'Freddy'];
+    //message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+
+    tracker = messenger.put(message);
+
+} catch(e) {
+    console.log("Caught Exception " + e);
+}

Propchange: qpid/proton/branches/fadams-javascript-binding/examples/messenger/javascript/spout.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/CMakeLists.txt?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/CMakeLists.txt (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/CMakeLists.txt Fri May  2 17:30:42 2014
@@ -222,9 +222,34 @@ set_target_properties(
   # This build is optimised and minified
   #LINK_FLAGS "-s \"EXPORT_NAME='proton'\" -s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" -O2 --closure 1 --pre-js
 
-  LINK_FLAGS "-s \"EXPORT_NAME='proton'\" -s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" -O2 --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-open.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/binding.js --post-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-close.js --js-library ${CMAKE_CURRENT_SOURCE_DIR}/my-library.js -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=\"[]\" -s EXPORTED_FUNCTIONS=\"['_test', '_uuid_generate', '_pn_bytes', '_pn_error_text', '_pn_code', '_pn_messenger', '_pn_messenger_name', '_pn_messenger_set_blocking', '_pn_messenger_free', '_pn_messenger_errno', '_pn_messenger_error', '_pn_messenger_get_outgoing_window', '_pn_messenger_set_outgoing_window', '_pn_messenger_get_incoming_window', '_pn_messenger_set_incoming_window', '_pn_messenger_start', '_pn_messenger_stop', '_pn_messenger_stopped', '_pn_messenger_subscribe', '_pn_messenger_put', '_pn_messenger_status', '_pn_messenger_buffered', '_pn_messenger_settle', '_pn_messenger_outgoing_tracker', '_pn_messenger_work', '_pn_messenger_recv', '_pn_m
 essenger_receiving', '_pn_messenger_get', '_pn_messenger_incoming_tracker', '_pn_messenger_incoming_subscription', '_pn_messenger_accept', '_pn_messenger_reject', '_pn_messenger_outgoing', '_pn_messenger_incoming',  '_pn_messenger_route', '_pn_messenger_rewrite', '_pn_subscription_get_context', '_pn_subscription_set_context', '_pn_subscription_address', '_pn_message', '_pn_message_free', '_pn_message_get_address', '_pn_message_errno', '_pn_message_error', '_pn_message_set_address', '_pn_message_get_subject', '_pn_message_set_subject', '_pn_message_instructions', '_pn_message_annotations', '_pn_message_properties', '_pn_message_body', '_pn_data', '_pn_data_free', '_pn_data_error', '_pn_data_errno', '_pn_data_clear', '_pn_data_rewind', '_pn_data_next', '_pn_data_prev', '_pn_data_enter', '_pn_data_exit', '_pn_data_lookup', '_pn_data_narrow', '_pn_data_widen', '_pn_data_type', '_pn_data_encode', '_pn_data_decode', '_pn_data_put_list', '_pn_data_put_map', '_pn_data_put_array', '_pn_data_
 put_described', '_pn_data_put_null', '_pn_data_put_bool', '_pn_data_put_ubyte', '_pn_data_put_byte', '_pn_data_put_ushort', '_pn_data_put_short', '_pn_data_put_uint', '_pn_data_put_int', '_pn_data_put_char', '_pn_data_put_ulong', '_pn_data_put_long', '_pn_data_put_timestamp', '_pn_data_put_float', '_pn_data_put_double', '_pn_data_put_decimal32', '_pn_data_put_decimal64', '_pn_data_put_decimal128', '_pn_data_put_uuid', '_pn_data_put_binary', '_pn_data_put_string', '_pn_data_put_symbol', '_pn_data_get_list', '_pn_data_get_map', '_pn_data_get_array', '_pn_data_is_described', '_pn_data_is_null', '_pn_data_get_bool', '_pn_data_get_ubyte', '_pn_data_get_byte', '_pn_data_get_ushort', '_pn_data_get_short', '_pn_data_get_uint', '_pn_data_get_int', '_pn_data_get_char', '_pn_data_get_ulong', '_pn_data_get_long', '_pn_data_get_timestamp', '_pn_data_get_float', '_pn_data_get_double', '_pn_data_get_decimal32', '_pn_data_get_decimal64', '_pn_data_get_decimal128', '_pn_data_get_uuid', '_pn_data_get
 _binary', '_pn_data_get_string', '_pn_data_get_symbol', '_pn_data_copy', '_pn_data_format', '_pn_data_dump']\""
+  LINK_FLAGS "-s \"EXPORT_NAME='proton'\" -s \"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" -O2 --closure 1 --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-open.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/binding.js --post-js ${CMAKE_CURRENT_SOURCE_DIR}/binding-close.js --js-library ${CMAKE_CURRENT_SOURCE_DIR}/my-library.js -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=\"[]\" -s EXPORTED_FUNCTIONS=\"['_test', '_uuid_generate', '_pn_bytes', '_pn_error_text', '_pn_code', '_pn_messenger', '_pn_messenger_name', '_pn_messenger_set_blocking', '_pn_messenger_free', '_pn_messenger_errno', '_pn_messenger_error', '_pn_messenger_get_outgoing_window', '_pn_messenger_set_outgoing_window', '_pn_messenger_get_incoming_window', '_pn_messenger_set_incoming_window', '_pn_messenger_start', '_pn_messenger_stop', '_pn_messenger_stopped', '_pn_messenger_subscribe', '_pn_messenger_put', '_pn_messenger_status', '_pn_messenger_buffered', '_pn_messenger_settle', '_pn_messenger_outgoing_tracker', '_pn_messenger_work', '_pn_messenger_r
 ecv', '_pn_messenger_receiving', '_pn_messenger_get', '_pn_messenger_incoming_tracker', '_pn_messenger_incoming_subscription', '_pn_messenger_accept', '_pn_messenger_reject', '_pn_messenger_outgoing', '_pn_messenger_incoming',  '_pn_messenger_route', '_pn_messenger_rewrite', '_pn_subscription_get_context', '_pn_subscription_set_context', '_pn_subscription_address', '_pn_message', '_pn_message_free', '_pn_message_get_address', '_pn_message_errno', '_pn_message_error', '_pn_message_set_address', '_pn_message_get_subject', '_pn_message_set_subject', '_pn_message_instructions', '_pn_message_annotations', '_pn_message_properties', '_pn_message_body', '_pn_data', '_pn_data_free', '_pn_data_error', '_pn_data_errno', '_pn_data_clear', '_pn_data_rewind', '_pn_data_next', '_pn_data_prev', '_pn_data_enter', '_pn_data_exit', '_pn_data_lookup', '_pn_data_narrow', '_pn_data_widen', '_pn_data_type', '_pn_data_encode', '_pn_data_decode', '_pn_data_put_list', '_pn_data_put_map', '_pn_data_put_array'
 , '_pn_data_put_described', '_pn_data_put_null', '_pn_data_put_bool', '_pn_data_put_ubyte', '_pn_data_put_byte', '_pn_data_put_ushort', '_pn_data_put_short', '_pn_data_put_uint', '_pn_data_put_int', '_pn_data_put_char', '_pn_data_put_ulong', '_pn_data_put_long', '_pn_data_put_timestamp', '_pn_data_put_float', '_pn_data_put_double', '_pn_data_put_decimal32', '_pn_data_put_decimal64', '_pn_data_put_decimal128', '_pn_data_put_uuid', '_pn_data_put_binary', '_pn_data_put_string', '_pn_data_put_symbol', '_pn_data_get_list', '_pn_data_get_map', '_pn_data_get_array', '_pn_data_is_described', '_pn_data_is_null', '_pn_data_get_bool', '_pn_data_get_ubyte', '_pn_data_get_byte', '_pn_data_get_ushort', '_pn_data_get_short', '_pn_data_get_uint', '_pn_data_get_int', '_pn_data_get_char', '_pn_data_get_ulong', '_pn_data_get_long', '_pn_data_get_timestamp', '_pn_data_get_float', '_pn_data_get_double', '_pn_data_get_decimal32', '_pn_data_get_decimal64', '_pn_data_get_decimal128', '_pn_data_get_uuid', '
 _pn_data_get_binary', '_pn_data_get_string', '_pn_data_get_symbol', '_pn_data_copy', '_pn_data_format', '_pn_data_dump']\""
   )
 
+# This command packages up the compiled proton.js into a node.js package called
+# qpid-proton and copies it to the <proton>/node_modules directory. This allows
+# the node.js test and example programs to do proton = require("qpid-proton");
+add_custom_command(
+    TARGET proton.js
+    COMMAND ${CMAKE_COMMAND}
+            -E copy_directory 
+            ${CMAKE_CURRENT_SOURCE_DIR}/qpid-proton 
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton
+    COMMAND ${CMAKE_COMMAND}
+            -E copy
+            ${CMAKE_CURRENT_BINARY_DIR}/proton.js
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton/lib
+   COMMENT "Building qpid-proton package for node.js"
+)
+
+# The cleanall target removes the qpid-proton package from <proton>/node_modules
+add_custom_target(
+    cleanall
+    COMMAND echo "CLEAN NODE MODULES"
+    COMMAND ${CMAKE_COMMAND}
+            -E remove_directory
+            ${PROJECT_SOURCE_DIR}/node_modules/qpid-proton
+)
+
 # If the docs target is specified and the jsdoc3 package for node.js has been
 # installed then build the JavaScript API documentation.
 if (NODE_JSDOC_FOUND)
@@ -236,8 +261,3 @@ if (NODE_JSDOC_FOUND)
 
 endif (NODE_JSDOC_FOUND)
 
-# Some hacks so check what's getting built TODO to get rid of eventually 
-#message(STATUS "qpid-proton-platform: ${qpid-proton-platform}")
-#message(STATUS "qpid-proton-core: ${qpid-proton-core}")
-
-

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/README
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/README?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/README (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/README Fri May  2 17:30:42 2014
@@ -15,36 +15,35 @@ emscripten itself depends upon. https://
 provides some fairly easy to follow instructions for getting started on several
 platforms the main dependencies are as follows (on Windows the SDK includes these):
 
-* The Emscripten code, from github (git clone git://github.com/kripken/emscripten.git. The documentation suggests
-  master branch but in the short term incoming is probably better as a few updates to emscripten have been added
-  to help get proton working and these may take a little while to get merged back to master.
-* LLVM with Clang. Version 3.2 is the officially supported version, others may not work. There are official clang
-  binaries that include LLVM for some platforms, if yours is not there then you should get the LLVM and Clang
-  sources and build them.
+* The Emscripten code, from github (git clone git://github.com/kripken/emscripten.git.
+  The documentation suggests master branch but in the short term incoming is
+  probably better as a few updates to emscripten have been added to help get
+  proton working and these may take a little while to get merged back to master.
+* LLVM with Clang. Emscripten uses LLVM and Clang, but at the moment the JavaScript
+  back-end for LLVM is off on a branch so you can't use a stock LLVM/Clang.
+  https://github.com/kripken/emscripten/wiki/LLVM-Backend has lots of explanation
+  and some easy to follow instructions for downloading and building fast-comp
 * Node.js (0.8 or above; 0.10.17 or above to run websocket-using servers in node)
 * Python 2.7.3
-* Optionally, if you want to use Closure Compiler to minify your code as much as possible, you will also need Java.
+* Java is required in order to use the Closure Compiler to minify the code.
+  
 
-If you haven't run Emscripten before it's a good idea to have a play with the tutorial
-https://github.com/kripken/emscripten/wiki/Tutorial
+If you haven't run Emscripten before it's a good idea to have a play with the
+tutorial https://github.com/kripken/emscripten/wiki/Tutorial
 
 
-when you are all set up with emscripten and have got the basic tests in the tutorial running
-building Proton should be simple, simply go to the Proton root directory and follow the main
-instructions in the README there, in precis (from the root directory) it's:
+
+
+when you are all set up with emscripten and have got the basic tests in the
+tutorial running building Proton should be simple, simply go to the Proton root
+directory and follow the main instructions in the README there, in precis (from
+the root directory) it's:
 
   mkdir build
   cd build
   cmake ..
   make
 
-
-In order to use WebSockets from Node.js you will need to install the "ws" package, the easiest
-way to do this is to use npm. From <proton-root>/build/proton-c/bindings/javascript (or where
-ever you decide to put the JavaScript binding library created by this build) simply do:
-
-  npm install ws
-
 and you should be all set, to test it's all working do:
 
   node recv-async.js
@@ -59,8 +58,7 @@ in another
 KNOWN ISSUES
 ============
 
-send-async and recv-async are both pretty hacky at the moment and not really asynchronous, this will
-be addressed ASAP.
+send-async and recv-async are both pretty hacky at the moment.
 
 
 SUPPORT

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/binding.js
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/binding.js?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/binding.js (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/binding.js Fri May  2 17:30:42 2014
@@ -25,7 +25,7 @@
  * <p>
  * This JavaScript wrapper provides a somewhat more idiomatic object oriented
  * interface which abstracts the low-level emscripten based implementation details
- * from client code.
+ * from client code. Any similarities to the Proton Python binding are deliberate.
  * @file
  */
 
@@ -123,7 +123,7 @@ Module['Messenger'] = function(name) { /
      * freed. In C code compiled by emscripten saving and restoring of the stack
      * is automatic, but if we want to us ALLOC_STACK from native JavaScript we
      * need to explicitly save and restore the stack using Runtime.stackSave()
-     * and Runtime.stackRestore() or we will leak memory.
+     * and Runtime.stackRestore() or we will leak emscripten heap memory.
      * See https://github.com/kripken/emscripten/wiki/Interacting-with-code
      * The _pn_messenger constructor copies the char* passed to it.
      */
@@ -415,7 +415,7 @@ _Messenger_['put'] = function(message) {
     // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
     // low/high pair around to methods that require a tracker.
     var low = _pn_messenger_outgoing_tracker(this._messenger);
-    var high = tempRet0;
+    var high = Runtime.getTempRet0();
     return new Data.Long(low, high);
 };
 
@@ -458,7 +458,7 @@ console.log("settle: not fully tested ye
     var flags = 0;
     if (tracker == null) {
         var low = _pn_messenger_outgoing_tracker(this._messenger);
-        var high = tempRet0;
+        var high = Runtime.getTempRet0();
         tracker = new Data.Long(low, high);
         flags = Module['Messenger'].PN_CUMULATIVE;
     }
@@ -531,12 +531,10 @@ _Messenger_['get'] = function(message) {
     // the high 32 bits via the tempRet0 variable. We use Data.Long to pass the
     // low/high pair around to methods that require a tracker.
     var low = _pn_messenger_incoming_tracker(this._messenger);
-    var high = tempRet0;
+    var high = Runtime.getTempRet0();
 console.log("get low = " + low);
 console.log("get high = " + high);
 
-console.log("get asm = " + asm);
-console.log("get asm['tempRet0'] = " + asm['tempRet0']);
     return new Data.Long(low, high);
 };
 
@@ -577,7 +575,7 @@ console.log("accept: not fully tested ye
     var flags = 0;
     if (tracker == null) {
         var low = _pn_messenger_incoming_tracker(this._messenger);
-        var high = tempRet0;
+        var high = Runtime.getTempRet0();
         tracker = new Data.Long(low, high);
         flags = Module['Messenger'].PN_CUMULATIVE;
     }
@@ -602,7 +600,7 @@ console.log("reject: not fully tested ye
     var flags = 0;
     if (tracker == null) {
         var low = _pn_messenger_incoming_tracker(this._messenger);
-        var high = tempRet0;
+        var high = Runtime.getTempRet0();
         tracker = new Data.Long(low, high);
         flags = Module['Messenger'].PN_CUMULATIVE;
     }
@@ -1237,6 +1235,77 @@ Data['Symbol'].prototype['equals'] = fun
     return this.toString() === rhs.toString();
 };
 
+// ---------------------- JavaScript Number Extensions ------------------------ 
+
+Number.prototype['asUnsignedByte'] = function() {
+    return new Data.TypedNumber('UnsignedByte', this);
+};
+
+Number.prototype['asByte'] = function() {
+    return new Data.TypedNumber('Byte', this);
+};
+
+Number.prototype['asUnsignedShort'] = function() {
+    return new Data.TypedNumber('UnsignedShort', this);
+};
+
+Number.prototype['asShort'] = function() {
+    return new Data.TypedNumber('Short', this);
+};
+
+Number.prototype['asUnsignedInteger'] = function() {
+    return new Data.TypedNumber('UnsignedInteger', this);
+};
+
+Number.prototype['asInteger'] = function() {
+    return new Data.TypedNumber('Integer', this);
+};
+
+Number.prototype['asUnsignedLong'] = function() {
+    return new Data.TypedNumber('UnsignedLong', this);
+};
+
+Number.prototype['asLong'] = function() {
+    return new Data.TypedNumber('Long', this);
+};
+
+Number.prototype['asFloat'] = function() {
+    return new Data.TypedNumber('Float', this);
+};
+
+Number.prototype['asDouble'] = function() {
+    return new Data.TypedNumber('Double', this);
+};
+
+Number.prototype['asChar'] = function() {
+    return new Data.TypedNumber('Char', this);
+};
+
+String.prototype['asChar'] = function() {
+    return new Data.TypedNumber('Char', this.charCodeAt(0));
+};
+
+// ------------------------- proton.Data.TypedNumber -------------------------- 
+/**
+ * Create a proton.Data.TypedNumber.
+ * @classdesc
+ * This class is a simple wrapper class that allows a "type" to be recorded for
+ * a number. The idea is that the JavaScript Number class is extended with extra
+ * methods to allow numbers to be "modified" to TypedNumbers, so for example
+ * 1.0.asFloat() would modify 1.0 by returning a TypedNumber with type = Float
+ * and value = 1. The strings used for type correspond to the names of the Data
+ * put* methods e.g. UnsignedByte, Byte, UnsignedShort, Short, UnsignedInteger,
+ * Integer, UnsignedLong, Long, Float, Double, Char so that the correct method
+ * to call can be easily derived from the TypedNumber's type.
+ * @constructor proton.Data.TypedNumber
+ * @param {string} type the type of the Number.
+ * @param {number} value the most significant word.
+ */
+// Use dot notation as it is a "protected" inner class not exported from the closure.
+Data.TypedNumber = function(type, value) { // Data.TypedNumber Constructor.
+    this.type  = type;
+    this.value = value;
+};
 
 // ----------------------------- proton.Data.Long ----------------------------- 
 /**
@@ -1250,6 +1319,7 @@ Data['Symbol'].prototype['equals'] = fun
  * @param {number} low the least significant word.
  * @param {number} high the most significant word.
  */
+// Use dot notation as it is a "protected" inner class not exported from the closure.
 Data.Long = function(low, high) { // Data.Long Constructor.
     this.low  = low  | 0;  // force into 32 signed bits.
     this.high = high | 0;  // force into 32 signed bits.
@@ -1805,7 +1875,6 @@ _Data_['putInteger'] = function(i) {
  * @param {number} c a single character.
  */
 _Data_['putChar'] = function(c) {
-console.log("putChar not properly implemented yet");
     this._check(_pn_data_put_char(this._data, c));
 };
 
@@ -1850,6 +1919,7 @@ console.log("putTimestamp not properly i
  * @param {number} f a floating point value.
  */
 _Data_['putFloat'] = function(f) {
+console.log("putFloat f = " + f);
     this._check(_pn_data_put_float(this._data, f));
 };
 
@@ -2043,7 +2113,7 @@ _Data_['getBoolean'] = function() {
  * @returns {number} value if the current node is an unsigned byte, returns 0 otherwise.
  */
 _Data_['getUnsignedByte'] = function() {
-    return _pn_data_get_ubyte(this._data);
+    return _pn_data_get_ubyte(this._data) & 0xFF; // & 0xFF converts to unsigned;
 };
 
 /**
@@ -2059,7 +2129,7 @@ _Data_['getByte'] = function() {
  * @return value if the current node is an unsigned short, returns 0 otherwise.
  */
 _Data_['getUnsignedShort'] = function() {
-    return _pn_data_get_ushort(this._data);
+    return _pn_data_get_ushort(this._data) & 0xFFFF; // & 0xFFFF converts to unsigned;
 };
 
 /**
@@ -2077,7 +2147,8 @@ _Data_['getShort'] = function() {
  * @returns {number} value if the current node is an unsigned int, returns 0 otherwise.
  */
 _Data_['getUnsignedInteger'] = function() {
-    return _pn_data_get_uint(this._data);
+    var value = _pn_data_get_uint(this._data);
+    return (value > 0) ? value : 4294967296 + value; // 4294967296 == 2^32
 };
 
 /**
@@ -2092,13 +2163,10 @@ _Data_['getInteger'] = function() {
 /**
  * @method getChar
  * @memberof! proton.Data#
- * @returns {number} value if the current node is a character, returns 0 otherwise.
+ * @returns {string} the character represented by the unicode value of the current node.
  */
-// TODO should this be dealing with strings not numbers?
 _Data_['getChar'] = function() {
-console.log("getChar not properly implemented yet");
-return "character";
-    //return _pn_data_get_char(this._data);
+    return String.fromCharCode(_pn_data_get_char(this._data));
 };
 
 /**
@@ -2107,6 +2175,7 @@ return "character";
  * @returns {number} value if the current node is an unsigned long, returns 0 otherwise.
  */
 _Data_['getUnsignedLong'] = function() {
+console.log("getUnsignedLong");
     return _pn_data_get_ulong(this._data);
 };
 
@@ -2123,7 +2192,7 @@ console.log("getLong");
     // the 64 bit number and Data.Long.toNumber() to convert it back into a
     // JavaScript number.
     var low = _pn_data_get_long(this._data);
-    var high = tempRet0;
+    var high = Runtime.getTempRet0();
     var long = new Data.Long(low, high);
     long = long.toNumber();
 
@@ -2442,8 +2511,12 @@ console.log("obj is quoted String " + qu
         this['putBinary'](obj);
     } else if (obj instanceof Data['Symbol']) {
         this['putSymbol'](obj);
+    } else if (obj instanceof Data.TypedNumber) { // Dot notation used for "protected" inner class.
+        // Call the appropriate serialisation method based upon the numerical type.
+        this['put' + obj.type](obj.value);
     } else if (Data.isNumber(obj)) {
         /**
+         * This block encodes standard JavaScript numbers by making some inferences.
          * Encoding JavaScript numbers is surprisingly complex and has several
          * gotchas. The code here tries to do what the author believes is the
          * most intuitive encoding of the native JavaScript Number. It first
@@ -2454,9 +2527,10 @@ console.log("obj is quoted String " + qu
          * 32 bit Int value. N.B. JavaScript automagically coerces floating
          * point numbers with a zero Fractional Part into an exact integer so
          * numbers like 1.0, 100.0 etc. will be encoded as int or long here,
-         * which is unlikely to be what is wanted. There's no easy way around this
-         * the two main options are to add a very small fractional number or to
-         * represent the number in a String literal e.g. "1.0f", "1.0d", "1l"
+         * which is unlikely to be what is wanted. There's no easy "transparent"
+         * way around this. The TypedNumber approach above allows applications
+         * to express more explicitly what is require, for example 1.0.asFloat()
+         * (1).asUnsignedByte(), (5).asLong() etc.
          */
         if (obj % 1 === 0) {
 console.log(obj + " is Integer Type " + (obj|0));

Added: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE?rev=1591980&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE (added)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE Fri May  2 17:30:42 2014
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/LICENSE
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md?rev=1591980&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md (added)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md Fri May  2 17:30:42 2014
@@ -0,0 +1,4 @@
+qpid-proton
+-----------
+
+apache qpid proton messenger AMQP 1.0 library

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/README.md
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/package.json
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/package.json?rev=1591980&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/package.json (added)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/bindings/javascript/qpid-proton/package.json Fri May  2 17:30:42 2014
@@ -0,0 +1,11 @@
+{
+    "name" : "qpid-proton",
+    "version": "0.7.0",
+    "description": "apache qpid proton messenger AMQP 1.0 library",
+    "repository": {
+        "type": "svn",
+        "url": "https://svn.apache.org/repos/asf/qpid/proton/trunk/"
+    },
+    "main" : "./lib/proton.js",
+    "dependencies": {}
+}

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/messenger/messenger.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/messenger/messenger.c?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/messenger/messenger.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/messenger/messenger.c Fri May  2 17:30:42 2014
@@ -602,6 +602,10 @@ pn_messenger_t *pn_messenger(const char 
        pni_interruptor_finalize);
     pn_list_add(m->pending, m->interruptor);
     m->interrupted = false;
+    // Explicitly initialise pipe file descriptors to invalid values in case pipe
+    // fails, if we don't do this m->ctrl[0] could default to 0 - which is stdin.
+    m->ctrl[0] = -1;
+    m->ctrl[1] = -1;
     pn_pipe(m->io, m->ctrl);
     pni_selectable_set_fd(m->interruptor, m->ctrl[0]);
     pni_selectable_set_context(m->interruptor, m);

Modified: qpid/proton/branches/fadams-javascript-binding/tools/cmake/Modules/FindNodePackages.cmake
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/tools/cmake/Modules/FindNodePackages.cmake?rev=1591980&r1=1591979&r2=1591980&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/tools/cmake/Modules/FindNodePackages.cmake (original)
+++ qpid/proton/branches/fadams-javascript-binding/tools/cmake/Modules/FindNodePackages.cmake Fri May  2 17:30:42 2014
@@ -18,43 +18,51 @@
 #
 
 # FindNodePackages
-# This module finds and installs (optionally) required node.js packages using npm
+# This module finds and installs (using npm) node.js packages that are used by
+# the JavaScript binding. The binding should still compile if these packages
+# cannot be installed but certain features might not work as described below.
+#
 # * The ws package is the WebSocket library used by emscripten when the target is
-#   node.js, it isn't needed for applications hosted on a browser where native 
-#   WebSockets will be used.
+#   node.js, it isn't needed for applications hosted on a browser (where native 
+#   WebSockets will be used), but without it it won't work with node.js.
 #
 # * The jsdoc package is a JavaScript API document generator analogous to Doxygen
 #   or JavaDoc, it is used by the docs target in the JavaScript binding.
 
 if (NOT NODE_PACKAGES_FOUND)
-    # Install ws node.js WebSocket library https://github.com/einaros/ws
-    message(STATUS "Installing node.js ws package")
+    # Check if the specified node.js package is already installed, if not install it.
+    macro(InstallPackage varname name)
+        execute_process(
+            COMMAND npm list --local ${name}
+            OUTPUT_VARIABLE check_package
+        )
+
+        set(${varname} OFF)
+
+        if (check_package MATCHES "${name}@.")
+            message(STATUS "Found node.js package: ${name}")
+            set(${varname} ON)
+        else()
+            message(STATUS "Installing node.js package: ${name}")
+
+            execute_process(
+                COMMAND npm install ${name}
+                WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+                OUTPUT_VARIABLE var
+            )
+
+            if (var)
+                message(STATUS "Installed node.js package: ${name}")
+                set(${varname} ON)
+            endif (var)
+        endif()
+    endmacro()
+
+    # Check if ws WebSocket library https://github.com/einaros/ws is installed
+    InstallPackage("NODE_WS_FOUND" "ws")
 
-    execute_process(
-        COMMAND npm install ws
-        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
-        OUTPUT_VARIABLE var
-    )
-
-    if (var)
-        message(STATUS "Node.js ws package has been installed")
-        set(NODE_WS_FOUND ON)
-    endif (var)
-
-    # Install jsdoc3 API documentation generator for JavaScript https://github.com/jsdoc3/jsdoc
-    message(STATUS "Installing node.js jsdoc package")
-
-    execute_process(
-        COMMAND npm install jsdoc
-        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
-        OUTPUT_VARIABLE var
-    )
-
-    if (var)
-        message(STATUS "Node.js jsdoc package has been installed")
-        set(NODE_JSDOC_FOUND ON)
-        set(JSDOC_EXE ${PROJECT_SOURCE_DIR}/node_modules/.bin/jsdoc)
-    endif (var)
+    # Check if jsdoc3 API documentation generator https://github.com/jsdoc3/jsdoc is installed
+    InstallPackage("NODE_JSDOC_FOUND" "jsdoc")
 
     set(NODE_PACKAGES_FOUND ON)
 endif (NOT NODE_PACKAGES_FOUND)



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org