import * as Equal from "../Equal.js" import { pipe } from "../Function.js" import { globalValue } from "../GlobalValue.js" import * as Hash from "../Hash.js" import { NodeInspectSymbol } from "../Inspectable.js" import { pipeArguments } from "../Pipeable.js" import { hasProperty } from "../Predicate.js" import type * as Redacted from "../Redacted.js" /** @internal */ const RedactedSymbolKey = "effect/Redacted" /** @internal */ export const redactedRegistry = globalValue( "effect/Redacted/redactedRegistry", () => new WeakMap, any>() ) /** @internal */ export const RedactedTypeId: Redacted.RedactedTypeId = Symbol.for( RedactedSymbolKey ) as Redacted.RedactedTypeId /** @internal */ export const proto = { [RedactedTypeId]: { _A: (_: never) => _ }, pipe() { return pipeArguments(this, arguments) }, toString() { return "" }, toJSON() { return "" }, [NodeInspectSymbol]() { return "" }, [Hash.symbol](this: Redacted.Redacted): number { return pipe( Hash.hash(RedactedSymbolKey), Hash.combine(Hash.hash(redactedRegistry.get(this))), Hash.cached(this) ) }, [Equal.symbol](this: Redacted.Redacted, that: unknown): boolean { return isRedacted(that) && Equal.equals(redactedRegistry.get(this), redactedRegistry.get(that)) } } /** @internal */ export const isRedacted = (u: unknown): u is Redacted.Redacted => hasProperty(u, RedactedTypeId) /** @internal */ export const make = (value: T): Redacted.Redacted => { const redacted = Object.create(proto) redactedRegistry.set(redacted, value) return redacted } /** @internal */ export const value = (self: Redacted.Redacted): T => { if (redactedRegistry.has(self)) { return redactedRegistry.get(self) } else { throw new Error("Unable to get redacted value") } } /** @internal */ export const unsafeWipe = (self: Redacted.Redacted): boolean => redactedRegistry.delete(self)