@shared-state/core
Version:
The core package of `@shared-state`
102 lines (100 loc) • 3.41 kB
JavaScript
function createSharedState(initialValueOrGetter) {
var value;
var subscriberSet = new Set();
var get = function get() {
if (value === undefined) {
value = typeof initialValueOrGetter === "function" ? initialValueOrGetter() : initialValueOrGetter;
}
return value;
};
var set = function set(valueOrUpdater) {
var previousValue = get();
var nextValue = typeof valueOrUpdater === "function" ? valueOrUpdater(previousValue) : valueOrUpdater;
if (Object.is(nextValue, previousValue)) return;
value = nextValue;
subscriberSet.forEach(function (subscriber) {
return subscriber(nextValue, previousValue);
});
};
var subscribe = function subscribe(handler) {
return subscriberSet.add(handler);
};
var unsubscribe = function unsubscribe(handler) {
return subscriberSet["delete"](handler);
};
return {
get: get,
set: set,
subscribe: subscribe,
unsubscribe: unsubscribe
};
}
function createDerivedSharedState(getter, setter) {
var value;
var dependencySet;
var subscriberSet = new Set();
var get = function get() {
return subscriberSet.size > 0 ? value : getter(function (sharedState) {
return sharedState.get();
});
};
var set = function set(valueOrUpdater) {
if (!setter) return;
var previousValue = get();
var nextValue = typeof valueOrUpdater === "function" ? valueOrUpdater(previousValue) : valueOrUpdater;
if (Object.is(nextValue, previousValue)) return;
setter(nextValue);
};
var updateValueAndDependencySet = function updateValueAndDependencySet() {
var previousValue = get();
var previousDependencySet = dependencySet;
var nextDependencySet = new Set();
var nextValue = getter(function (sharedState) {
nextDependencySet.add(sharedState);
return sharedState.get();
});
if (previousDependencySet !== undefined) {
nextDependencySet.forEach(function (sharedState) {
return !previousDependencySet.has(sharedState) && sharedState.subscribe(updateValueAndDependencySet);
});
previousDependencySet.forEach(function (sharedState) {
return !nextDependencySet.has(sharedState) && sharedState.unsubscribe(updateValueAndDependencySet);
});
}
dependencySet = nextDependencySet;
if (Object.is(nextValue, previousValue)) return;
value = nextValue;
subscriberSet.forEach(function (subscriber) {
return subscriber(nextValue, previousValue);
});
};
return {
get: get,
set: set,
subscribe: function subscribe(handler) {
if (subscriberSet.size === 0) {
var nextDependencySet = new Set();
value = getter(function (sharedState) {
sharedState.subscribe(updateValueAndDependencySet);
nextDependencySet.add(sharedState);
return sharedState.get();
});
dependencySet = nextDependencySet;
}
subscriberSet.add(handler);
},
unsubscribe: function unsubscribe(handler) {
subscriberSet["delete"](handler);
if (subscriberSet.size === 0) {
if (dependencySet !== undefined) {
dependencySet.forEach(function (sharedState) {
return sharedState.unsubscribe(updateValueAndDependencySet);
});
dependencySet = undefined;
}
value = undefined;
}
}
};
}
export { createDerivedSharedState, createSharedState };