Optimize XYZAC motion updates and persist power-off recovery
This commit is contained in:
@@ -1,7 +1,20 @@
|
||||
import { CONTEXT_ID, PROTOCOL_SCHEMA, isEnvelope, type MessageEnvelope } from "./protocol";
|
||||
import { attachPersistedPowerOffCheckpoint, clearPersistedPowerOffCheckpoint, persistPowerOffCheckpoint } from "./power-off-checkpoint-storage";
|
||||
|
||||
type Listener = (message: MessageEnvelope) => void;
|
||||
|
||||
function commandError(message: MessageEnvelope): Error {
|
||||
const payload = message.payload && typeof message.payload === "object" ? message.payload as Record<string, unknown> : {};
|
||||
const error = new Error(String(payload.reason ?? payload.gate_reason ?? payload.message_key ?? payload.code ?? "worker_error"));
|
||||
Object.assign(error, {
|
||||
code: String(payload.code ?? "worker_error"),
|
||||
reason: payload.reason ?? payload.gate_reason ?? null,
|
||||
message_key: payload.message_key ?? null,
|
||||
response: message,
|
||||
});
|
||||
return error;
|
||||
}
|
||||
|
||||
export class ReactWorkerClient {
|
||||
private readonly worker: Worker;
|
||||
private readonly contextId: string;
|
||||
@@ -19,11 +32,14 @@ export class ReactWorkerClient {
|
||||
this.sessionId = sessionId;
|
||||
this.worker.onmessage = (event: MessageEvent<unknown>) => {
|
||||
if (!isEnvelope(event.data)) return;
|
||||
const persistence = persistPowerOffCheckpoint(event.data);
|
||||
if (persistence && event.data.payload && typeof event.data.payload === "object") Object.assign(event.data.payload, { recovery_persistence: persistence });
|
||||
clearPersistedPowerOffCheckpoint(event.data);
|
||||
for (const listener of this.listeners) listener(event.data);
|
||||
const pending = this.pending.get(event.data.seq);
|
||||
if (pending) {
|
||||
this.pending.delete(event.data.seq);
|
||||
if (event.data.kind === "ERROR" || event.data.payload && typeof event.data.payload === "object" && (event.data.payload as { status?: string }).status === "blocked") pending.reject(new Error(String((event.data.payload as { code?: string }).code ?? "worker_error")));
|
||||
if (event.data.kind === "ERROR" || event.data.payload && typeof event.data.payload === "object" && (event.data.payload as { status?: string }).status === "blocked") pending.reject(commandError(event.data));
|
||||
else pending.resolve(event.data);
|
||||
}
|
||||
};
|
||||
@@ -45,7 +61,8 @@ export class ReactWorkerClient {
|
||||
subscribe(listener: Listener): () => void { this.listeners.add(listener); return () => this.listeners.delete(listener); }
|
||||
|
||||
send(kind: string, payload: unknown = {}, operationId?: string): Promise<MessageEnvelope> {
|
||||
const message: MessageEnvelope = { schema_version: PROTOCOL_SCHEMA, kind, context_id: this.contextId, session_id: this.sessionId, seq: ++this.sequence, ...(operationId ? { operation_id: operationId } : {}), payload };
|
||||
const nextPayload = kind === "LOAD_WORKSPACE" ? attachPersistedPowerOffCheckpoint(payload) : payload;
|
||||
const message: MessageEnvelope = { schema_version: PROTOCOL_SCHEMA, kind, context_id: this.contextId, session_id: this.sessionId, seq: ++this.sequence, ...(operationId ? { operation_id: operationId } : {}), payload: nextPayload };
|
||||
return new Promise((resolve, reject) => { this.pending.set(message.seq, { resolve, reject }); this.worker.postMessage(message); });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user