0Z4C0
// navigation
// @ozaco/std

Shared

Cross-cutting helpers and type utilities every other `std` module builds on: guards, `match`, `pipe`, deep merge, dotted paths, and more.

import from@ozaco/std/shared

shared is the dependency-free foundation of the standard library — the small, general-purpose helpers and types that result, effect, plugin, codec and logger all reuse, kept in one place so they never import each other in a cycle.

On the runtime side it ships type guards (isString, isObject, isPromise, isGenerator, …), a fluent pattern matcher (match), left-to-right function composition that transparently threads promises (pipe), immutable object helpers (deepMerge, getPath/setPath/unsetPath, flatten), string and error formatting (kebabToPascal, createTags, serializeError), lazy promises, a bitflag test, a binary-heap PriorityQueue, and synchronous Standard Schema validation (validateSync).

On the type side it exports the primitives the rest of the library is written against — AnyType, EmptyType, Primitive, LiteralUnion, Writable/WriteableDeep, ExplicitObject, the Pipe and MatchBuilder shapes, and the vendor-neutral StandardSchemaV1 / StandardJSONSchemaV1 interfaces used for schema interop.

// on this page
01

Guards

Runtime type predicates that narrow `unknown`.

fn

isString

Narrow a value to `string`.

signature
function isString(value: unknown): value is string
fn

isNumber

Narrow a value to `number`.

signature
function isNumber(value: unknown): value is number
fn

isBoolean

Narrow a value to `boolean`.

signature
function isBoolean(value: unknown): value is boolean
fn

isUndefined

Narrow a value to `undefined`.

signature
function isUndefined(value: unknown): value is undefined
fn

isFunction

Narrow a value to a callable `Function`.

signature
function isFunction(value: unknown): value is Function
fn

isObject

Narrow a value to a non-null, non-array object.

signature
function isObject(value: unknown): value is Record<string, unknown>
fn

isArray

Narrow a value to an array.

signature
function isArray<T>(value: unknown): value is T[]
fn

isPromise

Narrow a value to a thenable (`PromiseLike`).

signature
function isPromise(value: unknown): value is PromiseLike<any>
fn

isGenerator

Narrow a value to a synchronous `Generator`.

signature
function isGenerator(value: unknown): value is Generator<any, any>
fn

isAsyncGenerator

Narrow a value to an `AsyncGenerator`.

signature
function isAsyncGenerator(value: unknown): value is AsyncGenerator<any, any>
fn

isAsyncIterable

Narrow a value to an `AsyncIterable`.

signature
function isAsyncIterable(value: any): value is AsyncIterable<unknown>
fn

isArrayBuffer

Narrow a value to an `ArrayBuffer`.

signature
function isArrayBuffer(value: unknown): value is ArrayBuffer
fn

isSharedArrayBuffer

Narrow a value to a `SharedArrayBuffer` (guarding platforms without it).

signature
function isSharedArrayBuffer(value: unknown): value is SharedArrayBuffer
fn

isArrayBufferView

Narrow a value to any `ArrayBufferView` (typed array or `DataView`).

signature
function isArrayBufferView(value: unknown): value is ArrayBufferView
02

Utilities

Functional, object, string and collection helpers.

fn

match

Build a fluent, type-narrowing pattern matcher over a value.

signature
function match<const T>(value: T): MatchBuilder<T, T, never>

// MatchBuilder chains:
.with(schema, handler)      // match by Standard Schema, narrowing the remaining type
.when(predicate, handler)   // match by predicate/type-guard
.otherwise(handler)         // fallback, returns the result
.exhaustive()               // require all cases covered (compile-time)
.run()                      // evaluate, returning the result or null

Cases are evaluated top-to-bottom: the first with schema that validates or when predicate that passes wins, and its handler (a function, or a bare value for when) produces the result. .otherwise supplies a fallback, .exhaustive requires the union to be fully covered (throwing at runtime if nothing matches), and .run returns null when no case matches.

example
import { match } from '@ozaco/std/shared'

const label = match(status)
  .when((s): s is 200 => s === 200, () => 'ok')
  .when((s) => s >= 500, () => 'server error')
  .otherwise(() => 'unknown')
fn

pipe

Thread a value left-to-right through functions, awaiting promises between steps.

signature
const pipe: Pipe

// Pipe is a set of overloads (1 → 26 functions):
function pipe<A>(a: A): A
function pipe<A, B>(a: A, ab: (a: Awaited<A>) => B): B
function pipe<A, B, C>(a: A, ab: (a: Awaited<A>) => B, bc: (b: Awaited<B>) => C): C
// …and so on

Applies each function to the running value in order. If any step is a promise, the next function is chained with .then, so an async step turns the whole pipeline async — each subsequent function receives the Awaited value.

example
import { pipe } from '@ozaco/std/shared'

const doubled = pipe(
  '  42 ',
  (s) => s.trim(),
  (s) => Number(s),
  (n) => n * 2,
) //=> 84
fn

deepMerge

Recursively merge plain objects left → right, cloning nested objects and returning a fresh tree.

signature
function deepMerge<T extends Record<string, any>>(
  ...sources: (Partial<T> | undefined)[]
): T

Later sources win. Nested plain objects merge deeply; arrays and primitives are replaced wholesale. An undefined value never overrides an earlier one. Inputs are never mutated — nested objects are cloned so the result never aliases a source (arrays are shared by reference).

example
import { deepMerge } from '@ozaco/std/shared'

deepMerge(
  { a: 1, nested: { x: 1 } },
  { b: 3, nested: { y: 2 } },
) //=> { a: 1, b: 3, nested: { x: 1, y: 2 } }
fn

getPath

Read a dotted key (`a.b.c`) from a nested object.

signature
function getPath<T = unknown>(obj: Record<string, any>, path: string): T | undefined

Returns undefined if any segment along the path is missing or non-object.

example
import { getPath } from '@ozaco/std/shared'

getPath({ a: { b: 1 } }, 'a.b') //=> 1
getPath({ a: {} }, 'a.b.c')     //=> undefined
fn

setPath

Set a dotted key, returning a new object with intermediates created/cloned.

signature
function setPath<T extends Record<string, any>>(
  obj: T,
  path: string,
  value: unknown,
): T

Immutable: the original object and untouched branches are preserved; only the path down to the leaf is cloned.

example
import { setPath } from '@ozaco/std/shared'

setPath({ a: { b: 1 } }, 'a.c', 2) //=> { a: { b: 1, c: 2 } }
fn

unsetPath

Remove a dotted key, returning a new object (a no-op copy if the path is absent).

signature
function unsetPath<T extends Record<string, any>>(obj: T, path: string): T
fn

flattenEntries

Flatten a nested object to leaf `{ key, value }` entries with dotted keys.

signature
function flattenEntries(obj: Record<string, any>, prefix?: string): FlatEntry[]

Recurses into nested plain objects; arrays are treated as leaf values.

example
import { flattenEntries } from '@ozaco/std/shared'

flattenEntries({ a: { b: 1 }, c: 2 })
//=> [{ key: 'a.b', value: 1 }, { key: 'c', value: 2 }]
fn

flatten

Flatten a nested object to dotted keys, keeping only function-valued leaves.

signature
function flatten(obj: Record<string, any>, prefix?: string): Record<string, any>

Recurses into nested plain objects and collects only function leaves under their dotted key path (non-function, non-object values are dropped). Used internally to flatten nested action maps in the plugin system.

fn

createTags

Build a frozen tag map from a prefix and kebab-case names, keyed in PascalCase.

signature
function createTags<const T extends string | null, const U extends string[]>(
  prefix: T,
  ...list: U
): Tags<T, U>

Each name becomes a PascalCase key whose value is prefix.name (or just name when prefix is null). Used to declare namespaced error-tag constants like CodecErrors.

example
import { createTags } from '@ozaco/std/shared'

const Errors = createTags('std:codec', 'no-codec', 'no-match')
//=> { NoCodec: 'std:codec.no-codec', NoMatch: 'std:codec.no-match' }
fn

kebabToPascal

Convert a `kebab-case` string to `PascalCase`, at the value and type level.

signature
function kebabToPascal<S extends string>(s: S): KebabToPascal<S>
example
import { kebabToPascal } from '@ozaco/std/shared'

kebabToPascal('no-match') //=> 'NoMatch'
fn

serializeError

Render any thrown value into a stable, human-readable string.

signature
function serializeError(error: unknown): string

Strings pass through; Errors become name: message (with (code) appended when present); null/undefined stringify; other objects are JSON.stringifyd (falling back to Object.prototype.toString); everything else is String(...).

fn

validateSync

Validate a value against a Standard Schema synchronously, as a `Result`.

signature
function validateSync<Schema extends StandardSchemaV1>(
  schema: Schema,
  value: unknown,
): Result<
  StandardSchemaV1.InferOutput<Schema>,
  readonly StandardSchemaV1.Issue[]
>

Works with any Standard Schema library (zod, valibot, arktype, …). Returns succeed(output) on success or fail(issues) with the schema’s raw issues, so the caller keeps control of formatting. Async schemas cannot run here — a failure is returned advising validate (a Future) from @ozaco/std/effect.

example
import { validateSync } from '@ozaco/std/shared'
import { isSuccess } from '@ozaco/std/result'

const result = validateSync(userSchema, input)
if (isSuccess(result)) {
  result.value // typed schema output
}
fn

lazyPromise

Create a promise whose executor runs only when it is first awaited.

signature
function lazyPromise<T, E>(
  resolver: (resolve: (value: T) => void, reject: (error: E) => void) => void,
): Promise<T>

The resolver is deferred until the first then/catch/finally, then memoized, so an unawaited lazyPromise never does work. The returned object is Promise-shaped and interoperates with await.

fn

lazyPromiseWithResolvers

A lazy counterpart to `Promise.withResolvers`, recording a settle even before anyone awaits.

signature
function lazyPromiseWithResolvers<T>(): PromiseWithResolvers<T>

Returns { promise, resolve, reject } where promise is a lazyPromise. Calling resolve/reject before the promise is awaited records the outcome (first settle wins); it is replayed when the promise is eventually awaited.

example
import { lazyPromiseWithResolvers } from '@ozaco/std/shared'

const { promise, resolve } = lazyPromiseWithResolvers<number>()
resolve(42)         // settles before anyone awaits
await promise //=> 42
fn

hasFlag

Test whether a bit (or mask) is set within a numeric bitfield.

signature
function hasFlag(flags: number, flag: number): boolean
example
import { hasFlag } from '@ozaco/std/shared'

hasFlag(0b1010, 0b0010) //=> true
class

PriorityQueue

A binary-heap priority queue; lower priority numbers pop first, ties FIFO within a tier.

signature
class PriorityQueue<T> {
  push(priority: number, item: T): void
  pop(): T | undefined
}

Items sharing a priority are grouped into a tier and dequeued first-in-first-out; tiers are ordered by a min-heap so pop always returns an item from the lowest priority number present. push and pop are amortized O(log n) in the number of distinct priorities.

example
import { PriorityQueue } from '@ozaco/std/shared'

const q = new PriorityQueue<string>()
q.push(10, 'low')
q.push(1, 'high')
q.pop() //=> 'high' (lowest priority number wins)
03

Types

Type-level primitives and interop shapes.

type

AnyType

An intentional `any` escape hatch, isolated behind a named alias.

signature
type AnyType = any
type

EmptyType

The empty object type `{}` (any non-nullish value).

signature
type EmptyType = {}
type

AnyFunction

A unary function accepting and returning `any`.

signature
type AnyFunction = (value: any) => any
type

Primitive

The union of all JavaScript primitive types.

signature
type Primitive = null | undefined | string | number | boolean | symbol | bigint
type

LiteralUnion

A literal union that still autocompletes but accepts any value of the base type.

signature
type LiteralUnion<LiteralType, BaseType extends Primitive> =
  | LiteralType
  | (BaseType & Record<never, never>)
example
type Color = LiteralUnion<'red' | 'green', string>
// suggests 'red' | 'green' but accepts any string
type

Writable

Strip `readonly` from every top-level property of `T`.

signature
type Writable<T> = { -readonly [P in keyof T]: T[P] }
type

WriteableDeep

Recursively strip `readonly` throughout `T`.

signature
type WriteableDeep<T> = { -readonly [P in keyof T]: WriteableDeep<T[P]> }
type

KnownKeys

The explicitly declared keys of `T`, excluding index signatures.

signature
type KnownKeys<T> = keyof {
  [K in keyof T as string extends K
    ? never
    : number extends K
      ? never
      : symbol extends K
        ? never
        : K]: T[K]
}
type

ExplicitObject

Pick only the explicitly declared keys of `T` (drops index signatures).

signature
type ExplicitObject<T> = Pick<T, KnownKeys<T> & keyof T>
type

Tags

The shape produced by `createTags`: PascalCase keys mapping to `prefix.name` tags.

signature
type Tags<T extends string | null, U extends string[]> = {
  readonly [K in U[number] as KebabToPascal<K>]: T extends null ? K : `${T}.${K}`
}
type

KebabToPascal

Type-level `kebab-case` → `PascalCase` string transform.

signature
type KebabToPascal<S extends string> = S extends `${infer Head}-${infer Tail}`
  ? `${Capitalize<Head>}${KebabToPascal<Tail>}`
  : Capitalize<S>
type

IsPromise

Resolve to `true` when `T` is a `Promise`, else `false`.

signature
type IsPromise<T> = T extends Promise<any> ? true : false
type

IsPromiseStrict

Like `IsPromise`, but a bare `object`/`{}` resolves to `false`.

signature
type IsPromiseStrict<T> = object extends T
  ? false
  : T extends Promise<any>
    ? true
    : false
type

GuardValue

Extract the narrowed (or argument) type from a type-guard/predicate function.

signature
type GuardValue<fn> = fn extends (value: any) => value is infer b
  ? b
  : fn extends (value: infer a) => unknown
    ? a
    : never
type

PromiseWithResolvers

The return shape of `Promise.withResolvers` for `T`.

signature
type PromiseWithResolvers<T> = ReturnType<typeof Promise.withResolvers<T>>
iface

FlatEntry

A flattened leaf produced by `flattenEntries`: a dotted key and its value.

signature
interface FlatEntry {
  key: string
  value: unknown
}
type

MatchCase

One case registered on a `match` builder: a handler with a predicate or schema.

signature
type MatchCase = {
  handler: (value: any) => any
  predicate?: (value: any) => boolean
  schema?: StandardSchemaV1
}
iface

MatchBuilder

The fluent builder returned by `match`, tracking input, remaining and output types.

signature
interface MatchBuilder<Input, Remaining, Output> {
  with<S extends StandardSchemaV1, R>(
    schema: S,
    handler: (value: StandardSchemaV1.InferOutput<S>) => R,
  ): MatchBuilder<Input, Exclude<Remaining, StandardSchemaV1.InferInput<S>>, Output | R>
  when(predicate, handler): MatchBuilder<Input, Remaining, Output | ...>
  otherwise<R>(handler: (value: Remaining) => R): Output | R
  exhaustive: [Remaining] extends [never] ? () => Output : Result.Failure<Remaining>
  run(): Output | null
}

Each with/when narrows Remaining, and exhaustive is callable only once Remaining is never — otherwise its type surfaces the uncovered cases as a Result.Failure.

iface

Pipe

The overloaded call signature backing `pipe` (1 → 26 functions).

signature
interface Pipe {
  <A>(a: A): A
  <A, B>(a: A, ab: (a: Awaited<A>) => B): B
  <A, B, C>(a: A, ab: (a: Awaited<A>) => B, bc: (b: Awaited<B>) => C): C
  // …overloads up to 26 functions
}

Every step receives the Awaited result of the previous one, so promises are threaded transparently.

iface

StandardSchemaV1

The vendor-neutral Standard Schema interface used for validation interop.

signature
interface StandardSchemaV1<Input = unknown, Output = Input> {
  readonly '~standard': StandardSchemaV1.Props<Input, Output>
}

The StandardSchemaV1 namespace also exposes:

  • Props — the ~standard payload, including validate(value, options?).
  • ValidationResult / SuccessResult / FailureResult — the validate outcome.
  • Issue / PathSegment — the failure issue shape (message + path).
  • Options, Types, InferInput, InferOutput — options and inference helpers.

It extends StandardTypedV1, the shared base carrying version, vendor and inferred types.

iface

StandardTypedV1

The base of the Standard Schema family: version, vendor and inferred input/output types.

signature
interface StandardTypedV1<Input = unknown, Output = Input> {
  readonly '~standard': StandardTypedV1.Props<Input, Output>
}

The StandardTypedV1 namespace exposes Props (version, vendor, optional types), Types (input/output), and the InferInput/InferOutput helpers reused by the schema variants.

iface

StandardJSONSchemaV1

A Standard-typed schema that can additionally emit JSON Schema for its input/output.

signature
interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
  readonly '~standard': StandardJSONSchemaV1.Props<Input, Output>
}

Extends the Standard typed base with a jsonSchema converter (input/output) targeting a JSON Schema Target (draft-2020-12, draft-07, openapi-3.0, …). The namespace also exposes Props, Converter, Options, Types, InferInput and InferOutput.