vite-plugin-react18-pages
Version:
<p> <a href="https://www.npmjs.com/package/vite-plugin-react-pages" target="_blank" rel="noopener"><img src="https://img.shields.io/npm/v/vite-plugin-react-pages.svg" alt="npm package" /></a> </p>
249 lines • 9.46 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PagesDataKeeper = void 0;
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
const UpdateBuffer_1 = require("./UpdateBuffer");
const PAGE_MODULE_PREFIX = '/@vp-page';
const ensurePageId = (moduleId) => moduleId.startsWith(PAGE_MODULE_PREFIX)
? moduleId.slice(PAGE_MODULE_PREFIX.length)
: moduleId;
const ensureModuleId = (pageId) => pageId.startsWith(PAGE_MODULE_PREFIX) ? pageId : PAGE_MODULE_PREFIX + pageId;
const isPageRelatedModule = (moduleId) => moduleId.startsWith(PAGE_MODULE_PREFIX);
/**
* building upon VirtualModulesManager,
* PagesDataKeeper recognize and handle page modules.
*/
class PagesDataKeeper extends UpdateBuffer_1.PageUpdateBuffer {
constructor(virtualModulesManager) {
super();
this.virtualModulesManager = virtualModulesManager;
/**
* this.pages is a cache of this.virtualModulesManager.getModules
* which is updated in batch (may be outdated for a short time)
*/
this.pages = {};
virtualModulesManager.getModules((modules) => {
Object.entries(modules).forEach(([moduleId, data]) => {
this.setPageData(moduleId, data);
});
virtualModulesManager.addModuleListener((moduleId, data) => {
this.setPageData(moduleId, data);
}, isPageRelatedModule);
}, isPageRelatedModule);
}
/** turn PagesDataInternal to PagesData */
getPages() {
return Object.fromEntries(Object.entries(this.pages).map(([pageId, page]) => [
pageId,
transformOnePageDataInternal(page),
]));
}
getPage(pageId) {
const page = this.pages[pageId];
if (!page)
return null;
return transformOnePageDataInternal(page);
}
/**
* when low-level page virtule modules has changed, update this.pages data
* and notify listeners
*/
setPageData(moduleId, rawData) {
const pageId = ensurePageId(moduleId);
const oldPageData = this.pages[pageId];
const pageData = this.createPageDataFromRaw(rawData);
// Page is deleted
if (!pageData) {
if (oldPageData) {
delete this.pages[pageId];
this.scheduleUpdate({
type: 'delete',
pageId,
});
}
return;
}
// Page is added
if (!oldPageData) {
this.pages[pageId] = pageData;
this.scheduleUpdate({
type: 'add',
pageId,
});
return;
}
// Page is updated
this.pages[pageId] = pageData;
if (!(0, fast_deep_equal_1.default)(pageData.runtimeData, oldPageData.runtimeData)) {
this.scheduleUpdate({
type: 'update',
dataType: 'runtime',
pageId,
});
}
if (!(0, fast_deep_equal_1.default)(pageData.staticData, oldPageData.staticData)) {
this.scheduleUpdate({
type: 'update',
dataType: 'static',
pageId,
});
}
}
createPageDataFromRaw(rawData) {
const pageData = {
runtimeData: {},
staticData: {},
};
const { runtimeData: dataMap, staticData: staticDataMap } = pageData;
rawData.forEach((data) => {
var _a, _b;
if (!data)
return;
const { dataPath, staticData } = data;
if (!dataPath && !staticData)
return;
const key = (_a = data.key) !== null && _a !== void 0 ? _a : 'main';
const priority = (_b = data.priority) !== null && _b !== void 0 ? _b : 1;
if (dataPath) {
if (!dataMap[key] || priority > dataMap[key].priority)
dataMap[key] = { dataPath, priority };
}
if (staticData) {
if (!staticDataMap[key] || priority > staticDataMap[key].priority)
staticDataMap[key] = { staticData, priority };
}
});
if (isEmptyPage(pageData))
return null;
return pageData;
function isEmptyPage(pageData) {
const { runtimeData, staticData } = pageData;
return (Object.keys(runtimeData).length === 0 &&
Object.keys(staticData).length === 0);
}
}
/**
* update page virtule modules according to fs files
*/
addFSWatcher(baseDir, globs, fileHandler) {
this.virtualModulesManager.addFSWatcher(baseDir, globs, async (file, lowerAPI) => {
const pageAPIs = this.createPageAPIs(lowerAPI);
const res = await fileHandler(file, pageAPIs);
if (res) {
pageAPIs.addPageData(res);
}
});
}
createOneTimePageAPIs(updaterAPIs) {
const handlerAPI = {
addModuleData(moduleId, data) {
// if the update has no upstream, use a constant name
updaterAPIs.addModuleData(moduleId, data, 'VP_ANONYMOUS_MODULE');
},
getModuleData: updaterAPIs.getModuleData,
};
return this.createPageAPIs(handlerAPI);
}
/**
* TODO:
* getRuntimeData and getStaticData are very inefficient to implement,
* redesign them in the next verion
*/
createPageAPIs(lowerAPI) {
const getRuntimeData = (pageId) => {
const moduleId = ensureModuleId(pageId);
// don't use pages as data source because this is a cache updated in batch.
// instead, get data by virtualModulesManager._getModuleDataNow
// which is updated immediately after updateing virtule modules
const getDataObject = () => {
// reconstruct the data object, which is inefficient
const rawData = this.virtualModulesManager._getModuleDataNow(moduleId);
const pageData = this.createPageDataFromRaw(rawData);
if (!pageData)
return {};
return pageData.runtimeData;
};
const setData = (key, value) => {
lowerAPI.addModuleData(moduleId, {
key,
dataPath: value,
});
};
const getData = (key) => {
const existValue = getDataObject()[key];
return existValue === null || existValue === void 0 ? void 0 : existValue.dataPath;
};
return createProxy({ getDataObject, setData, getData });
};
const getStaticData = (pageId) => {
const moduleId = ensureModuleId(pageId);
const getDataObject = () => {
const rawData = this.virtualModulesManager._getModuleDataNow(moduleId);
const pageData = this.createPageDataFromRaw(rawData);
if (!pageData)
return {};
return pageData.staticData;
};
const setData = (key, value) => {
lowerAPI.addModuleData(moduleId, {
key,
staticData: value,
});
};
const getData = (key) => {
const existValue = getDataObject()[key];
return existValue === null || existValue === void 0 ? void 0 : existValue.staticData;
};
return createProxy({ getDataObject, setData, getData });
};
const addPageData = (dataPiece) => {
const moduleId = ensureModuleId(dataPiece.pageId);
lowerAPI.addModuleData(moduleId, dataPiece);
};
return {
getRuntimeData,
getStaticData,
addPageData,
};
function createProxy({ getDataObject, setData, getData, }) {
return new Proxy({}, {
...defaultProxyTraps,
set(target, key, value) {
setData(key, value);
return true;
},
get(target, key) {
return getData(key);
},
has(target, key) {
return Reflect.has(getDataObject(), key);
},
ownKeys: function (target) {
return Reflect.ownKeys(getDataObject());
},
});
}
}
}
exports.PagesDataKeeper = PagesDataKeeper;
const defaultProxyTraps = Object.fromEntries(Object.getOwnPropertyNames(Reflect).map((fnName) => [
fnName,
() => {
throw new Error(`unsupported operation on page data obejct proxy`);
},
]));
function transformOnePageDataInternal(page) {
const runtimeData = Object.fromEntries(Object.entries(page.runtimeData).map(([key, { dataPath }]) => [
key,
dataPath,
]));
const staticData = Object.fromEntries(Object.entries(page.staticData).map(([key, { staticData }]) => [
key,
staticData,
]));
return { data: runtimeData, staticData };
}
//# sourceMappingURL=PagesDataKeeper.js.map