@modern-js-reduck/react
Version:
The meta-framework suite designed from scratch for frontend-focused modern web development.
93 lines (92 loc) • 2.47 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createBatchManager", {
enumerable: true,
get: () => createBatchManager
});
const _store = require("@modern-js-reduck/store");
const _reactdom = require("react-dom");
const combineSubscribe = (store, subscribes) => {
let changed = false;
const handlers = /* @__PURE__ */ new Set();
return (handler) => {
handlers.add(handler);
const disposer = [];
subscribes.forEach((subscribe) => {
disposer.push(subscribe(() => {
changed = true;
}));
});
const unsubscribeStore = store.subscribe(() => {
if (changed) {
handlers.forEach((h) => h());
}
changed = false;
});
return () => {
unsubscribeStore();
disposer.forEach((dispose) => dispose());
};
};
};
const createBatchManager = (store) => {
const usingModelsMap = /* @__PURE__ */ new Map();
let unsubscribe;
const updateList = [];
const setupSubscribe = () => {
if (typeof unsubscribe === "function") {
unsubscribe();
}
const modelSet = /* @__PURE__ */ new Set();
for (const [model, count] of usingModelsMap) {
if (count !== 0) {
modelSet.add(model);
}
}
const subscribe = combineSubscribe(store, [
...modelSet
].map((m) => store.use(m)[2]));
unsubscribe = subscribe(() => {
(0, _reactdom.unstable_batchedUpdates)(() => {
let update = updateList.shift();
while (update) {
update();
update = updateList.shift();
}
});
});
};
const changeModels = (action, ...models) => {
models.forEach((model) => {
if (!_store.utils.isModel(model)) {
return;
}
let usingCount = usingModelsMap.get(model);
if (action === "add") {
usingModelsMap.set(model, (usingCount || 0) + 1);
} else if (action === "remove") {
if (usingCount) {
usingCount -= 1;
if (usingCount === 0) {
usingModelsMap.delete(model);
} else {
usingModelsMap.set(model, usingCount);
}
}
}
});
setupSubscribe();
};
const addModels = (...args) => changeModels("add", ...args);
const removeModels = (...args) => changeModels("remove", ...args);
const pushUpdate = (update) => {
updateList.push(update);
};
return {
addModels,
removeModels,
pushUpdate
};
};