@dojocho/effect-ts 0.0.1

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 (149) hide show
  1. package/DOJO.md +22 -0
  2. package/dojo.json +50 -0
  3. package/katas/001-hello-effect/SENSEI.md +72 -0
  4. package/katas/001-hello-effect/solution.test.ts +35 -0
  5. package/katas/001-hello-effect/solution.ts +16 -0
  6. package/katas/002-transform-with-map/SENSEI.md +72 -0
  7. package/katas/002-transform-with-map/solution.test.ts +33 -0
  8. package/katas/002-transform-with-map/solution.ts +16 -0
  9. package/katas/003-generator-pipelines/SENSEI.md +72 -0
  10. package/katas/003-generator-pipelines/solution.test.ts +40 -0
  11. package/katas/003-generator-pipelines/solution.ts +29 -0
  12. package/katas/004-flatmap-and-chaining/SENSEI.md +80 -0
  13. package/katas/004-flatmap-and-chaining/solution.test.ts +34 -0
  14. package/katas/004-flatmap-and-chaining/solution.ts +18 -0
  15. package/katas/005-pipe-composition/SENSEI.md +81 -0
  16. package/katas/005-pipe-composition/solution.test.ts +41 -0
  17. package/katas/005-pipe-composition/solution.ts +19 -0
  18. package/katas/006-handle-errors/SENSEI.md +86 -0
  19. package/katas/006-handle-errors/solution.test.ts +53 -0
  20. package/katas/006-handle-errors/solution.ts +30 -0
  21. package/katas/007-tagged-errors/SENSEI.md +79 -0
  22. package/katas/007-tagged-errors/solution.test.ts +82 -0
  23. package/katas/007-tagged-errors/solution.ts +37 -0
  24. package/katas/008-error-patterns/SENSEI.md +89 -0
  25. package/katas/008-error-patterns/solution.test.ts +41 -0
  26. package/katas/008-error-patterns/solution.ts +38 -0
  27. package/katas/009-option-type/SENSEI.md +96 -0
  28. package/katas/009-option-type/solution.test.ts +49 -0
  29. package/katas/009-option-type/solution.ts +26 -0
  30. package/katas/010-either-and-exit/SENSEI.md +86 -0
  31. package/katas/010-either-and-exit/solution.test.ts +33 -0
  32. package/katas/010-either-and-exit/solution.ts +17 -0
  33. package/katas/011-services-and-context/SENSEI.md +82 -0
  34. package/katas/011-services-and-context/solution.test.ts +23 -0
  35. package/katas/011-services-and-context/solution.ts +17 -0
  36. package/katas/012-layers/SENSEI.md +73 -0
  37. package/katas/012-layers/solution.test.ts +23 -0
  38. package/katas/012-layers/solution.ts +26 -0
  39. package/katas/013-testing-effects/SENSEI.md +88 -0
  40. package/katas/013-testing-effects/solution.test.ts +41 -0
  41. package/katas/013-testing-effects/solution.ts +20 -0
  42. package/katas/014-schema-basics/SENSEI.md +81 -0
  43. package/katas/014-schema-basics/solution.test.ts +35 -0
  44. package/katas/014-schema-basics/solution.ts +25 -0
  45. package/katas/015-domain-modeling/SENSEI.md +85 -0
  46. package/katas/015-domain-modeling/solution.test.ts +46 -0
  47. package/katas/015-domain-modeling/solution.ts +42 -0
  48. package/katas/016-retry-and-schedule/SENSEI.md +72 -0
  49. package/katas/016-retry-and-schedule/solution.test.ts +26 -0
  50. package/katas/016-retry-and-schedule/solution.ts +23 -0
  51. package/katas/017-parallel-effects/SENSEI.md +70 -0
  52. package/katas/017-parallel-effects/solution.test.ts +33 -0
  53. package/katas/017-parallel-effects/solution.ts +17 -0
  54. package/katas/018-race-and-timeout/SENSEI.md +75 -0
  55. package/katas/018-race-and-timeout/solution.test.ts +30 -0
  56. package/katas/018-race-and-timeout/solution.ts +27 -0
  57. package/katas/019-ref-and-state/SENSEI.md +72 -0
  58. package/katas/019-ref-and-state/solution.test.ts +29 -0
  59. package/katas/019-ref-and-state/solution.ts +16 -0
  60. package/katas/020-fibers/SENSEI.md +80 -0
  61. package/katas/020-fibers/solution.test.ts +23 -0
  62. package/katas/020-fibers/solution.ts +23 -0
  63. package/katas/021-acquire-release/SENSEI.md +57 -0
  64. package/katas/021-acquire-release/solution.test.ts +23 -0
  65. package/katas/021-acquire-release/solution.ts +22 -0
  66. package/katas/022-scoped-layers/SENSEI.md +52 -0
  67. package/katas/022-scoped-layers/solution.test.ts +35 -0
  68. package/katas/022-scoped-layers/solution.ts +19 -0
  69. package/katas/023-resource-patterns/SENSEI.md +52 -0
  70. package/katas/023-resource-patterns/solution.test.ts +20 -0
  71. package/katas/023-resource-patterns/solution.ts +13 -0
  72. package/katas/024-streams-basics/SENSEI.md +61 -0
  73. package/katas/024-streams-basics/solution.test.ts +30 -0
  74. package/katas/024-streams-basics/solution.ts +16 -0
  75. package/katas/025-stream-operations/SENSEI.md +59 -0
  76. package/katas/025-stream-operations/solution.test.ts +26 -0
  77. package/katas/025-stream-operations/solution.ts +17 -0
  78. package/katas/026-combining-streams/SENSEI.md +54 -0
  79. package/katas/026-combining-streams/solution.test.ts +20 -0
  80. package/katas/026-combining-streams/solution.ts +16 -0
  81. package/katas/027-data-pipelines/SENSEI.md +58 -0
  82. package/katas/027-data-pipelines/solution.test.ts +22 -0
  83. package/katas/027-data-pipelines/solution.ts +16 -0
  84. package/katas/028-logging-and-spans/SENSEI.md +58 -0
  85. package/katas/028-logging-and-spans/solution.test.ts +50 -0
  86. package/katas/028-logging-and-spans/solution.ts +20 -0
  87. package/katas/029-http-client/SENSEI.md +59 -0
  88. package/katas/029-http-client/solution.test.ts +49 -0
  89. package/katas/029-http-client/solution.ts +24 -0
  90. package/katas/030-capstone/SENSEI.md +63 -0
  91. package/katas/030-capstone/solution.test.ts +67 -0
  92. package/katas/030-capstone/solution.ts +55 -0
  93. package/katas/031-config-and-environment/SENSEI.md +77 -0
  94. package/katas/031-config-and-environment/solution.test.ts +38 -0
  95. package/katas/031-config-and-environment/solution.ts +11 -0
  96. package/katas/032-cause-and-defects/SENSEI.md +90 -0
  97. package/katas/032-cause-and-defects/solution.test.ts +50 -0
  98. package/katas/032-cause-and-defects/solution.ts +23 -0
  99. package/katas/033-pattern-matching/SENSEI.md +86 -0
  100. package/katas/033-pattern-matching/solution.test.ts +36 -0
  101. package/katas/033-pattern-matching/solution.ts +28 -0
  102. package/katas/034-deferred-and-coordination/SENSEI.md +85 -0
  103. package/katas/034-deferred-and-coordination/solution.test.ts +25 -0
  104. package/katas/034-deferred-and-coordination/solution.ts +24 -0
  105. package/katas/035-queue-and-backpressure/SENSEI.md +100 -0
  106. package/katas/035-queue-and-backpressure/solution.test.ts +25 -0
  107. package/katas/035-queue-and-backpressure/solution.ts +21 -0
  108. package/katas/036-schema-advanced/SENSEI.md +81 -0
  109. package/katas/036-schema-advanced/solution.test.ts +55 -0
  110. package/katas/036-schema-advanced/solution.ts +19 -0
  111. package/katas/037-cache-and-memoization/SENSEI.md +73 -0
  112. package/katas/037-cache-and-memoization/solution.test.ts +47 -0
  113. package/katas/037-cache-and-memoization/solution.ts +24 -0
  114. package/katas/038-metrics/SENSEI.md +91 -0
  115. package/katas/038-metrics/solution.test.ts +39 -0
  116. package/katas/038-metrics/solution.ts +23 -0
  117. package/katas/039-managed-runtime/SENSEI.md +75 -0
  118. package/katas/039-managed-runtime/solution.test.ts +29 -0
  119. package/katas/039-managed-runtime/solution.ts +19 -0
  120. package/katas/040-request-batching/SENSEI.md +87 -0
  121. package/katas/040-request-batching/solution.test.ts +56 -0
  122. package/katas/040-request-batching/solution.ts +32 -0
  123. package/package.json +22 -0
  124. package/skills/effect-patterns-building-apis/SKILL.md +2393 -0
  125. package/skills/effect-patterns-building-data-pipelines/SKILL.md +1876 -0
  126. package/skills/effect-patterns-concurrency/SKILL.md +2999 -0
  127. package/skills/effect-patterns-concurrency-getting-started/SKILL.md +351 -0
  128. package/skills/effect-patterns-core-concepts/SKILL.md +3199 -0
  129. package/skills/effect-patterns-domain-modeling/SKILL.md +1385 -0
  130. package/skills/effect-patterns-error-handling/SKILL.md +1212 -0
  131. package/skills/effect-patterns-error-handling-resilience/SKILL.md +179 -0
  132. package/skills/effect-patterns-error-management/SKILL.md +1668 -0
  133. package/skills/effect-patterns-getting-started/SKILL.md +237 -0
  134. package/skills/effect-patterns-making-http-requests/SKILL.md +1756 -0
  135. package/skills/effect-patterns-observability/SKILL.md +1586 -0
  136. package/skills/effect-patterns-platform/SKILL.md +1195 -0
  137. package/skills/effect-patterns-platform-getting-started/SKILL.md +179 -0
  138. package/skills/effect-patterns-project-setup--execution/SKILL.md +233 -0
  139. package/skills/effect-patterns-resource-management/SKILL.md +827 -0
  140. package/skills/effect-patterns-scheduling/SKILL.md +451 -0
  141. package/skills/effect-patterns-scheduling-periodic-tasks/SKILL.md +763 -0
  142. package/skills/effect-patterns-streams/SKILL.md +2052 -0
  143. package/skills/effect-patterns-streams-getting-started/SKILL.md +421 -0
  144. package/skills/effect-patterns-streams-sinks/SKILL.md +1181 -0
  145. package/skills/effect-patterns-testing/SKILL.md +1632 -0
  146. package/skills/effect-patterns-tooling-and-debugging/SKILL.md +1125 -0
  147. package/skills/effect-patterns-value-handling/SKILL.md +676 -0
  148. package/tsconfig.json +20 -0
  149. package/vitest.config.ts +3 -0
@@ -0,0 +1,237 @@
1
+ ---
2
+ name: effect-patterns-getting-started
3
+ description: Effect-TS patterns for Getting Started. Use when working with getting started in Effect-TS applications.
4
+ ---
5
+ # Effect-TS Patterns: Getting Started
6
+ This skill provides 6 curated Effect-TS patterns for getting started.
7
+ Use this skill when working on tasks related to:
8
+ - getting started
9
+ - Best practices in Effect-TS applications
10
+ - Real-world patterns and solutions
11
+
12
+ ---
13
+
14
+ ## 🟢 Beginner Patterns
15
+
16
+ ### Retry a Failed Operation with Effect.retry
17
+
18
+ **Rule:** Retry failed operations with Effect.retry.
19
+
20
+ **Good Example:**
21
+
22
+ ```typescript
23
+ import { Effect, Schedule, pipe } from "effect";
24
+
25
+ class ApiError {
26
+ readonly _tag = "ApiError";
27
+ constructor(readonly status: number) {}
28
+ }
29
+
30
+ const fetchUserData = (userId: string) =>
31
+ Effect.tryPromise({
32
+ try: async () => {
33
+ const response = await fetch(`/api/users/${userId}`);
34
+ if (!response.ok) throw new ApiError(response.status);
35
+ return response.json();
36
+ },
37
+ catch: (error) => error as ApiError,
38
+ });
39
+
40
+ // Retry up to 3 times with 500ms between attempts
41
+ const fetchWithRetry = (userId: string) =>
42
+ pipe(
43
+ fetchUserData(userId),
44
+ Effect.retry(
45
+ Schedule.recurs(3).pipe(Schedule.addDelay(() => "500 millis"))
46
+ ),
47
+ Effect.catchAll((error) =>
48
+ Effect.succeed({ error: `Failed after retries: ${error._tag}` })
49
+ )
50
+ );
51
+ ```
52
+
53
+ **Rationale:**
54
+
55
+ Use `Effect.retry` to automatically retry an Effect that fails. Combine it
56
+ with a `Schedule` to control how many times to retry and how long to wait
57
+ between attempts.
58
+
59
+
60
+ Network requests fail. Databases time out. Services go down temporarily.
61
+ Instead of failing immediately, you often want to retry a few times.
62
+ Effect makes this a one-liner.
63
+
64
+ ---
65
+
66
+ ### Hello World: Your First Effect
67
+
68
+ **Rule:** Create your first Effect program with Effect.succeed.
69
+
70
+ **Good Example:**
71
+
72
+ ```typescript
73
+ import { Effect } from "effect";
74
+
75
+ // Step 1: Create an Effect that succeeds with a value
76
+ const helloWorld = Effect.succeed("Hello, Effect!");
77
+
78
+ // Step 2: Run the Effect and get the result
79
+ const result = Effect.runSync(helloWorld);
80
+
81
+ console.log(result); // "Hello, Effect!"
82
+ ```
83
+
84
+ **Rationale:**
85
+
86
+ Create your first Effect using `Effect.succeed` to wrap a value, then run it
87
+ with `Effect.runSync` to see the result.
88
+
89
+
90
+ Every journey starts with "Hello World". In Effect, you create computations
91
+ by describing what you want to happen, then you run them. This separation is
92
+ what makes Effect powerful.
93
+
94
+ ---
95
+
96
+ ### Transform Values with Effect.map
97
+
98
+ **Rule:** Transform Effect values with map.
99
+
100
+ **Good Example:**
101
+
102
+ ```typescript
103
+ import { Effect } from "effect";
104
+
105
+ // Start with an Effect that succeeds with a number
106
+ const getNumber = Effect.succeed(5);
107
+
108
+ // Transform it: multiply by 2
109
+ const doubled = Effect.map(getNumber, (n) => n * 2);
110
+
111
+ // Transform again: convert to string
112
+ const asString = Effect.map(doubled, (n) => `The result is ${n}`);
113
+
114
+ // Run to see the result
115
+ const result = Effect.runSync(asString);
116
+ console.log(result); // "The result is 10"
117
+ ```
118
+
119
+ **Rationale:**
120
+
121
+ Use `Effect.map` to transform the success value inside an Effect. The
122
+ transformation function receives the value and returns a new value.
123
+
124
+
125
+ Just like `Array.map` transforms array elements, `Effect.map` transforms
126
+ the success value of an Effect. This lets you build pipelines of
127
+ transformations without running anything until the end.
128
+
129
+ ---
130
+
131
+ ### Handle Your First Error with Effect.fail and catchAll
132
+
133
+ **Rule:** Handle errors with Effect.fail and catchAll.
134
+
135
+ **Good Example:**
136
+
137
+ ```typescript
138
+ import { Effect, pipe } from "effect";
139
+
140
+ class UserNotFound {
141
+ readonly _tag = "UserNotFound";
142
+ constructor(readonly id: string) {}
143
+ }
144
+
145
+ const findUser = (id: string) =>
146
+ id === "123"
147
+ ? Effect.succeed({ id, name: "Alice" })
148
+ : Effect.fail(new UserNotFound(id));
149
+
150
+ const program = pipe(
151
+ findUser("456"),
152
+ Effect.catchTag("UserNotFound", (e) =>
153
+ Effect.succeed({ id: e.id, name: "Guest" })
154
+ ),
155
+ Effect.map((user) => `Hello, ${user.name}!​`)
156
+ );
157
+
158
+ const result = Effect.runSync(program);
159
+ console.log(result); // "Hello, Guest!"
160
+ ```
161
+
162
+ **Rationale:**
163
+
164
+ Use `Effect.fail` to create an Effect that fails with an error, and
165
+ `Effect.catchAll` to recover from that failure.
166
+
167
+
168
+ Real programs fail. Effect makes failures explicit in the type system so you
169
+ can't forget to handle them. Unlike try/catch, Effect errors are tracked in
170
+ types.
171
+
172
+ ---
173
+
174
+ ### Run Multiple Effects in Parallel with Effect.all
175
+
176
+ **Rule:** Run multiple Effects in parallel with Effect.all.
177
+
178
+ **Good Example:**
179
+
180
+ ```typescript
181
+ import { Effect, pipe } from "effect";
182
+
183
+ // Simulate fetching data from different sources
184
+ const fetchUser = Effect.succeed({ id: 1, name: "Alice" }).pipe(
185
+ Effect.delay("100 millis")
186
+ );
187
+
188
+ const fetchPosts = Effect.succeed([
189
+ { id: 1, title: "Hello World" },
190
+ { id: 2, title: "Effect is awesome" },
191
+ ]).pipe(Effect.delay("150 millis"));
192
+
193
+ const fetchSettings = Effect.succeed({ theme: "dark" }).pipe(
194
+ Effect.delay("50 millis")
195
+ );
196
+
197
+ // Fetch all data in parallel
198
+ const program = Effect.gen(function* () {
199
+ const [user, posts, settings] = yield* Effect.all(
200
+ [fetchUser, fetchPosts, fetchSettings],
201
+ { concurrency: "unbounded" }
202
+ );
203
+
204
+ yield* Effect.log(`Loaded ${user.name} with ${posts.length} posts`);
205
+ return { user, posts, settings };
206
+ });
207
+
208
+ Effect.runPromise(program);
209
+ ```
210
+
211
+ **Rationale:**
212
+
213
+ Use `Effect.all` to run multiple Effects concurrently and wait for all of
214
+ them to complete. By default, Effects run sequentially - add the
215
+ `concurrency` option to run them in parallel.
216
+
217
+
218
+ Real applications often need to do multiple things at once - fetch data from
219
+ several APIs, process multiple files, etc. `Effect.all` lets you express
220
+ this naturally without callback hell or complex Promise.all patterns.
221
+
222
+ ---
223
+
224
+ ### Why Effect? Comparing Effect to Promise
225
+
226
+ **Rule:** Understand why Effect is better than raw Promises.
227
+
228
+ **Rationale:**
229
+
230
+ Effect solves three problems that Promises don't:
231
+ 1. **Errors are typed** - You know exactly what can go wrong
232
+ 2. **Dependencies are tracked** - You know what services are needed
233
+ 3. **Effects are lazy** - Nothing runs until you say so
234
+
235
+ ---
236
+
237
+