fluidstate
Version:
Library for fine-grained reactivity state management
115 lines (113 loc) • 4.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getArraySetChanges = exports.getArrayDeleteChanges = void 0;
var _reactivePlugin = require("./reactive-plugin");
/**
* Generates a list of change descriptions for an array set operation.
* This function is intended to be called before the actual mutation occurs,
* so `array` reflects the state *before* the change.
*
* @param array The reactive array proxy, reflecting state *before* the change.
* @param inertArr The underlying inert array.
* @param property The property being set (either a numeric index or the string 'length').
* @param previousValue For numeric `property`, the current value at that index. For 'length' `property`, the current length of the array.
* @param nextValue For numeric `property`, the new value to be set at the index. For 'length' `property`, the new length to be set.
* @param currentLength The length of `array` *before* the operation.
* @returns An array of ReactiveChange objects, or null if no reportable changes occurred.
*/
const getArraySetChanges = (array, inertArr, property, previousValue, nextValue, currentLength) => {
const changes = [];
if (property === "length") {
const newLength = Number(nextValue);
if (!Number.isInteger(newLength) || newLength >= 2 ** 32 || newLength < 0) {
return null;
}
if (newLength < currentLength) {
for (let i = currentLength - 1; i >= newLength; i--) {
changes.push({
type: _reactivePlugin.ArrayChangeType.PopValue,
index: i,
previousValue: inertArr[i]
});
}
} else if (newLength > currentLength) {
for (let i = currentLength; i < newLength; i++) {
changes.push({
type: _reactivePlugin.ArrayChangeType.PushValue,
index: i,
nextValue: undefined
});
}
}
} else {
const index = Number(property);
if (!Number.isInteger(index) || index >= 2 ** 32 - 1 || index < 0) {
return null;
}
if (index < currentLength) {
// Standard set within existing bounds
changes.push({
type: _reactivePlugin.ArrayChangeType.SetValue,
index,
previousValue,
nextValue
});
} else {
for (let i = currentLength; i < index; i++) {
changes.push({
type: _reactivePlugin.ArrayChangeType.PushValue,
index: i,
nextValue: undefined
});
}
changes.push({
type: _reactivePlugin.ArrayChangeType.PushValue,
index,
nextValue
});
}
}
if (changes.length === 0) {
return null;
}
return changes.map(arrayChange => ({
type: _reactivePlugin.ReactiveChangeType.Array,
array,
arrayChange
}));
};
/**
* Generates a list of change descriptions for an array delete operation.
* `delete array[index]` makes the property at `index` a "hole", and accessing it yields `undefined`.
* The array length does not change. This is treated as setting the value at `index` to `undefined`.
*
* @param array The reactive array proxy, reflecting state *before* the change.
* @param property The property being set (either a numeric index or the string 'length').
* @param previousValue The value at the `property` index *before* deletion.
* @returns An array of ReactiveChange objects, or null if no reportable changes occurred.
*/
exports.getArraySetChanges = getArraySetChanges;
const getArrayDeleteChanges = (array, property, previousValue) => {
if (property === "length") {
return null;
}
const index = Number(property);
if (!Number.isInteger(index) || index >= 2 ** 32 - 1 || index < 0) {
return null;
}
const arrayChange = {
type: _reactivePlugin.ArrayChangeType.SetValue,
index,
previousValue,
nextValue: undefined
};
return [{
type: _reactivePlugin.ReactiveChangeType.Array,
array,
arrayChange
}];
};
exports.getArrayDeleteChanges = getArrayDeleteChanges;
//# sourceMappingURL=reactive-plugin-array.js.map