diff --git a/packages/async-flow/src/async-flow.js b/packages/async-flow/src/async-flow.js index 7993531e37d0..137b2a53f352 100644 --- a/packages/async-flow/src/async-flow.js +++ b/packages/async-flow/src/async-flow.js @@ -13,7 +13,7 @@ import { LogEntryShape, FlowStateShape } from './type-guards.js'; /** * @import {WeakMapStore} from '@agoric/store' * @import {Zone} from '@agoric/base-zone' - * @import {FlowState, GuestAsyncFunc, HostAsyncFuncWrapper, PreparationOptions} from '../src/types.js' + * @import {FlowState, GuestAsyncFunc, HostAsyncFuncWrapper, HostOf, PreparationOptions} from '../src/types.js' * @import {ReplayMembrane} from '../src/replay-membrane.js' */ @@ -434,11 +434,12 @@ export const prepareAsyncFlowTools = (outerZone, outerOptions = {}) => { }; /** + * @template {GuestAsyncFunc} F * @param {Zone} zone * @param {string} tag - * @param {GuestAsyncFunc} guestFunc + * @param {F} guestFunc * @param {{ startEager?: boolean }} [options] - * @returns {HostAsyncFuncWrapper} + * @returns {HostOf} */ const asyncFlow = (zone, tag, guestFunc, options = undefined) => { const makeAsyncFlowKit = prepareAsyncFlowKit(zone, tag, guestFunc, options); @@ -452,6 +453,7 @@ export const prepareAsyncFlowTools = (outerZone, outerOptions = {}) => { defineProperties(wrapperFunc, { length: { value: guestFunc.length }, }); + // @ts-expect-error cast return harden(wrapperFunc); }; diff --git a/packages/async-flow/src/types.d.ts b/packages/async-flow/src/types.d.ts index 95b2b6f6a6e6..77ec495194e7 100644 --- a/packages/async-flow/src/types.d.ts +++ b/packages/async-flow/src/types.d.ts @@ -51,6 +51,13 @@ type HostInterface = { [K in keyof T]: HostOf; }; +/** + * Convert an entire Host interface into what the Guest will receive. + */ +type GuestInterface = { + [K in keyof T]: GuestOf; +}; + /** * The function the host must provide to match an interface the guest expects. * @@ -60,6 +67,8 @@ export type HostOf = F extends (...args: infer A) => Promise ? (...args: A) => Vow> : F; +export type HostArgs = { [K in keyof GA]: HostOf }; + export type PreparationOptions = { vowTools?: VowTools; makeLogStore?: (() => LogStore) | undefined; diff --git a/packages/orchestration/src/examples/basic-flows.contract.js b/packages/orchestration/src/examples/basic-flows.contract.js index 2404b42da026..ed0762bcd50f 100644 --- a/packages/orchestration/src/examples/basic-flows.contract.js +++ b/packages/orchestration/src/examples/basic-flows.contract.js @@ -10,7 +10,6 @@ import { provideOrchestration } from '../utils/start-helper.js'; * @import {Baggage} from '@agoric/vat-data'; * @import {Orchestrator} from '@agoric/orchestration'; * @import {OrchestrationPowers} from '../utils/start-helper.js'; - * @import {ResolvedContinuingOfferResult} from '../utils/zoe-tools.js'; */ /** @@ -45,7 +44,6 @@ export const start = async (zcf, privateArgs, baggage) => { privateArgs.marshaller, ); - /** @type {OfferHandler>} */ const makeOrchAccount = orchestrate( 'makeOrchAccount', undefined, diff --git a/packages/orchestration/src/examples/swapExample.contract.js b/packages/orchestration/src/examples/swapExample.contract.js index a7d4bb806b12..1415d3b23e9e 100644 --- a/packages/orchestration/src/examples/swapExample.contract.js +++ b/packages/orchestration/src/examples/swapExample.contract.js @@ -5,7 +5,6 @@ import { orcUtils } from '../utils/orc.js'; import { withOrchestration } from '../utils/start-helper.js'; /** - * @import {GuestInterface, GuestOf} from '@agoric/async-flow'; * @import {LocalTransfer} from '../utils/zoe-tools.js'; * @import {Orchestrator, CosmosValidatorAddress} from '../types.js' * @import {TimerService} from '@agoric/time'; @@ -102,12 +101,6 @@ const contract = async (zcf, privateArgs, zone, { orchestrate, zoeTools }) => { const { brands } = zcf.getTerms(); /** deprecated historical example */ - /** - * @type {OfferHandler< - * unknown, - * { staked: Amount<'nat'>; validator: CosmosValidatorAddress } - * >} - */ const swapAndStakeHandler = orchestrate( 'LSTTia', { zcf, localTransfer: zoeTools.localTransfer }, diff --git a/packages/orchestration/src/examples/unbondExample.contract.js b/packages/orchestration/src/examples/unbondExample.contract.js index 0b0beac9bf32..17efa3af2be5 100644 --- a/packages/orchestration/src/examples/unbondExample.contract.js +++ b/packages/orchestration/src/examples/unbondExample.contract.js @@ -4,7 +4,6 @@ import { withOrchestration } from '../utils/start-helper.js'; /** * @import {Orchestrator, IcaAccount, CosmosValidatorAddress} from '../types.js' * @import {TimerService} from '@agoric/time'; - * @import {Baggage} from '@agoric/vat-data'; * @import {LocalChain} from '@agoric/vats/src/localchain.js'; * @import {NameHub} from '@agoric/vats'; * @import {Remote} from '@agoric/internal'; @@ -59,7 +58,6 @@ const unbondAndLiquidStakeFn = async (orch, { zcf }, _seat, _offerArgs) => { * @param {OrchestrationTools} tools */ const contract = async (zcf, privateArgs, zone, { orchestrate }) => { - /** @type {OfferHandler} */ const unbondAndLiquidStake = orchestrate( 'LSTTia', { zcf }, diff --git a/packages/orchestration/src/facade.js b/packages/orchestration/src/facade.js index ae6b4cf007a9..8229c3583318 100644 --- a/packages/orchestration/src/facade.js +++ b/packages/orchestration/src/facade.js @@ -3,7 +3,7 @@ import { assertAllDefined } from '@agoric/internal'; /** - * @import {AsyncFlowTools} from '@agoric/async-flow'; + * @import {AsyncFlowTools, GuestInterface, HostArgs} from '@agoric/async-flow'; * @import {Zone} from '@agoric/zone'; * @import {Vow, VowTools} from '@agoric/vow'; * @import {TimerService} from '@agoric/time'; @@ -55,24 +55,18 @@ export const makeOrchestrationFacade = ({ const { when } = vowTools; /** - * @template GuestReturn - * @template HostReturn - * @template GuestContext - * @template HostContext - * @template {any[]} GuestArgs - * @template {any[]} HostArgs + * @template RT - return type + * @template HC - host context + * @template {any[]} GA - guest args * @param {string} durableName - the orchestration flow identity in the zone * (to resume across upgrades) - * @param {HostContext} hostCtx - values to pass through the async flow - * membrane + * @param {HC} hostCtx - values to pass through the async flow membrane * @param {( * guestOrc: Orchestrator, - * guestCtx: GuestContext, - * ...args: GuestArgs - * ) => Promise} guestFn - * @returns {(...args: HostArgs) => Promise} TODO returns a - * Promise for now for compat before use of asyncFlow. But really should be - * `Vow` + * guestCtx: GuestInterface, + * ...args: GA + * ) => Promise} guestFn + * @returns {(...args: HostArgs) => Promise} */ const orchestrate = (durableName, hostCtx, guestFn) => { const subZone = zone.subZone(durableName); @@ -89,7 +83,10 @@ export const makeOrchestrationFacade = ({ const orcFn = (...args) => // TODO remove the `when` after fixing the return type // to `Vow` + // @ts-expect-error cast when(hostFn(wrappedOrc, wrappedCtx, ...args)); + + // @ts-expect-error cast return harden(orcFn); };