内容与注册表指纹拆成两条命令,指纹退出内容 DTO
- read_xhs_minitool_export 只回内容(form + hasScript),新增 read_xhs_minitool_export_hash 单独回注册表指纹;save_xhs_minitool_export_form 成功后回新的指纹。 - XHSMiniToolExportState 去掉 contentHash:它是写回时的同步细节,混在「面板渲染的内容」里会让自动刷新顺手换掉写回基线,把两次刷新之间的外部改动认成自己的基线、静默吞掉冲突。 - 分两条命令之后,刷新这条高频路径在类型上就碰不到基线;指纹只在进编辑会话或重读到的内容真的被采纳时取一次。 - 待办标注:这条命令切分也让「面板不再显示任何同步状态」在类型上成立(前端不必拿到指纹就能渲染)。
This commit is contained in:
@@ -8,7 +8,8 @@ use client_extensions::*;
|
||||
use environment_check::preflight_web_game_creation;
|
||||
use error_report::*;
|
||||
use export::draft::xhs_minitool::commands::{
|
||||
read_xhs_minitool_export, run_xhs_minitool_export_build, save_xhs_minitool_export_form,
|
||||
read_xhs_minitool_export, read_xhs_minitool_export_hash, run_xhs_minitool_export_build,
|
||||
save_xhs_minitool_export_form,
|
||||
};
|
||||
use game_distribution_publish::*;
|
||||
use plugin_host::{
|
||||
@@ -689,6 +690,7 @@ pub(super) fn run() {
|
||||
create_local_project_checkpoint,
|
||||
export_local_project_package,
|
||||
read_xhs_minitool_export,
|
||||
read_xhs_minitool_export_hash,
|
||||
save_xhs_minitool_export_form,
|
||||
run_xhs_minitool_export_build,
|
||||
prepare_local_project_game_package,
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
//! 导出面板用到的三个 `#[tauri::command]`。
|
||||
//! 导出面板用到的四个 `#[tauri::command]`。
|
||||
//!
|
||||
//! 每个命令只做一件事,全部走 typed 失败([`XHSMiniToolExportError`])。没有项目写锁、不推进
|
||||
//! revision:宿主在这里读写的,就是 `.export/` 下那一个注册表文件。
|
||||
//!
|
||||
//! 「内容」与「注册表指纹」是两条命令:[`read_xhs_minitool_export`] 是面板自动刷新反复调的
|
||||
//! 那条,拿不到指纹;指纹(写回时的 `baseHash`)只在进编辑会话、或内容真的被采纳时单独取一次。
|
||||
//! 分开是为了让刷新动作在类型上就动不了写回基线——否则外部改动会被静默吞掉。
|
||||
//!
|
||||
//! 入参在 JS 侧是 camelCase(Tauri 的既有口径):`projectPath`、`baseHash`。
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -13,16 +17,27 @@ use super::registry::{self, RegistrySnapshot};
|
||||
use super::validation::validate_form;
|
||||
use super::{build, script};
|
||||
|
||||
/// 读现场:注册表(缺则补一份空表单)+ 脚本是否存在。
|
||||
/// 读内容:注册表(缺则补一份空表单)+ 脚本是否存在。自动刷新反复调的就是这一条。
|
||||
#[tauri::command]
|
||||
pub(crate) async fn read_xhs_minitool_export(
|
||||
project_path: String,
|
||||
) -> Result<XHSMiniToolExportState, XHSMiniToolExportError> {
|
||||
let root = project_root(&project_path)?;
|
||||
Ok(state(&root, registry::load(&root)?))
|
||||
Ok(content(&root, registry::load(&root)?))
|
||||
}
|
||||
|
||||
/// 保存表单:先硬校验(首个错误即返回),再按 `base_hash` 判冲突。
|
||||
/// 读注册表指纹:写回时原样带回做冲突判据。
|
||||
///
|
||||
/// 单独一条命令,且**只在内容被采纳时**取:让「刷新」这条高频路径在类型上碰不到写回基线。
|
||||
#[tauri::command]
|
||||
pub(crate) async fn read_xhs_minitool_export_hash(
|
||||
project_path: String,
|
||||
) -> Result<String, XHSMiniToolExportError> {
|
||||
let root = project_root(&project_path)?;
|
||||
Ok(registry::load(&root)?.content_hash)
|
||||
}
|
||||
|
||||
/// 保存表单:先硬校验(首个错误即返回),再按 `base_hash` 判冲突;成功后回新的指纹。
|
||||
///
|
||||
/// 校验挡在保存之前是刻意的——平台字数与 icon 限制是硬约束,让它在用户输入时就被看见,比等到
|
||||
/// 人工上传被平台打回便宜。
|
||||
@@ -31,10 +46,10 @@ pub(crate) async fn save_xhs_minitool_export_form(
|
||||
project_path: String,
|
||||
form: XHSMiniToolExportForm,
|
||||
base_hash: String,
|
||||
) -> Result<XHSMiniToolExportState, XHSMiniToolExportError> {
|
||||
) -> Result<String, XHSMiniToolExportError> {
|
||||
let root = project_root(&project_path)?;
|
||||
validate_form(&root, &form)?;
|
||||
Ok(state(&root, registry::save(&root, &form, &base_hash)?))
|
||||
Ok(registry::save(&root, &form, &base_hash)?.content_hash)
|
||||
}
|
||||
|
||||
/// 跑一次导出:每次都重新执行项目脚本、重新产出 zip。
|
||||
@@ -47,11 +62,10 @@ pub(crate) async fn run_xhs_minitool_export_build(
|
||||
}
|
||||
|
||||
/// `hasScript` 永远现算:注册表里不存、也不缓存这个事实。
|
||||
fn state(root: &Path, snapshot: RegistrySnapshot) -> XHSMiniToolExportState {
|
||||
fn content(root: &Path, snapshot: RegistrySnapshot) -> XHSMiniToolExportState {
|
||||
XHSMiniToolExportState {
|
||||
form: snapshot.form,
|
||||
has_script: script::find(root).is_some(),
|
||||
content_hash: snapshot.content_hash,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,10 +52,11 @@ pub(crate) enum XHSMiniToolExportField {
|
||||
IconPath,
|
||||
}
|
||||
|
||||
/// 面板读到的现场状态。
|
||||
/// 面板读到的现场内容。
|
||||
///
|
||||
/// 没有「产物是否已存在」:每次导出都重新构建。也没有 status / 已适配标记——「有没有脚本」
|
||||
/// 永远从 npm 包的 `package.json` 现算,不落盘。
|
||||
/// 永远从 npm 包的 `package.json` 现算,不落盘。也没有注册表指纹:那是写回时的同步细节,
|
||||
/// 由 `read_xhs_minitool_export_hash` 单独给,自动刷新读的这条命令碰不到它。
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = concat!(env!("CARGO_MANIFEST_DIR"), "/../src/view/project-development/export/generated/"))]
|
||||
@@ -63,8 +64,6 @@ pub(crate) struct XHSMiniToolExportState {
|
||||
pub(crate) form: XHSMiniToolExportForm,
|
||||
/// `scripts["build:xhs-minitool"]` 是否存在。
|
||||
pub(crate) has_script: bool,
|
||||
/// 注册表文件的当前内容指纹。保存时原样带回做冲突判据;它不写进文件。
|
||||
pub(crate) content_hash: String,
|
||||
}
|
||||
|
||||
/// 一次成功导出的结果。产物路径是常量(`.export/xhs-minitool.zip`),不进 DTO。
|
||||
|
||||
+4
-7
@@ -2,17 +2,14 @@
|
||||
import type { XHSMiniToolExportForm } from "./XHSMiniToolExportForm";
|
||||
|
||||
/**
|
||||
* 面板读到的现场状态。
|
||||
* 面板读到的现场内容。
|
||||
*
|
||||
* 没有「产物是否已存在」:每次导出都重新构建。也没有 status / 已适配标记——「有没有脚本」
|
||||
* 永远从 npm 包的 `package.json` 现算,不落盘。
|
||||
* 永远从 npm 包的 `package.json` 现算,不落盘。也没有注册表指纹:那是写回时的同步细节,
|
||||
* 由 `read_xhs_minitool_export_hash` 单独给,自动刷新读的这条命令碰不到它。
|
||||
*/
|
||||
export type XHSMiniToolExportState = { form: XHSMiniToolExportForm,
|
||||
/**
|
||||
* `scripts["build:xhs-minitool"]` 是否存在。
|
||||
*/
|
||||
hasScript: boolean,
|
||||
/**
|
||||
* 注册表文件的当前内容指纹。保存时原样带回做冲突判据;它不写进文件。
|
||||
*/
|
||||
contentHash: string, };
|
||||
hasScript: boolean, };
|
||||
|
||||
Reference in New Issue
Block a user