@zeix/cause-effect 1.0.0 → 1.0.2

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.
Files changed (62) hide show
  1. package/.github/copilot-instructions.md +5 -1
  2. package/.zed/settings.json +24 -1
  3. package/ARCHITECTURE.md +27 -1
  4. package/CHANGELOG.md +21 -0
  5. package/CLAUDE.md +1 -1
  6. package/GUIDE.md +2 -5
  7. package/README.md +45 -3
  8. package/REQUIREMENTS.md +3 -3
  9. package/eslint.config.js +2 -1
  10. package/index.dev.js +14 -0
  11. package/index.js +1 -1
  12. package/index.ts +1 -1
  13. package/package.json +5 -4
  14. package/skills/cause-effect/SKILL.md +69 -0
  15. package/skills/cause-effect/agents/openai.yaml +4 -0
  16. package/skills/cause-effect/references/api-facts.md +179 -0
  17. package/skills/cause-effect/references/error-classes.md +153 -0
  18. package/skills/cause-effect/references/non-obvious-behaviors.md +195 -0
  19. package/skills/cause-effect/references/signal-types.md +292 -0
  20. package/skills/cause-effect/workflows/answer-question.md +54 -0
  21. package/skills/cause-effect/workflows/debug.md +71 -0
  22. package/skills/cause-effect/workflows/use-api.md +63 -0
  23. package/skills/cause-effect-dev/SKILL.md +61 -100
  24. package/skills/cause-effect-dev/references/api-facts.md +96 -0
  25. package/skills/cause-effect-dev/references/error-classes.md +97 -0
  26. package/skills/cause-effect-dev/references/internal-types.md +54 -0
  27. package/skills/cause-effect-dev/references/non-obvious-behaviors.md +162 -0
  28. package/skills/cause-effect-dev/references/source-map.md +45 -0
  29. package/skills/cause-effect-dev/workflows/answer-question.md +55 -0
  30. package/skills/cause-effect-dev/workflows/fix-bug.md +63 -0
  31. package/skills/cause-effect-dev/workflows/implement-feature.md +46 -0
  32. package/skills/cause-effect-dev/workflows/write-tests.md +64 -0
  33. package/skills/changelog-keeper/SKILL.md +47 -37
  34. package/skills/tech-writer/SKILL.md +94 -0
  35. package/skills/tech-writer/references/document-map.md +199 -0
  36. package/skills/tech-writer/references/tone-guide.md +189 -0
  37. package/skills/tech-writer/workflows/consistency-review.md +98 -0
  38. package/skills/tech-writer/workflows/update-after-change.md +65 -0
  39. package/skills/tech-writer/workflows/update-agent-docs.md +77 -0
  40. package/skills/tech-writer/workflows/update-architecture.md +61 -0
  41. package/skills/tech-writer/workflows/update-jsdoc.md +72 -0
  42. package/skills/tech-writer/workflows/update-public-api.md +59 -0
  43. package/skills/tech-writer/workflows/update-requirements.md +80 -0
  44. package/src/graph.ts +2 -0
  45. package/src/nodes/collection.ts +38 -0
  46. package/src/nodes/effect.ts +13 -1
  47. package/src/nodes/list.ts +41 -2
  48. package/src/nodes/memo.ts +0 -1
  49. package/src/nodes/sensor.ts +10 -4
  50. package/src/nodes/store.ts +11 -0
  51. package/src/signal.ts +6 -0
  52. package/test/list.test.ts +121 -0
  53. package/tsconfig.json +9 -0
  54. package/types/index.d.ts +1 -1
  55. package/types/src/graph.d.ts +2 -0
  56. package/types/src/nodes/collection.d.ts +38 -0
  57. package/types/src/nodes/effect.d.ts +13 -1
  58. package/types/src/nodes/list.d.ts +30 -2
  59. package/types/src/nodes/memo.d.ts +0 -1
  60. package/types/src/nodes/sensor.d.ts +10 -4
  61. package/types/src/nodes/store.d.ts +11 -0
  62. package/types/src/signal.d.ts +6 -0
@@ -0,0 +1,98 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — full index of documents, their scope, and what to verify in each
3
+ </required_reading>
4
+
5
+ <process>
6
+ ## Step 1: Read the source of truth
7
+
8
+ Read `index.ts` for the complete public API surface. Read `src/graph.ts` for the graph engine
9
+ and internal node shapes. Note the current version in `package.json`.
10
+
11
+ These are the ground truth. Every document is checked against them, not against each other.
12
+
13
+ ## Step 2: Check each document in turn
14
+
15
+ Work through the documents in this order. For each one, read the current document alongside
16
+ the relevant source, then record findings before moving to the next.
17
+
18
+ ### REQUIREMENTS.md
19
+ - Signal type table (9 types) matches the exports in `index.ts`
20
+ - Bundle size targets still reflect current library scope
21
+ - Non-goals do not contradict any feature that has since been added
22
+ - Stability section reflects the current version and release status
23
+
24
+ ### ARCHITECTURE.md
25
+ - Concrete Node Types table matches the node shapes in `src/graph.ts`
26
+ - Node Field Mixins table matches `SourceFields`, `SinkFields`, `OwnerFields`, `AsyncFields`
27
+ as defined in `src/graph.ts`
28
+ - Flag names (`FLAG_CLEAN`, `FLAG_CHECK`, `FLAG_DIRTY`, `FLAG_RUNNING`) match `src/graph.ts`
29
+ - Each signal type subsection describes the correct internal composition and lifecycle
30
+ - No subsection references a removed node type, flag, or function
31
+
32
+ ### CLAUDE.md
33
+ - Internal Node Shapes block matches `src/graph.ts`
34
+ - `activeOwner` / `activeSink` semantics description is accurate
35
+ - Each non-obvious behavior entry is still accurate for the current implementation
36
+ - Mental model analogy covers all 9 signal types
37
+
38
+ ### .github/copilot-instructions.md
39
+ - Signal Types list covers all 9 signal types with accurate one-line descriptions
40
+ - Key Files Structure lists all current `src/` files
41
+ - Code patterns in "Common Code Patterns" compile against current `index.ts`
42
+ (check factory signatures, option names, parameter order)
43
+ - API Design Principles reflect current conventions
44
+
45
+ ### README.md
46
+ - Every factory function exported from `index.ts` has a documented `### SignalType` section
47
+ - All option names, parameter names, and types match current signatures
48
+ - Code examples in the API section use current factory signatures
49
+ - "Choosing the Right Signal" table covers all 9 signal types
50
+ - "Advanced Usage" examples use current API
51
+
52
+ ### GUIDE.md
53
+ - "The Familiar Core" table references current factory function names
54
+ - "What Works Differently" sections describe current behavior
55
+ - "Beyond the Basics" signal type sections are accurate and use current API
56
+ - Code examples compile against current `index.ts`
57
+
58
+ ### JSDoc in src/ (spot-check)
59
+ - Read `src/nodes/state.ts`, `src/nodes/memo.ts`, and `src/nodes/effect.ts`
60
+ - Verify that `@param` tags match current parameter names and types
61
+ - Verify that `@returns` descriptions are accurate
62
+ - Flag any JSDoc that describes removed or renamed options
63
+
64
+ ## Step 3: Compile findings
65
+
66
+ Produce a structured report before making any edits:
67
+
68
+ ```
69
+ ## Consistency Review — [date]
70
+
71
+ ### Accurate (no changes needed)
72
+ - REQUIREMENTS.md: consistent
73
+ - ...
74
+
75
+ ### Gaps found
76
+ - ARCHITECTURE.md, "Concrete Node Types": [specific claim] is outdated — [what is correct]
77
+ - README.md, "### Task": option `abort` renamed to `signal` in current index.ts
78
+ - ...
79
+ ```
80
+
81
+ Be specific: name the document, section, and the exact discrepancy. Do not summarize vaguely.
82
+
83
+ ## Step 4: Confirm before editing
84
+
85
+ Present the report and ask: **"Shall I apply all of these updates, or would you like to
86
+ review and select?"**
87
+
88
+ Do not make any edits until explicitly confirmed. If the user confirms all, follow the
89
+ relevant per-document workflow for each gap identified. If they select a subset, update
90
+ only those.
91
+ </process>
92
+
93
+ <success_criteria>
94
+ - All seven documents checked against current source (`index.ts`, `src/graph.ts`)
95
+ - Findings reported as a structured list with specific document, section, and discrepancy
96
+ - No edits made before confirmation
97
+ - After confirmation, each gap resolved using the appropriate per-document workflow
98
+ </success_criteria>
@@ -0,0 +1,65 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — map the change type to affected documents
3
+ </required_reading>
4
+
5
+ <process>
6
+ ## Step 1: Understand the change
7
+
8
+ Inspect the diff against the main branch:
9
+
10
+ ```bash
11
+ git diff main..HEAD -- src/ index.ts
12
+ ```
13
+
14
+ If no diff is available, ask the user to describe what changed.
15
+
16
+ ## Step 2: Classify the change
17
+
18
+ Identify which of the following change types apply — more than one may apply:
19
+
20
+ | Change type | Examples |
21
+ |---|---|
22
+ | **New public API** | New factory function, new export, new type in `index.ts` |
23
+ | **Changed public API** | Modified signature, new option, renamed parameter, changed return type |
24
+ | **Removed public API** | Removed export, removed option, removed type |
25
+ | **New or changed non-obvious behavior** | Graph semantics, propagation edge case, ownership subtlety |
26
+ | **Internal implementation change** | Graph engine logic, flag values, node shapes, propagation algorithm |
27
+ | **Vision or scope change** | New design principle, changed audience, new constraint or non-goal |
28
+
29
+ ## Step 3: Determine affected documents
30
+
31
+ Use this table to identify which documents need updating:
32
+
33
+ | Change type | JSDoc | ARCHITECTURE.md | CLAUDE.md + copilot | README.md | GUIDE.md | REQUIREMENTS.md |
34
+ |---|---|---|---|---|---|---|
35
+ | New public API | ✓ | ✓ | ✓ | ✓ | ✓ if conceptually new | ✓ signal type table only |
36
+ | Changed public API | ✓ | if node shape changed | ✓ if behavior changes | ✓ | ✓ if affects mental model | ✗ |
37
+ | Removed public API | ✓ | ✓ if structural | ✓ | ✓ | ✓ if was documented | ✗ |
38
+ | New/changed non-obvious behavior | ✗ | ✓ if graph-level | ✓ | ✓ if affects usage pattern | ✗ | ✗ |
39
+ | Internal implementation change | ✗ | ✓ | ✓ | ✗ | ✗ | ✗ |
40
+ | Vision or scope change | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ |
41
+
42
+ ## Step 4: Update affected documents in order
43
+
44
+ Follow the corresponding workflow for each affected document. Always work in this order — each layer informs the next:
45
+
46
+ 1. **JSDoc** (`src/`) — closest to code; establishes precise wording
47
+ → workflows/update-jsdoc.md
48
+ 2. **ARCHITECTURE.md** — internal structure; must be consistent with source
49
+ → workflows/update-architecture.md
50
+ 3. **CLAUDE.md + copilot-instructions.md** — agent docs; must be consistent with architecture
51
+ → workflows/update-agent-docs.md
52
+ 4. **README.md + GUIDE.md** — public docs; must be consistent with API and agent docs
53
+ → workflows/update-public-api.md
54
+ 5. **REQUIREMENTS.md** — only if scope changed
55
+ → workflows/update-requirements.md
56
+
57
+ Skip any document not identified as affected in Step 3.
58
+ </process>
59
+
60
+ <success_criteria>
61
+ - Change type(s) correctly identified from the diff or description
62
+ - Only affected documents updated — no speculative edits
63
+ - Documents updated in the prescribed order
64
+ - Each document follows its tone guide
65
+ </success_criteria>
@@ -0,0 +1,77 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — CLAUDE.md and copilot-instructions.md sections
3
+ 2. references/tone-guide.md — agent-docs tone rules
4
+ </required_reading>
5
+
6
+ <process>
7
+ ## Step 1: Read the source
8
+
9
+ Read the relevant `src/nodes/*.ts` file(s) and `src/graph.ts` if the change touches graph
10
+ semantics. Read the current `CLAUDE.md` and `.github/copilot-instructions.md` in full.
11
+ Never update agent docs from memory — subtle inaccuracies are worse than gaps.
12
+
13
+ ## Step 2: Update CLAUDE.md
14
+
15
+ CLAUDE.md is the inference-time reference for Claude. It covers the mental model, internal
16
+ node shapes, and non-obvious behaviors. Token cost is real — every line must earn its place.
17
+
18
+ **Mental model section**
19
+ - Update the spreadsheet-cell analogy if a new signal type is added. One line per type,
20
+ consistent with the existing terse style.
21
+
22
+ **Internal Node Shapes section**
23
+ - Update the node shape table if `SourceFields`, `SinkFields`, `OwnerFields`, or `AsyncFields`
24
+ changed in `src/graph.ts`, or if a new node type was added.
25
+ - Update the `activeOwner` / `activeSink` description if their semantics changed.
26
+
27
+ **Non-Obvious Behaviors section**
28
+ - Add an entry when a behavior is counterintuitive enough that a competent developer would
29
+ not predict it from the public API alone.
30
+ - Remove or correct an entry when a previously non-obvious behavior has changed.
31
+
32
+ Each entry must follow this structure exactly:
33
+ 1. **Bold statement** of the behavior — one sentence, declarative.
34
+ 2. One or two sentences of implication. No padding.
35
+ 3. A code example only if the correct pattern is non-obvious from the statement alone.
36
+ Use the existing before/after style where it adds clarity.
37
+
38
+ Do NOT add entries for behavior that is obvious from the type signatures or from standard
39
+ reactive library conventions. The bar is: would an experienced reactive developer be
40
+ surprised by this?
41
+
42
+ ## Step 3: Update .github/copilot-instructions.md
43
+
44
+ copilot-instructions.md drives GitHub Copilot's code generation. Accuracy of the code
45
+ patterns is critical — Copilot uses these as generation templates.
46
+
47
+ **Core Architecture section**
48
+ - Update the node type list if a new node type was added or an existing one changed role.
49
+ - Update the flag list (`FLAG_CLEAN`, `FLAG_CHECK`, `FLAG_DIRTY`, `FLAG_RUNNING`) if flags
50
+ were added, renamed, or removed.
51
+
52
+ **Signal Types section**
53
+ - Add a one-line entry for each new signal type: `**Name** (\`createName\`): description`.
54
+ - Update the description of any signal type whose behavior or options changed.
55
+
56
+ **Key Files Structure section**
57
+ - Add a new line if a new source file was added.
58
+
59
+ **Common Code Patterns section**
60
+ - This is the highest-value section. Update the code block under "Creating Signals" to
61
+ reflect any changed factory signatures or new signal types.
62
+ - Patterns must compile against the current API. Verify each pattern against `index.ts`.
63
+ - Add a new pattern block only if the new usage cannot be inferred from existing patterns.
64
+
65
+ **Coding Conventions / API Design Principles sections**
66
+ - Update only if a new convention was established or an existing one changed.
67
+ </process>
68
+
69
+ <success_criteria>
70
+ - Source file(s) read before any edits
71
+ - CLAUDE.md non-obvious behavior entries accurate, terse, and consistently structured
72
+ - CLAUDE.md node shapes consistent with `src/graph.ts`
73
+ - copilot-instructions.md code patterns compile against the current `index.ts`
74
+ - Both documents remain concise — no explanatory padding
75
+ - Tone matches references/tone-guide.md: terse and direct for CLAUDE.md,
76
+ structured and pattern-focused for copilot-instructions.md
77
+ </success_criteria>
@@ -0,0 +1,61 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — ARCHITECTURE.md section
3
+ 2. references/tone-guide.md — architecture tone rules
4
+ </required_reading>
5
+
6
+ <process>
7
+ ## Step 1: Read the source of truth
8
+
9
+ Read `src/graph.ts` in full. Read any changed `src/nodes/*.ts` file(s). ARCHITECTURE.md
10
+ describes internals — accuracy requires reading the actual implementation, not inferring
11
+ from public API or documentation.
12
+
13
+ ## Step 2: Identify what changed architecturally
14
+
15
+ Changes that warrant an ARCHITECTURE.md update:
16
+
17
+ | Changed | Section to update |
18
+ |---|---|
19
+ | Edge structure (`Edge` type fields) | Core Data Structures → Edges |
20
+ | Node field mixins (`SourceFields`, `SinkFields`, etc.) | Core Data Structures → Node Field Mixins |
21
+ | Concrete node types or their composition | Core Data Structures → Concrete Node Types |
22
+ | `activeSink` protocol or `link()`/`trimSources()`/`unlink()` | Automatic Dependency Tracking |
23
+ | Flag values or `propagate()`/`refresh()`/`setState()` | Change Propagation |
24
+ | `batch()`/`flush()` or effect scheduling | Effect Scheduling |
25
+ | `activeOwner`, cleanup storage, `createScope()` | Ownership and Cleanup |
26
+ | New or changed signal type | Signal Types → relevant subsection |
27
+
28
+ Do NOT update sections that remain accurate. If only `src/nodes/memo.ts` changed, only
29
+ the Memo subsection under "Signal Types" needs editing.
30
+
31
+ ## Step 3: Update the affected section(s)
32
+
33
+ For each affected section:
34
+
35
+ 1. Re-read the current section text alongside the new source.
36
+ 2. Identify specific claims that are now wrong or incomplete.
37
+ 3. Make the minimal edit that makes those claims accurate.
38
+
39
+ **Node shape changes:** Update the table in "Concrete Node Types" and the corresponding
40
+ mixin table if field composition changed. If a new field mixin was added, add a row.
41
+
42
+ **Propagation or flag changes:** Update the prose description and any pseudocode or
43
+ inline code that references the changed behavior. If flag names changed, update every
44
+ occurrence.
45
+
46
+ **New signal type:** Add a new subsection under "Signal Types" following the existing
47
+ pattern: one paragraph describing the node's role in the graph, its internal composition,
48
+ and any non-obvious lifecycle behavior (watched activation, ownership, async cancellation).
49
+ Do not duplicate the public API — describe the internal mechanics only.
50
+
51
+ **Removed signal type:** Remove its subsection. Check for cross-references in other
52
+ subsections.
53
+ </process>
54
+
55
+ <success_criteria>
56
+ - `src/graph.ts` read in full before any edits
57
+ - Only sections affected by the change were modified
58
+ - Node shapes, flag names, and function descriptions match the current source exactly
59
+ - New signal type subsection follows the structure and depth of existing subsections
60
+ - Tone is technical and internal-facing per references/tone-guide.md
61
+ </success_criteria>
@@ -0,0 +1,72 @@
1
+ <required_reading>
2
+ 1. references/tone-guide.md — jsdoc tone rules
3
+ </required_reading>
4
+
5
+ <process>
6
+ ## Step 1: Read the implementation first
7
+
8
+ Read the full source file being updated. JSDoc must describe what the code actually does —
9
+ not what it should do, not what the previous version did.
10
+
11
+ For public API changes, also read `index.ts` to confirm the exported signature matches
12
+ the implementation.
13
+
14
+ ## Step 2: Identify which JSDoc blocks need updating
15
+
16
+ A JSDoc block needs updating when any of the following changed:
17
+
18
+ - The function signature (parameter added, removed, renamed, or retyped)
19
+ - The return type or return value semantics
20
+ - A thrown error condition that a caller must handle
21
+ - The function no longer exists (remove the block with the function)
22
+
23
+ Do NOT update JSDoc blocks that remain accurate. Read each existing block against the
24
+ current implementation before deciding whether to edit it.
25
+
26
+ ## Step 3: Write or update the JSDoc block
27
+
28
+ Follow this structure for all public API functions:
29
+
30
+ ```typescript
31
+ /**
32
+ * One-line summary. No period if it reads as a fragment; period if it reads as a sentence.
33
+ *
34
+ * Second paragraph only if the one-liner is genuinely insufficient — e.g. a non-obvious
35
+ * constraint or a behavioral guarantee that cannot fit on one line. Omit otherwise.
36
+ *
37
+ * @param name - What it is. Include constraints (`T extends {}`, valid range, allowed
38
+ * values). One line per param; wrap only if a constraint needs explaining.
39
+ * @param options - Options object, if present. Document only options that are non-obvious;
40
+ * skip `equals` and `guard` unless the signal's default behavior for them is unusual.
41
+ * @returns What is returned and any guarantee about its value (e.g. "Always non-nullish").
42
+ */
43
+ ```
44
+
45
+ **Constraints on length:**
46
+ - Summary line: one line, no exceptions.
47
+ - `@param` entries: one line each unless a constraint genuinely requires a second.
48
+ - No `@example` blocks — examples live in `README.md`. Add one only if the usage pattern
49
+ is so non-obvious that a developer would misuse the function without it.
50
+ - No `@throws` unless the error can occur in correct, non-erroneous usage (e.g.
51
+ `UnsetSignalValueError` on `Sensor.get()` before first value). Do not document
52
+ programmer-error throws (`RequiredOwnerError`, `InvalidCallbackError`, `CircularDependencyError`).
53
+
54
+ **Type annotations in JSDoc:**
55
+ - Do NOT repeat TypeScript types in `@param` or `@returns` tags. TypeScript already
56
+ enforces them. Only describe semantics, not types.
57
+
58
+ ## Step 4: Check consistency across the file
59
+
60
+ After updating, scan the rest of the file for any JSDoc that cross-references the changed
61
+ function or type. Update those references if they are now stale.
62
+ </process>
63
+
64
+ <success_criteria>
65
+ - Source file read in full before any edits
66
+ - Every updated block has a one-line summary
67
+ - No `@example` blocks added unless usage is genuinely non-obvious
68
+ - No `@throws` for programmer-error conditions
69
+ - TypeScript types not duplicated in JSDoc prose
70
+ - Updated blocks compile without JSDoc-related errors
71
+ - Unchanged blocks left untouched
72
+ </success_criteria>
@@ -0,0 +1,59 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — README.md and GUIDE.md sections
3
+ 2. references/tone-guide.md — public-api and guide tone rules
4
+ </required_reading>
5
+
6
+ <process>
7
+ ## Step 1: Read the source of truth
8
+
9
+ Read `index.ts` for the current public API surface. Read the relevant `src/nodes/*.ts`
10
+ file(s) for any changed signal type. Do this before opening either document.
11
+
12
+ ## Step 2: Update README.md
13
+
14
+ README.md is the authoritative public API reference. Make targeted edits only:
15
+
16
+ **New signal type**
17
+ - Add a `### SignalType` section under `## API` with: factory signature, all options, and
18
+ at least one realistic example showing normal usage.
19
+ - Add the type to the "Choosing the Right Signal" table with a one-line description.
20
+ - If the type participates in ownership or has a `watched` lifecycle, add an example to
21
+ "Advanced Usage → Resource Management".
22
+
23
+ **Changed option or signature**
24
+ - Update the relevant `### SignalType` section. Update the example if the old pattern no
25
+ longer compiles or no longer represents idiomatic usage.
26
+ - If the change is a rename or a breaking type change, note the migration inline under the
27
+ parameter description, not in a separate section.
28
+
29
+ **Removed API**
30
+ - Remove all mentions. Check: the API section, "Choosing the Right Signal", "Advanced Usage",
31
+ and any cross-references in other signal type sections.
32
+
33
+ **New or changed behavior**
34
+ - Update the description in the relevant section. If the behavior is subtle, add or update
35
+ an example. If it is an advanced pattern, add to "Advanced Usage".
36
+
37
+ ## Step 3: Update GUIDE.md
38
+
39
+ GUIDE.md explains the library through the lens of developers migrating from React, Vue,
40
+ or Angular. Update it only when the change affects the conceptual picture:
41
+
42
+ - **"The Familiar Core" table** — update if a core factory name changes.
43
+ - **"What Works Differently"** — update if a fundamental behavioral contract changes
44
+ (e.g. synchronous vs. async execution, nullability rules, ownership model).
45
+ - **"Beyond the Basics"** — update if a new signal type is added, or if a major signal
46
+ type changes significantly enough that its comparative explanation is wrong.
47
+
48
+ Do NOT add every option change or minor signature tweak to GUIDE.md. Only update it when
49
+ a developer's existing mental model from another framework would now lead them astray.
50
+ </process>
51
+
52
+ <success_criteria>
53
+ - `index.ts` read before any edits were made
54
+ - README.md accurately reflects the current public API: all factories documented, all
55
+ options current, all examples valid
56
+ - GUIDE.md updated only where the conceptual picture for framework migrants changed
57
+ - Both documents follow their respective tones from references/tone-guide.md
58
+ - No sections rewritten beyond what the change requires
59
+ </success_criteria>
@@ -0,0 +1,80 @@
1
+ <required_reading>
2
+ 1. references/document-map.md — REQUIREMENTS.md section
3
+ 2. references/tone-guide.md — requirements tone rules
4
+ </required_reading>
5
+
6
+ <process>
7
+ ## Step 1: Confirm the update is warranted
8
+
9
+ REQUIREMENTS.md captures the library's vision, audience, design principles, constraints,
10
+ and non-goals. It is intentionally written to survive version bumps. Do NOT update it for:
11
+
12
+ - Bug fixes or internal refactors
13
+ - New options on existing signal types
14
+ - Changed implementation details
15
+ - Documentation or tooling changes
16
+
17
+ Only update REQUIREMENTS.md when one of these applies:
18
+
19
+ | Trigger | Section affected |
20
+ |---|---|
21
+ | A new signal type is added to the library | "Design Principles → Minimal Surface, Maximum Coverage" table |
22
+ | A signal type is removed | Same table + "Non-Goals" if it was previously out of scope |
23
+ | A runtime environment is added or dropped | "Runtime Environments" |
24
+ | A bundle size target changes | "Size and Performance Constraints" |
25
+ | A design principle is added, changed, or removed | "Design Principles" |
26
+ | The primary or secondary audience shifts | "Audience" |
27
+ | A non-goal is resolved or a new one is added | "Non-Goals" |
28
+ | Stability guarantees change | "Stability" |
29
+
30
+ If the change does not meet any of these criteria, stop and explain why REQUIREMENTS.md
31
+ does not need updating. Do not edit it speculatively.
32
+
33
+ ## Step 2: Read the full document
34
+
35
+ Read `REQUIREMENTS.md` in full before touching anything. Identify the single section
36
+ (or at most two) that the change affects. Changes to REQUIREMENTS.md are almost always
37
+ one table row, one list item, or one short paragraph — rarely more.
38
+
39
+ ## Step 3: Make the minimal edit
40
+
41
+ Make only the change the trigger warrants:
42
+
43
+ **Signal type table (most common):**
44
+ Add or remove a row. The row format is:
45
+ `| **Type** | Role description | Data structure |`
46
+ Keep the role description to one short phrase. The table reflects the final state
47
+ of the type set — it is not a changelog.
48
+
49
+ **Runtime environments:**
50
+ Add or remove the environment name from the prose list. One line.
51
+
52
+ **Bundle size targets:**
53
+ Update the number in the table. If the target changed for a reason that future readers
54
+ should understand, add one sentence of rationale — no more.
55
+
56
+ **Non-goals:**
57
+ Each non-goal is a bold heading followed by one sentence. Do not expand them into
58
+ paragraphs. If adding a new non-goal, follow the same pattern. If resolving one,
59
+ remove it entirely — do not mark it as resolved inline.
60
+
61
+ **Stability section:**
62
+ Update only the factual claims (version number, breaking change expectations). Preserve
63
+ the formal register of the surrounding text.
64
+
65
+ ## Step 4: Verify internal consistency
66
+
67
+ After editing, confirm:
68
+ - The signal type table count matches the count stated in the prose ("9 signal types").
69
+ - The "Non-Goals" section does not contradict anything now present in the codebase.
70
+ - The "Stability" section accurately describes the current version and compatibility stance.
71
+ </process>
72
+
73
+ <success_criteria>
74
+ - Update was warranted by one of the listed triggers
75
+ - Only the affected section was changed — no rewrites of accurate content
76
+ - Signal type table count consistent with prose and with `index.ts`
77
+ - Formal, strategic tone preserved throughout per references/tone-guide.md
78
+ - No changelog-style language ("previously", "now", "we changed") — state the current
79
+ truth only
80
+ </success_criteria>
package/src/graph.ts CHANGED
@@ -590,6 +590,8 @@ function createScope(fn: () => MaybeCleanup): Cleanup {
590
590
  * reactive graph.
591
591
  *
592
592
  * @since 0.18.5
593
+ * @param fn - The function to execute without an active owner
594
+ * @returns The return value of `fn`
593
595
  */
594
596
  function unown<T>(fn: () => T): T {
595
597
  const prev = activeOwner
@@ -36,10 +36,24 @@ import { createTask } from './task'
36
36
 
37
37
  type CollectionSource<T extends {}> = List<T> | Collection<T>
38
38
 
39
+ /**
40
+ * Transformation callback for `deriveCollection` — sync or async.
41
+ * Sync callbacks produce a `Memo<T>` per item; async callbacks produce a `Task<T>`
42
+ * with automatic cancellation when the source item changes.
43
+ *
44
+ * @template T - The type of derived items
45
+ * @template U - The type of source items
46
+ */
39
47
  type DeriveCollectionCallback<T extends {}, U extends {}> =
40
48
  | ((sourceValue: U) => T)
41
49
  | ((sourceValue: U, abort: AbortSignal) => Promise<T>)
42
50
 
51
+ /**
52
+ * A read-only reactive keyed collection with per-item reactivity.
53
+ * Created by `createCollection` (externally driven) or via `.deriveCollection()` on a `List` or `Collection`.
54
+ *
55
+ * @template T - The type of items in the collection
56
+ */
43
57
  type Collection<T extends {}> = {
44
58
  readonly [Symbol.toStringTag]: 'Collection'
45
59
  readonly [Symbol.isConcatSpreadable]: true
@@ -59,18 +73,42 @@ type Collection<T extends {}> = {
59
73
  readonly length: number
60
74
  }
61
75
 
76
+ /**
77
+ * Granular mutation descriptor passed to the `applyChanges` callback inside a `CollectionCallback`.
78
+ *
79
+ * @template T - The type of items in the collection
80
+ */
62
81
  type CollectionChanges<T> = {
82
+ /** Items to add. Each item is assigned a new key via the configured `keyConfig`. */
63
83
  add?: T[]
84
+ /** Items whose values have changed. Matched to existing entries by key. */
64
85
  change?: T[]
86
+ /** Items to remove. Matched to existing entries by key. */
65
87
  remove?: T[]
66
88
  }
67
89
 
90
+ /**
91
+ * Configuration options for `createCollection`.
92
+ *
93
+ * @template T - The type of items in the collection
94
+ */
68
95
  type CollectionOptions<T extends {}> = {
96
+ /** Initial items. Defaults to `[]`. */
69
97
  value?: T[]
98
+ /** Key generation strategy. See `KeyConfig`. Defaults to auto-increment. */
70
99
  keyConfig?: KeyConfig<T>
100
+ /** Factory for per-item signals. Defaults to `createState`. */
71
101
  createItem?: (value: T) => Signal<T>
72
102
  }
73
103
 
104
+ /**
105
+ * Setup callback for `createCollection`. Invoked when the collection gains its first downstream
106
+ * subscriber; receives an `applyChanges` function to push granular mutations into the graph.
107
+ *
108
+ * @template T - The type of items in the collection
109
+ * @param apply - Call with a `CollectionChanges` object to add, update, or remove items
110
+ * @returns A cleanup function invoked when the collection loses all subscribers
111
+ */
74
112
  type CollectionCallback<T extends {}> = (
75
113
  apply: (changes: CollectionChanges<T>) => void,
76
114
  ) => Cleanup
@@ -20,13 +20,22 @@ import {
20
20
 
21
21
  /* === Types === */
22
22
 
23
+ /** A value that is either synchronous or a `Promise` — used for handler return types in `match()`. */
23
24
  type MaybePromise<T> = T | Promise<T>
24
25
 
26
+ /**
27
+ * Handlers for all states of one or more signals passed to `match()`.
28
+ *
29
+ * @template T - Tuple of `Signal` types being matched
30
+ */
25
31
  type MatchHandlers<T extends readonly Signal<unknown & {}>[]> = {
32
+ /** Called when all signals have a value. Receives a tuple of resolved values. */
26
33
  ok: (values: {
27
34
  [K in keyof T]: T[K] extends Signal<infer V> ? V : never
28
35
  }) => MaybePromise<MaybeCleanup>
36
+ /** Called when one or more signals hold an error. Defaults to `console.error`. */
29
37
  err?: (errors: readonly Error[]) => MaybePromise<MaybeCleanup>
38
+ /** Called when one or more signals are unset (pending). */
30
39
  nil?: () => MaybePromise<MaybeCleanup>
31
40
  }
32
41
 
@@ -88,10 +97,13 @@ function createEffect(fn: EffectCallback): Cleanup {
88
97
  }
89
98
 
90
99
  /**
91
- * Runs handlers based on the current values of signals.
100
+ * Reads one or more signals and dispatches to the appropriate handler based on their state.
92
101
  * Must be called within an active owner (effect or scope) so async cleanup can be registered.
93
102
  *
94
103
  * @since 0.15.0
104
+ * @param signals - Tuple of signals to read; all must have a value for `ok` to run.
105
+ * @param handlers - Object with an `ok` branch and optional `err` and `nil` branches.
106
+ * @returns An optional cleanup function if the active handler returns one.
95
107
  * @throws RequiredOwnerError If called without an active owner.
96
108
  */
97
109
  function match<T extends readonly Signal<unknown & {}>[]>(