import { withExponentialBackoff } from "../util/retry.js";
/**
 * Wraps a local or remote state store implementation
 * and handles serialization/deserialization.
 */
export class StateStoreProxy {
    scope;
    dispatch;
    constructor(scope) {
        this.scope = scope;
    }
    async run(method, params) {
        this.dispatch ??= this.provision();
        return this.dispatch.then(async (dispatch) => {
            const result = await withExponentialBackoff(() => dispatch(method, params), () => true);
            return result;
        });
    }
    init() {
        return this.run("init", []);
    }
    deinit() {
        return this.run("deinit", []);
    }
    list() {
        return this.run("list", []);
    }
    listScopes() {
        return this.run("listScopes", []);
    }
    count() {
        return this.run("count", []);
    }
    async get(key) {
        const result = await this.run("get", [key]);
        if (result === undefined) {
            return undefined;
        }
        return await this.deserialize(result);
    }
    async getBatch(ids) {
        return this.deserializeMany(await this.run("getBatch", [ids]));
    }
    async all() {
        return this.deserializeMany(await this.run("all", []));
    }
    async set(key, value) {
        return this.run("set", [key, await this.serialize(value)]);
    }
    async delete(key) {
        return this.run("delete", [key]);
    }
    async deserialize(state) {
        const { deserialize } = await import("../serde.js"); // dynamic import to avoid circular dependency
        return await deserialize(this.scope, state);
    }
    async serialize(state) {
        const { serialize } = await import("../serde.js");
        return await serialize(this.scope, state);
    }
    async deserializeMany(states) {
        return Object.fromEntries(await Promise.all(Object.entries(states).map(async ([key, value]) => [
            key,
            await this.deserialize(value),
        ])));
    }
}
//# sourceMappingURL=proxy.js.map