import { DestroyedSignal } from "./destroy.js";
import { ResourceFQN, ResourceID, ResourceKind, ResourceScope, ResourceSeq, } from "./resource.js";
export function context({ scope, phase, kind, id, fqn, seq, state, replace, props, isReplacement = false, }) {
    function create(...args) {
        const [ID, props] = typeof args[0] === "string" ? args : [id, args[0]];
        return {
            ...props,
            [ResourceKind]: kind,
            [ResourceID]: ID,
            [ResourceFQN]: fqn,
            [ResourceScope]: scope,
            [ResourceSeq]: seq,
        };
    }
    return Object.assign(create, {
        stage: scope.stage,
        scope,
        id: id,
        fqn: fqn,
        phase,
        output: state.output,
        props,
        replace,
        isReplacement,
        get: (key) => state.data[key],
        set: async (key, value) => {
            state.data[key] = value;
        },
        delete: async (key) => {
            const value = state.data[key];
            delete state.data[key];
            return value;
        },
        quiet: scope.quiet,
        destroy: (retainChildren = false) => {
            throw new DestroyedSignal(retainChildren);
        },
        onCleanup: (fn) => {
            // make the function idempotent so repeated calls don't cause the process to hang
            let promise;
            scope.root.onCleanup(async () => {
                promise ??= Promise.resolve(fn());
                await promise;
            });
        },
        create,
    });
}
//# sourceMappingURL=context.js.map