You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/07/18 21:04:18 UTC

[45/50] [abbrv] tinkerpop git commit: Javascript GLV

Javascript GLV


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

Branch: refs/heads/TINKERPOP-1489
Commit: 66bd5fa408746d3ccc3cc0b74598836bb0019b70
Parents: 2704245
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Wed Oct 5 16:14:46 2016 +0200
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Jul 18 17:01:43 2017 -0400

----------------------------------------------------------------------
 gremlin-javascript/pom.xml                      |  132 ++
 .../GraphTraversalSourceGenerator.groovy        |  247 +++
 .../javascript/TraversalSourceGenerator.groovy  |  398 ++++
 .../javascript/GenerateGremlinJavascript.java   |   32 +
 .../gremlin/javascript/jsr223/SymbolHelper.java |   59 +
 .../driver/remote-connection.js                 |  107 +
 .../main/javascript/gremlin-javascript/index.js |   85 +
 .../process/graph-traversal.js                  | 2025 ++++++++++++++++++
 .../gremlin-javascript/process/traversal.js     |  395 ++++
 .../gremlin-javascript/structure/graph.js       |  146 ++
 .../structure/io/graph-serializer.js            |  406 ++++
 .../javascript/gremlin-javascript/helper.js     |   84 +
 .../gremlin-javascript/test-exports.js          |   78 +
 .../gremlin-javascript/test-graphson.js         |  108 +
 .../gremlin-javascript/test-traversal.js        |   54 +
 pom.xml                                         |    1 +
 16 files changed, 4357 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-javascript/pom.xml b/gremlin-javascript/pom.xml
new file mode 100644
index 0000000..387e628
--- /dev/null
+++ b/gremlin-javascript/pom.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.tinkerpop</groupId>
+        <artifactId>tinkerpop</artifactId>
+        <version>3.2.3-SNAPSHOT</version>
+    </parent>
+    <artifactId>gremlin-javascript</artifactId>
+    <name>Apache TinkerPop :: Gremlin Javascript</name>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy</artifactId>
+            <version>${groovy.version}</version>
+            <classifier>indy</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>tinkergraph-gremlin</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-test</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tinkerpop</groupId>
+            <artifactId>gremlin-server</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <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>
+    </properties>
+    <build>
+        <directory>${basedir}/target</directory>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-javascript</id>
+                        <phase>generate-test-resources</phase>
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                        <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>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>js-tests</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>exec</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>
+                        </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>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/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
new file mode 100644
index 0000000..81c38dc
--- /dev/null
+++ b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
@@ -0,0 +1,247 @@
+/*
+ *  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
+
+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 java.lang.reflect.Modifier
+
+/**
+ * @author Jorge Bay Gondra
+ */
+class GraphTraversalSourceGenerator {
+
+    public static void create(final String graphTraversalSourceFile) {
+
+        final StringBuilder moduleOutput = new StringBuilder()
+
+        moduleOutput.append("""/*
+ *  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.
+ */
+ """)
+
+//////////////////////////
+// GraphTraversalSource //
+//////////////////////////
+        moduleOutput.append("""
+/**
+ * @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 {GraphTraversal}
+   */
+  GraphTraversalSource.prototype.withRemote = function (remoteConnection) {
+    var traversalStrategy = new t.TraversalStrategies(this._traversalStrategies);
+    traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection));
+    return new GraphTraversal(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) }.
+                findAll {
+                    !it.name.equals("clone") &&
+                            !it.name.equals(TraversalSource.Symbols.withBindings) &&
+                            !it.name.equals(TraversalSource.Symbols.withRemote)
+                }.
+                collect { SymbolHelper.toJs(it.name) }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { method ->
+                    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);
+  };
+""")
+                }
+        GraphTraversalSource.getMethods(). // SPAWN STEPS
+                findAll { GraphTraversal.class.equals(it.returnType) }.
+                collect { SymbolHelper.toJs(it.name) }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { method ->
+                    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);
+  };
+""")
+                }
+////////////////////
+// GraphTraversal //
+////////////////////
+        moduleOutput.append(
+                """
+  /**
+   * Represents a graph 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) }.
+                unique().
+                sort { a, b -> a <=> b }.
+                forEach { method ->
+                    moduleOutput.append(
+                            """
+  /**
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  GraphTraversal.prototype.${method} = function (args) {
+    this._bytecode.addStep('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+    return this;
+  };
+""")
+                };
+
+////////////////////////
+// AnonymousTraversal //
+////////////////////////
+        moduleOutput.append("""
+  /**
+   * Contains the static method definitions
+   * @type {Object}
+   */
+  var statics = {};
+""");
+        __.class.getMethods().
+                findAll { GraphTraversal.class.equals(it.returnType) }.
+                findAll { Modifier.isStatic(it.getModifiers()) }.
+                collect { SymbolHelper.toJs(it.name) }.
+                unique().
+                sort { a, b -> a <=> b }.
+                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);
+  };
+""")
+                };
+
+        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);""")
+
+        // save to file
+        final File file = new File(graphTraversalSourceFile);
+        file.delete()
+        moduleOutput.eachLine { file.append(it + "\n") }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/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
new file mode 100644
index 0000000..efcb826
--- /dev/null
+++ b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
@@ -0,0 +1,398 @@
+/*
+ *  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
+
+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
+
+/**
+ * @author Jorge Bay Gondra
+ */
+class TraversalSourceGenerator {
+
+    public static void create(final String traversalSourceFile) {
+
+        final StringBuilder moduleOutput = new StringBuilder()
+
+        moduleOutput.append("""/*
+ *  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.
+ */
+""")
+        moduleOutput.append("""
+/**
+ * @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;
+  }
+
+  /** @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);
+    });
+  };
+
+  /** @param {Function} callback */
+  Traversal.prototype.one = function (callback) {
+    this.list(function (err, result) {
+      callback(err, result ? result[0] : null);
+    });
+  };
+
+  /**
+   * 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 + ')';
+  };
+
+  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) }.
+                unique().
+                sort { a, b -> a <=> b }.
+                each { method ->
+                    moduleOutput.append(
+                            """
+  /** @param {...Object} args */
+  P.${method} = function (args) {
+    return createP('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+  };
+""")
+                };
+        moduleOutput.append("""
+  P.prototype.and = function (arg) {
+    return new P('and', 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 */
+  TraversalStrategies.prototype.applyStrategies = function (traversal) {
+    this.strategies.forEach(function eachStrategy(s) {
+      s.apply(traversal);
+    });
+  };
+
+  /**
+   * @abstract
+   * @constructor
+   */
+  function TraversalStrategy() {
+
+  }
+
+  /**
+   * @abstract
+   * @param {Traversal} traversal
+   */
+  TraversalStrategy.prototype.apply = function (traversal) {
+
+  };
+
+  /**
+   * 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;
+  }
+
+  /**
+   * @type {{barrier, cardinality, column, direction, operator, order, pop, scope, t}}
+   */
+  var enums = {};\n""")
+
+        for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
+                .findAll { Enum.class.isAssignableFrom(it) }
+                .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
+                .collect()) {
+            moduleOutput.append("  enums.${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("');\n")
+        }
+
+        moduleOutput.append("""
+  // Utility functions
+  /** @returns {Array} */
+  function parseArgs() {
+    return (arguments.length === 1 ? [ arguments[0] ] : Array.apply(null, arguments));
+  }
+
+  /**
+   * @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 inherits(ctor, superCtor) {
+    ctor.super_ = superCtor;
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  }
+
+  var toExport = {
+    Bytecode: Bytecode,
+    EnumValue: EnumValue,
+    inherits: inherits,
+    P: P,
+    parseArgs: parseArgs,
+    Traversal: Traversal,
+    TraversalSideEffects: TraversalSideEffects,
+    TraversalStrategies: TraversalStrategies,
+    TraversalStrategy: TraversalStrategy,
+    Traverser: Traverser
+  };
+  Object.keys(enums).forEach(function (k) {
+    toExport[k] = enums[k];
+  });
+  if (typeof module !== 'undefined') {
+    // CommonJS
+    module.exports = toExport;
+    return;
+  }
+  // Nashorn and rest
+  return toExport;
+}).call(this);""")
+
+        // 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/66bd5fa4/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
new file mode 100644
index 0000000..1656db4
--- /dev/null
+++ b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
@@ -0,0 +1,32 @@
+/*
+ *  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/66bd5fa4/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
new file mode 100644
index 0000000..535de44
--- /dev/null
+++ b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
@@ -0,0 +1,59 @@
+/*
+ *  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/66bd5fa4/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
new file mode 100644
index 0000000..99b177f
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
@@ -0,0 +1,107 @@
+/*
+ *  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;
+    }
+    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/66bd5fa4/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
new file mode 100644
index 0000000..cda8200
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
@@ -0,0 +1,85 @@
+/*
+ *  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 exportModule() {
+  "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 = 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,
+      inherits: t.inherits,
+      P: t.P,
+      parseArgs: t.parseArgs,
+      Traversal: t.Traversal,
+      TraversalSideEffects: t.TraversalSideEffects,
+      TraversalStrategies: t.TraversalStrategies,
+      TraversalStrategy: t.TraversalStrategy,
+      Traverser: t.Traverser,
+      GraphTraversal: gt.GraphTraversal,
+      GraphTraversalSource: gt.GraphTraversalSource,
+      statics: gt.statics
+    },
+    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;
+  }
+  return toExport;
+}).call(this);
\ No newline at end of file