{"version":3,"file":"index.mjs","names":["isSchedulerError","pureValue: T","promise: Promise<T>","effects: readonly Effect<unknown>[]"],"sources":["../src/scheduler/types.ts","../src/scheduler/async-scheduler.ts","../src/scheduler/effect.ts","../src/scheduler/sync-scheduler.ts"],"sourcesContent":["import type { Result } from \"neverthrow\";\n\n/**\n * Abstract base class for all effects.\n * Effects encapsulate both the data and the execution logic.\n *\n * @template TResult - The type of value this effect produces when executed\n *\n * @example\n * ```typescript\n * function* myGenerator() {\n *   const value = yield* new PureEffect(42).run();\n *   return value; // 42\n * }\n * ```\n */\nexport abstract class Effect<TResult = unknown> {\n  /**\n   * Execute the effect synchronously and return the result.\n   */\n  executeSync(): TResult {\n    return this._executeSync();\n  }\n\n  /**\n   * Execute the effect asynchronously and return the result.\n   */\n  async executeAsync(): Promise<TResult> {\n    return this._executeAsync();\n  }\n\n  /**\n   * Returns a generator that yields this effect and returns the result.\n   * Enables the `yield*` pattern for cleaner effect handling.\n   *\n   * @example\n   * ```typescript\n   * const value = yield* effect.run();\n   * ```\n   */\n  *run(): Generator<Effect<TResult>, TResult, EffectReturn> {\n    return EffectReturn.unwrap((yield this) as EffectReturn<TResult>);\n  }\n\n  /**\n   * Internal synchronous execution logic.\n   * Subclasses must implement this method.\n   */\n  protected abstract _executeSync(): TResult;\n\n  /**\n   * Internal asynchronous execution logic.\n   * Subclasses must implement this method.\n   */\n  protected abstract _executeAsync(): Promise<TResult>;\n}\n\nconst EFFECT_RETURN = Symbol(\"EffectReturn\");\nexport class EffectReturn<TResult = unknown> {\n  private readonly [EFFECT_RETURN]: TResult;\n\n  private constructor(value: TResult) {\n    this[EFFECT_RETURN] = value;\n  }\n\n  static wrap<TResult>(value: TResult): EffectReturn<TResult> {\n    return new EffectReturn(value);\n  }\n\n  static unwrap<TResult>(value: EffectReturn<TResult>): TResult {\n    return value[EFFECT_RETURN];\n  }\n}\n\n/**\n * Extract the result type from an Effect.\n */\nexport type EffectResult<E> = E extends Effect<infer T> ? T : never;\n\n/**\n * Generator type that yields Effects.\n */\nexport type EffectGenerator<TReturn> = Generator<Effect, TReturn, EffectReturn>;\n\n/**\n * Generator function type that creates an EffectGenerator.\n */\nexport type EffectGeneratorFn<TReturn> = () => EffectGenerator<TReturn>;\n\n/**\n * Error type for scheduler operations.\n */\nexport type SchedulerError = {\n  readonly kind: \"scheduler-error\";\n  readonly message: string;\n  readonly cause?: unknown;\n};\n\n/**\n * Create a SchedulerError.\n */\nexport const createSchedulerError = (message: string, cause?: unknown): SchedulerError => ({\n  kind: \"scheduler-error\",\n  message,\n  cause,\n});\n\n/**\n * Synchronous scheduler interface.\n * Throws if an async-only effect (defer, yield) is encountered.\n */\nexport interface SyncScheduler {\n  run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError>;\n}\n\n/**\n * Asynchronous scheduler interface.\n * Handles all effect types including defer, yield, and parallel.\n */\nexport interface AsyncScheduler {\n  run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>>;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AsyncScheduler, Effect, EffectGeneratorFn, SchedulerError } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create an asynchronous scheduler.\n *\n * This scheduler can handle all effect types including defer and yield.\n * Parallel effects are executed concurrently using Promise.all.\n *\n * @returns An AsyncScheduler instance\n *\n * @example\n * const scheduler = createAsyncScheduler();\n * const result = await scheduler.run(function* () {\n *   const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n *   yield* new YieldEffect().run(); // Yield to event loop\n *   return data;\n * });\n */\nexport const createAsyncScheduler = (): AsyncScheduler => {\n  const run = async <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>> => {\n    try {\n      const generator = generatorFn();\n      let result = generator.next();\n\n      while (!result.done) {\n        const effect = result.value as Effect<unknown>;\n        const effectResult = await effect.executeAsync();\n        result = generator.next(EffectReturn.wrap(effectResult));\n      }\n\n      return ok(result.value);\n    } catch (error) {\n      if (isSchedulerError(error)) {\n        return err(error);\n      }\n      return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n    }\n  };\n\n  return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n  return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n","import { Effect } from \"./types\";\n\n/**\n * Pure effect - returns a value immediately.\n * Works in both sync and async schedulers.\n *\n * @example\n * const result = yield* new PureEffect(42).run(); // 42\n */\nexport class PureEffect<T> extends Effect<T> {\n  constructor(readonly pureValue: T) {\n    super();\n  }\n\n  protected _executeSync(): T {\n    return this.pureValue;\n  }\n\n  protected _executeAsync(): Promise<T> {\n    return Promise.resolve(this.pureValue);\n  }\n}\n\n/**\n * Defer effect - wraps a Promise for async execution.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n */\nexport class DeferEffect<T> extends Effect<T> {\n  constructor(readonly promise: Promise<T>) {\n    super();\n  }\n\n  protected _executeSync(): T {\n    throw new Error(\"DeferEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n  }\n\n  protected _executeAsync(): Promise<T> {\n    return this.promise;\n  }\n}\n\n/**\n * Parallel effect - executes multiple effects concurrently.\n * In sync schedulers, effects are executed sequentially.\n * In async schedulers, effects are executed with Promise.all.\n *\n * @example\n * const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]\n */\nexport class ParallelEffect extends Effect<readonly unknown[]> {\n  constructor(readonly effects: readonly Effect<unknown>[]) {\n    super();\n  }\n\n  protected _executeSync(): readonly unknown[] {\n    return this.effects.map((e) => e.executeSync());\n  }\n\n  protected async _executeAsync(): Promise<readonly unknown[]> {\n    return Promise.all(this.effects.map((e) => e.executeAsync()));\n  }\n}\n\n/**\n * Yield effect - yields control back to the event loop.\n * This helps prevent blocking the event loop in long-running operations.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * for (let i = 0; i < 10000; i++) {\n *   doWork(i);\n *   if (i % 100 === 0) {\n *     yield* new YieldEffect().run();\n *   }\n * }\n */\nexport class YieldEffect extends Effect<void> {\n  protected _executeSync(): void {\n    throw new Error(\"YieldEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n  }\n\n  protected async _executeAsync(): Promise<void> {\n    await new Promise<void>((resolve) => {\n      if (typeof setImmediate !== \"undefined\") {\n        setImmediate(resolve);\n      } else {\n        setTimeout(resolve, 0);\n      }\n    });\n  }\n}\n\n/**\n * Effect factory namespace for convenience.\n * Provides static methods to create effects.\n */\nexport const Effects = {\n  /**\n   * Create a pure effect that returns a value immediately.\n   */\n  pure: <T>(value: T): PureEffect<T> => new PureEffect(value),\n\n  /**\n   * Create a defer effect that wraps a Promise.\n   */\n  defer: <T>(promise: Promise<T>): DeferEffect<T> => new DeferEffect(promise),\n\n  /**\n   * Create a parallel effect that executes multiple effects concurrently.\n   */\n  parallel: (effects: readonly Effect<unknown>[]): ParallelEffect => new ParallelEffect(effects),\n\n  /**\n   * Create a yield effect that returns control to the event loop.\n   */\n  yield: (): YieldEffect => new YieldEffect(),\n} as const;\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { Effect, EffectGeneratorFn, SchedulerError, SyncScheduler } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create a synchronous scheduler.\n *\n * This scheduler executes generators synchronously.\n * It throws an error if an async-only effect (defer, yield) is encountered.\n *\n * @returns A SyncScheduler instance\n *\n * @example\n * const scheduler = createSyncScheduler();\n * const result = scheduler.run(function* () {\n *   const a = yield* new PureEffect(1).run();\n *   const b = yield* new PureEffect(2).run();\n *   return a + b;\n * });\n * // result = ok(3)\n */\nexport const createSyncScheduler = (): SyncScheduler => {\n  const run = <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError> => {\n    try {\n      const generator = generatorFn();\n      let result = generator.next();\n\n      while (!result.done) {\n        const effect = result.value as Effect<unknown>;\n        const effectResult = effect.executeSync();\n        result = generator.next(EffectReturn.wrap(effectResult));\n      }\n\n      return ok(result.value);\n    } catch (error) {\n      if (isSchedulerError(error)) {\n        return err(error);\n      }\n      return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n    }\n  };\n\n  return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n  return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n"],"mappings":"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"}