@fncts/io 0.0.29 → 0.0.31

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 (59) hide show
  1. package/IO/api/blocking.d.ts +7 -0
  2. package/IO.d.ts +2 -0
  3. package/Ref/Synchronized/definition.d.ts +3 -3
  4. package/Semaphore.d.ts +30 -0
  5. package/SubscriptionRef.d.ts +3 -3
  6. package/_cjs/Channel/api/mapOutConcurrentIO.cjs +14 -16
  7. package/_cjs/Channel/api/mapOutConcurrentIO.cjs.map +1 -1
  8. package/_cjs/Channel/api/mergeAllWith.cjs +30 -32
  9. package/_cjs/Channel/api/mergeAllWith.cjs.map +1 -1
  10. package/_cjs/IO/api/blocking.cjs +20 -0
  11. package/_cjs/IO/api/blocking.cjs.map +1 -0
  12. package/_cjs/IO.cjs +22 -0
  13. package/_cjs/IO.cjs.map +1 -1
  14. package/_cjs/Ref/Synchronized/constructors.cjs +4 -5
  15. package/_cjs/Ref/Synchronized/constructors.cjs.map +1 -1
  16. package/_cjs/Ref/Synchronized/definition.cjs +1 -2
  17. package/_cjs/Ref/Synchronized/definition.cjs.map +1 -1
  18. package/_cjs/Semaphore.cjs +90 -0
  19. package/_cjs/Semaphore.cjs.map +1 -0
  20. package/_cjs/Stream/api.cjs +47 -49
  21. package/_cjs/Stream/api.cjs.map +1 -1
  22. package/_cjs/SubscriptionRef.cjs +2 -3
  23. package/_cjs/SubscriptionRef.cjs.map +1 -1
  24. package/_cjs/internal/BackgroundScheduler.cjs +199 -0
  25. package/_cjs/internal/BackgroundScheduler.cjs.map +1 -0
  26. package/_mjs/Channel/api/mapOutConcurrentIO.mjs +14 -16
  27. package/_mjs/Channel/api/mapOutConcurrentIO.mjs.map +1 -1
  28. package/_mjs/Channel/api/mergeAllWith.mjs +30 -32
  29. package/_mjs/Channel/api/mergeAllWith.mjs.map +1 -1
  30. package/_mjs/IO/api/blocking.mjs +12 -0
  31. package/_mjs/IO/api/blocking.mjs.map +1 -0
  32. package/_mjs/IO.mjs +2 -0
  33. package/_mjs/IO.mjs.map +1 -1
  34. package/_mjs/Ref/Synchronized/constructors.mjs +4 -5
  35. package/_mjs/Ref/Synchronized/constructors.mjs.map +1 -1
  36. package/_mjs/Ref/Synchronized/definition.mjs +1 -2
  37. package/_mjs/Ref/Synchronized/definition.mjs.map +1 -1
  38. package/_mjs/Semaphore.mjs +78 -0
  39. package/_mjs/Semaphore.mjs.map +1 -0
  40. package/_mjs/Stream/api.mjs +47 -49
  41. package/_mjs/Stream/api.mjs.map +1 -1
  42. package/_mjs/SubscriptionRef.mjs +2 -3
  43. package/_mjs/SubscriptionRef.mjs.map +1 -1
  44. package/_mjs/internal/BackgroundScheduler.mjs +191 -0
  45. package/_mjs/internal/BackgroundScheduler.mjs.map +1 -0
  46. package/_src/Channel/api/mapOutConcurrentIO.ts +1 -1
  47. package/_src/Channel/api/mergeAllWith.ts +1 -1
  48. package/_src/IO/api/blocking.ts +9 -0
  49. package/_src/IO.ts +2 -0
  50. package/_src/Ref/Synchronized/constructors.ts +2 -2
  51. package/_src/Ref/Synchronized/definition.ts +1 -1
  52. package/_src/Semaphore.ts +81 -0
  53. package/_src/Stream/api.ts +1 -1
  54. package/_src/SubscriptionRef.ts +2 -2
  55. package/_src/global.ts +4 -0
  56. package/_src/internal/BackgroundScheduler.ts +276 -0
  57. package/global.d.ts +4 -0
  58. package/internal/BackgroundScheduler.d.ts +47 -0
  59. package/package.json +2 -2
@@ -35,7 +35,7 @@ export function mergeAllWith<OutDone>(
35
35
  const cancelers = Δ(IO.acquireRelease(Queue.makeUnbounded<Future<never, void>>(), (queue) => queue.shutdown));
36
36
  const lastDone = Δ(Ref.make<Maybe<OutDone>>(Nothing()));
37
37
  const errorSignal = Δ(Future.make<never, void>());
38
- const permits = Δ(TSemaphore.make(n).commit);
38
+ const permits = Δ(Semaphore(n));
39
39
  const pull = Δ(channels.toPull);
40
40
  const evaluatePull = (pull: IO<Env | Env1, OutErr | OutErr1, Either<OutDone, OutElem>>) =>
41
41
  pull
@@ -0,0 +1,9 @@
1
+ import { backgroundScheduler } from "@fncts/io/internal/BackgroundScheduler";
2
+
3
+ /**
4
+ * @tsplus static fncts.io.IOOps blocking
5
+ * @tsplus getter fncts.io.IO blocking
6
+ */
7
+ export function blocking<R, E, A>(self: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
8
+ return FiberRef.currentScheduler.locally(backgroundScheduler)(IO.yieldNow) > self;
9
+ }
package/_src/IO.ts CHANGED
@@ -13,6 +13,7 @@ export * from "./IO/api/addFinalizer.js";
13
13
  export * from "./IO/api/addFinalizerExit.js";
14
14
  export * from "./IO/api/asyncInterrupt.js";
15
15
  export * from "./IO/api/asyncIO.js";
16
+ export * from "./IO/api/blocking.js";
16
17
  export * from "./IO/api/bracket.js";
17
18
  export * from "./IO/api/bracketExit.js";
18
19
  export * from "./IO/api/clockWith.js";
@@ -38,6 +39,7 @@ export * from "./IO/api/memoize.js";
38
39
  export * from "./IO/api/once.js";
39
40
  export * from "./IO/api/onTermination.js";
40
41
  export * from "./IO/api/provideLayer.js";
42
+ export * from "./IO/api/provideScope.js";
41
43
  export * from "./IO/api/provideSomeLayer.js";
42
44
  export * from "./IO/api/race.js";
43
45
  export * from "./IO/api/raceFirst.js";
@@ -5,7 +5,7 @@ import { PSynchronizedInternal } from "./definition.js";
5
5
  */
6
6
  export function unsafeMakeSynchronized<A>(a: A, __tsplusTrace?: string): Ref.Synchronized<A> {
7
7
  const ref = Ref.unsafeMake(a);
8
- const semaphore = TSemaphore.unsafeMake(1);
8
+ const semaphore = Semaphore.unsafeMake(1);
9
9
  return new PSynchronizedInternal(semaphore, ref.get, (a: A) => ref.set(a));
10
10
  }
11
11
 
@@ -15,7 +15,7 @@ export function unsafeMakeSynchronized<A>(a: A, __tsplusTrace?: string): Ref.Syn
15
15
  export function makeSynchronized<A>(a: Lazy<A>, __tsplusTrace?: string): UIO<Ref.Synchronized<A>> {
16
16
  return Do((_) => {
17
17
  const ref = _(Ref.make(a));
18
- const semaphore = _(TSemaphore.make(1).commit);
18
+ const semaphore = _(Semaphore(1));
19
19
  return new PSynchronizedInternal(semaphore, ref.get, (a: A) => ref.set(a));
20
20
  });
21
21
  }
@@ -30,7 +30,7 @@ export const Synchronized: PSynchronizedOps = {};
30
30
  export class PSynchronizedInternal<RA, RB, EA, EB, A, B> extends RefInternal<RA, RB, EA, EB, A, B> {
31
31
  readonly [SynchronizedTypeId]: SynchronizedTypeId = SynchronizedTypeId;
32
32
  constructor(
33
- readonly semaphore: TSemaphore,
33
+ readonly semaphore: Semaphore,
34
34
  readonly unsafeGet: IO<RB, EB, B>,
35
35
  readonly unsafeSet: (a: A) => IO<RA, EA, void>,
36
36
  ) {
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @tsplus type fncts.io.Semaphore
3
+ * @tsplus companion fncts.io.SemaphoreOps
4
+ */
5
+ export class Semaphore {
6
+ constructor(readonly permits: number) {}
7
+
8
+ taken = 0;
9
+ waiters = new Set<() => void>();
10
+
11
+ get free(): number {
12
+ return this.permits - this.taken;
13
+ }
14
+
15
+ runNext() {
16
+ const next = this.waiters.values().next();
17
+ if (!next.done) {
18
+ this.waiters.delete(next.value);
19
+ next.value();
20
+ }
21
+ }
22
+
23
+ take(n: number) {
24
+ return IO.asyncInterrupt<never, never, number>((cb) => {
25
+ if (this.free < n) {
26
+ const observer = () => {
27
+ if (this.free >= n) {
28
+ this.waiters.delete(observer);
29
+ this.taken += n;
30
+ cb(IO.succeedNow(n));
31
+ }
32
+ };
33
+ this.waiters.add(observer);
34
+ return Either.left(
35
+ IO(() => {
36
+ this.waiters.delete(observer);
37
+ }),
38
+ );
39
+ }
40
+ this.taken += n;
41
+ return Either.right(IO.succeedNow(n));
42
+ });
43
+ }
44
+
45
+ release(n: number) {
46
+ return IO.withFiberRuntime<never, never, void>((fiber) => {
47
+ this.taken -= n;
48
+ fiber.getFiberRef(FiberRef.currentScheduler).scheduleTask(() => {
49
+ this.waiters.forEach((wake) => wake());
50
+ });
51
+ return IO.unit;
52
+ });
53
+ }
54
+
55
+ withPermits(permits: number) {
56
+ return <R, E, A>(io: IO<R, E, A>): IO<R, E, A> => {
57
+ return IO.uninterruptibleMask((restore) =>
58
+ restore(this.take(permits)).flatMap((permits) => restore(io).ensuring(this.release(permits))),
59
+ );
60
+ };
61
+ }
62
+
63
+ withPermit<R, E, A>(io: IO<R, E, A>): IO<R, E, A> {
64
+ return this.withPermits(1)(io);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @tsplus static fncts.io.SemaphoreOps unsafeMake
70
+ */
71
+ export function unsafeMakeSemaphore(permits: number): Semaphore {
72
+ return new Semaphore(permits);
73
+ }
74
+
75
+ /**
76
+ * @tsplus static fncts.io.SemaphoreOps make
77
+ * @tsplus static fncts.io.SemaphoreOps __call
78
+ */
79
+ export function makeSemaphore(permits: number, __tsplusTrace?: string): UIO<Semaphore> {
80
+ return IO(Semaphore.unsafeMake(permits));
81
+ }
@@ -1092,7 +1092,7 @@ export function distributedWithDynamic<E, A>(
1092
1092
  );
1093
1093
  const add = Δ(
1094
1094
  Do((Δ) => {
1095
- const queuesLock = Δ(TSemaphore.make(1).commit);
1095
+ const queuesLock = Δ(Semaphore(1));
1096
1096
  const newQueue = Δ(
1097
1097
  Ref.make<UIO<readonly [symbol, Queue<Exit<Maybe<E>, A>>]>>(
1098
1098
  Do((Δ) => {
@@ -6,7 +6,7 @@ export type SubscriptionRefTypeId = typeof SubscriptionRefTypeId;
6
6
 
7
7
  export class SubscriptionRefInternal<A> extends PSynchronizedInternal<never, never, never, never, A, A> {
8
8
  readonly [SubscriptionRefTypeId]: SubscriptionRefTypeId = SubscriptionRefTypeId;
9
- constructor(readonly semaphore: TSemaphore, readonly hub: Hub<A>, readonly ref: Ref<A>) {
9
+ constructor(readonly semaphore: Semaphore, readonly hub: Hub<A>, readonly ref: Ref<A>) {
10
10
  super(semaphore, ref.get, (a) => ref.set(a));
11
11
  }
12
12
  changes: Stream<never, never, A> = Stream.unwrapScoped(
@@ -50,7 +50,7 @@ export function concrete<A>(_: SubscriptionRef<A>): asserts _ is SubscriptionRef
50
50
  */
51
51
  export function make<A>(value: Lazy<A>): UIO<SubscriptionRef<A>> {
52
52
  return Do((Δ) => {
53
- const semaphore = Δ(TSemaphore.make(1).commit);
53
+ const semaphore = Δ(Semaphore(1));
54
54
  const hub = Δ(Hub.makeUnbounded<A>());
55
55
  const ref = Δ(Ref.make(value));
56
56
  return new SubscriptionRefInternal(semaphore, hub, ref);
package/_src/global.ts CHANGED
@@ -119,6 +119,10 @@ import { Finalizer } from "@fncts/io/Scope/Finalizer";
119
119
  * @tsplus global
120
120
  */
121
121
  import { ScopedRef } from "@fncts/io/ScopedRef/definition";
122
+ /**
123
+ * @tsplus global
124
+ */
125
+ import { Semaphore } from "@fncts/io/Semaphore";
122
126
  /**
123
127
  * @tsplus global
124
128
  */
@@ -0,0 +1,276 @@
1
+ import type { Scheduler } from "@fncts/io/internal/Scheduler";
2
+
3
+ interface IdleDeadline {
4
+ timeRemaining(): number;
5
+ readonly didTimeout: boolean;
6
+ }
7
+
8
+ declare const requestIdleCallback: ((callback: (deadline: IdleDeadline) => void) => number) | undefined;
9
+ declare const cancelIdleCallback: ((handle: number | undefined) => void) | undefined;
10
+ declare const requestAnimationFrame: ((callback: (time: number) => void) => void) | undefined;
11
+ interface Navigator {
12
+ scheduling:
13
+ | {
14
+ isInputPending: (() => boolean) | undefined;
15
+ }
16
+ | undefined;
17
+ }
18
+ declare const navigator: Navigator;
19
+
20
+ interface WhenReady<T> {
21
+ promise: () => Promise<T>;
22
+ resolve: (value: T) => void;
23
+ }
24
+
25
+ function whenReady<T>(): WhenReady<T> {
26
+ const observers: Array<(value: T) => void> = [];
27
+
28
+ const promise = () => new Promise<T>((resolve) => observers.push(resolve));
29
+
30
+ return {
31
+ promise,
32
+ resolve: (value) => observers.forEach((observer) => observer(value)),
33
+ };
34
+ }
35
+
36
+ interface Task {
37
+ ready: () => Promise<void>;
38
+ resolve: () => void;
39
+ }
40
+
41
+ interface State {
42
+ tasks: Array<Task>;
43
+ frameTimeElapsed: boolean;
44
+ onIdleCallback: WhenReady<void>;
45
+ onAnimationFrame: WhenReady<void>;
46
+ frameWorkStartTime: number | undefined;
47
+ idleDeadline: IdleDeadline | undefined;
48
+ }
49
+
50
+ export class BackgroundScheduler implements Scheduler {
51
+ state: State = {
52
+ tasks: [],
53
+ idleDeadline: undefined,
54
+ frameTimeElapsed: false,
55
+ onIdleCallback: whenReady(),
56
+ onAnimationFrame: whenReady(),
57
+ frameWorkStartTime: undefined,
58
+ };
59
+
60
+ isTracking = false;
61
+ idleCallbackId: number | undefined;
62
+ lastCallTime = 0;
63
+ lastResult = false;
64
+ globalId = 0;
65
+ running = new Set<number>();
66
+ callbacks: Array<() => void> = [];
67
+ promiseEscapeId: number | undefined;
68
+
69
+ scheduleTask(task: () => void) {
70
+ this.yieldBackgroundOrContinue().then(() => {
71
+ task();
72
+ });
73
+ }
74
+
75
+ createTask(): Task {
76
+ const wr = whenReady<void>();
77
+ const item = { ready: wr.promise, resolve: wr.resolve };
78
+ this.state.tasks.push(item);
79
+ if (this.state.tasks.length === 1) {
80
+ this.startTracking();
81
+ }
82
+ return item;
83
+ }
84
+
85
+ startTracking(): void {
86
+ if (this.isTracking) {
87
+ return;
88
+ }
89
+
90
+ this.isTracking = true;
91
+
92
+ const reset = () => {
93
+ this.state.idleDeadline = undefined;
94
+ this.state.frameTimeElapsed = false;
95
+ this.state.frameWorkStartTime = undefined;
96
+ };
97
+
98
+ const loop = () => {
99
+ if (typeof requestIdleCallback !== "undefined") {
100
+ this.idleCallbackId = requestIdleCallback((deadline) => {
101
+ reset();
102
+ this.state.idleDeadline = deadline;
103
+ this.state.onIdleCallback.resolve();
104
+ this.state.onIdleCallback = whenReady();
105
+ });
106
+ }
107
+
108
+ const cb = () => {
109
+ reset();
110
+ this.state.onAnimationFrame.resolve();
111
+ this.state.onAnimationFrame = whenReady();
112
+ if (this.state.tasks.length === 0) {
113
+ this.isTracking = false;
114
+ if (typeof cancelIdleCallback !== "undefined") {
115
+ cancelIdleCallback(this.idleCallbackId);
116
+ }
117
+ } else {
118
+ loop();
119
+ }
120
+ };
121
+
122
+ if (typeof requestAnimationFrame !== "undefined") {
123
+ requestAnimationFrame(cb);
124
+ } else {
125
+ setTimeout(cb, 0);
126
+ }
127
+ };
128
+
129
+ loop();
130
+ }
131
+
132
+ removeTask(task: Task) {
133
+ const index = this.state.tasks.indexOf(task);
134
+ if (index !== -1) {
135
+ this.state.tasks.splice(index, 1);
136
+ }
137
+ }
138
+
139
+ nextTask() {
140
+ if (this.state.tasks.length > 0) {
141
+ this.state.tasks[0]!.resolve();
142
+ }
143
+ }
144
+
145
+ isTimeToYield(): boolean {
146
+ const now = Date.now();
147
+
148
+ if (!this.lastResult && now - this.lastCallTime === 0) {
149
+ return this.lastResult;
150
+ }
151
+
152
+ this.lastCallTime = now;
153
+ this.lastResult =
154
+ now >= this.calculateDeadline() ||
155
+ (typeof navigator !== "undefined" && navigator.scheduling?.isInputPending?.() === true);
156
+
157
+ if (this.lastResult) {
158
+ this.state.frameTimeElapsed = true;
159
+ }
160
+
161
+ return this.lastResult;
162
+ }
163
+
164
+ calculateDeadline(): number {
165
+ if (this.state.frameWorkStartTime === undefined) {
166
+ return -1;
167
+ }
168
+
169
+ const idleDeadline =
170
+ this.state.idleDeadline === undefined
171
+ ? Number.MAX_SAFE_INTEGER
172
+ : Date.now() + this.state.idleDeadline.timeRemaining();
173
+
174
+ return Math.min(this.state.frameWorkStartTime + 5, idleDeadline);
175
+ }
176
+
177
+ requestPromiseEscape(callback: () => void): number {
178
+ const id = this.globalId;
179
+
180
+ this.running.add(id);
181
+
182
+ Promise.resolve().then(() => {
183
+ Promise.resolve().then(() => {
184
+ if (this.running.has(id)) {
185
+ callback();
186
+ this.running.delete(id);
187
+ }
188
+ });
189
+ });
190
+
191
+ this.globalId += 1;
192
+
193
+ return id;
194
+ }
195
+
196
+ cancelPromiseEscape(id: number | undefined): void {
197
+ if (id !== undefined) {
198
+ this.running.delete(id);
199
+ }
200
+ }
201
+
202
+ requestNextTask(callback: () => void): void {
203
+ if (this.callbacks.length === 0) {
204
+ const channel = new MessageChannel();
205
+ channel.port2.postMessage(undefined);
206
+ // @ts-expect-error
207
+ channel.port1.onmessage = (): void => {
208
+ channel.port1.close();
209
+ channel.port2.close();
210
+
211
+ const callbacksCopy = this.callbacks;
212
+ this.callbacks = [];
213
+ for (const callback of callbacksCopy) {
214
+ callback();
215
+ }
216
+ };
217
+ }
218
+
219
+ this.callbacks.push(callback);
220
+ }
221
+
222
+ async yieldControl(): Promise<void> {
223
+ this.cancelPromiseEscape(this.promiseEscapeId);
224
+
225
+ const task = this.createTask();
226
+
227
+ await this.schedule();
228
+
229
+ if (this.state.tasks[0] !== task) {
230
+ await task.ready();
231
+ if (this.isTimeToYield()) {
232
+ await this.schedule();
233
+ }
234
+ }
235
+
236
+ this.removeTask(task);
237
+
238
+ this.cancelPromiseEscape(this.promiseEscapeId);
239
+
240
+ this.promiseEscapeId = this.requestPromiseEscape(() => {
241
+ this.nextTask();
242
+ });
243
+ }
244
+
245
+ async schedule(): Promise<void> {
246
+ if (this.state.frameTimeElapsed) {
247
+ await this.state.onAnimationFrame.promise();
248
+ }
249
+
250
+ if (typeof requestIdleCallback === "undefined") {
251
+ await new Promise<void>((resolve) => this.requestNextTask(resolve));
252
+
253
+ if (typeof navigator !== "undefined" && navigator.scheduling?.isInputPending?.() === true) {
254
+ await this.schedule();
255
+ } else if (this.state.frameWorkStartTime === undefined) {
256
+ this.state.frameWorkStartTime = Date.now();
257
+ }
258
+ } else {
259
+ await this.state.onIdleCallback.promise();
260
+
261
+ if (this.state.frameWorkStartTime === undefined) {
262
+ this.state.frameWorkStartTime = Date.now();
263
+ }
264
+ }
265
+ }
266
+
267
+ yieldBackgroundOrContinue(): Promise<void> {
268
+ if (this.isTimeToYield()) {
269
+ return this.yieldControl();
270
+ }
271
+
272
+ return Promise.resolve();
273
+ }
274
+ }
275
+
276
+ export const backgroundScheduler = new BackgroundScheduler();
package/global.d.ts CHANGED
@@ -118,6 +118,10 @@ import { Finalizer } from "@fncts/io/Scope/Finalizer";
118
118
  * @tsplus global
119
119
  */
120
120
  import { ScopedRef } from "@fncts/io/ScopedRef/definition";
121
+ /**
122
+ * @tsplus global
123
+ */
124
+ import { Semaphore } from "@fncts/io/Semaphore";
121
125
  /**
122
126
  * @tsplus global
123
127
  */
@@ -0,0 +1,47 @@
1
+ import type { Scheduler } from "@fncts/io/internal/Scheduler";
2
+ interface IdleDeadline {
3
+ timeRemaining(): number;
4
+ readonly didTimeout: boolean;
5
+ }
6
+ interface WhenReady<T> {
7
+ promise: () => Promise<T>;
8
+ resolve: (value: T) => void;
9
+ }
10
+ interface Task {
11
+ ready: () => Promise<void>;
12
+ resolve: () => void;
13
+ }
14
+ interface State {
15
+ tasks: Array<Task>;
16
+ frameTimeElapsed: boolean;
17
+ onIdleCallback: WhenReady<void>;
18
+ onAnimationFrame: WhenReady<void>;
19
+ frameWorkStartTime: number | undefined;
20
+ idleDeadline: IdleDeadline | undefined;
21
+ }
22
+ export declare class BackgroundScheduler implements Scheduler {
23
+ state: State;
24
+ isTracking: boolean;
25
+ idleCallbackId: number | undefined;
26
+ lastCallTime: number;
27
+ lastResult: boolean;
28
+ globalId: number;
29
+ running: Set<number>;
30
+ callbacks: Array<() => void>;
31
+ promiseEscapeId: number | undefined;
32
+ scheduleTask(task: () => void): void;
33
+ createTask(): Task;
34
+ startTracking(): void;
35
+ removeTask(task: Task): void;
36
+ nextTask(): void;
37
+ isTimeToYield(): boolean;
38
+ calculateDeadline(): number;
39
+ requestPromiseEscape(callback: () => void): number;
40
+ cancelPromiseEscape(id: number | undefined): void;
41
+ requestNextTask(callback: () => void): void;
42
+ yieldControl(): Promise<void>;
43
+ schedule(): Promise<void>;
44
+ yieldBackgroundOrContinue(): Promise<void>;
45
+ }
46
+ export declare const backgroundScheduler: BackgroundScheduler;
47
+ export {};
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@fncts/io",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "dependencies": {
5
- "@fncts/base": "0.0.25",
5
+ "@fncts/base": "0.0.26",
6
6
  "@fncts/transformers": "0.0.4",
7
7
  "@fncts/typelevel": "0.0.15"
8
8
  },