From 2417bd636dda8327d1da14cb50fc26409e14cf63 Mon Sep 17 00:00:00 2001 From: Filipp Riabchun Date: Mon, 15 Aug 2016 16:29:02 +0400 Subject: [PATCH] feat(http): allow lazy (cancellable) requests PR #388 ISSUES CLOSED: #355 --- http/src/MainHTTPSource.js | 34 ++++++++ http/src/MainHTTPSource.js.map | 1 + http/src/http-driver.js | 154 +++++++++++++++++++++++++++++++++ http/src/http-driver.js.map | 1 + http/src/http-driver.ts | 11 ++- http/src/interfaces.js | 2 + http/src/interfaces.js.map | 1 + http/src/interfaces.ts | 1 + http/src/isolate.js | 21 +++++ http/src/isolate.js.map | 1 + http/test/node.js | 55 ++++++++++++ 11 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 http/src/MainHTTPSource.js create mode 100644 http/src/MainHTTPSource.js.map create mode 100644 http/src/http-driver.js create mode 100644 http/src/http-driver.js.map create mode 100644 http/src/interfaces.js create mode 100644 http/src/interfaces.js.map create mode 100644 http/src/isolate.js create mode 100644 http/src/isolate.js.map diff --git a/http/src/MainHTTPSource.js b/http/src/MainHTTPSource.js new file mode 100644 index 000000000..f0d4d7d8f --- /dev/null +++ b/http/src/MainHTTPSource.js @@ -0,0 +1,34 @@ +"use strict"; +var isolate_1 = require('./isolate'); +var xstream_adapter_1 = require('@cycle/xstream-adapter'); +var MainHTTPSource = (function () { + function MainHTTPSource(_res$$, runStreamAdapter, _namespace) { + if (_namespace === void 0) { _namespace = []; } + this._res$$ = _res$$; + this.runStreamAdapter = runStreamAdapter; + this._namespace = _namespace; + this.isolateSource = isolate_1.isolateSource; + this.isolateSink = isolate_1.isolateSink; + } + Object.defineProperty(MainHTTPSource.prototype, "response$$", { + get: function () { + return this.runStreamAdapter.adapt(this._res$$, xstream_adapter_1["default"].streamSubscribe); + }, + enumerable: true, + configurable: true + }); + MainHTTPSource.prototype.filter = function (predicate) { + var filteredResponse$$ = this._res$$.filter(predicate); + return new MainHTTPSource(filteredResponse$$, this.runStreamAdapter, this._namespace); + }; + MainHTTPSource.prototype.select = function (category) { + var res$$ = this._res$$; + if (category) { + res$$ = this._res$$.filter(function (res$) { return res$.request && res$.request.category === category; }); + } + return this.runStreamAdapter.adapt(res$$, xstream_adapter_1["default"].streamSubscribe); + }; + return MainHTTPSource; +}()); +exports.MainHTTPSource = MainHTTPSource; +//# sourceMappingURL=MainHTTPSource.js.map \ No newline at end of file diff --git a/http/src/MainHTTPSource.js.map b/http/src/MainHTTPSource.js.map new file mode 100644 index 000000000..98b375982 --- /dev/null +++ b/http/src/MainHTTPSource.js.map @@ -0,0 +1 @@ +{"version":3,"file":"MainHTTPSource.js","sourceRoot":"","sources":["MainHTTPSource.ts"],"names":[],"mappings":";AAEA,wBAAyC,WAAW,CAAC,CAAA;AAErD,gCAA2B,wBAAwB,CAAC,CAAA;AAGpD;IACE,wBAAoB,MAAuD,EACvD,gBAA+B,EAC/B,UAA8B;QAAtC,0BAAsC,GAAtC,eAAsC;QAF9B,WAAM,GAAN,MAAM,CAAiD;QACvD,qBAAgB,GAAhB,gBAAgB,CAAe;QAC/B,eAAU,GAAV,UAAU,CAAoB;QAyB3C,kBAAa,GAAsD,uBAAa,CAAC;QACjF,gBAAW,GAAsD,qBAAW,CAAC;IAzBpF,CAAC;IAED,sBAAI,sCAAU;aAAd;YACE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAChC,IAAI,CAAC,MAAM,EACX,4BAAc,CAAC,eAAe,CAC/B,CAAC;QACJ,CAAC;;;OAAA;IAED,+BAAM,GAAN,UAAO,SAA0E;QAC/E,IAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,cAAc,CAAC,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACxF,CAAC;IAED,+BAAM,GAAN,UAAO,QAAiB;QACtB,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CACxB,UAAA,IAAI,IAAI,OAAA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAlD,CAAkD,CAC3D,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,4BAAc,CAAC,eAAe,CAAC,CAAC;IAC5E,CAAC;IAIH,qBAAC;AAAD,CAAC,AA9BD,IA8BC;AA9BY,sBAAc,iBA8B1B,CAAA"} \ No newline at end of file diff --git a/http/src/http-driver.js b/http/src/http-driver.js new file mode 100644 index 000000000..3f290a6da --- /dev/null +++ b/http/src/http-driver.js @@ -0,0 +1,154 @@ +"use strict"; +var xstream_1 = require('xstream'); +var MainHTTPSource_1 = require('./MainHTTPSource'); +var xstream_adapter_1 = require('@cycle/xstream-adapter'); +var superagent = require('superagent'); +function preprocessReqOptions(reqOptions) { + reqOptions.withCredentials = reqOptions.withCredentials || false; + reqOptions.redirects = typeof reqOptions.redirects === 'number' ? reqOptions.redirects : 5; + reqOptions.method = reqOptions.method || "get"; + return reqOptions; +} +function optionsToSuperagent(rawReqOptions) { + var reqOptions = preprocessReqOptions(rawReqOptions); + if (typeof reqOptions.url !== "string") { + throw new Error("Please provide a `url` property in the request options."); + } + var lowerCaseMethod = reqOptions.method.toLowerCase(); + var sanitizedMethod = lowerCaseMethod === "delete" ? "del" : lowerCaseMethod; + var request = superagent[sanitizedMethod](reqOptions.url); + if (typeof request.redirects === "function") { + request = request.redirects(reqOptions.redirects); + } + if (reqOptions.type) { + request = request.type(reqOptions.type); + } + if (reqOptions.send) { + request = request.send(reqOptions.send); + } + if (reqOptions.accept) { + request = request.accept(reqOptions.accept); + } + if (reqOptions.query) { + request = request.query(reqOptions.query); + } + if (reqOptions.withCredentials) { + request = request.withCredentials(); + } + if (typeof reqOptions.user === 'string' && typeof reqOptions.password === 'string') { + request = request.auth(reqOptions.user, reqOptions.password); + } + if (reqOptions.headers) { + for (var key in reqOptions.headers) { + if (reqOptions.headers.hasOwnProperty(key)) { + request = request.set(key, reqOptions.headers[key]); + } + } + } + if (reqOptions.field) { + for (var key in reqOptions.field) { + if (reqOptions.field.hasOwnProperty(key)) { + request = request.field(key, reqOptions.field[key]); + } + } + } + if (reqOptions.attach) { + for (var i = reqOptions.attach.length - 1; i >= 0; i--) { + var a = reqOptions.attach[i]; + request = request.attach(a.name, a.path, a.filename); + } + } + return request; +} +exports.optionsToSuperagent = optionsToSuperagent; +function createResponse$(reqInput) { + return xstream_1["default"].create({ + start: function startResponseStream(listener) { + try { + var reqOptions_1 = normalizeRequestInput(reqInput); + this.request = optionsToSuperagent(reqOptions_1); + if (reqOptions_1.progress) { + this.request = this.request.on('progress', function (res) { + res.request = reqOptions_1; + listener.next(res); + }); + } + this.request.end(function (err, res) { + if (err) { + listener.error(err); + } + else { + res.request = reqOptions_1; + listener.next(res); + listener.complete(); + } + }); + } + catch (err) { + listener.error(err); + } + }, + stop: function stopResponseStream() { + if (this.request && this.request.abort) { + this.request.abort(); + } + } + }); +} +exports.createResponse$ = createResponse$; +function softNormalizeRequestInput(reqInput) { + var reqOptions; + try { + reqOptions = normalizeRequestInput(reqInput); + } + catch (err) { + reqOptions = { url: 'Error', _error: err }; + } + return reqOptions; +} +function normalizeRequestInput(reqOptions) { + if (typeof reqOptions === 'string') { + return { url: reqOptions }; + } + else if (typeof reqOptions === 'object') { + return reqOptions; + } + else { + throw new Error("Observable of requests given to HTTP Driver must emit " + + "either URL strings or objects with parameters."); + } +} +function makeRequestInputToResponse$(runStreamAdapter) { + return function requestInputToResponse$(reqInput) { + var response$ = createResponse$(reqInput).remember(); + var reqOptions = softNormalizeRequestInput(reqInput); + if (!reqOptions.lazy) { + /* tslint:disable:no-empty */ + response$.addListener({ next: function () { }, error: function () { }, complete: function () { } }); + } + response$ = (runStreamAdapter) ? + runStreamAdapter.adapt(response$, xstream_adapter_1["default"].streamSubscribe) : + response$; + Object.defineProperty(response$, 'request', { + value: reqOptions, + writable: false + }); + return response$; + }; +} +function makeHTTPDriver() { + function httpDriver(request$, runSA) { + var response$$ = request$ + .map(makeRequestInputToResponse$(runSA)) + .remember(); + var httpSource = new MainHTTPSource_1.MainHTTPSource(response$$, runSA, []); + /* tslint:disable:no-empty */ + response$$.addListener({ next: function () { }, error: function () { }, complete: function () { } }); + /* tslint:enable:no-empty */ + return httpSource; + } + httpDriver.streamAdapter = xstream_adapter_1["default"]; + return httpDriver; +} +exports.makeHTTPDriver = makeHTTPDriver; +//# sourceMappingURL=http-driver.js.map \ No newline at end of file diff --git a/http/src/http-driver.js.map b/http/src/http-driver.js.map new file mode 100644 index 000000000..f38ececc2 --- /dev/null +++ b/http/src/http-driver.js.map @@ -0,0 +1 @@ +{"version":3,"file":"http-driver.js","sourceRoot":"","sources":["http-driver.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/http/src/http-driver.ts b/http/src/http-driver.ts index 80eacb80a..d3baf0440 100644 --- a/http/src/http-driver.ts +++ b/http/src/http-driver.ts @@ -128,14 +128,17 @@ function normalizeRequestInput(reqOptions: RequestInput): RequestOptions { function makeRequestInputToResponse$(runStreamAdapter: StreamAdapter) { return function requestInputToResponse$(reqInput: RequestInput): MemoryStream & ResponseStream { let response$ = createResponse$(reqInput).remember(); - /* tslint:disable:no-empty */ - response$.addListener({next: () => {}, error: () => {}, complete: () => {}}); - /* tslint:enable:no-empty */ + let reqOptions = softNormalizeRequestInput(reqInput); + if (!reqOptions.lazy) { + /* tslint:disable:no-empty */ + response$.addListener({next: () => {}, error: () => {}, complete: () => {}}); + /* tslint:enable:no-empty */ + } response$ = (runStreamAdapter) ? runStreamAdapter.adapt(response$, XStreamAdapter.streamSubscribe) : response$; Object.defineProperty(response$, 'request', { - value: softNormalizeRequestInput(reqInput), + value: reqOptions, writable: false, }); return & ResponseStream> response$; diff --git a/http/src/interfaces.js b/http/src/interfaces.js new file mode 100644 index 000000000..03a0f5c6e --- /dev/null +++ b/http/src/interfaces.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=interfaces.js.map \ No newline at end of file diff --git a/http/src/interfaces.js.map b/http/src/interfaces.js.map new file mode 100644 index 000000000..0fc31ba20 --- /dev/null +++ b/http/src/interfaces.js.map @@ -0,0 +1 @@ +{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["interfaces.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/http/src/interfaces.ts b/http/src/interfaces.ts index 4928e7076..179c4929a 100644 --- a/http/src/interfaces.ts +++ b/http/src/interfaces.ts @@ -20,6 +20,7 @@ export interface RequestOptions { withCredentials?: boolean; redirects?: number; category?: string; + lazy?: boolean; _error?: any; _namespace?: Array; } diff --git a/http/src/isolate.js b/http/src/isolate.js new file mode 100644 index 000000000..665dafa72 --- /dev/null +++ b/http/src/isolate.js @@ -0,0 +1,21 @@ +"use strict"; +function isolateSource(httpSource, scope) { + return httpSource.filter(function (res$) { + return Array.isArray(res$.request._namespace) && + res$.request._namespace.indexOf(scope) !== -1; + }); +} +exports.isolateSource = isolateSource; +function isolateSink(request$, scope) { + return request$.map(function (req) { + if (typeof req === "string") { + return { url: req, _namespace: [scope] }; + } + var reqOptions = req; + reqOptions._namespace = reqOptions._namespace || []; + reqOptions._namespace.push(scope); + return reqOptions; + }); +} +exports.isolateSink = isolateSink; +//# sourceMappingURL=isolate.js.map \ No newline at end of file diff --git a/http/src/isolate.js.map b/http/src/isolate.js.map new file mode 100644 index 000000000..e73826b21 --- /dev/null +++ b/http/src/isolate.js.map @@ -0,0 +1 @@ +{"version":3,"file":"isolate.js","sourceRoot":"","sources":["isolate.ts"],"names":[],"mappings":";AAMA,uBAA8B,UAAsB,EAAE,KAAa;IACjE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAC,IAAoB;QAC5C,OAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YACtC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAD7C,CAC6C,CAC9C,CAAC;AACJ,CAAC;AALe,qBAAa,gBAK5B,CAAA;AAED,qBAA4B,QAAgD,EAAE,KAAa;IACzF,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAC,GAAiB;QACpC,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC5B,MAAM,CAAC,EAAC,GAAG,EAAW,GAAG,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAC,CAAC;QAClD,CAAC;QACD,IAAM,UAAU,GAAoB,GAAG,CAAC;QACxC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;QACpD,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,CAAC,UAAU,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC;AAVe,mBAAW,cAU1B,CAAA"} \ No newline at end of file diff --git a/http/test/node.js b/http/test/node.js index 155e6e4fd..e51431508 100644 --- a/http/test/node.js +++ b/http/test/node.js @@ -39,6 +39,61 @@ describe('HTTP Driver in Node.js', function () { } ); + it('should not auto-execute lazy request without listening to response stream', + function(done) { + function main() { + return { + HTTP: Rx.Observable.of({ + url: uri + '/pet', + method: 'POST', + send: {name: 'Woof', species: 'Dog'}, + lazy: true + }) + } + } + + var output = Cycle(main, { HTTP: makeHTTPDriver() }); + globalSandbox.petPOSTResponse = null; + output.run(); + + setTimeout(function () { + assert.strictEqual(globalSandbox.petPOSTResponse, null); + done(); + }, 250); + } + ); + + it('should execute lazy HTTP request when listening to response stream', + function(done) { + function main() { + return { + HTTP: Rx.Observable.of({ + url: uri + '/pet', + method: 'POST', + send: {name: 'Woof', species: 'Dog'}, + lazy: true + }) + } + } + + var output = Cycle(main, { HTTP: makeHTTPDriver() }); + globalSandbox.petPOSTResponse = null; + + output.sources.HTTP.response$$ + .mergeAll() + .subscribe(); + + output.run(); + + setTimeout(function () { + assert.notStrictEqual(globalSandbox.petPOSTResponse, null); + assert.strictEqual(globalSandbox.petPOSTResponse, 'added Woof the Dog'); + globalSandbox.petPOSTResponse = null; + done(); + }, 250); + } + ); + it('should add request options object to each response', function(done) { function main() {