···11+const CHANNEL = Symbol.for('moroutine.channel');
22+33+export interface ChannelOptions {
44+ highWaterMark?: number;
55+}
66+77+export interface ChannelMarker<T> {
88+ readonly [CHANNEL]: {
99+ iterable: AsyncIterable<T>;
1010+ options?: ChannelOptions;
1111+ };
1212+}
1313+1414+/**
1515+ * Wraps an AsyncIterable for streaming to a worker.
1616+ * @param iterable - The async iterable to pipe to the worker.
1717+ * @param opts - Optional. highWaterMark controls backpressure buffering (default: 16).
1818+ * @returns The iterable, typed as AsyncIterable<T> for transparent moroutine arg use.
1919+ */
2020+export function channel<T>(iterable: AsyncIterable<T>, opts?: ChannelOptions): AsyncIterable<T> {
2121+ return { [CHANNEL]: { iterable, options: opts } } as unknown as AsyncIterable<T>;
2222+}
2323+2424+export { CHANNEL };
+5-5
src/execute.ts
···77import { Task } from './task.ts';
88import { StreamTask } from './stream-task.ts';
99import { runStreamOnDedicated } from './dedicated-runner.ts';
1010-import { STREAM } from './stream.ts';
1111-import type { StreamOptions } from './stream.ts';
1010+import { CHANNEL } from './channel.ts';
1111+import type { ChannelOptions } from './channel.ts';
12121313let nextCallId = 0;
1414const pending = new Map<number, { resolve: (value: any) => void; reject: (reason: any) => void }>();
···7171}
72727373function prepareArg(arg: unknown): unknown {
7474- if (typeof arg === 'object' && arg !== null && STREAM in arg) {
7575- const data = (arg as any)[STREAM];
7474+ if (typeof arg === 'object' && arg !== null && CHANNEL in arg) {
7575+ const data = (arg as any)[CHANNEL];
7676 let iterable = data.iterable;
7777 const highWater = data.options?.highWaterMark ?? DEFAULT_HIGH_WATER;
7878···110110 });
111111}
112112113113-export function dispatchStream<T>(worker: Worker, id: string, args: unknown[], opts?: StreamOptions): AsyncIterable<T> {
113113+export function dispatchStream<T>(worker: Worker, id: string, args: unknown[], opts?: ChannelOptions): AsyncIterable<T> {
114114 const url = id.slice(0, id.lastIndexOf('#'));
115115 freezeModule(url);
116116 const highWater = opts?.highWaterMark ?? DEFAULT_HIGH_WATER;
+2-2
src/index.ts
···22export type { Arg } from './mo.ts';
33export { Task } from './task.ts';
44export { StreamTask } from './stream-task.ts';
55-export { stream } from './stream.ts';
66-export type { StreamOptions } from './stream.ts';
55+export { channel } from './channel.ts';
66+export type { ChannelOptions } from './channel.ts';
77export { workers } from './worker-pool.ts';
88export { transfer } from './transfer.ts';
99export type { Runner } from './runner.ts';
+2-2
src/runner.ts
···11import type { Task } from './task.ts';
22import type { StreamTask } from './stream-task.ts';
33-import type { StreamOptions } from './stream.ts';
33+import type { ChannelOptions } from './channel.ts';
4455type TaskResults<T extends Task<any>[]> = { [K in keyof T]: T[K] extends Task<infer R> ? R : never };
66···88export type Runner = {
99 <T>(task: Task<T>): Promise<T>;
1010 <T extends Task<any>[]>(tasks: [...T]): Promise<TaskResults<T>>;
1111- <T>(task: StreamTask<T>, opts?: StreamOptions): AsyncIterable<T>;
1111+ <T>(task: StreamTask<T>, opts?: ChannelOptions): AsyncIterable<T>;
1212 [Symbol.dispose](): void;
1313};
-24
src/stream.ts
···11-const STREAM = Symbol.for('moroutine.stream');
22-33-export interface StreamOptions {
44- highWaterMark?: number;
55-}
66-77-export interface StreamMarker<T> {
88- readonly [STREAM]: {
99- iterable: AsyncIterable<T>;
1010- options?: StreamOptions;
1111- };
1212-}
1313-1414-/**
1515- * Wraps an AsyncIterable for streaming to a worker.
1616- * @param iterable - The async iterable to pipe to the worker.
1717- * @param opts - Optional. highWaterMark controls backpressure buffering (default: 16).
1818- * @returns The iterable, typed as AsyncIterable<T> for transparent moroutine arg use.
1919- */
2020-export function stream<T>(iterable: AsyncIterable<T>, opts?: StreamOptions): AsyncIterable<T> {
2121- return { [STREAM]: { iterable, options: opts } } as unknown as AsyncIterable<T>;
2222-}
2323-2424-export { STREAM };
+2-2
src/worker-pool.ts
···33import { setupWorker, execute, dispatchStream } from './execute.ts';
44import type { Task } from './task.ts';
55import { StreamTask } from './stream-task.ts';
66-import type { StreamOptions } from './stream.ts';
66+import type { ChannelOptions } from './channel.ts';
77import type { Runner } from './runner.ts';
8899const workerEntryUrl = new URL('./worker-entry.ts', import.meta.url);
···3333 }
34343535 const run: Runner = Object.assign(
3636- (taskOrTasks: Task<any> | Task<any>[] | StreamTask<any>, opts?: StreamOptions): any => {
3636+ (taskOrTasks: Task<any> | Task<any>[] | StreamTask<any>, opts?: ChannelOptions): any => {
3737 if (taskOrTasks instanceof StreamTask) {
3838 if (disposed) throw new Error('Worker pool is disposed');
3939 const worker = pool[next % pool.length];