Skip to content

v0.39.0 - FlameFrame: schema-validated DataFrame (2026-03-23)

What Changed?

This release introduces FlameFrame<T>, a new class that combines DataFrame and the FlameWright type validation system. Every factory method and transformation re-validates the data against a schema and returns a FlameFrameResult<T> containing both the validated frame and any errors. FlameFrame is now exported from both the v2 and top-level entry points.


What's New

Main Feature: FlameFrame

What it does: FlameFrame<T> wraps a DataFrame with a FlameRecord<T> schema. Each cell is validated on construction and after every transformation. Errors are collected in FlameFrameErrors and can be exported as a DataFrame for logging to a spreadsheet.

How to use it:

TypeScript
import { FlameFrame, FlameGuards } from "gaslamp";

const schema = {
  name: FlameGuards.isString,
  age:  FlameGuards.isNumber,
};

// Create from a GAS Range
const { frame, errors } = FlameFrame.from(
  DataFrame.fromRange(sheet.getRange("A1:B10")),
  schema,
);

if (errors.hasErrors) {
  // Write validation errors back to the sheet for review
  Logger.log(errors.toDataFrame().toString());
} else {
  const adults = frame.filter((row) => (row.get("age") as number) >= 18);
  Logger.log(adults.frame.toString());
}

Strict mode (throw on first error):

TypeScript
try {
  const { frame } = FlameFrame.from(df, schema, { strict: true });
} catch (e) {
  Logger.log(e.message);
  // "FlameFrame validation failed | row 2 | field "name" | got number"
}

Added

  • FlameFrame<T> — schema-validated immutable DataFrame wrapper
  • FlameFrameErrors — container for per-row validation errors with toDataFrame() output
  • ValidationError type — { rowIndex, field, actual, expected }
  • FlameFrameOptions type — { strict?: boolean }
  • FlameFrameResult<T> type — { frame, errors } returned by all factory and transformation methods
  • Exported from src/v2/index.ts and src/index.ts

Changed

  • filter skips re-validation (rows are only removed, values unchanged)
  • withColumn always re-validates to ensure consistency when new data is introduced

Fixed

  • ValidationError.expected is typed as string (was incorrectly Cell)
  • strict option is preserved as an instance field and propagated through all transformations

Is It Safe to Upgrade?

  • Breaking Changes: No
  • Backward Compatible: Yes

FlameFrame is a new addition. All existing DataFrame, LazyDataFrame, and GroupedDataFrame APIs are unchanged.


Release Details

  • Date: 2026-03-23
  • Version: v0.39.0
  • gaslamp: clasp version 85
  • pilotlamp: clasp version 42
  • Files Changed: 3 (src/v2/flameframe.ts, src/v2/index.ts, src/index.ts)
  • Commits:
  • 660b021 docs(v2/flameframe): add comment explaining why withColumn always re-validates
  • 6821e9b perf(v2/flameframe): skip re-validation in filter using _skip helper
  • 97df047 feat: export FlameFrame and FlameFrameErrors from top-level entry point
  • 9409afa feat(v2): export FlameFrame and FlameFrameErrors from v2 entry point
  • 3ede4bd docs(v2/flameframe): improve docstrings with descriptions and examples for all public API
  • efdd694 fix(v2/flameframe): change ValidationError.expected type from Cell to string
  • af78271 fix(v2/flameframe): persist strict option as instance field to propagate through transformations
  • 8336d85 refactor(v2/flameframe): delegate fromRows/fromColumns/fromArrays to from
  • fd8d065 fix(v2/flameframe): change ValidationError.expected to Cell and use "unknown" as fallback
  • 6624bfd feat(v2/flameframe): add FlameFrame and FlameFrameErrors with schema-validated DataFrame wrapper

Known Issues

  • ValidationError.expected is always "unknown" because Flame<T> guards do not expose their type name at runtime.

Next Steps

  • Add tests for FlameFrame (__tests__/v2/flameframe.test.ts)
  • Consider adding fromRange / fromSheet factory methods for direct GAS integration