pure-effect 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -194,6 +194,9 @@ export declare function Command<R, T = R, E = unknown, Ctx = unknown>(
194
194
  /** The name a Command is known by in traces, replays and spans: `meta.name`, else `cmd.name`, else `'anonymous'`. */
195
195
  export declare function commandName(command: CommandState<any, any, any, any>): string;
196
196
 
197
+ /** Reads the context passed to `runEffect`. With no argument it succeeds with the context; name its type as `Ask<AppCtx>()`. */
198
+ export declare function Ask<Ctx = unknown>(): AskState<Ctx, never, Ctx>;
199
+
197
200
  /** Reads the context passed to `runEffect`. Give the value, error and context types, or none. */
198
201
  export declare function Ask<T = never, E = never, Ctx = unknown, N extends AnyEffect = Effect<T, E, Ctx>>(
199
202
  next: (context: Ctx) => N
@@ -1245,6 +1248,53 @@ export declare function effectPipe<
1245
1248
  >;
1246
1249
  // END effectPipe overloads.
1247
1250
 
1251
+ // The symbol and the iterator's yield type exist only in the declarations, never at runtime: together they are how
1252
+ // `effectGen` reads each step's Effect type out of the body's yield type.
1253
+ declare const stepEffect: unique symbol;
1254
+ declare const stepContext: unique symbol;
1255
+
1256
+ /** A step for `yield*` inside `effectGen`, which gives back the Effect's value. Using it any other way throws. */
1257
+ // The context is also a function parameter, which TypeScript compares the opposite way to the Effect, so of two steps
1258
+ // it merges in a generator's yield type it can only drop the one that reads less context.
1259
+ export type Step<X extends AnyEffect, C = EffectContext<X>> = {
1260
+ readonly [stepEffect]?: X;
1261
+ readonly [stepContext]?: (context: C) => void;
1262
+ [Symbol.iterator](): Generator<Step<X, C>, EffectValue<X>, unknown>;
1263
+ };
1264
+
1265
+ /** Wraps an Effect for `yield*` inside `effectGen`: `const user = yield* step(findUser(email))`. */
1266
+ export declare function step<X extends AnyEffect>(effect: X): Step<X>;
1267
+
1268
+ type StepEffectOf<Y> = Y extends Step<infer X, any> ? X : never;
1269
+ // An `any` return would match both branches and turn the error union into `any`, so it counts as a plain value.
1270
+ type GenIsAny<R> = 0 extends 1 & R ? true : false;
1271
+ type ReturnedEffect<R> = GenIsAny<R> extends true ? never : R extends AnyEffect ? R : never;
1272
+ type GenValue<R> = GenIsAny<R> extends true ? any : R extends AnyEffect ? EffectValue<R> : R;
1273
+ type GenError<Y, R> = EffectError<StepEffectOf<Y>> | EffectError<ReturnedEffect<R>>;
1274
+ // A step that reads no context gives `unknown`, which would erase the others in an intersection, so it is dropped. Each
1275
+ // context is boxed, so one that is itself a union is intersected whole rather than member by member.
1276
+ type GenNeeds<X> = X extends AnyEffect
1277
+ ? EffectContext<X> extends infer C
1278
+ ? unknown extends C
1279
+ ? never
1280
+ : { context: C }
1281
+ : never
1282
+ : never;
1283
+ type GenIntersection<U> = (U extends any ? (u: U) => void : never) extends (i: infer I) => void ? I : never;
1284
+ type GenContext<Y, R> = [GenNeeds<StepEffectOf<Y> | ReturnedEffect<R>>] extends [never]
1285
+ ? unknown
1286
+ : GenIntersection<GenNeeds<StepEffectOf<Y> | ReturnedEffect<R>>> extends { context: infer C }
1287
+ ? C
1288
+ : unknown;
1289
+
1290
+ /**
1291
+ * Builds a flow function from a generator function, written with `yield* step(effect)` where `async` code writes
1292
+ * `await`. A plain return value is a `Success`; return a `Failure` to stop.
1293
+ */
1294
+ export declare function effectGen<I, Y extends Step<any, any>, R>(
1295
+ body: (input: I) => Generator<Y, R, unknown>
1296
+ ): (input: I) => Effect<GenValue<R>, GenError<Y, R>, GenContext<Y, R>>;
1297
+
1248
1298
  /**
1249
1299
  * Wraps each Command, and each `Parallel`. Call `op` and return its result; a hook that calls another passes `path` on.
1250
1300
  */
@@ -1256,12 +1306,12 @@ export type StepRunner = (
1256
1306
  ) => Promise<unknown>;
1257
1307
 
1258
1308
  /**
1259
- * Which branch, if any, cancelled a `Parallel`, and how many branches it had; `branch: null` means an enclosing one
1260
- * did. A replay refuses a `Parallel` whose count differs, and a decision without one is not checked.
1309
+ * Which branch, if any, cancelled a `Parallel`, whether it threw, and how many branches it had; `branch: null` means an
1310
+ * enclosing one did. A replay refuses a `Parallel` whose count differs, and a decision without one is not checked.
1261
1311
  */
1262
1312
  export type ParallelDecision =
1263
1313
  | { cancelled: false; branches?: number | undefined }
1264
- | { cancelled: true; branch: number | null; branches?: number | undefined };
1314
+ | { cancelled: true; branch: number | null; branches?: number | undefined; threw?: true | undefined };
1265
1315
 
1266
1316
  /**
1267
1317
  * `flowName` is `context.flowName`, or `''` when the context has none. `initialInput` is what the flow was called with
@@ -1458,3 +1508,6 @@ export declare function timeTravel<T, E = unknown, Ctx = unknown>(
1458
1508
  version?: string | undefined;
1459
1509
  }
1460
1510
  ): Promise<SuccessState<T> | FailureState<E>>;
1511
+
1512
+ // Only the declarations marked `export` are public; without this, a declaration file exports every top-level one.
1513
+ export {};