refactor: move upload fetch timeout helper
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
## 1. 目标
|
||||
|
||||
在 `3-19` 已归档的基础上,继续把仍留在 Rust inline / 主壳大 runtime 中的浏览器行为切成可审计模块。Codex 维护本文件作为事实源,Reasonix 只承接短批次审计、窄范围实现或浏览器 smoke;每批最多 2 个 worker。
|
||||
在 `3-19` 已归档的基础上,继续把仍留在 Rust inline / 主壳大 runtime 中的浏览器行为切成可审计模块。Codex 维护本文件作为事实源,Reasonix 只承接短批次审计、窄范围实现或浏览器 smoke;每批最多 4 个 worker。
|
||||
|
||||
## 2. 本轮边界
|
||||
|
||||
@@ -65,3 +65,9 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据
|
||||
- 2026-05-25:Codex 创建本续跑事实源。
|
||||
- 2026-05-25:修正执行约束:本文件遵循当前 goal 的“每批最多 2 个 worker”,不再沿用早期草稿中的 4 worker 并行方案。
|
||||
- 2026-05-25:下一批只派发 Worker B(local upload / filetree 下一刀只读审计);Worker A/C/D 暂缓。
|
||||
- 2026-05-25:Reasonix local upload / filetree 只读审计尝试未产生 `result.json` / `process-handoff`,且运行期间出现额外 Batch A2 runner,主控已终止进程;该结果不作为正式 handoff 采纳。
|
||||
- 可参考的 transcript 结论:`fetchWithTimeout` 是低风险纯工具函数,可先迁入 `local-upload-runtime.js`;`uploadFileToMediaAsset` / `uploadFilesWithResolvedTarget` / `insertUploadedAssetIntoEditor` 仍与 API、editor 插入和 snapshot refresh 耦合,暂不迁。
|
||||
- 2026-05-25:Codex 主控直接完成低风险切片:`local-upload-runtime.js` 新增并导出 `fetchWithTimeout`,`layout.rs` 的 inline `fetchWithTimeout` 先委托 runtime,保留原 fallback。
|
||||
- 修改:`rust/crates/mnote-web/browser/local-upload-runtime.js`、`rust/crates/mnote-web/src/ssr/pages/layout.rs`。
|
||||
- 已验证:`node --check rust/crates/mnote-web/browser/local-upload-runtime.js`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/Cargo.toml -p mnote-web`、`cargo test --manifest-path rust/Cargo.toml -p mnote-web mnote_browser_runtime_assets_are_explicitly_mounted -- --test-threads=1`、`cargo test --manifest-path rust/Cargo.toml -p mnote-web local_upload_runtime_contains_editor_upload_context_helpers -- --test-threads=1`。
|
||||
- 未完成:`insertUploadedAssetIntoEditor`、`uploadFileToMediaAsset`、`uploadFilesWithResolvedTarget` 仍未迁出。
|
||||
|
||||
@@ -67,4 +67,7 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据
|
||||
- 已迁函数:`node_is_within_root`、`active_editor_text_selection`、`has_active_text_selection`、`selection_summary`、`selection_has_rich_marks`。
|
||||
- 未迁:`SelectionPayload`、`selection_payload`、`send_selection_state*`、`selection_event_payload`,原因是仍依赖 bridge event、`HoveredBlockState` 和 runtime block id 边界。
|
||||
- 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`task488`、`task489`、CodeGraph pending 0。
|
||||
- 2026-05-25:下一批只派发 Worker B(overlay / block menu 只读审计);Worker C/D 暂缓,避免超过每批最多 2 个 worker 的 goal 约束。
|
||||
- 2026-05-25:执行口径修正:用户指出只读审计推进过慢,后续 B/C/D 应使用独立 worktree 产出候选 patch,而不是只读审计;每批最多 4 个 worker。
|
||||
- 2026-05-25:Reasonix runner 异常:后续实现 run 未写 `result.json`、`process-handoff.md/json`,部分 transcript 停在工具调用阶段;Codex 不采纳其文字结论,只复核实际 diff。
|
||||
- 2026-05-25:Reasonix overlay / block menu 只读审计尝试未产生 `result.json` / `process-handoff`,且运行期间出现额外 Batch A2 runner,主控已终止进程;该结果不作为正式 handoff 采纳。
|
||||
- transcript 只显示探索过程,未形成函数归属表;下一次应改为更窄的单问题只读任务,例如只审计 `floating_toolbar_anchor_from_selection` / `sync_text_selection_overlay` 能否迁入 `overlays.rs`。
|
||||
|
||||
@@ -124,6 +124,28 @@ function openEditorUploadFilePicker(detail, deps) {
|
||||
input.click();
|
||||
}
|
||||
|
||||
async function fetchWithTimeout(input, init, timeoutMs, label) {
|
||||
var controller = typeof AbortController === 'function' ? new AbortController() : null;
|
||||
var timer = 0;
|
||||
try {
|
||||
if (controller) {
|
||||
timer = window.setTimeout(function() {
|
||||
controller.abort();
|
||||
}, Math.max(1000, Number(timeoutMs) || 15000));
|
||||
}
|
||||
var nextInit = Object.assign({}, init || {});
|
||||
if (controller) nextInit.signal = controller.signal;
|
||||
return await fetch(input, nextInit);
|
||||
} catch (error) {
|
||||
if (error && error.name === 'AbortError') {
|
||||
throw new Error((label || '请求') + '超时');
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
if (timer) window.clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
function localAssetOpenUrl(asset, download, context) {
|
||||
if (!isLocalUploadedAsset(asset)) return '';
|
||||
var rootUri = String(context && context.rootUri || asset && (asset.rootUri || asset.root_uri) || '').trim() || currentRootUri();
|
||||
@@ -252,6 +274,7 @@ window.__mnoteLocalUploadRuntime = {
|
||||
resolveEditorUploadContext: resolveEditorUploadContext,
|
||||
editorRootFromUploadOptions: editorRootFromUploadOptions,
|
||||
openEditorUploadFilePicker: openEditorUploadFilePicker,
|
||||
fetchWithTimeout: fetchWithTimeout,
|
||||
localAssetOpenUrl: localAssetOpenUrl,
|
||||
uploadedAssetType: uploadedAssetType,
|
||||
fileTreeIconKindForFileName: fileTreeIconKindForFileName,
|
||||
|
||||
@@ -3879,6 +3879,10 @@ const SIDEBAR_TREE_JS: &str = r##"
|
||||
}
|
||||
|
||||
async function fetchWithTimeout(input, init, timeoutMs, label) {
|
||||
var runtimeFn = localUploadRuntimeFunction('fetchWithTimeout');
|
||||
if (runtimeFn) {
|
||||
return await runtimeFn(input, init || {}, timeoutMs, label);
|
||||
}
|
||||
var controller = typeof AbortController === 'function' ? new AbortController() : null;
|
||||
var timer = 0;
|
||||
try {
|
||||
@@ -10930,6 +10934,7 @@ mod tests {
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("function resolveEditorUploadContext"));
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("function editorRootFromUploadOptions"));
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("function openEditorUploadFilePicker"));
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("function fetchWithTimeout"));
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("uploadFilesWithResolvedTarget"));
|
||||
assert!(LOCAL_UPLOAD_RUNTIME_JS.contains("__mnoteLastEditorUploadRoot"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user