diff --git a/async-writer/LICENSE b/async-writer/LICENSE deleted file mode 100644 index 4e2da36e5..000000000 --- a/async-writer/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2016 eBay Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/async-writer/README.md b/async-writer/README.md deleted file mode 100644 index bfd492cd6..000000000 --- a/async-writer/README.md +++ /dev/null @@ -1,100 +0,0 @@ -async-writer -============ - -The `async-writer` module makes it possible to asynchronously write to an output stream while still flushing out bytes in the correct order. That is, the `async-writer` module allows you to write parts of a stream out of order and the `async-writer` module does the hard work of ensuring that the output bytes are flushed in the correct order. Content that is written before it is ready to be flushed is buffered and immediately flushed as soon it is ready. - -An async writer is helpful if during writing you have to wait for an asynchronous operation to complete before writing to part of a stream. As an example, you might start writing a page to produce HTML and then get to a part of the page that depends on data that has not yet been loaded. With that use case, you can continue to write the remainder of the page and still pipe out the stream to the response. The async writer will ensure that the bytes are flushed out in the correct order. - -# Installation - -``` -npm install async-writer --save -``` - -# Usage - -The simplest usage of an async writer is shown below: - -```javascript -var through = require('through'); - -var output = ''; -var stream = through(function write(data) { - output += data; - }); - -var out = require('async-writer').create(stream) - .on('error', function(err) { - // Something went wrong during writing - }) - .on('end', function() { - // Value of output: "ABC" - }); - -out.write('A'); -out.write('B'); -out.write('C'); -out.end(); -``` - -Asynchronous, out-of-order writing to an output stream is shown below: - -```javascript -var through = require('through'); - -var output = ''; -var stream = through(function write(data) { - output += data; - }); - -var out = require('async-writer').create(stream) - .on('error', function(err) { - // Something went wrong during writing - }) - .on('end', function() { - // Value of output: "ABC" - }); - -out.write('A'); - -var asyncOut = out.beginAsync(); -setTimeout(function() { - asyncOut.write('B'); - asyncOut.end(); -}, 1000); - -out.write('C'); -out.end(); -``` - -You can also pipe another stream to a async writer. For example, the following code illustrates how multiple templates could be written to the same async writer: - -```javascript -var through = require('through'); - -var output = ''; -var stream = through(function write(data) { - output += data; - }); - -var out = require('async-writer').create(stream) - .on('error', function(err) { - // Something went wrong during writing - }) - .on('end', function() { - // Value of output: "ABC" - }); - -out.write('A'); - -var asyncOut = out.beginAsync(); -require('fs').createReadStream('b.txt', 'utf8') - .pipe(asyncOut); - -out.write('C'); -out.end(); -``` - -# Debug mode - -Just replace `require('async-writer')` with `require('async-writer/debug')` and you'll get debug output and diagrams of the current state. \ No newline at end of file diff --git a/async-writer/debug.js b/async-writer/debug.js deleted file mode 100644 index 976d2e6d5..000000000 --- a/async-writer/debug.js +++ /dev/null @@ -1,172 +0,0 @@ -var index = require('./') -var streamId = 0; - -Object.keys(index).forEach(function(key) { - exports[key] = index[key]; -}) - -exports.create = function(writer, options) { - var asyncStream = index.create.apply(index, arguments); - var state = { - bufferId: 0, - substreamId: 0 - } - - if(arguments.length === 1 && typeof writer.write !== 'function') { - options = writer; - writer = null; - } - - asyncStream.name = (options && options.name) || 'originalStream'+(streamId++ ? streamId : ''); - asyncStream.on('finish', function() { - streamId--; - }); - - asyncStream.writer.name = 'originalWriter'; - - console.log('\n' + bold(asyncStream.name + green('.create()'))); - console.log(createDiagram(asyncStream)); - - logEvents(asyncStream, state); - - return asyncStream; -} - -function logEvents(asyncStream, state) { - var _write = asyncStream.write; - asyncStream.write = function(str) { - var thisStream = _write.apply(this, arguments); - console.log('\n' + bold(this.name + cyan('.write(') + reset(grey(str)) + cyan(')'))); - console.log(createDiagram(this)); - return thisStream; - } - - var _beginAsync = asyncStream.beginAsync; - asyncStream.beginAsync = function() { - var newStream = _beginAsync.apply(this, arguments); - newStream.name = newStream.name || 'stream'+(++state.substreamId); - this.writer.name = 'buffer'+(++state.bufferId); - console.log('\n' + bold(newStream.name + grey(' = ') + this.name + green('.beginAsync()'))); - console.log(createDiagram(this)); - logEvents(newStream, state); - return newStream; - } - - var _end = asyncStream.end; - asyncStream.end = function() { - var thisStream = _end.apply(this, arguments); - console.log('\n' + bold(this.name + red('.end()'))); - console.log(createDiagram(this)); - return thisStream; - } -} - -function createDiagram(asyncStream) { - var streams = []; - var writers = []; - var contents = []; - - var currentWriter = asyncStream._originalWriter; - - while(currentWriter) { - var currentIndex = writers.length; - - writers.push(currentWriter.name); - contents.push(currentWriter.toString()); - - if(currentWriter.stream) { - streams[currentIndex] = currentWriter.stream.name; - } - - if(currentWriter.stream === asyncStream) { - streams[currentIndex] += '*' - } - - currentWriter = currentWriter.next; - } - - var line1 = ''; - var line2 = ''; - var line3 = ''; - var line4 = ''; - - writers.forEach(function(writer, i) { - var stream = streams[i] || ''; - var content = contents[i] || ''; - var longest = Math.max(writer.length, stream.length, content.length); - - line1 += stream + ' '.repeat(longest-stream.length); - - if(stream) { - line2 += '↕' + ' '.repeat(longest-1); - } else { - line2 += ' '.repeat(longest); - } - - line3 += writer + ' '.repeat(longest-writer.length); - line4 += content + ' '.repeat(longest-content.length); - - if(i !== writers.length-1) { - line1 += ' '; - line2 += ' '; - line3 += grey(' → '); - line4 += ' '; - } - }) - - if(line1 === ' '.repeat(line1.length)) line1 = null; - if(line2 === ' '.repeat(line2.length)) line2 = null; - - return (line1 ? line1 + '\n' : '') + (line2 ? grey(line2) + '\n' : '') + line3 + '\n' + magenta(line4) + '\n'; -} - -var canFormat = (function () { - if (process.stdout && !process.stdout.isTTY) { - return false; - } - - if (process.platform === 'win32') { - return true; - } - - if ('COLORTERM' in process.env) { - return true; - } - - if (process.env.TERM === 'dumb') { - return false; - } - - if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { - return true; - } - - return false; -})(); - -function format(str, begin, end) { - begin = canFormat ? '\u001b['+begin+'m' : ''; - end = canFormat ? '\u001b['+end+'m' : ''; - return begin + str + end; -} -function reset(str) { - return format(str, 0, 0); -} -function red(str) { - return format(str, 31, 39); -} -function cyan(str) { - return format(str, 36, 39); -} -function magenta(str) { - return format(str, 35, 39); -} -function green(str) { - return format(str, 32, 39); -} -function grey(str) { - return format(str, 90, 39); -} -function bold(str) { - return format(str, 1, 22); -} diff --git a/async-writer/package.json b/async-writer/package.json deleted file mode 100644 index 7c00d3cef..000000000 --- a/async-writer/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "async-writer", - "description": "The async-writer module makes it possible to asynchronously write data to an output stream while still flushing out bytes in the correct order", - "repository": { - "type": "git", - "url": "https://github.com/marko-js/async-writer.git" - }, - "scripts": { - "test": "npm run mocha && npm run jshint", - "mocha": "mocha --ui bdd --reporter spec ./test/", - "mocha-debug": "node-debug _mocha ./test/", - "jshint": "jshint src/" - }, - "author": "Patrick Steele-Idem ", - "maintainers": [ - "Patrick Steele-Idem ", - "Michael Rawlings " - ], - "dependencies": { - "events": "^1.0.2", - "marko-dom": "^1.0.0", - "marko-html-util": "^1.0.0" - }, - "devDependencies": { - "chai": "~1.8.1", - "jshint": "^2.9.3", - "mocha": "~1.15.1", - "through": "^2.3.4", - "through2": "^0.6.5" - }, - "license": "Apache-2.0", - "bin": {}, - "main": "src/index.js", - "publishConfig": { - "registry": "https://registry.npmjs.org/" - }, - "version": "3.0.1" -} diff --git a/async-writer/src/index.js b/async-writer/src/index.js deleted file mode 100644 index 85b261270..000000000 --- a/async-writer/src/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -var AsyncStream = require('./AsyncStream'); - -exports.create = function (writer, options) { - var global; - var shouldBuffer; - - if(arguments.length === 1 && typeof writer.write !== 'function') { - options = writer; - writer = null; - } - - if (options) { - global = options.global; - shouldBuffer = options.buffer === true; - } - - var asyncStream = new AsyncStream( - global, - writer, - null /* Internally used to pass state */, - shouldBuffer); //Create a new context using the writer provided - - return asyncStream; -}; - -exports.AsyncStream = exports.AsyncWriter /* legacy */ = AsyncStream; -exports.enableAsyncStackTrace = AsyncStream.enableAsyncStackTrace; diff --git a/async-writer/test/.jshintrc b/async-writer/test/.jshintrc deleted file mode 100644 index b6fbb7e15..000000000 --- a/async-writer/test/.jshintrc +++ /dev/null @@ -1,65 +0,0 @@ -{ - "predef": [ - "jasmine", - "spyOn", - "it", - "xit", - "console", - "describe", - "xdescribe", - "beforeEach", - "before", - "after", - "waits", - "waitsFor", - "runs", - "raptor", - "$rset", - "$radd", - "$rget", - "$renv", - "$rwidgets", - "$", - "dust", - "__rhinoHelpers", - "Packages", - "JavaAdapter", - "unescape" - ], - - "globals": { - "require": true, - "describe": true, - "it": true - }, - - "node" : true, - "es5" : false, - "browser" : true, - "boss" : false, - "curly": false, - "debug": false, - "devel": false, - "eqeqeq": true, - "evil": true, - "forin": false, - "immed": true, - "laxbreak": false, - "newcap": true, - "noarg": true, - "noempty": false, - "nonew": true, - "nomen": false, - "onevar": false, - "plusplus": false, - "regexp": false, - "undef": true, - "sub": false, - "white": false, - "eqeqeq": false, - "latedef": true, - "unused": "vars", - - /* Relaxing options: */ - "eqnull": true -} \ No newline at end of file diff --git a/package.json b/package.json index 5014611b8..dd9938e5f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "argly": "^1.0.0", "app-module-path": "^1.0.5", "async-vdom-builder": "^1.0.0", - "async-writer": "^3.0.0", "browser-refresh-client": "^1.0.0", "char-props": "~0.1.5", "deresolve": "^1.0.0", @@ -91,7 +90,8 @@ "phantomjs-prebuilt": "^2.1.13", "request": "^2.72.0", "require-self-ref": "^2.0.1", - "through": "^2.3.4" + "through": "^2.3.4", + "through2": "^2.0.1" }, "license": "Apache-2.0", "bin": { diff --git a/async-writer/src/AsyncStream.js b/runtime/html/AsyncStream.js similarity index 100% rename from async-writer/src/AsyncStream.js rename to runtime/html/AsyncStream.js diff --git a/async-writer/src/BufferedWriter.js b/runtime/html/BufferedWriter.js similarity index 100% rename from async-writer/src/BufferedWriter.js rename to runtime/html/BufferedWriter.js diff --git a/async-writer/src/StringWriter.js b/runtime/html/StringWriter.js similarity index 100% rename from async-writer/src/StringWriter.js rename to runtime/html/StringWriter.js diff --git a/runtime/html/index.js b/runtime/html/index.js index b3ae8d22d..6c27cc08f 100644 --- a/runtime/html/index.js +++ b/runtime/html/index.js @@ -19,8 +19,8 @@ var helpers; } }; -var asyncWriter = require('async-writer'); -var AsyncStream = asyncWriter.AsyncStream; + +var AsyncStream = require('./AsyncStream'); function createOut(globalData) { return new AsyncStream(globalData); @@ -36,7 +36,7 @@ exports.AsyncStream = AsyncStream; function Template(path, func, options) { this.path = path; this._ = func; - this._shouldBuffer = !options || options.shouldBuffer !=- false; + this._shouldBuffer = !options || options.shouldBuffer !== false; } Template.prototype = { @@ -168,7 +168,6 @@ exports.Template = Template; helpers = require('./helpers'); exports.helpers = helpers; +exports.enableAsyncStackTrace = AsyncStream.enableAsyncStackTrace; - -require('../')._setRuntime(exports); - +require('../')._setRuntime(exports); \ No newline at end of file diff --git a/runtime/stream.js b/runtime/stream.js index 9d74d3b24..b534093d8 100644 --- a/runtime/stream.js +++ b/runtime/stream.js @@ -9,13 +9,13 @@ line to your app: */ var stream = require('stream'); -var asyncWriter = require('async-writer'); +var AsyncStream = require('./html/AsyncStream'); function Readable(template, data, options) { Readable.$super.call(this); this._t = template; this._d = data; - this._options = options; + this._shouldBuffer = !options || options.shouldBuffer !== false; this._rendered = false; } @@ -37,8 +37,9 @@ Readable.prototype = { var template = this._t; var data = this._d; - - var out = asyncWriter.create(this, this._options); + var globalData = data && data.$global; + var shouldBuffer = this._shouldBuffer; + var out = new AsyncStream(globalData, this, null, shouldBuffer); template.render(data, out); out.end(); } diff --git a/async-writer/test/test.js b/test/AsyncStream-test.js similarity index 91% rename from async-writer/test/test.js rename to test/AsyncStream-test.js index d818e10f8..4ca8ebf46 100644 --- a/async-writer/test/test.js +++ b/test/AsyncStream-test.js @@ -6,7 +6,7 @@ var expect = require('chai').expect; var nodePath = require('path'); var fs = require('fs'); var fsReadOptions = { encoding: 'utf8' }; -var asyncWriter = require('../'); +var AsyncStream = require('../runtime/html/AsyncStream'); /* DEBUG INFO: =========== @@ -15,6 +15,22 @@ var asyncWriter = require('../'); // var asyncWriter = require('../debug'); +function createAsyncStream(options) { + if (typeof options.write === 'function') { + return new AsyncStream(null, options); + } else if (typeof options === 'object') { + var name = options.name; + var globalData = options.global; + var out = new AsyncStream(globalData); + if (name) { + out.name = name; + } + return out; + } else { + return new AsyncStream(); + } +} + describe('async-writer' , function() { beforeEach(function(done) { @@ -28,7 +44,7 @@ describe('async-writer' , function() { }); it('should render a series of sync calls correctly', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); out.write('2'); out.write('3'); @@ -42,7 +58,7 @@ describe('async-writer' , function() { }); it('should render a series of sync and async calls correctly', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut1 = out.beginAsync(); @@ -68,7 +84,7 @@ describe('async-writer' , function() { }); it('should allow an async fragment to complete synchronously', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync(); @@ -87,7 +103,7 @@ describe('async-writer' , function() { }); it('should allow the async callback to provide data', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync(); @@ -105,7 +121,7 @@ describe('async-writer' , function() { }); it('should handle timeouts correctly', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); var errors = []; out.on('error', function(e) { errors.push(e); @@ -130,7 +146,7 @@ describe('async-writer' , function() { }); it('should render nested async calls correctly', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync(); @@ -178,7 +194,7 @@ describe('async-writer' , function() { }); it('should handle odd execution ordering', function(done) { - var outA = asyncWriter.create({ name:'outA' }); + var outA = createAsyncStream({ name:'outA' }); outA.on('finish', function() { var output = outA.getOutput(); @@ -212,7 +228,7 @@ describe('async-writer' , function() { }); it('should handle sync errors correctly', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); var errors = []; out.on('error', function(e) { errors.push(e); @@ -236,7 +252,7 @@ describe('async-writer' , function() { it('should support chaining', function(done) { var errors = []; - var out = asyncWriter.create() + var out = new AsyncStream() .on('error', function(e) { errors.push(e); }) @@ -268,7 +284,7 @@ describe('async-writer' , function() { ); var errors = []; - var out = asyncWriter.create(through2) + var out = createAsyncStream(through2) .on('error', function(e) { errors.push(e); }) @@ -300,7 +316,7 @@ describe('async-writer' , function() { ); var errors = []; - var out = asyncWriter.create(through) + var out = createAsyncStream(through) .on('error', function(e) { errors.push(e); }) @@ -336,7 +352,7 @@ describe('async-writer' , function() { }); - out = asyncWriter.create(out) + out = createAsyncStream(out) .on('error', function(e) { errors.push(e); }) @@ -356,12 +372,12 @@ describe('async-writer' , function() { it('should support piping to an async writer', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync(); - var helloReadStream = fs.createReadStream(nodePath.join(__dirname, 'hello.txt'), fsReadOptions); + var helloReadStream = fs.createReadStream(nodePath.join(__dirname, 'fixtures/AsyncStream/hello.txt'), fsReadOptions); helloReadStream.pipe(asyncOut); out.write('2'); @@ -391,12 +407,12 @@ describe('async-writer' , function() { done(e); }); - out = asyncWriter.create(through); + out = createAsyncStream(through); out.write('1'); var asyncOut = out.beginAsync(); - var helloReadStream = fs.createReadStream(nodePath.join(__dirname, 'hello.txt'), fsReadOptions); + var helloReadStream = fs.createReadStream(nodePath.join(__dirname, 'fixtures/AsyncStream/hello.txt'), fsReadOptions); helloReadStream.pipe(asyncOut); out.write('2'); @@ -411,7 +427,7 @@ describe('async-writer' , function() { }); it('should allow an async fragment to flush last', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync({last: true}); @@ -431,7 +447,7 @@ describe('async-writer' , function() { }); it('should allow an async fragment to flush last asynchronously', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut = out.beginAsync({last: true}); @@ -467,7 +483,7 @@ describe('async-writer' , function() { done(); }); - var out = asyncWriter.create(passthrough); + var out = createAsyncStream(passthrough); out.write('hello'); out.error('test'); }); @@ -477,7 +493,7 @@ describe('async-writer' , function() { var PassThrough = stream.PassThrough; var passthrough = new PassThrough(); - var out = asyncWriter.create(passthrough); + var out = createAsyncStream(passthrough); out.write('hello'); try { out.error('test'); @@ -489,7 +505,7 @@ describe('async-writer' , function() { }); it('should allow multiple onLast calls', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.write('1'); var asyncOut1 = out.beginAsync(); @@ -548,7 +564,7 @@ describe('async-writer' , function() { done(); }); - var out = asyncWriter.create(through); + var out = createAsyncStream(through); out.write('1'); var asyncOut1 = out.beginAsync(); @@ -582,7 +598,7 @@ describe('async-writer' , function() { done(); }); - var out = asyncWriter.create(through); + var out = createAsyncStream(through); out.write('1'); var asyncOut1 = out.beginAsync({ timeout: 50}); @@ -621,7 +637,7 @@ describe('async-writer' , function() { done(); }); - var out = asyncWriter.create(through); + var out = createAsyncStream(through); out.write('1'); var asyncOut1 = out.beginAsync(); @@ -662,7 +678,7 @@ describe('async-writer' , function() { done(); }); - var out = asyncWriter.create(through); + var out = createAsyncStream(through); out.write('1'); var asyncOut1 = out.beginAsync(); @@ -686,8 +702,8 @@ describe('async-writer' , function() { it('should track finished correctly', function(done) { var myGlobal = {}; - var out1 = asyncWriter.create(null, {global: myGlobal}); - var out2 = asyncWriter.create(null, {global: myGlobal}); + var out1 = createAsyncStream({global: myGlobal}); + var out2 = createAsyncStream({global: myGlobal}); function handleFinished() { if (out1.data.__finishedFlag && out2.data.__finishedFlag) { @@ -723,7 +739,7 @@ describe('async-writer' , function() { }); it('should end correctly if top-level is ended asynchronously', function(done) { - var out = asyncWriter.create(); + var out = new AsyncStream(); out.name = 'outer'; out.on('finish', function() { @@ -748,7 +764,7 @@ describe('async-writer' , function() { }); it('should end correctly if top-level is ended asynchronously when providing custom globals', function(done) { - var out = asyncWriter.create(null, {global: { foo: 'bar' }}); + var out = createAsyncStream({global: { foo: 'bar' }}); out.name = 'outer'; out.on('finish', function() { @@ -783,7 +799,7 @@ describe('async-writer' , function() { } ); - var out = asyncWriter.create(stream); + var out = createAsyncStream(stream); expect(out.stream).to.equal(stream); var asyncOut1 = out.beginAsync(); diff --git a/async-writer/test/hello.txt b/test/fixtures/AsyncStream/hello.txt similarity index 100% rename from async-writer/test/hello.txt rename to test/fixtures/AsyncStream/hello.txt