| 45 | export const make = <V>(value: V): Effect.Effect<ObservableResource<never, V>> => makeEffect(Effect.succeed(value)) |
| 46 | |
| 47 | export const makeEffect = <V, E>( |
| 48 | effect: Effect.Effect<V, E> |
| 49 | ): Effect.Effect<ObservableResource<E, V>> => |
| 50 | pipe( |
| 51 | Effect.zip(Ref.make(0), Ref.make(0)), |
| 52 | Effect.map(([resourceAcquisitionCount, resourceAcquisitionReleasing]) => { |
| 53 | const getState = Effect.zip( |
| 54 | Ref.get(resourceAcquisitionCount), |
| 55 | Ref.get(resourceAcquisitionReleasing) |
| 56 | ) |
| 57 | const scoped = Effect.uninterruptibleMask((restore) => |
| 58 | Effect.gen(function*() { |
| 59 | const parent = yield* Effect.scope |
| 60 | const child = yield* Scope.fork(parent, ExecutionStrategy.sequential) |
| 61 | yield* Ref.update(resourceAcquisitionCount, (n) => n + 1) |
| 62 | yield* Scope.addFinalizer(child, Ref.update(resourceAcquisitionReleasing, (n) => n + 1)) |
| 63 | return yield* Effect.acquireReleaseInterruptible( |
| 64 | restore(effect), |
| 65 | (exit) => Scope.close(child, exit) |
| 66 | ) |
| 67 | }) |
| 68 | ) |
| 69 | return new ObservableResourceImpl(scoped, getState) |
| 70 | }) |
| 71 | ) |