Skip to content

fill out JSDocs with examples#1141

Open
jbolda wants to merge 2 commits intov4-1-alphafrom
jsdoc-examples
Open

fill out JSDocs with examples#1141
jbolda wants to merge 2 commits intov4-1-alphafrom
jsdoc-examples

Conversation

@jbolda
Copy link
Member

@jbolda jbolda commented Mar 18, 2026

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.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 18, 2026

Open in StackBlitz

npm i https://pkg.pr.new/effection@1141

commit: bee3aac

/**
* 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence currently reads as truncated, so the constructor's purpose is less clear than the example below it.

Suggested change
* 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.

Comment on lines +21 to +41
* @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");
* });
* }
* });
* ```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
* @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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
* import { createApi, type Operation } from "effection";
* import { type Operation } from "effection";
* import { createApi } from "effection/experimental";

Comment on lines +469 to +479
* 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);
* }
* };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
* 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example forgets to call useValue(), which makes the consumption pattern look different from how resource() is actually used.

Suggested change
* console.log(yield* useValue); // 42
* console.log(yield* useValue()); // 42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants