mirror of https://github.com/openclaw/openclaw.git
refactor: share extension deferred and runtime helpers
This commit is contained in:
parent
1ac4bac8b1
commit
6a61d5504c
|
|
@ -1,5 +1,6 @@
|
||||||
import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/irc";
|
import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/irc";
|
||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||||
import { ircOnboardingAdapter } from "./onboarding.js";
|
import { ircOnboardingAdapter } from "./onboarding.js";
|
||||||
import type { CoreConfig } from "./types.js";
|
import type { CoreConfig } from "./types.js";
|
||||||
|
|
||||||
|
|
@ -63,13 +64,7 @@ describe("irc onboarding", () => {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const runtime: RuntimeEnv = {
|
const runtime: RuntimeEnv = createRuntimeEnv();
|
||||||
log: vi.fn(),
|
|
||||||
error: vi.fn(),
|
|
||||||
exit: vi.fn((code: number): never => {
|
|
||||||
throw new Error(`exit ${code}`);
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = await ircOnboardingAdapter.configure({
|
const result = await ircOnboardingAdapter.configure({
|
||||||
cfg: {} as CoreConfig,
|
cfg: {} as CoreConfig,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/matrix";
|
import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/matrix";
|
||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||||
import { matrixPlugin } from "./channel.js";
|
import { matrixPlugin } from "./channel.js";
|
||||||
import { setMatrixRuntime } from "./runtime.js";
|
import { setMatrixRuntime } from "./runtime.js";
|
||||||
import { createMatrixBotSdkMock } from "./test-mocks.js";
|
import { createMatrixBotSdkMock } from "./test-mocks.js";
|
||||||
|
|
@ -10,13 +11,7 @@ vi.mock("@vector-im/matrix-bot-sdk", () =>
|
||||||
);
|
);
|
||||||
|
|
||||||
describe("matrix directory", () => {
|
describe("matrix directory", () => {
|
||||||
const runtimeEnv: RuntimeEnv = {
|
const runtimeEnv: RuntimeEnv = createRuntimeEnv();
|
||||||
log: vi.fn(),
|
|
||||||
error: vi.fn(),
|
|
||||||
exit: vi.fn((code: number): never => {
|
|
||||||
throw new Error(`exit ${code}`);
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
setMatrixRuntime({
|
setMatrixRuntime({
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
PAIRING_APPROVED_MESSAGE,
|
PAIRING_APPROVED_MESSAGE,
|
||||||
type ChannelPlugin,
|
type ChannelPlugin,
|
||||||
} from "openclaw/plugin-sdk/matrix";
|
} from "openclaw/plugin-sdk/matrix";
|
||||||
|
import { buildTrafficStatusSummary } from "../../shared/channel-status-summary.js";
|
||||||
import { matrixMessageActions } from "./actions.js";
|
import { matrixMessageActions } from "./actions.js";
|
||||||
import { MatrixConfigSchema } from "./config-schema.js";
|
import { MatrixConfigSchema } from "./config-schema.js";
|
||||||
import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
|
import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
|
||||||
|
|
@ -410,8 +411,7 @@ export const matrixPlugin: ChannelPlugin<ResolvedMatrixAccount> = {
|
||||||
lastError: runtime?.lastError ?? null,
|
lastError: runtime?.lastError ?? null,
|
||||||
probe,
|
probe,
|
||||||
lastProbeAt: runtime?.lastProbeAt ?? null,
|
lastProbeAt: runtime?.lastProbeAt ?? null,
|
||||||
lastInboundAt: runtime?.lastInboundAt ?? null,
|
...buildTrafficStatusSummary(runtime),
|
||||||
lastOutboundAt: runtime?.lastOutboundAt ?? null,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
gateway: {
|
gateway: {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,7 @@
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { createDeferred } from "../../../shared/deferred.js";
|
||||||
import { DEFAULT_SEND_GAP_MS, enqueueSend } from "./send-queue.js";
|
import { DEFAULT_SEND_GAP_MS, enqueueSend } from "./send-queue.js";
|
||||||
|
|
||||||
function deferred<T>() {
|
|
||||||
let resolve!: (value: T | PromiseLike<T>) => void;
|
|
||||||
let reject!: (reason?: unknown) => void;
|
|
||||||
const promise = new Promise<T>((res, rej) => {
|
|
||||||
resolve = res;
|
|
||||||
reject = rej;
|
|
||||||
});
|
|
||||||
return { promise, resolve, reject };
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("enqueueSend", () => {
|
describe("enqueueSend", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
|
@ -21,7 +12,7 @@ describe("enqueueSend", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("serializes sends per room", async () => {
|
it("serializes sends per room", async () => {
|
||||||
const gate = deferred<void>();
|
const gate = createDeferred<void>();
|
||||||
const events: string[] = [];
|
const events: string[] = [];
|
||||||
|
|
||||||
const first = enqueueSend("!room:example.org", async () => {
|
const first = enqueueSend("!room:example.org", async () => {
|
||||||
|
|
@ -91,7 +82,7 @@ describe("enqueueSend", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("continues queued work when the head task fails", async () => {
|
it("continues queued work when the head task fails", async () => {
|
||||||
const gate = deferred<void>();
|
const gate = createDeferred<void>();
|
||||||
const events: string[] = [];
|
const events: string[] = [];
|
||||||
|
|
||||||
const first = enqueueSend("!room:example.org", async () => {
|
const first = enqueueSend("!room:example.org", async () => {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ import {
|
||||||
mapAllowFromEntries,
|
mapAllowFromEntries,
|
||||||
type ChannelPlugin,
|
type ChannelPlugin,
|
||||||
} from "openclaw/plugin-sdk/nostr";
|
} from "openclaw/plugin-sdk/nostr";
|
||||||
import { buildPassiveChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
import {
|
||||||
|
buildPassiveChannelStatusSummary,
|
||||||
|
buildTrafficStatusSummary,
|
||||||
|
} from "../../shared/channel-status-summary.js";
|
||||||
import type { NostrProfile } from "./config-schema.js";
|
import type { NostrProfile } from "./config-schema.js";
|
||||||
import { NostrConfigSchema } from "./config-schema.js";
|
import { NostrConfigSchema } from "./config-schema.js";
|
||||||
import type { MetricEvent, MetricsSnapshot } from "./metrics.js";
|
import type { MetricEvent, MetricsSnapshot } from "./metrics.js";
|
||||||
|
|
@ -176,8 +179,7 @@ export const nostrPlugin: ChannelPlugin<ResolvedNostrAccount> = {
|
||||||
lastStartAt: runtime?.lastStartAt ?? null,
|
lastStartAt: runtime?.lastStartAt ?? null,
|
||||||
lastStopAt: runtime?.lastStopAt ?? null,
|
lastStopAt: runtime?.lastStopAt ?? null,
|
||||||
lastError: runtime?.lastError ?? null,
|
lastError: runtime?.lastError ?? null,
|
||||||
lastInboundAt: runtime?.lastInboundAt ?? null,
|
...buildTrafficStatusSummary(runtime),
|
||||||
lastOutboundAt: runtime?.lastOutboundAt ?? null,
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@ type PassiveChannelStatusSnapshot = {
|
||||||
lastProbeAt?: number | null;
|
lastProbeAt?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type TrafficStatusSnapshot = {
|
||||||
|
lastInboundAt?: number | null;
|
||||||
|
lastOutboundAt?: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
export function buildPassiveChannelStatusSummary<TExtra extends object>(
|
export function buildPassiveChannelStatusSummary<TExtra extends object>(
|
||||||
snapshot: PassiveChannelStatusSnapshot,
|
snapshot: PassiveChannelStatusSnapshot,
|
||||||
extra?: TExtra,
|
extra?: TExtra,
|
||||||
|
|
@ -32,3 +37,12 @@ export function buildPassiveProbedChannelStatusSummary<TExtra extends object>(
|
||||||
lastProbeAt: snapshot.lastProbeAt ?? null,
|
lastProbeAt: snapshot.lastProbeAt ?? null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildTrafficStatusSummary<TSnapshot extends TrafficStatusSnapshot>(
|
||||||
|
snapshot?: TSnapshot | null,
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
lastInboundAt: snapshot?.lastInboundAt ?? null,
|
||||||
|
lastOutboundAt: snapshot?.lastOutboundAt ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
export function createDeferred<T>() {
|
||||||
|
let resolve!: (value: T | PromiseLike<T>) => void;
|
||||||
|
let reject!: (reason?: unknown) => void;
|
||||||
|
const promise = new Promise<T>((res, rej) => {
|
||||||
|
resolve = res;
|
||||||
|
reject = rej;
|
||||||
|
});
|
||||||
|
return { promise, resolve, reject };
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,7 @@ import {
|
||||||
summarizeMapping,
|
summarizeMapping,
|
||||||
warnMissingProviderGroupPolicyFallbackOnce,
|
warnMissingProviderGroupPolicyFallbackOnce,
|
||||||
} from "openclaw/plugin-sdk/zalouser";
|
} from "openclaw/plugin-sdk/zalouser";
|
||||||
|
import { createDeferred } from "../../shared/deferred.js";
|
||||||
import {
|
import {
|
||||||
buildZalouserGroupCandidates,
|
buildZalouserGroupCandidates,
|
||||||
findZalouserGroupEntry,
|
findZalouserGroupEntry,
|
||||||
|
|
@ -129,16 +130,6 @@ function resolveInboundQueueKey(message: ZaloInboundMessage): string {
|
||||||
return `direct:${senderId || threadId}`;
|
return `direct:${senderId || threadId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDeferred<T>() {
|
|
||||||
let resolve!: (value: T | PromiseLike<T>) => void;
|
|
||||||
let reject!: (reason?: unknown) => void;
|
|
||||||
const promise = new Promise<T>((res, rej) => {
|
|
||||||
resolve = res;
|
|
||||||
reject = rej;
|
|
||||||
});
|
|
||||||
return { promise, resolve, reject };
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveZalouserDmSessionScope(config: OpenClawConfig) {
|
function resolveZalouserDmSessionScope(config: OpenClawConfig) {
|
||||||
const configured = config.session?.dmScope;
|
const configured = config.session?.dmScope;
|
||||||
return configured === "main" || !configured ? "per-channel-peer" : configured;
|
return configured === "main" || !configured ? "per-channel-peer" : configured;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue