@rxx/core
Version:
React MVI micro framework.
227 lines (226 loc) • 9.66 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var rxjs_1 = require("rxjs");
var intent_1 = require("./intent/intent");
var state_handler_1 = require("./handler/state-handler");
var utils_1 = require("./utils");
var combine_template_1 = require("./observable/combine-template");
var intent_handler_1 = require("./intent/intent-handler");
var subject_1 = require("./subject");
var devtools_1 = require("./devtools");
var reducer_1 = require("./reducer");
var StoreGroup = (function () {
function StoreGroup(intent, stores, service, subject) {
this.intent = intent;
this.stores = stores;
this.service = service;
this.subject = subject;
this.storeInstances = [];
}
StoreGroup.prototype.initialize = function () {
var _this = this;
return this.stores.reduce(function (state, Store) {
var store = new Store(_this.intent, _this.service, _this.subject.observable);
var nextState = store.initialize();
_this.storeInstances.push(store);
if (nextState.view) {
state.view = tslib_1.__assign({}, state.view, nextState.view);
}
for (var key in nextState) {
if (key !== 'view') {
if (!nextState[key] || !(nextState[key] instanceof rxjs_1.Observable)) {
throw new Error("Property " + key + " must be Observable.");
}
if (state[key]) {
state[key] = state[key].merge(nextState[key]);
}
else {
state[key] = nextState[key];
}
}
}
return state;
}, { view: {} });
};
StoreGroup.prototype.getStores = function () {
return this.storeInstances;
};
return StoreGroup;
}());
var Provisioning = (function () {
function Provisioning(name, context, intentConstructors, storeConstructors, stateFactory, service, stateHandlers, intentAdvice) {
if (stateFactory === void 0) { stateFactory = function (o, i) { return i; }; }
if (service === void 0) { service = {}; }
if (stateHandlers === void 0) { stateHandlers = {}; }
if (intentAdvice === void 0) { intentAdvice = function (v) { return v; }; }
var _this = this;
this.name = name;
this.context = context;
this.intentConstructors = intentConstructors;
this.storeConstructors = storeConstructors;
this.stateFactory = stateFactory;
this.service = service;
this.stateHandlers = stateHandlers;
this.intentAdvice = intentAdvice;
this.isDisposed = false;
this.handlerSubscriptions = [];
this.subscribers = [];
this.handlers = {};
this.devToolsSubscribers = [];
this.cache = null;
if (!this.context.provisioning) {
this.handlers = state_handler_1.getHandlers();
}
else {
utils_1.forIn(state_handler_1.getHandlers(), function (v, k) {
_this.handlers[k] = v.clone();
});
}
if (this.stateHandlers) {
utils_1.forIn(this.stateHandlers, function (v, k) {
_this.handlers[k] = v;
});
}
this.devTools = devtools_1.connectDevTools({ name: this.name, instanceId: this.name });
}
Provisioning.prototype.dispose = function (removeCache) {
if (removeCache === void 0) { removeCache = true; }
this.isDisposed = true;
this.subscription && this.subscription.unsubscribe();
this.subscription = null;
this.intent.dispose();
this.handlerSubscriptions.forEach(function (s) { return s.unsubscribe(); });
this.devToolsSubscribers.forEach(function (a) { return a(); });
if (removeCache) {
this.cache = null;
}
};
Provisioning.prototype.prepare = function () {
var _this = this;
if (this.isDisposed) {
this.intent.prepare(this.context.__intent);
this.subject.prepare(this.context.__subject);
}
else if (!this.intent) {
this.intent = new intent_1.Intent(this.context.__intent);
this.subject = new subject_1.SubjectTree(this.devTools, this.context.__subject);
}
if (!this.cache) {
this.cache = {};
var intentInstance = {};
for (var key in this.intentConstructors) {
intentInstance[key] = this.intentAdvice(new this.intentConstructors[key](function (type, payload) {
_this.subject.notify({ type: type, payload: payload });
_this.intent.push(type, payload);
}, tslib_1.__assign({ intent: this.intent.response }, utils_1.mapValues(this.handlers, function (v) { return v.response; }))));
}
this.cache.intentInstance = intentInstance;
var storeGroup = (this.cache.storeGroup = new StoreGroup(intentInstance, this.storeConstructors, this.service, this.subject));
var intentHandler = (this.cache.intentHandler = intent_handler_1.generateIntentHandler(this.intent, this.subject));
this.cache.storeState = this.stateFactory(this.subject.observable, storeGroup.initialize());
this.cache.stores = storeGroup.getStores();
}
utils_1.forIn(this.handlers, function (handler) {
handler.setIntent(_this.cache.intentHandler);
handler.setSubject(_this.subject);
});
if (this.isDisposed || !this.subscription) {
var state = tslib_1.__assign({}, this.cache.storeState);
this.subscribeHandler(state);
this.subscription = combine_template_1.combineTemplate(state).subscribe(function (state) {
if (_this.context && _this.context.provisioning) {
var parentState = _this.context.provisioning.getState();
for (var key in parentState) {
if (state[key]) {
state[key] = tslib_1.__assign({}, parentState[key], state[key]);
}
else {
state[key] = parentState[key];
}
}
}
_this.notifyUpdate(state);
}, function (error) {
console.error(error);
});
this.devToolsSubscribers.push(this.devTools.subscribe(function (message) {
if (message.type === 'DISPATCH' &&
message.payload.type === 'JUMP_TO_STATE') {
var state_1 = JSON.parse(message.state);
_this.notifyUpdateView(state_1);
_this.subject.suspendDevtools();
_this.subject.notify({
type: reducer_1.SystemEvent.REPLACE_STATE,
payload: { state: state_1 },
});
_this.subject.notify(state_1.__payload__);
_this.subject.resumeDevtools();
}
}));
}
this.isDisposed = false;
};
Provisioning.prototype.getStores = function () {
return this.cache.storeGroup.getStores();
};
Provisioning.prototype.getState = function () {
return this.state;
};
Provisioning.prototype.getIntentHandler = function () {
return this.cache.intentHandler;
};
Provisioning.prototype.getIntentInstance = function () {
return this.cache.intentInstance;
};
Provisioning.prototype.getIntent = function () {
return this.intent;
};
Provisioning.prototype.getSubject = function () {
return this.subject;
};
Provisioning.prototype.subscribe = function (subscriber, runInitial) {
var _this = this;
if (runInitial === void 0) { runInitial = false; }
this.subscribers.push(subscriber);
if (runInitial) {
subscriber(this.state);
}
return function () {
var index = -1;
_this.subscribers.some(function (v, i) {
if (v === subscriber) {
index = i;
return true;
}
return false;
});
_this.subscribers.splice(index, 1);
};
};
Provisioning.prototype.getHandlers = function () {
return this.handlers;
};
Provisioning.prototype.subscribeHandler = function (state) {
for (var key in this.handlers) {
this.handlerSubscriptions.push(this.handlers[key].subscribe(state));
}
};
Provisioning.prototype.notifyUpdate = function (newState) {
this.state = newState;
this.subject.setState(newState);
this.intent.setState(newState);
utils_1.forIn(this.handlers, function (v) { return v.setState(newState); });
this.subscribers.forEach(function (subscriber) { return subscriber(newState); });
};
Provisioning.prototype.notifyUpdateView = function (viewState) {
var _this = this;
this.state.view = viewState;
this.subject.setState(this.state);
this.intent.setState(this.state);
utils_1.forIn(this.handlers, function (v) { return v.setState(_this.state); });
this.subscribers.forEach(function (subscriber) { return subscriber(_this.state); });
};
return Provisioning;
}());
exports.Provisioning = Provisioning;