refactor: split tree shell page runtime
This commit is contained in:
+1
-1
@@ -205,7 +205,7 @@ cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib ssr::pages::layout
|
|||||||
拆分项:
|
拆分项:
|
||||||
|
|
||||||
- [ ] D1. `tree-shell-state-runtime.js`:state hydration、serialization、patch dispatch。
|
- [ ] D1. `tree-shell-state-runtime.js`:state hydration、serialization、patch dispatch。
|
||||||
- [ ] D2. `tree-shell-page-runtime.js`:page tree keyboard、expand、focus、drag/drop intent。
|
- [x] D2. `tree-shell-page-runtime.js`:page tree keyboard、expand、focus、drag/drop intent。
|
||||||
- [ ] D3. `tree-shell-filetree-runtime.js`:filetree row normalization、resource meta、open target。
|
- [ ] D3. `tree-shell-filetree-runtime.js`:filetree row normalization、resource meta、open target。
|
||||||
- [ ] D4. `tree-shell-picker-runtime.js`:picker search/focus/pick root。
|
- [ ] D4. `tree-shell-picker-runtime.js`:picker search/focus/pick root。
|
||||||
- [ ] D5. `tree-shell-dom-runtime.js`:DOM patch/render helpers。
|
- [ ] D5. `tree-shell-dom-runtime.js`:DOM patch/render helpers。
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// MNote debug /tree shell page-mode runtime helpers.
|
||||||
|
|
||||||
|
export async function reducePageActionWithRuntime(runtimeContext, action, item) {
|
||||||
|
if (runtimeContext.mode !== "page" || !runtimeContext.runtimeReduceEndpoint) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const runtimeAction = runtimeContext.buildPageRuntimeAction(action, item);
|
||||||
|
if (!runtimeAction) return null;
|
||||||
|
const response = await fetch(runtimeContext.runtimeReduceEndpoint, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
mode: "page",
|
||||||
|
requestId: `page-runtime-${Date.now()}`,
|
||||||
|
environment: runtimeContext.buildPageRuntimeEnvironment(),
|
||||||
|
state: runtimeContext.readPageRuntimeState(action, item),
|
||||||
|
action: runtimeAction,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(await runtimeContext.readErrorMessage(response));
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function reconcilePageRuntimeResult(runtimeContext, runtimeResult, item) {
|
||||||
|
const result = runtimeContext.normalizePageRuntimeResult(runtimeResult);
|
||||||
|
if (!result) return false;
|
||||||
|
const previousExpanded = new Set(runtimeContext.expanded);
|
||||||
|
let shouldPatchTree = false;
|
||||||
|
if (Array.isArray(result.expandedIds)) {
|
||||||
|
shouldPatchTree =
|
||||||
|
runtimeContext.commitPageExpandedIds(result.expandedIds) || shouldPatchTree;
|
||||||
|
}
|
||||||
|
const currentFocusedNodeId = runtimeContext.getFocusedNodeId();
|
||||||
|
if (result.focusedId && result.focusedId !== currentFocusedNodeId) {
|
||||||
|
runtimeContext.setFocusedNodeId(result.focusedId);
|
||||||
|
runtimeContext.postPageFocusChange(result.focusedId);
|
||||||
|
shouldPatchTree = true;
|
||||||
|
}
|
||||||
|
const itemNodeId = runtimeContext.normalizeText(item?.nodeId);
|
||||||
|
if (
|
||||||
|
itemNodeId &&
|
||||||
|
previousExpanded.has(itemNodeId) !== runtimeContext.expanded.has(itemNodeId)
|
||||||
|
) {
|
||||||
|
runtimeContext.postPageExpandChange(itemNodeId, runtimeContext.expanded.has(itemNodeId));
|
||||||
|
}
|
||||||
|
if (shouldPatchTree) {
|
||||||
|
runtimeContext.patchPageTreeAfterRuntimeState(
|
||||||
|
Array.isArray(result.expandedIds) ? [itemNodeId, ...result.expandedIds] : [itemNodeId],
|
||||||
|
result.focusedId || runtimeContext.getFocusedNodeId(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return shouldPatchTree;
|
||||||
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
// MNote debug /tree shell 浏览器运行时外置模块。
|
// MNote debug /tree shell 浏览器运行时外置模块。
|
||||||
// 该文件由 tree.rs 原 inline runtime 同构迁出,语义仍由 Rust tree_shell reducer 主导。
|
// 该文件由 tree.rs 原 inline runtime 同构迁出,语义仍由 Rust tree_shell reducer 主导。
|
||||||
|
|
||||||
|
import {
|
||||||
|
reconcilePageRuntimeResult,
|
||||||
|
reducePageActionWithRuntime,
|
||||||
|
} from "./tree-shell-page-runtime.js";
|
||||||
|
|
||||||
function buildFileTreeRuntimeEnvironment(runtimeContext) {
|
function buildFileTreeRuntimeEnvironment(runtimeContext) {
|
||||||
const fileTreeRowById = runtimeContext.fileTreeRowById || new Map();
|
const fileTreeRowById = runtimeContext.fileTreeRowById || new Map();
|
||||||
return {
|
return {
|
||||||
@@ -17,60 +22,6 @@ function buildFileTreeRuntimeEnvironment(runtimeContext) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reducePageActionWithRuntime(runtimeContext, action, item) {
|
|
||||||
if (runtimeContext.mode !== "page" || !runtimeContext.runtimeReduceEndpoint) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const runtimeAction = runtimeContext.buildPageRuntimeAction(action, item);
|
|
||||||
if (!runtimeAction) return null;
|
|
||||||
const response = await fetch(runtimeContext.runtimeReduceEndpoint, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "content-type": "application/json" },
|
|
||||||
body: JSON.stringify({
|
|
||||||
mode: "page",
|
|
||||||
requestId: `page-runtime-${Date.now()}`,
|
|
||||||
environment: runtimeContext.buildPageRuntimeEnvironment(),
|
|
||||||
state: runtimeContext.readPageRuntimeState(action, item),
|
|
||||||
action: runtimeAction,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(await runtimeContext.readErrorMessage(response));
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
function reconcilePageRuntimeResult(runtimeContext, runtimeResult, item) {
|
|
||||||
const result = runtimeContext.normalizePageRuntimeResult(runtimeResult);
|
|
||||||
if (!result) return false;
|
|
||||||
const previousExpanded = new Set(runtimeContext.expanded);
|
|
||||||
let shouldPatchTree = false;
|
|
||||||
if (Array.isArray(result.expandedIds)) {
|
|
||||||
shouldPatchTree =
|
|
||||||
runtimeContext.commitPageExpandedIds(result.expandedIds) || shouldPatchTree;
|
|
||||||
}
|
|
||||||
const currentFocusedNodeId = runtimeContext.getFocusedNodeId();
|
|
||||||
if (result.focusedId && result.focusedId !== currentFocusedNodeId) {
|
|
||||||
runtimeContext.setFocusedNodeId(result.focusedId);
|
|
||||||
runtimeContext.postPageFocusChange(result.focusedId);
|
|
||||||
shouldPatchTree = true;
|
|
||||||
}
|
|
||||||
const itemNodeId = runtimeContext.normalizeText(item?.nodeId);
|
|
||||||
if (
|
|
||||||
itemNodeId &&
|
|
||||||
previousExpanded.has(itemNodeId) !== runtimeContext.expanded.has(itemNodeId)
|
|
||||||
) {
|
|
||||||
runtimeContext.postPageExpandChange(itemNodeId, runtimeContext.expanded.has(itemNodeId));
|
|
||||||
}
|
|
||||||
if (shouldPatchTree) {
|
|
||||||
runtimeContext.patchPageTreeAfterRuntimeState(
|
|
||||||
Array.isArray(result.expandedIds) ? [itemNodeId, ...result.expandedIds] : [itemNodeId],
|
|
||||||
result.focusedId || runtimeContext.getFocusedNodeId(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return shouldPatchTree;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startTreeShellRuntime() {
|
function startTreeShellRuntime() {
|
||||||
const stateElement = document.getElementById("tree-shell-state");
|
const stateElement = document.getElementById("tree-shell-state");
|
||||||
const appElement = document.getElementById("tree-shell-app");
|
const appElement = document.getElementById("tree-shell-app");
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ pub fn build_router(state: AppState) -> Router {
|
|||||||
"/api/mnote-browser-runtime/tree-shell-runtime.js",
|
"/api/mnote-browser-runtime/tree-shell-runtime.js",
|
||||||
get(web_shell::tree_shell_runtime_asset),
|
get(web_shell::tree_shell_runtime_asset),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/mnote-browser-runtime/tree-shell-page-runtime.js",
|
||||||
|
get(web_shell::tree_shell_page_runtime_asset),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/mnote-browser-runtime/document-conflict-panel-runtime.js",
|
"/api/mnote-browser-runtime/document-conflict-panel-runtime.js",
|
||||||
get(web_shell::document_conflict_panel_runtime_asset),
|
get(web_shell::document_conflict_panel_runtime_asset),
|
||||||
@@ -617,6 +621,7 @@ mod tests {
|
|||||||
"/api/mnote-browser-runtime/sidebar-tree-runtime.js",
|
"/api/mnote-browser-runtime/sidebar-tree-runtime.js",
|
||||||
"/api/mnote-browser-runtime/tree-live-controller.js",
|
"/api/mnote-browser-runtime/tree-live-controller.js",
|
||||||
"/api/mnote-browser-runtime/tree-shell-runtime.js",
|
"/api/mnote-browser-runtime/tree-shell-runtime.js",
|
||||||
|
"/api/mnote-browser-runtime/tree-shell-page-runtime.js",
|
||||||
"/api/mnote-browser-runtime/document-conflict-panel-runtime.js",
|
"/api/mnote-browser-runtime/document-conflict-panel-runtime.js",
|
||||||
"/api/mnote-browser-runtime/document-pane-runtime.js",
|
"/api/mnote-browser-runtime/document-pane-runtime.js",
|
||||||
"/api/mnote-browser-runtime/document-mindmap-host-runtime.js",
|
"/api/mnote-browser-runtime/document-mindmap-host-runtime.js",
|
||||||
|
|||||||
@@ -938,6 +938,20 @@ pub async fn tree_shell_runtime_asset() -> Response {
|
|||||||
.unwrap_or_else(|_| Response::new(Body::empty()))
|
.unwrap_or_else(|_| Response::new(Body::empty()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn tree_shell_page_runtime_asset() -> Response {
|
||||||
|
const JS: &str = include_str!("../../browser/tree-shell-page-runtime.js");
|
||||||
|
Response::builder()
|
||||||
|
.status(StatusCode::OK)
|
||||||
|
.header(
|
||||||
|
header::CONTENT_TYPE,
|
||||||
|
"application/javascript; charset=utf-8",
|
||||||
|
)
|
||||||
|
.header(header::CACHE_CONTROL, "no-store")
|
||||||
|
.header(HEADER_MNOTE_WEB_OWNER, "mnote-web")
|
||||||
|
.body(Body::from(JS))
|
||||||
|
.unwrap_or_else(|_| Response::new(Body::empty()))
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn document_conflict_panel_runtime_asset() -> Response {
|
pub async fn document_conflict_panel_runtime_asset() -> Response {
|
||||||
// include_str! 路径相对于当前源文件 (src/routes/web_shell.rs -> ../../browser/)
|
// include_str! 路径相对于当前源文件 (src/routes/web_shell.rs -> ../../browser/)
|
||||||
const JS: &str = include_str!("../../browser/document-conflict-panel-runtime.js");
|
const JS: &str = include_str!("../../browser/document-conflict-panel-runtime.js");
|
||||||
|
|||||||
Reference in New Issue
Block a user