brass-runtime 1.1.0 → 1.2.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.
- package/README.md +88 -311
- package/dist/examples/canceler.d.ts +2 -0
- package/dist/examples/canceler.d.ts.map +1 -0
- package/dist/examples/{test-canceler.js → canceler.js} +1 -0
- package/dist/examples/canceler.js.map +1 -0
- package/dist/examples/demo.d.ts +3 -0
- package/dist/examples/demo.d.ts.map +1 -0
- package/dist/examples/demo.js +38 -28
- package/dist/examples/demo.js.map +1 -0
- package/dist/examples/fiberFinalizer.d.ts +2 -0
- package/dist/examples/fiberFinalizer.d.ts.map +1 -0
- package/dist/examples/fiberFinalizer.js +1 -0
- package/dist/examples/fiberFinalizer.js.map +1 -0
- package/dist/examples/fromPromise.d.ts +3 -0
- package/dist/examples/fromPromise.d.ts.map +1 -0
- package/dist/examples/fromPromise.js +44 -0
- package/dist/examples/fromPromise.js.map +1 -0
- package/dist/examples/index.d.ts +7 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/dist/examples/index.js +4 -1
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/resourceExample.d.ts +2 -0
- package/dist/examples/resourceExample.d.ts.map +1 -0
- package/dist/examples/resourceExample.js +1 -0
- package/dist/examples/resourceExample.js.map +1 -0
- package/dist/examples/toPromise.d.ts +2 -0
- package/dist/examples/toPromise.d.ts.map +1 -0
- package/dist/examples/toPromise.js +13 -0
- package/dist/examples/toPromise.js.map +1 -0
- package/dist/fibers/fiber.d.ts +24 -0
- package/dist/fibers/fiber.d.ts.map +1 -0
- package/dist/fibers/fiber.js +16 -6
- package/dist/fibers/fiber.js.map +1 -0
- package/dist/{index.js → index.cjs} +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +11 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +1 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/scope.d.ts +28 -0
- package/dist/scheduler/scope.d.ts.map +1 -0
- package/dist/scheduler/scope.js +1 -0
- package/dist/scheduler/scope.js.map +1 -0
- package/dist/stream/buffer.d.ts +3 -0
- package/dist/stream/buffer.d.ts.map +1 -0
- package/dist/stream/buffer.js +78 -47
- package/dist/stream/buffer.js.map +1 -0
- package/dist/stream/queue.d.ts +9 -0
- package/dist/stream/queue.d.ts.map +1 -0
- package/dist/stream/queue.js +98 -0
- package/dist/stream/queue.js.map +1 -0
- package/dist/stream/stream.d.ts +37 -0
- package/dist/stream/stream.d.ts.map +1 -0
- package/dist/stream/stream.js +70 -37
- package/dist/stream/stream.js.map +1 -0
- package/dist/stream/structuredConcurrency.d.ts +25 -0
- package/dist/stream/structuredConcurrency.d.ts.map +1 -0
- package/dist/stream/structuredConcurrency.js +1 -0
- package/dist/stream/structuredConcurrency.js.map +1 -0
- package/dist/types/asyncEffect.d.ts +44 -0
- package/dist/types/asyncEffect.d.ts.map +1 -0
- package/dist/types/asyncEffect.js +30 -13
- package/dist/types/asyncEffect.js.map +1 -0
- package/dist/types/cancel.d.ts +21 -0
- package/dist/types/cancel.d.ts.map +1 -0
- package/dist/types/cancel.js +1 -0
- package/dist/types/cancel.js.map +1 -0
- package/dist/types/effect.d.ts +20 -0
- package/dist/types/effect.d.ts.map +1 -0
- package/dist/types/effect.js +19 -123
- package/dist/types/effect.js.map +1 -0
- package/dist/types/option.d.ts +11 -0
- package/dist/types/option.d.ts.map +1 -0
- package/dist/types/option.js +1 -0
- package/dist/types/option.js.map +1 -0
- package/package.json +19 -6
package/README.md
CHANGED
|
@@ -1,361 +1,138 @@
|
|
|
1
|
-
# 🛠️ brass-runtime — Mini runtime
|
|
1
|
+
# 🛠️ brass-runtime — Mini ZIO-like runtime in TypeScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A small experimental runtime inspired by ZIO 2, implemented in vanilla TypeScript and intentionally built without using `Promise` / `async`/`await` as the primary semantic primitive.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- **Efectos puros** (sincrónicos y asincrónicos)
|
|
8
|
-
- **Concurrencia estructurada**
|
|
9
|
-
- **Fibras** (fibers)
|
|
10
|
-
- **Scheduler cooperativo**
|
|
11
|
-
- **Limpieza segura de recursos (acquire / release)**
|
|
12
|
-
- **Scopes estructurados**
|
|
13
|
-
- **Finalizers (a nivel scope y fibra)**
|
|
14
|
-
- **Streams estructurados (ZStream-like) con backpressure**
|
|
15
|
-
|
|
16
|
-
Todo con un diseño **determinístico**, **pure FP**, y sin depender de `Promise` ni `async/await` para la semántica del modelo.
|
|
5
|
+
Goals: explore typed effects, structured concurrency, fibers, cooperative scheduling, resource safety and streams with backpressure — in a deterministic, pure-FP friendly way.
|
|
17
6
|
|
|
18
7
|
---
|
|
19
8
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
### 1. `Effect` sincrónico (núcleo funcional)
|
|
23
|
-
|
|
24
|
-
En `brass-runtime`, un efecto puro se modela como:
|
|
25
|
-
|
|
26
|
-
```ts
|
|
27
|
-
type Exit<E, A> =
|
|
28
|
-
| { _tag: "Success"; value: A }
|
|
29
|
-
| { _tag: "Failure"; error: E };
|
|
9
|
+
## Key ideas
|
|
30
10
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- `
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
39
|
-
- `catchAll`
|
|
40
|
-
- `zip`
|
|
41
|
-
- `foreach`
|
|
42
|
-
- `collectAll`
|
|
43
|
-
- `as`, `asUnit`, `tap`
|
|
44
|
-
|
|
45
|
-
Este núcleo no usa `Promise` ni `async/await`. Es **100% sincrónico y determinista**.
|
|
11
|
+
- Pure, sync core effect: `Effect<R, E, A>` and `Exit<E, A>`.
|
|
12
|
+
- An algebraic representation for async work: `Async<R, E, A>` with an explicit interpreter (no `Promise` as runtime primitive).
|
|
13
|
+
- A cooperative `Scheduler` for deterministic task interleaving and fairness.
|
|
14
|
+
- Lightweight `Fiber`s with cooperative interruption, `join`, and LIFO finalizers.
|
|
15
|
+
- Structured `Scope`s that manage child fibers, sub-scopes and finalizers; closing a scope cleans up children deterministically.
|
|
16
|
+
- Resource-safe `acquireRelease` semantics (acquire + release tied to scope finalizers).
|
|
17
|
+
- Structured concurrency combinators: `race`, `zipPar`, `collectAllPar`.
|
|
18
|
+
- ZStream-style streams with backpressure, `Pull` semantics and resource safety.
|
|
46
19
|
|
|
47
20
|
---
|
|
48
21
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Para modelar operaciones asincrónicas, `brass-runtime` define un tipo de datos algebraico:
|
|
22
|
+
## What's new (recent changes)
|
|
52
23
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
| { _tag: "Async"; register: (env: R, cb: (exit: Exit<E, A>) => void) => void }
|
|
59
|
-
| { _tag: "FlatMap"; first: Async<R, E, any>; andThen: (a: any) => Async<R, E, A> };
|
|
60
|
-
```
|
|
24
|
+
- Implemented stream buffering primitives: `buffer` supports bounded buffering with backpressure semantics.
|
|
25
|
+
- Added `fromPromiseAbortable` helper to integrate callback/Promise APIs that support `AbortSignal`, preserving cooperative cancellation.
|
|
26
|
+
- Added `toPromise` for interop convenience (tests/examples use it to await results from the runtime).
|
|
27
|
+
- New example: `src/examples/fromPromise.ts` — demonstrates creating a stream from abortable Promises and using `buffer` + `collectStream`.
|
|
28
|
+
- Misc: tests and examples updated to exercise buffer modes and abortable integration.
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- `asyncSucceed`
|
|
65
|
-
- `asyncFail`
|
|
66
|
-
- `asyncSync`
|
|
67
|
-
- `asyncTotal`
|
|
68
|
-
- `async` (primitive para integrar APIs callback-based como `setTimeout`, `fs`, etc.)
|
|
69
|
-
- `asyncMap`
|
|
70
|
-
- `asyncFlatMap`
|
|
71
|
-
|
|
72
|
-
Y un runtime que ejecuta `Async` mediante un **intérprete explícito**, sin usar `Promise`.
|
|
30
|
+
Branch containing recent work: `feature/buffer-pipes`.
|
|
73
31
|
|
|
74
32
|
---
|
|
75
33
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
Esto permite testear y razonar sobre la concurrencia sin depender del azar del event loop.
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
### 4. Fibers (fibras)
|
|
97
|
-
|
|
98
|
-
Cada programa `Async` corre dentro de una **fibra**:
|
|
99
|
-
|
|
100
|
-
```ts
|
|
101
|
-
type Fiber<E, A> = {
|
|
102
|
-
id: number;
|
|
103
|
-
status: () => "Running" | "Done" | "Interrupted";
|
|
104
|
-
join: (cb: (exit: Exit<E | Interrupted, A>) => void) => void;
|
|
105
|
-
interrupt: () => void;
|
|
106
|
-
addFinalizer: (f: (exit: Exit<E | Interrupted, A>) => Async<any, any, any>) => void;
|
|
107
|
-
};
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Las fibras proveen:
|
|
111
|
-
|
|
112
|
-
- concurrencia liviana (miles de fibers),
|
|
113
|
-
- cancelación cooperativa (`interrupt`),
|
|
114
|
-
- `join` para esperar resultados,
|
|
115
|
-
- **finalizers de fibra** (LIFO) que se ejecutan siempre: éxito, fallo o interrupción.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
### 5. Scopes — Concurrencia estructurada
|
|
120
|
-
|
|
121
|
-
Un **Scope** modela una unidad de concurrencia estructurada:
|
|
122
|
-
|
|
123
|
-
```ts
|
|
124
|
-
class Scope<R> {
|
|
125
|
-
fork<E, A>(eff: Async<R, E, A>, env: R): Fiber<E, A>;
|
|
126
|
-
subScope(): Scope<R>;
|
|
127
|
-
addFinalizer(f: (exit: Exit<any, any>) => Async<R, any, any>): void;
|
|
128
|
-
close(exit?: Exit<any, any>): void;
|
|
129
|
-
isClosed(): boolean;
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Un scope:
|
|
134
|
-
|
|
135
|
-
- rastrea las fibras hijas,
|
|
136
|
-
- rastrea sub-scopes,
|
|
137
|
-
- mantiene una pila de finalizers (LIFO),
|
|
138
|
-
- al cerrarse:
|
|
139
|
-
- interrumpe fibras hijas,
|
|
140
|
-
- cierra sub-scopes,
|
|
141
|
-
- ejecuta finalizers registrados.
|
|
142
|
-
|
|
143
|
-
Esto da **concurrencia estructurada** al estilo ZIO:
|
|
144
|
-
si algo vive en un `Scope`, se limpia cuando el scope termina.
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
### 6. Acquire / Release — Resource Safety
|
|
149
|
-
|
|
150
|
-
Al estilo `ZIO.acquireRelease`, `brass-runtime` implementa:
|
|
151
|
-
|
|
152
|
-
```ts
|
|
153
|
-
acquireRelease(
|
|
154
|
-
acquire: Async<R, E, A>,
|
|
155
|
-
release: (res: A, exit: Exit<any, any>) => Async<R, any, any>,
|
|
156
|
-
scope: Scope<R>
|
|
157
|
-
): Async<R, E, A>;
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Semántica:
|
|
161
|
-
|
|
162
|
-
- `acquire` corre dentro del scope,
|
|
163
|
-
- si tiene éxito, registra un finalizer que hace `release(res, exitFinalDelScope)`,
|
|
164
|
-
- el finalizer se ejecuta:
|
|
165
|
-
- si el scope cierra con éxito,
|
|
166
|
-
- si hay error,
|
|
167
|
-
- si hay interrupción/cancelación.
|
|
168
|
-
|
|
169
|
-
**Garantiza cleanup de recursos** (archivos, sockets, conexiones, etc.) de forma estructurada.
|
|
34
|
+
## Features (status)
|
|
35
|
+
|
|
36
|
+
- [x] Sync core: `Effect` (pure FP core)
|
|
37
|
+
- [x] Async algebra: `Async` (no Promises in semantics)
|
|
38
|
+
- [x] Cooperative `Scheduler`
|
|
39
|
+
- [x] Fibers with LIFO finalizers and interruption
|
|
40
|
+
- [x] `Scope` (structured concurrency and finalizers)
|
|
41
|
+
- [x] `acquireRelease` / resource safety
|
|
42
|
+
- [x] Structured concurrency: `race`, `zipPar`, `collectAllPar`
|
|
43
|
+
- [x] ZStream-like core (pull-based, resource-aware)
|
|
44
|
+
- [x] Buffering in streams (bounded/backpressure modes)
|
|
45
|
+
- [ ] Merge / zipPar of streams
|
|
46
|
+
- [ ] Hubs / Broadcast / Multicast
|
|
47
|
+
- [ ] Pipelines (`ZPipeline`-style)
|
|
48
|
+
- [ ] Advanced Channels / Sinks
|
|
170
49
|
|
|
171
50
|
---
|
|
172
51
|
|
|
173
|
-
|
|
52
|
+
## API highlights
|
|
174
53
|
|
|
175
|
-
|
|
54
|
+
Core types
|
|
55
|
+
- `type Exit<E, A> = Success | Failure`
|
|
56
|
+
- `type Effect<R, E, A> = (env: R) => Exit<E, A>`
|
|
57
|
+
- `type Async<R, E, A> = Succeed | Fail | Sync | Async | FlatMap`
|
|
176
58
|
|
|
177
|
-
|
|
59
|
+
Async constructors
|
|
60
|
+
- `asyncSucceed`, `asyncFail`, `asyncSync`, `asyncTotal`
|
|
61
|
+
- `async` primitive for callback integration
|
|
62
|
+
- `asyncMap`, `asyncFlatMap`
|
|
63
|
+
- `fromPromiseAbortable` — integrate APIs that accept `AbortSignal` and support cooperative cancellation
|
|
178
64
|
|
|
179
|
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
65
|
+
Fibers / Concurrency
|
|
66
|
+
- `Fiber<E, A>`: `id`, `status()`, `join(cb)`, `interrupt()`, `addFinalizer(...)`
|
|
67
|
+
- `Scheduler.schedule(task: () => void)`
|
|
68
|
+
- `race`, `zipPar`, `collectAllPar` — structured concurrency semantics
|
|
183
69
|
|
|
184
|
-
|
|
70
|
+
Scopes & Resource safety
|
|
71
|
+
- `class Scope<R>`: `fork`, `subScope`, `addFinalizer`, `close`, `isClosed`
|
|
72
|
+
- `acquireRelease(acquire, release, scope)`
|
|
185
73
|
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
- si alguno falla → cancela el resto,
|
|
194
|
-
- si todos completan → devuelve la lista de resultados.
|
|
195
|
-
|
|
196
|
-
Esto replica la semántica de **ZIO 2 structured concurrency**.
|
|
74
|
+
Streams (ZStream-like)
|
|
75
|
+
- `type Pull<R, E, A> = Async<R, Option<E>, A>`
|
|
76
|
+
- `type ZStream<R, E, A> = { open: (scope: Scope<R>) => Pull<R, E, A> }`
|
|
77
|
+
- Constructors: `empty`, `streamOf`, `fromArray`, `fromPull`
|
|
78
|
+
- Transformations: `map`, `filter`, `fromResource`
|
|
79
|
+
- Buffering: `buffer(stream, capacity, mode)` — bounded buffer with backpressure or dropping modes
|
|
80
|
+
- Interop: `collectStream`, `runCollect`, `toPromise` for awaiting results in examples
|
|
197
81
|
|
|
198
82
|
---
|
|
199
83
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
`brass-runtime` incluye una base de **streams estructurados** inspirados en `ZStream`:
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
type Pull<R, E, A> = Async<R, Option<E>, A>;
|
|
206
|
-
|
|
207
|
-
type ZStream<R, E, A> = {
|
|
208
|
-
open: (scope: Scope<R>) => Pull<R, E, A>;
|
|
209
|
-
};
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
Donde:
|
|
213
|
-
|
|
214
|
-
- `Success(a)` → el stream produjo un valor,
|
|
215
|
-
- `Failure(Some(e))` → error,
|
|
216
|
-
- `Failure(None)` → fin del stream.
|
|
217
|
-
|
|
218
|
-
Constructores básicos:
|
|
219
|
-
|
|
220
|
-
- `empty`
|
|
221
|
-
- `streamOf`
|
|
222
|
-
- `fromArray`
|
|
223
|
-
|
|
224
|
-
Transformaciones:
|
|
225
|
-
|
|
226
|
-
- `map`
|
|
227
|
-
- `filter`
|
|
228
|
-
- `fromResource` (integra acquire/release con streams)
|
|
84
|
+
## Example (what to look at)
|
|
229
85
|
|
|
230
|
-
|
|
86
|
+
See `src/examples/fromPromise.ts`:
|
|
87
|
+
- Shows `fromPromiseAbortable` producing stream elements with cooperative cancellation.
|
|
88
|
+
- Demonstrates `buffer` with a bounded capacity and backpressure semantics.
|
|
89
|
+
- Uses `collectStream` + `toPromise` to gather stream output in an example-run friendly way.
|
|
231
90
|
|
|
232
|
-
|
|
233
|
-
runCollect(stream, env): Async<R, E, A[]>;
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
El consumo se hace respetando backpressure: cada `pull` produce como mucho un valor,
|
|
237
|
-
y el scope del stream garantiza que todos los recursos/finalizers se limpien al terminar
|
|
238
|
-
(el stream o el consumidor).
|
|
91
|
+
Do not copy the example here — open `src/examples/fromPromise.ts` for details.
|
|
239
92
|
|
|
240
93
|
---
|
|
241
94
|
|
|
242
|
-
##
|
|
243
|
-
|
|
244
|
-
Una posible organización de archivos para tu repo de **brass-runtime**:
|
|
95
|
+
## Running examples and tests
|
|
245
96
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
types/
|
|
252
|
-
|
|
97
|
+
- Use your editor's run configuration (WebStorm 2025.3.1 recommended) or run with `ts-node` for quick iteration.
|
|
98
|
+
- Typical flow:
|
|
99
|
+
- Install deps: `npm install`
|
|
100
|
+
- Run an example directly: `npx ts-node src/examples/fromPromise.ts` (or configure a Node run config that compiles first)
|
|
101
|
+
- Build: `npm run build` → run compiled files from `dist/`
|
|
253
102
|
|
|
254
|
-
|
|
255
|
-
demo.ts
|
|
256
|
-
fiberFinalizer.ts
|
|
257
|
-
resourceExample.ts
|
|
258
|
-
```
|
|
103
|
+
Adjust the commands to your preferred setup. The project intentionally leaves runtime execution flexible (ts-node, esbuild, tsc + node, etc.).
|
|
259
104
|
|
|
260
105
|
---
|
|
261
106
|
|
|
262
|
-
##
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
asyncFlatMap,
|
|
268
|
-
asyncSucceed,
|
|
269
|
-
} from "./asyncEffect";
|
|
270
|
-
import { sleep } from "./std";
|
|
271
|
-
import { Scope } from "./scope";
|
|
272
|
-
import { race } from "./concurrency";
|
|
273
|
-
|
|
274
|
-
type Env = {};
|
|
275
|
-
|
|
276
|
-
function task(name: string, ms: number) {
|
|
277
|
-
return asyncFlatMap(sleep(ms), () =>
|
|
278
|
-
asyncSucceed(`Terminé ${name}`)
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function main() {
|
|
283
|
-
const env: Env = {};
|
|
284
|
-
const scope = new Scope<Env>();
|
|
285
|
-
|
|
286
|
-
const fast = task("rápida", 200);
|
|
287
|
-
const slow = task("lenta", 1000);
|
|
288
|
-
|
|
289
|
-
race(fast, slow, scope)(env, exit => {
|
|
290
|
-
console.log("Resultado race:", exit);
|
|
291
|
-
scope.close(exit);
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
main();
|
|
296
|
-
```
|
|
107
|
+
## Project structure (recommended)
|
|
108
|
+
Examples:
|
|
109
|
+
- `src/examples/fromPromise.ts` (abortable promise -> stream + buffer)
|
|
110
|
+
- `src/examples/resourceExample.ts` (acquire/release + scope)
|
|
111
|
+
- `src/examples/fiberFinalizer.ts` (fiber finalizer LIFO semantics)
|
|
297
112
|
|
|
298
113
|
---
|
|
299
114
|
|
|
300
|
-
##
|
|
115
|
+
## Design notes
|
|
301
116
|
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
- Fibras,
|
|
307
|
-
- Scopes y finalizers,
|
|
308
|
-
- Streams con recursos seguros y backpressure.
|
|
309
|
-
- Servir como base educativa y potencialmente como **runtime experimental**
|
|
310
|
-
para proyectos de ejemplo, demos y pruebas de conceptos FP en TS.
|
|
117
|
+
- Determinism: scheduling is explicit and testable via the cooperative `Scheduler`.
|
|
118
|
+
- No hidden `Promise` semantics: the runtime models async as an algebraic datatype with an explicit interpreter.
|
|
119
|
+
- Resource safety is structural — scopes tie resource lifetimes to lexical structure, ensuring deterministic cleanup.
|
|
120
|
+
- Streaming model uses pull-based backpressure; buffering is explicit and configurable.
|
|
311
121
|
|
|
312
122
|
---
|
|
313
123
|
|
|
314
|
-
##
|
|
315
|
-
|
|
316
|
-
- [x] Núcleo de efectos sincrónicos (`Effect`)
|
|
317
|
-
- [x] Núcleo de efectos asincrónicos (`Async`) sin Promises
|
|
318
|
-
- [x] Scheduler cooperativo
|
|
319
|
-
- [x] Fibers con finalizers
|
|
320
|
-
- [x] Scopes con finalizers (LIFO)
|
|
321
|
-
- [x] Acquire / Release
|
|
322
|
-
- [x] Concurrencia estructurada (`race`, `zipPar`, `collectAllPar`)
|
|
323
|
-
- [x] Streams básicos (`ZStream`-like) con backpressure y scopes
|
|
324
|
-
- [ ] Buffering en streams
|
|
325
|
-
- [ ] Merge / zipPar de streams
|
|
326
|
-
- [ ] Hubs / Broadcast / Multicast
|
|
327
|
-
- [ ] Pipelines (tipo `ZPipeline`)
|
|
328
|
-
- [ ] Channels / Sinks avanzado
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## 📜 Licencia
|
|
124
|
+
## Contributing
|
|
333
125
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
```text
|
|
338
|
-
MIT License
|
|
339
|
-
Copyright (c) 2025
|
|
340
|
-
```
|
|
126
|
+
- Branch for current work: `feature/buffer-pipes`.
|
|
127
|
+
- Open issues / PRs welcome. Aim for small, focused PRs that preserve the runtime invariants (no hidden Promise semantics).
|
|
128
|
+
- Tests should exercise scheduling determinism, interruption guarantees and resource cleanup.
|
|
341
129
|
|
|
342
130
|
---
|
|
343
131
|
|
|
344
|
-
##
|
|
345
|
-
|
|
346
|
-
Ideas de mejora, PRs y discusiones de diseño son más que bienvenidas.
|
|
132
|
+
## License
|
|
347
133
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
- Integrar fs / net de Node de forma segura vía `Async`,
|
|
351
|
-
- Agregar tests deterministas de concurrencia,
|
|
352
|
-
- Implementar Hubs y Queues al estilo ZIO,
|
|
353
|
-
- Extender ZStream con merges, buffers y pipelines,
|
|
354
|
-
- Explorar integración con TypeScript decorators para “endpoints” basados en efectos.
|
|
134
|
+
MIT License © 2025
|
|
355
135
|
|
|
356
136
|
---
|
|
357
137
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
**Nombre del proyecto:** `brass-runtime`
|
|
361
|
-
**Objetivo:** construir un mini ZIO-like runtime en el ecosistema JS/TS, pero manteniendo el control total sobre la semántica de los efectos desde el código de usuario.
|
|
138
|
+
If you need the README translated to Spanish or a trimmed/expanded version for npm package metadata, a shorter project landing page, or a CHANGELOG entry for the branch `feature/buffer-pipes`, provide the preference and a target audience.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canceler.d.ts","sourceRoot":"","sources":["../../src/examples/canceler.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canceler.js","sourceRoot":"","sources":["../../src/examples/canceler.ts"],"names":[],"mappings":";;AAAA,2CAA+C;AAC/C,sDAA2C;AAE3C,IAAI,KAAK,GAAG,CAAC,CAAC;AAEd,MAAM,MAAM,GAAG,IAAA,mBAAK,EAAuB,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;IACpD,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;QACxB,KAAK,EAAE,CAAC;IACZ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1C,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,IAAA,sBAAc,EAAC,MAAM,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;IACvC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,GAAG,EAAE;IACZ,MAAM,EAAE,GAAG,KAAK,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAEhC,UAAU,CAAC,GAAG,EAAE;QACZ,MAAM,EAAE,GAAG,KAAK,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QAEjC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QACpE,CAAC;IACL,CAAC,EAAE,GAAG,CAAC,CAAC;AACZ,CAAC,EAAE,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/examples/demo.ts"],"names":[],"mappings":"AAMA,OAAO,EAAS,KAAK,KAAK,EAA8B,MAAM,sBAAsB,CAAC;AAKrF,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAK7D"}
|
package/dist/examples/demo.js
CHANGED
|
@@ -2,37 +2,53 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.sleep = sleep;
|
|
4
4
|
const fiber_1 = require("../fibers/fiber");
|
|
5
|
-
const effect_1 = require("../types/effect");
|
|
6
5
|
const stream_1 = require("../stream/stream");
|
|
7
6
|
const scope_1 = require("../scheduler/scope");
|
|
8
7
|
const asyncEffect_1 = require("../types/asyncEffect");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
console.log("Fiber A:", exit);
|
|
8
|
+
const effect_1 = require("../types/effect"); // succeed ahora devuelve Async
|
|
9
|
+
function sleep(ms) {
|
|
10
|
+
return (0, asyncEffect_1.async)((_, cb) => {
|
|
11
|
+
const t = setTimeout(() => cb({ _tag: "Success", value: undefined }), ms);
|
|
12
|
+
return () => clearTimeout(t);
|
|
15
13
|
});
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
}
|
|
15
|
+
function task(name, ms) {
|
|
16
|
+
return (0, asyncEffect_1.asyncFlatMap)(sleep(ms), () => (0, asyncEffect_1.asyncSucceed)(`Terminé ${name} después de ${ms}ms`));
|
|
17
|
+
}
|
|
18
|
+
// Helper: correr un efecto y loguear su Exit
|
|
19
|
+
function run(label, eff, env) {
|
|
20
|
+
const f = (0, fiber_1.fork)(eff, env);
|
|
21
|
+
f.join((exit) => {
|
|
22
|
+
const ex = exit;
|
|
23
|
+
console.log(label, ex);
|
|
18
24
|
});
|
|
25
|
+
return f;
|
|
26
|
+
}
|
|
27
|
+
function main() {
|
|
28
|
+
const env = {};
|
|
29
|
+
// Fibras simples
|
|
30
|
+
const fiberA = run("Fiber A:", task("A", 1000), env);
|
|
31
|
+
const fiberB = run("Fiber B:", task("B", 500), env);
|
|
32
|
+
// “zip” de efectos (sin helper): flatMap + map
|
|
19
33
|
const eff1 = (0, effect_1.succeed)(10);
|
|
20
34
|
const eff2 = (0, effect_1.succeed)(20);
|
|
21
|
-
const sumEff = (0,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
35
|
+
const sumEff = (0, asyncEffect_1.asyncFlatMap)(eff1, (a) => (0, asyncEffect_1.asyncFlatMap)(eff2, (b) => (0, asyncEffect_1.asyncSucceed)([a, b])));
|
|
36
|
+
run("zip(eff1, eff2):", sumEff, env);
|
|
37
|
+
// foreach sobre array (sin helper): secuenciar efectos
|
|
38
|
+
const nums = [1, 2, 3];
|
|
39
|
+
const foreachEff = nums.reduce((accEff, n) => (0, asyncEffect_1.asyncFlatMap)(accEff, (acc) => (0, asyncEffect_1.asyncFlatMap)((0, effect_1.succeed)(n * 2), (m) => (0, asyncEffect_1.asyncSucceed)([...acc, m]))), (0, asyncEffect_1.asyncSucceed)([]));
|
|
40
|
+
run("foreach array:", foreachEff, env);
|
|
41
|
+
// Stream map + collect (collectStream devuelve Async)
|
|
26
42
|
const s = (0, stream_1.fromArray)([1, 2, 3, 4]);
|
|
27
43
|
const sMapped = (0, stream_1.mapStream)(s, (n) => n * 10);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
const collectedEff = (0, stream_1.collectStream)(sMapped); // <- ahora NO recibe env acá
|
|
45
|
+
run("Stream mapeado:", collectedEff, env);
|
|
46
|
+
// Scope
|
|
47
|
+
(0, scope_1.withScope)((scope) => {
|
|
31
48
|
const f1 = scope.fork(task("A", 1000), env);
|
|
32
49
|
const f2 = scope.fork(task("B", 1500), env);
|
|
33
50
|
const f3 = scope.fork(task("C", 2000), env);
|
|
34
51
|
console.log("Tareas lanzadas dentro del scope");
|
|
35
|
-
// Si quiero, cancelo todo luego de 1.2s
|
|
36
52
|
setTimeout(() => {
|
|
37
53
|
console.log("CANCELANDO TODO EL SCOPE...");
|
|
38
54
|
scope.close();
|
|
@@ -41,15 +57,9 @@ function main() {
|
|
|
41
57
|
f2.join(console.log);
|
|
42
58
|
f3.join(console.log);
|
|
43
59
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
setTimeout(() => {
|
|
48
|
-
cb({ _tag: "Success", value: undefined });
|
|
49
|
-
}, ms);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function task(name, ms) {
|
|
53
|
-
return (0, asyncEffect_1.asyncFlatMap)(sleep(ms), () => (0, asyncEffect_1.asyncSucceed)(`Terminé ${name} después de ${ms}ms`));
|
|
60
|
+
// (opcional) esperar a que terminen A/B si querés
|
|
61
|
+
fiberA.join(() => { });
|
|
62
|
+
fiberB.join(() => { });
|
|
54
63
|
}
|
|
55
64
|
main();
|
|
65
|
+
//# sourceMappingURL=demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/examples/demo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fiberFinalizer.d.ts","sourceRoot":"","sources":["../../src/examples/fiberFinalizer.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fiberFinalizer.js","sourceRoot":"","sources":["../../src/examples/fiberFinalizer.ts"],"names":[],"mappings":";;AAAA,oBAAoB;AACpB,sDAAgE;AAChE,2CAAuC;AACvC,iCAA+B;AAE/B,SAAS,UAAU,CAAC,IAAS;IACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IACnF,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IACnF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,IAAI;IACT,MAAM,GAAG,GAAG,EAAE,CAAC;IACf,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEtB,MAAM,GAAG,GACL,IAAA,0BAAY,EAAC,IAAA,wBAAU,EAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,CACtD,IAAA,0BAAY,EAAC,IAAA,YAAK,EAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAC3B,IAAA,wBAAU,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAC3B,CACJ,CAAC;IAEN,MAAM,KAAK,GAAG,IAAA,YAAI,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAE7B,mCAAmC;IACnC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,IAAA,wBAAU,EAAC,GAAG,EAAE;;QACZ,QAAQ,IAAI,CAAC,CAAC;QACd,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAE3B,MAAM,KAAK,GAAG,MAAA,IAAI,KAAK,EAAE,CAAC,KAAK,0CACzB,KAAK,CAAC,IAAI,EACX,KAAK,CAAC,CAAC,EAAE,CAAC,EACV,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhB,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,KAAK,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACvE,CAAC,CAAC,CACL,CAAC;IAEF,+DAA+D;IAC/D,UAAU,CAAC,GAAG,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,2BAA2B,CAAC,CAAC;QAC/D,KAAK,CAAC,SAAS,EAAE,CAAC;IACtB,CAAC,EAAE,GAAG,CAAC,CAAC;IAER,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QAChB,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,sBAAsB,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACP,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fromPromise.d.ts","sourceRoot":"","sources":["../../src/examples/fromPromise.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAclE,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAmBjC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.slowRangeFromPromise = slowRangeFromPromise;
|
|
4
|
+
const asyncEffect_1 = require("../types/asyncEffect");
|
|
5
|
+
const option_1 = require("../types/option");
|
|
6
|
+
const stream_1 = require("../stream/stream");
|
|
7
|
+
const buffer_1 = require("../stream/buffer");
|
|
8
|
+
// delay abortable en Promise
|
|
9
|
+
function sleepAbortable(ms, signal) {
|
|
10
|
+
return new Promise((res, rej) => {
|
|
11
|
+
const t = setTimeout(res, ms);
|
|
12
|
+
signal.addEventListener("abort", () => {
|
|
13
|
+
clearTimeout(t);
|
|
14
|
+
rej(new Error("aborted"));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function slowRangeFromPromise(start, end, msPerElem) {
|
|
19
|
+
const go = (i) => (0, stream_1.fromPull)(i > end
|
|
20
|
+
? (0, asyncEffect_1.asyncFail)(option_1.none)
|
|
21
|
+
: (0, asyncEffect_1.asyncFlatMap)((0, asyncEffect_1.fromPromiseAbortable)(async (_env, signal) => {
|
|
22
|
+
await sleepAbortable(msPerElem, signal);
|
|
23
|
+
return i;
|
|
24
|
+
},
|
|
25
|
+
// en este stream no queremos “errores reales”, solo fin => never
|
|
26
|
+
() => undefined), (v) => (0, asyncEffect_1.asyncSucceed)([v, go(i + 1)])));
|
|
27
|
+
return go(start);
|
|
28
|
+
}
|
|
29
|
+
async function test_fromPromise_buffer() {
|
|
30
|
+
const s = slowRangeFromPromise(1, 10, 30);
|
|
31
|
+
const sb = (0, buffer_1.buffer)(s, 4, "backpressure");
|
|
32
|
+
const out = await (0, asyncEffect_1.toPromise)((0, stream_1.collectStream)(sb), undefined);
|
|
33
|
+
console.log("buffered out length =", out.length);
|
|
34
|
+
console.log(out);
|
|
35
|
+
}
|
|
36
|
+
async function test_fromPromise_emits() {
|
|
37
|
+
const s = slowRangeFromPromise(1, 5, 10);
|
|
38
|
+
const out = await (0, asyncEffect_1.toPromise)((0, stream_1.collectStream)(s), undefined);
|
|
39
|
+
console.log("out =", out);
|
|
40
|
+
// esperado: [1,2,3,4,5]
|
|
41
|
+
}
|
|
42
|
+
test_fromPromise_emits().catch(console.error);
|
|
43
|
+
test_fromPromise_buffer().catch(console.error);
|
|
44
|
+
//# sourceMappingURL=fromPromise.js.map
|