@coder/backstage-plugin-coder
Version:
Create and manage Coder workspaces from Backstage
79 lines (77 loc) • 2.69 kB
JavaScript
function areSameByReference(v1, v2) {
return Object.is(v1, v2) || v1 === 0 && v2 === 0;
}
function defaultDidSnapshotsChange(oldSnapshot, newSnapshot) {
if (areSameByReference(oldSnapshot, newSnapshot)) {
return false;
}
const oldIsPrimitive = typeof oldSnapshot !== "object" || oldSnapshot === null;
const newIsPrimitive = typeof newSnapshot !== "object" || newSnapshot === null;
if (oldIsPrimitive && newIsPrimitive) {
const numbersAreWithinTolerance = typeof oldSnapshot === "number" && typeof newSnapshot === "number" && Math.abs(oldSnapshot - newSnapshot) < 5e-5;
if (numbersAreWithinTolerance) {
return false;
}
return oldSnapshot !== newSnapshot;
}
const changedFromObjectToPrimitive = !oldIsPrimitive && newIsPrimitive;
const changedFromPrimitiveToObject = oldIsPrimitive && !newIsPrimitive;
if (changedFromObjectToPrimitive || changedFromPrimitiveToObject) {
return true;
}
if (Array.isArray(oldSnapshot) && Array.isArray(newSnapshot)) {
const sameByShallowComparison = oldSnapshot.length === newSnapshot.length && oldSnapshot.every(
(element, index) => areSameByReference(element, newSnapshot[index])
);
return !sameByShallowComparison;
}
const oldInnerValues = Object.values(oldSnapshot);
const newInnerValues = Object.values(newSnapshot);
if (oldInnerValues.length !== newInnerValues.length) {
return true;
}
for (const [index, value] of oldInnerValues.entries()) {
if (value !== newInnerValues[index]) {
return true;
}
}
return false;
}
class StateSnapshotManager {
subscriptions;
didSnapshotsChange;
activeSnapshot;
constructor(options) {
const { initialSnapshot, didSnapshotsChange } = options;
this.subscriptions = /* @__PURE__ */ new Set();
this.activeSnapshot = initialSnapshot;
this.didSnapshotsChange = didSnapshotsChange ?? defaultDidSnapshotsChange;
}
notifySubscriptions() {
const snapshotBinding = this.activeSnapshot;
this.subscriptions.forEach((cb) => cb(snapshotBinding));
}
unsubscribe = (callback) => {
this.subscriptions.delete(callback);
};
subscribe = (callback) => {
this.subscriptions.add(callback);
return () => this.unsubscribe(callback);
};
getSnapshot = () => {
return this.activeSnapshot;
};
updateSnapshot = (newSnapshot) => {
const snapshotsChanged = this.didSnapshotsChange(
this.activeSnapshot,
newSnapshot
);
if (!snapshotsChanged) {
return;
}
this.activeSnapshot = newSnapshot;
this.notifySubscriptions();
};
}
export { StateSnapshotManager, defaultDidSnapshotsChange };
//# sourceMappingURL=StateSnapshotManager.esm.js.map