@metreeca/core - v0.12.0
    Preparing search index...

    Module values

    General-purpose value operations.

    Deep Views

    State at the type level what the operations below enforce at run time: a structure no caller may write to, or one stated slot by slot without loosening the type of any slot:

    import { type DeepReadonly, type DeepPartial } from '@metreeca/core/values';

    type User = { name: string, address: { city: string } };

    declare const frozen: DeepReadonly<User>;
    frozen.address.city = "Rome"; // rejected at compile time

    const probe: DeepPartial<User> = { address: { city: "Rome" } }; // partial at any depth
    const typo: DeepPartial<User> = { address: { town: "Rome" } }; // rejected: no such slot

    Deep Equality

    Compare nested structures for structural equality:

    import { equals } from '@metreeca/core/values';

    // Objects and arrays
    equals({ a: [1, 2] }, { a: [1, 2] }); // true
    equals({ a: 1, b: 2 }, { b: 2, a: 1 }); // true (order-independent)
    equals([1, [2, 3]], [1, [2, 3]]); // true (nested arrays)

    // Primitives and functions
    equals(42, 42); // true
    equals(-0, +0); // false (distinguishes -0 from +0)

    const fn = () => {};
    equals(fn, fn); // true (same reference)

    Deep Freezing

    Create deeply frozen clones of plain objects and arrays, leaving every other value untouched:

    import { immutable } from '@metreeca/core/values';

    // Objects and arrays
    const original = { a: [1, 2, 3], b: { c: 4 } };
    const frozen = immutable(original);

    frozen.a[0] = 999; // throws Error
    frozen.b.c = 999; // throws Error

    // Primitives, functions and non-plain objects
    immutable(42); // 42
    immutable("hello"); // "hello"

    const fn = () => "hello";
    fn.config = { port: 3000 };

    immutable(fn) === fn; // true (handed back unchanged, properties still mutable)
    immutable(new Date()); // the same Date, not a frozen clone

    Stable Identity

    Cloning is idempotent at every depth: each frozen object and array is branded, so re-freezing a clone, or any nested member extracted from it, returns the same reference rather than a fresh copy. A frozen member keeps its identity even when reached through another path or nested into a new structure:

    import { immutable } from '@metreeca/core/values';

    const frozen = immutable({ inner: { p: 1 } });

    immutable(frozen) === frozen; // true (whole graph)
    immutable(frozen.inner) === frozen.inner; // true (nested member)

    immutable({ ref: frozen.inner }).ref === frozen.inner; // true (member nested into a new structure)

    Type-Safe Freezing

    Validate and freeze with optional type guards:

    import { immutable } from '@metreeca/core/values';
    import { isObject, isString, isNumber } from '@metreeca/core';

    // Define a type guard
    const isUser = (v: unknown): v is { name: string; age: number } =>
    isObject(v, { name: isString, age: isNumber });

    // Validate and freeze in one step
    const user = immutable(data, isUser);

    // Memoized: repeated calls with same guard return same reference
    immutable(user, isUser) === user; // true (no re-validation)

    // Different guard triggers revalidation
    const isAdmin = (v: unknown): v is { name: string; age: number } =>
    isUser(v) && v.age >= 18;

    immutable(user, isAdmin); // revalidates

    Sealed Content

    Attach hidden content to a frozen clone under a symbol key, retrievable only through the same symbol:

    import { immutable, seal } from '@metreeca/core/values';

    const Meta = Symbol("meta");

    const sealed = seal({ id: 1 }, Meta, { source: "cache" });

    seal(sealed, Meta); // { source: "cache" }
    seal({ id: 1 }, Meta); // undefined (nothing sealed under Meta)

    Object.keys(sealed); // ["id"] (sealed content is not enumerable)

    seal(42, Meta, "content"); // 42 (primitives are returned as-is)

    Both the sealed clone and its content are deep-frozen and branded, so immutable returns them unchanged:

    immutable(sealed) === sealed; // true
    

    Type Aliases

    DeepReadonly

    A deeply read-only view of a value.

    DeepPartial

    A deeply partial view of a value.

    Atomic

    A value treated as atomic by the deep operations.

    Functions

    equals

    Checks deep object equality.

    immutable

    Creates an immutable deep clone, optionally validating against a type guard.

    seal

    Inspects or attaches sealed content on a value.