bloc-react
Advanced tools
Comparing version 0.1.27 to 0.1.28-2
@@ -0,498 +1,544 @@ | ||
import { __assign, __extends, __spreadArray } from 'tslib'; | ||
import React, { useMemo, useContext, useState, useCallback, useEffect } from 'react'; | ||
const LOCAL_STORAGE_PREFIX = "data."; | ||
const cubitDefaultOptions = { | ||
persistKey: "", | ||
persistData: true | ||
var LOCAL_STORAGE_PREFIX = "data."; | ||
var cubitDefaultOptions = { | ||
persistKey: "", | ||
persistData: true, | ||
}; | ||
const createId = () => { | ||
return "_" + Math.random().toString(36).substr(2, 9); | ||
var createId = function () { | ||
return '_' + Math.random().toString(36).substr(2, 9); | ||
}; | ||
class BehaviorSubject { | ||
isClosed = false; | ||
prevValue; | ||
value; | ||
observers = []; | ||
constructor(initialValue) { | ||
this.value = initialValue; | ||
} | ||
getValue() { | ||
return this.value; | ||
} | ||
subscribe(observer) { | ||
const id = createId(); | ||
this.observers.push({ observer, id }); | ||
this.triggerObservers(); | ||
return { | ||
unsubscribe: () => this.removeObserver(id) | ||
var BehaviorSubject = /** @class */ (function () { | ||
function BehaviorSubject(initialValue) { | ||
this.isClosed = false; | ||
this.observers = []; | ||
this.value = initialValue; | ||
} | ||
BehaviorSubject.prototype.getValue = function () { | ||
return this.value; | ||
}; | ||
} | ||
complete() { | ||
this.observers = []; | ||
this.isClosed = true; | ||
} | ||
next(value) { | ||
this.value = value; | ||
this.triggerObservers(); | ||
} | ||
triggerObservers() { | ||
this.observers.forEach(({ observer }) => { | ||
observer.next(this.value); | ||
BehaviorSubject.prototype.subscribe = function (observer) { | ||
var _this = this; | ||
var id = createId(); | ||
this.observers.push({ observer: observer, id: id }); | ||
this.triggerObservers(); | ||
return { | ||
unsubscribe: function () { return _this.removeObserver(id); } | ||
}; | ||
}; | ||
BehaviorSubject.prototype.complete = function () { | ||
this.observers = []; | ||
this.isClosed = true; | ||
}; | ||
BehaviorSubject.prototype.next = function (value) { | ||
this.value = value; | ||
this.triggerObservers(); | ||
}; | ||
BehaviorSubject.prototype.triggerObservers = function () { | ||
var _this = this; | ||
this.observers.forEach(function (_a) { | ||
var observer = _a.observer; | ||
observer.next(_this.value); | ||
}); | ||
}; | ||
BehaviorSubject.prototype.removeObserver = function (removeId) { | ||
this.observers = this.observers.filter(function (_a) { | ||
var id = _a.id; | ||
return id !== removeId; | ||
}); | ||
}; | ||
return BehaviorSubject; | ||
}()); | ||
var StreamAbstraction = /** @class */ (function () { | ||
function StreamAbstraction(initialValue, blocOptions) { | ||
var _this = this; | ||
if (blocOptions === void 0) { blocOptions = {}; } | ||
this.isClosed = false; | ||
this.removeListeners = []; | ||
this.removeRemoveListener = function (index) { | ||
_this.removeListeners.splice(index, 1); | ||
}; | ||
this.addRemoveListener = function (method) { | ||
var index = _this.removeListeners.length; | ||
_this.removeListeners.push(method); | ||
return function () { return _this.removeRemoveListener(index); }; | ||
}; | ||
this.subscribe = function (observer) { return _this._subject.subscribe({ | ||
next: observer.next, | ||
}); }; | ||
this.complete = function () { | ||
_this.isClosed = true; | ||
_this._subject.complete(); | ||
}; | ||
this.clearCache = function () { | ||
var key = _this._options.persistKey; | ||
if (key) { | ||
localStorage.removeItem("".concat(LOCAL_STORAGE_PREFIX).concat(key)); | ||
} | ||
}; | ||
this.next = function (value) { | ||
_this._subject.next(value); | ||
_this.updateCache(); | ||
}; | ||
this.getCachedValue = function () { | ||
var cachedValue = localStorage.getItem("".concat(LOCAL_STORAGE_PREFIX).concat(_this._options.persistKey)); | ||
if (cachedValue) { | ||
try { | ||
return _this.jsonToState(cachedValue); | ||
} | ||
catch (e) { | ||
var error = new Error("Failed to parse JSON in localstorage for the key: \"".concat(LOCAL_STORAGE_PREFIX).concat(_this._options.persistKey, "\"")); | ||
console.error(error); | ||
return error; | ||
} | ||
} | ||
return new Error("Key not found"); | ||
}; | ||
this.updateCache = function () { | ||
var _a = _this._options, persistData = _a.persistData, persistKey = _a.persistKey; | ||
if (persistData && persistKey) { | ||
localStorage.setItem("".concat(LOCAL_STORAGE_PREFIX).concat(persistKey), _this.stateToJson(_this.state)); | ||
} | ||
else { | ||
_this.clearCache(); | ||
} | ||
}; | ||
var value = initialValue; | ||
var options = __assign(__assign({}, cubitDefaultOptions), blocOptions); | ||
this._options = options; | ||
if (options.persistKey && options.persistData) { | ||
var cachedValue = this.getCachedValue(); | ||
if (!(cachedValue instanceof Error)) { | ||
value = cachedValue; | ||
} | ||
} | ||
this._subject = new BehaviorSubject(value); | ||
} | ||
Object.defineProperty(StreamAbstraction.prototype, "state", { | ||
get: function () { | ||
return this._subject.getValue(); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
} | ||
removeObserver(removeId) { | ||
this.observers = this.observers.filter(({ id }) => id !== removeId); | ||
} | ||
} | ||
class StreamAbstraction { | ||
isClosed = false; | ||
removeListeners = []; | ||
_options; | ||
_subject; | ||
constructor(initialValue, blocOptions = {}) { | ||
let value = initialValue; | ||
const options = { ...cubitDefaultOptions, ...blocOptions }; | ||
this._options = options; | ||
if (options.persistKey && options.persistData) { | ||
const cachedValue = this.getCachedValue(); | ||
if (!(cachedValue instanceof Error)) { | ||
value = cachedValue; | ||
} | ||
StreamAbstraction.prototype.jsonToState = function (state) { | ||
return JSON.parse(state).state; | ||
}; | ||
StreamAbstraction.prototype.stateToJson = function (state) { | ||
return JSON.stringify({ state: state }); | ||
}; | ||
return StreamAbstraction; | ||
}()); | ||
var BlocBase = /** @class */ (function (_super) { | ||
__extends(BlocBase, _super); | ||
function BlocBase(initialValue, blocOptions) { | ||
if (blocOptions === void 0) { blocOptions = {}; } | ||
var _this = _super.call(this, initialValue, blocOptions) || this; | ||
_this.id = createId(); | ||
_this.createdAt = new Date(); | ||
_this.meta = { | ||
scope: 'unknown' | ||
}; | ||
_this.changeListeners = []; | ||
_this.registerListeners = []; | ||
_this.valueChangeListeners = []; | ||
_this.consumer = null; | ||
// listeners | ||
_this.removeChangeListener = function (index) { | ||
_this.changeListeners.splice(index, 1); | ||
}; | ||
_this.addChangeListener = function (method) { | ||
var index = _this.changeListeners.length; | ||
_this.changeListeners.push(method); | ||
return function () { return _this.removeChangeListener(index); }; | ||
}; | ||
_this.removeValueChangeListener = function (index) { | ||
_this.valueChangeListeners.splice(index, 1); | ||
}; | ||
_this.addValueChangeListener = function (method) { | ||
var index = _this.valueChangeListeners.length; | ||
_this.valueChangeListeners.push(method); | ||
return function () { return _this.removeValueChangeListener(index); }; | ||
}; | ||
_this.removeRegisterListener = function (index) { | ||
_this.registerListeners.splice(index, 1); | ||
}; | ||
_this.addRegisterListener = function (method) { | ||
var index = _this.registerListeners.length; | ||
_this.registerListeners.push(method); | ||
return function () { return _this.removeRegisterListener(index); }; | ||
}; | ||
_this.notifyChange = function (state) { | ||
var _a; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyChange(_this, state); | ||
_this.changeListeners.forEach(function (fn) { return fn({ | ||
currentState: _this.state, | ||
nextState: state, | ||
}, _this); }); | ||
}; | ||
_this.notifyValueChange = function () { | ||
var _a; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyValueChange(_this); | ||
_this.valueChangeListeners.forEach(function (fn) { return fn(_this.state, _this); }); | ||
}; | ||
return _this; | ||
} | ||
this._subject = new BehaviorSubject(value); | ||
} | ||
get state() { | ||
return this._subject.getValue(); | ||
} | ||
removeRemoveListener = (index) => { | ||
this.removeListeners.splice(index, 1); | ||
}; | ||
addRemoveListener = (method) => { | ||
const index = this.removeListeners.length; | ||
this.removeListeners.push(method); | ||
return () => this.removeRemoveListener(index); | ||
}; | ||
subscribe = (observer) => this._subject.subscribe({ | ||
next: observer.next | ||
}); | ||
complete = () => { | ||
this.isClosed = true; | ||
this._subject.complete(); | ||
}; | ||
clearCache = () => { | ||
const key = this._options.persistKey; | ||
if (key) { | ||
localStorage.removeItem(`${LOCAL_STORAGE_PREFIX}${key}`); | ||
return BlocBase; | ||
}(StreamAbstraction)); | ||
var Bloc = /** @class */ (function (_super) { | ||
__extends(Bloc, _super); | ||
function Bloc(initialState, options) { | ||
var _this = _super.call(this, initialState, options) || this; | ||
_this.onTransition = null; | ||
_this.mapEventToState = null; | ||
_this.add = function (event) { | ||
if (_this.mapEventToState) { | ||
var newState = _this.mapEventToState(event); | ||
_this.notifyChange(newState); | ||
_this.notifyTransition(newState, event); | ||
_this.next(newState); | ||
_this.notifyValueChange(); | ||
} | ||
else { | ||
console.error("\"mapEventToState\" not implemented for \"".concat(_this.constructor.name, "\"")); | ||
} | ||
}; | ||
_this.notifyTransition = function (state, event) { | ||
var _a, _b; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyTransition(_this, state, event); | ||
(_b = _this.onTransition) === null || _b === void 0 ? void 0 : _b.call(_this, { | ||
currentState: _this.state, | ||
event: event, | ||
nextState: state, | ||
}); | ||
}; | ||
return _this; | ||
} | ||
}; | ||
jsonToState(state) { | ||
return JSON.parse(state).state; | ||
} | ||
stateToJson(state) { | ||
return JSON.stringify({ state }); | ||
} | ||
next = (value) => { | ||
this._subject.next(value); | ||
this.updateCache(); | ||
}; | ||
getCachedValue = () => { | ||
const cachedValue = localStorage.getItem(`${LOCAL_STORAGE_PREFIX}${this._options.persistKey}`); | ||
if (cachedValue) { | ||
try { | ||
return this.jsonToState(cachedValue); | ||
} catch (e) { | ||
const error = new Error(`Failed to parse JSON in localstorage for the key: "${LOCAL_STORAGE_PREFIX}${this._options.persistKey}"`); | ||
console.error(error); | ||
return error; | ||
} | ||
return Bloc; | ||
}(BlocBase)); | ||
var Cubit = /** @class */ (function (_super) { | ||
__extends(Cubit, _super); | ||
function Cubit() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.emit = function (value) { | ||
_this.notifyChange(value); | ||
_this.next(value); | ||
_this.notifyValueChange(); | ||
}; | ||
return _this; | ||
} | ||
return new Error("Key not found"); | ||
}; | ||
updateCache = () => { | ||
const { persistData, persistKey } = this._options; | ||
if (persistData && persistKey) { | ||
localStorage.setItem(`${LOCAL_STORAGE_PREFIX}${persistKey}`, this.stateToJson(this.state)); | ||
} else { | ||
this.clearCache(); | ||
} | ||
}; | ||
} | ||
return Cubit; | ||
}(BlocBase)); | ||
class BlocBase extends StreamAbstraction { | ||
id = createId(); | ||
createdAt = new Date(); | ||
meta = { | ||
scope: "unknown" | ||
}; | ||
changeListeners = []; | ||
registerListeners = []; | ||
valueChangeListeners = []; | ||
consumer = null; | ||
constructor(initialValue, blocOptions = {}) { | ||
super(initialValue, blocOptions); | ||
} | ||
removeChangeListener = (index) => { | ||
this.changeListeners.splice(index, 1); | ||
}; | ||
addChangeListener = (method) => { | ||
const index = this.changeListeners.length; | ||
this.changeListeners.push(method); | ||
return () => this.removeChangeListener(index); | ||
}; | ||
removeValueChangeListener = (index) => { | ||
this.valueChangeListeners.splice(index, 1); | ||
}; | ||
addValueChangeListener = (method) => { | ||
const index = this.valueChangeListeners.length; | ||
this.valueChangeListeners.push(method); | ||
return () => this.removeValueChangeListener(index); | ||
}; | ||
removeRegisterListener = (index) => { | ||
this.registerListeners.splice(index, 1); | ||
}; | ||
addRegisterListener = (method) => { | ||
const index = this.registerListeners.length; | ||
this.registerListeners.push(method); | ||
return () => this.removeRegisterListener(index); | ||
}; | ||
notifyChange = (state) => { | ||
this.consumer?.notifyChange(this, state); | ||
this.changeListeners.forEach((fn) => fn({ | ||
currentState: this.state, | ||
nextState: state | ||
}, this)); | ||
}; | ||
notifyValueChange = () => { | ||
this.consumer?.notifyValueChange(this); | ||
this.valueChangeListeners.forEach((fn) => fn(this.state, this)); | ||
}; | ||
} | ||
class Bloc extends BlocBase { | ||
onTransition = null; | ||
mapEventToState = null; | ||
constructor(initialState, options) { | ||
super(initialState, options); | ||
} | ||
add = (event) => { | ||
if (this.mapEventToState) { | ||
const newState = this.mapEventToState(event); | ||
this.notifyChange(newState); | ||
this.notifyTransition(newState, event); | ||
this.next(newState); | ||
this.notifyValueChange(); | ||
} else { | ||
console.error(`"mapEventToState" not implemented for "${this.constructor.name}"`); | ||
var BlocObserver = /** @class */ (function () { | ||
function BlocObserver(methods) { | ||
var _this = this; | ||
if (methods === void 0) { methods = {}; } | ||
// trigger events | ||
this.addChange = function (bloc, state) { | ||
_this.onChange(bloc, _this.createChangeEvent(bloc, state)); | ||
}; | ||
this.addTransition = function (bloc, state, event) { | ||
_this.onTransition(bloc, _this.createTransitionEvent(bloc, state, event)); | ||
}; | ||
this.addBlocAdded = function (bloc) { | ||
_this.onBlocAdded(bloc); | ||
}; | ||
this.addBlocRemoved = function (bloc) { | ||
_this.onBlocRemoved(bloc); | ||
}; | ||
// consume | ||
this.defaultAction = function () { }; | ||
this.onBlocAdded = this.defaultAction; | ||
this.onBlocRemoved = this.defaultAction; | ||
this.onChange = methods.onChange ? methods.onChange : this.defaultAction; | ||
this.onTransition = methods.onTransition ? methods.onTransition : this.defaultAction; | ||
} | ||
}; | ||
notifyTransition = (state, event) => { | ||
this.consumer?.notifyTransition(this, state, event); | ||
this.onTransition?.({ | ||
currentState: this.state, | ||
event, | ||
nextState: state | ||
}); | ||
}; | ||
} | ||
class Cubit extends BlocBase { | ||
emit = (value) => { | ||
this.notifyChange(value); | ||
this.next(value); | ||
this.notifyValueChange(); | ||
}; | ||
} | ||
class BlocObserver { | ||
onChange; | ||
onTransition; | ||
constructor(methods = {}) { | ||
this.onChange = methods.onChange ? methods.onChange : this.defaultAction; | ||
this.onTransition = methods.onTransition ? methods.onTransition : this.defaultAction; | ||
} | ||
addChange = (bloc, state) => { | ||
this.onChange(bloc, this.createChangeEvent(bloc, state)); | ||
}; | ||
addTransition = (bloc, state, event) => { | ||
this.onTransition(bloc, this.createTransitionEvent(bloc, state, event)); | ||
}; | ||
addBlocAdded = (bloc) => { | ||
this.onBlocAdded(bloc); | ||
}; | ||
addBlocRemoved = (bloc) => { | ||
this.onBlocRemoved(bloc); | ||
}; | ||
defaultAction = () => { | ||
}; | ||
onBlocAdded = this.defaultAction; | ||
onBlocRemoved = this.defaultAction; | ||
createTransitionEvent(bloc, state, event) { | ||
return { | ||
currentState: bloc.state, | ||
event, | ||
nextState: state | ||
BlocObserver.prototype.createTransitionEvent = function (bloc, state, event) { | ||
return { | ||
currentState: bloc.state, | ||
event: event, | ||
nextState: state, | ||
}; | ||
}; | ||
} | ||
createChangeEvent(bloc, state) { | ||
return { | ||
currentState: bloc.state, | ||
nextState: state | ||
BlocObserver.prototype.createChangeEvent = function (bloc, state) { | ||
return { | ||
currentState: bloc.state, | ||
nextState: state, | ||
}; | ||
}; | ||
} | ||
} | ||
return BlocObserver; | ||
}()); | ||
class BlocConsumer { | ||
observer; | ||
mocksEnabled = false; | ||
providerList = []; | ||
blocListGlobal; | ||
blocChangeObservers = []; | ||
blocValueChangeObservers = []; | ||
mockBlocs = []; | ||
constructor(blocs, options = {}) { | ||
this.blocListGlobal = blocs; | ||
this.observer = options.observer || new BlocObserver(); | ||
for (const b of blocs) { | ||
b.consumer = this; | ||
b.registerListeners.forEach((fn) => fn(this, b)); | ||
b.meta.scope = "global"; | ||
this.observer.addBlocAdded(b); | ||
var BlocConsumer = /** @class */ (function () { | ||
function BlocConsumer(blocs, options) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
this.mocksEnabled = false; | ||
this.providerList = []; | ||
this.blocChangeObservers = []; | ||
this.blocValueChangeObservers = []; | ||
this.mockBlocs = []; | ||
this.blocListGlobal = blocs; | ||
this.observer = options.observer || new BlocObserver(); | ||
var _loop_1 = function (b) { | ||
b.consumer = this_1; | ||
b.registerListeners.forEach(function (fn) { return fn(_this, b); }); | ||
b.meta.scope = 'global'; | ||
this_1.observer.addBlocAdded(b); | ||
}; | ||
var this_1 = this; | ||
for (var _i = 0, blocs_1 = blocs; _i < blocs_1.length; _i++) { | ||
var b = blocs_1[_i]; | ||
_loop_1(b); | ||
} | ||
} | ||
} | ||
notifyChange(bloc, state) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addChange(bloc, state); | ||
for (const [blocClass, callback, scope] of this.blocChangeObservers) { | ||
const isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
const matchesScope = scope === "all" || isGlobal && scope === "global" || !isGlobal && scope === "local"; | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc, { | ||
nextState: state, | ||
currentState: bloc.state | ||
}); | ||
} | ||
} | ||
} | ||
notifyValueChange(bloc) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
for (const [blocClass, callback, scope] of this.blocValueChangeObservers) { | ||
const isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
const matchesScope = scope === "all" || isGlobal && scope === "global" || !isGlobal && scope === "local"; | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc); | ||
} | ||
} | ||
} | ||
notifyTransition(bloc, state, event) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addTransition(bloc, state, event); | ||
} | ||
addBlocChangeObserver(blocClass, callback, scope = "all") { | ||
this.blocChangeObservers.push([blocClass, callback, scope]); | ||
} | ||
addBlocValueChangeObserver(blocClass, callback, scope = "all") { | ||
this.blocValueChangeObservers.push([blocClass, callback, scope]); | ||
} | ||
addLocalBloc(item) { | ||
this.providerList.push(item); | ||
item.bloc.consumer = this; | ||
item.bloc.registerListeners.forEach((fn) => fn(this, item.bloc)); | ||
item.bloc.meta.scope = "local"; | ||
this.observer.addBlocAdded(item.bloc); | ||
} | ||
removeLocalBloc(id, bloc) { | ||
const item = this.providerList.find((i) => i.id === id && i.bloc === bloc); | ||
if (item) { | ||
item.bloc.complete(); | ||
item.bloc.removeListeners.forEach((fn) => fn()); | ||
this.observer.addBlocRemoved(item.bloc); | ||
this.providerList = this.providerList.filter((i) => i !== item); | ||
} | ||
} | ||
addBlocMock(bloc) { | ||
if (this.mocksEnabled) { | ||
this.mockBlocs = [bloc, ...this.mockBlocs]; | ||
} | ||
} | ||
resetMocks() { | ||
this.mockBlocs = []; | ||
} | ||
getGlobalBloc(blocClass) { | ||
if (this.mocksEnabled) { | ||
const mockedBloc = this.mockBlocs.find((c) => c instanceof blocClass); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return this.blocListGlobal.find((c) => c instanceof blocClass); | ||
} | ||
getLocalBlocForProvider(id, blocClass) { | ||
for (const providerItem of this.providerList) { | ||
if (providerItem.id === id) { | ||
if (providerItem.bloc instanceof blocClass) { | ||
return providerItem.bloc; | ||
BlocConsumer.prototype.notifyChange = function (bloc, state) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
let parent = providerItem.parent; | ||
while (parent) { | ||
const parentItem = this.providerList.find((i) => i.id === parent); | ||
if (parentItem?.bloc instanceof blocClass) { | ||
return parentItem.bloc; | ||
} | ||
parent = parentItem?.parent; | ||
this.observer.addChange(bloc, state); | ||
for (var _i = 0, _a = this.blocChangeObservers; _i < _a.length; _i++) { | ||
var _b = _a[_i], blocClass = _b[0], callback = _b[1], scope = _b[2]; | ||
var isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
var matchesScope = scope === "all" || | ||
(isGlobal && scope === "global") || | ||
(!isGlobal && scope === "local"); | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc, { | ||
nextState: state, | ||
currentState: bloc.state | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
return void 0; | ||
} | ||
getGlobalBlocInstance(global, blocClass) { | ||
if (this.mocksEnabled) { | ||
const mockedBloc = this.mockBlocs.find((c) => c instanceof blocClass); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return global.find((c) => c instanceof blocClass); | ||
} | ||
} | ||
}; | ||
BlocConsumer.prototype.notifyValueChange = function (bloc) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
for (var _i = 0, _a = this.blocValueChangeObservers; _i < _a.length; _i++) { | ||
var _b = _a[_i], blocClass = _b[0], callback = _b[1], scope = _b[2]; | ||
var isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
var matchesScope = scope === "all" || | ||
(isGlobal && scope === "global") || | ||
(!isGlobal && scope === "local"); | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc); | ||
} | ||
} | ||
}; | ||
BlocConsumer.prototype.notifyTransition = function (bloc, state, event) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addTransition(bloc, state, event); | ||
}; | ||
BlocConsumer.prototype.addBlocChangeObserver = function (blocClass, callback, scope) { | ||
if (scope === void 0) { scope = "all"; } | ||
this.blocChangeObservers.push([blocClass, callback, scope]); | ||
}; | ||
BlocConsumer.prototype.addBlocValueChangeObserver = function (blocClass, callback, scope) { | ||
if (scope === void 0) { scope = "all"; } | ||
this.blocValueChangeObservers.push([blocClass, callback, scope]); | ||
}; | ||
BlocConsumer.prototype.addLocalBloc = function (item) { | ||
var _this = this; | ||
this.providerList.push(item); | ||
item.bloc.consumer = this; | ||
item.bloc.registerListeners.forEach(function (fn) { return fn(_this, item.bloc); }); | ||
item.bloc.meta.scope = 'local'; | ||
this.observer.addBlocAdded(item.bloc); | ||
}; | ||
BlocConsumer.prototype.removeLocalBloc = function (id, bloc) { | ||
var item = this.providerList.find(function (i) { return i.id === id && i.bloc === bloc; }); | ||
if (item) { | ||
item.bloc.complete(); | ||
item.bloc.removeListeners.forEach(function (fn) { return fn(); }); | ||
this.observer.addBlocRemoved(item.bloc); | ||
this.providerList = this.providerList.filter(function (i) { return i !== item; }); | ||
} | ||
}; | ||
BlocConsumer.prototype.addBlocMock = function (bloc) { | ||
if (this.mocksEnabled) { | ||
this.mockBlocs = __spreadArray([bloc], this.mockBlocs, true); | ||
} | ||
}; | ||
BlocConsumer.prototype.resetMocks = function () { | ||
this.mockBlocs = []; | ||
}; | ||
BlocConsumer.prototype.getGlobalBloc = function (blocClass) { | ||
if (this.mocksEnabled) { | ||
var mockedBloc = this.mockBlocs.find(function (c) { return c instanceof blocClass; }); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return this.blocListGlobal.find(function (c) { return c instanceof blocClass; }); | ||
}; | ||
BlocConsumer.prototype.getLocalBlocForProvider = function (id, blocClass) { | ||
var _loop_2 = function (providerItem) { | ||
if (providerItem.id === id) { | ||
if (providerItem.bloc instanceof blocClass) { | ||
return { value: providerItem.bloc }; | ||
} | ||
var parent_1 = providerItem.parent; | ||
while (parent_1) { | ||
var parentItem = this_2.providerList.find(function (i) { return i.id === parent_1; }); | ||
if ((parentItem === null || parentItem === void 0 ? void 0 : parentItem.bloc) instanceof blocClass) { | ||
return { value: parentItem.bloc }; | ||
} | ||
parent_1 = parentItem === null || parentItem === void 0 ? void 0 : parentItem.parent; | ||
} | ||
} | ||
}; | ||
var this_2 = this; | ||
for (var _i = 0, _a = this.providerList; _i < _a.length; _i++) { | ||
var providerItem = _a[_i]; | ||
var state_1 = _loop_2(providerItem); | ||
if (typeof state_1 === "object") | ||
return state_1.value; | ||
} | ||
return undefined; | ||
}; | ||
BlocConsumer.prototype.getGlobalBlocInstance = function (global, blocClass) { | ||
if (this.mocksEnabled) { | ||
var mockedBloc = this.mockBlocs.find(function (c) { return c instanceof blocClass; }); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return global.find(function (c) { return c instanceof blocClass; }); | ||
}; | ||
return BlocConsumer; | ||
}()); | ||
const defaultBlocHookOptions = { | ||
subscribe: true | ||
var defaultBlocHookOptions = { | ||
subscribe: true | ||
}; | ||
class BlocRuntimeError { | ||
error; | ||
constructor(message) { | ||
this.error = new Error(message); | ||
} | ||
} | ||
class NoValue { | ||
} | ||
class BlocReact extends BlocConsumer { | ||
providerCount = 0; | ||
_blocsGlobal; | ||
_contextLocalProviderKey = React.createContext("none"); | ||
constructor(blocs, options) { | ||
super(blocs, options); | ||
this._blocsGlobal = blocs; | ||
this.BlocProvider = this.BlocProvider.bind(this); | ||
this.BlocBuilder = this.BlocBuilder.bind(this); | ||
} | ||
useBloc = (blocClass, options = {}) => { | ||
const mergedOptions = { | ||
...defaultBlocHookOptions, | ||
...options | ||
}; | ||
let blocInstance = useMemo(() => options.create ? options.create() : void 0, []); | ||
if (!blocInstance) { | ||
const localProviderKey = useContext(this._contextLocalProviderKey); | ||
const localBlocInstance = useMemo(() => this.getLocalBlocForProvider(localProviderKey, blocClass), []); | ||
blocInstance = useMemo(() => localBlocInstance || this.getGlobalBlocInstance(this._blocsGlobal, blocClass), []); | ||
var BlocRuntimeError = /** @class */ (function () { | ||
function BlocRuntimeError(message) { | ||
this.error = new Error(message); | ||
} | ||
const { subscribe, shouldUpdate = true } = mergedOptions; | ||
if (!blocInstance) { | ||
const name = blocClass.prototype.constructor.name; | ||
const error = new BlocRuntimeError(`"${name}" | ||
no bloc with this name was found in the global context. | ||
# Solutions: | ||
1. Wrap your code in a BlocProvider. | ||
2. Add "${name}" to the "BlocReact" constructor: | ||
const state = new BlocReact( | ||
[ | ||
... | ||
new ${name}(), | ||
] | ||
) | ||
`); | ||
console.error(error.error); | ||
return [ | ||
NoValue, | ||
{}, | ||
{ | ||
error, | ||
complete: true | ||
} | ||
]; | ||
return BlocRuntimeError; | ||
}()); | ||
var NoValue = /** @class */ (function () { | ||
function NoValue() { | ||
} | ||
const [data, setData] = useState(blocInstance.state); | ||
const updateData = useCallback((nextState) => { | ||
if (shouldUpdate === true || shouldUpdate({ nextState, currentState: data })) { | ||
setData(nextState); | ||
} | ||
}, []); | ||
useEffect(() => { | ||
if (subscribe) { | ||
const subscription = blocInstance?.subscribe({ | ||
next: updateData | ||
}); | ||
return () => { | ||
subscription?.unsubscribe(); | ||
return NoValue; | ||
}()); | ||
var BlocReact = /** @class */ (function (_super) { | ||
__extends(BlocReact, _super); | ||
function BlocReact(blocs, options) { | ||
var _this = _super.call(this, blocs, options) || this; | ||
_this.providerCount = 0; | ||
_this._contextLocalProviderKey = React.createContext('none'); | ||
_this.useBloc = function (blocClass, options) { | ||
if (options === void 0) { options = {}; } | ||
var mergedOptions = __assign(__assign({}, defaultBlocHookOptions), options); | ||
var blocInstance = useMemo(function () { return options.create ? options.create() : undefined; }, []); | ||
if (!blocInstance) { | ||
var localProviderKey_1 = useContext(_this._contextLocalProviderKey); | ||
var localBlocInstance_1 = useMemo(function () { return _this.getLocalBlocForProvider(localProviderKey_1, blocClass); }, []); | ||
blocInstance = useMemo(function () { return localBlocInstance_1 || _this.getGlobalBlocInstance(_this._blocsGlobal, blocClass); }, []); | ||
} | ||
var subscribe = mergedOptions.subscribe, _a = mergedOptions.shouldUpdate, shouldUpdate = _a === void 0 ? true : _a; | ||
if (!blocInstance) { | ||
var name_1 = blocClass.prototype.constructor.name; | ||
var error = new BlocRuntimeError("\"".concat(name_1, "\" \n no bloc with this name was found in the global context.\n \n # Solutions:\n \n 1. Wrap your code in a BlocProvider.\n \n 2. Add \"").concat(name_1, "\" to the \"BlocReact\" constructor:\n const state = new BlocReact(\n [\n ...\n new ").concat(name_1, "(),\n ]\n )\n ")); | ||
console.error(error.error); | ||
return [ | ||
NoValue, | ||
{}, | ||
{ | ||
error: error, | ||
complete: true | ||
} | ||
]; | ||
} | ||
var _b = useState(blocInstance.state), data = _b[0], setData = _b[1]; | ||
var updateData = useCallback(function (nextState) { | ||
if (shouldUpdate === true || shouldUpdate({ nextState: nextState, currentState: data })) { | ||
setData(nextState); | ||
} | ||
}, []); | ||
useEffect(function () { | ||
if (subscribe) { | ||
var subscription_1 = blocInstance === null || blocInstance === void 0 ? void 0 : blocInstance.subscribe({ | ||
next: updateData | ||
}); | ||
return function () { | ||
subscription_1 === null || subscription_1 === void 0 ? void 0 : subscription_1.unsubscribe(); | ||
}; | ||
} | ||
}, []); | ||
return [ | ||
data, | ||
blocInstance | ||
]; | ||
}; | ||
} | ||
}, []); | ||
return [ | ||
data, | ||
blocInstance | ||
]; | ||
}; | ||
BlocBuilder(props) { | ||
const hook = this.useBloc(props.blocClass, { | ||
shouldUpdate: props.shouldUpdate | ||
}); | ||
return props.builder(hook); | ||
} | ||
BlocProvider(props) { | ||
const id = useMemo(() => createId(), []); | ||
const localProviderKey = useContext(this._contextLocalProviderKey); | ||
const bloc = useMemo(() => { | ||
const newBloc = typeof props.bloc === "function" ? props.bloc(id) : props.bloc; | ||
if (newBloc) { | ||
this.addLocalBloc({ | ||
bloc: newBloc, | ||
id, | ||
parent: localProviderKey | ||
_this.withBlocProvider = function (bloc) { return function (Component) { | ||
var BlocProvider = _this.BlocProvider; | ||
return /** @class */ (function (_super) { | ||
__extends(WithBlocProvider, _super); | ||
function WithBlocProvider() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
WithBlocProvider.prototype.render = function () { | ||
return (React.createElement(BlocProvider, { bloc: bloc }, | ||
React.createElement(Component, __assign({}, this.props)))); | ||
}; | ||
return WithBlocProvider; | ||
}(React.Component)); | ||
}; }; | ||
_this._blocsGlobal = blocs; | ||
_this.BlocProvider = _this.BlocProvider.bind(_this); | ||
_this.BlocBuilder = _this.BlocBuilder.bind(_this); | ||
return _this; | ||
} | ||
// Components | ||
BlocReact.prototype.BlocBuilder = function (props) { | ||
var hook = this.useBloc(props.blocClass, { | ||
shouldUpdate: props.shouldUpdate | ||
}); | ||
} else { | ||
console.error(`BLoC is undefined`); | ||
} | ||
return newBloc; | ||
}, []); | ||
const context = useMemo(() => { | ||
return React.createContext(bloc); | ||
}, [bloc]); | ||
useEffect(() => { | ||
return () => { | ||
this.removeLocalBloc(id, bloc); | ||
}; | ||
}, []); | ||
return /* @__PURE__ */ React.createElement(this._contextLocalProviderKey.Provider, { | ||
value: id | ||
}, /* @__PURE__ */ React.createElement(context.Provider, { | ||
value: bloc | ||
}, props.children)); | ||
} | ||
withBlocProvider = (bloc) => (Component) => { | ||
const { BlocProvider } = this; | ||
return class WithBlocProvider extends React.Component { | ||
render() { | ||
return /* @__PURE__ */ React.createElement(BlocProvider, { | ||
bloc | ||
}, /* @__PURE__ */ React.createElement(Component, { | ||
...this.props | ||
})); | ||
} | ||
return props.builder(hook); | ||
}; | ||
}; | ||
} | ||
BlocReact.prototype.BlocProvider = function (props) { | ||
var _this = this; | ||
var id = useMemo(function () { return createId(); }, []); | ||
var localProviderKey = useContext(this._contextLocalProviderKey); | ||
var bloc = useMemo(function () { | ||
var newBloc = typeof props.bloc === "function" ? props.bloc(id) : props.bloc; | ||
if (newBloc) { | ||
_this.addLocalBloc({ | ||
bloc: newBloc, | ||
id: id, | ||
parent: localProviderKey | ||
}); | ||
} | ||
else { | ||
console.error("BLoC is undefined"); | ||
} | ||
return newBloc; | ||
}, []); | ||
var context = useMemo(function () { | ||
return React.createContext(bloc); | ||
}, [bloc]); | ||
useEffect(function () { | ||
return function () { | ||
_this.removeLocalBloc(id, bloc); | ||
}; | ||
}, []); | ||
return (React.createElement(this._contextLocalProviderKey.Provider, { value: id }, | ||
React.createElement(context.Provider, { value: bloc }, props.children))); | ||
}; | ||
return BlocReact; | ||
}(BlocConsumer)); | ||
export { Bloc, BlocObserver, BlocReact, Cubit }; | ||
//# sourceMappingURL=bloc-react.esm.js.map |
@@ -5,2 +5,3 @@ 'use strict'; | ||
var tslib = require('tslib'); | ||
var React = require('react'); | ||
@@ -12,495 +13,540 @@ | ||
const LOCAL_STORAGE_PREFIX = "data."; | ||
const cubitDefaultOptions = { | ||
persistKey: "", | ||
persistData: true | ||
var LOCAL_STORAGE_PREFIX = "data."; | ||
var cubitDefaultOptions = { | ||
persistKey: "", | ||
persistData: true, | ||
}; | ||
const createId = () => { | ||
return "_" + Math.random().toString(36).substr(2, 9); | ||
var createId = function () { | ||
return '_' + Math.random().toString(36).substr(2, 9); | ||
}; | ||
class BehaviorSubject { | ||
isClosed = false; | ||
prevValue; | ||
value; | ||
observers = []; | ||
constructor(initialValue) { | ||
this.value = initialValue; | ||
} | ||
getValue() { | ||
return this.value; | ||
} | ||
subscribe(observer) { | ||
const id = createId(); | ||
this.observers.push({ observer, id }); | ||
this.triggerObservers(); | ||
return { | ||
unsubscribe: () => this.removeObserver(id) | ||
var BehaviorSubject = /** @class */ (function () { | ||
function BehaviorSubject(initialValue) { | ||
this.isClosed = false; | ||
this.observers = []; | ||
this.value = initialValue; | ||
} | ||
BehaviorSubject.prototype.getValue = function () { | ||
return this.value; | ||
}; | ||
} | ||
complete() { | ||
this.observers = []; | ||
this.isClosed = true; | ||
} | ||
next(value) { | ||
this.value = value; | ||
this.triggerObservers(); | ||
} | ||
triggerObservers() { | ||
this.observers.forEach(({ observer }) => { | ||
observer.next(this.value); | ||
BehaviorSubject.prototype.subscribe = function (observer) { | ||
var _this = this; | ||
var id = createId(); | ||
this.observers.push({ observer: observer, id: id }); | ||
this.triggerObservers(); | ||
return { | ||
unsubscribe: function () { return _this.removeObserver(id); } | ||
}; | ||
}; | ||
BehaviorSubject.prototype.complete = function () { | ||
this.observers = []; | ||
this.isClosed = true; | ||
}; | ||
BehaviorSubject.prototype.next = function (value) { | ||
this.value = value; | ||
this.triggerObservers(); | ||
}; | ||
BehaviorSubject.prototype.triggerObservers = function () { | ||
var _this = this; | ||
this.observers.forEach(function (_a) { | ||
var observer = _a.observer; | ||
observer.next(_this.value); | ||
}); | ||
}; | ||
BehaviorSubject.prototype.removeObserver = function (removeId) { | ||
this.observers = this.observers.filter(function (_a) { | ||
var id = _a.id; | ||
return id !== removeId; | ||
}); | ||
}; | ||
return BehaviorSubject; | ||
}()); | ||
var StreamAbstraction = /** @class */ (function () { | ||
function StreamAbstraction(initialValue, blocOptions) { | ||
var _this = this; | ||
if (blocOptions === void 0) { blocOptions = {}; } | ||
this.isClosed = false; | ||
this.removeListeners = []; | ||
this.removeRemoveListener = function (index) { | ||
_this.removeListeners.splice(index, 1); | ||
}; | ||
this.addRemoveListener = function (method) { | ||
var index = _this.removeListeners.length; | ||
_this.removeListeners.push(method); | ||
return function () { return _this.removeRemoveListener(index); }; | ||
}; | ||
this.subscribe = function (observer) { return _this._subject.subscribe({ | ||
next: observer.next, | ||
}); }; | ||
this.complete = function () { | ||
_this.isClosed = true; | ||
_this._subject.complete(); | ||
}; | ||
this.clearCache = function () { | ||
var key = _this._options.persistKey; | ||
if (key) { | ||
localStorage.removeItem("".concat(LOCAL_STORAGE_PREFIX).concat(key)); | ||
} | ||
}; | ||
this.next = function (value) { | ||
_this._subject.next(value); | ||
_this.updateCache(); | ||
}; | ||
this.getCachedValue = function () { | ||
var cachedValue = localStorage.getItem("".concat(LOCAL_STORAGE_PREFIX).concat(_this._options.persistKey)); | ||
if (cachedValue) { | ||
try { | ||
return _this.jsonToState(cachedValue); | ||
} | ||
catch (e) { | ||
var error = new Error("Failed to parse JSON in localstorage for the key: \"".concat(LOCAL_STORAGE_PREFIX).concat(_this._options.persistKey, "\"")); | ||
console.error(error); | ||
return error; | ||
} | ||
} | ||
return new Error("Key not found"); | ||
}; | ||
this.updateCache = function () { | ||
var _a = _this._options, persistData = _a.persistData, persistKey = _a.persistKey; | ||
if (persistData && persistKey) { | ||
localStorage.setItem("".concat(LOCAL_STORAGE_PREFIX).concat(persistKey), _this.stateToJson(_this.state)); | ||
} | ||
else { | ||
_this.clearCache(); | ||
} | ||
}; | ||
var value = initialValue; | ||
var options = tslib.__assign(tslib.__assign({}, cubitDefaultOptions), blocOptions); | ||
this._options = options; | ||
if (options.persistKey && options.persistData) { | ||
var cachedValue = this.getCachedValue(); | ||
if (!(cachedValue instanceof Error)) { | ||
value = cachedValue; | ||
} | ||
} | ||
this._subject = new BehaviorSubject(value); | ||
} | ||
Object.defineProperty(StreamAbstraction.prototype, "state", { | ||
get: function () { | ||
return this._subject.getValue(); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
} | ||
removeObserver(removeId) { | ||
this.observers = this.observers.filter(({ id }) => id !== removeId); | ||
} | ||
} | ||
class StreamAbstraction { | ||
isClosed = false; | ||
removeListeners = []; | ||
_options; | ||
_subject; | ||
constructor(initialValue, blocOptions = {}) { | ||
let value = initialValue; | ||
const options = { ...cubitDefaultOptions, ...blocOptions }; | ||
this._options = options; | ||
if (options.persistKey && options.persistData) { | ||
const cachedValue = this.getCachedValue(); | ||
if (!(cachedValue instanceof Error)) { | ||
value = cachedValue; | ||
} | ||
StreamAbstraction.prototype.jsonToState = function (state) { | ||
return JSON.parse(state).state; | ||
}; | ||
StreamAbstraction.prototype.stateToJson = function (state) { | ||
return JSON.stringify({ state: state }); | ||
}; | ||
return StreamAbstraction; | ||
}()); | ||
var BlocBase = /** @class */ (function (_super) { | ||
tslib.__extends(BlocBase, _super); | ||
function BlocBase(initialValue, blocOptions) { | ||
if (blocOptions === void 0) { blocOptions = {}; } | ||
var _this = _super.call(this, initialValue, blocOptions) || this; | ||
_this.id = createId(); | ||
_this.createdAt = new Date(); | ||
_this.meta = { | ||
scope: 'unknown' | ||
}; | ||
_this.changeListeners = []; | ||
_this.registerListeners = []; | ||
_this.valueChangeListeners = []; | ||
_this.consumer = null; | ||
// listeners | ||
_this.removeChangeListener = function (index) { | ||
_this.changeListeners.splice(index, 1); | ||
}; | ||
_this.addChangeListener = function (method) { | ||
var index = _this.changeListeners.length; | ||
_this.changeListeners.push(method); | ||
return function () { return _this.removeChangeListener(index); }; | ||
}; | ||
_this.removeValueChangeListener = function (index) { | ||
_this.valueChangeListeners.splice(index, 1); | ||
}; | ||
_this.addValueChangeListener = function (method) { | ||
var index = _this.valueChangeListeners.length; | ||
_this.valueChangeListeners.push(method); | ||
return function () { return _this.removeValueChangeListener(index); }; | ||
}; | ||
_this.removeRegisterListener = function (index) { | ||
_this.registerListeners.splice(index, 1); | ||
}; | ||
_this.addRegisterListener = function (method) { | ||
var index = _this.registerListeners.length; | ||
_this.registerListeners.push(method); | ||
return function () { return _this.removeRegisterListener(index); }; | ||
}; | ||
_this.notifyChange = function (state) { | ||
var _a; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyChange(_this, state); | ||
_this.changeListeners.forEach(function (fn) { return fn({ | ||
currentState: _this.state, | ||
nextState: state, | ||
}, _this); }); | ||
}; | ||
_this.notifyValueChange = function () { | ||
var _a; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyValueChange(_this); | ||
_this.valueChangeListeners.forEach(function (fn) { return fn(_this.state, _this); }); | ||
}; | ||
return _this; | ||
} | ||
this._subject = new BehaviorSubject(value); | ||
} | ||
get state() { | ||
return this._subject.getValue(); | ||
} | ||
removeRemoveListener = (index) => { | ||
this.removeListeners.splice(index, 1); | ||
}; | ||
addRemoveListener = (method) => { | ||
const index = this.removeListeners.length; | ||
this.removeListeners.push(method); | ||
return () => this.removeRemoveListener(index); | ||
}; | ||
subscribe = (observer) => this._subject.subscribe({ | ||
next: observer.next | ||
}); | ||
complete = () => { | ||
this.isClosed = true; | ||
this._subject.complete(); | ||
}; | ||
clearCache = () => { | ||
const key = this._options.persistKey; | ||
if (key) { | ||
localStorage.removeItem(`${LOCAL_STORAGE_PREFIX}${key}`); | ||
return BlocBase; | ||
}(StreamAbstraction)); | ||
var Bloc = /** @class */ (function (_super) { | ||
tslib.__extends(Bloc, _super); | ||
function Bloc(initialState, options) { | ||
var _this = _super.call(this, initialState, options) || this; | ||
_this.onTransition = null; | ||
_this.mapEventToState = null; | ||
_this.add = function (event) { | ||
if (_this.mapEventToState) { | ||
var newState = _this.mapEventToState(event); | ||
_this.notifyChange(newState); | ||
_this.notifyTransition(newState, event); | ||
_this.next(newState); | ||
_this.notifyValueChange(); | ||
} | ||
else { | ||
console.error("\"mapEventToState\" not implemented for \"".concat(_this.constructor.name, "\"")); | ||
} | ||
}; | ||
_this.notifyTransition = function (state, event) { | ||
var _a, _b; | ||
(_a = _this.consumer) === null || _a === void 0 ? void 0 : _a.notifyTransition(_this, state, event); | ||
(_b = _this.onTransition) === null || _b === void 0 ? void 0 : _b.call(_this, { | ||
currentState: _this.state, | ||
event: event, | ||
nextState: state, | ||
}); | ||
}; | ||
return _this; | ||
} | ||
}; | ||
jsonToState(state) { | ||
return JSON.parse(state).state; | ||
} | ||
stateToJson(state) { | ||
return JSON.stringify({ state }); | ||
} | ||
next = (value) => { | ||
this._subject.next(value); | ||
this.updateCache(); | ||
}; | ||
getCachedValue = () => { | ||
const cachedValue = localStorage.getItem(`${LOCAL_STORAGE_PREFIX}${this._options.persistKey}`); | ||
if (cachedValue) { | ||
try { | ||
return this.jsonToState(cachedValue); | ||
} catch (e) { | ||
const error = new Error(`Failed to parse JSON in localstorage for the key: "${LOCAL_STORAGE_PREFIX}${this._options.persistKey}"`); | ||
console.error(error); | ||
return error; | ||
} | ||
return Bloc; | ||
}(BlocBase)); | ||
var Cubit = /** @class */ (function (_super) { | ||
tslib.__extends(Cubit, _super); | ||
function Cubit() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.emit = function (value) { | ||
_this.notifyChange(value); | ||
_this.next(value); | ||
_this.notifyValueChange(); | ||
}; | ||
return _this; | ||
} | ||
return new Error("Key not found"); | ||
}; | ||
updateCache = () => { | ||
const { persistData, persistKey } = this._options; | ||
if (persistData && persistKey) { | ||
localStorage.setItem(`${LOCAL_STORAGE_PREFIX}${persistKey}`, this.stateToJson(this.state)); | ||
} else { | ||
this.clearCache(); | ||
} | ||
}; | ||
} | ||
return Cubit; | ||
}(BlocBase)); | ||
class BlocBase extends StreamAbstraction { | ||
id = createId(); | ||
createdAt = new Date(); | ||
meta = { | ||
scope: "unknown" | ||
}; | ||
changeListeners = []; | ||
registerListeners = []; | ||
valueChangeListeners = []; | ||
consumer = null; | ||
constructor(initialValue, blocOptions = {}) { | ||
super(initialValue, blocOptions); | ||
} | ||
removeChangeListener = (index) => { | ||
this.changeListeners.splice(index, 1); | ||
}; | ||
addChangeListener = (method) => { | ||
const index = this.changeListeners.length; | ||
this.changeListeners.push(method); | ||
return () => this.removeChangeListener(index); | ||
}; | ||
removeValueChangeListener = (index) => { | ||
this.valueChangeListeners.splice(index, 1); | ||
}; | ||
addValueChangeListener = (method) => { | ||
const index = this.valueChangeListeners.length; | ||
this.valueChangeListeners.push(method); | ||
return () => this.removeValueChangeListener(index); | ||
}; | ||
removeRegisterListener = (index) => { | ||
this.registerListeners.splice(index, 1); | ||
}; | ||
addRegisterListener = (method) => { | ||
const index = this.registerListeners.length; | ||
this.registerListeners.push(method); | ||
return () => this.removeRegisterListener(index); | ||
}; | ||
notifyChange = (state) => { | ||
this.consumer?.notifyChange(this, state); | ||
this.changeListeners.forEach((fn) => fn({ | ||
currentState: this.state, | ||
nextState: state | ||
}, this)); | ||
}; | ||
notifyValueChange = () => { | ||
this.consumer?.notifyValueChange(this); | ||
this.valueChangeListeners.forEach((fn) => fn(this.state, this)); | ||
}; | ||
} | ||
class Bloc extends BlocBase { | ||
onTransition = null; | ||
mapEventToState = null; | ||
constructor(initialState, options) { | ||
super(initialState, options); | ||
} | ||
add = (event) => { | ||
if (this.mapEventToState) { | ||
const newState = this.mapEventToState(event); | ||
this.notifyChange(newState); | ||
this.notifyTransition(newState, event); | ||
this.next(newState); | ||
this.notifyValueChange(); | ||
} else { | ||
console.error(`"mapEventToState" not implemented for "${this.constructor.name}"`); | ||
var BlocObserver = /** @class */ (function () { | ||
function BlocObserver(methods) { | ||
var _this = this; | ||
if (methods === void 0) { methods = {}; } | ||
// trigger events | ||
this.addChange = function (bloc, state) { | ||
_this.onChange(bloc, _this.createChangeEvent(bloc, state)); | ||
}; | ||
this.addTransition = function (bloc, state, event) { | ||
_this.onTransition(bloc, _this.createTransitionEvent(bloc, state, event)); | ||
}; | ||
this.addBlocAdded = function (bloc) { | ||
_this.onBlocAdded(bloc); | ||
}; | ||
this.addBlocRemoved = function (bloc) { | ||
_this.onBlocRemoved(bloc); | ||
}; | ||
// consume | ||
this.defaultAction = function () { }; | ||
this.onBlocAdded = this.defaultAction; | ||
this.onBlocRemoved = this.defaultAction; | ||
this.onChange = methods.onChange ? methods.onChange : this.defaultAction; | ||
this.onTransition = methods.onTransition ? methods.onTransition : this.defaultAction; | ||
} | ||
}; | ||
notifyTransition = (state, event) => { | ||
this.consumer?.notifyTransition(this, state, event); | ||
this.onTransition?.({ | ||
currentState: this.state, | ||
event, | ||
nextState: state | ||
}); | ||
}; | ||
} | ||
class Cubit extends BlocBase { | ||
emit = (value) => { | ||
this.notifyChange(value); | ||
this.next(value); | ||
this.notifyValueChange(); | ||
}; | ||
} | ||
class BlocObserver { | ||
onChange; | ||
onTransition; | ||
constructor(methods = {}) { | ||
this.onChange = methods.onChange ? methods.onChange : this.defaultAction; | ||
this.onTransition = methods.onTransition ? methods.onTransition : this.defaultAction; | ||
} | ||
addChange = (bloc, state) => { | ||
this.onChange(bloc, this.createChangeEvent(bloc, state)); | ||
}; | ||
addTransition = (bloc, state, event) => { | ||
this.onTransition(bloc, this.createTransitionEvent(bloc, state, event)); | ||
}; | ||
addBlocAdded = (bloc) => { | ||
this.onBlocAdded(bloc); | ||
}; | ||
addBlocRemoved = (bloc) => { | ||
this.onBlocRemoved(bloc); | ||
}; | ||
defaultAction = () => { | ||
}; | ||
onBlocAdded = this.defaultAction; | ||
onBlocRemoved = this.defaultAction; | ||
createTransitionEvent(bloc, state, event) { | ||
return { | ||
currentState: bloc.state, | ||
event, | ||
nextState: state | ||
BlocObserver.prototype.createTransitionEvent = function (bloc, state, event) { | ||
return { | ||
currentState: bloc.state, | ||
event: event, | ||
nextState: state, | ||
}; | ||
}; | ||
} | ||
createChangeEvent(bloc, state) { | ||
return { | ||
currentState: bloc.state, | ||
nextState: state | ||
BlocObserver.prototype.createChangeEvent = function (bloc, state) { | ||
return { | ||
currentState: bloc.state, | ||
nextState: state, | ||
}; | ||
}; | ||
} | ||
} | ||
return BlocObserver; | ||
}()); | ||
class BlocConsumer { | ||
observer; | ||
mocksEnabled = false; | ||
providerList = []; | ||
blocListGlobal; | ||
blocChangeObservers = []; | ||
blocValueChangeObservers = []; | ||
mockBlocs = []; | ||
constructor(blocs, options = {}) { | ||
this.blocListGlobal = blocs; | ||
this.observer = options.observer || new BlocObserver(); | ||
for (const b of blocs) { | ||
b.consumer = this; | ||
b.registerListeners.forEach((fn) => fn(this, b)); | ||
b.meta.scope = "global"; | ||
this.observer.addBlocAdded(b); | ||
var BlocConsumer = /** @class */ (function () { | ||
function BlocConsumer(blocs, options) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
this.mocksEnabled = false; | ||
this.providerList = []; | ||
this.blocChangeObservers = []; | ||
this.blocValueChangeObservers = []; | ||
this.mockBlocs = []; | ||
this.blocListGlobal = blocs; | ||
this.observer = options.observer || new BlocObserver(); | ||
var _loop_1 = function (b) { | ||
b.consumer = this_1; | ||
b.registerListeners.forEach(function (fn) { return fn(_this, b); }); | ||
b.meta.scope = 'global'; | ||
this_1.observer.addBlocAdded(b); | ||
}; | ||
var this_1 = this; | ||
for (var _i = 0, blocs_1 = blocs; _i < blocs_1.length; _i++) { | ||
var b = blocs_1[_i]; | ||
_loop_1(b); | ||
} | ||
} | ||
} | ||
notifyChange(bloc, state) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addChange(bloc, state); | ||
for (const [blocClass, callback, scope] of this.blocChangeObservers) { | ||
const isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
const matchesScope = scope === "all" || isGlobal && scope === "global" || !isGlobal && scope === "local"; | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc, { | ||
nextState: state, | ||
currentState: bloc.state | ||
}); | ||
} | ||
} | ||
} | ||
notifyValueChange(bloc) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
for (const [blocClass, callback, scope] of this.blocValueChangeObservers) { | ||
const isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
const matchesScope = scope === "all" || isGlobal && scope === "global" || !isGlobal && scope === "local"; | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc); | ||
} | ||
} | ||
} | ||
notifyTransition(bloc, state, event) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addTransition(bloc, state, event); | ||
} | ||
addBlocChangeObserver(blocClass, callback, scope = "all") { | ||
this.blocChangeObservers.push([blocClass, callback, scope]); | ||
} | ||
addBlocValueChangeObserver(blocClass, callback, scope = "all") { | ||
this.blocValueChangeObservers.push([blocClass, callback, scope]); | ||
} | ||
addLocalBloc(item) { | ||
this.providerList.push(item); | ||
item.bloc.consumer = this; | ||
item.bloc.registerListeners.forEach((fn) => fn(this, item.bloc)); | ||
item.bloc.meta.scope = "local"; | ||
this.observer.addBlocAdded(item.bloc); | ||
} | ||
removeLocalBloc(id, bloc) { | ||
const item = this.providerList.find((i) => i.id === id && i.bloc === bloc); | ||
if (item) { | ||
item.bloc.complete(); | ||
item.bloc.removeListeners.forEach((fn) => fn()); | ||
this.observer.addBlocRemoved(item.bloc); | ||
this.providerList = this.providerList.filter((i) => i !== item); | ||
} | ||
} | ||
addBlocMock(bloc) { | ||
if (this.mocksEnabled) { | ||
this.mockBlocs = [bloc, ...this.mockBlocs]; | ||
} | ||
} | ||
resetMocks() { | ||
this.mockBlocs = []; | ||
} | ||
getGlobalBloc(blocClass) { | ||
if (this.mocksEnabled) { | ||
const mockedBloc = this.mockBlocs.find((c) => c instanceof blocClass); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return this.blocListGlobal.find((c) => c instanceof blocClass); | ||
} | ||
getLocalBlocForProvider(id, blocClass) { | ||
for (const providerItem of this.providerList) { | ||
if (providerItem.id === id) { | ||
if (providerItem.bloc instanceof blocClass) { | ||
return providerItem.bloc; | ||
BlocConsumer.prototype.notifyChange = function (bloc, state) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
let parent = providerItem.parent; | ||
while (parent) { | ||
const parentItem = this.providerList.find((i) => i.id === parent); | ||
if (parentItem?.bloc instanceof blocClass) { | ||
return parentItem.bloc; | ||
} | ||
parent = parentItem?.parent; | ||
this.observer.addChange(bloc, state); | ||
for (var _i = 0, _a = this.blocChangeObservers; _i < _a.length; _i++) { | ||
var _b = _a[_i], blocClass = _b[0], callback = _b[1], scope = _b[2]; | ||
var isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
var matchesScope = scope === "all" || | ||
(isGlobal && scope === "global") || | ||
(!isGlobal && scope === "local"); | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc, { | ||
nextState: state, | ||
currentState: bloc.state | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
return void 0; | ||
} | ||
getGlobalBlocInstance(global, blocClass) { | ||
if (this.mocksEnabled) { | ||
const mockedBloc = this.mockBlocs.find((c) => c instanceof blocClass); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return global.find((c) => c instanceof blocClass); | ||
} | ||
} | ||
}; | ||
BlocConsumer.prototype.notifyValueChange = function (bloc) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
for (var _i = 0, _a = this.blocValueChangeObservers; _i < _a.length; _i++) { | ||
var _b = _a[_i], blocClass = _b[0], callback = _b[1], scope = _b[2]; | ||
var isGlobal = this.blocListGlobal.indexOf(bloc) !== -1; | ||
var matchesScope = scope === "all" || | ||
(isGlobal && scope === "global") || | ||
(!isGlobal && scope === "local"); | ||
if (matchesScope && bloc instanceof blocClass) { | ||
callback(bloc); | ||
} | ||
} | ||
}; | ||
BlocConsumer.prototype.notifyTransition = function (bloc, state, event) { | ||
if (bloc.isClosed) { | ||
return; | ||
} | ||
this.observer.addTransition(bloc, state, event); | ||
}; | ||
BlocConsumer.prototype.addBlocChangeObserver = function (blocClass, callback, scope) { | ||
if (scope === void 0) { scope = "all"; } | ||
this.blocChangeObservers.push([blocClass, callback, scope]); | ||
}; | ||
BlocConsumer.prototype.addBlocValueChangeObserver = function (blocClass, callback, scope) { | ||
if (scope === void 0) { scope = "all"; } | ||
this.blocValueChangeObservers.push([blocClass, callback, scope]); | ||
}; | ||
BlocConsumer.prototype.addLocalBloc = function (item) { | ||
var _this = this; | ||
this.providerList.push(item); | ||
item.bloc.consumer = this; | ||
item.bloc.registerListeners.forEach(function (fn) { return fn(_this, item.bloc); }); | ||
item.bloc.meta.scope = 'local'; | ||
this.observer.addBlocAdded(item.bloc); | ||
}; | ||
BlocConsumer.prototype.removeLocalBloc = function (id, bloc) { | ||
var item = this.providerList.find(function (i) { return i.id === id && i.bloc === bloc; }); | ||
if (item) { | ||
item.bloc.complete(); | ||
item.bloc.removeListeners.forEach(function (fn) { return fn(); }); | ||
this.observer.addBlocRemoved(item.bloc); | ||
this.providerList = this.providerList.filter(function (i) { return i !== item; }); | ||
} | ||
}; | ||
BlocConsumer.prototype.addBlocMock = function (bloc) { | ||
if (this.mocksEnabled) { | ||
this.mockBlocs = tslib.__spreadArray([bloc], this.mockBlocs, true); | ||
} | ||
}; | ||
BlocConsumer.prototype.resetMocks = function () { | ||
this.mockBlocs = []; | ||
}; | ||
BlocConsumer.prototype.getGlobalBloc = function (blocClass) { | ||
if (this.mocksEnabled) { | ||
var mockedBloc = this.mockBlocs.find(function (c) { return c instanceof blocClass; }); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return this.blocListGlobal.find(function (c) { return c instanceof blocClass; }); | ||
}; | ||
BlocConsumer.prototype.getLocalBlocForProvider = function (id, blocClass) { | ||
var _loop_2 = function (providerItem) { | ||
if (providerItem.id === id) { | ||
if (providerItem.bloc instanceof blocClass) { | ||
return { value: providerItem.bloc }; | ||
} | ||
var parent_1 = providerItem.parent; | ||
while (parent_1) { | ||
var parentItem = this_2.providerList.find(function (i) { return i.id === parent_1; }); | ||
if ((parentItem === null || parentItem === void 0 ? void 0 : parentItem.bloc) instanceof blocClass) { | ||
return { value: parentItem.bloc }; | ||
} | ||
parent_1 = parentItem === null || parentItem === void 0 ? void 0 : parentItem.parent; | ||
} | ||
} | ||
}; | ||
var this_2 = this; | ||
for (var _i = 0, _a = this.providerList; _i < _a.length; _i++) { | ||
var providerItem = _a[_i]; | ||
var state_1 = _loop_2(providerItem); | ||
if (typeof state_1 === "object") | ||
return state_1.value; | ||
} | ||
return undefined; | ||
}; | ||
BlocConsumer.prototype.getGlobalBlocInstance = function (global, blocClass) { | ||
if (this.mocksEnabled) { | ||
var mockedBloc = this.mockBlocs.find(function (c) { return c instanceof blocClass; }); | ||
if (mockedBloc) { | ||
return mockedBloc; | ||
} | ||
} | ||
return global.find(function (c) { return c instanceof blocClass; }); | ||
}; | ||
return BlocConsumer; | ||
}()); | ||
const defaultBlocHookOptions = { | ||
subscribe: true | ||
var defaultBlocHookOptions = { | ||
subscribe: true | ||
}; | ||
class BlocRuntimeError { | ||
error; | ||
constructor(message) { | ||
this.error = new Error(message); | ||
} | ||
} | ||
class NoValue { | ||
} | ||
class BlocReact extends BlocConsumer { | ||
providerCount = 0; | ||
_blocsGlobal; | ||
_contextLocalProviderKey = React__default["default"].createContext("none"); | ||
constructor(blocs, options) { | ||
super(blocs, options); | ||
this._blocsGlobal = blocs; | ||
this.BlocProvider = this.BlocProvider.bind(this); | ||
this.BlocBuilder = this.BlocBuilder.bind(this); | ||
} | ||
useBloc = (blocClass, options = {}) => { | ||
const mergedOptions = { | ||
...defaultBlocHookOptions, | ||
...options | ||
}; | ||
let blocInstance = React.useMemo(() => options.create ? options.create() : void 0, []); | ||
if (!blocInstance) { | ||
const localProviderKey = React.useContext(this._contextLocalProviderKey); | ||
const localBlocInstance = React.useMemo(() => this.getLocalBlocForProvider(localProviderKey, blocClass), []); | ||
blocInstance = React.useMemo(() => localBlocInstance || this.getGlobalBlocInstance(this._blocsGlobal, blocClass), []); | ||
var BlocRuntimeError = /** @class */ (function () { | ||
function BlocRuntimeError(message) { | ||
this.error = new Error(message); | ||
} | ||
const { subscribe, shouldUpdate = true } = mergedOptions; | ||
if (!blocInstance) { | ||
const name = blocClass.prototype.constructor.name; | ||
const error = new BlocRuntimeError(`"${name}" | ||
no bloc with this name was found in the global context. | ||
# Solutions: | ||
1. Wrap your code in a BlocProvider. | ||
2. Add "${name}" to the "BlocReact" constructor: | ||
const state = new BlocReact( | ||
[ | ||
... | ||
new ${name}(), | ||
] | ||
) | ||
`); | ||
console.error(error.error); | ||
return [ | ||
NoValue, | ||
{}, | ||
{ | ||
error, | ||
complete: true | ||
} | ||
]; | ||
return BlocRuntimeError; | ||
}()); | ||
var NoValue = /** @class */ (function () { | ||
function NoValue() { | ||
} | ||
const [data, setData] = React.useState(blocInstance.state); | ||
const updateData = React.useCallback((nextState) => { | ||
if (shouldUpdate === true || shouldUpdate({ nextState, currentState: data })) { | ||
setData(nextState); | ||
} | ||
}, []); | ||
React.useEffect(() => { | ||
if (subscribe) { | ||
const subscription = blocInstance?.subscribe({ | ||
next: updateData | ||
}); | ||
return () => { | ||
subscription?.unsubscribe(); | ||
return NoValue; | ||
}()); | ||
var BlocReact = /** @class */ (function (_super) { | ||
tslib.__extends(BlocReact, _super); | ||
function BlocReact(blocs, options) { | ||
var _this = _super.call(this, blocs, options) || this; | ||
_this.providerCount = 0; | ||
_this._contextLocalProviderKey = React__default["default"].createContext('none'); | ||
_this.useBloc = function (blocClass, options) { | ||
if (options === void 0) { options = {}; } | ||
var mergedOptions = tslib.__assign(tslib.__assign({}, defaultBlocHookOptions), options); | ||
var blocInstance = React.useMemo(function () { return options.create ? options.create() : undefined; }, []); | ||
if (!blocInstance) { | ||
var localProviderKey_1 = React.useContext(_this._contextLocalProviderKey); | ||
var localBlocInstance_1 = React.useMemo(function () { return _this.getLocalBlocForProvider(localProviderKey_1, blocClass); }, []); | ||
blocInstance = React.useMemo(function () { return localBlocInstance_1 || _this.getGlobalBlocInstance(_this._blocsGlobal, blocClass); }, []); | ||
} | ||
var subscribe = mergedOptions.subscribe, _a = mergedOptions.shouldUpdate, shouldUpdate = _a === void 0 ? true : _a; | ||
if (!blocInstance) { | ||
var name_1 = blocClass.prototype.constructor.name; | ||
var error = new BlocRuntimeError("\"".concat(name_1, "\" \n no bloc with this name was found in the global context.\n \n # Solutions:\n \n 1. Wrap your code in a BlocProvider.\n \n 2. Add \"").concat(name_1, "\" to the \"BlocReact\" constructor:\n const state = new BlocReact(\n [\n ...\n new ").concat(name_1, "(),\n ]\n )\n ")); | ||
console.error(error.error); | ||
return [ | ||
NoValue, | ||
{}, | ||
{ | ||
error: error, | ||
complete: true | ||
} | ||
]; | ||
} | ||
var _b = React.useState(blocInstance.state), data = _b[0], setData = _b[1]; | ||
var updateData = React.useCallback(function (nextState) { | ||
if (shouldUpdate === true || shouldUpdate({ nextState: nextState, currentState: data })) { | ||
setData(nextState); | ||
} | ||
}, []); | ||
React.useEffect(function () { | ||
if (subscribe) { | ||
var subscription_1 = blocInstance === null || blocInstance === void 0 ? void 0 : blocInstance.subscribe({ | ||
next: updateData | ||
}); | ||
return function () { | ||
subscription_1 === null || subscription_1 === void 0 ? void 0 : subscription_1.unsubscribe(); | ||
}; | ||
} | ||
}, []); | ||
return [ | ||
data, | ||
blocInstance | ||
]; | ||
}; | ||
} | ||
}, []); | ||
return [ | ||
data, | ||
blocInstance | ||
]; | ||
}; | ||
BlocBuilder(props) { | ||
const hook = this.useBloc(props.blocClass, { | ||
shouldUpdate: props.shouldUpdate | ||
}); | ||
return props.builder(hook); | ||
} | ||
BlocProvider(props) { | ||
const id = React.useMemo(() => createId(), []); | ||
const localProviderKey = React.useContext(this._contextLocalProviderKey); | ||
const bloc = React.useMemo(() => { | ||
const newBloc = typeof props.bloc === "function" ? props.bloc(id) : props.bloc; | ||
if (newBloc) { | ||
this.addLocalBloc({ | ||
bloc: newBloc, | ||
id, | ||
parent: localProviderKey | ||
_this.withBlocProvider = function (bloc) { return function (Component) { | ||
var BlocProvider = _this.BlocProvider; | ||
return /** @class */ (function (_super) { | ||
tslib.__extends(WithBlocProvider, _super); | ||
function WithBlocProvider() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
} | ||
WithBlocProvider.prototype.render = function () { | ||
return (React__default["default"].createElement(BlocProvider, { bloc: bloc }, | ||
React__default["default"].createElement(Component, tslib.__assign({}, this.props)))); | ||
}; | ||
return WithBlocProvider; | ||
}(React__default["default"].Component)); | ||
}; }; | ||
_this._blocsGlobal = blocs; | ||
_this.BlocProvider = _this.BlocProvider.bind(_this); | ||
_this.BlocBuilder = _this.BlocBuilder.bind(_this); | ||
return _this; | ||
} | ||
// Components | ||
BlocReact.prototype.BlocBuilder = function (props) { | ||
var hook = this.useBloc(props.blocClass, { | ||
shouldUpdate: props.shouldUpdate | ||
}); | ||
} else { | ||
console.error(`BLoC is undefined`); | ||
} | ||
return newBloc; | ||
}, []); | ||
const context = React.useMemo(() => { | ||
return React__default["default"].createContext(bloc); | ||
}, [bloc]); | ||
React.useEffect(() => { | ||
return () => { | ||
this.removeLocalBloc(id, bloc); | ||
}; | ||
}, []); | ||
return /* @__PURE__ */ React__default["default"].createElement(this._contextLocalProviderKey.Provider, { | ||
value: id | ||
}, /* @__PURE__ */ React__default["default"].createElement(context.Provider, { | ||
value: bloc | ||
}, props.children)); | ||
} | ||
withBlocProvider = (bloc) => (Component) => { | ||
const { BlocProvider } = this; | ||
return class WithBlocProvider extends React__default["default"].Component { | ||
render() { | ||
return /* @__PURE__ */ React__default["default"].createElement(BlocProvider, { | ||
bloc | ||
}, /* @__PURE__ */ React__default["default"].createElement(Component, { | ||
...this.props | ||
})); | ||
} | ||
return props.builder(hook); | ||
}; | ||
}; | ||
} | ||
BlocReact.prototype.BlocProvider = function (props) { | ||
var _this = this; | ||
var id = React.useMemo(function () { return createId(); }, []); | ||
var localProviderKey = React.useContext(this._contextLocalProviderKey); | ||
var bloc = React.useMemo(function () { | ||
var newBloc = typeof props.bloc === "function" ? props.bloc(id) : props.bloc; | ||
if (newBloc) { | ||
_this.addLocalBloc({ | ||
bloc: newBloc, | ||
id: id, | ||
parent: localProviderKey | ||
}); | ||
} | ||
else { | ||
console.error("BLoC is undefined"); | ||
} | ||
return newBloc; | ||
}, []); | ||
var context = React.useMemo(function () { | ||
return React__default["default"].createContext(bloc); | ||
}, [bloc]); | ||
React.useEffect(function () { | ||
return function () { | ||
_this.removeLocalBloc(id, bloc); | ||
}; | ||
}, []); | ||
return (React__default["default"].createElement(this._contextLocalProviderKey.Provider, { value: id }, | ||
React__default["default"].createElement(context.Provider, { value: bloc }, props.children))); | ||
}; | ||
return BlocReact; | ||
}(BlocConsumer)); | ||
@@ -507,0 +553,0 @@ exports.Bloc = Bloc; |
{ | ||
"name": "bloc-react", | ||
"version": "0.1.27", | ||
"version": "0.1.28-2", | ||
"license": "MIT", | ||
@@ -9,6 +9,10 @@ "main": "dist/bloc-react.js", | ||
"keywords": [ | ||
"react", | ||
"typescript", | ||
"rxjs", | ||
"state-management", | ||
"reactjs", | ||
"observer-pattern", | ||
"bloc", | ||
"state", | ||
"react", | ||
"reactive" | ||
"bloc-pattern" | ||
], | ||
@@ -26,6 +30,9 @@ "scripts": { | ||
}, | ||
"dependencies": {}, | ||
"dependencies": { | ||
"@rollup/plugin-commonjs": "^21.0.1", | ||
"rollup-plugin-typescript2": "^0.31.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.16.7", | ||
"@babel/preset-env": "^7.16.8", | ||
"@babel/core": "^7.16.12", | ||
"@babel/preset-env": "^7.16.11", | ||
"@babel/preset-react": "^7.16.7", | ||
@@ -40,3 +47,3 @@ "@babel/preset-typescript": "^7.16.7", | ||
"@testing-library/react-hooks": "^7.0.2", | ||
"@types/chrome": "^0.0.176", | ||
"@types/chrome": "^0.0.177", | ||
"@types/enzyme": "^3.10.11", | ||
@@ -47,5 +54,5 @@ "@types/jest": "^27.4.0", | ||
"@types/react-dom": "^17.0.11", | ||
"@types/react-router-dom": "^5.3.2", | ||
"@typescript-eslint/eslint-plugin": "^5.10.0", | ||
"@typescript-eslint/parser": "^5.10.0", | ||
"@types/react-router-dom": "^5.3.3", | ||
"@typescript-eslint/eslint-plugin": "^5.10.1", | ||
"@typescript-eslint/parser": "^5.10.1", | ||
"@vitejs/plugin-react-refresh": "^1.3.6", | ||
@@ -55,4 +62,4 @@ "@wojtekmaj/enzyme-adapter-react-17": "^0.6.6", | ||
"enzyme": "^3.11.0", | ||
"esbuild": "^0.14.11", | ||
"eslint": "^8.7.0", | ||
"esbuild": "^0.14.14", | ||
"eslint": "^8.8.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
@@ -73,7 +80,6 @@ "eslint-config-standard": "^16.0.3", | ||
"react-router-dom": "^6.2.1", | ||
"rollup": "^2.64.0", | ||
"rollup": "^2.66.1", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"rollup-plugin-commonjs": "^10.1.0", | ||
"rollup-plugin-dts": "^4.1.0", | ||
"rollup-plugin-esbuild": "^4.8.2", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
@@ -83,4 +89,4 @@ "rollup-plugin-peer-deps-external": "^2.2.4", | ||
"ts-jest": "^27.1.3", | ||
"typescript": "^4.5.4", | ||
"vite": "^2.7.12" | ||
"typescript": "^4.5.5", | ||
"vite": "^2.7.13" | ||
}, | ||
@@ -87,0 +93,0 @@ "jest": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
51
4030
164930
2
+ Added@rollup/plugin-commonjs@21.1.0(transitive)
+ Added@rollup/pluginutils@3.1.04.2.1(transitive)
+ Added@types/estree@0.0.39(transitive)
+ Added@types/node@22.10.10(transitive)
+ Added@yarn-tool/resolve-package@1.0.47(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcommondir@1.0.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedestree-walker@1.0.12.0.2(transitive)
+ Addedfind-cache-dir@3.3.2(transitive)
+ Addedfind-up@4.1.05.0.0(transitive)
+ Addedfs-extra@10.1.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedfsevents@2.3.3(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-core-module@2.16.1(transitive)
+ Addedis-reference@1.2.1(transitive)
+ Addedjsonfile@6.1.0(transitive)
+ Addedlocate-path@5.0.06.0.0(transitive)
+ Addedmagic-string@0.25.9(transitive)
+ Addedmake-dir@3.1.0(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedp-limit@2.3.03.1.0(transitive)
+ Addedp-locate@4.1.05.0.0(transitive)
+ Addedp-try@2.2.0(transitive)
+ Addedpath-exists@4.0.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-is-network-drive@1.0.21(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedpath-strip-sep@1.0.18(transitive)
+ Addedpicomatch@2.3.1(transitive)
+ Addedpkg-dir@4.2.05.0.0(transitive)
+ Addedresolve@1.22.10(transitive)
+ Addedrollup@2.79.2(transitive)
+ Addedrollup-plugin-typescript2@0.31.2(transitive)
+ Addedsemver@6.3.1(transitive)
+ Addedsourcemap-codec@1.4.8(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
+ Addedtslib@2.8.1(transitive)
+ Addedtypescript@5.7.3(transitive)
+ Addedundici-types@6.20.0(transitive)
+ Addeduniversalify@2.0.1(transitive)
+ Addedupath2@3.1.20(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedyocto-queue@0.1.0(transitive)