15774a1c02
Project CI / AI game creator shell Rust shard 1/4 (push) Successful in 7m24s
Project CI / AI game creator shell Rust shard 4/4 (push) Successful in 7m25s
Project CI / AI game creator shell Rust shard 2/4 (push) Successful in 7m28s
Project CI / AI game creator shell Rust shard 3/4 (push) Successful in 7m31s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m57s
Project CI / AI game creator shell Rust crates (push) Successful in 2m41s
Project CI / Repository checks (push) Successful in 4m10s
Project CI / Native shell tests (push) Successful in 11m20s
Project CI / Frontend tests (push) Successful in 10m30s
Project CI / AI game creator shell web tests (push) Successful in 5m41s
Project CI / Backend tests (push) Successful in 14m9s
接入真实项目打开、切换和关闭生命周期并修复退出等待竞态 新增后台项目列表及按原目录校验导出的 ZIP 下载 补充快照完整性元数据、后台权限和取消清理 固定默认 AGC 存储目标并支持空文件与特殊字符路径 补充自动化测试及真实 OSS 只读导出验证 记录本地数据库 404 导致完整 HTTP 联调和安装版实机验证待补
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
type WorkspaceInvoke = (
|
|
command: string,
|
|
args?: Record<string, unknown>,
|
|
) => Promise<unknown>;
|
|
|
|
/** 同一 WebView 的登记串行提交;旧请求完成后不能覆盖更新的工程状态。 */
|
|
export function createProjectSnapshotWorkspaceRegistration(
|
|
invoke: WorkspaceInvoke,
|
|
) {
|
|
let requestedPath: string | null | undefined;
|
|
let revision = 0;
|
|
let ownerRevision = 0;
|
|
let queue = Promise.resolve();
|
|
|
|
function setProject(projectPath: string | null) {
|
|
if (requestedPath === projectPath) return queue;
|
|
requestedPath = projectPath;
|
|
const requestRevision = ++revision;
|
|
queue = queue.then(async () => {
|
|
try {
|
|
await invoke('set_active_project_snapshot_workspace', { projectPath });
|
|
} catch {
|
|
// 失败不能被记作已登记;下一次相同路径登记仍可重新提交。
|
|
if (revision === requestRevision) requestedPath = undefined;
|
|
try {
|
|
await invoke('append_application_log', {
|
|
level: 'error',
|
|
source: 'project-snapshot',
|
|
message: 'project_snapshot.workspace.registration.failed',
|
|
});
|
|
} catch {
|
|
// 原生桥本身不可用时也不阻断项目创作。
|
|
}
|
|
}
|
|
});
|
|
return queue;
|
|
}
|
|
|
|
function acquire() {
|
|
const owner = ++ownerRevision;
|
|
return () => {
|
|
// StrictMode 的同轮卸载/重挂以及工作台替换不代表工程真的关闭。
|
|
queueMicrotask(() => {
|
|
if (owner === ownerRevision) void setProject(null);
|
|
});
|
|
};
|
|
}
|
|
|
|
return { setProject, acquire };
|
|
}
|
|
|
|
const registrations = new WeakMap<
|
|
WorkspaceInvoke,
|
|
ReturnType<typeof createProjectSnapshotWorkspaceRegistration>
|
|
>();
|
|
|
|
export function projectSnapshotWorkspaceRegistration(invoke: WorkspaceInvoke) {
|
|
let registration = registrations.get(invoke);
|
|
if (!registration) {
|
|
registration = createProjectSnapshotWorkspaceRegistration(invoke);
|
|
registrations.set(invoke, registration);
|
|
}
|
|
return registration;
|
|
}
|