Conversation
commit: |
| /** | ||
| * Create a new {@link Api}. This is the constructor behind | ||
| * middleware decoration used through core such as with {@link Scope#around}. | ||
| * One may implement an API for any operation to |
There was a problem hiding this comment.
This sentence currently reads as truncated, so the constructor's purpose is less clear than the example below it.
| * One may implement an API for any operation to | |
| * One may implement an API around any operation or value and then decorate it per-scope. |
| * @example | ||
| * ```ts | ||
| * import { createContext, main } from "effection"; | ||
| * | ||
| * let YourContext = createContext<string>("context-id"); | ||
| * | ||
| * await main(function* () { | ||
| * let scope = yield* useScope(); | ||
| * scope.set(YourContext, "abc-123"); | ||
| * | ||
| * // loop through operations and run each within child scope | ||
| * // where the arbitrary operations need access to the context value. | ||
| * for (let operation of operations) { | ||
| * yield* scope.run(function*() { | ||
| * const value = yield* YourContext.expect(); // "abc-123" | ||
| * // or set a different value for children of this scope | ||
| * YourContext.set("def-456"); | ||
| * }); | ||
| * } | ||
| * }); | ||
| * ``` |
There was a problem hiding this comment.
This second example is hard to follow as written because it uses useScope() without importing it, references operations without defining it, and calls YourContext.set() without yield*. I think a smaller, self-contained example would make the distinction between scope.set() and Context.expect() much clearer.
| * @example | |
| * ```ts | |
| * import { createContext, main } from "effection"; | |
| * | |
| * let YourContext = createContext<string>("context-id"); | |
| * | |
| * await main(function* () { | |
| * let scope = yield* useScope(); | |
| * scope.set(YourContext, "abc-123"); | |
| * | |
| * // loop through operations and run each within child scope | |
| * // where the arbitrary operations need access to the context value. | |
| * for (let operation of operations) { | |
| * yield* scope.run(function*() { | |
| * const value = yield* YourContext.expect(); // "abc-123" | |
| * // or set a different value for children of this scope | |
| * YourContext.set("def-456"); | |
| * }); | |
| * } | |
| * }); | |
| * ``` | |
| * @example | |
| * ```ts | |
| * import { createContext, main, useScope } from "effection"; | |
| * | |
| * let YourContext = createContext<string>("context-id"); | |
| * | |
| * await main(function* () { | |
| * let scope = yield* useScope(); | |
| * scope.set(YourContext, "abc-123"); | |
| * | |
| * console.log(scope.get(YourContext)); // "abc-123" | |
| * console.log(yield* YourContext.expect()); // "abc-123" | |
| * | |
| * yield* YourContext.set("def-456"); | |
| * console.log(yield* YourContext.expect()); // "def-456" | |
| * }); | |
| * ``` |
| * | ||
| * @example | ||
| * ```ts | ||
| * import { createApi, type Operation } from "effection"; |
There was a problem hiding this comment.
This example imports createApi from the main entrypoint, but in this PR it is exported from effection/experimental. Adjusting the import will keep the example consistent with the actual public surface.
| * import { createApi, type Operation } from "effection"; | |
| * import { type Operation } from "effection"; | |
| * import { createApi } from "effection/experimental"; |
| * import type { Operation } from "effection"; | ||
| * | ||
| * function* DbMiddleware<[string], Operation<{ id: number; title: string }[]>>(args, next) { | ||
| * let [sql] = args; | ||
| * let start = Date.now(); | ||
| * try { | ||
| * return yield* next(...args); | ||
| * } finally { | ||
| * console.log("query ms", Date.now() - start, sql); | ||
| * } | ||
| * }; |
There was a problem hiding this comment.
This example currently isn't valid TypeScript, so it's likely to confuse readers trying to understand the Middleware shape. Suggest expressing it as a typed value instead.
| * import type { Operation } from "effection"; | |
| * | |
| * function* DbMiddleware<[string], Operation<{ id: number; title: string }[]>>(args, next) { | |
| * let [sql] = args; | |
| * let start = Date.now(); | |
| * try { | |
| * return yield* next(...args); | |
| * } finally { | |
| * console.log("query ms", Date.now() - start, sql); | |
| * } | |
| * }; | |
| * import type { Middleware, Operation } from "effection"; | |
| * | |
| * let dbMiddleware: Middleware< | |
| * [string], | |
| * Operation<{ id: number; title: string }[]> | |
| * > = function* (args, next) { | |
| * let [sql] = args; | |
| * let start = Date.now(); | |
| * try { | |
| * return yield* next(...args); | |
| * } finally { | |
| * console.log("query ms", Date.now() - start, sql); | |
| * } | |
| * }; |
| * }); | ||
| * } | ||
| * | ||
| * console.log(yield* useValue); // 42 |
There was a problem hiding this comment.
This example forgets to call useValue(), which makes the consumption pattern look different from how resource() is actually used.
| * console.log(yield* useValue); // 42 | |
| * console.log(yield* useValue()); // 42 |
Motivation
Filling out the JSDocs a bit more. These show up both on the website, but also in IDEs.
Closes #1139.
Approach
Fix a few broken bits, and add more examples.