/** * @since 1.0.0 */ import * as Context from "effect/Context" import * as Effect from "effect/Effect" import { dual } from "effect/Function" import * as Option from "effect/Option" import * as ParseResult from "effect/ParseResult" import * as Schema from "effect/Schema" /** * @since 1.0.0 * @category models */ export interface CollectorService { readonly addAll: (_: Iterable) => Effect.Effect readonly unsafeAddAll: (_: Iterable) => void readonly read: Effect.Effect> readonly unsafeRead: () => Array readonly unsafeClear: () => Array readonly clear: Effect.Effect> } /** * @since 1.0.0 * @category tags */ export class Collector extends Context.Tag("@effect/platform/Transferable/Collector")< Collector, CollectorService >() {} /** * @since 1.0.0 * @category constructors */ export const unsafeMakeCollector = (): CollectorService => { let tranferables: Array = [] const unsafeAddAll = (transfers: Iterable): void => { // eslint-disable-next-line no-restricted-syntax tranferables.push(...transfers) } const unsafeRead = (): Array => tranferables const unsafeClear = (): Array => { const prev = tranferables tranferables = [] return prev } return Collector.of({ unsafeAddAll, addAll: (transferables) => Effect.sync(() => unsafeAddAll(transferables)), unsafeRead, read: Effect.sync(unsafeRead), unsafeClear, clear: Effect.sync(unsafeClear) }) } /** * @since 1.0.0 * @category constructors */ export const makeCollector: Effect.Effect = Effect.sync(unsafeMakeCollector) /** * @since 1.0.0 * @category accessors */ export const addAll = (tranferables: Iterable): Effect.Effect => Effect.flatMap( Effect.serviceOption(Collector), Option.match({ onNone: () => Effect.void, onSome: (_) => _.addAll(tranferables) }) ) /** * @since 1.0.0 * @category schema */ export const schema: { /** * @since 1.0.0 * @category schema */ (f: (_: I) => Iterable): (self: Schema.Schema) => Schema.Schema /** * @since 1.0.0 * @category schema */ ( self: Schema.Schema, f: (_: I) => Iterable ): Schema.Schema } = dual(2, ( self: Schema.Schema, f: (_: I) => Iterable ) => Schema.transformOrFail( Schema.encodedSchema(self), self, { strict: true, decode: ParseResult.succeed, encode: (i) => Effect.as(addAll(f(i)), i) } )) /** * @since 1.0.0 * @category schema */ export const ImageData: Schema.Schema = schema( Schema.Any, (_) => [(_ as ImageData).data.buffer] ) /** * @since 1.0.0 * @category schema */ export const MessagePort: Schema.Schema = schema( Schema.Any, (_) => [_ as MessagePort] ) /** * @since 1.0.0 * @category schema */ export const Uint8Array: Schema.Schema = schema( Schema.Uint8ArrayFromSelf, (_) => [_.buffer] )