Skip to content

najimovs/tbc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TBC

TBC is a minimal binary tile container designed for fast, range-based reads in both Browser and NodeJS.

It is optimized for delivery and random access, not for incremental writing.


Key ideas

  • Fixed-size payload per tile
  • O(1) offset calculation
  • HTTP Range friendly (CDN / browser cache friendly)
  • Same API for Browser and NodeJS
  • Stateless header-based access

Installation

npm install tbc

Data model

  • Tiles are addressed by ( x, y ) coordinates
  • Each tile has a fixed payload capacity
  • Actual data length is stored separately
  • Empty tiles occupy space but contain no data

API

Browser (HTTP Range-based, async)

  • readHeader( url, options? )Promise<Header>
  • inBounds( header, x, y )boolean
  • hasData( url, header, x, y, options? )Promise<boolean>
  • read( url, header, x, y, options? )Promise<Uint8Array | null>
  • readMany( url, header, tiles, options? )Promise<TileResult[]>

NodeJS (filesystem-based, sync) - Same signatures!

  • readHeader( filename )Header
  • inBounds( header, x, y )boolean
  • hasData( filename, header, x, y )boolean
  • read( filename, header, x, y )Buffer | null
  • readMany( filename, header, tiles )TileResult[]

Write operations (NodeJS only):

  • create( filename, payloadCapacity, minX, minY, maxX, maxY )void
  • write( filename, x, y, buffer )void
  • clearTile( filename, x, y )void
  • clearAll( filename )void
  • getWriter( filename )Writer

Examples

Browser (HTTP Range requests)

import * as TBC from "tbc"

// Read header from remote file
const header = await TBC.readHeader( "https://cdn.example.com/tiles.tbc" )

// Check if tile exists
if ( TBC.inBounds( header, 11, 10 ) ) {

  const hasData = await TBC.hasData( "https://cdn.example.com/tiles.tbc", header, 11, 10 )

  if ( hasData ) {

    const payload = await TBC.read( "https://cdn.example.com/tiles.tbc", header, 11, 10 )
    console.log( payload ) // Uint8Array
  }
}

// Read multiple tiles at once
const tiles = [ { x: 10, y: 10 }, { x: 11, y: 10 }, { x: 12, y: 10 } ]
const results = await TBC.readMany( "https://cdn.example.com/tiles.tbc", header, tiles )

for ( const tile of results ) {

  if ( tile.payload ) {

    console.log( tile.x, tile.y, tile.payload )
  }
}

NodeJS (filesystem access) - Same API as Browser!

import * as TBC from "tbc"

// Get header first (same as browser)
const header = TBC.readHeader( "example.tbc" )

// Same function signatures as browser (except sync)
if ( TBC.inBounds( header, 11, 10 ) ) {

  const hasData = TBC.hasData( "example.tbc", header, 11, 10 )

  if ( hasData ) {

    const payload = TBC.read( "example.tbc", header, 11, 10 )
    console.log( payload ) // Buffer (instead of Uint8Array)
  }
}

// Read multiple tiles (same as browser)
const tiles = [ { x: 10, y: 10 }, { x: 11, y: 10 }, { x: 12, y: 10 } ]
const results = TBC.readMany( "example.tbc", header, tiles )

for ( const tile of results ) {

  if ( tile.payload ) {

    console.log( tile.x, tile.y, tile.payload ) // Buffer
  }
}

Writing (NodeJS only)

Writing is supported in NodeJS only and is intended for build-time or backend usage.

One-shot writes

import * as TBC from "tbc"

// Create new TBC file
TBC.create(
  "example.tbc",
  16,     // payload capacity (bytes per tile)
  10, 10, // minX, minY
  12, 12  // maxX, maxY
)

// Write individual tiles
TBC.write( "example.tbc", 10, 10, Buffer.from( "Hello" ) )
TBC.write( "example.tbc", 11, 10, Buffer.from( "World" ) )

// Clear tiles
TBC.clearTile( "example.tbc", 12, 12 )
TBC.clearAll( "example.tbc" ) // clear all tiles

Streaming writer (recommended for large datasets)

// Create file first
TBC.create( "example.tbc", 16, 10, 10, 12, 12 )

// Get writer instance
const writer = TBC.getWriter( "example.tbc" )

writer.write( 10, 10, Buffer.from( "A" ) )
writer.write( 11, 10, Buffer.from( "B" ) )
writer.write( 12, 10, Buffer.from( "C" ) )

// Clear specific tile
writer.clear( 12, 12 )

// Always close when done
writer.close()

Notes

  • Fixed file size: Total file size determined at creation time and cannot be changed
  • Automatic padding: Payload padding to capacity is handled internally
  • Thread-safe reads: Reading operations are safe for concurrent access
  • CDN optimized: Designed for efficient HTTP Range requests and caching
  • Format-agnostic: TBC stores raw binary data without knowing the payload format (PNG, JSON, protobuf, etc.)
  • Zero-copy reads: Payload data returned as-is without parsing or transformation
  • O(1) performance: Tile access time is constant regardless of file size or tile position

About

Tiled Binary Container

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors