@nicolastoulemont/std 0.3.0 → 0.5.0

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 (148) hide show
  1. package/dist/adt/index.d.mts +1 -1
  2. package/dist/adt/index.mjs +1 -3
  3. package/dist/adt-DZmVJG4P.mjs +2 -0
  4. package/dist/adt-DZmVJG4P.mjs.map +1 -0
  5. package/dist/{apply-fn.types-CXDoeA7D.d.mts → apply-fn.types-CMgY6WQe.d.mts} +1 -1
  6. package/dist/{apply-fn.types-CXDoeA7D.d.mts.map → apply-fn.types-CMgY6WQe.d.mts.map} +1 -1
  7. package/dist/brand/index.d.mts +2 -2
  8. package/dist/brand/index.mjs +1 -3
  9. package/dist/brand-BUqMmkzC.mjs +2 -0
  10. package/dist/{brand-CTaxGuU9.mjs.map → brand-BUqMmkzC.mjs.map} +1 -1
  11. package/dist/data/index.d.mts +1 -1
  12. package/dist/data/index.mjs +1 -3
  13. package/dist/data-DzqKBCQg.mjs +2 -0
  14. package/dist/data-DzqKBCQg.mjs.map +1 -0
  15. package/dist/discriminator.types-DkThfvNE.d.mts +7 -0
  16. package/dist/discriminator.types-DkThfvNE.d.mts.map +1 -0
  17. package/dist/either/index.d.mts +2 -2
  18. package/dist/either/index.mjs +1 -3
  19. package/dist/either-BDY9T5oz.mjs +2 -0
  20. package/dist/either-BDY9T5oz.mjs.map +1 -0
  21. package/dist/equality-D2EJvZm4.mjs +2 -0
  22. package/dist/equality-D2EJvZm4.mjs.map +1 -0
  23. package/dist/err/index.d.mts +2 -2
  24. package/dist/err/index.mjs +1 -3
  25. package/dist/err-CYs4b1RV.mjs +2 -0
  26. package/dist/err-CYs4b1RV.mjs.map +1 -0
  27. package/dist/flow/index.d.mts +1 -1
  28. package/dist/flow/index.mjs +1 -3
  29. package/dist/flow-CxKQ5yac.mjs +2 -0
  30. package/dist/flow-CxKQ5yac.mjs.map +1 -0
  31. package/dist/fx/index.d.mts +3 -0
  32. package/dist/fx/index.mjs +1 -0
  33. package/dist/fx-C4UuWCqP.mjs +2 -0
  34. package/dist/fx-C4UuWCqP.mjs.map +1 -0
  35. package/dist/fx.types-CXTwEa1G.mjs +2 -0
  36. package/dist/fx.types-CXTwEa1G.mjs.map +1 -0
  37. package/dist/fx.types-DO-8yG4c.d.mts +133 -0
  38. package/dist/fx.types-DO-8yG4c.d.mts.map +1 -0
  39. package/dist/index-78LWwTds.d.mts +288 -0
  40. package/dist/index-78LWwTds.d.mts.map +1 -0
  41. package/dist/index-BQ5wVDSP.d.mts +441 -0
  42. package/dist/index-BQ5wVDSP.d.mts.map +1 -0
  43. package/dist/{index-tkgTLCoq.d.mts → index-BahMvQpA.d.mts} +2 -2
  44. package/dist/{index-tkgTLCoq.d.mts.map → index-BahMvQpA.d.mts.map} +1 -1
  45. package/dist/index-Bs5TTFlK.d.mts +882 -0
  46. package/dist/index-Bs5TTFlK.d.mts.map +1 -0
  47. package/dist/index-BuLJRX1e.d.mts +476 -0
  48. package/dist/index-BuLJRX1e.d.mts.map +1 -0
  49. package/dist/{index-BR7takNf.d.mts → index-CDio8mJY.d.mts} +65 -26
  50. package/dist/index-CDio8mJY.d.mts.map +1 -0
  51. package/dist/{index-Cp_4sFun.d.mts → index-DLlx9jiG.d.mts} +38 -43
  52. package/dist/index-DLlx9jiG.d.mts.map +1 -0
  53. package/dist/index-DQoTXLSm.d.mts +846 -0
  54. package/dist/index-DQoTXLSm.d.mts.map +1 -0
  55. package/dist/index-DjjJIDaA.d.mts +221 -0
  56. package/dist/index-DjjJIDaA.d.mts.map +1 -0
  57. package/dist/{index-BCrD3pEs.d.mts → index-DtAPrec7.d.mts} +18 -18
  58. package/dist/index-DtAPrec7.d.mts.map +1 -0
  59. package/dist/{index-zC2zAtZY.d.mts → index-IdejL485.d.mts} +2 -2
  60. package/dist/{index-zC2zAtZY.d.mts.map → index-IdejL485.d.mts.map} +1 -1
  61. package/dist/index.d.mts +16 -802
  62. package/dist/index.mjs +1 -1393
  63. package/dist/option/index.d.mts +3 -3
  64. package/dist/option/index.mjs +1 -3
  65. package/dist/option-Qiv7Ls7L.mjs +2 -0
  66. package/dist/option-Qiv7Ls7L.mjs.map +1 -0
  67. package/dist/option.types-By5UOfC2.mjs +2 -0
  68. package/dist/option.types-By5UOfC2.mjs.map +1 -0
  69. package/dist/option.types-Cluybn30.d.mts +167 -0
  70. package/dist/option.types-Cluybn30.d.mts.map +1 -0
  71. package/dist/pipe/index.d.mts +1 -1
  72. package/dist/pipe/index.mjs +1 -3
  73. package/dist/pipe-BROILDeC.mjs +2 -0
  74. package/dist/{pipe-GYxZNkPB.mjs.map → pipe-BROILDeC.mjs.map} +1 -1
  75. package/dist/pipeable-KHu4D8ol.d.mts +27 -0
  76. package/dist/pipeable-KHu4D8ol.d.mts.map +1 -0
  77. package/dist/pipeable-rQvolRqh.mjs +2 -0
  78. package/dist/pipeable-rQvolRqh.mjs.map +1 -0
  79. package/dist/predicate/index.d.mts +2 -2
  80. package/dist/predicate/index.mjs +1 -3
  81. package/dist/predicate-DvXnfmeJ.mjs +2 -0
  82. package/dist/{predicate-BZkZmo-W.mjs.map → predicate-DvXnfmeJ.mjs.map} +1 -1
  83. package/dist/result/index.d.mts +3 -3
  84. package/dist/result/index.mjs +1 -3
  85. package/dist/result-B68pxC7l.mjs +2 -0
  86. package/dist/result-B68pxC7l.mjs.map +1 -0
  87. package/dist/result-uRORQlAQ.mjs +1 -0
  88. package/dist/result.types-fIbuBwVQ.d.mts +259 -0
  89. package/dist/result.types-fIbuBwVQ.d.mts.map +1 -0
  90. package/package.json +1 -9
  91. package/dist/adt-DraJkmij.mjs +0 -318
  92. package/dist/adt-DraJkmij.mjs.map +0 -1
  93. package/dist/brand-CTaxGuU9.mjs +0 -165
  94. package/dist/data-DgzWI4R_.mjs +0 -244
  95. package/dist/data-DgzWI4R_.mjs.map +0 -1
  96. package/dist/discriminator.types-DCkkrCj4.d.mts +0 -7
  97. package/dist/discriminator.types-DCkkrCj4.d.mts.map +0 -1
  98. package/dist/either-CnOBUH7a.mjs +0 -598
  99. package/dist/either-CnOBUH7a.mjs.map +0 -1
  100. package/dist/equality/index.d.mts +0 -86
  101. package/dist/equality/index.d.mts.map +0 -1
  102. package/dist/equality/index.mjs +0 -3
  103. package/dist/equality-YMebYwm1.mjs +0 -201
  104. package/dist/equality-YMebYwm1.mjs.map +0 -1
  105. package/dist/err-BqQApH9r.mjs +0 -169
  106. package/dist/err-BqQApH9r.mjs.map +0 -1
  107. package/dist/flow-pRdnqmMY.mjs +0 -21
  108. package/dist/flow-pRdnqmMY.mjs.map +0 -1
  109. package/dist/fn/index.d.mts +0 -2
  110. package/dist/fn/index.mjs +0 -3
  111. package/dist/fn-DFHj-EVA.mjs +0 -10
  112. package/dist/fn-DFHj-EVA.mjs.map +0 -1
  113. package/dist/gen/index.d.mts +0 -3
  114. package/dist/gen/index.mjs +0 -3
  115. package/dist/gen-DF-FXNdy.mjs +0 -99
  116. package/dist/gen-DF-FXNdy.mjs.map +0 -1
  117. package/dist/index-B3z7T6Dz.d.mts +0 -57
  118. package/dist/index-B3z7T6Dz.d.mts.map +0 -1
  119. package/dist/index-BCrD3pEs.d.mts.map +0 -1
  120. package/dist/index-BFhV56qy.d.mts +0 -105
  121. package/dist/index-BFhV56qy.d.mts.map +0 -1
  122. package/dist/index-BLG9B4bn.d.mts +0 -116
  123. package/dist/index-BLG9B4bn.d.mts.map +0 -1
  124. package/dist/index-BR7takNf.d.mts.map +0 -1
  125. package/dist/index-BiFc2xWF.d.mts +0 -211
  126. package/dist/index-BiFc2xWF.d.mts.map +0 -1
  127. package/dist/index-BwVaI5d0.d.mts +0 -79
  128. package/dist/index-BwVaI5d0.d.mts.map +0 -1
  129. package/dist/index-CckxkaUd.d.mts +0 -80
  130. package/dist/index-CckxkaUd.d.mts.map +0 -1
  131. package/dist/index-Cp_4sFun.d.mts.map +0 -1
  132. package/dist/index-DbfMra4p.d.mts +0 -72
  133. package/dist/index-DbfMra4p.d.mts.map +0 -1
  134. package/dist/index.d.mts.map +0 -1
  135. package/dist/index.mjs.map +0 -1
  136. package/dist/is-promise-BEl3eGZg.mjs +0 -11
  137. package/dist/is-promise-BEl3eGZg.mjs.map +0 -1
  138. package/dist/option-CKHDOVea.mjs +0 -410
  139. package/dist/option-CKHDOVea.mjs.map +0 -1
  140. package/dist/option.types-eqVODMIy.d.mts +0 -89
  141. package/dist/option.types-eqVODMIy.d.mts.map +0 -1
  142. package/dist/pipe-GYxZNkPB.mjs +0 -10
  143. package/dist/predicate-BZkZmo-W.mjs +0 -293
  144. package/dist/result-C5tPWR60.mjs +0 -422
  145. package/dist/result-C5tPWR60.mjs.map +0 -1
  146. package/dist/result-D7XJ96pv.mjs +0 -1
  147. package/dist/result.types-Bd8a43Fg.d.mts +0 -174
  148. package/dist/result.types-Bd8a43Fg.d.mts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,1393 +1 @@
1
- import { n as err, r as ok, t as Result } from "./result-C5tPWR60.mjs";
2
- import { n as data, r as record } from "./adt-DraJkmij.mjs";
3
- import { t as Brand } from "./brand-CTaxGuU9.mjs";
4
- import { i as tagged, n as tuple, r as struct, t as array } from "./data-DgzWI4R_.mjs";
5
- import { n as ensureRefinement, r as gen, t as ensure } from "./gen-DF-FXNdy.mjs";
6
- import { t as Option } from "./option-CKHDOVea.mjs";
7
- import { t as Either } from "./either-CnOBUH7a.mjs";
8
- import { n as TaggedError, t as Err } from "./err-BqQApH9r.mjs";
9
- import { t as flow } from "./flow-pRdnqmMY.mjs";
10
- import "./flow/index.mjs";
11
- import { t as pipe } from "./pipe-GYxZNkPB.mjs";
12
- import { t as Predicate } from "./predicate-BZkZmo-W.mjs";
13
- import { t as fn } from "./fn-DFHj-EVA.mjs";
14
-
15
- //#region src/fx/fx.ts
16
- /**
17
- * Implementation of unified Fx.gen function.
18
- * Detects sync vs async generator and returns appropriate computation type.
19
- */
20
- function fxGen(generatorFn) {
21
- const testGen = generatorFn();
22
- if (Symbol.asyncIterator in testGen) return {
23
- _tag: "AsyncFx",
24
- run: async () => {
25
- const result = await generatorFn().next();
26
- if (result.done !== true) {
27
- const yielded = result.value;
28
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") throw new Error(`Service "${yielded.serviceKey}" not provided. Use provide() to inject services.`);
29
- return err(yielded);
30
- }
31
- return ok(result.value);
32
- },
33
- async *[Symbol.asyncIterator]() {
34
- const gen$1 = generatorFn();
35
- let result = await gen$1.next();
36
- while (!result.done) {
37
- const injected = yield result.value;
38
- result = await gen$1.next(injected);
39
- }
40
- return result.value;
41
- }
42
- };
43
- return {
44
- _tag: "SyncFx",
45
- run: () => {
46
- const result = generatorFn().next();
47
- if (result.done !== true) {
48
- const yielded = result.value;
49
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") throw new Error(`Service "${yielded.serviceKey}" not provided. Use provide() to inject services.`);
50
- return err(yielded);
51
- }
52
- return ok(result.value);
53
- },
54
- *[Symbol.iterator]() {
55
- const gen$1 = generatorFn();
56
- let result = gen$1.next();
57
- while (!result.done) {
58
- const injected = yield result.value;
59
- result = gen$1.next(injected);
60
- }
61
- return result.value;
62
- }
63
- };
64
- }
65
- /**
66
- * Implementation of Fx.fn.
67
- */
68
- function fxFn(generatorFn, provider) {
69
- const testGen = generatorFn();
70
- const isAsync = Symbol.asyncIterator in testGen;
71
- if (provider) if (isAsync) return provider({
72
- _tag: "AsyncFx",
73
- run: async () => {
74
- throw new Error("Should not be called directly - use provider");
75
- },
76
- async *[Symbol.asyncIterator]() {
77
- const gen$1 = generatorFn();
78
- let result$1 = await gen$1.next();
79
- while (!result$1.done) {
80
- const injected = yield result$1.value;
81
- result$1 = await gen$1.next(injected);
82
- }
83
- return result$1.value;
84
- }
85
- }).run();
86
- else return provider({
87
- _tag: "SyncFx",
88
- run: () => {
89
- throw new Error("Should not be called directly - use provider");
90
- },
91
- *[Symbol.iterator]() {
92
- const gen$1 = generatorFn();
93
- let result$1 = gen$1.next();
94
- while (!result$1.done) {
95
- const injected = yield result$1.value;
96
- result$1 = gen$1.next(injected);
97
- }
98
- return result$1.value;
99
- }
100
- }).run();
101
- if (isAsync) return (async () => {
102
- let result$1 = await generatorFn().next();
103
- while (!result$1.done) return err(result$1.value);
104
- return ok(result$1.value);
105
- })();
106
- let result = generatorFn().next();
107
- while (!result.done) return err(result.value);
108
- return ok(result.value);
109
- }
110
- /**
111
- * Convenience alias for Result.ok.
112
- * Creates a successful Result that can be yielded in an Fx computation.
113
- *
114
- * @param value - The success value
115
- * @returns Result<T, never>
116
- *
117
- * @example
118
- * ```ts
119
- * const workflow = Fx.gen(function* () {
120
- * const value = yield* Fx.ok(42)
121
- * return value * 2
122
- * })
123
- * ```
124
- */
125
- const fxOk = ok;
126
- /**
127
- * Convenience alias for Result.err.
128
- * Creates an error Result that can be yielded in an Fx computation.
129
- *
130
- * @param error - The error value
131
- * @returns Result<never, E>
132
- *
133
- * @example
134
- * ```ts
135
- * const workflow = Fx.gen(function* () {
136
- * const config = yield* Config
137
- *
138
- * if (!config.dbUrl) {
139
- * return yield* Fx.err(new ValidationError({ field: "dbUrl" }))
140
- * }
141
- *
142
- * return config.dbUrl
143
- * })
144
- * ```
145
- */
146
- const fxErr = err;
147
- /**
148
- * Fx namespace containing utilities for creating and running effectful computations.
149
- *
150
- * Fx provides a minimal API inspired by Effect.ts:
151
- * - `Fx.gen()` - Create composable computations with service dependencies
152
- * - `Fx.fn()` - Execute computations immediately
153
- * - `Fx.ok()` - Create successful results (alias for Result.ok)
154
- * - `Fx.err()` - Create error results (alias for Result.err)
155
- *
156
- * @example
157
- * ```ts
158
- * import { Fx, Service, Layer, provide, pipe } from "@repo/std"
159
- *
160
- * // Define services
161
- * class Config extends Service<Config>()("Config") {
162
- * readonly dbUrl!: string
163
- * }
164
- *
165
- * class Logger extends Service<Logger>()("Logger") {
166
- * readonly info!: (msg: string) => void
167
- * }
168
- *
169
- * // Create layers
170
- * const ConfigLive = Layer.ok(Config, { dbUrl: "postgres://..." })
171
- * const LoggerLive = Layer.fx(Logger)(
172
- * Fx.gen(function* () {
173
- * const config = yield* Config
174
- * return { info: (msg) => console.log(`[${config.dbUrl}] ${msg}`) }
175
- * })
176
- * )
177
- *
178
- * // Create workflow
179
- * const myWorkflow = Fx.gen(function* () {
180
- * const logger = yield* Logger
181
- * logger.info("Hello from Fx!")
182
- * return "done"
183
- * })
184
- *
185
- * // Compose and run
186
- * const AppLayer = pipe(ConfigLive, Layer.provide(LoggerLive))
187
- * const result = pipe(myWorkflow, provide(AppLayer)).run()
188
- * ```
189
- */
190
- const Fx = {
191
- gen: fxGen,
192
- fn: fxFn,
193
- ok: fxOk,
194
- err: fxErr
195
- };
196
-
197
- //#endregion
198
- //#region src/fx/service.ts
199
- /**
200
- * Define a service with a unique key.
201
- * The returned class acts as both a type and a runtime tag for lookup.
202
- *
203
- * Usage follows a double-invocation pattern:
204
- * - First call provides the Self type parameter
205
- * - Second call provides the unique key
206
- *
207
- * @example
208
- * ```ts
209
- * class Config extends Service<Config>()("Config") {
210
- * readonly dbUrl!: string
211
- * readonly logLevel!: "debug" | "info" | "error"
212
- * }
213
- *
214
- * class Logger extends Service<Logger>()("Logger") {
215
- * readonly info!: (msg: string) => void
216
- * readonly error!: (msg: string) => void
217
- * }
218
- *
219
- * // Use in Fx.gen:
220
- * const workflow = Fx.gen(function* () {
221
- * const config = yield* Config
222
- * const logger = yield* Logger
223
- * logger.info(`DB URL: ${config.dbUrl}`)
224
- * })
225
- * ```
226
- */
227
- function Service() {
228
- return (key) => {
229
- const ServiceBase = class {
230
- static _tag = "Service";
231
- static key = key;
232
- static _Self = void 0;
233
- /**
234
- * Yielding the class returns a ServiceRequest.
235
- * The runtime intercepts this and provides the actual service instance.
236
- */
237
- static *[Symbol.iterator]() {
238
- return yield {
239
- _tag: "ServiceRequest",
240
- _service: void 0,
241
- serviceKey: key
242
- };
243
- }
244
- };
245
- return ServiceBase;
246
- };
247
- }
248
- /**
249
- * Create a service tag without class syntax.
250
- * Useful for simple services that don't need class inheritance.
251
- *
252
- * @example
253
- * ```ts
254
- * interface ConfigService {
255
- * readonly dbUrl: string
256
- * readonly logLevel: "debug" | "info" | "error"
257
- * }
258
- *
259
- * const Config = serviceTag<ConfigService>("Config")
260
- *
261
- * // Use in Fx.gen:
262
- * const workflow = Fx.gen(function* () {
263
- * const config = yield* Config
264
- * console.log(config.dbUrl)
265
- * })
266
- * ```
267
- */
268
- function serviceTag(key) {
269
- return {
270
- _tag: "Service",
271
- key,
272
- _Self: void 0,
273
- *[Symbol.iterator]() {
274
- return yield {
275
- _tag: "ServiceRequest",
276
- _service: void 0,
277
- serviceKey: key
278
- };
279
- }
280
- };
281
- }
282
-
283
- //#endregion
284
- //#region src/fx/context.ts
285
- /**
286
- * Create an empty context with no services.
287
- */
288
- const empty = () => ({
289
- _tag: "Context",
290
- _services: /* @__PURE__ */ new Map(),
291
- _Services: void 0
292
- });
293
- /**
294
- * Create a context with a single service.
295
- *
296
- * @param service - The service class (tag)
297
- * @param impl - The service implementation
298
- * @returns A context containing the service
299
- *
300
- * @example
301
- * ```ts
302
- * const ctx = Context.make(Config, { dbUrl: "postgres://...", logLevel: "info" })
303
- * ```
304
- */
305
- const make = (service, impl) => ({
306
- _tag: "Context",
307
- _services: new Map([[service.key, impl]]),
308
- _Services: void 0
309
- });
310
- /**
311
- * Add a service to an existing context (returns new context).
312
- * Curried for use with pipe.
313
- *
314
- * @param service - The service class (tag)
315
- * @param impl - The service implementation
316
- * @returns A function that takes a context and returns a new context with the service added
317
- *
318
- * @example
319
- * ```ts
320
- * const ctx = pipe(
321
- * Context.empty(),
322
- * Context.add(Config, configImpl),
323
- * Context.add(Logger, loggerImpl),
324
- * )
325
- * ```
326
- */
327
- const add = (service, impl) => (ctx) => ({
328
- _tag: "Context",
329
- _services: new Map([...ctx._services, [service.key, impl]]),
330
- _Services: void 0
331
- });
332
- /**
333
- * Merge two contexts together.
334
- * If both contexts have the same service, the second context's implementation wins.
335
- *
336
- * @param a - First context
337
- * @param b - Second context
338
- * @returns A new context with services from both
339
- *
340
- * @example
341
- * ```ts
342
- * const ctx = Context.merge(configContext, loggerContext)
343
- * ```
344
- */
345
- const merge = (a, b) => ({
346
- _tag: "Context",
347
- _services: new Map([...a._services, ...b._services]),
348
- _Services: void 0
349
- });
350
- function get(ctxOrService, maybeService) {
351
- if (maybeService === void 0) {
352
- const service$1 = ctxOrService;
353
- return (ctx$1) => {
354
- const impl$1 = ctx$1._services.get(service$1.key);
355
- if (impl$1 === void 0) throw new Error(`Service "${service$1.key}" not found in context. Available services: [${[...ctx$1._services.keys()].join(", ")}]`);
356
- return impl$1;
357
- };
358
- }
359
- const ctx = ctxOrService;
360
- const service = maybeService;
361
- const impl = ctx._services.get(service.key);
362
- if (impl === void 0) throw new Error(`Service "${service.key}" not found in context. Available services: [${[...ctx._services.keys()].join(", ")}]`);
363
- return impl;
364
- }
365
- /**
366
- * Unsafely get a service from a context by key string.
367
- * Used internally by the runtime when resolving ServiceRequests.
368
- * Returns undefined if not found (caller should handle).
369
- */
370
- const unsafeGet = (ctx, key) => ctx._services.get(key);
371
- /**
372
- * Check if a context contains a specific service.
373
- *
374
- * @param ctx - The context to check
375
- * @param service - The service class (tag)
376
- * @returns true if the service is in the context
377
- */
378
- const has = (ctx, service) => ctx._services.has(service.key);
379
- /**
380
- * Get all service keys in a context.
381
- */
382
- const keys = (ctx) => [...ctx._services.keys()];
383
- /**
384
- * Get the size (number of services) in a context.
385
- */
386
- const size = (ctx) => ctx._services.size;
387
- /**
388
- * Check if a value is a Context.
389
- */
390
- const isContext = (value) => typeof value === "object" && value !== null && "_tag" in value && value._tag === "Context";
391
- /**
392
- * Context namespace containing utilities for managing service contexts.
393
- *
394
- * A Context is an immutable map of services that can be provided to Fx computations.
395
- * Services are identified by their unique keys.
396
- *
397
- * @example
398
- * ```ts
399
- * import { Context, Service } from "@repo/std"
400
- *
401
- * class Config extends Service<Config>()("Config") {
402
- * readonly dbUrl!: string
403
- * }
404
- *
405
- * class Logger extends Service<Logger>()("Logger") {
406
- * readonly info!: (msg: string) => void
407
- * }
408
- *
409
- * // Create a context with services
410
- * const ctx = pipe(
411
- * Context.empty(),
412
- * Context.add(Config, { dbUrl: "postgres://..." }),
413
- * Context.add(Logger, { info: console.log }),
414
- * )
415
- *
416
- * // Or use make and merge
417
- * const configCtx = Context.make(Config, { dbUrl: "postgres://..." })
418
- * const loggerCtx = Context.make(Logger, { info: console.log })
419
- * const fullCtx = Context.merge(configCtx, loggerCtx)
420
- * ```
421
- */
422
- const Context = {
423
- empty,
424
- make,
425
- add,
426
- merge,
427
- get,
428
- unsafeGet,
429
- has,
430
- keys,
431
- size,
432
- isContext
433
- };
434
-
435
- //#endregion
436
- //#region src/fx/layer.ts
437
- /**
438
- * Create a layer from a synchronous value (no dependencies).
439
- */
440
- const layerOk = (service, impl) => ({
441
- _tag: "Layer",
442
- _ROut: void 0,
443
- _E: void 0,
444
- _RIn: void 0,
445
- build: () => ({
446
- _tag: "SyncFx",
447
- run: () => ok(Context.make(service, impl)),
448
- *[Symbol.iterator]() {
449
- return Context.make(service, impl);
450
- }
451
- })
452
- });
453
- /**
454
- * Create a layer that always fails with an error.
455
- */
456
- const layerErr = (error) => ({
457
- _tag: "Layer",
458
- _ROut: void 0,
459
- _E: void 0,
460
- _RIn: void 0,
461
- build: () => ({
462
- _tag: "SyncFx",
463
- run: () => ({
464
- ok: false,
465
- error,
466
- *[Symbol.iterator]() {
467
- yield error;
468
- throw new Error("Unreachable");
469
- }
470
- }),
471
- *[Symbol.iterator]() {
472
- yield error;
473
- throw new Error("Unreachable");
474
- }
475
- })
476
- });
477
- /**
478
- * Create a layer from an Fx computation (can have dependencies).
479
- */
480
- const layerFx = (service) => (fx) => ({
481
- _tag: "Layer",
482
- _ROut: void 0,
483
- _E: void 0,
484
- _RIn: void 0,
485
- build: () => {
486
- if (fx._tag === "AsyncFx") return {
487
- _tag: "AsyncFx",
488
- run: async () => {
489
- throw new Error("Layer build should use iterator");
490
- },
491
- async *[Symbol.asyncIterator]() {
492
- const gen$1 = fx[Symbol.asyncIterator]();
493
- let result = await gen$1.next();
494
- while (!result.done) {
495
- const value = yield result.value;
496
- result = await gen$1.next(value);
497
- }
498
- return Context.make(service, result.value);
499
- }
500
- };
501
- return {
502
- _tag: "SyncFx",
503
- run: () => {
504
- throw new Error("Layer build should use iterator");
505
- },
506
- *[Symbol.iterator]() {
507
- const gen$1 = fx[Symbol.iterator]();
508
- let result = gen$1.next();
509
- while (!result.done) {
510
- const value = yield result.value;
511
- result = gen$1.next(value);
512
- }
513
- return Context.make(service, result.value);
514
- }
515
- };
516
- }
517
- });
518
- /**
519
- * Create a scoped layer (with resource cleanup).
520
- */
521
- const layerScoped = (service) => (fx) => ({
522
- _tag: "Layer",
523
- _ROut: void 0,
524
- _E: void 0,
525
- _RIn: void 0,
526
- build: (_memoMap, scope) => {
527
- if (fx._tag === "AsyncFx") return {
528
- _tag: "AsyncFx",
529
- run: async () => {
530
- throw new Error("Layer build should use iterator");
531
- },
532
- async *[Symbol.asyncIterator]() {
533
- const gen$1 = fx[Symbol.asyncIterator]();
534
- let result = await gen$1.next();
535
- while (!result.done) {
536
- const yielded = result.value;
537
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === "@std/Scope") result = await gen$1.next(scope);
538
- else {
539
- const value = yield yielded;
540
- result = await gen$1.next(value);
541
- }
542
- }
543
- return Context.make(service, result.value);
544
- }
545
- };
546
- return {
547
- _tag: "SyncFx",
548
- run: () => {
549
- throw new Error("Layer build should use iterator");
550
- },
551
- *[Symbol.iterator]() {
552
- const gen$1 = fx[Symbol.iterator]();
553
- let result = gen$1.next();
554
- while (!result.done) {
555
- const yielded = result.value;
556
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === "@std/Scope") result = gen$1.next(scope);
557
- else {
558
- const value = yield yielded;
559
- result = gen$1.next(value);
560
- }
561
- }
562
- return Context.make(service, result.value);
563
- }
564
- };
565
- }
566
- });
567
- /**
568
- * Provide dependencies to a layer and merge outputs.
569
- */
570
- const layerProvide = (deps) => (layer) => ({
571
- _tag: "Layer",
572
- _ROut: void 0,
573
- _E: void 0,
574
- _RIn: void 0,
575
- build: (memoMap, scope) => {
576
- const depsBuildFx = deps.build(memoMap, scope);
577
- if (depsBuildFx._tag === "AsyncFx") return {
578
- _tag: "AsyncFx",
579
- run: async () => {
580
- throw new Error("Layer build should use iterator");
581
- },
582
- async *[Symbol.asyncIterator]() {
583
- const depsGen = depsBuildFx[Symbol.asyncIterator]();
584
- let depsResult = await depsGen.next();
585
- while (!depsResult.done) {
586
- const value = yield depsResult.value;
587
- depsResult = await depsGen.next(value);
588
- }
589
- const depsCtx = depsResult.value;
590
- const layerBuildFx = layer.build(memoMap, scope);
591
- if (layerBuildFx._tag === "AsyncFx") {
592
- const layerGen$1 = layerBuildFx[Symbol.asyncIterator]();
593
- let layerResult$1 = await layerGen$1.next();
594
- while (!layerResult$1.done) {
595
- const yielded = layerResult$1.value;
596
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
597
- const service = depsCtx._services.get(yielded.serviceKey);
598
- if (service !== void 0) {
599
- layerResult$1 = await layerGen$1.next(service);
600
- continue;
601
- }
602
- }
603
- const value = yield yielded;
604
- layerResult$1 = await layerGen$1.next(value);
605
- }
606
- return Context.merge(depsCtx, layerResult$1.value);
607
- }
608
- const layerGen = layerBuildFx[Symbol.iterator]();
609
- let layerResult = layerGen.next();
610
- while (!layerResult.done) {
611
- const yielded = layerResult.value;
612
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
613
- const service = depsCtx._services.get(yielded.serviceKey);
614
- if (service !== void 0) {
615
- layerResult = layerGen.next(service);
616
- continue;
617
- }
618
- }
619
- const value = yield yielded;
620
- layerResult = layerGen.next(value);
621
- }
622
- return Context.merge(depsCtx, layerResult.value);
623
- }
624
- };
625
- return {
626
- _tag: "SyncFx",
627
- run: () => {
628
- throw new Error("Layer build should use iterator");
629
- },
630
- *[Symbol.iterator]() {
631
- const depsGen = depsBuildFx[Symbol.iterator]();
632
- let depsResult = depsGen.next();
633
- while (!depsResult.done) {
634
- const value = yield depsResult.value;
635
- depsResult = depsGen.next(value);
636
- }
637
- const depsCtx = depsResult.value;
638
- const layerBuildFx = layer.build(memoMap, scope);
639
- if (layerBuildFx._tag === "SyncFx") {
640
- const syncGen = layerBuildFx[Symbol.iterator]();
641
- let layerResult = syncGen.next();
642
- while (!layerResult.done) {
643
- const yielded = layerResult.value;
644
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
645
- const service = depsCtx._services.get(yielded.serviceKey);
646
- if (service !== void 0) {
647
- layerResult = syncGen.next(service);
648
- continue;
649
- }
650
- }
651
- const value = yield yielded;
652
- layerResult = syncGen.next(value);
653
- }
654
- return Context.merge(depsCtx, layerResult.value);
655
- }
656
- throw new Error("Cannot use async layer in sync context");
657
- }
658
- };
659
- }
660
- });
661
- /**
662
- * Merge multiple layers with automatic dependency resolution.
663
- */
664
- const layerMerge = (...layers) => ({
665
- _tag: "Layer",
666
- _ROut: void 0,
667
- _E: void 0,
668
- _RIn: void 0,
669
- build: (memoMap, scope) => {
670
- if (layers.some((l) => l.build(memoMap, scope)._tag === "AsyncFx")) return {
671
- _tag: "AsyncFx",
672
- run: async () => {
673
- throw new Error("Layer build should use iterator");
674
- },
675
- async *[Symbol.asyncIterator]() {
676
- let ctx = Context.empty();
677
- for (const layer of layers) {
678
- const buildFx = layer.build(memoMap, scope);
679
- if (buildFx._tag === "AsyncFx") {
680
- const gen$1 = buildFx[Symbol.asyncIterator]();
681
- let result = await gen$1.next();
682
- while (!result.done) {
683
- const yielded = result.value;
684
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
685
- const service = ctx._services.get(yielded.serviceKey);
686
- if (service !== void 0) {
687
- result = await gen$1.next(service);
688
- continue;
689
- }
690
- }
691
- const value = yield yielded;
692
- result = await gen$1.next(value);
693
- }
694
- ctx = Context.merge(ctx, result.value);
695
- } else {
696
- const gen$1 = buildFx[Symbol.iterator]();
697
- let result = gen$1.next();
698
- while (!result.done) {
699
- const yielded = result.value;
700
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
701
- const service = ctx._services.get(yielded.serviceKey);
702
- if (service !== void 0) {
703
- result = gen$1.next(service);
704
- continue;
705
- }
706
- }
707
- const value = yield yielded;
708
- result = gen$1.next(value);
709
- }
710
- ctx = Context.merge(ctx, result.value);
711
- }
712
- }
713
- return ctx;
714
- }
715
- };
716
- return {
717
- _tag: "SyncFx",
718
- run: () => {
719
- throw new Error("Layer build should use iterator");
720
- },
721
- *[Symbol.iterator]() {
722
- let ctx = Context.empty();
723
- for (const layer of layers) {
724
- const buildFx = layer.build(memoMap, scope);
725
- if (buildFx._tag !== "SyncFx") throw new Error("Expected sync layer in sync context");
726
- const gen$1 = buildFx[Symbol.iterator]();
727
- let result = gen$1.next();
728
- while (!result.done) {
729
- const yielded = result.value;
730
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
731
- const service = ctx._services.get(yielded.serviceKey);
732
- if (service !== void 0) {
733
- result = gen$1.next(service);
734
- continue;
735
- }
736
- }
737
- const value = yield yielded;
738
- result = gen$1.next(value);
739
- }
740
- ctx = Context.merge(ctx, result.value);
741
- }
742
- return ctx;
743
- }
744
- };
745
- }
746
- });
747
- const Layer = {
748
- ok: layerOk,
749
- err: layerErr,
750
- fx: layerFx,
751
- scoped: layerScoped,
752
- provide: layerProvide,
753
- merge: layerMerge
754
- };
755
-
756
- //#endregion
757
- //#region src/fx/scope.ts
758
- var ScopeTag = class extends Service()("@std/Scope") {};
759
- /**
760
- * Create a new Scope instance.
761
- * This is the concrete implementation of the ScopeService interface.
762
- */
763
- function createScope() {
764
- const finalizers = [];
765
- let closed = false;
766
- const children = [];
767
- return {
768
- addFinalizer(finalizer) {
769
- return {
770
- _tag: "SyncFx",
771
- get run() {
772
- return (() => {
773
- if (!closed) finalizers.push(finalizer);
774
- return ok(void 0);
775
- });
776
- },
777
- *[Symbol.iterator]() {
778
- if (!closed) finalizers.push(finalizer);
779
- }
780
- };
781
- },
782
- close(exit) {
783
- if (finalizers.some((f) => {
784
- return f()._tag === "AsyncFx";
785
- })) return {
786
- _tag: "AsyncFx",
787
- get run() {
788
- return (async () => {
789
- if (closed) return ok(void 0);
790
- closed = true;
791
- for (const child of [...children].toReversed()) {
792
- const childClose = child.close(exit);
793
- if (childClose._tag === "AsyncFx") await childClose.run();
794
- else childClose.run();
795
- }
796
- const reversed = [...finalizers].toReversed();
797
- for (const finalizer of reversed) {
798
- const fx = finalizer();
799
- if (fx._tag === "AsyncFx") await fx.run();
800
- else fx.run();
801
- }
802
- return ok(void 0);
803
- });
804
- },
805
- async *[Symbol.asyncIterator]() {
806
- if (closed) return;
807
- closed = true;
808
- for (const child of [...children].toReversed()) {
809
- const childClose = child.close(exit);
810
- if (childClose._tag === "AsyncFx") await childClose.run();
811
- else childClose.run();
812
- }
813
- const reversed = [...finalizers].toReversed();
814
- for (const finalizer of reversed) {
815
- const fx = finalizer();
816
- if (fx._tag === "AsyncFx") await fx.run();
817
- else fx.run();
818
- }
819
- }
820
- };
821
- return {
822
- _tag: "SyncFx",
823
- get run() {
824
- return (() => {
825
- if (closed) return ok(void 0);
826
- closed = true;
827
- for (const child of [...children].toReversed()) child.close(exit).run();
828
- const reversed = [...finalizers].toReversed();
829
- for (const finalizer of reversed) finalizer().run();
830
- return ok(void 0);
831
- });
832
- },
833
- *[Symbol.iterator]() {
834
- if (closed) return;
835
- closed = true;
836
- for (const child of [...children].toReversed()) child.close(exit).run();
837
- const reversed = [...finalizers].toReversed();
838
- for (const finalizer of reversed) finalizer().run();
839
- }
840
- };
841
- },
842
- fork() {
843
- const child = createScope();
844
- children.push(child);
845
- return child;
846
- }
847
- };
848
- }
849
-
850
- //#endregion
851
- //#region src/fx/memo-map.ts
852
- /**
853
- * MemoMap caches built layers so each layer is only built once.
854
- * Multiple dependents share the same service instance.
855
- *
856
- * This implements the "service singleton" pattern where a service
857
- * is instantiated once and shared across all consumers.
858
- *
859
- * @example
860
- * ```ts
861
- * // Database is built once, shared by DocumentService and TeamService
862
- * const AppLayer = Layer.merge(
863
- * ConfigLive,
864
- * LoggerLive,
865
- * DatabaseLive, // Built once
866
- * DocumentServiceLive, // Uses shared Database
867
- * TeamServiceLive, // Uses same Database instance
868
- * )
869
- * ```
870
- */
871
- var MemoMap = class {
872
- cache = /* @__PURE__ */ new Map();
873
- /**
874
- * Get a cached context or build the layer if not cached.
875
- *
876
- * @param layer - The layer to get or build
877
- * @param scope - The scope for resource management
878
- * @param deps - Context containing the layer's dependencies
879
- * @returns An Fx producing the layer's context
880
- */
881
- getOrBuild(layer, scope, deps) {
882
- const cached = this.cache.get(layer);
883
- if (cached?.context) return {
884
- _tag: "SyncFx",
885
- run: () => ok(cached.context),
886
- *[Symbol.iterator]() {
887
- return cached.context;
888
- }
889
- };
890
- if (cached?.promise) return {
891
- _tag: "AsyncFx",
892
- run: async () => {
893
- return ok(await cached.promise);
894
- },
895
- async *[Symbol.asyncIterator]() {
896
- return await cached.promise;
897
- }
898
- };
899
- this.cache.set(layer, { building: true });
900
- const buildFx = layer.build(this, scope);
901
- const cacheRef = this.cache;
902
- if (buildFx._tag === "AsyncFx") {
903
- const buildPromise = (async () => {
904
- const gen$1 = buildFx[Symbol.asyncIterator]();
905
- let result = await gen$1.next();
906
- while (!result.done) {
907
- const yielded = result.value;
908
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
909
- const service = deps._services.get(yielded.serviceKey);
910
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found during layer build`);
911
- result = await gen$1.next(service);
912
- } else throw yielded;
913
- }
914
- const ctx = result.value;
915
- cacheRef.set(layer, { context: ctx });
916
- return ctx;
917
- })();
918
- this.cache.set(layer, { promise: buildPromise });
919
- return {
920
- _tag: "AsyncFx",
921
- run: async () => {
922
- try {
923
- return ok(await buildPromise);
924
- } catch (e) {
925
- return {
926
- ok: false,
927
- error: e,
928
- *[Symbol.iterator]() {
929
- yield e;
930
- throw new Error("Unreachable");
931
- }
932
- };
933
- }
934
- },
935
- async *[Symbol.asyncIterator]() {
936
- try {
937
- return await buildPromise;
938
- } catch (e) {
939
- yield e;
940
- throw new Error("Unreachable", { cause: e });
941
- }
942
- }
943
- };
944
- }
945
- return {
946
- _tag: "SyncFx",
947
- run: () => {
948
- const gen$1 = buildFx[Symbol.iterator]();
949
- let result = gen$1.next();
950
- while (!result.done) {
951
- const yielded = result.value;
952
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
953
- const service = deps._services.get(yielded.serviceKey);
954
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found during layer build`);
955
- result = gen$1.next(service);
956
- } else return {
957
- ok: false,
958
- error: yielded,
959
- *[Symbol.iterator]() {
960
- yield yielded;
961
- throw new Error("Unreachable");
962
- }
963
- };
964
- }
965
- const ctx = result.value;
966
- cacheRef.set(layer, { context: ctx });
967
- return ok(ctx);
968
- },
969
- *[Symbol.iterator]() {
970
- const gen$1 = buildFx[Symbol.iterator]();
971
- let result = gen$1.next();
972
- while (!result.done) {
973
- const yielded = result.value;
974
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
975
- const service = deps._services.get(yielded.serviceKey);
976
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found during layer build`);
977
- result = gen$1.next(service);
978
- } else {
979
- yield yielded;
980
- throw new Error("Unreachable");
981
- }
982
- }
983
- cacheRef.set(layer, { context: result.value });
984
- return result.value;
985
- }
986
- };
987
- }
988
- /**
989
- * Clear the cache.
990
- * Useful for testing.
991
- */
992
- clear() {
993
- this.cache.clear();
994
- }
995
- /**
996
- * Get the number of cached layers.
997
- */
998
- get size() {
999
- return this.cache.size;
1000
- }
1001
- };
1002
-
1003
- //#endregion
1004
- //#region src/fx/provide.ts
1005
- /**
1006
- * Provide a layer to an Fx computation, resolving all service requirements.
1007
- * Creates a new scope for resource management.
1008
- *
1009
- * @param layer - The layer providing services (must have no external requirements)
1010
- * @returns A function that takes an Fx and returns an Fx with dependencies resolved
1011
- *
1012
- * @example
1013
- * ```ts
1014
- * const result = pipe(
1015
- * updateDocumentWorkflow(userId, docId, data),
1016
- * provide(AppLayer)
1017
- * ).run()
1018
- * ```
1019
- */
1020
- const provide = (layer) => (fx) => {
1021
- const memoMap = new MemoMap();
1022
- const scope = createScope();
1023
- const layerBuildFx = layer.build(memoMap, scope);
1024
- if (layerBuildFx._tag === "AsyncFx" || fx._tag === "AsyncFx") return {
1025
- _tag: "AsyncFx",
1026
- get run() {
1027
- return (async () => {
1028
- try {
1029
- let ctx;
1030
- if (layerBuildFx._tag === "AsyncFx") {
1031
- const gen$1 = layerBuildFx[Symbol.asyncIterator]();
1032
- let result = await gen$1.next();
1033
- while (!result.done) result = await gen$1.next(void 0);
1034
- ctx = result.value;
1035
- } else {
1036
- const gen$1 = layerBuildFx[Symbol.iterator]();
1037
- let result = gen$1.next();
1038
- while (!result.done) result = gen$1.next(void 0);
1039
- ctx = result.value;
1040
- }
1041
- if (fx._tag === "AsyncFx") {
1042
- const fxGen$2 = fx[Symbol.asyncIterator]();
1043
- let fxResult$1 = await fxGen$2.next();
1044
- while (!fxResult$1.done) {
1045
- const yielded = fxResult$1.value;
1046
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1047
- const service = ctx._services.get(yielded.serviceKey);
1048
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1049
- fxResult$1 = await fxGen$2.next(service);
1050
- } else return err(yielded);
1051
- }
1052
- return ok(fxResult$1.value);
1053
- }
1054
- const fxGen$1 = fx[Symbol.iterator]();
1055
- let fxResult = fxGen$1.next();
1056
- while (!fxResult.done) {
1057
- const yielded = fxResult.value;
1058
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1059
- const service = ctx._services.get(yielded.serviceKey);
1060
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1061
- fxResult = fxGen$1.next(service);
1062
- } else return err(yielded);
1063
- }
1064
- return ok(fxResult.value);
1065
- } finally {
1066
- const closeResult = scope.close({
1067
- _tag: "Success",
1068
- value: void 0
1069
- });
1070
- if (closeResult._tag === "AsyncFx") await closeResult.run();
1071
- else closeResult.run();
1072
- }
1073
- });
1074
- },
1075
- async *[Symbol.asyncIterator]() {
1076
- try {
1077
- let ctx;
1078
- if (layerBuildFx._tag === "AsyncFx") {
1079
- const gen$1 = layerBuildFx[Symbol.asyncIterator]();
1080
- let result = await gen$1.next();
1081
- while (!result.done) {
1082
- yield result.value;
1083
- result = await gen$1.next(void 0);
1084
- }
1085
- ctx = result.value;
1086
- } else {
1087
- const gen$1 = layerBuildFx[Symbol.iterator]();
1088
- let result = gen$1.next();
1089
- while (!result.done) {
1090
- yield result.value;
1091
- result = gen$1.next(void 0);
1092
- }
1093
- ctx = result.value;
1094
- }
1095
- if (fx._tag === "AsyncFx") {
1096
- const fxGen$2 = fx[Symbol.asyncIterator]();
1097
- let fxResult$1 = await fxGen$2.next();
1098
- while (!fxResult$1.done) {
1099
- const yielded = fxResult$1.value;
1100
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1101
- const service = ctx._services.get(yielded.serviceKey);
1102
- if (service !== void 0) {
1103
- fxResult$1 = await fxGen$2.next(service);
1104
- continue;
1105
- }
1106
- }
1107
- const value = yield yielded;
1108
- fxResult$1 = await fxGen$2.next(value);
1109
- }
1110
- return fxResult$1.value;
1111
- }
1112
- const fxGen$1 = fx[Symbol.iterator]();
1113
- let fxResult = fxGen$1.next();
1114
- while (!fxResult.done) {
1115
- const yielded = fxResult.value;
1116
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1117
- const service = ctx._services.get(yielded.serviceKey);
1118
- if (service !== void 0) {
1119
- fxResult = fxGen$1.next(service);
1120
- continue;
1121
- }
1122
- }
1123
- const value = yield yielded;
1124
- fxResult = fxGen$1.next(value);
1125
- }
1126
- return fxResult.value;
1127
- } finally {
1128
- const closeResult = scope.close({
1129
- _tag: "Success",
1130
- value: void 0
1131
- });
1132
- if (closeResult._tag === "AsyncFx") await closeResult.run();
1133
- else closeResult.run();
1134
- }
1135
- }
1136
- };
1137
- return {
1138
- _tag: "SyncFx",
1139
- get run() {
1140
- return (() => {
1141
- try {
1142
- const layerGen = layerBuildFx[Symbol.iterator]();
1143
- let layerResult = layerGen.next();
1144
- while (!layerResult.done) layerResult = layerGen.next(void 0);
1145
- const ctx = layerResult.value;
1146
- const fxGen$1 = fx[Symbol.iterator]();
1147
- let fxResult = fxGen$1.next();
1148
- while (!fxResult.done) {
1149
- const yielded = fxResult.value;
1150
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1151
- const service = ctx._services.get(yielded.serviceKey);
1152
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1153
- fxResult = fxGen$1.next(service);
1154
- } else return err(yielded);
1155
- }
1156
- return ok(fxResult.value);
1157
- } finally {
1158
- scope.close({
1159
- _tag: "Success",
1160
- value: void 0
1161
- }).run();
1162
- }
1163
- });
1164
- },
1165
- *[Symbol.iterator]() {
1166
- try {
1167
- const layerGen = layerBuildFx[Symbol.iterator]();
1168
- let layerResult = layerGen.next();
1169
- while (!layerResult.done) {
1170
- yield layerResult.value;
1171
- layerResult = layerGen.next(void 0);
1172
- }
1173
- const ctx = layerResult.value;
1174
- const fxGen$1 = fx[Symbol.iterator]();
1175
- let fxResult = fxGen$1.next();
1176
- while (!fxResult.done) {
1177
- const yielded = fxResult.value;
1178
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1179
- const service = ctx._services.get(yielded.serviceKey);
1180
- if (service !== void 0) {
1181
- fxResult = fxGen$1.next(service);
1182
- continue;
1183
- }
1184
- }
1185
- const value = yield yielded;
1186
- fxResult = fxGen$1.next(value);
1187
- }
1188
- return fxResult.value;
1189
- } finally {
1190
- scope.close({
1191
- _tag: "Success",
1192
- value: void 0
1193
- }).run();
1194
- }
1195
- }
1196
- };
1197
- };
1198
- /**
1199
- * Provide a context directly to an Fx computation.
1200
- *
1201
- * @param ctx - The context containing services
1202
- * @returns A function that takes an Fx and returns an Fx with dependencies resolved
1203
- *
1204
- * @example
1205
- * ```ts
1206
- * const ctx = Context.make(Config, configImpl)
1207
- * const result = pipe(
1208
- * myWorkflow,
1209
- * provideContext(ctx)
1210
- * ).run()
1211
- * ```
1212
- */
1213
- const provideContext = (ctx) => (fx) => {
1214
- if (fx._tag === "AsyncFx") return {
1215
- _tag: "AsyncFx",
1216
- get run() {
1217
- return (async () => {
1218
- const gen$1 = fx[Symbol.asyncIterator]();
1219
- let result = await gen$1.next();
1220
- while (!result.done) {
1221
- const yielded = result.value;
1222
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1223
- const service = ctx._services.get(yielded.serviceKey);
1224
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1225
- result = await gen$1.next(service);
1226
- } else return err(yielded);
1227
- }
1228
- return ok(result.value);
1229
- });
1230
- },
1231
- async *[Symbol.asyncIterator]() {
1232
- const gen$1 = fx[Symbol.asyncIterator]();
1233
- let result = await gen$1.next();
1234
- while (!result.done) {
1235
- const yielded = result.value;
1236
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1237
- const service = ctx._services.get(yielded.serviceKey);
1238
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1239
- result = await gen$1.next(service);
1240
- } else {
1241
- yield yielded;
1242
- result = await gen$1.next(void 0);
1243
- }
1244
- }
1245
- return result.value;
1246
- }
1247
- };
1248
- return {
1249
- _tag: "SyncFx",
1250
- get run() {
1251
- return (() => {
1252
- const gen$1 = fx[Symbol.iterator]();
1253
- let result = gen$1.next();
1254
- while (!result.done) {
1255
- const yielded = result.value;
1256
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1257
- const service = ctx._services.get(yielded.serviceKey);
1258
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1259
- result = gen$1.next(service);
1260
- } else return err(yielded);
1261
- }
1262
- return ok(result.value);
1263
- });
1264
- },
1265
- *[Symbol.iterator]() {
1266
- const gen$1 = fx[Symbol.iterator]();
1267
- let result = gen$1.next();
1268
- while (!result.done) {
1269
- const yielded = result.value;
1270
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") {
1271
- const service = ctx._services.get(yielded.serviceKey);
1272
- if (service === void 0) throw new Error(`Service "${yielded.serviceKey}" not found`);
1273
- result = gen$1.next(service);
1274
- } else {
1275
- yield yielded;
1276
- result = gen$1.next(void 0);
1277
- }
1278
- }
1279
- return result.value;
1280
- }
1281
- };
1282
- };
1283
- /**
1284
- * Provide a single service to an Fx computation.
1285
- *
1286
- * @param service - The service class (tag)
1287
- * @param impl - The service implementation
1288
- * @returns A function that takes an Fx and returns an Fx with the service provided
1289
- *
1290
- * @example
1291
- * ```ts
1292
- * const result = pipe(
1293
- * myWorkflow,
1294
- * provideService(Config, configImpl),
1295
- * provideService(Logger, loggerImpl),
1296
- * ).run()
1297
- * ```
1298
- */
1299
- const provideService = (service, impl) => (fx) => {
1300
- if (fx._tag === "AsyncFx") return {
1301
- _tag: "AsyncFx",
1302
- get run() {
1303
- return (async () => {
1304
- const gen$1 = fx[Symbol.asyncIterator]();
1305
- let result = await gen$1.next();
1306
- while (!result.done) {
1307
- const yielded = result.value;
1308
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === service.key) result = await gen$1.next(impl);
1309
- else if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") throw new Error(`Service "${yielded.serviceKey}" not found`);
1310
- else return err(yielded);
1311
- }
1312
- return ok(result.value);
1313
- });
1314
- },
1315
- async *[Symbol.asyncIterator]() {
1316
- const gen$1 = fx[Symbol.asyncIterator]();
1317
- let result = await gen$1.next();
1318
- while (!result.done) {
1319
- const yielded = result.value;
1320
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === service.key) result = await gen$1.next(impl);
1321
- else {
1322
- const value = yield yielded;
1323
- result = await gen$1.next(value);
1324
- }
1325
- }
1326
- return result.value;
1327
- }
1328
- };
1329
- return {
1330
- _tag: "SyncFx",
1331
- get run() {
1332
- return (() => {
1333
- const gen$1 = fx[Symbol.iterator]();
1334
- let result = gen$1.next();
1335
- while (!result.done) {
1336
- const yielded = result.value;
1337
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === service.key) result = gen$1.next(impl);
1338
- else if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest") throw new Error(`Service "${yielded.serviceKey}" not found`);
1339
- else return err(yielded);
1340
- }
1341
- return ok(result.value);
1342
- });
1343
- },
1344
- *[Symbol.iterator]() {
1345
- const gen$1 = fx[Symbol.iterator]();
1346
- let result = gen$1.next();
1347
- while (!result.done) {
1348
- const yielded = result.value;
1349
- if (typeof yielded === "object" && yielded !== null && "_tag" in yielded && yielded._tag === "ServiceRequest" && yielded.serviceKey === service.key) result = gen$1.next(impl);
1350
- else {
1351
- const value = yield yielded;
1352
- result = gen$1.next(value);
1353
- }
1354
- }
1355
- return result.value;
1356
- }
1357
- };
1358
- };
1359
-
1360
- //#endregion
1361
- //#region src/std.ts
1362
- /**
1363
- * Main Std namespace containing all utility functions and types.
1364
- */
1365
- const Std = {
1366
- array,
1367
- data,
1368
- flow,
1369
- fn,
1370
- gen,
1371
- pipe,
1372
- record,
1373
- struct,
1374
- tagged,
1375
- tuple,
1376
- ...Result,
1377
- Option,
1378
- Either,
1379
- Err,
1380
- TaggedError,
1381
- Predicate,
1382
- Brand,
1383
- Fx,
1384
- Service,
1385
- Layer,
1386
- Context,
1387
- Scope: ScopeTag,
1388
- provide
1389
- };
1390
-
1391
- //#endregion
1392
- export { Brand, Context, Either, Err, Fx, Layer, Option, Predicate, Result, ScopeTag as Scope, Service, Std, TaggedError, array, data, ensure, ensureRefinement, flow, fn, gen, pipe, provide, provideContext, provideService, record, serviceTag, struct, tagged, tuple };
1393
- //# sourceMappingURL=index.mjs.map
1
+ import{t as e}from"./pipeable-rQvolRqh.mjs";import{t}from"./flow-CxKQ5yac.mjs";import{t as n}from"./result-B68pxC7l.mjs";import{n as r,r as i}from"./adt-DZmVJG4P.mjs";import{t as a}from"./brand-BUqMmkzC.mjs";import{i as o,n as s,r as c,t as l}from"./data-DzqKBCQg.mjs";import{t as u}from"./option-Qiv7Ls7L.mjs";import{t as d}from"./either-BDY9T5oz.mjs";import{n as f,t as p}from"./err-CYs4b1RV.mjs";import"./flow/index.mjs";import{t as m}from"./pipe-BROILDeC.mjs";import{t as h}from"./predicate-DvXnfmeJ.mjs";import{b as g,c as _,f as v,l as y,n as b,o as x,p as S,r as C,t as w,u as T}from"./fx-C4UuWCqP.mjs";export{a as Brand,y as Context,d as Either,p as Err,g as Exit,S as Fx,_ as Layer,u as Option,h as Predicate,n as Result,x as Scope,T as Service,f as TaggedError,l as array,r as data,t as flow,m as pipe,e as pipeMethod,w as provide,b as provideContext,C as provideService,i as record,v as serviceTag,c as struct,o as tagged,s as tuple};