@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,179 @@
1
+ ---
2
+ name: effect-patterns-platform-getting-started
3
+ description: Effect-TS patterns for Platform Getting Started. Use when working with platform getting started in Effect-TS applications.
4
+ ---
5
+ # Effect-TS Patterns: Platform Getting Started
6
+ This skill provides 2 curated Effect-TS patterns for platform getting started.
7
+ Use this skill when working on tasks related to:
8
+ - platform getting started
9
+ - Best practices in Effect-TS applications
10
+ - Real-world patterns and solutions
11
+
12
+ ---
13
+
14
+ ## 🟢 Beginner Patterns
15
+
16
+ ### Your First Platform Operation
17
+
18
+ **Rule:** Use @effect/platform for cross-platform system operations with Effect integration.
19
+
20
+ **Good Example:**
21
+
22
+ ```typescript
23
+ import { Effect } from "effect"
24
+ import { FileSystem } from "@effect/platform"
25
+ import { NodeContext, NodeRuntime } from "@effect/platform-node"
26
+
27
+ // Read a file - returns Effect<string, PlatformError>
28
+ const readConfig = Effect.gen(function* () {
29
+ const fs = yield* FileSystem.FileSystem
30
+
31
+ // Read file as UTF-8 string
32
+ const content = yield* fs.readFileString("./config.json")
33
+
34
+ return JSON.parse(content)
35
+ })
36
+
37
+ // Write a file
38
+ const writeLog = Effect.gen(function* () {
39
+ const fs = yield* FileSystem.FileSystem
40
+
41
+ yield* fs.writeFileString(
42
+ "./app.log",
43
+ `Started at ${new Date().toISOString()}\n`
44
+ )
45
+ })
46
+
47
+ // Combine operations
48
+ const program = Effect.gen(function* () {
49
+ const config = yield* readConfig
50
+ yield* Effect.log(`Loaded config: ${config.appName}`)
51
+
52
+ yield* writeLog
53
+ yield* Effect.log("Log file created")
54
+ })
55
+
56
+ // Run with Node.js platform
57
+ program.pipe(
58
+ Effect.provide(NodeContext.layer),
59
+ NodeRuntime.runMain
60
+ )
61
+ ```
62
+
63
+ **Rationale:**
64
+
65
+ Effect Platform provides type-safe, cross-platform system operations. Use `@effect/platform-node` for Node.js or `@effect/platform-bun` for Bun.
66
+
67
+ ---
68
+
69
+
70
+ Platform wraps system operations in Effect, giving you:
71
+
72
+ 1. **Type safety** - File operations return `Effect<Content, PlatformError>`
73
+ 2. **Resource management** - Files are automatically closed
74
+ 3. **Cross-platform** - Same code works on Node.js, Bun, browser
75
+ 4. **Composability** - Chain file ops with other effects
76
+
77
+ ---
78
+
79
+ ---
80
+
81
+ ### Access Environment Variables
82
+
83
+ **Rule:** Use Effect to access environment variables with proper error handling.
84
+
85
+ **Good Example:**
86
+
87
+ ```typescript
88
+ import { Effect, Config, Option } from "effect"
89
+
90
+ // ============================================
91
+ // BASIC: Read required variable
92
+ // ============================================
93
+
94
+ const getApiKey = Config.string("API_KEY")
95
+
96
+ const program1 = Effect.gen(function* () {
97
+ const apiKey = yield* getApiKey
98
+ yield* Effect.log(`API Key: ${apiKey.slice(0, 4)}...`)
99
+ })
100
+
101
+ // ============================================
102
+ // OPTIONAL: With default value
103
+ // ============================================
104
+
105
+ const getPort = Config.number("PORT").pipe(
106
+ Config.withDefault(3000)
107
+ )
108
+
109
+ const program2 = Effect.gen(function* () {
110
+ const port = yield* getPort
111
+ yield* Effect.log(`Server will run on port ${port}`)
112
+ })
113
+
114
+ // ============================================
115
+ // OPTIONAL: Return Option instead of failing
116
+ // ============================================
117
+
118
+ const getOptionalFeature = Config.string("FEATURE_FLAG").pipe(
119
+ Config.option
120
+ )
121
+
122
+ const program3 = Effect.gen(function* () {
123
+ const feature = yield* getOptionalFeature
124
+
125
+ if (Option.isSome(feature)) {
126
+ yield* Effect.log(`Feature enabled: ${feature.value}`)
127
+ } else {
128
+ yield* Effect.log("Feature flag not set")
129
+ }
130
+ })
131
+
132
+ // ============================================
133
+ // COMBINED: Multiple variables as config object
134
+ // ============================================
135
+
136
+ const AppConfig = Config.all({
137
+ apiKey: Config.string("API_KEY"),
138
+ apiUrl: Config.string("API_URL"),
139
+ port: Config.number("PORT").pipe(Config.withDefault(3000)),
140
+ debug: Config.boolean("DEBUG").pipe(Config.withDefault(false)),
141
+ })
142
+
143
+ const program4 = Effect.gen(function* () {
144
+ const config = yield* AppConfig
145
+
146
+ yield* Effect.log(`API URL: ${config.apiUrl}`)
147
+ yield* Effect.log(`Port: ${config.port}`)
148
+ yield* Effect.log(`Debug: ${config.debug}`)
149
+ })
150
+
151
+ // ============================================
152
+ // RUN: Will fail if required vars missing
153
+ // ============================================
154
+
155
+ Effect.runPromise(program4).catch((error) => {
156
+ console.error("Missing required environment variables")
157
+ console.error(error)
158
+ })
159
+ ```
160
+
161
+ **Rationale:**
162
+
163
+ Access environment variables using Effect's built-in functions or Platform's environment service for type-safe configuration.
164
+
165
+ ---
166
+
167
+
168
+ Environment variables can be missing or malformed. Effect helps you:
169
+
170
+ 1. **Handle missing vars** - Return `Option` or fail with typed error
171
+ 2. **Validate values** - Parse and validate with Schema
172
+ 3. **Provide defaults** - Fallback values when vars are missing
173
+ 4. **Document requirements** - Types show what's needed
174
+
175
+ ---
176
+
177
+ ---
178
+
179
+
@@ -0,0 +1,233 @@
1
+ ---
2
+ name: effect-patterns-project-setup--execution
3
+ description: Effect-TS patterns for Project Setup Execution. Use when working with project setup execution in Effect-TS applications.
4
+ ---
5
+ # Effect-TS Patterns: Project Setup Execution
6
+ This skill provides 4 curated Effect-TS patterns for project setup execution.
7
+ Use this skill when working on tasks related to:
8
+ - project setup execution
9
+ - Best practices in Effect-TS applications
10
+ - Real-world patterns and solutions
11
+
12
+ ---
13
+
14
+ ## 🟢 Beginner Patterns
15
+
16
+ ### Execute Synchronous Effects with Effect.runSync
17
+
18
+ **Rule:** Execute synchronous effects with Effect.runSync.
19
+
20
+ **Good Example:**
21
+
22
+ ```typescript
23
+ import { Effect } from "effect";
24
+
25
+ // Simple synchronous program
26
+ const program1 = Effect.gen(function* () {
27
+ const n = 10;
28
+ const result = n * 2;
29
+ yield* Effect.log(`Simple program result: ${result}`);
30
+ return result;
31
+ });
32
+
33
+ // Run simple program
34
+ Effect.runSync(program1);
35
+
36
+ // Program with logging
37
+ const program2 = Effect.gen(function* () {
38
+ yield* Effect.logInfo("Starting calculation...");
39
+ const n = yield* Effect.sync(() => 10);
40
+ yield* Effect.logInfo(`Got number: ${n}`);
41
+ const result = yield* Effect.sync(() => n * 2);
42
+ yield* Effect.logInfo(`Result: ${result}`);
43
+ return result;
44
+ });
45
+
46
+ // Run with logging
47
+ Effect.runSync(program2);
48
+
49
+ // Program with error handling
50
+ const program3 = Effect.gen(function* () {
51
+ yield* Effect.logInfo("Starting division...");
52
+ const n = yield* Effect.sync(() => 10);
53
+ const divisor = yield* Effect.sync(() => 0);
54
+
55
+ yield* Effect.logInfo(`Attempting to divide ${n} by ${divisor}...`);
56
+ return yield* Effect.try({
57
+ try: () => {
58
+ if (divisor === 0) throw new Error("Cannot divide by zero");
59
+ return n / divisor;
60
+ },
61
+ catch: (error) => {
62
+ if (error instanceof Error) {
63
+ return error;
64
+ }
65
+ return new Error("Unknown error occurred");
66
+ },
67
+ });
68
+ }).pipe(
69
+ Effect.catchAll((error) => Effect.logInfo(`Error occurred: ${error.message}`))
70
+ );
71
+
72
+ // Run with error handling
73
+ Effect.runSync(program3);
74
+ ```
75
+
76
+ **Explanation:**
77
+ Use `runSync` only for Effects that are fully synchronous. If the Effect
78
+ contains async code, use `runPromise` instead.
79
+
80
+ **Anti-Pattern:**
81
+
82
+ Do not use `runSync` on an Effect that contains asynchronous operations like
83
+ `Effect.delay` or `Effect.promise`. This will result in a runtime error.
84
+
85
+ **Rationale:**
86
+
87
+ To execute an `Effect` that is guaranteed to be synchronous, use
88
+ `Effect.runSync`. This will return the success value directly or throw the
89
+ error.
90
+
91
+
92
+ `Effect.runSync` is an optimized runner for Effects that don't involve any
93
+ asynchronous operations. If the Effect contains any async operations,
94
+ `runSync` will throw an error.
95
+
96
+ ---
97
+
98
+ ### Execute Asynchronous Effects with Effect.runPromise
99
+
100
+ **Rule:** Execute asynchronous effects with Effect.runPromise.
101
+
102
+ **Good Example:**
103
+
104
+ ```typescript
105
+ import { Effect } from "effect";
106
+
107
+ const program = Effect.succeed("Hello, World!").pipe(Effect.delay("1 second"));
108
+
109
+ const promise = Effect.runPromise(program);
110
+
111
+ const programWithLogging = Effect.gen(function* () {
112
+ const result = yield* program;
113
+ yield* Effect.log(result); // Logs "Hello, World!" after 1 second.
114
+ return result;
115
+ });
116
+
117
+ Effect.runPromise(programWithLogging);
118
+ ```
119
+
120
+ **Explanation:**
121
+ `Effect.runPromise` executes your effect and returns a Promise, making it
122
+ easy to integrate with existing JavaScript async workflows.
123
+
124
+ **Anti-Pattern:**
125
+
126
+ Never call `runPromise` inside another `Effect` composition. Effects are
127
+ meant to be composed together _before_ being run once at the end.
128
+
129
+ **Rationale:**
130
+
131
+ To execute an `Effect` that may be asynchronous and retrieve its result, use
132
+ `Effect.runPromise`. This should only be done at the outermost layer of your
133
+ application.
134
+
135
+
136
+ `Effect.runPromise` is the bridge from the Effect world to the Promise-based
137
+ world of Node.js and browsers. If the Effect succeeds, the Promise resolves;
138
+ if it fails, the Promise rejects.
139
+
140
+ ---
141
+
142
+ ### Set Up a New Effect Project
143
+
144
+ **Rule:** Set up a new Effect project.
145
+
146
+ **Good Example:**
147
+
148
+ ```typescript
149
+ // 1. Init project (e.g., `npm init -y`)
150
+ // 2. Install deps (e.g., `npm install effect`, `npm install -D typescript tsx`)
151
+ // 3. Create tsconfig.json with `"strict": true`
152
+ // 4. Create src/index.ts
153
+ import { Effect } from "effect";
154
+
155
+ const program = Effect.log("Hello, World!");
156
+
157
+ Effect.runSync(program);
158
+
159
+ // 5. Run the program (e.g., `npx tsx src/index.ts`)
160
+ ```
161
+
162
+ **Explanation:**
163
+ This setup ensures you have TypeScript and Effect ready to go, with strict
164
+ type-checking for maximum safety and correctness.
165
+
166
+ **Anti-Pattern:**
167
+
168
+ Avoid disabling `strict` mode in your `tsconfig.json`. Running with
169
+ `"strict": false` will cause you to lose many of the type-safety guarantees
170
+ that make Effect so powerful.
171
+
172
+ **Rationale:**
173
+
174
+ To start a new Effect project, initialize a standard Node.js project, add
175
+ `effect` and `typescript` as dependencies, and create a `tsconfig.json` file
176
+ with strict mode enabled.
177
+
178
+
179
+ A proper setup is crucial for leveraging Effect's powerful type-safety
180
+ features. Using TypeScript's `strict` mode is non-negotiable.
181
+
182
+ ---
183
+
184
+
185
+ ## 🟠 Advanced Patterns
186
+
187
+ ### Create a Reusable Runtime from Layers
188
+
189
+ **Rule:** Create a reusable runtime from layers.
190
+
191
+ **Good Example:**
192
+
193
+ ```typescript
194
+ import { Effect, Layer, Runtime } from "effect";
195
+
196
+ class GreeterService extends Effect.Service<GreeterService>()("Greeter", {
197
+ sync: () => ({
198
+ greet: (name: string) => Effect.sync(() => `Hello ${name}`),
199
+ }),
200
+ }) {}
201
+
202
+ const runtime = Effect.runSync(
203
+ Layer.toRuntime(GreeterService.Default).pipe(Effect.scoped)
204
+ );
205
+
206
+ // In a server, you would reuse `run` for every request.
207
+ Runtime.runPromise(runtime)(Effect.log("Hello"));
208
+ ```
209
+
210
+ **Explanation:**
211
+ By compiling your layers into a Runtime once, you avoid rebuilding the
212
+ dependency graph for every effect execution.
213
+
214
+ **Anti-Pattern:**
215
+
216
+ For a long-running application, avoid providing layers and running an effect
217
+ in a single operation. This forces Effect to rebuild the dependency graph on
218
+ every execution.
219
+
220
+ **Rationale:**
221
+
222
+ For applications that need to run multiple effects (e.g., a web server), use
223
+ `Layer.toRuntime(appLayer)` to compile your dependency graph into a single,
224
+ reusable `Runtime` object.
225
+
226
+
227
+ Building the dependency graph from layers has a one-time cost. Creating a
228
+ `Runtime` once when your application starts is highly efficient for
229
+ long-running applications.
230
+
231
+ ---
232
+
233
+