function computedRef
computedRef<TArgs extends readonly RefValue<unknown>[], TDecoded>(
refs: [...TArgs],
computation: (...args: [...UnwrapRefTuple<TArgs>]) => TDecoded
): RefValue<TDecoded>

Creates a computed reference that depends on multiple other references.

Computed references allow you to create dynamic values that are calculated from other references during encoding/decoding. This is useful for scenarios where a value depends on multiple other values, such as calculating array lengths, offsets, or derived values.

Examples

Example 1

import { assertEquals } from "@std/assert";
import { computedRef, ref, struct, u16le, u8, array } from "@hertzg/binstruct";

// Create the base references
const width = u16le();
const height = u16le();

// Create a computed reference for total pixels
const totalPixels = computedRef(
  [ref(width), ref(height)],
  (w, h) => w * h
);

// Define a structure using the computed reference
const coder = struct({
  width: width,
  height: height,
  pixels: array(u8(), totalPixels),
});

// Test data
const data = {
  width: 3,
  height: 2,
  pixels: [255, 128, 64, 0, 255, 128],
};

// Encode and decode
const buffer = new Uint8Array(1000);
const bytesWritten = coder.encode(data, buffer);
const [decoded, bytesRead] = coder.decode(buffer);

// Verify the computed value
assertEquals(decoded.width, 3);
assertEquals(decoded.height, 2);
assertEquals(decoded.pixels.length, 6); // 3 * 2
assertEquals(decoded.pixels, data.pixels);
assertEquals(bytesWritten, bytesRead);

Example 2

import { assertEquals } from "@std/assert";
import { computedRef, ref, struct, u16le, u32le, array } from "@hertzg/binstruct";

// Create references for different counts
const headerCount = u16le();
const dataCount = u16le();

// Create a computed reference for total count
const totalCount = computedRef(
  [ref(headerCount), ref(dataCount)],
  (header, data) => header + data
);

// Define a structure with the computed reference
const coder = struct({
  headerCount: headerCount,
  dataCount: dataCount,
  headers: array(u32le(), ref(headerCount)),
  dataItems: array(u32le(), ref(dataCount)),
});

// Test data
const data = {
  headerCount: 2,
  dataCount: 3,
  headers: [100, 200],
  dataItems: [300, 400, 500],
};

// Encode and decode
const buffer = new Uint8Array(1000);
const bytesWritten = coder.encode(data, buffer);
const [decoded, bytesRead] = coder.decode(buffer);

// Verify the computed total
assertEquals(decoded.headerCount, 2);
assertEquals(decoded.dataCount, 3);
assertEquals(decoded.headers.length, 2);
assertEquals(decoded.dataItems.length, 3);
assertEquals(bytesWritten, bytesRead);

Type Parameters

TArgs extends readonly RefValue<unknown>[]
TDecoded

Parameters

refs: [...TArgs]

An array of references that the computation depends on

computation: (...args: [...UnwrapRefTuple<TArgs>]) => TDecoded

A function that computes the final value from the resolved references

Return Type

A new reference that computes its value from the input references

Usage

import { computedRef } from "mod.ts";