interface resolver {
    use error.{error};
    use schema.{definition-id, directive};
    use resolver-types.{response, field-id, field, arguments-id, subscription-item};
    use headers.{headers};
    use context.{authorized-operation-context};
    use event-queue.{event-queue};

    prepare: func(
        event-queue: event-queue,
        subgraph-name: string,
        directive: directive,
        root-field-id: field-id,
        fields: list<field>,
    ) -> result<list<u8>, error>;

    resolve: func(
        event-queue: event-queue,
        context: authorized-operation-context,
        prepared: list<u8>,
        headers: headers,
        arguments: list<tuple<arguments-id, list<u8>>>
    ) -> response;

    create-subscription: func(
        event-queue: event-queue,
        context: authorized-operation-context,
        prepared: list<u8>,
        headers: headers,
        arguments: list<tuple<arguments-id, list<u8>>>
    ) -> result<option<list<u8>>, error>;

    // resolves the next item in a subscription stream. Must be called after resolve-subscription
    // If data is null, it means the subscription is done and no more items will be requested.
    resolve-next-subscription-item: func() -> result<option<subscription-item>, error>;

    // Called if the key provided by resolve-subscription is enough and any stored state can be dropped.
    // This implies resolve-next-subscription-item will never be called.
    drop-subscription: func();
}
