{"version":3,"sources":["../src/messagePortRPC.ts","../src/forGenerator.ts"],"sourcesContent":["// Naming is from https://www.w3.org/History/1992/nfs_dxcern_mirror/rpc/doc/Introduction/HowItWorks.html.\n\nimport { type ReturnValueOfPromise } from './private/types/ReturnValueOfPromise.ts';\n\nconst ABORT = 'ABORT';\nconst CALL = 'CALL';\nconst REJECT = 'REJECT';\nconst RESOLVE = 'RESOLVE';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Subroutine = (...args: any[]) => Promise<unknown> | unknown;\ntype RPCCallMessage<T extends Subroutine> = [typeof CALL, ...Parameters<T>];\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype RPCRejectMessage = [typeof REJECT, any];\ntype RPCResolveMessage<T extends Subroutine> = [typeof RESOLVE, ReturnValueOfPromise<ReturnType<T>>];\n\ntype CallInit = {\n  signal?: AbortSignal | undefined;\n  transfer?: readonly Transferable[] | undefined;\n};\n\n// Regardless whether T returns Promise or not, the client stub must return Promise.\ntype ClientStub<T extends Subroutine> = (...args: Parameters<T>) => Promise<ReturnValueOfPromise<ReturnType<T>>>;\n\ntype ClientStubWithExtra<T extends Subroutine> = ClientStub<T> & {\n  /**\n   * Creates a new stub with options.\n   *\n   * @param {AbortSignal} init.signal - Abort signal to abort the call to the stub.\n   * @param {Transferable[]} init.transfer - Transfer ownership of objects specified in `args`.\n   */\n  withOptions: (init: CallInit) => ClientStub<T>;\n};\n\ntype ServerStub<T extends Subroutine> = (this: { signal: AbortSignal }, ...args: Parameters<T>) => ReturnType<T>;\n\n/**\n * Binds a function to a `MessagePort` in RPC fashion and/or create a RPC function stub connected to a `MessagePort`.\n *\n * In a traditional RPC setting:\n *\n * - server should call this function with `fn` argument, the returned function should be ignored;\n * - client should call this function without `fn` argument, the returned function is the stub to call the server.\n *\n * This function supports bidirectional RPC when both sides are passing the `fn` argument.\n *\n * When calling the returned function stub, the arguments and return value are transferred over `MessagePort`.\n * Thus, they will be cloned by the underlying structured clone algorithm.\n *\n * The returned stub has a variant `withOptions` for passing transferables and abort signal.\n *\n * @param {MessagePort} port - The `MessagePort` object to send the calls. The underlying `MessageChannel` must be exclusively used by this function only.\n * @param {Function} fn - The function to invoke. If not set, this RPC cannot be invoked by the other side of `MessagePort`.\n *\n * @returns An asynchronous function, when called, will invoke the function on the other side of `MessagePort`.\n */\nexport default function messagePortRPC<C extends Subroutine>(port: MessagePort): ClientStubWithExtra<C>;\n\nexport default function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(\n  port: MessagePort,\n  fn: ServerStub<S>\n): ClientStubWithExtra<C>;\n\nexport default function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(\n  port: MessagePort,\n  fn: ServerStub<S>,\n  options: { signal: AbortSignal }\n): ClientStubWithExtra<C>;\n\nexport default function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(\n  port: MessagePort,\n  fn?: ServerStub<S>\n): ClientStubWithExtra<C> {\n  // We cannot neuter the input port because it would cause memory leak:\n  // - We can neuter a port by passing it through Structured Clone Algorithm so the input port will become non-functional\n  // - After a port is neutered, closing the neutered port will not close the cloned port\n  // - Thus, the port owner will no longer able to close the port\n  // - This defeated our philosophy: whoever pass a resources to a function, should own the resources unless it is intentional and no other workarounds\n\n  type ClientSubroutineParameters = Parameters<C>;\n  type ClientSubroutineReturnValue = ReturnValueOfPromise<ReturnType<C>>;\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const handleMessage = (event: MessageEvent<RPCCallMessage<S>>): void => {\n    const data = event.data as RPCCallMessage<S> | undefined;\n\n    if (Array.isArray(data) && data[0] === CALL) {\n      event.stopImmediatePropagation();\n\n      const [returnPort] = event.ports;\n\n      if (!returnPort) {\n        throw new Error('RPCCallMessage must contains a port.');\n      }\n\n      if (fn) {\n        (async function () {\n          const abortController = new AbortController();\n\n          try {\n            returnPort.onmessage = ({ data }) => Array.isArray(data) && data[0] === ABORT && abortController.abort();\n\n            returnPort.postMessage([\n              RESOLVE,\n              await fn.call({ signal: abortController.signal }, ...(data.slice(1) as Parameters<S>))\n            ]);\n          } catch (error) {\n            returnPort.postMessage([REJECT, error]);\n          } finally {\n            returnPort.close();\n          }\n        })();\n      } else {\n        returnPort.postMessage([\n          REJECT,\n          new Error(\n            'No function was registered on this RPC. This is probably calling a client which do not implement the function.'\n          )\n        ]);\n        returnPort.close();\n      }\n    }\n  };\n\n  port.addEventListener('message', handleMessage);\n  port.start();\n\n  const createWithOptions =\n    (init: CallInit): ((...args: ClientSubroutineParameters) => Promise<ClientSubroutineReturnValue>) =>\n    (...args) => {\n      return new Promise<ClientSubroutineReturnValue>((resolve, reject) => {\n        const { port1, port2 } = new MessageChannel();\n\n        port1.onmessage = event => {\n          const data = event.data as RPCRejectMessage | RPCResolveMessage<C>;\n\n          if (data[0] === RESOLVE) {\n            resolve(data[1]);\n          } else {\n            reject(data[1]);\n          }\n\n          port1.close();\n        };\n\n        init?.signal?.addEventListener('abort', () => {\n          port1.postMessage([ABORT]);\n          port1.close();\n\n          reject(new Error('Aborted.'));\n        });\n\n        port.postMessage([CALL, ...args] satisfies RPCCallMessage<C>, [port2, ...(init.transfer || [])]);\n      });\n    };\n\n  const stub = createWithOptions({}) as ClientStubWithExtra<C>;\n\n  stub.withOptions = createWithOptions;\n\n  return stub;\n}\n","// Naming is from https://www.w3.org/History/1992/nfs_dxcern_mirror/rpc/doc/Introduction/HowItWorks.html.\n\nimport messagePortRPC from './messagePortRPC.ts';\n\nconst GENERATE = 'GENERATOR_GENERATE';\n\n// type GeneratorSubroutine<TArgs extends unknown[] = any[], T = unknown, TReturn = any, TNext = unknown> = (\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype GeneratorSubroutine = (...args: any[]) => AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>;\ntype RPCGeneratorGenerateMessage<T extends GeneratorSubroutine> = [\n  typeof GENERATE,\n  Readonly<{\n    asyncDispose: MessagePort;\n    next: MessagePort;\n    return: MessagePort;\n    throw: MessagePort;\n  }>,\n  ...Parameters<T>\n];\n\ntype CallInit = {\n  signal?: AbortSignal;\n  transfer?: Transferable[];\n};\n\ntype NextOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> =\n  T extends AsyncGenerator<unknown, unknown, infer U> ? U : T extends Generator<unknown, unknown, infer V> ? V : never;\ntype ReturnOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> =\n  T extends AsyncGenerator<unknown, infer U> ? U : T extends Generator<unknown, infer V> ? V : never;\ntype YieldOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> =\n  T extends AsyncGenerator<infer U>\n    ? U\n    : T extends Generator<infer U>\n      ? U\n      : T extends AsyncIterator<infer U>\n        ? U\n        : T extends Iterator<infer U>\n          ? U\n          : never;\n\n// Regardless whether T returns Promise or not, the client stub must return Promise.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ClientGeneratorStub<T extends GeneratorSubroutine> = (\n  ...args: Parameters<T>\n) => AsyncGenerator<YieldOfGenerator<ReturnType<T>>, ReturnOfGenerator<ReturnType<T>>, NextOfGenerator<ReturnType<T>>>;\n\ntype ClientGeneratorStubWithExtra<T extends GeneratorSubroutine> = ClientGeneratorStub<T> & {\n  /**\n   * Creates a new stub with options.\n   *\n   * @param {AbortSignal} init.signal - Abort signal to abort the call to the stub.\n   * @param {Transferable[]} init.transfer - Transfer ownership of objects specified in `args`.\n   */\n  withOptions: (init: CallInit) => ClientGeneratorStub<T>;\n};\n\ntype ServerStub<T extends GeneratorSubroutine> = (...args: Parameters<T>) => ReturnType<T>;\n\n/**\n * Binds a generator function to a `MessagePort` in RPC fashion and/or create a RPC function stub connected to a `MessagePort`.\n *\n * In a traditional RPC setting:\n *\n * - server should call this generator function with `fn` argument, the returned function should be ignored;\n * - client should call this generator function without `fn` argument, the returned function is the stub to call the server.\n *\n * This function supports bidirectional RPC when both sides are passing the `fn` argument.\n *\n * When calling the returned function stub, the arguments and return value are transferred over `MessagePort`.\n * Thus, they will be cloned by the underlying structured clone algorithm.\n *\n * The returned stub has a variant `withOptions` for passing transferables and abort signal.\n *\n * Notes: if `next()` is used on the client stub and did not iterate until `{ done: true }`, caller must use the `withOptions({ signal: AbortSignal })`\n * to release resources.\n *\n * @param {MessagePort} port - The `MessagePort` object to send the calls. The underlying `MessageChannel` must be exclusively used by this function only.\n * @param {Function} fn - The generator function to invoke. If not set, this RPC cannot be invoked by the other side of `MessagePort`.\n *\n * @returns An asynchronous generator function, when called, will invoke the generator function on the other side of `MessagePort`.\n */\nexport default function forGenerator<C extends GeneratorSubroutine>(port: MessagePort): ClientGeneratorStubWithExtra<C>;\n\nexport default function forGenerator<C extends GeneratorSubroutine, S extends GeneratorSubroutine = C>(\n  port: MessagePort,\n  fn: ServerStub<S>\n): ClientGeneratorStubWithExtra<C>;\n\nexport default function forGenerator<C extends GeneratorSubroutine, S extends GeneratorSubroutine = C>(\n  port: MessagePort,\n  fn: ServerStub<S>,\n  options: { signal: AbortSignal }\n): ClientGeneratorStubWithExtra<C>;\n\nexport default function forGenerator<C extends GeneratorSubroutine, S extends GeneratorSubroutine = C>(\n  port: MessagePort,\n  fn?: ServerStub<S>\n): ClientGeneratorStubWithExtra<C> {\n  // We cannot neuter the input port because it would cause memory leak:\n  // - We can neuter a port by passing it through Structured Clone Algorithm so the input port will become non-functional\n  // - After a port is neutered, closing the neutered port will not close the cloned port\n  // - Thus, the port owner will no longer able to close the port\n  // - This defeated our philosophy: whoever pass a resources to a function, should own the resources unless it is intentional and no other workarounds\n\n  type ClientSubroutineParameters = Parameters<C>;\n  type ClientSubroutineYield = YieldOfGenerator<ReturnType<C>>;\n  type ClientSubroutineReturn = ReturnOfGenerator<ReturnType<C>>;\n  type ClientSubroutineNext = NextOfGenerator<ReturnType<C>>;\n  type ClientSubroutineIteratorResult = IteratorResult<ClientSubroutineYield, ClientSubroutineReturn>;\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const handleMessage = (event: MessageEvent<RPCGeneratorGenerateMessage<S>>): void => {\n    const data = event.data as RPCGeneratorGenerateMessage<S> | undefined;\n\n    if (Array.isArray(data) && data[0] === GENERATE) {\n      event.stopImmediatePropagation();\n\n      if (!fn) {\n        throw new Error(\n          'No function was registered on this RPC. This is probably calling a client which do not implement the function.'\n        );\n      }\n\n      const [_, messagePorts, ...args] = data;\n\n      const generator = fn(...args);\n\n      messagePortRPC(messagePorts.next, generator.next.bind(generator));\n\n      // This is a slight deviation from the actual `Iterator`.\n      // In the original approach, `Iterator.return` is not defined.\n      // In our approach, the client stub does not know if the server stub has `Iterator.return` defined or not, instead, we simply return `{ done: true }`.\n      messagePortRPC(messagePorts.return, value => generator.return?.(value) || { done: true });\n      messagePortRPC(messagePorts.throw, error => generator.throw?.(error) || Promise.reject(error));\n      messagePortRPC(messagePorts.asyncDispose, async (): Promise<void> => {\n        const symbolAsyncDispose: typeof Symbol.asyncDispose = Symbol.asyncDispose || Symbol.for('Symbol.asyncDispose');\n        const symbolDispose: typeof Symbol.dispose = Symbol.dispose || Symbol.for('Symbol.dispose');\n\n        symbolAsyncDispose in generator\n          ? await generator[symbolAsyncDispose]()\n          : symbolDispose in generator && generator[symbolDispose]();\n      });\n    }\n  };\n\n  port.addEventListener('message', handleMessage);\n  port.start();\n\n  const createWithOptions = (\n    init: CallInit\n  ): ((\n    ...args: ClientSubroutineParameters\n  ) => AsyncGenerator<ClientSubroutineYield, ClientSubroutineReturn, ClientSubroutineNext>) => {\n    let checkAborted: (() => void) | undefined;\n\n    return (...args: ClientSubroutineParameters) => {\n      const { port1: asyncDisposePort1, port2: asyncDisposePort2 } = new MessageChannel();\n      const { port1: nextPort1, port2: nextPort2 } = new MessageChannel();\n      const { port1: returnPort1, port2: returnPort2 } = new MessageChannel();\n      const { port1: throwPort1, port2: throwPort2 } = new MessageChannel();\n\n      const subInit = { signal: init.signal };\n\n      const closePorts = () => {\n        asyncDisposePort1.close();\n        asyncDisposePort2.close();\n        nextPort1.close();\n        nextPort2.close();\n        returnPort1.close();\n        returnPort2.close();\n        throwPort1.close();\n        throwPort2.close();\n      };\n\n      const asyncDisposeRPC = messagePortRPC<() => void>(asyncDisposePort1).withOptions(subInit);\n\n      const nextRPC =\n        messagePortRPC<(next: ClientSubroutineNext | void) => ClientSubroutineIteratorResult>(nextPort1).withOptions(\n          subInit\n        );\n\n      const returnRPC =\n        messagePortRPC<(returnValue: ClientSubroutineReturn) => ClientSubroutineIteratorResult>(\n          returnPort1\n        ).withOptions(subInit);\n\n      const throwRPC =\n        messagePortRPC<(error: unknown) => ClientSubroutineIteratorResult>(throwPort1).withOptions(subInit);\n\n      let finished = false;\n      const callGenerator = async (\n        fn: () => Promise<IteratorResult<ClientSubroutineYield, ClientSubroutineReturn>>\n      ): Promise<IteratorResult<ClientSubroutineYield, ClientSubroutineReturn>> => {\n        checkAborted?.();\n\n        // After the generator returned { done: true, value: any } once, all subsequent calls will be { done: true }.\n        if (finished) {\n          // It is okay to return without \"value\" property.\n          return { done: true } as IteratorResult<ClientSubroutineYield, ClientSubroutineReturn>;\n        }\n\n        const result = await fn();\n\n        if (result.done) {\n          finished = true;\n\n          closePorts();\n        }\n\n        return result;\n      };\n\n      const asyncDisposeGenerator = async (fn: () => Promise<void>): Promise<void> => {\n        checkAborted?.();\n\n        await fn();\n\n        finished = true;\n        closePorts();\n\n        checkAborted = () => {\n          throw new Error('This generator has been disposed.');\n        };\n      };\n\n      const generator: AsyncGenerator<ClientSubroutineYield, ClientSubroutineReturn, ClientSubroutineNext> = {\n        next: (value: NextOfGenerator<ReturnType<C>> | void) => callGenerator(() => nextRPC(value)),\n        return: (value: ReturnOfGenerator<ReturnType<C>>) => callGenerator(() => returnRPC(value)),\n        throw: (error: unknown) => callGenerator(() => throwRPC(error)),\n        // Ponyfills for Symbol.asyncDispose\n        [Symbol.asyncDispose || Symbol.for('Symbol.asyncDispose')]: () =>\n          asyncDisposeGenerator(() => asyncDisposeRPC()),\n        [Symbol.asyncIterator]: () => generator\n      };\n\n      port.postMessage(\n        [\n          GENERATE,\n          { asyncDispose: asyncDisposePort2, next: nextPort2, return: returnPort2, throw: throwPort2 },\n          ...args\n        ] satisfies RPCGeneratorGenerateMessage<C>,\n        [...(init.transfer || []), asyncDisposePort2, nextPort2, returnPort2, throwPort2]\n      );\n\n      init.signal?.addEventListener(\n        'abort',\n        () => {\n          checkAborted = () => {\n            throw new Error('This generator has been aborted.');\n          };\n\n          closePorts();\n        },\n        { once: true }\n      );\n\n      return generator;\n    };\n  };\n\n  const stub = createWithOptions({}) as ClientGeneratorStubWithExtra<C>;\n\n  stub.withOptions = createWithOptions;\n\n  return stub;\n}\n"],"mappings":"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","names":["data","fn"]}