@onesy/subscription
Version:
Subscription method management
100 lines (76 loc) • 3.33 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import is from '@onesy/utils/is';
import copy from '@onesy/utils/copy';
import Try from '@onesy/utils/try';
const optionsDefault = {
emit: {
priorValue: true,
copy: false,
pre: {},
post: {}
}
};
class OnesySubscription {
constructor(value) {
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_defineProperty(this, "methods", []);
_defineProperty(this, "push", this.emit);
this.value = value;
this.options = options;
this.options = { ...optionsDefault,
...this.options
};
}
get length() {
return this.methods.length;
}
emit(value) {
var _this$options$emit, _this$options$emit$pr, _this$options$emit$po;
for (var _len = arguments.length, other = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
other[_key - 1] = arguments[_key];
}
const values = [value, ...other]; // Important for use cases,
// to be available pre emit,
// Save value as last emitted value as a previous state optionally
if ((_this$options$emit = this.options.emit) !== null && _this$options$emit !== void 0 && _this$options$emit.priorValue) this.value = values.length === 1 ? values[0] : values; // Pre
// Value might be of simple type so we have to assign a new value to the value
if (is('function', (_this$options$emit$pr = this.options.emit.pre) === null || _this$options$emit$pr === void 0 ? void 0 : _this$options$emit$pr.method)) this.options.emit.pre.method(...values); // Whether to send a copied value version or not,
// it might be useful since if value is of reference type,
// methods in the beginning might update the value,
// and other following methods wouldn't get the
// same value as it was sent to the first method.
const methodValue = this.options.emit.copy ? copy(values) : values;
const methods = this.methods.filter(method => is('function', method)); // Emit to methods
for (const method of methods) Try(() => method(...methodValue)); // Post
// Value might be of simple type so we have to assign a new value to the value
if (is('function', (_this$options$emit$po = this.options.emit.post) === null || _this$options$emit$po === void 0 ? void 0 : _this$options$emit$po.method)) this.options.emit.post.method(...values);
} // alias
forEach() {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
this.methods.forEach(method => Try(() => method(...args)));
}
map(value_) {
if (!this.methods.length) return;
let value = value_;
for (const method of this.methods) value = Try(() => method(value));
return value;
}
subscribe(method) {
if (is('function', method) && this.methods.indexOf(method) === -1) this.methods.push(method);
const instance = this;
return {
unsubscribe: () => {
instance.unsubscribe(method);
}
};
}
unsubscribe(method) {
if (is('function', method) && this.methods.indexOf(method) > -1) {
const index = this.methods.findIndex(method_ => method_ === method);
if (index > -1) this.methods.splice(index, 1);
}
}
}
export default OnesySubscription;