arrow-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From w...@apache.org
Subject [5/7] arrow git commit: ARROW-1479: [JS] Expand JavaScript implementation
Date Fri, 08 Sep 2017 23:02:08 GMT
http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/closure-compiler-scripts/flatbuffers.js
----------------------------------------------------------------------
diff --git a/js/closure-compiler-scripts/flatbuffers.js b/js/closure-compiler-scripts/flatbuffers.js
new file mode 100644
index 0000000..e51a4a0
--- /dev/null
+++ b/js/closure-compiler-scripts/flatbuffers.js
@@ -0,0 +1,1204 @@
+/**
+ * closure-compiler-friendly flatbuffers
+ * copied from node_modules/flatbuffers/js/flatbuffers.js
+ * update as needed
+ */
+
+ /// @file
+/// @addtogroup flatbuffers_javascript_api
+/// @{
+/// @cond FLATBUFFERS_INTERNAL
+
+goog.module("module$flatbuffers");
+goog.module.declareLegacyNamespace();
+/**
+ * @fileoverview
+ *
+ * Need to suppress 'global this' error so the Node.js export line doesn't cause
+ * closure compile to error out.
+ * @suppress {globalThis}
+ */
+
+/**
+ * @const
+ * @namespace
+ */
+var flatbuffers = {};
+
+/**
+ * @typedef {number}
+ */
+flatbuffers.Offset;
+
+/**
+ * @typedef {{
+ *   bb: flatbuffers.ByteBuffer,
+ *   bb_pos: number
+ * }}
+ */
+flatbuffers.Table;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZEOF_SHORT = 2;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZEOF_INT = 4;
+
+/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
+
+/**
+ * @enum {number}
+ */
+flatbuffers.Encoding = {
+  UTF8_BYTES: 1,
+  UTF16_STRING: 2
+};
+
+/**
+ * @type {Int32Array}
+ * @const
+ */
+flatbuffers.int32 = new Int32Array(2);
+
+/**
+ * @type {Float32Array}
+ * @const
+ */
+flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
+
+/**
+ * @type {Float64Array}
+ * @const
+ */
+flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
+
+/**
+ * @type {boolean}
+ * @const
+ */
+flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @constructor
+ * @param {number} low
+ * @param {number} high
+ */
+flatbuffers.Long = function(low, high) {
+  /**
+   * @type {number}
+   * @const
+   */
+  this.low = low | 0;
+
+  /**
+   * @type {number}
+   * @const
+   */
+  this.high = high | 0;
+};
+
+/**
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.Long.create = function(low, high) {
+  // Special-case zero to avoid GC overhead for default values
+  return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
+};
+
+/**
+ * @returns {number}
+ */
+flatbuffers.Long.prototype.toFloat64 = function() {
+  return (this.low >>> 0) + this.high * 0x100000000;
+};
+
+/**
+ * @param {flatbuffers.Long} other
+ * @returns {boolean}
+ */
+flatbuffers.Long.prototype.equals = function(other) {
+  return this.low == other.low && this.high == other.high;
+};
+
+/**
+ * @type {flatbuffers.Long}
+ * @const
+ */
+flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
+
+/// @endcond
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Create a FlatBufferBuilder.
+ *
+ * @constructor
+ * @param {number=} opt_initial_size
+ */
+flatbuffers.Builder = function(opt_initial_size) {
+  if (!opt_initial_size) {
+    var initial_size = 1024;
+  } else {
+    var initial_size = opt_initial_size;
+  }
+
+  /**
+   * @type {flatbuffers.ByteBuffer}
+   * @private
+   */
+  this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
+
+  /**
+   * Remaining space in the ByteBuffer.
+   *
+   * @type {number}
+   * @private
+   */
+  this.space = initial_size;
+
+  /**
+   * Minimum alignment encountered so far.
+   *
+   * @type {number}
+   * @private
+   */
+  this.minalign = 1;
+
+  /**
+   * The vtable for the current table.
+   *
+   * @type {Array.<number>}
+   * @private
+   */
+  this.vtable = null;
+
+  /**
+   * The amount of fields we're actually using.
+   *
+   * @type {number}
+   * @private
+   */
+  this.vtable_in_use = 0;
+
+  /**
+   * Whether we are currently serializing a table.
+   *
+   * @type {boolean}
+   * @private
+   */
+  this.isNested = false;
+
+  /**
+   * Starting offset of the current struct/table.
+   *
+   * @type {number}
+   * @private
+   */
+  this.object_start = 0;
+
+  /**
+   * List of offsets of all vtables.
+   *
+   * @type {Array.<number>}
+   * @private
+   */
+  this.vtables = [];
+
+  /**
+   * For the current vector being built.
+   *
+   * @type {number}
+   * @private
+   */
+  this.vector_num_elems = 0;
+
+  /**
+   * False omits default values from the serialized data
+   *
+   * @type {boolean}
+   * @private
+   */
+  this.force_defaults = false;
+};
+
+/**
+ * In order to save space, fields that are set to their default value
+ * don't get serialized into the buffer. Forcing defaults provides a
+ * way to manually disable this optimization.
+ *
+ * @param {boolean} forceDefaults true always serializes default values
+ */
+flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
+  this.force_defaults = forceDefaults;
+};
+
+/**
+ * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
+ * called finish(). The actual data starts at the ByteBuffer's current position,
+ * not necessarily at 0.
+ *
+ * @returns {flatbuffers.ByteBuffer}
+ */
+flatbuffers.Builder.prototype.dataBuffer = function() {
+  return this.bb;
+};
+
+/**
+ * Get the bytes representing the FlatBuffer. Only call this after you've
+ * called finish().
+ *
+ * @returns {Uint8Array}
+ */
+flatbuffers.Builder.prototype.asUint8Array = function() {
+  return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Prepare to write an element of `size` after `additional_bytes` have been
+ * written, e.g. if you write a string, you need to align such the int length
+ * field is aligned to 4 bytes, and the string data follows it directly. If all
+ * you need to do is alignment, `additional_bytes` will be 0.
+ *
+ * @param {number} size This is the of the new element to write
+ * @param {number} additional_bytes The padding size
+ */
+flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
+  // Track the biggest thing we've ever aligned to.
+  if (size > this.minalign) {
+    this.minalign = size;
+  }
+
+  // Find the amount of alignment needed such that `size` is properly
+  // aligned after `additional_bytes`
+  var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
+
+  // Reallocate the buffer if needed.
+  while (this.space < align_size + size + additional_bytes) {
+    var old_buf_size = this.bb.capacity();
+    this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
+    this.space += this.bb.capacity() - old_buf_size;
+  }
+
+  this.pad(align_size);
+};
+
+/**
+ * @param {number} byte_size
+ */
+flatbuffers.Builder.prototype.pad = function(byte_size) {
+  for (var i = 0; i < byte_size; i++) {
+    this.bb.writeInt8(--this.space, 0);
+  }
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt8 = function(value) {
+  this.bb.writeInt8(this.space -= 1, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt16 = function(value) {
+  this.bb.writeInt16(this.space -= 2, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeInt32 = function(value) {
+  this.bb.writeInt32(this.space -= 4, value);
+};
+
+/**
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.Builder.prototype.writeInt64 = function(value) {
+  this.bb.writeInt64(this.space -= 8, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeFloat32 = function(value) {
+  this.bb.writeFloat32(this.space -= 4, value);
+};
+
+/**
+ * @param {number} value
+ */
+flatbuffers.Builder.prototype.writeFloat64 = function(value) {
+  this.bb.writeFloat64(this.space -= 8, value);
+};
+/// @endcond
+
+/**
+ * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int8` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt8 = function(value) {
+  this.prep(1, 0);
+  this.writeInt8(value);
+};
+
+/**
+ * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int16` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt16 = function(value) {
+  this.prep(2, 0);
+  this.writeInt16(value);
+};
+
+/**
+ * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `int32` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt32 = function(value) {
+  this.prep(4, 0);
+  this.writeInt32(value);
+};
+
+/**
+ * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {flatbuffers.Long} value The `int64` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addInt64 = function(value) {
+  this.prep(8, 0);
+  this.writeInt64(value);
+};
+
+/**
+ * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float32` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addFloat32 = function(value) {
+  this.prep(4, 0);
+  this.writeFloat32(value);
+};
+
+/**
+ * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
+ * @param {number} value The `float64` to add the the buffer.
+ */
+flatbuffers.Builder.prototype.addFloat64 = function(value) {
+  this.prep(8, 0);
+  this.writeFloat64(value);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt8(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt16(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addInt32(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {flatbuffers.Long} value
+ * @param {flatbuffers.Long} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || !value.equals(defaultValue)) {
+    this.addInt64(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addFloat32(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {number} value
+ * @param {number} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addFloat64(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * @param {number} voffset
+ * @param {flatbuffers.Offset} value
+ * @param {flatbuffers.Offset} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
+  if (this.force_defaults || value != defaultValue) {
+    this.addOffset(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * Structs are stored inline, so nothing additional is being added. `d` is always 0.
+ *
+ * @param {number} voffset
+ * @param {flatbuffers.Offset} value
+ * @param {flatbuffers.Offset} defaultValue
+ */
+flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
+  if (value != defaultValue) {
+    this.nested(value);
+    this.slot(voffset);
+  }
+};
+
+/**
+ * Structures are always stored inline, they need to be created right
+ * where they're used.  You'll get this assertion failure if you
+ * created it elsewhere.
+ *
+ * @param {flatbuffers.Offset} obj The offset of the created object
+ */
+flatbuffers.Builder.prototype.nested = function(obj) {
+  if (obj != this.offset()) {
+    throw new Error('FlatBuffers: struct must be serialized inline.');
+  }
+};
+
+/**
+ * Should not be creating any other object, string or vector
+ * while an object is being constructed
+ */
+flatbuffers.Builder.prototype.notNested = function() {
+  if (this.isNested) {
+    throw new Error('FlatBuffers: object serialization must not be nested.');
+  }
+};
+
+/**
+ * Set the current vtable at `voffset` to the current location in the buffer.
+ *
+ * @param {number} voffset
+ */
+flatbuffers.Builder.prototype.slot = function(voffset) {
+  this.vtable[voffset] = this.offset();
+};
+
+/**
+ * @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
+ */
+flatbuffers.Builder.prototype.offset = function() {
+  return this.bb.capacity() - this.space;
+};
+
+/**
+ * Doubles the size of the backing ByteBuffer and copies the old data towards
+ * the end of the new buffer (since we build the buffer backwards).
+ *
+ * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
+ * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
+ * to it. The data is located at the end of the buffer.
+ *
+ * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
+ * it a uint8Array we need to suppress the type check:
+ * @suppress {checkTypes}
+ */
+flatbuffers.Builder.growByteBuffer = function(bb) {
+  var old_buf_size = bb.capacity();
+
+  // Ensure we don't grow beyond what fits in an int.
+  if (old_buf_size & 0xC0000000) {
+    throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
+  }
+
+  var new_buf_size = old_buf_size << 1;
+  var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
+  nbb.setPosition(new_buf_size - old_buf_size);
+  nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
+  return nbb;
+};
+/// @endcond
+
+/**
+ * Adds on offset, relative to where it will be written.
+ *
+ * @param {flatbuffers.Offset} offset The offset to add.
+ */
+flatbuffers.Builder.prototype.addOffset = function(offset) {
+  this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
+  this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Start encoding a new object in the buffer.  Users will not usually need to
+ * call this directly. The FlatBuffers compiler will generate helper methods
+ * that call this method internally.
+ *
+ * @param {number} numfields
+ */
+flatbuffers.Builder.prototype.startObject = function(numfields) {
+  this.notNested();
+  if (this.vtable == null) {
+    this.vtable = [];
+  }
+  this.vtable_in_use = numfields;
+  for (var i = 0; i < numfields; i++) {
+    this.vtable[i] = 0; // This will push additional elements as needed
+  }
+  this.isNested = true;
+  this.object_start = this.offset();
+};
+
+/**
+ * Finish off writing the object that is under construction.
+ *
+ * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
+ */
+flatbuffers.Builder.prototype.endObject = function() {
+  if (this.vtable == null || !this.isNested) {
+    throw new Error('FlatBuffers: endObject called without startObject');
+  }
+
+  this.addInt32(0);
+  var vtableloc = this.offset();
+
+  // Write out the current vtable.
+  for (var i = this.vtable_in_use - 1; i >= 0; i--) {
+    // Offset relative to the start of the table.
+    this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
+  }
+
+  var standard_fields = 2; // The fields below:
+  this.addInt16(vtableloc - this.object_start);
+  this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT);
+
+  // Search for an existing vtable that matches the current one.
+  var existing_vtable = 0;
+outer_loop:
+  for (var i = 0; i < this.vtables.length; i++) {
+    var vt1 = this.bb.capacity() - this.vtables[i];
+    var vt2 = this.space;
+    var len = this.bb.readInt16(vt1);
+    if (len == this.bb.readInt16(vt2)) {
+      for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
+        if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
+          continue outer_loop;
+        }
+      }
+      existing_vtable = this.vtables[i];
+      break;
+    }
+  }
+
+  if (existing_vtable) {
+    // Found a match:
+    // Remove the current vtable.
+    this.space = this.bb.capacity() - vtableloc;
+
+    // Point table to existing vtable.
+    this.bb.writeInt32(this.space, existing_vtable - vtableloc);
+  } else {
+    // No match:
+    // Add the location of the current vtable to the list of vtables.
+    this.vtables.push(this.offset());
+
+    // Point table to current vtable.
+    this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
+  }
+
+  this.isNested = false;
+  return vtableloc;
+};
+/// @endcond
+
+/**
+ * Finalize a buffer, poiting to the given `root_table`.
+ *
+ * @param {flatbuffers.Offset} root_table
+ * @param {string=} opt_file_identifier
+ */
+flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
+  if (opt_file_identifier) {
+    var file_identifier = opt_file_identifier;
+    this.prep(this.minalign, flatbuffers.SIZEOF_INT +
+      flatbuffers.FILE_IDENTIFIER_LENGTH);
+    if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
+      throw new Error('FlatBuffers: file identifier must be length ' +
+        flatbuffers.FILE_IDENTIFIER_LENGTH);
+    }
+    for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
+      this.writeInt8(file_identifier.charCodeAt(i));
+    }
+  }
+  this.prep(this.minalign, flatbuffers.SIZEOF_INT);
+  this.addOffset(root_table);
+  this.bb.setPosition(this.space);
+};
+
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * This checks a required field has been set in a given table that has
+ * just been constructed.
+ *
+ * @param {flatbuffers.Offset} table
+ * @param {number} field
+ */
+flatbuffers.Builder.prototype.requiredField = function(table, field) {
+  var table_start = this.bb.capacity() - table;
+  var vtable_start = table_start - this.bb.readInt32(table_start);
+  var ok = this.bb.readInt16(vtable_start + field) != 0;
+
+  // If this fails, the caller will show what field needs to be set.
+  if (!ok) {
+    throw new Error('FlatBuffers: field ' + field + ' must be set');
+  }
+};
+
+/**
+ * Start a new array/vector of objects.  Users usually will not call
+ * this directly. The FlatBuffers compiler will create a start/end
+ * method for vector types in generated code.
+ *
+ * @param {number} elem_size The size of each element in the array
+ * @param {number} num_elems The number of elements in the array
+ * @param {number} alignment The alignment of the array
+ */
+flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
+  this.notNested();
+  this.vector_num_elems = num_elems;
+  this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
+  this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
+};
+
+/**
+ * Finish off the creation of an array and all its elements. The array must be
+ * created with `startVector`.
+ *
+ * @returns {flatbuffers.Offset} The offset at which the newly created array
+ * starts.
+ */
+flatbuffers.Builder.prototype.endVector = function() {
+  this.writeInt32(this.vector_num_elems);
+  return this.offset();
+};
+/// @endcond
+
+/**
+ * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
+ * instead of a string, it is assumed to contain valid UTF-8 encoded data.
+ *
+ * @param {string|Uint8Array} s The string to encode
+ * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
+ */
+flatbuffers.Builder.prototype.createString = function(s) {
+  if (s instanceof Uint8Array) {
+    var utf8 = s;
+  } else {
+    var utf8 = [];
+    var i = 0;
+
+    while (i < s.length) {
+      var codePoint;
+
+      // Decode UTF-16
+      var a = s.charCodeAt(i++);
+      if (a < 0xD800 || a >= 0xDC00) {
+        codePoint = a;
+      } else {
+        var b = s.charCodeAt(i++);
+        codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
+      }
+
+      // Encode UTF-8
+      if (codePoint < 0x80) {
+        utf8.push(codePoint);
+      } else {
+        if (codePoint < 0x800) {
+          utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
+        } else {
+          if (codePoint < 0x10000) {
+            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
+          } else {
+            utf8.push(
+              ((codePoint >> 18) & 0x07) | 0xF0,
+              ((codePoint >> 12) & 0x3F) | 0x80);
+          }
+          utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
+        }
+        utf8.push((codePoint & 0x3F) | 0x80);
+      }
+    }
+  }
+
+  this.addInt8(0);
+  this.startVector(1, utf8.length, 1);
+  this.bb.setPosition(this.space -= utf8.length);
+  for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
+    bytes[offset++] = utf8[i];
+  }
+  return this.endVector();
+};
+
+/**
+ * A helper function to avoid generated code depending on this file directly.
+ *
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.Builder.prototype.createLong = function(low, high) {
+  return flatbuffers.Long.create(low, high);
+};
+////////////////////////////////////////////////////////////////////////////////
+/// @cond FLATBUFFERS_INTERNAL
+/**
+ * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
+ *
+ * @constructor
+ * @param {Uint8Array} bytes
+ */
+flatbuffers.ByteBuffer = function(bytes) {
+  /**
+   * @type {Uint8Array}
+   * @private
+   */
+  this.bytes_ = bytes;
+
+  /**
+   * @type {number}
+   * @private
+   */
+  this.position_ = 0;
+};
+
+/**
+ * Create and allocate a new ByteBuffer with a given size.
+ *
+ * @param {number} byte_size
+ * @returns {flatbuffers.ByteBuffer}
+ */
+flatbuffers.ByteBuffer.allocate = function(byte_size) {
+  return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
+};
+
+/**
+ * Get the underlying `Uint8Array`.
+ *
+ * @returns {Uint8Array}
+ */
+flatbuffers.ByteBuffer.prototype.bytes = function() {
+  return this.bytes_;
+};
+
+/**
+ * Get the buffer's position.
+ *
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.position = function() {
+  return this.position_;
+};
+
+/**
+ * Set the buffer's position.
+ *
+ * @param {number} position
+ */
+flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
+  this.position_ = position;
+};
+
+/**
+ * Get the buffer's capacity.
+ *
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.capacity = function() {
+  return this.bytes_.length;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
+  return this.readUint8(offset) << 24 >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
+  return this.bytes_[offset];
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
+  return this.readUint16(offset) << 16 >> 16;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
+  return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
+  return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
+  return this.readInt32(offset) >>> 0;
+};
+
+/**
+ * @param {number} offset
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
+  return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
+};
+
+/**
+ * @param {number} offset
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
+  return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
+  flatbuffers.int32[0] = this.readInt32(offset);
+  return flatbuffers.float32[0];
+};
+
+/**
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
+  flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
+  flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
+  return flatbuffers.float64[0];
+};
+
+/**
+ * @param {number} offset
+ * @param {number|boolean} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
+  this.bytes_[offset] = /** @type {number} */(value);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
+  this.bytes_[offset] = value;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
+  this.bytes_[offset] = value;
+  this.bytes_[offset + 1] = value >> 8;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
+    this.bytes_[offset] = value;
+    this.bytes_[offset + 1] = value >> 8;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
+  this.bytes_[offset] = value;
+  this.bytes_[offset + 1] = value >> 8;
+  this.bytes_[offset + 2] = value >> 16;
+  this.bytes_[offset + 3] = value >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
+    this.bytes_[offset] = value;
+    this.bytes_[offset + 1] = value >> 8;
+    this.bytes_[offset + 2] = value >> 16;
+    this.bytes_[offset + 3] = value >> 24;
+};
+
+/**
+ * @param {number} offset
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
+  this.writeInt32(offset, value.low);
+  this.writeInt32(offset + 4, value.high);
+};
+
+/**
+ * @param {number} offset
+ * @param {flatbuffers.Long} value
+ */
+flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
+    this.writeUint32(offset, value.low);
+    this.writeUint32(offset + 4, value.high);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
+  flatbuffers.float32[0] = value;
+  this.writeInt32(offset, flatbuffers.int32[0]);
+};
+
+/**
+ * @param {number} offset
+ * @param {number} value
+ */
+flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
+  flatbuffers.float64[0] = value;
+  this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
+  this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
+};
+
+/**
+ * Look up a field in the vtable, return an offset into the object, or 0 if the
+ * field is not present.
+ *
+ * @param {number} bb_pos
+ * @param {number} vtable_offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
+  var vtable = bb_pos - this.readInt32(bb_pos);
+  return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
+};
+
+/**
+ * Initialize any Table-derived type to point to the union at the given offset.
+ *
+ * @param {flatbuffers.Table} t
+ * @param {number} offset
+ * @returns {flatbuffers.Table}
+ */
+flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
+  t.bb_pos = offset + this.readInt32(offset);
+  t.bb = this;
+  return t;
+};
+
+/**
+ * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
+ * This allocates a new string and converts to wide chars upon each access.
+ *
+ * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
+ * the "optionalEncoding" argument. This is useful for avoiding conversion to
+ * and from UTF-16 when the data will just be packaged back up in another
+ * FlatBuffer later on.
+ *
+ * @param {number} offset
+ * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
+ * @returns {string|Uint8Array}
+ */
+flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
+  offset += this.readInt32(offset);
+
+  var length = this.readInt32(offset);
+  var result = '';
+  var i = 0;
+
+  offset += flatbuffers.SIZEOF_INT;
+
+  if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
+    return this.bytes_.subarray(offset, offset + length);
+  }
+
+  while (i < length) {
+    var codePoint;
+
+    // Decode UTF-8
+    var a = this.readUint8(offset + i++);
+    if (a < 0xC0) {
+      codePoint = a;
+    } else {
+      var b = this.readUint8(offset + i++);
+      if (a < 0xE0) {
+        codePoint =
+          ((a & 0x1F) << 6) |
+          (b & 0x3F);
+      } else {
+        var c = this.readUint8(offset + i++);
+        if (a < 0xF0) {
+          codePoint =
+            ((a & 0x0F) << 12) |
+            ((b & 0x3F) << 6) |
+            (c & 0x3F);
+        } else {
+          var d = this.readUint8(offset + i++);
+          codePoint =
+            ((a & 0x07) << 18) |
+            ((b & 0x3F) << 12) |
+            ((c & 0x3F) << 6) |
+            (d & 0x3F);
+        }
+      }
+    }
+
+    // Encode UTF-16
+    if (codePoint < 0x10000) {
+      result += String.fromCharCode(codePoint);
+    } else {
+      codePoint -= 0x10000;
+      result += String.fromCharCode(
+        (codePoint >> 10) + 0xD800,
+        (codePoint & ((1 << 10) - 1)) + 0xDC00);
+    }
+  }
+
+  return result;
+};
+
+/**
+ * Retrieve the relative offset stored at "offset"
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
+  return offset + this.readInt32(offset);
+};
+
+/**
+ * Get the start of data of a vector whose offset is stored at "offset" in this object.
+ *
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
+  return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
+};
+
+/**
+ * Get the length of a vector whose offset is stored at "offset" in this object.
+ *
+ * @param {number} offset
+ * @returns {number}
+ */
+flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
+  return this.readInt32(offset + this.readInt32(offset));
+};
+
+/**
+ * @param {string} ident
+ * @returns {boolean}
+ */
+flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
+  if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
+    throw new Error('FlatBuffers: file identifier must be length ' +
+                    flatbuffers.FILE_IDENTIFIER_LENGTH);
+  }
+  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
+    if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
+      return false;
+    }
+  }
+  return true;
+};
+
+/**
+ * A helper function to avoid generated code depending on this file directly.
+ *
+ * @param {number} low
+ * @param {number} high
+ * @returns {flatbuffers.Long}
+ */
+flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
+  return flatbuffers.Long.create(low, high);
+};
+
+// Exports for Node.js and RequireJS
+exports.flatbuffers = flatbuffers;
+
+/// @endcond
+/// @}

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/closure-compiler-scripts/text-encoding.js
----------------------------------------------------------------------
diff --git a/js/closure-compiler-scripts/text-encoding.js b/js/closure-compiler-scripts/text-encoding.js
new file mode 100644
index 0000000..ca9154f
--- /dev/null
+++ b/js/closure-compiler-scripts/text-encoding.js
@@ -0,0 +1,648 @@
+/**
+ * closure-compiler-friendly text-encoding-utf-8
+ * copied from node_modules/text-encoding-utf-8/lib/encoding.cjs.js
+ * update as needed
+ */
+
+ // This is free and unencumbered software released into the public domain.
+// See LICENSE.md for more information.
+
+//
+// Utilities
+//
+
+goog.module("module$text_encoding");
+goog.module.declareLegacyNamespace();
+/**
+ * @param {number} a The number to test.
+ * @param {number} min The minimum value in the range, inclusive.
+ * @param {number} max The maximum value in the range, inclusive.
+ * @return {boolean} True if a >= min and a <= max.
+ */
+function inRange(a, min, max) {
+  return min <= a && a <= max;
+}
+
+/**
+ * @param {*} o
+ * @return {Object}
+ */
+function ToDictionary(o) {
+  if (o === undefined) return {};
+  if (o === Object(o)) return o;
+  throw TypeError('Could not convert argument to dictionary');
+}
+
+/**
+ * @param {string} string Input string of UTF-16 code units.
+ * @return {!Array.<number>} Code points.
+ */
+function stringToCodePoints(string) {
+  // https://heycam.github.io/webidl/#dfn-obtain-unicode
+
+  // 1. Let S be the DOMString value.
+  var s = String(string);
+
+  // 2. Let n be the length of S.
+  var n = s.length;
+
+  // 3. Initialize i to 0.
+  var i = 0;
+
+  // 4. Initialize U to be an empty sequence of Unicode characters.
+  var u = [];
+
+  // 5. While i < n:
+  while (i < n) {
+
+    // 1. Let c be the code unit in S at index i.
+    var c = s.charCodeAt(i);
+
+    // 2. Depending on the value of c:
+
+    // c < 0xD800 or c > 0xDFFF
+    if (c < 0xD800 || c > 0xDFFF) {
+      // Append to U the Unicode character with code point c.
+      u.push(c);
+    }
+
+    // 0xDC00 ≤ c ≤ 0xDFFF
+    else if (0xDC00 <= c && c <= 0xDFFF) {
+      // Append to U a U+FFFD REPLACEMENT CHARACTER.
+      u.push(0xFFFD);
+    }
+
+    // 0xD800 ≤ c ≤ 0xDBFF
+    else if (0xD800 <= c && c <= 0xDBFF) {
+      // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT
+      // CHARACTER.
+      if (i === n - 1) {
+        u.push(0xFFFD);
+      }
+      // 2. Otherwise, i < n−1:
+      else {
+        // 1. Let d be the code unit in S at index i+1.
+        var d = string.charCodeAt(i + 1);
+
+        // 2. If 0xDC00 ≤ d ≤ 0xDFFF, then:
+        if (0xDC00 <= d && d <= 0xDFFF) {
+          // 1. Let a be c & 0x3FF.
+          var a = c & 0x3FF;
+
+          // 2. Let b be d & 0x3FF.
+          var b = d & 0x3FF;
+
+          // 3. Append to U the Unicode character with code point
+          // 2^16+2^10*a+b.
+          u.push(0x10000 + (a << 10) + b);
+
+          // 4. Set i to i+1.
+          i += 1;
+        }
+
+        // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a
+        // U+FFFD REPLACEMENT CHARACTER.
+        else  {
+          u.push(0xFFFD);
+        }
+      }
+    }
+
+    // 3. Set i to i+1.
+    i += 1;
+  }
+
+  // 6. Return U.
+  return u;
+}
+
+/**
+ * @param {!Array.<number>} code_points Array of code points.
+ * @return {string} string String of UTF-16 code units.
+ */
+function codePointsToString(code_points) {
+  var s = '';
+  for (var i = 0; i < code_points.length; ++i) {
+    var cp = code_points[i];
+    if (cp <= 0xFFFF) {
+      s += String.fromCharCode(cp);
+    } else {
+      cp -= 0x10000;
+      s += String.fromCharCode((cp >> 10) + 0xD800,
+                               (cp & 0x3FF) + 0xDC00);
+    }
+  }
+  return s;
+}
+
+
+//
+// Implementation of Encoding specification
+// https://encoding.spec.whatwg.org/
+//
+
+//
+// 3. Terminology
+//
+
+/**
+ * End-of-stream is a special token that signifies no more tokens
+ * are in the stream.
+ * @const
+ */ var end_of_stream = -1;
+
+/**
+ * A stream represents an ordered sequence of tokens.
+ *
+ * @constructor
+ * @param {!(Array.<number>|Uint8Array)} tokens Array of tokens that provide the
+ * stream.
+ */
+function Stream(tokens) {
+  /** @type {!Array.<number>} */
+  this.tokens = [].slice.call(tokens);
+}
+
+Stream.prototype = {
+  /**
+   * @return {boolean} True if end-of-stream has been hit.
+   */
+  endOfStream: function() {
+    return !this.tokens.length;
+  },
+
+  /**
+   * When a token is read from a stream, the first token in the
+   * stream must be returned and subsequently removed, and
+   * end-of-stream must be returned otherwise.
+   *
+   * @return {number} Get the next token from the stream, or
+   * end_of_stream.
+   */
+   read: function() {
+    if (!this.tokens.length)
+      return end_of_stream;
+     return this.tokens.shift();
+   },
+
+  /**
+   * When one or more tokens are prepended to a stream, those tokens
+   * must be inserted, in given order, before the first token in the
+   * stream.
+   *
+   * @param {(number|!Array.<number>)} token The token(s) to prepend to the stream.
+   */
+  prepend: function(token) {
+    if (Array.isArray(token)) {
+      var tokens = /**@type {!Array.<number>}*/(token);
+      while (tokens.length)
+        this.tokens.unshift(tokens.pop());
+    } else {
+      this.tokens.unshift(token);
+    }
+  },
+
+  /**
+   * When one or more tokens are pushed to a stream, those tokens
+   * must be inserted, in given order, after the last token in the
+   * stream.
+   *
+   * @param {(number|!Array.<number>)} token The tokens(s) to prepend to the stream.
+   */
+  push: function(token) {
+    if (Array.isArray(token)) {
+      var tokens = /**@type {!Array.<number>}*/(token);
+      while (tokens.length)
+        this.tokens.push(tokens.shift());
+    } else {
+      this.tokens.push(token);
+    }
+  }
+};
+
+//
+// 4. Encodings
+//
+
+// 4.1 Encoders and decoders
+
+/** @const */
+var finished = -1;
+
+/**
+ * @param {boolean} fatal If true, decoding errors raise an exception.
+ * @param {number=} opt_code_point Override the standard fallback code point.
+ * @return {number} The code point to insert on a decoding error.
+ */
+function decoderError(fatal, opt_code_point) {
+  if (fatal)
+    throw TypeError('Decoder error');
+  return opt_code_point || 0xFFFD;
+}
+
+//
+// 7. API
+//
+
+/** @const */ var DEFAULT_ENCODING = 'utf-8';
+
+// 7.1 Interface TextDecoder
+
+/**
+ * @constructor
+ * @param {string=} encoding The label of the encoding;
+ *     defaults to 'utf-8'.
+ * @param {Object=} options
+ */
+function TextDecoder(encoding, options) {
+  if (!(this instanceof TextDecoder)) {
+    return new TextDecoder(encoding, options);
+  }
+  encoding = encoding !== undefined ? String(encoding).toLowerCase() : DEFAULT_ENCODING;
+  if (encoding !== DEFAULT_ENCODING) {
+    throw new Error('Encoding not supported. Only utf-8 is supported');
+  }
+  options = ToDictionary(options);
+
+  /** @private @type {boolean} */
+  this._streaming = false;
+  /** @private @type {boolean} */
+  this._BOMseen = false;
+  /** @private @type {?Decoder} */
+  this._decoder = null;
+  /** @private @type {boolean} */
+  this._fatal = Boolean(options['fatal']);
+  /** @private @type {boolean} */
+  this._ignoreBOM = Boolean(options['ignoreBOM']);
+
+  Object.defineProperty(this, 'encoding', {value: 'utf-8'});
+  Object.defineProperty(this, 'fatal', {value: this._fatal});
+  Object.defineProperty(this, 'ignoreBOM', {value: this._ignoreBOM});
+}
+
+TextDecoder.prototype = {
+  /**
+   * @param {ArrayBufferView=} input The buffer of bytes to decode.
+   * @param {Object=} options
+   * @return {string} The decoded string.
+   */
+  decode: function decode(input, options) {
+    var bytes;
+    if (typeof input === 'object' && input instanceof ArrayBuffer) {
+      bytes = new Uint8Array(input);
+    } else if (typeof input === 'object' && 'buffer' in input &&
+               input.buffer instanceof ArrayBuffer) {
+      bytes = new Uint8Array(input.buffer,
+                             input.byteOffset,
+                             input.byteLength);
+    } else {
+      bytes = new Uint8Array(0);
+    }
+
+    options = ToDictionary(options);
+
+    if (!this._streaming) {
+      this._decoder = new UTF8Decoder({fatal: this._fatal});
+      this._BOMseen = false;
+    }
+    this._streaming = Boolean(options['stream']);
+
+    var input_stream = new Stream(bytes);
+
+    var code_points = [];
+
+    /** @type {?(number|!Array.<number>)} */
+    var result;
+
+    while (!input_stream.endOfStream()) {
+      result = this._decoder.handler(input_stream, input_stream.read());
+      if (result === finished)
+        break;
+      if (result === null)
+        continue;
+      if (Array.isArray(result))
+        code_points.push.apply(code_points, /**@type {!Array.<number>}*/(result));
+      else
+        code_points.push(result);
+    }
+    if (!this._streaming) {
+      do {
+        result = this._decoder.handler(input_stream, input_stream.read());
+        if (result === finished)
+          break;
+        if (result === null)
+          continue;
+        if (Array.isArray(result))
+          code_points.push.apply(code_points, /**@type {!Array.<number>}*/(result));
+        else
+          code_points.push(result);
+      } while (!input_stream.endOfStream());
+      this._decoder = null;
+    }
+
+    if (code_points.length) {
+      // If encoding is one of utf-8, utf-16be, and utf-16le, and
+      // ignore BOM flag and BOM seen flag are unset, run these
+      // subsubsteps:
+      if (['utf-8'].indexOf(this.encoding) !== -1 &&
+          !this._ignoreBOM && !this._BOMseen) {
+        // If token is U+FEFF, set BOM seen flag.
+        if (code_points[0] === 0xFEFF) {
+          this._BOMseen = true;
+          code_points.shift();
+        } else {
+          // Otherwise, if token is not end-of-stream, set BOM seen
+          // flag and append token to output.
+          this._BOMseen = true;
+        }
+      }
+    }
+
+    return codePointsToString(code_points);
+  }
+};
+
+// 7.2 Interface TextEncoder
+
+/**
+ * @constructor
+ * @param {string=} encoding The label of the encoding;
+ *     defaults to 'utf-8'.
+ * @param {Object=} options
+ */
+function TextEncoder(encoding, options) {
+  if (!(this instanceof TextEncoder))
+    return new TextEncoder(encoding, options);
+  encoding = encoding !== undefined ? String(encoding).toLowerCase() : DEFAULT_ENCODING;
+  if (encoding !== DEFAULT_ENCODING) {
+    throw new Error('Encoding not supported. Only utf-8 is supported');
+  }
+  options = ToDictionary(options);
+
+  /** @private @type {boolean} */
+  this._streaming = false;
+  /** @private @type {?Encoder} */
+  this._encoder = null;
+  /** @private @type {{fatal: boolean}} */
+  this._options = {fatal: Boolean(options['fatal'])};
+
+  Object.defineProperty(this, 'encoding', {value: 'utf-8'});
+}
+
+TextEncoder.prototype = {
+  /**
+   * @param {string=} opt_string The string to encode.
+   * @param {Object=} options
+   * @return {Uint8Array} Encoded bytes, as a Uint8Array.
+   */
+  encode: function encode(opt_string, options) {
+    opt_string = opt_string ? String(opt_string) : '';
+    options = ToDictionary(options);
+
+    // NOTE: This option is nonstandard. None of the encodings
+    // permitted for encoding (i.e. UTF-8, UTF-16) are stateful,
+    // so streaming is not necessary.
+    if (!this._streaming)
+      this._encoder = new UTF8Encoder(this._options);
+    this._streaming = Boolean(options['stream']);
+
+    var bytes = [];
+    var input_stream = new Stream(stringToCodePoints(opt_string));
+    /** @type {?(number|!Array.<number>)} */
+    var result;
+    while (!input_stream.endOfStream()) {
+      result = this._encoder.handler(input_stream, input_stream.read());
+      if (result === finished)
+        break;
+      if (Array.isArray(result))
+        bytes.push.apply(bytes, /**@type {!Array.<number>}*/(result));
+      else
+        bytes.push(result);
+    }
+    if (!this._streaming) {
+      while (true) {
+        result = this._encoder.handler(input_stream, input_stream.read());
+        if (result === finished)
+          break;
+        if (Array.isArray(result))
+          bytes.push.apply(bytes, /**@type {!Array.<number>}*/(result));
+        else
+          bytes.push(result);
+      }
+      this._encoder = null;
+    }
+    return new Uint8Array(bytes);
+  }
+};
+
+//
+// 8. The encoding
+//
+
+// 8.1 utf-8
+
+/**
+ * @constructor
+ * @implements {Decoder}
+ * @param {{fatal: boolean}} options
+ */
+function UTF8Decoder(options) {
+  var fatal = options.fatal;
+
+  // utf-8's decoder's has an associated utf-8 code point, utf-8
+  // bytes seen, and utf-8 bytes needed (all initially 0), a utf-8
+  // lower boundary (initially 0x80), and a utf-8 upper boundary
+  // (initially 0xBF).
+  var /** @type {number} */ utf8_code_point = 0,
+      /** @type {number} */ utf8_bytes_seen = 0,
+      /** @type {number} */ utf8_bytes_needed = 0,
+      /** @type {number} */ utf8_lower_boundary = 0x80,
+      /** @type {number} */ utf8_upper_boundary = 0xBF;
+
+  /**
+   * @param {Stream} stream The stream of bytes being decoded.
+   * @param {number} bite The next byte read from the stream.
+   * @return {?(number|!Array.<number>)} The next code point(s)
+   *     decoded, or null if not enough data exists in the input
+   *     stream to decode a complete code point.
+   */
+  this.handler = function(stream, bite) {
+    // 1. If byte is end-of-stream and utf-8 bytes needed is not 0,
+    // set utf-8 bytes needed to 0 and return error.
+    if (bite === end_of_stream && utf8_bytes_needed !== 0) {
+      utf8_bytes_needed = 0;
+      return decoderError(fatal);
+    }
+
+    // 2. If byte is end-of-stream, return finished.
+    if (bite === end_of_stream)
+      return finished;
+
+    // 3. If utf-8 bytes needed is 0, based on byte:
+    if (utf8_bytes_needed === 0) {
+
+      // 0x00 to 0x7F
+      if (inRange(bite, 0x00, 0x7F)) {
+        // Return a code point whose value is byte.
+        return bite;
+      }
+
+      // 0xC2 to 0xDF
+      if (inRange(bite, 0xC2, 0xDF)) {
+        // Set utf-8 bytes needed to 1 and utf-8 code point to byte
+        // − 0xC0.
+        utf8_bytes_needed = 1;
+        utf8_code_point = bite - 0xC0;
+      }
+
+      // 0xE0 to 0xEF
+      else if (inRange(bite, 0xE0, 0xEF)) {
+        // 1. If byte is 0xE0, set utf-8 lower boundary to 0xA0.
+        if (bite === 0xE0)
+          utf8_lower_boundary = 0xA0;
+        // 2. If byte is 0xED, set utf-8 upper boundary to 0x9F.
+        if (bite === 0xED)
+          utf8_upper_boundary = 0x9F;
+        // 3. Set utf-8 bytes needed to 2 and utf-8 code point to
+        // byte − 0xE0.
+        utf8_bytes_needed = 2;
+        utf8_code_point = bite - 0xE0;
+      }
+
+      // 0xF0 to 0xF4
+      else if (inRange(bite, 0xF0, 0xF4)) {
+        // 1. If byte is 0xF0, set utf-8 lower boundary to 0x90.
+        if (bite === 0xF0)
+          utf8_lower_boundary = 0x90;
+        // 2. If byte is 0xF4, set utf-8 upper boundary to 0x8F.
+        if (bite === 0xF4)
+          utf8_upper_boundary = 0x8F;
+        // 3. Set utf-8 bytes needed to 3 and utf-8 code point to
+        // byte − 0xF0.
+        utf8_bytes_needed = 3;
+        utf8_code_point = bite - 0xF0;
+      }
+
+      // Otherwise
+      else {
+        // Return error.
+        return decoderError(fatal);
+      }
+
+      // Then (byte is in the range 0xC2 to 0xF4) set utf-8 code
+      // point to utf-8 code point << (6 × utf-8 bytes needed) and
+      // return continue.
+      utf8_code_point = utf8_code_point << (6 * utf8_bytes_needed);
+      return null;
+    }
+
+    // 4. If byte is not in the range utf-8 lower boundary to utf-8
+    // upper boundary, run these substeps:
+    if (!inRange(bite, utf8_lower_boundary, utf8_upper_boundary)) {
+
+      // 1. Set utf-8 code point, utf-8 bytes needed, and utf-8
+      // bytes seen to 0, set utf-8 lower boundary to 0x80, and set
+      // utf-8 upper boundary to 0xBF.
+      utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
+      utf8_lower_boundary = 0x80;
+      utf8_upper_boundary = 0xBF;
+
+      // 2. Prepend byte to stream.
+      stream.prepend(bite);
+
+      // 3. Return error.
+      return decoderError(fatal);
+    }
+
+    // 5. Set utf-8 lower boundary to 0x80 and utf-8 upper boundary
+    // to 0xBF.
+    utf8_lower_boundary = 0x80;
+    utf8_upper_boundary = 0xBF;
+
+    // 6. Increase utf-8 bytes seen by one and set utf-8 code point
+    // to utf-8 code point + (byte − 0x80) << (6 × (utf-8 bytes
+    // needed − utf-8 bytes seen)).
+    utf8_bytes_seen += 1;
+    utf8_code_point += (bite - 0x80) << (6 * (utf8_bytes_needed - utf8_bytes_seen));
+
+    // 7. If utf-8 bytes seen is not equal to utf-8 bytes needed,
+    // continue.
+    if (utf8_bytes_seen !== utf8_bytes_needed)
+      return null;
+
+    // 8. Let code point be utf-8 code point.
+    var code_point = utf8_code_point;
+
+    // 9. Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes
+    // seen to 0.
+    utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;
+
+    // 10. Return a code point whose value is code point.
+    return code_point;
+  };
+}
+
+/**
+ * @constructor
+ * @implements {Encoder}
+ * @param {{fatal: boolean}} options
+ */
+function UTF8Encoder(options) {
+  var fatal = options.fatal;
+  /**
+   * @param {Stream} stream Input stream.
+   * @param {number} code_point Next code point read from the stream.
+   * @return {(number|!Array.<number>)} Byte(s) to emit.
+   */
+  this.handler = function(stream, code_point) {
+    // 1. If code point is end-of-stream, return finished.
+    if (code_point === end_of_stream)
+      return finished;
+
+    // 2. If code point is in the range U+0000 to U+007F, return a
+    // byte whose value is code point.
+    if (inRange(code_point, 0x0000, 0x007f))
+      return code_point;
+
+    // 3. Set count and offset based on the range code point is in:
+    var count, offset;
+    // U+0080 to U+07FF:    1 and 0xC0
+    if (inRange(code_point, 0x0080, 0x07FF)) {
+      count = 1;
+      offset = 0xC0;
+    }
+    // U+0800 to U+FFFF:    2 and 0xE0
+    else if (inRange(code_point, 0x0800, 0xFFFF)) {
+      count = 2;
+      offset = 0xE0;
+    }
+    // U+10000 to U+10FFFF: 3 and 0xF0
+    else if (inRange(code_point, 0x10000, 0x10FFFF)) {
+      count = 3;
+      offset = 0xF0;
+    }
+
+    // 4.Let bytes be a byte sequence whose first byte is (code
+    // point >> (6 × count)) + offset.
+    var bytes = [(code_point >> (6 * count)) + offset];
+
+    // 5. Run these substeps while count is greater than 0:
+    while (count > 0) {
+
+      // 1. Set temp to code point >> (6 × (count − 1)).
+      var temp = code_point >> (6 * (count - 1));
+
+      // 2. Append to bytes 0x80 | (temp & 0x3F).
+      bytes.push(0x80 | (temp & 0x3F));
+
+      // 3. Decrease count by one.
+      count -= 1;
+    }
+
+    // 6. Return bytes bytes, in order.
+    return bytes;
+  };
+}
+
+exports.TextEncoder = TextEncoder;
+exports.TextDecoder = TextDecoder;

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/closure-compiler-scripts/tslib.js
----------------------------------------------------------------------
diff --git a/js/closure-compiler-scripts/tslib.js b/js/closure-compiler-scripts/tslib.js
new file mode 100644
index 0000000..b5a722a
--- /dev/null
+++ b/js/closure-compiler-scripts/tslib.js
@@ -0,0 +1,151 @@
+/**
+ * closure-compiler-friendly tslib
+ * copied from node_modules/tslib/tslib.js
+ * update as needed
+ */
+
+var extendStatics = Object.setPrototypeOf ||
+    ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+    function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+
+function __extends(d, b) {
+    extendStatics(d, b);
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+
+var __assign = Object.assign || function (t) {
+    for (var s, i = 1, n = arguments.length; i < n; i++) {
+        s = arguments[i];
+        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+    }
+    return t;
+};
+
+function __rest(s, e) {
+    var t = {};
+    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
+        t[p] = s[p];
+    if (s != null && typeof Object.getOwnPropertySymbols === "function")
+        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
+            t[p[i]] = s[p[i]];
+    return t;
+};
+
+function __decorate(decorators, target, key, desc) {
+    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
+    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
+    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
+    return c > 3 && r && Object.defineProperty(target, key, r), r;
+};
+
+function __param(paramIndex, decorator) {
+    return function (target, key) { decorator(target, key, paramIndex); }
+};
+
+function __metadata(metadataKey, metadataValue) {
+    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
+};
+
+function __awaiter(thisArg, _arguments, P, generator) {
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+
+function __generator(thisArg, body) {
+    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
+    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
+    function verb(n) { return function (v) { return step([n, v]); }; }
+    function step(op) {
+        if (f) throw new TypeError("Generator is already executing.");
+        while (_) try {
+            if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
+            if (y = 0, t) op = [0, t.value];
+            switch (op[0]) {
+                case 0: case 1: t = op; break;
+                case 4: _.label++; return { value: op[1], done: false };
+                case 5: _.label++; y = op[1]; op = [0]; continue;
+                case 7: op = _.ops.pop(); _.trys.pop(); continue;
+                default:
+                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
+                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
+                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
+                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
+                    if (t[2]) _.ops.pop();
+                    _.trys.pop(); continue;
+            }
+            op = body.call(thisArg, _);
+        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
+        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
+    }
+};
+
+function __exportStar(m, exports) {
+    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+};
+
+function __values(o) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    if (m) return m.call(o);
+    return {
+        next: function () {
+            if (o && i >= o.length) o = void 0;
+            return { value: o && o[i++], done: !o };
+        }
+    };
+};
+
+function __read(o, n) {
+    var m = typeof Symbol === "function" && o[Symbol.iterator];
+    if (!m) return o;
+    var i = m.call(o), r, ar = [], e;
+    try {
+        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
+    }
+    catch (error) { e = { error: error }; }
+    finally {
+        try {
+            if (r && !r.done && (m = i["return"])) m.call(i);
+        }
+        finally { if (e) throw e.error; }
+    }
+    return ar;
+};
+
+function __spread() {
+    for (var ar = [], i = 0; i < arguments.length; i++)
+        ar = ar.concat(__read(arguments[i]));
+    return ar;
+};
+
+function __await(v) {
+    return this instanceof __await ? (this.v = v, this) : new __await(v);
+};
+
+function __asyncGenerator(thisArg, _arguments, generator) {
+    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+    var g = generator.apply(thisArg, _arguments || []), i, q = [];
+    return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
+    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
+    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
+    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);  }
+    function fulfill(value) { resume("next", value); }
+    function reject(value) { resume("throw", value); }
+    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
+};
+
+function __asyncDelegator(o) {
+    var i, p;
+    return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
+    function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; }
+};
+
+function __asyncValues(o) {
+    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
+    var m = o[Symbol.asyncIterator];
+    return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
+};

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/examples/read_file.html
----------------------------------------------------------------------
diff --git a/js/examples/read_file.html b/js/examples/read_file.html
index 5a650a0..2a1ebab 100644
--- a/js/examples/read_file.html
+++ b/js/examples/read_file.html
@@ -21,7 +21,7 @@ under the License.
 
 <html>
   <head>
-    <title>arrow.js browser test</title>
+    <title>Arrow.js browser test</title>
     <meta charset="utf-8">
     <style>
 table {
@@ -33,30 +33,41 @@ table, th, td {
     </style>
     <script type="text/javascript">
 var reader = new FileReader();
-function addCell (tr, type, name) {
+function addCell (tr, type, value) {
   var td = document.createElement(type)
-  td.textContent = name;
+  td.textContent = value;
   tr.appendChild(td);
 }
 reader.onload = function (evt) {
-  var reader = new arrow.getReader(new Uint8Array(evt.target.result));
-  var schema = reader.getSchema();
-  var length = reader.loadNextBatch();
-console.log(JSON.stringify(schema, null, '\t'));
 
+  var arrowTable = Arrow.Table.from(new Uint8Array(evt.target.result));
   var thead = document.getElementById("thead");
   var tbody = document.getElementById("tbody");
-  var header_row = document.createElement("tr");
 
-  schema.forEach(function (d) {
-    addCell(header_row, "th", d.name);
-  });
+  while (thead.hasChildNodes()) {
+      thead.removeChild(thead.lastChild);
+  }
+
+  while (tbody.hasChildNodes()) {
+      tbody.removeChild(tbody.lastChild);
+  }
+
+  var header_row = document.createElement("tr");
+  for (let column of arrowTable.cols()) {
+    addCell(header_row, "th", column.name);
+  }
 
   thead.appendChild(header_row);
 
-  for (var i = 0; i < length; i += 1|0) {
+  for (let row of arrowTable.rows(true)) {
     var tr = document.createElement("tr");
-    schema.forEach(function (d) { addCell(tr, "td", reader.getVector(d.name).get(i)); });
+    for (let cell of row) {
+      addCell(tr, "td",
+        cell == null ? 'null'
+        : !Array.isArray(cell) ? cell
+        : '[' + cell.map((value) => value == null ? 'null' : value).join(', ') + ']'
+      );
+    }
     tbody.appendChild(tr);
   }
 }
@@ -74,6 +85,6 @@ function handleFiles(files) {
       <tbody id="tbody">
       </tbody>
     </table>
-    <script type="text/javascript" src="../_bundles/arrow.js"></script>
+    <script type="text/javascript" src="../dist/Arrow.js"></script>
   </body>
 </html>

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/flatbuffers.sh
----------------------------------------------------------------------
diff --git a/js/flatbuffers.sh b/js/flatbuffers.sh
deleted file mode 100755
index 0f8e3f9..0000000
--- a/js/flatbuffers.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-echo "Compiling flatbuffer schemas..."
-mkdir -p lib lib-esm
-DIR=`mktemp -d`
-flatc -o $DIR --js ../format/*.fbs
-cat $DIR/*_generated.js > src/Arrow_generated.js
-
-# Duplicate in the tsc-generated outputs - we can't make tsc pull in .js files
-# and still prooduce declaration files
-cat $DIR/*_generated.js > lib/Arrow_generated.js
-cat $DIR/*_generated.js > lib-esm/Arrow_generated.js
-rm -rf $DIR

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/gulpfile.js
----------------------------------------------------------------------
diff --git a/js/gulpfile.js b/js/gulpfile.js
new file mode 100644
index 0000000..90c45b7
--- /dev/null
+++ b/js/gulpfile.js
@@ -0,0 +1,285 @@
+// 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.
+
+const del = require(`del`);
+const gulp = require(`gulp`);
+const path = require(`path`);
+const pump = require(`pump`);
+const ts = require(`gulp-typescript`);
+const streamMerge = require(`merge2`);
+const sourcemaps = require(`gulp-sourcemaps`);
+const child_process = require(`child_process`);
+const gulpJsonTransform = require(`gulp-json-transform`);
+const closureCompiler = require(`google-closure-compiler`).gulp();
+
+const knownTargets = [`es5`, `es2015`, `esnext`];
+const knownModules = [`cjs`, `esm`, `cls`, `umd`];
+
+// see: https://github.com/google/closure-compiler/blob/c1372b799d94582eaf4b507a4a22558ff26c403c/src/com/google/javascript/jscomp/CompilerOptions.java#L2988
+const gCCTargets = {
+    es5: `ECMASCRIPT5`,
+    es2015: `ECMASCRIPT_2015`,
+    es2016: `ECMASCRIPT_2016`,
+    es2017: `ECMASCRIPT_2017`,
+    esnext: `ECMASCRIPT_NEXT`
+};
+
+const tsProjects = [];
+const argv = require(`command-line-args`)([
+    { name: `all`, alias: `a`, type: Boolean },
+    { name: 'update', alias: 'u', type: Boolean },
+    { name: 'verbose', alias: 'v', type: Boolean },
+    { name: `target`, type: String, defaultValue: `` },
+    { name: `module`, type: String, defaultValue: `` },
+    { name: `coverage`, type: Boolean, defaultValue: false },
+    { name: `targets`, alias: `t`, type: String, multiple: true, defaultValue: [] },
+    { name: `modules`, alias: `m`, type: String, multiple: true, defaultValue: [] }
+]);
+
+const { targets, modules } = argv;
+
+argv.target && !targets.length && targets.push(argv.target);
+argv.module && !modules.length && modules.push(argv.module);
+(argv.all || !targets.length) && targets.push(`all`);
+(argv.all || !modules.length) && modules.push(`all`);
+
+for (const [target, format] of combinations([`all`, `all`])) {
+    const combo = `${target}:${format}`;
+    gulp.task(`test:${combo}`, gulp.series(testTask(target, format, combo, `targets/${target}/${format}`)));
+    gulp.task(`clean:${combo}`, gulp.series(cleanTask(target, format, combo, `targets/${target}/${format}`)));
+    gulp.task(`build:${combo}`, gulp.series(buildTask(target, format, combo, `targets/${target}/${format}`)));
+    gulp.task(`bundle:${combo}`, gulp.series(bundleTask(target, format, combo, `targets/${target}/${format}`)));
+    gulp.task(`test:debug:${combo}`, gulp.series(testTask(target, format, combo, `targets/${target}/${format}`, true)));
+}
+
+gulp.task(`test`, gulp.series(runTaskCombos(`test`)));
+gulp.task(`clean`, gulp.parallel(runTaskCombos(`clean`)));
+gulp.task(`build`, gulp.parallel(runTaskCombos(`bundle`)));
+gulp.task(`test:debug`, gulp.series(runTaskCombos(`test:debug`)));
+gulp.task(`default`, gulp.task(`build`));
+
+function runTaskCombos(name) {
+    const combos = [];
+    for (const [target, format] of combinations(targets, modules)) {
+        if (format === `cls`) {
+            continue;
+        }
+        combos.push(`${name}:${target}:${format}`);
+    }
+    return combos;
+}
+
+function cleanTask(target, format, taskName, outDir) {
+    return () => {
+        const globs = [`${outDir}/**`];
+        if (target === `es5` && format === `cjs`) {
+            globs.push(`typings`);
+        }
+        return del(globs);
+    };
+}
+
+function buildTask(target, format, taskName, outDir) {
+    return format === `umd`
+        ? closureTask(target, format, taskName, outDir)
+        : typescriptTask(target, format, taskName, outDir);
+}
+
+function bundleTask(target, format, taskName, outDir) {
+    return [
+        [`build:${taskName}`],
+        (cb) => streamMerge([
+            pump(gulp.src([`LICENSE`, `README.md`, `CHANGELOG.md`]), gulp.dest(outDir)),
+            pump(
+                gulp.src(`package.json`),
+                gulpJsonTransform((orig) => [
+                    `version`, `description`,
+                    `author`, `homepage`, `bugs`, `license`,
+                    `keywords`, `repository`, `peerDependencies`
+                ].reduce((copy, key) => (
+                    (copy[key] = orig[key]) && copy || copy
+                ), {
+                    main: `Arrow.js`,
+                    typings: `Arrow.d.ts`,
+                    name: `@apache-arrow/${target}-${format}`
+                }), 2),
+                gulp.dest(outDir),
+                onError
+            )
+        ])
+    ];
+}
+
+function testTask(target, format, taskName, outDir, debug) {
+    const jestOptions = !debug ? [] : [
+        `--runInBand`, `--env`, `jest-environment-node-debug`];
+    argv.update && jestOptions.unshift(`-u`);
+    argv.verbose && jestOptions.unshift(`--verbose`);
+    argv.coverage && jestOptions.unshift(`--coverage`);
+    const jestPath = `./node_modules/.bin/jest`;
+    const debugOpts = jestOptions.join(' ');
+    const spawnOptions = {
+        stdio: [`ignore`, `inherit`, `inherit`],
+        env: Object.assign({}, process.env, {
+            TEST_TARGET: target, TEST_MODULE: format
+        })
+    };
+    return () => !debug ?
+        child_process.spawn(jestPath, jestOptions, spawnOptions) :
+        child_process.exec(`node --inspect-brk ${jestPath} ${debugOpts}`, spawnOptions);
+}
+
+function closureTask(target, format, taskName, outDir) {
+    const clsTarget = `es5`;
+    const googleRoot = `targets/${clsTarget}/cls`;
+    const languageIn = clsTarget === `es5` ? `es2015` : clsTarget;
+    return [
+        [`clean:${taskName}`, `build:${clsTarget}:cls`],
+        () => {
+            return streamMerge([
+                closureStream(closureSrcs(false), `Arrow`, onError, true),
+                closureStream(closureSrcs(true), `Arrow.internal`, onError)
+            ])
+            .on('end', () => del([`targets/${target}/cls/**`]));
+        }
+    ];
+    function closureSrcs(isInternal) {
+        return gulp.src([
+            `closure-compiler-scripts/*.js`,
+            `${googleRoot}/**/*.js`,
+            `!${googleRoot}/format/*.js`,
+            `!${googleRoot}/Arrow.externs.js`,
+            `!${googleRoot}/Arrow${isInternal ? `` : `.internal`}.js`
+        ], { base: `./` });
+    }
+    function closureStream(sources, entry, onError, copyToDist) {
+        const streams = [
+            sources,
+            sourcemaps.init(),
+            closureCompiler(closureArgs(entry)),
+            sourcemaps.write('.'),
+            gulp.dest(outDir)
+        ];
+        // copy the UMD bundle to dist
+        if (target === `es5` && copyToDist) {
+            streams.push(gulp.dest(`dist`));
+        }
+        return pump(...streams, onError);
+    }
+    function closureArgs(entry) {
+        return {
+            third_party: true,
+            externs: `${googleRoot}/Arrow.externs.js`,
+            warning_level: `QUIET`,
+            dependency_mode: `LOOSE`,
+            rewrite_polyfills: false,
+            // formatting: `PRETTY_PRINT`,
+            compilation_level: `ADVANCED`,
+            assume_function_wrapper: true,
+            js_output_file: `${entry}.js`,
+            language_in: gCCTargets[languageIn],
+            language_out: gCCTargets[clsTarget],
+            entry_point: `${googleRoot}/${entry}.js`,
+            output_wrapper:
+`// 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.
+(function (global, factory) {
+    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+    typeof define === 'function' && define.amd ? define(['exports'], factory) :
+    (factory(global.Arrow = global.Arrow || {}));
+}(this, (function (exports) {%output%}.bind(this))));`
+        };
+    }
+}
+
+function typescriptTask(target, format, taskName, outDir) {
+    return [
+        [`clean:${taskName}`],
+        () => {
+            const tsconfigPath = `tsconfig/tsconfig.${target}.${format}.json`;
+            let { js, dts } = tsProjects.find((p) => p.target === target && p.format === format) || {};
+            if (!js || !dts) {
+                let tsProject = ts.createProject(tsconfigPath);
+                ({ js, dts } = pump(
+                    tsProject.src(),
+                    sourcemaps.init(),
+                    tsProject(ts.reporter.fullReporter(true)),
+                    onError
+                ));
+                dts = [dts, gulp.dest(outDir)];
+                js = [js, sourcemaps.write(), gulp.dest(outDir)];
+                // copy types to the root
+                if (target === `es5` && format === `cjs`) {
+                    dts.push(gulp.dest(`typings`));
+                }
+                tsProjects.push({
+                    target, format, 
+                    js: js = pump(...js, onError),
+                    dts: dts = pump(...dts, onError)
+                });
+            }
+            return streamMerge([ dts, js ]);
+        }
+    ];
+}
+
+function* combinations(_targets, _modules) {
+
+    const targets = known(knownTargets, _targets || [`all`]);
+    const modules = known(knownModules, _modules || [`all`]);
+
+    for (const format of modules) {
+        for (const target of targets) {
+            yield [target, format];
+        }
+    }
+
+    function known(known, values) {
+        return ~values.indexOf(`all`)
+            ? known
+            : Object.keys(
+                values.reduce((map, arg) => ((
+                    (known.indexOf(arg) !== -1) &&
+                    (map[arg.toLowerCase()] = true)
+                    || true) && map
+                ), {})
+            ).sort((a, b) => known.indexOf(a) - known.indexOf(b));
+    }
+}
+
+function onError(err) {
+    if (typeof err === 'number') {
+        process.exit(err);
+    } else if (err) {
+        console.error(err.stack || err.toString());
+        process.exit(1);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/lerna.json
----------------------------------------------------------------------
diff --git a/js/lerna.json b/js/lerna.json
new file mode 100644
index 0000000..c8fb8c0
--- /dev/null
+++ b/js/lerna.json
@@ -0,0 +1,9 @@
+{
+  "lerna": "2.0.0",
+  "version": "0.1.1",
+  "packages": [
+    "targets/es5/*",
+    "targets/es2015/*",
+    "targets/esnext/*"
+  ]
+}

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/package.json
----------------------------------------------------------------------
diff --git a/js/package.json b/js/package.json
index e46b5bd..8998221 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,29 +1,140 @@
 {
-  "name": "arrow",
-  "version": "0.0.0",
-  "description": "",
-  "main": "lib/arrow.js",
+  "name": "apache-arrow",
+  "version": "0.1.2",
+  "main": "./targets/es5/cjs/Arrow.js",
+  "module": "./targets/es5/esm/Arrow.js",
+  "browser": "./targets/es5/umd/Arrow.js",
+  "jsnext:main": "./targets/es2015/esm/Arrow.js",
+  "esnext:main": "./targets/esnext/esm/Arrow.js",
+  "typings": "./typings/Arrow.d.ts",
+  "description": "Apache Arrow columnar in-memory format",
   "scripts": {
-    "build": "./flatbuffers.sh && tsc && tsc -m es6 --outDir lib-esm && webpack",
-    "clean": "rm -rf lib lib-esm _bundles",
-    "test": "./node_modules/mocha/bin/mocha ./spec/arrow.js",
-    "lint": "./node_modules/tslint/bin/tslint"
+    "lerna": "lerna",
+    "commit": "git-cz",
+    "test": "gulp test",
+    "build": "gulp build",
+    "clean": "gulp clean",
+    "perf": "node ./perf/index.js",
+    "test:debug": "gulp test:debug",
+    "test:coverage": "gulp test -t esnext -m esm --coverage",
+    "validate": "npm-run-all lint build test",
+    "lerna:publish": "lerna exec --bail=false npm publish",
+    "prepublishOnly": "sh ./prepublish.sh",
+    "commitmsg": "validate-commit-msg",
+    "doc": "shx rm -rf ./doc && esdoc",
+    "lint": "npm-run-all -p lint:*",
+    "lint:src": "tslint --fix --type-check -p tsconfig.json -c tslint.json \"src/**/*.ts\"",
+    "lint:test": "tslint --fix --type-check -p test/tsconfig.json -c tslint.json \"test/**/*.ts\""
   },
-  "author": "",
-  "repository": "https://github.com/apache/arrow/",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/apache/arrow.git"
+  },
+  "keywords": [
+    "apache",
+    "arrow"
+  ],
+  "author": "Apache Software Foundation",
   "license": "Apache-2.0",
-  "devDependencies": {
-    "awesome-typescript-loader": "^3.1.3",
-    "chai": "^3.5.0",
-    "mocha": "^3.3.0",
-    "tslint": "^5.3.2",
-    "typescript": "^2.3.2",
-    "uglifyjs-webpack-plugin": "^0.4.3",
-    "webpack": "^2.3.3"
+  "bugs": {
+    "url": "https://issues.apache.org/jira/projects/ARROW"
+  },
+  "homepage": "https://github.com/apache/arrow/blob/master/js/README.md",
+  "files": [
+    "src",
+    "dist",
+    "typings",
+    "targets",
+    "LICENSE",
+    "README.md"
+  ],
+  "peerDependencies": {
+    "tslib": "^1.7.1"
   },
   "dependencies": {
-    "flatbuffers": "^1.5.0",
-    "text-encoding": "^0.6.4",
-    "commander": "^2.9.0"
+    "command-line-args": "~4.0.7",
+    "command-line-usage": "~4.0.1",
+    "flatbuffers": "~1.7.0",
+    "text-encoding": "~0.6.4"
+  },
+  "devDependencies": {
+    "@types/flatbuffers": "~1.6.4",
+    "@types/jest": "~20.0.8",
+    "@types/node": "~8.0.24",
+    "@types/text-encoding": "0.0.32",
+    "benchmark": "~2.1.4",
+    "commitizen": "~2.9.6",
+    "conventional-changelog-cli": "~1.3.2",
+    "conventional-commits-detector": "~0.1.1",
+    "conventional-github-releaser": "~1.1.12",
+    "conventional-recommended-bump": "~1.0.1",
+    "coveralls": "~2.13.1",
+    "cz-conventional-changelog": "~2.0.0",
+    "del": "~3.0.0",
+    "esdoc": "~1.0.1",
+    "esdoc-standard-plugin": "~1.0.0",
+    "google-closure-compiler": "~20170806.0.0",
+    "gulp": "github:gulpjs/gulp#4.0",
+    "gulp-json-transform": "~0.4.2",
+    "gulp-sourcemaps": "~2.6.1",
+    "gulp-typescript": "~3.2.2",
+    "jest": "~20.0.4",
+    "jest-environment-node-debug": "~2.0.0",
+    "json": "~9.0.6",
+    "lerna": "2.0.0",
+    "lint-staged": "~4.0.1",
+    "merge2": "~1.1.0",
+    "mkdirp": "~0.5.1",
+    "npm-run-all": "~4.0.2",
+    "pump": "~1.0.2",
+    "rimraf": "~2.6.1",
+    "shx": "~0.2.2",
+    "text-encoding-utf-8": "~1.0.1",
+    "trash": "~4.0.1",
+    "ts-jest": "~20.0.10",
+    "tslib": "~1.7.1",
+    "tslint": "~5.6.0",
+    "typescript": "~2.4.2",
+    "validate-commit-msg": "~2.14.0"
+  },
+  "config": {
+    "commitizen": {
+      "path": "cz-conventional-changelog"
+    }
+  },
+  "lint-staged": {
+    "*.@(ts)": [
+      "tslint --fix",
+      "git add"
+    ]
+  },
+  "jest": {
+    "verbose": false,
+    "globals": {
+      "ts-jest": {
+        "tsConfigFile": "test/tsconfig.json"
+      }
+    },
+    "roots": [
+      "<rootDir>/test/"
+    ],
+    "moduleFileExtensions": [
+      "js",
+      "ts",
+      "tsx"
+    ],
+    "mapCoverage": true,
+    "coverageReporters": [
+      "lcov"
+    ],
+    "coveragePathIgnorePatterns": [
+      "format\\/(File|Message|Schema|Tensor)_generated\\.(js|ts)$",
+      "test\\/.*\\.(ts|tsx|js)$"
+    ],
+    "transform": {
+      ".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js",
+      ".(js|jsx)": "<rootDir>/node_modules/babel-jest/build/index.js"
+    },
+    "testRegex": "(.*(-|\\.)(test|spec)s?)\\.(ts|tsx|js)$"
   }
 }

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/file/dictionary.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/file/dictionary.arrow b/js/perf/arrows/file/dictionary.arrow
new file mode 100644
index 0000000..34d41db
Binary files /dev/null and b/js/perf/arrows/file/dictionary.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/file/simple.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/file/simple.arrow b/js/perf/arrows/file/simple.arrow
new file mode 100644
index 0000000..838db6d
Binary files /dev/null and b/js/perf/arrows/file/simple.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/file/struct.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/file/struct.arrow b/js/perf/arrows/file/struct.arrow
new file mode 100644
index 0000000..3d2c018
Binary files /dev/null and b/js/perf/arrows/file/struct.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/count/records.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/count/records.arrow b/js/perf/arrows/multi/count/records.arrow
new file mode 100644
index 0000000..00d8837
Binary files /dev/null and b/js/perf/arrows/multi/count/records.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/count/schema.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/count/schema.arrow b/js/perf/arrows/multi/count/schema.arrow
new file mode 100644
index 0000000..dfd24e9
Binary files /dev/null and b/js/perf/arrows/multi/count/schema.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/latlong/records.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/latlong/records.arrow b/js/perf/arrows/multi/latlong/records.arrow
new file mode 100644
index 0000000..563d12d
Binary files /dev/null and b/js/perf/arrows/multi/latlong/records.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/latlong/schema.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/latlong/schema.arrow b/js/perf/arrows/multi/latlong/schema.arrow
new file mode 100644
index 0000000..638b2ab
Binary files /dev/null and b/js/perf/arrows/multi/latlong/schema.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/origins/records.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/origins/records.arrow b/js/perf/arrows/multi/origins/records.arrow
new file mode 100644
index 0000000..49a8c40
Binary files /dev/null and b/js/perf/arrows/multi/origins/records.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/multi/origins/schema.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/multi/origins/schema.arrow b/js/perf/arrows/multi/origins/schema.arrow
new file mode 100644
index 0000000..0d10fb0
Binary files /dev/null and b/js/perf/arrows/multi/origins/schema.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/stream/dictionary.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/stream/dictionary.arrow b/js/perf/arrows/stream/dictionary.arrow
new file mode 100644
index 0000000..17ca48b
Binary files /dev/null and b/js/perf/arrows/stream/dictionary.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/stream/simple.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/stream/simple.arrow b/js/perf/arrows/stream/simple.arrow
new file mode 100644
index 0000000..2c68c0e
Binary files /dev/null and b/js/perf/arrows/stream/simple.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/arrows/stream/struct.arrow
----------------------------------------------------------------------
diff --git a/js/perf/arrows/stream/struct.arrow b/js/perf/arrows/stream/struct.arrow
new file mode 100644
index 0000000..4e97b70
Binary files /dev/null and b/js/perf/arrows/stream/struct.arrow differ

http://git-wip-us.apache.org/repos/asf/arrow/blob/0c8853f9/js/perf/config.js
----------------------------------------------------------------------
diff --git a/js/perf/config.js b/js/perf/config.js
new file mode 100644
index 0000000..4fbcda3
--- /dev/null
+++ b/js/perf/config.js
@@ -0,0 +1,38 @@
+// 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.
+
+const fs = require('fs');
+const path = require('path');
+const arrowFormats = ['file', 'stream'];
+const arrowFileNames = ['simple', 'struct', 'dictionary'];
+const multipartArrows = ['count', 'latlong', 'origins'];
+let arrowTestConfigurations = [];
+
+arrowTestConfigurations = multipartArrows.reduce((configs, folder) => {
+    const schemaPath = path.resolve(__dirname, `./arrows/multi/${folder}/schema.arrow`);
+    const recordsPath = path.resolve(__dirname, `./arrows/multi/${folder}/records.arrow`);
+    return [...configs, [`multipart ${folder}`, fs.readFileSync(schemaPath), fs.readFileSync(recordsPath)]];
+}, arrowTestConfigurations);
+
+arrowTestConfigurations = arrowFormats.reduce((configs, format) => {
+    return arrowFileNames.reduce((configs, name) => {
+        const arrowPath = path.resolve(__dirname, `./arrows/${format}/${name}.arrow`);
+        return [...configs, [`${name} ${format}`, fs.readFileSync(arrowPath)]];
+    }, configs);
+}, arrowTestConfigurations);
+
+module.exports = arrowTestConfigurations;


Mime
View raw message