migration: establish exact preserved app baseline

This commit is contained in:
leefer
2026-07-30 23:51:48 +08:00
parent 41329943c4
commit 4083dceba3
399 changed files with 129967 additions and 23 deletions
+4
View File
@@ -0,0 +1,4 @@
window.XiaobaiPageModules.register("auction", ["auctionView"], {
enter: ["loadAuction"],
leave: ["clearAuction"],
});
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("dragon_tiger", ["dragonView"], {
enter: ["loadDragonTiger"],
});
+4
View File
@@ -0,0 +1,4 @@
window.XiaobaiPageModules.register("heaven", ["heavenView"], {
enter: ["loadHeaven"],
leave: ["stopHeaven"],
});
+1
View File
@@ -0,0 +1 @@
window.XiaobaiPageModules.register("ladder", ["ladderView"]);
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("mentor", ["mentorView"], {
enter: ["loadMentor"],
});
+7
View File
@@ -0,0 +1,7 @@
window.XiaobaiPageModules.register("pools", [
"limitPool",
"brokenView",
"downView",
"yesterdayView",
"performanceView",
]);
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("popularity", ["popularityView"], {
enter: ["loadPopularity"],
});
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("review", ["reviewWorkspaceView"], {
enter: ["loadReview"],
});
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("rotation", ["rotationView"], {
enter: ["loadRotation"],
});
+60
View File
@@ -0,0 +1,60 @@
(function exposePageModuleRuntime(global) {
"use strict";
const definitions = new Map();
let sealed = false;
function register(feature, viewIds, lifecycle = {}) {
if (sealed) throw new Error("Page module registry is already sealed");
if (!feature || !Array.isArray(viewIds) || !viewIds.length) {
throw new Error("Page modules require a feature and at least one view ID");
}
viewIds.forEach((viewId) => {
if (definitions.has(viewId)) throw new Error(`Duplicate page module: ${viewId}`);
definitions.set(viewId, Object.freeze({
feature,
viewId,
enter: Object.freeze([...(lifecycle.enter || [])]),
leave: Object.freeze([...(lifecycle.leave || [])]),
}));
});
}
function create(options) {
sealed = true;
const pages = options.pages;
const actions = Object.freeze({ ...(options.actions || {}) });
const missing = pages.all.filter((page) => !definitions.has(page.id)).map((page) => page.id);
if (missing.length) throw new Error(`Missing page modules: ${missing.join(", ")}`);
function run(actionNames, context) {
actionNames.forEach((actionName) => {
const action = actions[actionName];
if (typeof action !== "function") throw new Error(`Unknown page action: ${actionName}`);
action(context);
});
}
function beforeMount(viewId, previousView) {
actions.closeTransientUi?.({ viewId, previousView });
if (previousView && previousView !== viewId) {
run(definitions.get(previousView)?.leave || [], { viewId, previousView });
}
}
function afterMount(viewId, previousView) {
const context = { viewId, previousView };
actions.applyAccess?.(context);
run(definitions.get(viewId)?.enter || [], context);
}
return Object.freeze({
afterMount,
beforeMount,
get: (viewId) => definitions.get(viewId) || null,
has: (viewId) => definitions.has(viewId),
});
}
global.XiaobaiPageModules = Object.freeze({ create, register });
})(window);
+5
View File
@@ -0,0 +1,5 @@
window.XiaobaiPageModules.register("screener", ["screenerView"], {
enter: ["loadScreener"],
});
window.XiaobaiPageModules.register("screener", ["screenerTrackingView"]);
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("sentiment", ["sentimentCycleView"], {
enter: ["loadSentiment"],
});
+3
View File
@@ -0,0 +1,3 @@
window.XiaobaiPageModules.register("themes", ["themeLibraryView"], {
enter: ["loadThemes"],
});