/** * @since 2.0.0 */ import * as Effect from "./Effect.js" import { dual } from "./Function.js" import { pipeArguments } from "./Pipeable.js" import { hasProperty } from "./Predicate.js" import * as Readable from "./Readable.js" import * as Stream from "./Stream.js" import type { NoInfer } from "./Types.js" /** * @since 2.0.0 * @category type ids */ export const TypeId: unique symbol = Symbol.for("effect/Subscribable") /** * @since 2.0.0 * @category type ids */ export type TypeId = typeof TypeId /** * @since 2.0.0 * @category models */ export interface Subscribable extends Readable.Readable { readonly [TypeId]: TypeId readonly changes: Stream.Stream } /** * @since 2.0.0 * @category refinements */ export const isSubscribable = (u: unknown): u is Subscribable => hasProperty(u, TypeId) const Proto: Omit, "get" | "changes"> = { [Readable.TypeId]: Readable.TypeId, [TypeId]: TypeId, pipe() { return pipeArguments(this, arguments) } } /** * @since 2.0.0 * @category constructors */ export const make = (options: { readonly get: Effect.Effect readonly changes: Stream.Stream }): Subscribable => Object.assign(Object.create(Proto), options) /** * @since 2.0.0 * @category combinators */ export const map: { /** * @since 2.0.0 * @category combinators */ (f: (a: NoInfer) => B): (fa: Subscribable) => Subscribable /** * @since 2.0.0 * @category combinators */ (self: Subscribable, f: (a: NoInfer) => B): Subscribable } = dual(2, (self: Subscribable, f: (a: NoInfer) => B): Subscribable => make({ get: Effect.map(self.get, f), changes: Stream.map(self.changes, f) })) /** * @since 2.0.0 * @category combinators */ export const mapEffect: { /** * @since 2.0.0 * @category combinators */ (f: (a: NoInfer) => Effect.Effect): (fa: Subscribable) => Subscribable /** * @since 2.0.0 * @category combinators */ ( self: Subscribable, f: (a: NoInfer) => Effect.Effect ): Subscribable } = dual(2, ( self: Subscribable, f: (a: NoInfer) => Effect.Effect ): Subscribable => make({ get: Effect.flatMap(self.get, f), changes: Stream.mapEffect(self.changes, f) })) /** * @since 2.0.0 * @category constructors */ export const unwrap = ( effect: Effect.Effect, E1, R1> ): Subscribable => make({ get: Effect.flatMap(effect, (s) => s.get), changes: Stream.unwrap(Effect.map(effect, (s) => s.changes)) })