Socket
Socket
Sign inDemoInstall

synchronous-promise

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

synchronous-promise - npm Package Compare versions

Comparing version 1.0.12 to 1.0.13

237

dist/synchronous-promise.js

@@ -9,23 +9,39 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

function looksLikePromise(thing) {
return thing &&
thing.then &&
typeof (thing.then) === "function" &&
typeof (thing.catch) === "function";
}
function SynchronousPromise(ctorFunction) {
this.status = "pending";
this._paused = false;
this._next = [];
this._catchFunctions = [];
this._paused = false;
this._data = [];
this._runConstructorFunction(ctorFunction);
}
SynchronousPromise.prototype = {
then: function (next, fail) {
this._next.push([next, fail]);
if (this._isPendingResolutionOrRejection()) {
return this;
}
if (this.status === "resolved") {
this._applyNext();
return this._applyNext();
}
return this;
return this._applyCatch();
},
catch: function (fn) {
this._catchFunctions.push(fn);
if (this.status === "rejected") {
this._applyCatch();
this._next.push([undefined, fn]);
if (this._isPendingResolutionOrRejection()) {
return this;
}
return this;
return this._applyCatch();
},

@@ -38,34 +54,31 @@ pause: function () {

this._paused = false;
var self = this;
this._applyCatch().then(function () {
self._applyNext();
});
return this;
return this._applyNext();
},
_runConstructorFunction: function (ctorFunction) {
var self = this;
var doCatch = function (args) {
self._catchData = argumentsToArray(args);
this._next.push([
function (r) { return r; },
function (err) { throw err; }
]);
var isRun = false;
ctorFunction(function (result) {
if (isRun) {
return;
}
isRun = true;
self._setResolved();
self._data = [result];
self._applyNext();
}, function (err) {
if (isRun) {
return;
}
isRun = true;
self._setRejected();
self._data = [err];
self._applyCatch();
};
ctorFunction(function () {
self._data = argumentsToArray(arguments);
var doResolve = function () {
self._setResolved();
self._applyNext();
};
if (self._looksLikePromise(self._data[0])) {
self._data[0].then(function () {
self._data = argumentsToArray(arguments);
doResolve();
}).catch(function () {
doCatch(arguments);
});
} else {
doResolve();
}
}, function () {
self._setRejected();
doCatch(arguments);
});

@@ -79,79 +92,116 @@ },

},
_setPending: function () {
this.status = "pending";
},
_applyNext: function () {
if (this.status === "rejected") {
return this._applyCatch();
}
if (this._next.length === 0 || this._paused) {
return;
return this;
}
var next = this._next.shift();
var next = this._findFirstResolutionHandler();
if (!next) {
return this;
}
try {
if (!next) {
return;
var data = next.apply(null, this._data);
this._setResolved();
if (looksLikePromise(data)) {
this._handleNestedPromise(data);
return this;
}
var data = next[0].apply(null, this._data),
self = this;
if (this._looksLikePromise(data)) {
data.then(function () {
self._data = Array.prototype.slice.apply(arguments);
self._applyNext();
}).catch(function (e) {
throw e;
});
} else {
this._data = [data];
this._applyNext();
}
this._data = [data];
return this._applyNext();
} catch (e) {
this._next = [];
this._data = undefined;
if (next[1]) {
try { next[1](e); } catch (ignore) { }
} else {
this._catchData = [e];
this._setRejected();
this._applyCatch();
}
this._setRejected();
this._data = [e];
return this._applyCatch();
}
},
_looksLikePromise: function (thing) {
return thing &&
thing.then &&
typeof (thing.then) === "function";
},
_applyCatch: function () {
if (this._paused || this._catchFunctions.length === 0) {
return SynchronousPromise.resolve();
if (this.status === "resolved") {
return this._applyNext();
}
var catchFunction = (this._catchFunctions || []).shift(),
catchData = this._catchData;
if (!(catchFunction && catchData)) {
return SynchronousPromise.resolve(); // nyom
if (this._next.length === 0 || this._paused) {
return this;
}
var result = catchFunction.apply(null, catchData);
if (this._looksLikePromise(result)) {
var self = this;
result.then(function () {
self._data = Array.prototype.slice.apply(arguments);
self._setResolved();
self._applyNext();
}).catch(function () {
self._catchData = Array.prototype.slice.apply(arguments);
self._applyCatch();
});
} else {
var next = this._findFirstRejectionHandler();
if (!next) {
return this;
}
try {
var data = next.apply(null, this._data);
if (looksLikePromise(data)) {
this._handleNestedPromise(data);
return this;
}
this._setResolved();
this._data = [data];
return this._applyNext();
} catch (e) {
this._setRejected();
this._next = [];
this._data = undefined;
this._data = [e];
return this._applyCatch();
}
return SynchronousPromise.reject();
},
_handleNestedPromise: function (promise) {
this._setPending();
var self = this;
promise.then(function (d) {
self._setResolved();
self._data = [d];
self._applyNext();
}).catch(function (e) {
self._setRejected();
self._data = [e];
self._applyCatch();
});
},
_isPendingResolutionOrRejection: function () {
return this.status === "pending";
},
_findFirstResolutionHandler: function () {
var next;
while (!next && this._next.length > 0) {
next = this._next.shift()[0];
}
return next;
},
_findFirstRejectionHandler: function () {
var next;
while (!next && this._next.length > 0) {
next = this._next.shift()[1];
}
return next;
}
};
SynchronousPromise.resolve = function () {
var args = arguments;
SynchronousPromise.resolve = function (data) {
if (looksLikePromise(data)) {
return data;
}
return new SynchronousPromise(function (resolve) {
resolve.apply(null, argumentsToArray(args));
resolve(data);
});
};
SynchronousPromise.reject = function () {
var args = arguments;
SynchronousPromise.reject = function (error) {
if (looksLikePromise(error)) {
return error;
}
return new SynchronousPromise(function (resolve, reject) {
reject.apply(null, argumentsToArray(args));
reject(error);
});

@@ -207,2 +257,3 @@ };

},{}]},{},[1]);

@@ -0,0 +0,0 @@ export interface SynchronousPromise<T> extends Promise<T> {

@@ -6,23 +6,39 @@ "use strict";

function looksLikePromise(thing) {
return thing &&
thing.then &&
typeof (thing.then) === "function" &&
typeof (thing.catch) === "function";
}
function SynchronousPromise(ctorFunction) {
this.status = "pending";
this._paused = false;
this._next = [];
this._catchFunctions = [];
this._paused = false;
this._data = [];
this._runConstructorFunction(ctorFunction);
}
SynchronousPromise.prototype = {
then: function (next, fail) {
this._next.push([next, fail]);
if (this._isPendingResolutionOrRejection()) {
return this;
}
if (this.status === "resolved") {
this._applyNext();
return this._applyNext();
}
return this;
return this._applyCatch();
},
catch: function (fn) {
this._catchFunctions.push(fn);
if (this.status === "rejected") {
this._applyCatch();
this._next.push([undefined, fn]);
if (this._isPendingResolutionOrRejection()) {
return this;
}
return this;
return this._applyCatch();
},

@@ -35,34 +51,31 @@ pause: function () {

this._paused = false;
var self = this;
this._applyCatch().then(function () {
self._applyNext();
});
return this;
return this._applyNext();
},
_runConstructorFunction: function (ctorFunction) {
var self = this;
var doCatch = function (args) {
self._catchData = argumentsToArray(args);
this._next.push([
function (r) { return r; },
function (err) { throw err; }
]);
var isRun = false;
ctorFunction(function (result) {
if (isRun) {
return;
}
isRun = true;
self._setResolved();
self._data = [result];
self._applyNext();
}, function (err) {
if (isRun) {
return;
}
isRun = true;
self._setRejected();
self._data = [err];
self._applyCatch();
};
ctorFunction(function () {
self._data = argumentsToArray(arguments);
var doResolve = function () {
self._setResolved();
self._applyNext();
};
if (self._looksLikePromise(self._data[0])) {
self._data[0].then(function () {
self._data = argumentsToArray(arguments);
doResolve();
}).catch(function () {
doCatch(arguments);
});
} else {
doResolve();
}
}, function () {
self._setRejected();
doCatch(arguments);
});

@@ -76,79 +89,116 @@ },

},
_setPending: function () {
this.status = "pending";
},
_applyNext: function () {
if (this.status === "rejected") {
return this._applyCatch();
}
if (this._next.length === 0 || this._paused) {
return;
return this;
}
var next = this._next.shift();
var next = this._findFirstResolutionHandler();
if (!next) {
return this;
}
try {
if (!next) {
return;
var data = next.apply(null, this._data);
this._setResolved();
if (looksLikePromise(data)) {
this._handleNestedPromise(data);
return this;
}
var data = next[0].apply(null, this._data),
self = this;
if (this._looksLikePromise(data)) {
data.then(function () {
self._data = Array.prototype.slice.apply(arguments);
self._applyNext();
}).catch(function (e) {
throw e;
});
} else {
this._data = [data];
this._applyNext();
}
this._data = [data];
return this._applyNext();
} catch (e) {
this._next = [];
this._data = undefined;
if (next[1]) {
try { next[1](e); } catch (ignore) { }
} else {
this._catchData = [e];
this._setRejected();
this._applyCatch();
}
this._setRejected();
this._data = [e];
return this._applyCatch();
}
},
_looksLikePromise: function (thing) {
return thing &&
thing.then &&
typeof (thing.then) === "function";
},
_applyCatch: function () {
if (this._paused || this._catchFunctions.length === 0) {
return SynchronousPromise.resolve();
if (this.status === "resolved") {
return this._applyNext();
}
var catchFunction = (this._catchFunctions || []).shift(),
catchData = this._catchData;
if (!(catchFunction && catchData)) {
return SynchronousPromise.resolve(); // nyom
if (this._next.length === 0 || this._paused) {
return this;
}
var result = catchFunction.apply(null, catchData);
if (this._looksLikePromise(result)) {
var self = this;
result.then(function () {
self._data = Array.prototype.slice.apply(arguments);
self._setResolved();
self._applyNext();
}).catch(function () {
self._catchData = Array.prototype.slice.apply(arguments);
self._applyCatch();
});
} else {
var next = this._findFirstRejectionHandler();
if (!next) {
return this;
}
try {
var data = next.apply(null, this._data);
if (looksLikePromise(data)) {
this._handleNestedPromise(data);
return this;
}
this._setResolved();
this._data = [data];
return this._applyNext();
} catch (e) {
this._setRejected();
this._next = [];
this._data = undefined;
this._data = [e];
return this._applyCatch();
}
return SynchronousPromise.reject();
},
_handleNestedPromise: function (promise) {
this._setPending();
var self = this;
promise.then(function (d) {
self._setResolved();
self._data = [d];
self._applyNext();
}).catch(function (e) {
self._setRejected();
self._data = [e];
self._applyCatch();
});
},
_isPendingResolutionOrRejection: function () {
return this.status === "pending";
},
_findFirstResolutionHandler: function () {
var next;
while (!next && this._next.length > 0) {
next = this._next.shift()[0];
}
return next;
},
_findFirstRejectionHandler: function () {
var next;
while (!next && this._next.length > 0) {
next = this._next.shift()[1];
}
return next;
}
};
SynchronousPromise.resolve = function () {
var args = arguments;
SynchronousPromise.resolve = function (data) {
if (looksLikePromise(data)) {
return data;
}
return new SynchronousPromise(function (resolve) {
resolve.apply(null, argumentsToArray(args));
resolve(data);
});
};
SynchronousPromise.reject = function () {
var args = arguments;
SynchronousPromise.reject = function (error) {
if (looksLikePromise(error)) {
return error;
}
return new SynchronousPromise(function (resolve, reject) {
reject.apply(null, argumentsToArray(args));
reject(error);
});

@@ -203,1 +253,2 @@ };

};

@@ -32,13 +32,24 @@ /*

describe("then", function () {
it("should return the same promise", function () {
it("should return the same resolved promise", function () {
var sut = createResolved();
expect(sut.then(function () { })).to.equal(sut);
expect(sut.then(null, function () { })).to.equal(sut);
});
it("should return the same promise v2", function () {
it("should return the same resolved promise v2", function () {
var
result = createResolved().then(function () {
/* purposely don"t return anything */
/* purposely don't return anything */
});
expect(result).to.be.instanceOf(SynchronousPromise);
});
it("should return the same rejected promise", function () {
var sut = createRejected();
expect(sut.then(function () { })).to.equal(sut);
});
it("should return the same rejected promise v2", function () {
var result = createRejected().then(function () {
/* purposely don't return anything */
});
expect(result).to.be.instanceOf(SynchronousPromise)
});
it("should call into the catch function when the function given to then throws", function () {

@@ -59,3 +70,3 @@ var

});
it("should call into the failure function when the predecessor fails", function () {
it("should call into following catch rather than the sibling onRejected if onResolved fails", function () {
var

@@ -74,4 +85,4 @@ sut = createResolved(),

expect(captured).to.equal(expected);
expect(catchCaptured).to.be.null;
expect(captured).to.be.null;
expect(catchCaptured).to.equal(expected);
});

@@ -87,2 +98,12 @@ it("should bring the first resolve value into the first then", function () {

});
it("should bring the first rejected value into the first onRejected then handler", function () {
var
initial = new Error("123"),
captured = null;
createRejected(initial).then(function () {
}, function (e) {
captured = e
});
expect(captured).to.equal(initial);
});
it("should resolve when the first resolution is a resolved promise", function () {

@@ -96,3 +117,3 @@ var

expect(captured).to.equal("123");
})
});
it("should catch when the first resolution is a rejected promise", function () {

@@ -207,2 +228,15 @@ var

});
it("should call handler if the promise resolves", function () {
// Arrange
var
sut = SynchronousPromise.unresolved(),
resolved = false,
caught = false;
// Act
sut.then(() => resolved = true).catch(() => caught = true);
sut.resolve();
// Assert
expect(resolved).to.be.true;
expect(caught).to.be.false;
});
it("should be called on a delayed rejection", function () {

@@ -224,3 +258,3 @@ var

});
it("should return the same promise", function () {
it("should return a resolved promise if doesn't thrown an error", function () {
var

@@ -234,3 +268,3 @@ promise = createRejected("123"),

expect(result).to.be.instanceOf(SynchronousPromise);
expect(result).to.equal(promise);
expect(result.status).to.be.equal("resolved");
});

@@ -251,4 +285,19 @@ it("should not interfere with a later then if there is no error", function () {

});
it("should prevent then handlers after the error from being called", function () {
it("should not be called if the promise is handled successful by a previous onRejected handler", function () {
var
expected = new Error("123"),
notExpected = new Error("Not expected"),
capturedError = null;
createRejected(expected).then(function () {}, function (e) {
capturedError = e
})
.catch(function () {
/* purposely don't return anything */
capturedError = notExpected;
})
expect(capturedError).to.equal(expected);
});
it("should prevent the handlers after the error from being called", function () {
var
captured = null;

@@ -286,2 +335,35 @@ createResolved("123").catch(function (e) {

setTimeout(function () {
try {
expect(capturedA).to.equal(expected);
expect(capturedB).to.equal(expected);
done();
} catch (e) {
done(e);
}
}, 100);
});
it("should re-catch if a then onRejected handler returns a rejected promise", function (done) {
// Arrange
var
expected = "123",
pausedRejectedPromise = SynchronousPromise.reject(expected).pause(),
capturedA = null,
capturedB = null;
pausedRejectedPromise.then(function () {
/* purposely don't return anything */
}, function (e) {
capturedA = e;
// prove that this works even from an async promise
return Promise.reject(e);
}).catch(function (e) {
capturedB = e;
})
// Act
pausedRejectedPromise.resume();
// Assert
setTimeout(function () {
expect(capturedA).to.equal(expected);

@@ -317,6 +399,10 @@ expect(capturedB).to.equal(expected);

setTimeout(function () {
expect(capturedA).to.equal(expected);
expect(capturedB).to.be.null;
expect(secondResolve).to.equal("456");
done();
try {
expect(capturedA).to.equal(expected);
expect(capturedB).to.be.null;
expect(secondResolve).to.equal("456");
done();
} catch (e) {
done(e);
}
}, 100);

@@ -370,3 +456,3 @@ });

describe("starting paused", function () {
it("should return a promise in paused state with no initial data", function () {
it("should return a promise in paused state with no initial data and being resolved on resume", function () {
var

@@ -383,2 +469,30 @@ captured,

});
it("should return a promise in paused state with no initial data and being rejected on resume", function () {
var
captured,
expected = new Error("moon"),
promise = SynchronousPromise.resolve().pause().then(function () {
throw expected
}).catch(function (e) {
captured = e;
});
expect(captured).not.to.be.defined;
promise.resume();
expect(captured).to.equal(expected);
});
it("should return a promise in paused state with no initial data and being resolved after a catch on resume", function () {
var
captured,
error = new Error("moon"),
promise = SynchronousPromise.resolve().pause().then(function () {
throw error
}).catch(function (e) {
return e.message;
}).then(function (m) {
captured = m;
});
expect(captured).not.to.be.defined;
promise.resume();
expect(captured).to.equal("moon");
});
});

@@ -645,2 +759,2 @@ });

});
})
});
{
"name": "synchronous-promise",
"version": "1.0.12",
"version": "1.0.13",
"description": "Synchronous Promise-like prototype to use in testing where you would have used an ES6 Promise",

@@ -5,0 +5,0 @@ "main": "index.js",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc