This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
rayforce-wasm provides WebAssembly bindings and a full JavaScript SDK for RayforceDB, a high-performance columnar database. The SDK offers zero-copy TypedArray views over native Rayforce vectors for maximum performance.
# Prerequisites: Install Emscripten SDK 6.0.6
# https://emscripten.org/docs/getting_started/downloads.html
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install 6.0.6 && ./emsdk activate 6.0.6
source emsdk_env.sh
# Full build from GitHub
make app
# Development build from local ../rayforce sources
make dev
# Build optimized WASM with SDK (ES6 module)
make wasm
# Build standalone version with preloaded examples
make wasm-standalone
# Build debug version with assertions
make wasm-debug
# Start HTTP server for testing
make serve
# Clean build artifacts
make clean
# Clean all including pulled sources
make clean-all- Makefile - Main build orchestration
pull- Clones the pinned RayforceDB release tosrc/rayforce-repo/dev- Builds against local../rayforce/sourceswasm- Compiles to ES6 WASM module + copies SDK fileswasm-standalone- Includes preloaded example fileswasm-debug- Debug build with assertions and safe heap
rayforce-wasm/
├── Makefile # Build system
├── CLAUDE.md # This file
├── README.md # Documentation
├── src/
│ ├── main.c # WASM entry point with all exports
│ ├── rayforce.sdk.js # ES6 SDK module
│ ├── rayforce.umd.js # Legacy-named browser ESM bootstrap
│ ├── index.js # Main entry point
│ └── index.d.ts # Entry-point TypeScript definitions
├── build/
│ ├── obj/ # Compiled object files
│ └── librayforce.a # Static library
├── dist/
│ ├── rayforce.js # ES6 WASM module loader
│ ├── rayforce.wasm # WebAssembly binary
│ ├── rayforce.sdk.js # SDK module
│ ├── rayforce.umd.js # Browser ESM bootstrap
│ ├── index.js # Entry point
│ └── index.d.ts # Entry-point TypeScript definitions
└── examples/ # Usage examples
import { createRayforceSDK, Types } from './dist/rayforce.sdk.js';
// Initialize WASM first
const createRayforce = (await import('./dist/rayforce.js')).default;
const wasm = await createRayforce();
// Create SDK instance
const rf = createRayforceSDK(wasm);
// Evaluate expressions
const result = rf.eval('(+ (+ 1 2) 3)');
console.log(result.toJS()); // 6
// Zero-copy vector operations
const vec = rf.vector(Types.I64, [1, 2, 3, 4, 5]);
const view = vec.typedArray; // BigInt64Array - zero copy!
view[0] = 100n; // Mutate in place
// Create tables
const table = rf.table({
id: [1, 2, 3],
name: ['Alice', 'Bob', 'Carol'],
score: [95.5, 87.3, 92.1]
});
console.log(table.toRows());
// [{ id: 1, name: 'Alice', score: 95.5 }, ...]<script type="module">
import { init } from 'https://cdn.jsdelivr.net/npm/rayforce-wasm@0.2.1/dist/index.js';
const rf = await init();
const result = rf.eval('(sum (til 100))');
console.log(result.toJS()); // 4950
</script>| Type | Code | TypedArray | Description |
|---|---|---|---|
| LIST | 0 | - | Mixed-type container |
| B8 | 1 | Int8Array | Boolean |
| U8 | 2 | Uint8Array | Unsigned byte |
| I16 | 3 | Int16Array | 16-bit integer |
| I32 | 4 | Int32Array | 32-bit integer |
| I64 | 5 | BigInt64Array | 64-bit integer |
| F32 | 6 | Float32Array | 32-bit float |
| F64 | 7 | Float64Array | 64-bit float |
| DATE | 8 | Int32Array | Days since 2000-01-01 |
| TIME | 9 | Int32Array | Milliseconds since midnight |
| TIMESTAMP | 10 | BigInt64Array | Nanoseconds since 2000-01-01 |
| GUID | 11 | - | 128-bit UUID |
| SYM | 12 | BigInt64Array | Interned dictionary-encoded string column |
| STR | 13 | - | Variable-length string (atom or column) |
| TABLE | 98 | - | Table |
| DICT | 99 | - | Dictionary |
| LAMBDA | 100 | - | Function |
| NULL | 126 | - | Null |
| ERR | 127 | - | Error |
Types.SYMBOL and Types.C8 are kept as deprecated aliases mapping to
Types.SYM (12); update consumers before the next major release.
- Atoms (scalars): Have negative type codes (e.g., -5 for I64 scalar)
- Vectors: Have positive type codes (e.g., 5 for I64 vector)
eval_cmd(code, sourceName)- Evaluate with source-tracked nfostrof_obj(ptr)- Format object to string (mode=full)ray_release(ptr)- Decrement refcount (no-op for arena/error blocks)ray_retain(ptr)- Increment refcountversion_str()- Engine version (e.g. "2.1.0")
get_obj_type(ptr)- Get type codeget_obj_len(ptr)- Get lengthis_obj_atom(ptr)- Check if scalaris_obj_vector(ptr)- Check if vectoris_obj_null(ptr)- Check if nullis_obj_error(ptr)- Check if error
get_data_ptr(ptr)- Get pointer to data arrayget_element_size(type)- Get byte size of elementget_data_byte_size(ptr)- Get total data size
init_b8,init_u8,init_i16,init_i32,init_i64,init_f32,init_f64init_date,init_time,init_timestampinit_symbol_str,init_string_strinit_vector,init_list,init_dict,init_table
read_b8,read_u8,read_i16,read_i32,read_i64,read_f32,read_f64read_date,read_time,read_timestampread_symbol_id,symbol_to_strstr_atom_ptr,str_atom_len,str_vec_get(RAY_STR helpers)get_error_code,get_error_message,get_error_trace,get_error_info
vec_at_idx,vec_set_idx,vec_push,vec_insertfill_i64_vec,fill_i32_vec,fill_f64_vec
dict_keys,dict_vals,dict_gettable_keys,table_vals,table_col,table_row,table_count
query_select,query_updatetable_insert,table_upsert
-O3- Full optimization-msimd128- WASM SIMD support-fassociative-math- Math optimizations-ftree-vectorize- Auto-vectorization-DSYS_MALLOC- Use system malloc (required for WASM)
-g- Debug symbols-O0- No optimization-DDEBUG- Debug modeASSERTIONS=2- Runtime assertionsSAFE_HEAP=1- Heap safety checksSTACK_OVERFLOW_CHECK=2- Stack checks
- Make changes in
../rayforce/(main RayforceDB repo) - Run
make devto sync and build - Test with
make serveand open browser to examples/ - For production:
make appbuilds from fresh GitHub clone
- Requires Emscripten SDK 6.0.6 (emsdk) in PATH
emccandemarmust be available- Built WASM requires CORS headers for cross-origin usage
- Use
make servefor local testing (handles CORS)