Update Javascript GLV

Address feedback and provide maven integration:
- Reorganize gremlin-javascript into node.js project
- Simplify javascript code generators
- Generate package.json to match project version
- Introduce Promise factory for third-party promise library integration (ie: 
bluebird)
- Use toList() and next() traversal methods
- Include Remote connection implementation
- Fix enum casing
- Use Maven nodejs plugin
- .gitignore and .npmignore at gremlin-javascript level
- Run integration tests using a gremlin-server instance
- Add gremlin-javascript doc in gremlin-variants.asciidoc


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/2b4e8e3b
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/2b4e8e3b
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/2b4e8e3b

Branch: refs/heads/tp32
Commit: 2b4e8e3b517098dd29b3cfd1ed48f066eb120d66
Parents: e94d415
Author: Jorge Bay Gondra <jorgebaygon...@gmail.com>
Authored: Tue Jun 6 15:05:14 2017 +0200
Committer: Jorge Bay Gondra <jorgebaygon...@gmail.com>
Committed: Fri Jan 19 09:30:14 2018 +0100

----------------------------------------------------------------------
 docs/src/reference/gremlin-variants.asciidoc    |   75 +-
 gremlin-javascript/pom.xml                      |  171 +-
 .../javascript/GenerateGremlinJavascript.groovy |   36 +
 .../GraphTraversalSourceGenerator.groovy        |  226 +-
 .../javascript/PackageJsonGenerator.groovy      |   72 +
 .../gremlin/javascript/SymbolHelper.groovy      |   50 +
 .../javascript/TraversalSourceGenerator.groovy  |  437 ++--
 .../javascript/GenerateGremlinJavascript.java   |   32 -
 .../gremlin/javascript/jsr223/SymbolHelper.java |   59 -
 .../javascript/gremlin-javascript/.gitignore    |    5 +
 .../javascript/gremlin-javascript/.npmignore    |   26 +
 .../javascript/gremlin-javascript/README.md     |   39 +
 .../driver/remote-connection.js                 |  107 -
 .../main/javascript/gremlin-javascript/index.js |  113 +-
 .../lib/driver/driver-remote-connection.js      |  200 ++
 .../lib/driver/remote-connection.js             |   84 +
 .../gremlin-javascript/lib/process/bytecode.js  |   99 +
 .../lib/process/graph-traversal.js              | 2095 ++++++++++++++++++
 .../lib/process/traversal-strategy.js           |   88 +
 .../gremlin-javascript/lib/process/traversal.js |  236 ++
 .../gremlin-javascript/lib/structure/graph.js   |  138 ++
 .../lib/structure/io/graph-serializer.js        |  398 ++++
 .../javascript/gremlin-javascript/lib/utils.js  |   62 +
 .../javascript/gremlin-javascript/package.json  |   36 +
 .../process/graph-traversal.js                  | 2016 -----------------
 .../gremlin-javascript/process/traversal.js     |  392 ----
 .../gremlin-javascript/structure/graph.js       |  157 --
 .../structure/io/graph-serializer.js            |  415 ----
 .../test/integration/remote-connection-tests.js |   64 +
 .../test/integration/traversal-test.js          |   71 +
 .../test/unit/exports-test.js                   |   73 +
 .../test/unit/graphson-test.js                  |  112 +
 .../test/unit/traversal-test.js                 |  119 +
 .../javascript/gremlin-javascript/helper.js     |   84 -
 .../gremlin-javascript/test-exports.js          |   87 -
 .../gremlin-javascript/test-graphson.js         |  108 -
 .../gremlin-javascript/test-traversal.js        |   69 -
 pom.xml                                         |    4 +
 38 files changed, 4624 insertions(+), 4031 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc 
b/docs/src/reference/gremlin-variants.asciidoc
index 0c48c97..76952eb 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -392,8 +392,8 @@ g.V().Repeat(Out()).Times(2).Values("name").Fold().ToList()
 
 === Bindings
 
-When a traversal bytecode is sent over a `IRemoteConnection` (e.g. Gremlin 
Server), it will be translated, compiled, 
-and then executed. If the same traversal is sent again, translation and 
compilation can be skipped as the previously 
+When a traversal bytecode is sent over a `IRemoteConnection` (e.g. Gremlin 
Server), it will be translated, compiled,
+and then executed. If the same traversal is sent again, translation and 
compilation can be skipped as the previously
 compiled version should be cached. Many traversals are unique up to some 
parameterization. For instance,
 `g.V(1).Out("created").Values("name")` is considered different from 
`g.V(4).Out("created").Values("Name")`
 as they have different script "string" representations. However, 
`g.V(x).Out("created").Values("name")` with bindings of 
@@ -422,7 +422,7 @@ g = g.WithoutStrategies(typeof(SubgraphStrategy));
 names = g.V().Values("name").ToList(); // names: [marko, vadas, lop, josh, 
ripple, peter]
 
 var edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
-// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, 
weight:0.5], [label:knows, id:8, weight:1.0], 
+// edgeValueMaps: [[label:created, id:9, weight:0.4], [label:knows, id:7, 
weight:0.5], [label:knows, id:8, weight:1.0],
 //     [label:created, id:10, weight:1.0], [label:created, id:11, weight:0.4], 
[label:created, id:12, weight:0.2]]
 
 g = g.WithComputer(workers: 2, vertices: Has("name", "marko"));
@@ -435,3 +435,72 @@ edgeValueMaps = g.V().OutE().ValueMap(true).ToList();
 NOTE: Many of the TraversalStrategy classes in Gremlin.Net are proxies to the 
respective strategy on Apache TinkerPop’s
 JVM-based Gremlin traversal machine. As such, their `Apply(ITraversal)` method 
does nothing. However, the strategy is
 encoded in the Gremlin.Net bytecode and transmitted to the Gremlin traversal 
machine for re-construction machine-side.
+
+[[gremlin-javascript]]
+== Gremlin-JavaScript
+
+
+Apache TinkerPop's Gremlin-JavaScript implements Gremlin within the JavaScript 
language. It targets Node.js runtime
+and can be used on different operating systems on any Node.js 4 or above. 
Since the JavaScript naming conventions are
+very similar to that of Java, it should be very easy to switch between 
Gremlin-Java and Gremlin-JavaScript.
+
+[source,bash]
+npm install gremlin-javascript
+
+In Gremlin-JavaScript there exists `GraphTraversalSource`, `GraphTraversal`, 
and `__` which mirror the respective classes
+in Gremlin-Java. The `GraphTraversalSource` requires a RemoteConnection 
implementation in order to communicate with
+<<gremlin-server,GremlinServer>>.
+
+A traversal source can be spawned with `RemoteStrategy` from an empty `Graph`.
+
+[source,javascript]
+----
+const graph = new Graph();
+const g = graph.traversal().withRemote(new 
DriverRemoteConnection('ws://localhost:8182/gremlin'));
+----
+
+When a traversal from the `GraphTraversalSource` is iterated, the 
traversal’s `Bytecode` is sent over the wire via
+the registered `RemoteConnection`. The bytecode is used to construct the 
equivalent traversal at the remote
+traversal source.
+
+Since Gremlin-JavaScript currently doesn't support lambda expressions, all 
traversals can be translated to
+Gremlin-Java on the remote location (e.g. Gremlin Server).
+
+IMPORTANT: Gremlin-JavaScript’s `Traversal` base class supports the standard 
Gremlin methods such as `next()` and
+`toList()` Such "terminal" methods trigger the evaluation of the traversal.
+
+=== RemoteConnection Submission
+
+Very similar to Gremlin-Python and Gremlin-Java, there are various ways to 
submit a traversal to a
+`RemoteConnection` using terminal/action methods off of `Traversal`.
+
+* `Traversal.next()`
+* `Traversal.toList()`
+
+=== Static Enums and Methods
+
+Gremlin has various tokens (e.g. `t`, `P`, `order`, `direction`, etc.) that 
are represented in Gremlin-JavaScript as
+objects.
+
+These can be used analogously to how they are used in Gremlin-Java.
+
+[source,javascript]
+g.V().hasLabel("person").has("age",P.gt(30)).Order().By("age", 
order.decr).toList()
+
+These objects must be required manually from the `process` namespace:
+
+[source,javascript]
+----
+const gremlin = require('gremlin-javascript');
+const P = gremlin.process.P;
+----
+
+Finally, using static `__` anonymous traversals like `__.out()` can be 
expressed as below:
+
+[source,javascript]
+----
+const gremlin = require('gremlin-javascript');
+const __ = gremlin.process.statics;
+
+g.V().repeat(__.out()).times(2).values("name").fold().toList();
+----

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-javascript/pom.xml b/gremlin-javascript/pom.xml
index b9b78cc..1c9ffcc 100644
--- a/gremlin-javascript/pom.xml
+++ b/gremlin-javascript/pom.xml
@@ -37,6 +37,7 @@ limitations under the License.
             <version>${groovy.version}</version>
             <classifier>indy</classifier>
         </dependency>
+        <!-- TESTING -->
         <dependency>
             <groupId>org.apache.tinkerpop</groupId>
             <artifactId>tinkergraph-gremlin</artifactId>
@@ -58,12 +59,10 @@ limitations under the License.
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
-            <version>${slf4j.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
     <properties>
-        <!-- provides a way to convert maven.test.skip value to skipTests for 
use in skipping python tests -->
         <maven.test.skip>false</maven.test.skip>
         <skipTests>${maven.test.skip}</skipTests>
         
<gremlin.server.dir>${project.parent.basedir}/gremlin-server</gremlin.server.dir>
@@ -86,33 +85,92 @@ limitations under the License.
                         <configuration>
                             
<mainClass>org.apache.tinkerpop.gremlin.javascript.GenerateGremlinJavascript</mainClass>
                             <arguments>
-                                
<argument>${basedir}/src/main/javascript/gremlin-javascript/process/traversal.js</argument>
-                                
<argument>${basedir}/src/main/javascript/gremlin-javascript/process/graph-traversal.js</argument>
+                                <argument>${project.version}</argument>
+                                <argument>${basedir}</argument>
                             </arguments>
                         </configuration>
                     </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.gmavenplus</groupId>
+                <artifactId>gmavenplus-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>log4j</groupId>
+                        <artifactId>log4j</artifactId>
+                        <version>1.2.17</version>
+                        <scope>runtime</scope>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.apache.tinkerpop</groupId>
+                        <artifactId>gremlin-server</artifactId>
+                        <version>${project.version}</version>
+                        <scope>runtime</scope>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.codehaus.groovy</groupId>
+                        <artifactId>groovy-ant</artifactId>
+                        <version>${groovy.version}</version>
+                    </dependency>
+                </dependencies>
+                <executions>
                     <execution>
-                        <id>js-tests</id>
-                        <phase>test</phase>
+                        <id>gremlin-server-start</id>
+                        <phase>pre-integration-test</phase>
                         <goals>
-                            <goal>exec</goal>
+                            <goal>execute</goal>
                         </goals>
                         <configuration>
-                            <executable>jjs</executable>
-                            <arguments>
-                                
<argument>${basedir}/src/test/javascript/gremlin-javascript/test-exports.js</argument>
-                                
<argument>${basedir}/src/test/javascript/gremlin-javascript/test-graphson.js</argument>
-                                
<argument>${basedir}/src/test/javascript/gremlin-javascript/test-traversal.js</argument>
-                            </arguments>
+                            <scripts>
+                                <script>
+                                    <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+import org.apache.tinkerpop.gremlin.server.Settings
+import org.apache.tinkerpop.gremlin.server.Settings.ScriptEngineSettings
+import org.apache.tinkerpop.gremlin.server.op.session.Session
+
+if (${skipIntegrationTests}) return
+log.info("Starting Gremlin Server instances for native testing of 
gremlin-javascript")
+def settings = 
Settings.read("${gremlin.server.dir}/conf/gremlin-server-modern.yaml")
+settings.graphs.graph = 
"${gremlin.server.dir}/conf/tinkergraph-empty.properties"
+settings.scriptEngines["gremlin-groovy"].scripts = 
["${gremlin.server.dir}/scripts/generate-modern.groovy"]
+settings.port = 45950
+def server = new GremlinServer(settings)
+server.start().join()
+project.setContextValue("gremlin.javascript.server", server)
+log.info("Gremlin Server started on port 45950")
+]]>
+                                </script>
+                            </scripts>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>gremlin-server-stop</id>
+                        <phase>post-integration-test</phase>
+                        <goals>
+                            <goal>execute</goal>
+                        </goals>
+                        <configuration>
+                            <scripts>
+                                <script>
+                                    <![CDATA[
+import org.apache.tinkerpop.gremlin.server.GremlinServer
+import org.apache.tinkerpop.gremlin.server.op.session.Session
+
+if (${skipIntegrationTests}) return
+log.info("Tests for native gremlin-javascript complete")
+def server = project.getContextValue("gremlin.javascript.server")
+log.info("Shutting down $server")
+server.stop().join()
+]]>
+                                </script>
+                            </scripts>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>
             <plugin>
-                <groupId>org.codehaus.gmavenplus</groupId>
-                <artifactId>gmavenplus-plugin</artifactId>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-clean-plugin</artifactId>
                 <version>3.0.0</version>
@@ -124,6 +182,85 @@ limitations under the License.
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>com.github.eirslett</groupId>
+                <artifactId>frontend-maven-plugin</artifactId>
+                <version>1.4</version>
+                <executions>
+                    <execution>
+                        <id>install node and npm</id>
+                        <goals>
+                            <goal>install-node-and-npm</goal>
+                        </goals>
+                        <phase>generate-test-resources</phase>
+                    </execution>
+                    <execution>
+                        <id>npm install</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>generate-test-resources</phase>
+                        <configuration>
+                            <arguments>install</arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>npm test</id>
+                        <goals>
+                            <goal>npm</goal>
+                        </goals>
+                        <phase>integration-test</phase>
+                        <configuration>
+                            <arguments>test</arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+                <configuration>
+                    <skip>${skipIntegrationTests}</skip>
+                    
<workingDirectory>src/main/javascript/gremlin-javascript</workingDirectory>
+                    <nodeVersion>v4.8.3</nodeVersion>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
+    <profiles>
+        <!--
+        Provides a way to deploy the gremlin-javascript GLV to npm. This 
cannot be part of the standard maven execution
+        because npm does not have a staging environment like sonatype for 
releases. As soon as the release is
+        published it is public. In our release workflow, deploy occurs prior 
to vote on the release and we can't
+        make this stuff public until the vote is over.
+        -->
+        <profile>
+            <id>glv-javascript-deploy</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>com.github.eirslett</groupId>
+                        <artifactId>frontend-maven-plugin</artifactId>
+                        <version>1.4</version>
+                        <executions>
+                            <execution>
+                                <id>npm publish</id>
+                                <phase>deploy</phase>
+                                <goals>
+                                    <goal>npm</goal>
+                                </goals>
+                                <configuration>
+                                    <arguments>publish</arguments>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <skip>${skipIntegrationTests}</skip>
+                            
<workingDirectory>src/main/javascript/gremlin-javascript</workingDirectory>
+                            <nodeVersion>v4.8.3</nodeVersion>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy
 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy
new file mode 100644
index 0000000..ab9eaf1
--- /dev/null
+++ 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy
@@ -0,0 +1,36 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript
+
+public class GenerateGremlinJavascript {
+    public static void main(String[] args) {
+        String projectVersion = args[0];
+        final String baseDir = args[1];
+        final String jsModuleDir = 
"${baseDir}/src/main/javascript/gremlin-javascript";
+        Integer versionSnapshotIndex = projectVersion.indexOf("-SNAPSHOT");
+        if (versionSnapshotIndex > 0) {
+            // Use a alpha version x.y.z-alpha1
+            projectVersion = projectVersion.substring(0, versionSnapshotIndex) 
+ "-alpha1";
+        }
+        
TraversalSourceGenerator.create("$jsModuleDir/lib/process/traversal.js");
+        
GraphTraversalSourceGenerator.create("$jsModuleDir/lib/process/graph-traversal.js");
+        PackageJsonGenerator.create("$jsModuleDir/package.json", 
projectVersion);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
index 0ae6079..3227f2c 100644
--- 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
+++ 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
@@ -23,7 +23,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
 import 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
-import org.apache.tinkerpop.gremlin.javascript.jsr223.SymbolHelper
+import org.apache.tinkerpop.gremlin.javascript.SymbolHelper
 
 import java.lang.reflect.Modifier
 
@@ -63,45 +63,46 @@ class GraphTraversalSourceGenerator {
 /**
  * @author Jorge Bay Gondra
  */
-(function defineGraphTraversalModule() {
-  "use strict";
-
-  var t = loadModule.call(this, './traversal.js');
-  var remote = loadModule.call(this, '../driver/remote-connection.js');
-  var Bytecode = t.Bytecode;
-  var inherits = t.inherits;
-  var parseArgs = t.parseArgs;
-
-  /**
-   *
-   * @param {Graph} graph
-   * @param {TraversalStrategies} traversalStrategies
-   * @param {Bytecode} [bytecode]
-   * @constructor
-   */
-  function GraphTraversalSource(graph, traversalStrategies, bytecode) {
-    this.graph = graph;
-    this.traversalStrategies = traversalStrategies;
-    this.bytecode = bytecode || new Bytecode();
-  }
-
-  /**
-   * @param remoteConnection
-   * @returns {GraphTraversalSource}
-   */
-  GraphTraversalSource.prototype.withRemote = function (remoteConnection) {
-    var traversalStrategy = new 
t.TraversalStrategies(this.traversalStrategies);
-    traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection));
-    return new GraphTraversalSource(this.graph, traversalStrategy, new 
Bytecode(this.bytecode));
-  };
-
-  /**
-   * Returns the string representation of the GraphTraversalSource.
-   * @returns {string}
-   */
-  GraphTraversalSource.prototype.toString = function () {
-    return 'graphtraversalsource[' + this.graph.toString() + ']';
-  };
+'use strict';
+
+var t = require('./traversal.js');
+var remote = require('../driver/remote-connection');
+var utils = require('../utils');
+var Bytecode = require('./bytecode');
+var TraversalStrategies = require('./traversal-strategy').TraversalStrategies;
+var inherits = utils.inherits;
+var parseArgs = utils.parseArgs;
+
+/**
+ *
+ * @param {Graph} graph
+ * @param {TraversalStrategies} traversalStrategies
+ * @param {Bytecode} [bytecode]
+ * @constructor
+ */
+function GraphTraversalSource(graph, traversalStrategies, bytecode) {
+  this.graph = graph;
+  this.traversalStrategies = traversalStrategies;
+  this.bytecode = bytecode || new Bytecode();
+}
+
+/**
+ * @param remoteConnection
+ * @returns {GraphTraversalSource}
+ */
+GraphTraversalSource.prototype.withRemote = function (remoteConnection) {
+  var traversalStrategy = new TraversalStrategies(this.traversalStrategies);
+  traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection));
+  return new GraphTraversalSource(this.graph, traversalStrategy, new 
Bytecode(this.bytecode));
+};
+
+/**
+ * Returns the string representation of the GraphTraversalSource.
+ * @returns {string}
+ */
+GraphTraversalSource.prototype.toString = function () {
+  return 'graphtraversalsource[' + this.graph.toString() + ']';
+};
 """)
         GraphTraversalSource.getMethods(). // SOURCE STEPS
                 findAll { GraphTraversalSource.class.equals(it.returnType) }.
@@ -110,40 +111,40 @@ class GraphTraversalSourceGenerator {
                             
!it.name.equals(TraversalSource.Symbols.withBindings) &&
                             !it.name.equals(TraversalSource.Symbols.withRemote)
                 }.
-                collect { SymbolHelper.toJs(it.name) }.
+                collect { it.name }.
                 unique().
                 sort { a, b -> a <=> b }.
-                forEach { method ->
+                forEach { methodName ->
                     moduleOutput.append(
                             """
-  /**
-   * ${method} GraphTraversalSource method.
-   * @param {...Object} args
-   * @returns {GraphTraversalSource}
-   */
-  GraphTraversalSource.prototype.${method} = function (args) {
-    var b = new 
Bytecode(this.bytecode).addSource('${SymbolHelper.toJava(method)}', 
parseArgs.apply(null, arguments));
-    return new GraphTraversalSource(this.graph, new 
t.TraversalStrategies(this.traversalStrategies), b);
-  };
+/**
+ * Graph Traversal Source ${methodName} method.
+ * @param {...Object} args
+ * @returns {GraphTraversalSource}
+ */
+GraphTraversalSource.prototype.${SymbolHelper.toJs(methodName)} = function 
(args) {
+  var b = new Bytecode(this.bytecode).addSource('$methodName', 
parseArgs.apply(null, arguments));
+  return new GraphTraversalSource(this.graph, new 
TraversalStrategies(this.traversalStrategies), b);
+};
 """)
                 }
-        GraphTraversalSource.getMethods(). // SPAWN STEPS
+        GraphTraversalSource.getMethods().
                 findAll { GraphTraversal.class.equals(it.returnType) }.
-                collect { SymbolHelper.toJs(it.name) }.
+                collect { it.name }.
                 unique().
                 sort { a, b -> a <=> b }.
-                forEach { method ->
+                forEach { methodName ->
                     moduleOutput.append(
                             """
-  /**
-   * ${method} GraphTraversalSource step method.
-   * @param {...Object} args
-   * @returns {GraphTraversal}
-   */
-  GraphTraversalSource.prototype.${method} = function (args) {
-    var b = new 
Bytecode(this.bytecode).addStep('${SymbolHelper.toJava(method)}', 
parseArgs.apply(null, arguments));
-    return new GraphTraversal(this.graph, new 
t.TraversalStrategies(this.traversalStrategies), b);
-  };
+/**
+ * $methodName GraphTraversalSource step method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+GraphTraversalSource.prototype.${SymbolHelper.toJs(methodName)} = function 
(args) {
+  var b = new Bytecode(this.bytecode).addStep('$methodName', 
parseArgs.apply(null, arguments));
+  return new GraphTraversal(this.graph, new 
TraversalStrategies(this.traversalStrategies), b);
+};
 """)
                 }
 ////////////////////
@@ -151,34 +152,35 @@ class GraphTraversalSourceGenerator {
 ////////////////////
         moduleOutput.append(
                 """
-  /**
-   * Represents a graph traversal.
-   * @extends Traversal
-   * @constructor
-   */
-  function GraphTraversal(graph, traversalStrategies, bytecode) {
-    t.Traversal.call(this, graph, traversalStrategies, bytecode);
-  }
-
-  inherits(GraphTraversal, t.Traversal);
+/**
+ * Represents a graph traversal.
+ * @extends Traversal
+ * @constructor
+ */
+function GraphTraversal(graph, traversalStrategies, bytecode) {
+  t.Traversal.call(this, graph, traversalStrategies, bytecode);
+}
+
+inherits(GraphTraversal, t.Traversal);
 """)
         GraphTraversal.getMethods().
                 findAll { GraphTraversal.class.equals(it.returnType) }.
                 findAll { !it.name.equals("clone") && 
!it.name.equals("iterate") }.
-                collect { SymbolHelper.toJs(it.name) }.
+                collect { it.name }.
                 unique().
                 sort { a, b -> a <=> b }.
-                forEach { method ->
+                forEach { methodName ->
                     moduleOutput.append(
                             """
-  /**
-   * @param {...Object} args
-   * @returns {GraphTraversal}
-   */
-  GraphTraversal.prototype.${method} = function (args) {
-    this.bytecode.addStep('${SymbolHelper.toJava(method)}', 
parseArgs.apply(null, arguments));
-    return this;
-  };
+/**
+ * Graph traversal $methodName method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+GraphTraversal.prototype.${SymbolHelper.toJs(methodName)} = function (args) {
+  this.bytecode.addStep('$methodName', parseArgs.apply(null, arguments));
+  return this;
+};
 """)
                 };
 
@@ -186,11 +188,11 @@ class GraphTraversalSourceGenerator {
 // AnonymousTraversal //
 ////////////////////////
         moduleOutput.append("""
-  /**
-   * Contains the static method definitions
-   * @type {Object}
-   */
-  var statics = {};
+/**
+ * Contains the static method definitions
+ * @type {Object}
+ */
+var statics = {};
 """);
         __.class.getMethods().
                 findAll { GraphTraversal.class.equals(it.returnType) }.
@@ -202,44 +204,24 @@ class GraphTraversalSourceGenerator {
                 forEach { method ->
                     moduleOutput.append(
                             """
-  /**
-   * ${method}() static method
-   * @param {...Object} args
-   * @returns {GraphTraversal}
-   */
-  statics.${method} = function (args) {
-    var g = new GraphTraversal(null, null, new Bytecode());
-    return g.${method}.apply(g, arguments);
-  };
+/**
+ * ${method}() static method
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+statics.${method} = function (args) {
+  var g = new GraphTraversal(null, null, new Bytecode());
+  return g.${method}.apply(g, arguments);
+};
 """)
                 };
 
         moduleOutput.append("""
-  function loadModule(moduleName) {
-    if (typeof require !== 'undefined') {
-      return require(moduleName);
-    }
-    if (typeof load !== 'undefined') {
-      var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
-      this.__dependencies = this.__dependencies || {};
-      return this.__dependencies[path] = (this.__dependencies[path] || 
load(path));
-    }
-    throw new Error('No module loader was found');
-  }
-
-  var toExport = {
-    GraphTraversal: GraphTraversal,
-    GraphTraversalSource: GraphTraversalSource,
-    statics: statics
-  };
-  if (typeof module !== 'undefined') {
-    // CommonJS
-    module.exports = toExport;
-    return;
-  }
-  // Nashorn and rest
-  return toExport;
-}).call(this);""")
+module.exports = {
+  GraphTraversal: GraphTraversal,
+  GraphTraversalSource: GraphTraversalSource,
+  statics: statics
+};""");
 
         // save to file
         final File file = new File(graphTraversalSourceFile);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy
 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy
new file mode 100644
index 0000000..4b4d012
--- /dev/null
+++ 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy
@@ -0,0 +1,72 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript
+
+/**
+ * @author Jorge Bay Gondra
+ */
+class PackageJsonGenerator {
+
+    public static void create(final String traversalSourceFile, final String 
version) {
+
+        final StringBuilder moduleOutput = new StringBuilder();
+        moduleOutput.append("""{
+  "name": "gremlin-javascript",
+  "version": "${version}",
+  "description": "JavaScript Gremlin Language Variant",
+  "author": "Apache TinkerPop team",
+  "keywords": [
+    "graph",
+    "gremlin",
+    "tinkerpop",
+    "connection",
+    "glv",
+    "driver",
+    "graphdb"
+  ],
+  "license": "Apache-2.0",
+  "dependencies": {
+    "ws": "^3.0.0"
+  },
+  "devDependencies": {
+    "mocha": ">= 1.14.0"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/apache/tinkerpop.git";
+  },
+  "bugs": {
+    "url": "https://issues.apache.org/jira/browse/TINKERPOP";
+  },
+  "scripts": {
+    "test": "./node_modules/.bin/mocha test --recursive -t 5000",
+    "unit-test": "./node_modules/.bin/mocha test/unit"
+  },
+  "engines": {
+    "node": ">=4"
+  }
+}"""    );
+
+        // save to a file
+        final File file = new File(traversalSourceFile);
+        file.delete()
+        moduleOutput.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy
 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy
new file mode 100644
index 0000000..ed45cdb
--- /dev/null
+++ 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy
@@ -0,0 +1,50 @@
+/*
+ *  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.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript
+
+/**
+ * @author Jorge Bay Gondra
+ */
+public final class SymbolHelper {
+
+    private final static Map<String, String> TO_JS_MAP = new HashMap<>();
+
+    static {
+        TO_JS_MAP.put("in", "in_");
+        TO_JS_MAP.put("from", "from_");
+    }
+
+    private SymbolHelper() {
+        // static methods only, do not instantiate
+    }
+
+    public static String toJs(final String symbol) {
+        return TO_JS_MAP.getOrDefault(symbol, symbol);
+    }
+
+    public static String decapitalize(String string) {
+        if (string == null || string.length() == 0) {
+            return string;
+        }
+        def c = string.toCharArray();
+        c[0] = Character.toLowerCase(c[0]);
+        return new String(c);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
index d5899f0..f3405c3 100644
--- 
a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
+++ 
b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
@@ -21,7 +21,6 @@ package org.apache.tinkerpop.gremlin.javascript
 
 import org.apache.tinkerpop.gremlin.process.traversal.P
 import org.apache.tinkerpop.gremlin.util.CoreImports
-import org.apache.tinkerpop.gremlin.javascript.jsr223.SymbolHelper
 
 import java.lang.reflect.Modifier
 
@@ -57,334 +56,178 @@ class TraversalSourceGenerator {
 /**
  * @author Jorge Bay Gondra
  */
-(function defineTraversalModule() {
-  "use strict";
-
-  function Traversal(graph, traversalStrategies, bytecode) {
-    this.graph = graph;
-    this.traversalStrategies = traversalStrategies;
-    this.bytecode = bytecode;
-    this.traversers = null;
-    this.sideEffects = null;
-  }
+'use strict';
+
+var utils = require('../utils');
+var parseArgs = utils.parseArgs;
+var itemDone = Object.freeze({ value: null, done: true });
+var emptyArray = Object.freeze([]);
+
+function Traversal(graph, traversalStrategies, bytecode) {
+  this.graph = graph;
+  this.traversalStrategies = traversalStrategies;
+  this.bytecode = bytecode;
+  this.traversers = null;
+  this.sideEffects = null;
+  this._traversalStrategiesPromise = null;
+  this._traversersIteratorIndex = 0;
+}
 
-  /** @returns {Bytecode} */
-  Traversal.prototype.getBytecode = function () {
-    return this.bytecode;
-  };
+/** @returns {Bytecode} */
+Traversal.prototype.getBytecode = function () {
+  return this.bytecode;
+};
 
-  /** @param {Function} callback */
-  Traversal.prototype.list = function (callback) {
-    var self = this;
-    this.traversalStrategies.applyStrategies(this, function (err) {
-      if (err) {
-        return callback(err);
-      }
-      callback(err, self.traversers);
-    });
-  };
+/**
+ * Returns an Array containing the traverser objects.
+ * @returns {Promise.<Array>}
+ */
+Traversal.prototype.toList = function () {
+  var self = this;
+  return this._applyStrategies().then(function () {
+    if (!self.traversers || self._traversersIteratorIndex === 
self.traversers.length) {
+      return emptyArray;
+    }
+    var arr = new Array(self.traversers.length - 
self._traversersIteratorIndex);
+    for (var i = self._traversersIteratorIndex; i < self.traversers.length; 
i++) {
+      arr[i] = self.traversers[i].object;
+    }
+    self._traversersIteratorIndex = self.traversers.length;
+    return arr;
+  });
+};
 
-  /** @param {Function} callback */
-  Traversal.prototype.one = function (callback) {
-    this.list(function (err, result) {
-      callback(err, result && result.length > 0 ? result[0] : null);
-    });
-  };
+/**
+ * Async iterator method implementation.
+ * Returns a promise containing an iterator item.
+ * @returns {Promise.<{value, done}>}
+ */
+Traversal.prototype.next = function () {
+  var self = this;
+  return this._applyStrategies().then(function () {
+    if (!self.traversers || self._traversersIteratorIndex === 
self.traversers.length) {
+      return itemDone;
+    }
+    return { value: self.traversers[self._traversersIteratorIndex++].object, 
done: false };
+  });
+};
+
+Traversal.prototype._applyStrategies = function () {
+  if (this._traversalStrategiesPromise) {
+    // Apply strategies only once
+    return this._traversalStrategiesPromise;
+  }
+  return this._traversalStrategiesPromise = 
this.traversalStrategies.applyStrategies(this);
+};
 
-  /**
-   * Returns the Bytecode JSON representation of the traversal
-   * @returns {String}
-   */
-  Traversal.prototype.toString = function () {
-    return this.bytecode.toString();
-  };
+/**
+ * Returns the Bytecode JSON representation of the traversal
+ * @returns {String}
+ */
+Traversal.prototype.toString = function () {
+  return this.bytecode.toString();
+};
   """);
 
         moduleOutput.append("""
-  /**
-   * Represents an operation.
-   * @constructor
-   */
-  function P(operator, value, other) {
-    this.operator = operator;
-    this.value = value;
-    this.other = other;
-  }
-
-  /**
-   * Returns the string representation of the instance.
-   * @returns {string}
-   */
-  P.prototype.toString = function () {
-    if (this.other === undefined) {
-      return this.operator + '(' + this.value + ')';
-    }
-    return this.operator + '(' + this.value + ', ' + this.other + ')';
-  };
+/**
+ * Represents an operation.
+ * @constructor
+ */
+function P(operator, value, other) {
+  this.operator = operator;
+  this.value = value;
+  this.other = other;
+}
 
-  function createP(operator, args) {
-    args.unshift(null, operator);
-    return new (Function.prototype.bind.apply(P, args));
+/**
+ * Returns the string representation of the instance.
+ * @returns {string}
+ */
+P.prototype.toString = function () {
+  if (this.other === undefined) {
+    return this.operator + '(' + this.value + ')';
   }
+  return this.operator + '(' + this.value + ', ' + this.other + ')';
+};
+
+function createP(operator, args) {
+  args.unshift(null, operator);
+  return new (Function.prototype.bind.apply(P, args));
+}
 """)
         P.class.getMethods().
                 findAll { Modifier.isStatic(it.getModifiers()) }.
                 findAll { P.class.isAssignableFrom(it.returnType) }.
-                collect { SymbolHelper.toJs(it.name) }.
+                collect { it.name }.
                 unique().
                 sort { a, b -> a <=> b }.
-                each { method ->
+                each { methodName ->
                     moduleOutput.append(
                             """
-  /** @param {...Object} args */
-  P.${method} = function (args) {
-    return createP('${SymbolHelper.toJava(method)}', parseArgs.apply(null, 
arguments));
-  };
+/** @param {...Object} args */
+P.${SymbolHelper.toJs(methodName)} = function (args) {
+  return createP('$methodName', parseArgs.apply(null, arguments));
+};
 """)
                 };
         moduleOutput.append("""
-  P.prototype.and = function (arg) {
-    return new P('and', this, arg);
-  };
+P.prototype.and = function (arg) {
+  return new P('and', this, arg);
+};
 
-  P.prototype.or = function (arg) {
-    return new P('or', this, arg);
-  };
+P.prototype.or = function (arg) {
+  return new P('or', this, arg);
+};
 """)
 
         moduleOutput.append("""
-  function Traverser(object, bulk) {
-    this.object = object;
-    this.bulk = bulk == undefined ? 1 : bulk;
-  }
-
-  function TraversalSideEffects() {
-
-  }
-
-  /**
-   * Creates a new instance of TraversalStrategies.
-   * @param {TraversalStrategies} [traversalStrategies]
-   * @constructor
-   */
-  function TraversalStrategies(traversalStrategies) {
-    /** @type {Array<TraversalStrategy>} */
-    this.strategies = traversalStrategies ? traversalStrategies.strategies : 
[];
-  }
-
-  /** @param {TraversalStrategy} strategy */
-  TraversalStrategies.prototype.addStrategy = function (strategy) {
-    this.strategies.push(strategy);
-  };
-
-  /**
-   * @param {Traversal} traversal
-   * @param {Function} callback
-   */
-  TraversalStrategies.prototype.applyStrategies = function (traversal, 
callback) {
-    eachSeries(this.strategies, function eachStrategy(s, next) {
-      s.apply(traversal, next);
-    }, callback);
-  };
-
-  /**
-   * @abstract
-   * @constructor
-   */
-  function TraversalStrategy() {
-
-  }
-
-  /**
-   * @abstract
-   * @param {Traversal} traversal
-   * @param {Function} callback
-   */
-  TraversalStrategy.prototype.apply = function (traversal, callback) {
-
-  };
-
-  /**
-   * Creates a new instance of Bytecode
-   * @param {Bytecode} [toClone]
-   * @constructor
-   */
-  function Bytecode(toClone) {
-    this._bindings = {};
-    if (!toClone) {
-      this.sourceInstructions = [];
-      this.stepInstructions = [];
-    }
-    else {
-      this.sourceInstructions = toClone.sourceInstructions.slice(0);
-      this.stepInstructions = toClone.sourceInstructions.slice(0);
-    }
-  }
-
-  /**
-   * Adds a new source instructions
-   * @param {String} name
-   * @param {Array} values
-   * @returns {Bytecode}
-   */
-  Bytecode.prototype.addSource = function (name, values) {
-    if (name === undefined) {
-      throw new Error('Name is not defined');
-    }
-    var instruction = new Array(values.length + 1);
-    instruction[0] = name;
-    for (var i = 0; i < values.length; ++i) {
-      instruction[i + 1] = this._convertToArgument(values[i]);
-    }
-    this.sourceInstructions.push(this._generateInstruction(name, values));
-    return this;
-  };
-
-  /**
-   * Adds a new step instructions
-   * @param {String} name
-   * @param {Array} values
-   * @returns {Bytecode}
-   */
-  Bytecode.prototype.addStep = function (name, values) {
-    if (name === undefined) {
-      throw new Error('Name is not defined');
-    }
-    this.stepInstructions.push(this._generateInstruction(name, values));
-    return this;
-  };
-
-  Bytecode.prototype._generateInstruction = function (name, values) {
-    var instruction = new Array(values.length + 1);
-    instruction[0] = name;
-    for (var i = 0; i < values.length; ++i) {
-      instruction[i + 1] = this._convertToArgument(values[i]);
-    }
-    return instruction;
-  };
-
-  /**
-   * Returns the JSON representation of the source and step instructions
-   * @returns {String}
-   */
-  Bytecode.prototype.toString = function () {
-    return (
-      (this.sourceInstructions.length > 0 ? 
JSON.stringify(this.sourceInstructions) : '') +
-      (this.stepInstructions.length   > 0 ? 
JSON.stringify(this.stepInstructions) : '')
-    );
-  };
-
-  Bytecode.prototype._convertToArgument = function (value) {
-    return value;
-  };
-
-  function toEnum(typeName, keys) {
-    var result = {};
-    keys.split(' ').forEach(function (k) {
-      if (k === k.toUpperCase()) {
-        k = k.toLowerCase();
-      }
-      result[k] = new EnumValue(typeName, k);
-    });
-    return result;
-  }
-
-  function EnumValue(typeName, elementName) {
-    this.typeName = typeName;
-    this.elementName = elementName;
-  }
+function Traverser(object, bulk) {
+  this.object = object;
+  this.bulk = bulk == undefined ? 1 : bulk;
+}
 
-  // Utility functions
-  /** @returns {Array} */
-  function parseArgs() {
-    return (arguments.length === 1 ? [ arguments[0] ] : Array.apply(null, 
arguments));
-  }
+function TraversalSideEffects() {
 
-  /**
-   * @param {Array} arr
-   * @param {Function} fn
-   * @param {Function} [callback]
-   */
-  function eachSeries(arr, fn, callback) {
-    if (!Array.isArray(arr)) {
-      throw new TypeError('First parameter is not an Array');
-    }
-    callback = callback || noop;
-    var length = arr.length;
-    if (length === 0) {
-      return callback();
-    }
-    var sync;
-    var index = 1;
-    fn(arr[0], next);
-    if (sync === undefined) {
-      sync = false;
-    }
+}
 
-    function next(err) {
-      if (err) {
-        return callback(err);
-      }
-      if (index >= length) {
-        return callback();
-      }
-      if (sync === undefined) {
-        sync = true;
-      }
-      if (sync) {
-        return process.nextTick(function () {
-          fn(arr[index++], next);
-        });
-      }
-      fn(arr[index++], next);
+function toEnum(typeName, keys) {
+  var result = {};
+  keys.split(' ').forEach(function (k) {
+    var jsKey = k;
+    if (jsKey === jsKey.toUpperCase()) {
+      jsKey = jsKey.toLowerCase();
     }
-  }
+    result[jsKey] = new EnumValue(typeName, k);
+  });
+  return result;
+}
 
-  function inherits(ctor, superCtor) {
-    ctor.super_ = superCtor;
-    ctor.prototype = Object.create(superCtor.prototype, {
-      constructor: {
-        value: ctor,
-        enumerable: false,
-        writable: true,
-        configurable: true
-      }
-    });
-  }
+function EnumValue(typeName, elementName) {
+  this.typeName = typeName;
+  this.elementName = elementName;
+}
 
-  var toExport = {
-    Bytecode: Bytecode,
-    EnumValue: EnumValue,
-    inherits: inherits,
-    P: P,
-    parseArgs: parseArgs,
-    Traversal: Traversal,
-    TraversalSideEffects: TraversalSideEffects,
-    TraversalStrategies: TraversalStrategies,
-    TraversalStrategy: TraversalStrategy,
-    Traverser: Traverser""")
-        for (final Class<? extends Enum> enumClass : 
CoreImports.getClassImports()
-                .findAll { Enum.class.isAssignableFrom(it) }
-                .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
-                .collect()) {
-            moduleOutput.append(",\n    
${SymbolHelper.decapitalize(enumClass.getSimpleName())}: " +
-                    "toEnum('${SymbolHelper.toJs(enumClass.getSimpleName())}', 
'");
-            enumClass.getEnumConstants()
-                    .sort { a, b -> a.name() <=> b.name() }
-                    .each { value -> 
moduleOutput.append("${SymbolHelper.toJs(value.name())} "); }
-            moduleOutput.deleteCharAt(moduleOutput.length() - 1).append("')")
+module.exports = {
+  EnumValue: EnumValue,
+  P: P,
+  Traversal: Traversal,
+  TraversalSideEffects: TraversalSideEffects,
+  Traverser: Traverser""")
+        for (final Class<? extends Enum> enumClass : 
CoreImports.getClassImports().
+                findAll { Enum.class.isAssignableFrom(it) }.
+                sort { a, b -> a.simpleName <=> b.simpleName }) {
+            moduleOutput.append(",\n  
${SymbolHelper.decapitalize(enumClass.simpleName)}: " +
+                    "toEnum('${SymbolHelper.toJs(enumClass.simpleName)}', '");
+            moduleOutput.append(
+                enumClass.getEnumConstants().
+                        sort { a, b -> a.name() <=> b.name() }.
+                        collect { SymbolHelper.toJs(it.name()) }.
+                        join(' '));
+            moduleOutput.append("\')");
         }
 
-        moduleOutput.append("""
-  };
-  if (typeof module !== 'undefined') {
-    // CommonJS
-    module.exports = toExport;
-    return;
-  }
-  // Nashorn and rest
-  return toExport;
-}).call(this);""")
+        moduleOutput.append("""\n};""");
 
         // save to a file
         final File file = new File(traversalSourceFile);

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
 
b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
deleted file mode 100644
index 1656db4..0000000
--- 
a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.javascript;
-
-public class GenerateGremlinJavascript {
-
-    private GenerateGremlinJavascript() {
-        // just need the main method
-    }
-
-    public static void main(String[] args) {
-        TraversalSourceGenerator.create(args[0]);
-        GraphTraversalSourceGenerator.create(args[1]);
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
 
b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
deleted file mode 100644
index 535de44..0000000
--- 
a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  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.
- */
-
-package org.apache.tinkerpop.gremlin.javascript.jsr223;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Jorge Bay Gondra
- */
-public final class SymbolHelper {
-
-    private final static Map<String, String> TO_JS_MAP = new HashMap<>();
-    private final static Map<String, String> FROM_JS_MAP = new HashMap<>();
-
-    static {
-        TO_JS_MAP.put("in", "in_");
-        TO_JS_MAP.put("from", "from_");
-        TO_JS_MAP.forEach((k, v) -> FROM_JS_MAP.put(v, k));
-    }
-
-    private SymbolHelper() {
-        // static methods only, do not instantiate
-    }
-
-    public static String toJs(final String symbol) {
-        return TO_JS_MAP.getOrDefault(symbol, symbol);
-    }
-
-    public static String toJava(final String symbol) {
-        return FROM_JS_MAP.getOrDefault(symbol, symbol);
-    }
-
-    public static String decapitalize(String string) {
-        if (string == null || string.length() == 0) {
-            return string;
-        }
-        char c[] = string.toCharArray();
-        c[0] = Character.toLowerCase(c[0]);
-        return new String(c);
-    }
-}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
new file mode 100644
index 0000000..4c7120c
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/.gitignore
@@ -0,0 +1,5 @@
+node_modules/
+.idea/
+npm-debug.log
+# maven plugin com.github.eirslett frontend-maven-plugin installs node.js 
runtime in "node" folder
+node/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/.npmignore
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/.npmignore 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/.npmignore
new file mode 100644
index 0000000..82943d0
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/.npmignore
@@ -0,0 +1,26 @@
+# 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.
+
+*.gz
+*.tgz
+test/
+.DS_Store
+.idea
+node_modules/
+npm-debug.log
+# maven plugin com.github.eirslett frontend-maven-plugin installs node.js 
runtime in "node" folder
+node/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/README.md
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/README.md 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/README.md
new file mode 100644
index 0000000..388e175
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/README.md
@@ -0,0 +1,39 @@
+<!--
+
+ 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.
+
+-->
+
+# JavaScript Gremlin Language Variant
+
+[Apache TinkerPop™][tk] is a graph computing framework for both graph 
databases (OLTP) and graph analytic systems
+(OLAP). [Gremlin][gremlin] is the graph traversal language of TinkerPop. It 
can be described as a functional,
+data-flow language that enables users to succinctly express complex traversals 
on (or queries of) their application's
+property graph.
+
+Gremlin-Javascript implements Gremlin within the JavaScript language and can 
be used on Node.js.
+
+```bash
+npm install gremlin-javascript
+```
+
+Please see the [reference documentation][docs] at Apache TinkerPop for more 
information.
+
+[tk]: http://tinkerpop.apache.org
+[gremlin]: http://tinkerpop.apache.org/gremlin.html
+[docs]: http://tinkerpop.apache.org/docs/current/reference/#gremlin-javascript
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
deleted file mode 100644
index e19b537..0000000
--- 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  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.
- */
-
-/**
- * @author Jorge Bay Gondra
- */
-(function defineRemoteConnectionModule() {
-  "use strict";
-
-  var t = loadModule.call(this, '../process/traversal.js');
-  var inherits = t.inherits;
-
-  function RemoteConnection(url, traversalSource) {
-    this.url = url;
-    this.traversalSource = traversalSource;
-  }
-
-  /**
-   * @abstract
-   * @param {Bytecode} bytecode
-   * @param {Function} callback
-   */
-  RemoteConnection.prototype.submit = function (bytecode, callback) {
-    throw new Error('submit() needs to be implemented');
-  };
-
-  /**
-   * @extends {Traversal}
-   * @constructor
-   */
-  function RemoteTraversal(traversers, sideEffects) {
-    t.Traversal.call(this, null, null, null);
-    this.traversers = traversers;
-    this.sideEffects = sideEffects;
-  }
-
-  inherits(RemoteTraversal, t.Traversal);
-
-  /**
-   *
-   * @param {RemoteConnection} connection
-   * @extends {TraversalStrategy}
-   * @constructor
-   */
-  function RemoteStrategy(connection) {
-    t.TraversalStrategy.call(this);
-    this.connection = connection;
-  }
-
-  inherits(RemoteStrategy, t.TraversalStrategy);
-
-  /** @override */
-  RemoteStrategy.prototype.apply = function (traversal, callback) {
-    if (traversal.traversers) {
-      return callback();
-    }
-    this.connection.submit(traversal.getBytecode(), function (err, 
remoteTraversal) {
-      if (err) {
-        return callback(err);
-      }
-      traversal.sideEffects = remoteTraversal.sideEffects;
-      traversal.traversers = remoteTraversal.traversers;
-      callback();
-    });
-  };
-
-  function loadModule(moduleName) {
-    if (typeof require !== 'undefined') {
-      return require(moduleName);
-    }
-    if (typeof load !== 'undefined') {
-      var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
-      this.__dependencies = this.__dependencies || {};
-      return this.__dependencies[path] = (this.__dependencies[path] || 
load(path));
-    }
-    throw new Error('No module loader was found');
-  }
-
-  var toExport = {
-    RemoteConnection: RemoteConnection,
-    RemoteStrategy: RemoteStrategy,
-    RemoteTraversal: RemoteTraversal
-  };
-  if (typeof module !== 'undefined') {
-    // CommonJS
-    module.exports = toExport;
-    return;
-  }
-  // Nashorn and rest
-  return toExport;
-}).call(this);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
index ddcdac2..600ac53 100644
--- a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
@@ -20,73 +20,54 @@
 /**
  * @author Jorge Bay Gondra
  */
-(function exportModule() {
-  "use strict";
+'use strict';
 
-  function loadModule(moduleName) {
-    if (typeof require !== 'undefined') {
-      return require(moduleName);
-    }
-    if (typeof load !== 'undefined') {
-      var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
-      this.__dependencies = this.__dependencies || {};
-      return this.__dependencies[path] = (this.__dependencies[path] || 
load(path));
-    }
-    throw new Error('No module loader was found');
-  }
+var t = require('./lib/process/traversal');
+var gt = require('./lib/process/graph-traversal');
+var strategiesModule = require('./lib/process/traversal-strategy');
+var graph = require('./lib/structure/graph');
+var gs = require('./lib/structure/io/graph-serializer');
+var rc = require('./lib/driver/remote-connection');
+var Bytecode = require('./lib/process/bytecode');
 
-  var t = loadModule.call(this, './process/traversal.js');
-  var gt = loadModule.call(this, './process/graph-traversal.js');
-  var graph = loadModule.call(this, './structure/graph.js');
-  var gs = loadModule.call(this, './structure/io/graph-serializer.js');
-  var rc = loadModule.call(this, './driver/remote-connection.js');
-  var toExport = {
-    driver: {
-      RemoteConnection: rc.RemoteConnection,
-      RemoteStrategy: rc.RemoteStrategy,
-      RemoteTraversal: rc.RemoteTraversal
-    },
-    process: {
-      Bytecode: t.Bytecode,
-      EnumValue: t.EnumValue,
-      P: t.P,
-      Traversal: t.Traversal,
-      TraversalSideEffects: t.TraversalSideEffects,
-      TraversalStrategies: t.TraversalStrategies,
-      TraversalStrategy: t.TraversalStrategy,
-      Traverser: t.Traverser,
-      barrier: t.barrier,
-      cardinality: t.cardinality,
-      column: t.column,
-      direction: t.direction,
-      operator: t.operator,
-      order: t.order,
-      pop: t.pop,
-      scope: t.scope,
-      t: t.t,
-      GraphTraversal: gt.GraphTraversal,
-      GraphTraversalSource: gt.GraphTraversalSource,
-      statics: gt.statics
+module.exports = {
+  driver: {
+    RemoteConnection: rc.RemoteConnection,
+    RemoteStrategy: rc.RemoteStrategy,
+    RemoteTraversal: rc.RemoteTraversal
+  },
+  process: {
+    Bytecode: Bytecode,
+    EnumValue: t.EnumValue,
+    P: t.P,
+    Traversal: t.Traversal,
+    TraversalSideEffects: t.TraversalSideEffects,
+    TraversalStrategies: strategiesModule.TraversalStrategies,
+    TraversalStrategy: strategiesModule.TraversalStrategy,
+    Traverser: t.Traverser,
+    barrier: t.barrier,
+    cardinality: t.cardinality,
+    column: t.column,
+    direction: t.direction,
+    operator: t.operator,
+    order: t.order,
+    pop: t.pop,
+    scope: t.scope,
+    t: t.t,
+    GraphTraversal: gt.GraphTraversal,
+    GraphTraversalSource: gt.GraphTraversalSource,
+    statics: gt.statics
+  },
+  structure: {
+    io: {
+      GraphSONReader: gs.GraphSONReader,
+      GraphSONWriter: gs.GraphSONWriter
     },
-    structure: {
-      io: {
-        GraphSONReader: gs.GraphSONReader,
-        GraphSONWriter: gs.GraphSONWriter
-      },
-      Edge: graph.Edge,
-      Graph: graph.Graph,
-      Path: graph.Path,
-      Property: graph.Property,
-      Vertex: graph.Vertex,
-      VertexProperty: graph.VertexProperty
-    }
-  };
-
-
-  if (typeof module !== 'undefined') {
-    // CommonJS
-    module.exports = toExport;
-    return;
+    Edge: graph.Edge,
+    Graph: graph.Graph,
+    Path: graph.Path,
+    Property: graph.Property,
+    Vertex: graph.Vertex,
+    VertexProperty: graph.VertexProperty
   }
-  return toExport;
-}).call(this);
\ No newline at end of file
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
new file mode 100644
index 0000000..0d6d507
--- /dev/null
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/driver-remote-connection.js
@@ -0,0 +1,200 @@
+/*
+ *  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.
+ */
+
+/**
+ * @author Jorge Bay Gondra
+ */
+'use strict';
+
+var crypto = require('crypto');
+var WebSocket = require('ws');
+var util = require('util');
+var RemoteConnection = require('./remote-connection').RemoteConnection;
+var utils = require('../utils');
+var serializer = require('../structure/io/graph-serializer');
+var inherits = utils.inherits;
+var mimeType = 'application/vnd.gremlin-v2.0+json';
+var header = String.fromCharCode(mimeType.length) + mimeType;
+var responseStatusCode = {
+  success: 200,
+  noContent: 204,
+  partialContent: 206
+};
+
+/**
+ * Creates a new instance of DriverRemoteConnection.
+ * @param {String} url The resource uri.
+ * @param {Object} [options] The connection options.
+ * @param {Array} [options.ca] Trusted certificates.
+ * @param {String|Array|Buffer} [options.cert] The certificate key.
+ * @param {String|Buffer} [options.pfx] The private key, certificate, and CA 
certs.
+ * @param {GraphSONReader} [options.reader] The GraphSON2 reader to use.
+ * @param {Boolean} [options.rejectUnauthorized] Determines whether to verify 
or not the server certificate.
+ * @param {GraphSONWriter} [options.writer] The GraphSON2 writer to use.
+ * @constructor
+ */
+function DriverRemoteConnection(url, options) {
+  options = options || {};
+  this._ws = new WebSocket(url, {
+    ca: options.ca,
+    cert: options.cert,
+    pfx: options.pfx,
+    rejectUnauthorized: options.rejectUnauthorized
+  });
+  var self = this;
+  this._ws.on('open', function opened () {
+    self.isOpen = true;
+    if (self._openCallback) {
+      self._openCallback();
+    }
+  });
+  this._ws.on('message', function incoming (data) {
+    self._handleMessage(data);
+  });
+  // A map containing the request id and the handler
+  this._responseHandlers = {};
+  this._reader = options.reader || new serializer.GraphSONReader();
+  this._writer = options.writer || new serializer.GraphSONWriter();
+  this._openPromise = null;
+  this._openCallback = null;
+  this._closePromise = null;
+  this.isOpen = false;
+}
+
+inherits(DriverRemoteConnection, RemoteConnection);
+
+/**
+ * Opens the connection, if its not already opened.
+ * @returns {Promise}
+ */
+DriverRemoteConnection.prototype.open = function (promiseFactory) {
+  if (this._closePromise) {
+    return this._openPromise = utils.toPromise(promiseFactory, function 
promiseHandler(callback) {
+      callback(new Error('Connection has been closed'));
+    });
+  }
+  if (this._openPromise) {
+    return this._openPromise;
+  }
+  var self = this;
+  return this._openPromise = utils.toPromise(promiseFactory, function 
promiseHandler(callback) {
+    if (self.isOpen) {
+      return callback();
+    }
+    // It will be invoked when opened
+    self._openCallback = callback;
+  });
+};
+
+/** @override */
+DriverRemoteConnection.prototype.submit = function (bytecode, promiseFactory) {
+  var self = this;
+  return this.open().then(function () {
+    return utils.toPromise(promiseFactory, function promiseHandler(callback) {
+      var requestId = getUuid();
+      self._responseHandlers[requestId] = {
+        callback: callback,
+        result: null
+      };
+      var message = bufferFromString(header + 
JSON.stringify(self._getRequest(requestId, bytecode)));
+      self._ws.send(message);
+    });
+  });
+};
+
+DriverRemoteConnection.prototype._getRequest = function (id, bytecode) {
+  return ({
+    'requestId': { '@type': 'g:UUID', '@value': id },
+    'op': 'bytecode',
+    'processor': 'traversal',
+    'args': {
+      'gremlin': this._writer.adaptObject(bytecode),
+      'aliases': { 'g': 'g'}
+    }
+  });
+};
+
+DriverRemoteConnection.prototype._handleMessage = function (data) {
+  var response = this._reader.read(JSON.parse(data.toString()));
+  var handler = this._responseHandlers[response.requestId];
+  if (response.status.code >= 400) {
+    // callback in error
+    return handler.callback(
+      new Error(util.format('Server error: %s (%d)', response.status.message, 
response.status.code)));
+  }
+  switch (response.status.code) {
+    case responseStatusCode.noContent:
+      return handler.callback(null, { traversers: []});
+    case responseStatusCode.partialContent:
+      handler.result = handler.result || [];
+      handler.result.push.apply(handler.result, response.result.data);
+      break;
+    default:
+      if (handler.result) {
+        handler.result.push.apply(handler.result, response.result.data);
+      }
+      else {
+        handler.result = response.result.data;
+      }
+      return handler.callback(null, { traversers: handler.result });
+  }
+};
+
+/**
+ * Closes the Connection.
+ * @return {Promise}
+ */
+DriverRemoteConnection.prototype.close = function (promiseFactory) {
+  if (this._closePromise) {
+    return this._closePromise;
+  }
+  var self = this;
+  return this._closePromise = utils.toPromise(promiseFactory, function 
promiseHandler(callback) {
+    self._ws.on('close', function () {
+      self.isOpen = false;
+      callback();
+    });
+    self._ws.close();
+  });
+};
+
+function getUuid() {
+  var buffer = crypto.randomBytes(16);
+  //clear the version
+  buffer[6] &= 0x0f;
+  //set the version 4
+  buffer[6] |= 0x40;
+  //clear the variant
+  buffer[8] &= 0x3f;
+  //set the IETF variant
+  buffer[8] |= 0x80;
+  var hex = buffer.toString('hex');
+  return (
+    hex.substr(0, 8) + '-' +
+    hex.substr(8, 4) + '-' +
+    hex.substr(12, 4) + '-' +
+    hex.substr(16, 4) + '-' +
+    hex.substr(20, 12));
+}
+
+var bufferFromString = Buffer.from || function newBuffer(text) {
+  return new Buffer(text, 'utf8');
+};
+
+module.exports = DriverRemoteConnection;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
new file mode 100644
index 0000000..8176c37
--- /dev/null
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/driver/remote-connection.js
@@ -0,0 +1,84 @@
+/*
+ *  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.
+ */
+
+/**
+ * @author Jorge Bay Gondra
+ */
+'use strict';
+
+var t = require('../process/traversal');
+var TraversalStrategy = 
require('../process/traversal-strategy').TraversalStrategy;
+var utils = require('../utils');
+var inherits = utils.inherits;
+
+function RemoteConnection(url, traversalSource) {
+  this.url = url;
+}
+
+/**
+ * @abstract
+ * @param {Bytecode} bytecode
+ * @param {Function|undefined} promiseFactory
+ * @returns {Promise}
+ */
+RemoteConnection.prototype.submit = function (bytecode, promiseFactory) {
+  throw new Error('submit() was not implemented');
+};
+
+/**
+ * @extends {Traversal}
+ * @constructor
+ */
+function RemoteTraversal(traversers, sideEffects) {
+  t.Traversal.call(this, null, null, null);
+  this.traversers = traversers;
+  this.sideEffects = sideEffects;
+}
+
+inherits(RemoteTraversal, t.Traversal);
+
+/**
+ *
+ * @param {RemoteConnection} connection
+ * @extends {TraversalStrategy}
+ * @constructor
+ */
+function RemoteStrategy(connection) {
+  TraversalStrategy.call(this);
+  this.connection = connection;
+}
+
+inherits(RemoteStrategy, TraversalStrategy);
+
+/** @override */
+RemoteStrategy.prototype.apply = function (traversal, promiseFactory) {
+  if (traversal.traversers) {
+    return utils.resolvedPromise(promiseFactory);
+  }
+  return this.connection.submit(traversal.getBytecode(), 
promiseFactory).then(function (remoteTraversal) {
+    traversal.sideEffects = remoteTraversal.sideEffects;
+    traversal.traversers = remoteTraversal.traversers;
+  });
+};
+
+module.exports = {
+  RemoteConnection: RemoteConnection,
+  RemoteStrategy: RemoteStrategy,
+  RemoteTraversal: RemoteTraversal
+};

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/2b4e8e3b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
----------------------------------------------------------------------
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
new file mode 100644
index 0000000..9256e6a
--- /dev/null
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/bytecode.js
@@ -0,0 +1,99 @@
+/*
+ *  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.
+ */
+
+/**
+ * @author Jorge Bay Gondra
+ */
+'use strict';
+
+/**
+ * Creates a new instance of Bytecode
+ * @param {Bytecode} [toClone]
+ * @constructor
+ */
+function Bytecode(toClone) {
+  if (!toClone) {
+    this.sourceInstructions = [];
+    this.stepInstructions = [];
+  }
+  else {
+    this.sourceInstructions = toClone.sourceInstructions.slice(0);
+    this.stepInstructions = toClone.sourceInstructions.slice(0);
+  }
+}
+
+/**
+ * Adds a new source instructions
+ * @param {String} name
+ * @param {Array} values
+ * @returns {Bytecode}
+ */
+Bytecode.prototype.addSource = function (name, values) {
+  if (name === undefined) {
+    throw new Error('Name is not defined');
+  }
+  var instruction = new Array(values.length + 1);
+  instruction[0] = name;
+  for (var i = 0; i < values.length; ++i) {
+    instruction[i + 1] = this._convertToArgument(values[i]);
+  }
+  this.sourceInstructions.push(this._generateInstruction(name, values));
+  return this;
+};
+
+/**
+ * Adds a new step instructions
+ * @param {String} name
+ * @param {Array} values
+ * @returns {Bytecode}
+ */
+Bytecode.prototype.addStep = function (name, values) {
+  if (name === undefined) {
+    throw new Error('Name is not defined');
+  }
+  this.stepInstructions.push(this._generateInstruction(name, values));
+  return this;
+};
+
+Bytecode.prototype._generateInstruction = function (name, values) {
+  var length = (values ? values.length : 0) + 1;
+  var instruction = new Array(length);
+  instruction[0] = name;
+  for (var i = 1; i < length; i++) {
+    instruction[i] = this._convertToArgument(values[i - 1]);
+  }
+  return instruction;
+};
+
+/**
+ * Returns the JSON representation of the source and step instructions
+ * @returns {String}
+ */
+Bytecode.prototype.toString = function () {
+  return (
+    (this.sourceInstructions.length > 0 ? 
JSON.stringify(this.sourceInstructions) : '') +
+    (this.stepInstructions.length   > 0 ? 
JSON.stringify(this.stepInstructions) : '')
+  );
+};
+
+Bytecode.prototype._convertToArgument = function (value) {
+  return value;
+};
+
+module.exports = Bytecode;
\ No newline at end of file

Reply via email to