Files
Genarrative/apps/ai-game-creator-shell/src/services/projectSnapshotWorkspace.ts
T
kdletters 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 联调和安装版实机验证待补
2026-09-20 10:07:31 +08:00

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;
}