Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

derive-state

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

derive-state - npm Package Compare versions

Comparing version 0.1.0-alpha.3 to 0.1.0-alpha.4

313

dist/derive-state.cjs.development.js

@@ -21,8 +21,2 @@ 'use strict';

function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var ObserverList = /*#__PURE__*/function () {

@@ -67,2 +61,9 @@ function ObserverList() {

_createClass(ObserverList, [{
key: "size",
get: function get() {
return this.observers.size;
}
}]);
return ObserverList;

@@ -74,29 +75,23 @@ }();

var DerivedState = /*#__PURE__*/function () {
function DerivedState(derive) {
var _this = this;
var State = /*#__PURE__*/function () {
function State(initialValue) {
this.observerList = new ObserverList();
this.state = EMPTY;
this.teardown = derive({
next: function next(_next) {
if (_this.observerList.closed) {
throw new Error("Can't set the value of a closed ObservableState");
}
this.teardown = noop;
_this.state = _next;
if (arguments.length >= 1) {
this.state = initialValue;
}
}
_this.observerList.emit(_next);
},
complete: function complete() {
return _this.close();
}
}) || noop; // For synchronous completes
var _proto = State.prototype;
_proto.setValue = function setValue(newState) {
if (this.observerList.closed) {
this.teardown();
throw new Error("Can't set the value of a closed ObservableState");
}
}
var _proto = DerivedState.prototype;
this.state = newState;
this.observerList.emit(newState);
};

@@ -120,2 +115,35 @@ _proto.subscribe = function subscribe(next, complete) {

_proto.pipe = function pipe() {
for (var _len = arguments.length, operators = new Array(_len), _key = 0; _key < _len; _key++) {
operators[_key] = arguments[_key];
}
var firstOp = operators[0],
rest = operators.slice(1);
var first = firstOp(this);
var current = first;
rest.forEach(function (operator) {
current = operator(current);
});
return Object.assign(current, {
kill: function kill() {
return first.close();
}
});
};
_proto.appendTeardown = function appendTeardown(teardown) {
var old = this.teardown;
this.teardown = function () {
old();
teardown();
};
};
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
_proto.hasValue = function hasValue() {

@@ -133,19 +161,11 @@ return this.state !== EMPTY;

_proto.close = function close() {
var _this$teardown;
// On synchronous completes, this.teardown can possibly not be defined yet
(_this$teardown = this.teardown) == null ? void 0 : _this$teardown.call(this);
this.observerList.close();
};
_createClass(DerivedState, [{
_createClass(State, [{
key: "value",
get: function get() {
var _this2 = this;
var _this = this;
return new Promise(function (resolve, reject) {
if (_this2.hasValue()) return resolve(_this2.getValue());
if (_this.hasValue()) return resolve(_this.getValue());
var unsub = _this2.subscribe(function (v) {
var unsub = _this.subscribe(function (v) {
unsub();

@@ -160,39 +180,103 @@ resolve(v);

return DerivedState;
return State;
}();
var State = /*#__PURE__*/function (_DerivedState) {
_inheritsLoose(State, _DerivedState);
var EMPTY = /*#__PURE__*/Symbol('empty');
function State(initialValue) {
var _this3;
var Stateless = /*#__PURE__*/function () {
function Stateless(derive) {
if (derive === void 0) {
derive = noop;
}
var args = arguments;
var capturedObserver;
_this3 = _DerivedState.call(this, function (obs) {
capturedObserver = obs;
this.observerList = new ObserverList();
this.teardown = noop;
this.start = derive;
}
if (args.length >= 1) {
obs.next(initialValue);
}
}) || this;
var _proto = Stateless.prototype;
_this3.next = function (v) {
return capturedObserver.next(v);
_proto.emit = function emit(next) {
this.observerList.emit(next);
};
_proto.subscribe = function subscribe(next, complete) {
var _this = this;
var observer = {
next: next,
complete: complete || noop
};
return _this3;
}
if (this.observerList.closed) {
observer.complete();
return noop;
}
var _proto2 = State.prototype;
var unsub = this.observerList.addObserver(observer);
_proto2.setValue = function setValue(newState) {
this.next(newState);
if (this.observerList.size === 1) {
this.teardown = this.start({
next: function next(v) {
return _this.emit(v);
},
complete: function complete() {
return _this.close();
}
}) || noop;
}
return function () {
unsub();
if (_this.observerList.size === 0) {
_this.teardown();
}
};
};
return State;
}(DerivedState);
var EMPTY = /*#__PURE__*/Symbol('empty');
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
_proto.pipe = function pipe() {
for (var _len = arguments.length, operators = new Array(_len), _key = 0; _key < _len; _key++) {
operators[_key] = arguments[_key];
}
var firstOp = operators[0],
rest = operators.slice(1);
var first = firstOp(this);
var current = first;
rest.forEach(function (operator) {
current = operator(current);
});
return Object.assign(current, {
kill: function kill() {
return first.close();
}
});
};
_proto.capture = function capture() {
var state = new State();
var unsub = this.subscribe(function (n) {
return state.setValue(n);
}, function () {
return state.close();
});
state.appendTeardown(unsub);
return state;
};
return Stateless;
}();
var asStateless = function asStateless(observable) {
return new Stateless(function (obs) {
return observable.subscribe(obs.next, obs.complete);
});
};
var combine = function combine(input) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var active = false;

@@ -234,3 +318,3 @@ var value = Array.isArray(input) ? [] : {};

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var lastValue = EMPTY$1;

@@ -251,3 +335,3 @@ return source.subscribe(function (value) {

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
return source.subscribe(function (value) {

@@ -262,3 +346,3 @@ return filterFn(value) ? obs.next(value) : void 0;

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
return source.subscribe(function (value) {

@@ -272,3 +356,3 @@ return obs.next(mapFn(value));

var merge = function merge(observables) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var activeSubs = observables.length;

@@ -297,18 +381,5 @@

function pipe(source) {
var current = source;
for (var _len = arguments.length, operators = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
operators[_key - 1] = arguments[_key];
}
operators.forEach(function (operator) {
current = operator(current);
});
return current;
}
var skip = function skip(n) {
return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var i = 0;

@@ -328,3 +399,3 @@ return source.subscribe(function (v) {

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var state = {

@@ -344,3 +415,3 @@ skip: true

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var innerUnsub = function innerUnsub() {

@@ -363,3 +434,4 @@ return void 0;

activeSubs++;
innerUnsub = mapFn(value).subscribe(function (v) {
var inner$ = mapFn(value);
innerUnsub = inner$.subscribe(function (v) {
return obs.next(v);

@@ -378,3 +450,3 @@ }, handleComplete);

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
if (n < 1) {

@@ -410,3 +482,3 @@ return obs.complete();

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
obs.next(value);

@@ -418,74 +490,2 @@ return source.subscribe(obs.next, obs.complete);

var DerivedStateless = /*#__PURE__*/function () {
function DerivedStateless(derive) {
var _this = this;
this.observerList = new ObserverList();
this.teardown = derive({
next: function next(_next) {
return _this.observerList.emit(_next);
},
complete: function complete() {
return _this.close();
}
}) || noop;
}
var _proto = DerivedStateless.prototype;
_proto.subscribe = function subscribe(next, complete) {
var observer = {
next: next,
complete: complete || noop
};
if (this.observerList.closed) {
observer.complete();
return noop;
}
return this.observerList.addObserver(observer);
};
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
return DerivedStateless;
}();
var Stateless = /*#__PURE__*/function (_DerivedStateless) {
_inheritsLoose(Stateless, _DerivedStateless);
function Stateless() {
var _this2;
var capturedObserver;
_this2 = _DerivedStateless.call(this, function (obs) {
capturedObserver = obs;
}) || this;
_this2.next = function (v) {
return capturedObserver.next(v);
};
return _this2;
}
var _proto2 = Stateless.prototype;
_proto2.emit = function emit(newState) {
this.next(newState);
};
return Stateless;
}(DerivedStateless);
var asStateless = function asStateless(observable) {
return new DerivedStateless(function (obs) {
return observable.subscribe(obs.next, obs.complete);
});
};
exports.DerivedState = DerivedState;
exports.DerivedStateless = DerivedStateless;
exports.State = State;

@@ -499,3 +499,2 @@ exports.Stateless = Stateless;

exports.merge = merge;
exports.pipe = pipe;
exports.skip = skip;

@@ -502,0 +501,0 @@ exports.skipSynchronous = skipSynchronous;

@@ -1,2 +0,2 @@

"use strict";function t(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}Object.defineProperty(exports,"__esModule",{value:!0});var e=function(){function t(){this.observers=new Set,this.closed=!1}var e=t.prototype;return e.addObserver=function(t){var e=this;if(this.closed)throw new Error("StatelessObservable was closed, can't subscribe");return this.observers.add(t),function(){e.observers.delete(t)}},e.emit=function(t){if(this.closed)throw new Error("Observable was closed, can't emit new value");this.observers.forEach((function(e){return e.next(t)}))},e.close=function(){this.observers.forEach((function(t){return t.complete()})),this.observers.clear(),this.closed=!0},t}(),n=function(){},r=function(){function t(t){var r=this;this.observerList=new e,this.state=i,this.teardown=t({next:function(t){if(r.observerList.closed)throw new Error("Can't set the value of a closed ObservableState");r.state=t,r.observerList.emit(t)},complete:function(){return r.close()}})||n,this.observerList.closed&&this.teardown()}var r,o=t.prototype;return o.subscribe=function(t,e){var r={next:t,complete:e||n};if(this.observerList.closed)return this.state!==i&&t(this.state),null==e||e(),n;var o=this.observerList.addObserver(r);return this.state!==i&&t(this.state),o},o.hasValue=function(){return this.state!==i},o.getValue=function(){if(this.state===i)throw new Error("Can't retreive the value of the ObservableState, as it's empty");return this.state},o.close=function(){var t;null==(t=this.teardown)||t.call(this),this.observerList.close()},(r=[{key:"value",get:function(){var t=this;return new Promise((function(e,n){if(t.hasValue())return e(t.getValue());var r=t.subscribe((function(t){r(),e(t)}),(function(){return n(new Error("ObservableState completed without any value"))}))}))}}])&&function(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}(t.prototype,r),t}(),o=function(e){function n(t){var n,r,o=arguments;return(n=e.call(this,(function(e){r=e,o.length>=1&&e.next(t)}))||this).next=function(t){return r.next(t)},n}return t(n,e),n.prototype.setValue=function(t){this.next(t)},n}(r),i=Symbol("empty"),u=Symbol("empty"),s=function(){function t(t){var r=this;this.observerList=new e,this.teardown=t({next:function(t){return r.observerList.emit(t)},complete:function(){return r.close()}})||n}var r=t.prototype;return r.subscribe=function(t,e){var r={next:t,complete:e||n};return this.observerList.closed?(r.complete(),n):this.observerList.addObserver(r)},r.close=function(){this.teardown(),this.observerList.close()},t}(),c=function(e){function n(){var t,n;return(t=e.call(this,(function(t){n=t}))||this).next=function(t){return n.next(t)},t}return t(n,e),n.prototype.emit=function(t){this.next(t)},n}(s);exports.DerivedState=r,exports.DerivedStateless=s,exports.State=o,exports.Stateless=c,exports.asStateless=function(t){return new s((function(e){return t.subscribe(e.next,e.complete)}))},exports.combine=function(t){return new r((function(e){var n=!1,r=Array.isArray(t)?[]:{},o=Object.entries(t);if(0===o.length)return e.complete();var i=o.map((function(t){var i=t[0];return t[1].subscribe((function(t){r[i]=t,(n||Object.keys(r).length===o.length)&&(n=!0,e.next(r))}),e.complete)}));return function(){return i.forEach((function(t){return t()}))}}))},exports.distinctUntilChanged=function(t){return void 0===t&&(t=function(t,e){return t===e}),function(e){return new r((function(n){var r=u;return e.subscribe((function(e){r!==u&&t(e,r)||n.next(e),r=e}),n.complete)}))}},exports.filter=function(t){return function(e){return new r((function(n){return e.subscribe((function(e){return t(e)?n.next(e):void 0}),n.complete)}))}},exports.map=function(t){return function(e){return new r((function(n){return e.subscribe((function(e){return n.next(t(e))}),n.complete)}))}},exports.merge=function(t){return new r((function(e){var n=t.length;if(0===n)return e.complete();var r=t.map((function(t){return t.subscribe(e.next,(function(){0==--n&&e.complete()}))}));return function(){return r.forEach((function(t){return t()}))}}))},exports.pipe=function(t){for(var e=t,n=arguments.length,r=new Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return r.forEach((function(t){e=t(e)})),e},exports.skip=function(t){return function(e){return new r((function(n){var r=0;return e.subscribe((function(e){r>=t?n.next(e):r++}),n.complete)}))}},exports.skipSynchronous=function(){return function(t){return new r((function(e){var n={skip:!0},r=t.subscribe((function(t){return n.skip?void 0:e.next(t)}),e.complete);return n.skip=!1,r}))}},exports.switchMap=function(t){return function(e){return new r((function(n){var r=function(){},o=1,i=function(){0==--o&&n.complete()},u=e.subscribe((function(e){r(),o++,r=t(e).subscribe((function(t){return n.next(t)}),i)}),i);return function(){r(),u()}}))}},exports.take=function(t){return function(e){return new r((function(n){if(t<1)return n.complete();var r=0,o=e.subscribe((function(e){r<t&&n.next(e),++r>=t&&(o&&o(),n.complete())}),n.complete);return r>=t&&(o(),n.complete()),o}))}},exports.withDefault=function(t){return function(e){return new r((function(n){return n.next(t),e.subscribe(n.next,n.complete)}))}};
"use strict";function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function t(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}Object.defineProperty(exports,"__esModule",{value:!0});var n=function(){function e(){this.observers=new Set,this.closed=!1}var n=e.prototype;return n.addObserver=function(e){var t=this;if(this.closed)throw new Error("StatelessObservable was closed, can't subscribe");return this.observers.add(e),function(){t.observers.delete(e)}},n.emit=function(e){if(this.closed)throw new Error("Observable was closed, can't emit new value");this.observers.forEach((function(t){return t.next(e)}))},n.close=function(){this.observers.forEach((function(e){return e.complete()})),this.observers.clear(),this.closed=!0},t(e,[{key:"size",get:function(){return this.observers.size}}]),e}(),r=function(){},i=function(){function e(e){this.observerList=new n,this.state=o,this.teardown=r,arguments.length>=1&&(this.state=e)}var i=e.prototype;return i.setValue=function(e){if(this.observerList.closed)throw new Error("Can't set the value of a closed ObservableState");this.state=e,this.observerList.emit(e)},i.subscribe=function(e,t){var n={next:e,complete:t||r};if(this.observerList.closed)return this.state!==o&&e(this.state),null==t||t(),r;var i=this.observerList.addObserver(n);return this.state!==o&&e(this.state),i},i.pipe=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];var r=t[0],i=t.slice(1),o=r(this),s=o;return i.forEach((function(e){s=e(s)})),Object.assign(s,{kill:function(){return o.close()}})},i.appendTeardown=function(e){var t=this.teardown;this.teardown=function(){t(),e()}},i.close=function(){this.teardown(),this.observerList.close()},i.hasValue=function(){return this.state!==o},i.getValue=function(){if(this.state===o)throw new Error("Can't retreive the value of the ObservableState, as it's empty");return this.state},t(e,[{key:"value",get:function(){var e=this;return new Promise((function(t,n){if(e.hasValue())return t(e.getValue());var r=e.subscribe((function(e){r(),t(e)}),(function(){return n(new Error("ObservableState completed without any value"))}))}))}}]),e}(),o=Symbol("empty"),s=function(){function e(e){void 0===e&&(e=r),this.observerList=new n,this.teardown=r,this.start=e}var t=e.prototype;return t.emit=function(e){this.observerList.emit(e)},t.subscribe=function(e,t){var n=this,i={next:e,complete:t||r};if(this.observerList.closed)return i.complete(),r;var o=this.observerList.addObserver(i);return 1===this.observerList.size&&(this.teardown=this.start({next:function(e){return n.emit(e)},complete:function(){return n.close()}})||r),function(){o(),0===n.observerList.size&&n.teardown()}},t.close=function(){this.teardown(),this.observerList.close()},t.pipe=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];var r=t[0],i=t.slice(1),o=r(this),s=o;return i.forEach((function(e){s=e(s)})),Object.assign(s,{kill:function(){return o.close()}})},t.capture=function(){var e=new i,t=this.subscribe((function(t){return e.setValue(t)}),(function(){return e.close()}));return e.appendTeardown(t),e},e}(),u=Symbol("empty");exports.State=i,exports.Stateless=s,exports.asStateless=function(e){return new s((function(t){return e.subscribe(t.next,t.complete)}))},exports.combine=function(e){return new s((function(t){var n=!1,r=Array.isArray(e)?[]:{},i=Object.entries(e);if(0===i.length)return t.complete();var o=i.map((function(e){var o=e[0];return e[1].subscribe((function(e){r[o]=e,(n||Object.keys(r).length===i.length)&&(n=!0,t.next(r))}),t.complete)}));return function(){return o.forEach((function(e){return e()}))}}))},exports.distinctUntilChanged=function(e){return void 0===e&&(e=function(e,t){return e===t}),function(t){return new s((function(n){var r=u;return t.subscribe((function(t){r!==u&&e(t,r)||n.next(t),r=t}),n.complete)}))}},exports.filter=function(e){return function(t){return new s((function(n){return t.subscribe((function(t){return e(t)?n.next(t):void 0}),n.complete)}))}},exports.map=function(e){return function(t){return new s((function(n){return t.subscribe((function(t){return n.next(e(t))}),n.complete)}))}},exports.merge=function(e){return new s((function(t){var n=e.length;if(0===n)return t.complete();var r=e.map((function(e){return e.subscribe(t.next,(function(){0==--n&&t.complete()}))}));return function(){return r.forEach((function(e){return e()}))}}))},exports.skip=function(e){return function(t){return new s((function(n){var r=0;return t.subscribe((function(t){r>=e?n.next(t):r++}),n.complete)}))}},exports.skipSynchronous=function(){return function(e){return new s((function(t){var n={skip:!0},r=e.subscribe((function(e){return n.skip?void 0:t.next(e)}),t.complete);return n.skip=!1,r}))}},exports.switchMap=function(e){return function(t){return new s((function(n){var r=function(){},i=1,o=function(){0==--i&&n.complete()},s=t.subscribe((function(t){r(),i++;var s=e(t);r=s.subscribe((function(e){return n.next(e)}),o)}),o);return function(){r(),s()}}))}},exports.take=function(e){return function(t){return new s((function(n){if(e<1)return n.complete();var r=0,i=t.subscribe((function(t){r<e&&n.next(t),++r>=e&&(i&&i(),n.complete())}),n.complete);return r>=e&&(i(),n.complete()),i}))}},exports.withDefault=function(e){return function(t){return new s((function(n){return n.next(e),t.subscribe(n.next,n.complete)}))}};
//# sourceMappingURL=derive-state.cjs.production.min.js.map

@@ -17,8 +17,2 @@ function _defineProperties(target, props) {

function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var ObserverList = /*#__PURE__*/function () {

@@ -63,2 +57,9 @@ function ObserverList() {

_createClass(ObserverList, [{
key: "size",
get: function get() {
return this.observers.size;
}
}]);
return ObserverList;

@@ -70,29 +71,23 @@ }();

var DerivedState = /*#__PURE__*/function () {
function DerivedState(derive) {
var _this = this;
var State = /*#__PURE__*/function () {
function State(initialValue) {
this.observerList = new ObserverList();
this.state = EMPTY;
this.teardown = derive({
next: function next(_next) {
if (_this.observerList.closed) {
throw new Error("Can't set the value of a closed ObservableState");
}
this.teardown = noop;
_this.state = _next;
if (arguments.length >= 1) {
this.state = initialValue;
}
}
_this.observerList.emit(_next);
},
complete: function complete() {
return _this.close();
}
}) || noop; // For synchronous completes
var _proto = State.prototype;
_proto.setValue = function setValue(newState) {
if (this.observerList.closed) {
this.teardown();
throw new Error("Can't set the value of a closed ObservableState");
}
}
var _proto = DerivedState.prototype;
this.state = newState;
this.observerList.emit(newState);
};

@@ -116,2 +111,35 @@ _proto.subscribe = function subscribe(next, complete) {

_proto.pipe = function pipe() {
for (var _len = arguments.length, operators = new Array(_len), _key = 0; _key < _len; _key++) {
operators[_key] = arguments[_key];
}
var firstOp = operators[0],
rest = operators.slice(1);
var first = firstOp(this);
var current = first;
rest.forEach(function (operator) {
current = operator(current);
});
return Object.assign(current, {
kill: function kill() {
return first.close();
}
});
};
_proto.appendTeardown = function appendTeardown(teardown) {
var old = this.teardown;
this.teardown = function () {
old();
teardown();
};
};
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
_proto.hasValue = function hasValue() {

@@ -129,19 +157,11 @@ return this.state !== EMPTY;

_proto.close = function close() {
var _this$teardown;
// On synchronous completes, this.teardown can possibly not be defined yet
(_this$teardown = this.teardown) == null ? void 0 : _this$teardown.call(this);
this.observerList.close();
};
_createClass(DerivedState, [{
_createClass(State, [{
key: "value",
get: function get() {
var _this2 = this;
var _this = this;
return new Promise(function (resolve, reject) {
if (_this2.hasValue()) return resolve(_this2.getValue());
if (_this.hasValue()) return resolve(_this.getValue());
var unsub = _this2.subscribe(function (v) {
var unsub = _this.subscribe(function (v) {
unsub();

@@ -156,39 +176,103 @@ resolve(v);

return DerivedState;
return State;
}();
var State = /*#__PURE__*/function (_DerivedState) {
_inheritsLoose(State, _DerivedState);
var EMPTY = /*#__PURE__*/Symbol('empty');
function State(initialValue) {
var _this3;
var Stateless = /*#__PURE__*/function () {
function Stateless(derive) {
if (derive === void 0) {
derive = noop;
}
var args = arguments;
var capturedObserver;
_this3 = _DerivedState.call(this, function (obs) {
capturedObserver = obs;
this.observerList = new ObserverList();
this.teardown = noop;
this.start = derive;
}
if (args.length >= 1) {
obs.next(initialValue);
}
}) || this;
var _proto = Stateless.prototype;
_this3.next = function (v) {
return capturedObserver.next(v);
_proto.emit = function emit(next) {
this.observerList.emit(next);
};
_proto.subscribe = function subscribe(next, complete) {
var _this = this;
var observer = {
next: next,
complete: complete || noop
};
return _this3;
}
if (this.observerList.closed) {
observer.complete();
return noop;
}
var _proto2 = State.prototype;
var unsub = this.observerList.addObserver(observer);
_proto2.setValue = function setValue(newState) {
this.next(newState);
if (this.observerList.size === 1) {
this.teardown = this.start({
next: function next(v) {
return _this.emit(v);
},
complete: function complete() {
return _this.close();
}
}) || noop;
}
return function () {
unsub();
if (_this.observerList.size === 0) {
_this.teardown();
}
};
};
return State;
}(DerivedState);
var EMPTY = /*#__PURE__*/Symbol('empty');
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
_proto.pipe = function pipe() {
for (var _len = arguments.length, operators = new Array(_len), _key = 0; _key < _len; _key++) {
operators[_key] = arguments[_key];
}
var firstOp = operators[0],
rest = operators.slice(1);
var first = firstOp(this);
var current = first;
rest.forEach(function (operator) {
current = operator(current);
});
return Object.assign(current, {
kill: function kill() {
return first.close();
}
});
};
_proto.capture = function capture() {
var state = new State();
var unsub = this.subscribe(function (n) {
return state.setValue(n);
}, function () {
return state.close();
});
state.appendTeardown(unsub);
return state;
};
return Stateless;
}();
var asStateless = function asStateless(observable) {
return new Stateless(function (obs) {
return observable.subscribe(obs.next, obs.complete);
});
};
var combine = function combine(input) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var active = false;

@@ -230,3 +314,3 @@ var value = Array.isArray(input) ? [] : {};

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var lastValue = EMPTY$1;

@@ -247,3 +331,3 @@ return source.subscribe(function (value) {

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
return source.subscribe(function (value) {

@@ -258,3 +342,3 @@ return filterFn(value) ? obs.next(value) : void 0;

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
return source.subscribe(function (value) {

@@ -268,3 +352,3 @@ return obs.next(mapFn(value));

var merge = function merge(observables) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var activeSubs = observables.length;

@@ -293,18 +377,5 @@

function pipe(source) {
var current = source;
for (var _len = arguments.length, operators = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
operators[_key - 1] = arguments[_key];
}
operators.forEach(function (operator) {
current = operator(current);
});
return current;
}
var skip = function skip(n) {
return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var i = 0;

@@ -324,3 +395,3 @@ return source.subscribe(function (v) {

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var state = {

@@ -340,3 +411,3 @@ skip: true

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
var innerUnsub = function innerUnsub() {

@@ -359,3 +430,4 @@ return void 0;

activeSubs++;
innerUnsub = mapFn(value).subscribe(function (v) {
var inner$ = mapFn(value);
innerUnsub = inner$.subscribe(function (v) {
return obs.next(v);

@@ -374,3 +446,3 @@ }, handleComplete);

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
if (n < 1) {

@@ -406,3 +478,3 @@ return obs.complete();

return function (source) {
return new DerivedState(function (obs) {
return new Stateless(function (obs) {
obs.next(value);

@@ -414,73 +486,3 @@ return source.subscribe(obs.next, obs.complete);

var DerivedStateless = /*#__PURE__*/function () {
function DerivedStateless(derive) {
var _this = this;
this.observerList = new ObserverList();
this.teardown = derive({
next: function next(_next) {
return _this.observerList.emit(_next);
},
complete: function complete() {
return _this.close();
}
}) || noop;
}
var _proto = DerivedStateless.prototype;
_proto.subscribe = function subscribe(next, complete) {
var observer = {
next: next,
complete: complete || noop
};
if (this.observerList.closed) {
observer.complete();
return noop;
}
return this.observerList.addObserver(observer);
};
_proto.close = function close() {
this.teardown();
this.observerList.close();
};
return DerivedStateless;
}();
var Stateless = /*#__PURE__*/function (_DerivedStateless) {
_inheritsLoose(Stateless, _DerivedStateless);
function Stateless() {
var _this2;
var capturedObserver;
_this2 = _DerivedStateless.call(this, function (obs) {
capturedObserver = obs;
}) || this;
_this2.next = function (v) {
return capturedObserver.next(v);
};
return _this2;
}
var _proto2 = Stateless.prototype;
_proto2.emit = function emit(newState) {
this.next(newState);
};
return Stateless;
}(DerivedStateless);
var asStateless = function asStateless(observable) {
return new DerivedStateless(function (obs) {
return observable.subscribe(obs.next, obs.complete);
});
};
export { DerivedState, DerivedStateless, State, Stateless, asStateless, combine, distinctUntilChanged, filter, map, merge, pipe, skip, skipSynchronous, switchMap, take, withDefault };
export { State, Stateless, asStateless, combine, distinctUntilChanged, filter, map, merge, skip, skipSynchronous, switchMap, take, withDefault };
//# sourceMappingURL=derive-state.esm.js.map
export interface Observable<T> {
subscribe(next: (value: T) => void, complete?: () => void): () => void;
close(): void;
pipe: PipeFn<T>;
}
export interface ObservableState<T> extends Observable<T> {
export interface StateObservable<T> extends Observable<T> {
value: Promise<T>;

@@ -10,2 +11,5 @@ hasValue(): boolean;

}
export interface StatelessObservable<T> extends Observable<T> {
capture(): StateObservable<T>;
}
export interface Observer<T> {

@@ -15,1 +19,12 @@ next: (value: T) => void;

}
export interface Operator<T, R> {
(source: Observable<T>): Observable<R>;
}
interface PipeFn<T> {
<R>(op: Operator<T, R>): Observable<R>;
<S1, R>(op0: Operator<T, S1>, opN: Operator<S1, R>): Observable<R>;
<S1, S2, R>(op0: Operator<T, S1>, op1: Operator<S1, S2>, opN: Operator<S2, R>): Observable<R>;
<S1, S2, S3, R>(op0: Operator<T, S1>, op1: Operator<S1, S2>, op2: Operator<S2, S3>, opN: Operator<S3, R>): Observable<R>;
<S1, S2, S3, S4, R>(op0: Operator<T, S1>, op1: Operator<S1, S2>, op2: Operator<S2, S3>, op3: Operator<S3, S4>, opN: Operator<S4, R>): Observable<R>;
}
export {};

@@ -8,3 +8,4 @@ import { Observer } from './interface';

close(): void;
get size(): number;
}
export declare const noop: () => undefined;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const combine: <T>(input: { [K in keyof T]: Observable<T[K]>; }) => DerivedState<T>;
export declare const combine: <T>(input: { [K in keyof T]: Observable<T[K]>; }) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const distinctUntilChanged: <T>(eqFn?: (a: T, b: T) => boolean) => (source: Observable<T>) => DerivedState<T>;
export declare const distinctUntilChanged: <T>(eqFn?: (a: T, b: T) => boolean) => (source: Observable<T>) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const filter: <T>(filterFn: (value: T) => boolean) => (source: Observable<T>) => DerivedState<T>;
export declare const filter: <T>(filterFn: (value: T) => boolean) => (source: Observable<T>) => Stateless<T>;

@@ -6,3 +6,2 @@ export * from './combine';

export * from './merge';
export * from './operators';
export * from './skip';

@@ -9,0 +8,0 @@ export * from './skipSynchronous';

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const map: <T, R>(mapFn: (value: T) => R) => (source: Observable<T>) => DerivedState<R>;
export declare const map: <T, R>(mapFn: (value: T) => R) => (source: Observable<T>) => Stateless<R>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const merge: <T>(observables: Observable<T>[]) => DerivedState<T>;
export declare const merge: <T>(observables: Observable<T>[]) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const skip: (n: number) => <T>(source: Observable<T>) => DerivedState<T>;
export declare const skip: (n: number) => <T>(source: Observable<T>) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const skipSynchronous: () => <T>(source: Observable<T>) => DerivedState<T>;
export declare const skipSynchronous: () => <T>(source: Observable<T>) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const switchMap: <T, R>(mapFn: (value: T) => Observable<R>) => (source: Observable<T>) => DerivedState<R>;
export declare const switchMap: <T, R>(mapFn: (value: T) => Observable<R>) => (source: Observable<T>) => Stateless<R>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const take: (n: number) => <T>(source: Observable<T>) => DerivedState<T>;
export declare const take: (n: number) => <T>(source: Observable<T>) => Stateless<T>;

@@ -1,3 +0,3 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export declare const withDefault: <T>(value: T) => <S>(source: Observable<S>) => DerivedState<T | S>;
export declare const withDefault: <T>(value: T) => <S>(source: Observable<S>) => Stateless<T | S>;

@@ -1,17 +0,17 @@

import { ObservableState, Observer } from './interface';
export declare class DerivedState<T> implements ObservableState<T> {
import { StateObservable, Operator } from './interface';
export declare class State<T> implements StateObservable<T> {
private observerList;
private state;
private teardown;
constructor(derive: (observer: Observer<T>) => void | (() => void));
constructor(initialValue?: T);
setValue(newState: T): void;
subscribe(next: (value: T) => void, complete?: () => void): () => void;
pipe(...operators: Operator<any, any>[]): import("./interface").Observable<any> & {
kill: () => void;
};
appendTeardown(teardown: () => void): void;
close(): void;
hasValue(): boolean;
getValue(): T;
close(): void;
get value(): Promise<T>;
}
export declare class State<T> extends DerivedState<T> {
private next;
constructor(initialValue?: T);
setValue(newState: T): void;
}

@@ -1,14 +0,15 @@

import { Observable, ObservableState, Observer } from './interface';
export declare class DerivedStateless<T> implements Observable<T> {
import { StateObservable, Observer, Operator, StatelessObservable } from './interface';
export declare class Stateless<T> implements StatelessObservable<T> {
private observerList;
private teardown;
constructor(derive: (observer: Observer<T>) => void | (() => void));
private start;
constructor(derive?: (observer: Observer<T>) => void | (() => void));
emit(next: T): void;
subscribe(next: (value: T) => void, complete?: () => void): () => void;
close(): void;
pipe(...operators: Operator<any, any>[]): import("./interface").Observable<any> & {
kill: () => void;
};
capture(): StateObservable<T>;
}
export declare class Stateless<T> extends DerivedStateless<T> {
private next;
constructor();
emit(newState: T): void;
}
export declare const asStateless: <T>(observable: ObservableState<T>) => DerivedStateless<unknown>;
export declare const asStateless: <T>(observable: StateObservable<T>) => Stateless<unknown>;
{
"version": "0.1.0-alpha.3",
"version": "0.1.0-alpha.4",
"license": "MIT",

@@ -4,0 +4,0 @@ "main": "dist/index.js",

@@ -5,3 +5,3 @@ # DeriveState

Heavily inspired from RxJS, but while RxJS focuses on asynchronous values, DeriveState focuses on stateful boxes, (aka cells in a spreadsheet) - As if everything were a `BehaviourSubject`, but where you can derive them from other states.
Heavily inspired from RxJS, but while RxJS focuses on asynchronous values, DeriveState focuses on stateful boxes, (aka cells in a spreadsheet) - As if everything were a `BehaviourSubject`, and you create new states deriving them from other states.

@@ -12,4 +12,6 @@ Experimental

## State
```ts
import { State, DerivedState } from 'derive-state';
import { State } from 'derive-state';

@@ -24,44 +26,82 @@ const apples = new State(0);

const squaredApples = new DerivedState(next =>
apples.subscribe(apples => next(apples * apples))
);
squaredApples.subscribe(apples =>
console.log(`We now have ${apples} squared apple(s)`)
);
// Logs "We now have 4 squared apple(s)"
console.log('apples: ' + apples.getValue());
// Logs "apples: 2"
```
// `squaredApples` is a DerivedState, it doesn't have a function `setValue`
// but its state will react to changes from `apples`
apples.setValue(3);
// Logs "We now have 3 apple(s)" "We now have 9 squared apple(s)"
The initial value is optional: if omitted the state will be empty
```ts
import { State } from 'derive-state';
const apples = new State();
apples.subscribe(apples => console.log(`We now have ${apples} apple(s)`));
// Doesn't log anything
// We can't read the value synchronously in this case
expect(() => apples.getValue()).toThrow();
// We have a function that tell us whether it holds a value or not
expect(apples.hasValue()).toBe(false);
// Or we can get a promise for when it finally has a value
apples.value.then(v => console.log(`Promise resolved with ${v}`));
apples.setValue(2);
// Logs "We now have 2 apple(s)" followed by "Promise resolved with 2"
expect(apples.hasValue()).toBe(true);
```
DeriveState also exports some operators to help compose states. Internally, all
of them are using `new DerivedState`
Subscriptions and state can both get cleaned up:
Note that pipe is an external function, where the first parameter is the observable
to throw down the pipeline.
```ts
import { pipe, combine, map } from 'derive-state';
import { State } from 'derive-state';
const pears = new State(10);
const apples = new State(0);
const fruits = pipe(
combine([apples, pears]), // eq. combineLatest in rxjs
map(([apples, pears]) => apples + pears)
const unsub1 = apples.subscribe(
apples => console.log(`We now have ${apples} apple(s)`)
() => console.log("complete")
);
fruits.subscribe(fruits => console.log(`We have ${fruits} fruit(s) in total`));
// Logs "We have 13 fruit(s) in total"
// Logs "We now have 0 apple(s)"
unsub1();
apples.setValue(2);
// Doesn't log anything
apples.subscribe(
apples => console.log(`We now have ${apples} apple(s)`)
() => console.log("complete")
);
// Logs "We now have 2 apple(s)"
apples.close();
// Logs "complete"
// We can't set the value of a closed state.
// As semantically it means this value won't ever change again.
expect(() => apples.setValue(5)).toThrow();
// But we can still read the value
console.log('apples: ' + apples.getValue());
// Logs "apples: 2"
// And subscribe (it will just call back and close the subscription immediately)
apples.subscribe(
apples => console.log(`We now have ${apples} apple(s)`)
() => console.log("complete")
);
// Logs "We now have 2 apple(s)" followed by "complete"
```
For convenience, it also exposes Stateless observables: those that you will only
get updates from new values.
## Stateless
Note that when deriving a state using any of the exposed operators, it will
result in a stateful observable. DeriveState exports a utility to turn a stateful
observable to a stateless:
An stateless observable doesn't hold any value.
It has two main ways it can be used:
### Similar to an event emitter
```ts
import { Stateless, asStateless } from 'derive-state';
import { Stateless } from 'derive-state';

@@ -75,24 +115,63 @@ const clicks = new Stateless();

// Logs "received a click"
```
const totalClicks = pipe(
clicks,
scan(acc => acc + 1, 0) // (scan operator TBD)
### Derived from another observable
```ts
import { Stateless } from 'derive-state';
const apples = new State(2);
const squaredApples = new Stateless(obs => {});
const squaredApples = new Stateless(obs =>
apples.subscribe(apples => obs.next(apples * apples), obs.complete)
);
totalClicks.subscribe(total => console.log(`total clicks: ${total}`));
// Logs "total clicks: 0"
squaredApples.subscribe(apples =>
console.log(`We now have ${apples} squared apple(s)`)
);
// Logs "We now have 4 squared apple(s)"
clicks.emit('click');
// Logs "received a click" "total clicks: 1"
// Equivalent when using `pipe`:
const pipedSquaredApples = apples.pipe(map(apples => apples * apples));
```
const totalClickChanges = asStateless(totalClicks);
totalClickChanges.subscribe(total => console.log('new total clicks: ${total}'));
// Logs nothing
**A stateless is lazy**: Meaning it won't run the derive function until someone subscribes to it.
clicks.emit('click');
// Logs "received a click" "total clicks: 2" "new total clicks: 2"
**A stateless is multicast**: It will share the derive function along all the subscribers in the chain.
totalClickChanges.subscribe(total => console.log('new total clicks: ${total}'));
// Logs nothing
Stateless are designed to make composition easily: This way we can write operators that define their behaviour, and we can compose them easily with `pipe`.
Note that this has an apparent issue:
```ts
const squaredApples = apples.pipe(map(apples => apples * apples));
squaredApples.subscribe(apples =>
console.log(`We now have ${apples} squared apple(s)`)
);
// Logs "We now have 4 squared apple(s)"
squaredApples.subscribe(apples =>
console.log(`We now have ${apples} squared apple(s)`)
);
// Doesn't log anything
```
This is due to the nature of `squaredApples` being stateless and multicast: By the time the second subscriber comes in, `apples` has already emitted its value, so it won't receive it. When `apple` changes, both subscribers will receive the new value.
That's why usually you would `capture` these stateless observables into stateful observables. The trade-off is that while stateless observables get cleaned up when they don't have subscriptions, stateful observables as they hold a value they need cleaning up, that's why you'd call `capture` only after you've applied the composed operator chain
```ts
const pears = new State(10);
// eq. combineLatest in rxjs
const totalFruits = combine([apples, pears])
.pipe(map(([apples, pears]) => apples + pears))
.capture();
totalFruits.subscribe(fruits => console.log(`We now have ${fruits} fruits`));
// Logs "We now have 12 fruits"
totalFruits.subscribe(fruits => console.log(`We now have ${fruits} fruits`));
// Logs "We now have 12 fruits"
```
### Operators

@@ -99,0 +178,0 @@

export interface Observable<T> {
subscribe(next: (value: T) => void, complete?: () => void): () => void;
close(): void;
pipe: PipeFn<T>;
}
export interface ObservableState<T> extends Observable<T> {
export interface StateObservable<T> extends Observable<T> {
value: Promise<T>;

@@ -12,2 +13,6 @@ hasValue(): boolean;

export interface StatelessObservable<T> extends Observable<T> {
capture(): StateObservable<T>;
}
export interface Observer<T> {

@@ -17,1 +22,28 @@ next: (value: T) => void;

}
export interface Operator<T, R> {
(source: Observable<T>): Observable<R>;
}
interface PipeFn<T> {
<R>(op: Operator<T, R>): Observable<R>;
<S1, R>(op0: Operator<T, S1>, opN: Operator<S1, R>): Observable<R>;
<S1, S2, R>(
op0: Operator<T, S1>,
op1: Operator<S1, S2>,
opN: Operator<S2, R>
): Observable<R>;
<S1, S2, S3, R>(
op0: Operator<T, S1>,
op1: Operator<S1, S2>,
op2: Operator<S2, S3>,
opN: Operator<S3, R>
): Observable<R>;
<S1, S2, S3, S4, R>(
op0: Operator<T, S1>,
op1: Operator<S1, S2>,
op2: Operator<S2, S3>,
op3: Operator<S3, S4>,
opN: Operator<S4, R>
): Observable<R>;
}

@@ -31,4 +31,8 @@ import { Observer } from './interface';

}
get size() {
return this.observers.size;
}
}
export const noop = () => void 0;

@@ -1,6 +0,6 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const combine = <T>(input: { [K in keyof T]: Observable<T[K]> }) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
let active = false;

@@ -7,0 +7,0 @@ let value: any = Array.isArray(input) ? [] : {};

@@ -1,2 +0,2 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';

@@ -7,3 +7,3 @@

) => (source: Observable<T>) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
let lastValue: T | typeof EMPTY = EMPTY;

@@ -10,0 +10,0 @@ return source.subscribe(value => {

@@ -1,2 +0,2 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';

@@ -7,3 +7,3 @@

) =>
new DerivedState<T>(obs =>
new Stateless<T>(obs =>
source.subscribe(

@@ -10,0 +10,0 @@ value => (filterFn(value) ? obs.next(value) : void 0),

@@ -6,3 +6,2 @@ export * from './combine';

export * from './merge';
export * from './operators';
export * from './skip';

@@ -9,0 +8,0 @@ export * from './skipSynchronous';

@@ -1,7 +0,7 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const map = <T, R>(mapFn: (value: T) => R) => (source: Observable<T>) =>
new DerivedState<R>(obs =>
new Stateless<R>(obs =>
source.subscribe(value => obs.next(mapFn(value)), obs.complete)
);

@@ -1,6 +0,6 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const merge = <T>(observables: Observable<T>[]) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
let activeSubs = observables.length;

@@ -7,0 +7,0 @@ if (activeSubs === 0) {

@@ -1,6 +0,6 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const skip = (n: number) => <T>(source: Observable<T>) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
let i = 0;

@@ -7,0 +7,0 @@ return source.subscribe(v => {

@@ -1,6 +0,6 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const skipSynchronous = () => <T>(source: Observable<T>) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
const state = {

@@ -7,0 +7,0 @@ skip: true,

@@ -1,2 +0,2 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';

@@ -7,3 +7,3 @@

) =>
new DerivedState<R>(obs => {
new Stateless<R>(obs => {
let innerUnsub = (): void => void 0;

@@ -22,3 +22,4 @@ let activeSubs = 1;

activeSubs++;
innerUnsub = mapFn(value).subscribe(v => obs.next(v), handleComplete);
const inner$ = mapFn(value) as Observable<R>;
innerUnsub = inner$.subscribe(v => obs.next(v), handleComplete);
}, handleComplete);

@@ -25,0 +26,0 @@

@@ -1,6 +0,6 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const take = (n: number) => <T>(source: Observable<T>) =>
new DerivedState<T>(obs => {
new Stateless<T>(obs => {
if (n < 1) {

@@ -7,0 +7,0 @@ return obs.complete();

@@ -1,8 +0,8 @@

import { DerivedState } from '../state';
import { Stateless } from '../stateless';
import { Observable } from '../interface';
export const withDefault = <T>(value: T) => <S>(source: Observable<S>) =>
new DerivedState<S | T>(obs => {
new Stateless<S | T>(obs => {
obs.next(value);
return source.subscribe(obs.next, obs.complete);
});

@@ -1,26 +0,21 @@

import { ObservableState, Observer } from './interface';
import { StateObservable, Observer, Operator } from './interface';
import { noop, ObserverList } from './internal';
export class DerivedState<T> implements ObservableState<T> {
export class State<T> implements StateObservable<T> {
private observerList = new ObserverList<T>();
private state: T | typeof EMPTY = EMPTY;
private teardown: () => void;
private teardown: () => void = noop;
constructor(derive: (observer: Observer<T>) => void | (() => void)) {
this.teardown =
derive({
next: next => {
if (this.observerList.closed) {
throw new Error("Can't set the value of a closed ObservableState");
}
this.state = next;
this.observerList.emit(next);
},
complete: () => this.close(),
}) || noop;
constructor(initialValue?: T) {
if (arguments.length >= 1) {
this.state = initialValue!;
}
}
// For synchronous completes
setValue(newState: T) {
if (this.observerList.closed) {
this.teardown();
throw new Error("Can't set the value of a closed ObservableState");
}
this.state = newState;
this.observerList.emit(newState);
}

@@ -44,2 +39,25 @@

}
pipe(...operators: Operator<any, any>[]) {
const [firstOp, ...rest] = operators;
const first = firstOp(this);
let current = first;
rest.forEach(operator => {
current = operator(current);
});
return Object.assign(current, { kill: () => first.close() });
}
appendTeardown(teardown: () => void) {
const old = this.teardown;
this.teardown = () => {
old();
teardown();
};
}
close() {
this.teardown();
this.observerList.close();
}
hasValue() {

@@ -56,7 +74,2 @@ return this.state !== EMPTY;

}
close() {
// On synchronous completes, this.teardown can possibly not be defined yet
this.teardown?.();
this.observerList.close();
}

@@ -77,22 +90,2 @@ get value() {

export class State<T> extends DerivedState<T> {
private next: (value: T) => void;
constructor(initialValue?: T) {
const args = arguments;
let capturedObserver: Observer<T>;
super(obs => {
capturedObserver = obs;
if (args.length >= 1) {
obs.next(initialValue!);
}
});
this.next = (v: T) => capturedObserver!.next(v);
}
setValue(newState: T) {
this.next(newState);
}
}
const EMPTY = Symbol('empty');

@@ -1,16 +0,23 @@

import { Observable, ObservableState, Observer } from './interface';
import {
StateObservable,
Observer,
Operator,
StatelessObservable,
} from './interface';
import { noop, ObserverList } from './internal';
import { State } from './state';
export class DerivedStateless<T> implements Observable<T> {
export class Stateless<T> implements StatelessObservable<T> {
private observerList = new ObserverList<T>();
private teardown: () => void;
private teardown: () => void = noop;
private start: (observer: Observer<T>) => void | (() => void);
constructor(derive: (observer: Observer<T>) => void | (() => void)) {
this.teardown =
derive({
next: next => this.observerList.emit(next),
complete: () => this.close(),
}) || noop;
constructor(derive: (observer: Observer<T>) => void | (() => void) = noop) {
this.start = derive;
}
emit(next: T) {
this.observerList.emit(next);
}
subscribe(next: (value: T) => void, complete?: () => void) {

@@ -27,3 +34,16 @@ const observer: Observer<T> = {

return this.observerList.addObserver(observer);
const unsub = this.observerList.addObserver(observer);
if (this.observerList.size === 1) {
this.teardown =
this.start({
next: v => this.emit(v),
complete: () => this.close(),
}) || noop;
}
return () => {
unsub();
if (this.observerList.size === 0) {
this.teardown();
}
};
}

@@ -35,21 +55,25 @@

}
}
export class Stateless<T> extends DerivedStateless<T> {
private next: (value: T) => void;
constructor() {
let capturedObserver: Observer<T>;
super(obs => {
capturedObserver = obs;
pipe(...operators: Operator<any, any>[]) {
const [firstOp, ...rest] = operators;
const first = firstOp(this);
let current = first;
rest.forEach(operator => {
current = operator(current);
});
this.next = (v: T) => capturedObserver!.next(v);
return Object.assign(current, { kill: () => first.close() });
}
emit(newState: T) {
this.next(newState);
capture() {
const state = new State<T>();
const unsub = this.subscribe(
n => state.setValue(n),
() => state.close()
);
state.appendTeardown(unsub);
return state as StateObservable<T>;
}
}
export const asStateless = <T>(observable: ObservableState<T>) =>
new DerivedStateless(obs => observable.subscribe(obs.next, obs.complete));
export const asStateless = <T>(observable: StateObservable<T>) =>
new Stateless(obs => observable.subscribe(obs.next, obs.complete));

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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