



























@@ -327,8 +327,10 @@ export class OpenClaw {
327327});
328328private readonly replayByRunId = new Map<string, OpenClawEvent[]>();
329329private connected = false;
330+private closed = false;
330331private eventPumpPromise: Promise<void> | null = null;
331332private eventPumpReady: Promise<void> | null = null;
333+private closePromise: Promise<void> | null = null;
332334333335constructor(options: OpenClawOptions = {}) {
334336this.transport =
@@ -351,24 +353,45 @@ export class OpenClaw {
351353}
352354353355async connect(): Promise<void> {
356+this.assertOpen();
354357if (this.connected) {
355358await this.startEventPump();
359+this.assertOpen();
356360return;
357361}
358362if (isConnectableTransport(this.transport)) {
359363await this.transport.connect();
360364}
365+this.assertOpen();
361366this.connected = true;
362367await this.startEventPump();
368+this.assertOpen();
363369}
364370365371async close(): Promise<void> {
366-await this.transport.close?.();
367-await this.eventPumpPromise?.catch(() => {});
368-this.normalizedEvents.close();
369-this.eventPumpPromise = null;
370-this.eventPumpReady = null;
371-this.connected = false;
372+if (this.closePromise) {
373+return await this.closePromise;
374+}
375+if (this.closed) {
376+return;
377+}
378+this.closed = true;
379+this.closePromise = (async () => {
380+try {
381+await this.transport.close?.();
382+await this.eventPumpPromise?.catch(() => {});
383+} finally {
384+this.normalizedEvents.close();
385+this.eventPumpPromise = null;
386+this.eventPumpReady = null;
387+this.connected = false;
388+}
389+})();
390+try {
391+await this.closePromise;
392+} finally {
393+this.closePromise = null;
394+}
372395}
373396374397async request<T = unknown>(
@@ -377,6 +400,7 @@ export class OpenClaw {
377400options?: GatewayRequestOptions,
378401): Promise<T> {
379402await this.connect();
403+this.assertOpen();
380404return await this.transport.request<T>(method, params, options);
381405}
382406@@ -392,13 +416,21 @@ export class OpenClaw {
392416}
393417394418rawEvents(filter?: (event: GatewayEvent) => boolean): AsyncIterable<GatewayEvent> {
419+this.assertOpen();
395420return this.transport.events(filter);
396421}
397422423+private assertOpen(): void {
424+if (this.closed) {
425+throw new Error("OpenClaw SDK client is closed");
426+}
427+}
428+398429private async *iterateEvents(
399430filter?: (event: OpenClawEvent) => boolean,
400431): AsyncIterable<OpenClawEvent> {
401432await this.connect();
433+this.assertOpen();
402434for await (const event of this.normalizedEvents.stream(filter)) {
403435yield event;
404436}
@@ -409,6 +441,7 @@ export class OpenClaw {
409441filter?: (event: OpenClawEvent) => boolean,
410442): AsyncIterable<OpenClawEvent> {
411443await this.connect();
444+this.assertOpen();
412445const replayEvents = this.replaySnapshot(runId);
413446let hasCanonicalAssistantRunEvent = replayEvents.some(isAssistantRunEvent);
414447let hasTerminalRunEvent = replayEvents.some(isTerminalRunEvent);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。