Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Neumenon/glyph/llms.txt

Use this file to discover all available pages before exploring further.

Parsing

The GLYPH JavaScript SDK provides parsers to convert GLYPH format strings back to GValue objects.

Packed Parser

Parse packed format (positional encoding) back to GValue:
import { parsePacked, Schema } from 'glyph-js';

const schema = /* your schema */;

// Parse dense format
const value1 = parsePacked('Team@(^t:ARS Arsenal EPL)', schema);

// Parse with bitmap (sparse optionals)
const value2 = parsePacked(
  'Match@{bm=0b101}(^m:123 2025-12-19T20:00:00Z 2 1)',
  schema
);

// Access parsed values
console.log(value1.get('name')?.asStr()); // "Arsenal"
console.log(value2.get('homeScore')?.asInt()); // 2

Packed Format Syntax

The packed format uses positional encoding:
TypeName@(value1 value2 value3)
With optional bitmap for sparse fields:
TypeName@{bm=0b101}(required1 required2 optional1 optional3)
Bitmap encoding:
  • 0b prefix indicates binary
  • Bits are ordered LSB-first (right to left)
  • Each bit corresponds to an optional field
  • 1 = field is present, 0 = field is null

Nested Structs

Packed format supports nested structures:
const nested = parsePacked(
  'Match@(^m:123 Team@(^t:ARS Arsenal EPL) Team@(^t:LIV Liverpool EPL) 2 1)',
  schema
);

const homeTeam = nested.get('home')?.asStruct();
const homeName = homeTeam?.fields.find(f => f.key === 'name')?.value.asStr();

Tabular Parser

Parse tabular format (optimized for lists) back to GValue:
import { parseTabular, TabularParseResult } from 'glyph-js';

const input = `
@tab Team [t n l]
^t:ARS Arsenal EPL
^t:LIV Liverpool EPL
^t:MCI "Man City" EPL
@end
`;

const result: TabularParseResult = parseTabular(input, schema);

console.log(result.typeName); // "Team"
console.log(result.columns);  // ["t", "n", "l"]
console.log(result.rows.length); // 3

// Access row data
for (const row of result.rows) {
  const name = row.get('name')?.asStr();
  const league = row.get('league')?.asStr();
  console.log(`${name} - ${league}`);
}

Tabular Format Syntax

Tabular format is optimized for lists of structs:
@tab TypeName [col1 col2 col3]
value1 value2 value3
value4 value5 value6
@end
Column identifiers:
  • Field name: name
  • Wire key: n (if defined in schema)
  • Field ID: #2

Cell Formats

Tabular cells support all GLYPH value types:
const input = `
@tab Event [id time score active]
^e:1 2025-12-19T20:00:00Z 2 t
^e:2 2025-12-20T15:00:00Z ∅ f
^e:3 2025-12-21T18:30:00Z 1 t
@end
`;

const result = parseTabular(input, schema);
Supported formats:
  • Null: , null, nil, none
  • Boolean: t/true, f/false
  • Integer: 42, -17
  • Float: 3.14, 1.5e-3
  • String: bare tokens or "quoted strings"
  • Ref: ^prefix:value
  • Time: ISO 8601 format
  • List: [item1 item2 item3]
  • Map: {key1=val1 key2=val2}
  • Nested packed: Team@(^t:ARS Arsenal EPL)

Escaped Strings

Quoted strings support standard escape sequences:
const input = `
@tab Message [id text]
^m:1 "Hello\nWorld"
^m:2 "Quote: \"test\""
^m:3 "Tab:\tseparated"
@end
`;

const result = parseTabular(input, schema);
const text = result.rows[0].get('text')?.asStr();
// "Hello\nWorld" (actual newline)

Header Parser

Parse GLYPH metadata headers:
import { parseHeader, Header } from 'glyph-js';

// Parse header line
const header1 = parseHeader('@lyph v2.6 @schema#a3f5b2c1 @mode=packed');

if (header1) {
  console.log(header1.version);   // "v2.6"
  console.log(header1.schemaId);  // "a3f5b2c1"
  console.log(header1.mode);      // "packed"
}

// Parse with additional metadata
const header2 = parseHeader(
  '@glyph v2.6 @schema#abc123 @mode=tabular @keys=wire @target=^doc:main'
);

if (header2) {
  console.log(header2.keyMode);   // "wire"
  console.log(header2.target);    // { prefix: "doc", value: "main" }
}

Header Fields

version
string
required
GLYPH version (e.g., “v2.6”)
schemaId
string
Schema hash for version validation
mode
'auto' | 'struct' | 'packed' | 'tabular' | 'patch'
Encoding mode hint
keyMode
'wire' | 'name' | 'fid'
Field key encoding mode
target
RefID
Target document reference (for patches)

Parse Options

Configure parser behavior:
import { ParseOptions } from 'glyph-js';

const options: ParseOptions = {
  schema: schema,      // Schema for type validation
  tolerant: false      // Strict parsing (throw on errors)
};

const value = parsePacked(input, schema);
schema
Schema
Schema for type hints and validation (required for most operations)
tolerant
boolean
default:"false"
Enable tolerant mode (continue parsing on recoverable errors)

Error Handling

Parsers throw descriptive errors on invalid input:
try {
  const value = parsePacked('InvalidFormat', schema);
} catch (error) {
  console.error(error.message);
  // "unknown type: InvalidFormat" (at pos 13)
}

try {
  const result = parseTabular(badInput, schema);
} catch (error) {
  console.error(error.message);
  // "row has 2 values, expected 3"
}
Common parse errors:
  • Unknown type name
  • Type mismatch
  • Invalid syntax
  • Unexpected end of input
  • Row length mismatch (tabular)
  • Unknown column name (tabular)
  • Unterminated string
  • Invalid number format

Value Types

Scalar Parsing

The parser automatically detects value types:
// Null


// Boolean
t, f, true, false

// Integer
0, 42, -17

// Float
3.14, -0.5, 1.5e-3, 2e10

// String (bare)
Hello, simple_token, path/to/file

// String (quoted)
"Hello World", "Quote: \"test\""

// Ref
^user:123, ^t:ARS, ^"complex:ref:with:colons"

// Time
2025-12-19T20:00:00Z, 2025-01-15T14:30:00.123Z

Container Parsing

Parse nested containers:
// List
[1 2 3]
[^t:ARS ^t:LIV ^t:MCI]
["Alice" "Bob" "Charlie"]

// Map
{name=Arsenal league=EPL}
{id=^t:ARS founded=1886}

// Struct (v1 format)
Team{id=^t:ARS name=Arsenal league=EPL}

// Packed struct
Team@(^t:ARS Arsenal EPL)

// Sum
Result:Ok("success")
Option:Some(42)

Complete Example

Parse a complete GLYPH document with header:
import { 
  parseHeader, 
  parseTabular, 
  Schema,
  SchemaBuilder,
  t 
} from 'glyph-js';

// Define schema
const schema = new SchemaBuilder()
  .addPackedStruct('Player', 'v1')
    .field('id', t.id(), { fid: 1, wireKey: 'i' })
    .field('name', t.str(), { fid: 2, wireKey: 'n' })
    .field('team', t.str(), { fid: 3, wireKey: 't' })
    .field('goals', t.int(), { fid: 4, wireKey: 'g' })
  .build();

// Parse document
const document = `
@lyph v2.6 @schema#${schema.hash} @mode=tabular

@tab Player [i n t g]
^p:1 "Bukayo Saka" Arsenal 14
^p:2 "Mohamed Salah" Liverpool 18
^p:3 "Erling Haaland" "Man City" 27
@end
`;

const lines = document.trim().split('\n');

// Parse header
const header = parseHeader(lines[0]);
if (header?.schemaId !== schema.hash) {
  throw new Error('Schema mismatch');
}

// Parse tabular data
const tableStart = lines.findIndex(l => l.startsWith('@tab'));
const tableLines = lines.slice(tableStart).join('\n');
const result = parseTabular(tableLines, schema);

console.log(`Parsed ${result.rows.length} players`);

for (const player of result.rows) {
  const name = player.get('name')?.asStr();
  const team = player.get('team')?.asStr();
  const goals = player.get('goals')?.asInt();
  console.log(`${name} (${team}): ${goals} goals`);
}

Performance

The parser is optimized for streaming and handles large datasets efficiently:
  • Single-pass parsing: No backtracking
  • Zero-copy strings: Direct string slices where possible
  • Lazy evaluation: Values parsed on demand
  • Incremental tabular: Process rows as they arrive
// Parse large tabular dataset
const largeInput = generateLargeTabular(10000); // 10k rows
const start = performance.now();
const result = parseTabular(largeInput, schema);
const elapsed = performance.now() - start;

console.log(`Parsed ${result.rows.length} rows in ${elapsed.toFixed(2)}ms`);
// Typical: ~5-10ms for 10k rows

Next Steps

Core Types

Learn about GValue and Schema

Streaming

Incremental validation for real-time parsing

Build docs developers (and LLMs) love