fluidstate
Version:
Library for fine-grained reactivity state management
236 lines (235 loc) • 8.87 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createReactiveSet = void 0;
var _reactiveNames = require("../extras/reactive-names");
var _reactivePlugin = require("../extras/reactive-plugin");
var _reactiveAtom = require("../primitives/reactive-atom");
var _reactiveChildren = require("./reactive-children");
var _reactiveProxy = require("./reactive-proxy");
var _reactivePluginSet = require("../extras/reactive-plugin-set");
const createReactiveSet = (inertSet, reactiveOptions, nameOptions) => {
const atomName = (0, _reactiveNames.createAtomNameFromOptions)(nameOptions);
const proxy = new Proxy(inertSet, new ReactiveSetProxyHandler(new ReactiveSetOverrides(atomName, inertSet, {
items: (0, _reactiveAtom.createAtom)((0, _reactiveNames.createSetAtomName)(atomName))
}, () => proxy, reactiveOptions)));
return proxy;
};
exports.createReactiveSet = createReactiveSet;
class ReactiveSetProxyHandler {
constructor(setOverrides) {
this.setOverrides = setOverrides;
}
get(inertSet, property, receiver) {
const ownPropertyDescriptor = Reflect.getOwnPropertyDescriptor(inertSet, property);
const isInherited = Reflect.has(inertSet, property) && !ownPropertyDescriptor;
if (isInherited && property in this.setOverrides) {
return this.setOverrides[property];
}
return Reflect.get(inertSet, property, receiver);
}
}
class ReactiveSetOverrides {
#atomName;
#inertSet;
#reactive;
#getProxy;
#options;
constructor(atomName, inertSet, reactive, getProxy, reactiveOptions) {
this.#atomName = atomName;
this.#inertSet = inertSet;
this.#reactive = reactive;
this.#getProxy = getProxy;
this.#options = {
reactiveOptions
};
}
[Symbol.iterator] = () => {
return this.#getSetValues();
};
entries = () => {
return this.#entries();
};
keys = () => {
return this.#getSetValues();
};
values = () => {
return this.#getSetValues();
};
get [Symbol.toStringTag]() {
return Set.prototype[Symbol.toStringTag];
}
get size() {
this.#reactive.items.reportObserved();
return this.#inertSet.size;
}
has = value => {
const result = this.#hasStoredValue(this.#getStored(value));
this.#reactive.items.reportObserved();
return result;
};
add = value => {
const valueToStore = this.#getStored(value);
const itemAlreadyExists = this.#hasStoredValue(valueToStore);
const changes = !this.#hasPlugins() || itemAlreadyExists ? null : (0, _reactivePluginSet.getSetAddChanges)(this.#getProxy(), valueToStore);
if (changes) {
(0, _reactivePlugin.beforeChange)(changes, this.#options.reactiveOptions?.plugins);
}
Set.prototype.add.call(this.#inertSet, valueToStore);
if (!itemAlreadyExists) {
this.#reactive.items.reportChanged();
}
if (changes) {
(0, _reactivePlugin.afterChange)(changes, this.#options.reactiveOptions?.plugins);
}
return this;
};
delete = value => {
const valueToDelete = this.#getStored(value);
const itemAlreadyExists = this.#hasStoredValue(valueToDelete);
const changes = !this.#hasPlugins() || !itemAlreadyExists ? null : (0, _reactivePluginSet.getSetDeleteChanges)(this.#getProxy(), valueToDelete);
if (changes) {
(0, _reactivePlugin.beforeChange)(changes, this.#options.reactiveOptions?.plugins);
}
const resultStored = Set.prototype.delete.call(this.#inertSet, valueToDelete);
const reactive = (0, _reactiveProxy.getReactive)(valueToDelete);
const resultReactive = !!(reactive && Set.prototype.delete.call(this.#inertSet, reactive));
const result = resultStored || resultReactive;
if (result) {
this.#reactive.items.reportChanged();
}
if (changes) {
(0, _reactivePlugin.afterChange)(changes, this.#options.reactiveOptions?.plugins);
}
return result;
};
clear = () => {
const isAlreadyEmpty = this.#inertSet.size === 0;
const changes = !this.#hasPlugins() || isAlreadyEmpty ? null : (0, _reactivePluginSet.getSetClearChanges)(this.#getProxy(), Array.from(this.#inertSet.values()));
if (changes) {
(0, _reactivePlugin.beforeChange)(changes, this.#options.reactiveOptions?.plugins);
}
Set.prototype.clear.call(this.#inertSet);
if (!isAlreadyEmpty) {
this.#reactive.items.reportChanged();
}
if (changes) {
(0, _reactivePlugin.afterChange)(changes, this.#options.reactiveOptions?.plugins);
}
};
forEach = (callbackfn, thisArg) => {
try {
const result = Set.prototype.forEach.call(this.#inertSet, (_value, key, set) => {
const keyValue = (0, _reactiveChildren.getChild)(this.#options, key, () => (0, _reactiveProxy.createProxy)(key, (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetValueAtomName
}));
return callbackfn.call(this, keyValue, keyValue, set);
}, thisArg);
return result;
} finally {
this.#reactive.items.reportObserved();
}
};
union = other => {
try {
return (0, _reactiveProxy.createProxy)(this.#inertSet.union(other), (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetTransformedAtomName
});
} finally {
this.#reactive.items.reportObserved();
}
};
intersection = other => {
try {
return (0, _reactiveProxy.createProxy)(this.#inertSet.intersection(other), (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetTransformedAtomName
});
} finally {
this.#reactive.items.reportObserved();
}
};
difference = other => {
try {
return (0, _reactiveProxy.createProxy)(this.#inertSet.difference(other), (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetTransformedAtomName
});
} finally {
this.#reactive.items.reportObserved();
}
};
symmetricDifference = other => {
try {
return (0, _reactiveProxy.createProxy)(this.#inertSet.symmetricDifference(other), (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetTransformedAtomName
});
} finally {
this.#reactive.items.reportObserved();
}
};
isSubsetOf = other => {
(0, _reactiveProxy.getReactive)(other)?.size;
try {
return this.#inertSet.isSubsetOf((0, _reactiveProxy.ensureInert)(other));
} finally {
this.#reactive.items.reportObserved();
}
};
isSupersetOf = other => {
(0, _reactiveProxy.getReactive)(other)?.size;
try {
return this.#inertSet.isSupersetOf((0, _reactiveProxy.ensureInert)(other));
} finally {
this.#reactive.items.reportObserved();
}
};
isDisjointFrom = other => {
(0, _reactiveProxy.getReactive)(other)?.size;
try {
return this.#inertSet.isDisjointFrom((0, _reactiveProxy.ensureInert)(other));
} finally {
this.#reactive.items.reportObserved();
}
};
*#entries() {
const result = Set.prototype.entries.call(this.#inertSet);
this.#reactive.items.reportObserved();
for (const [key] of result) {
const keyValue = (0, _reactiveChildren.getChild)(this.#options, key, () => (0, _reactiveProxy.createProxy)(key, (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetValueAtomName
}));
yield [keyValue, keyValue];
}
}
*#getSetValues() {
const result = Set.prototype.values.call(this.#inertSet);
this.#reactive.items.reportObserved();
for (const item of result) {
yield (0, _reactiveChildren.getChild)(this.#options, item, () => (0, _reactiveProxy.createProxy)(item, (0, _reactiveChildren.getChildOptions)(this.#options), {
parentAtomName: this.#atomName,
createAtomName: _reactiveNames.createSetValueAtomName
}));
}
}
#getStored(value) {
return this.#options.reactiveOptions?.deep === false ? value : (0, _reactiveProxy.ensureInert)(value);
}
#hasStoredValue(storedValue) {
const hasStoredValueDirectly = Set.prototype.has.call(this.#inertSet, storedValue);
if (hasStoredValueDirectly || this.#options.reactiveOptions?.deep === false) {
return hasStoredValueDirectly;
}
const reactive = (0, _reactiveProxy.getReactive)(storedValue);
return reactive && Set.prototype.has.call(this.#inertSet, reactive) || false;
}
#hasPlugins() {
return (this.#options.reactiveOptions?.plugins?.length ?? 0) > 0;
}
}
//# sourceMappingURL=reactive-set.js.map