@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44
55## Project Overview
66
7- rayforce-wasm provides WebAssembly bindings for RayforceDB, a high-performance database. It compiles the native RayforceDB C runtime to WebAssembly using Emscripten, enabling RayforceDB to run in web browsers and Node.js environments .
7+ 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 .
88
99## Build Commands
1010
@@ -21,7 +21,7 @@ make app
2121# Development build from local ../rayforce sources
2222make dev
2323
24- # Build optimized WASM (ES6 module)
24+ # Build optimized WASM with SDK (ES6 module)
2525make wasm
2626
2727# Build standalone version with preloaded examples
@@ -47,7 +47,7 @@ make clean-all
4747- ** Makefile** - Main build orchestration
4848 - ` pull ` - Clones RayforceDB from GitHub to ` build/rayforce-c/ `
4949 - ` sync ` - Copies from local ` ../rayforce/ ` for development
50- - ` wasm ` - Compiles to ES6 WASM module
50+ - ` wasm ` - Compiles to ES6 WASM module + copies SDK files
5151 - ` wasm-standalone ` - Includes preloaded example files
5252 - ` wasm-debug ` - Debug build with assertions and safe heap
5353
@@ -59,75 +59,141 @@ rayforce-wasm/
5959├── CLAUDE.md # This file
6060├── README.md # Documentation
6161├── src/
62- │ └── rayforce/ # Copied C sources from RayforceDB
62+ │ ├── main.c # WASM entry point with all exports
63+ │ ├── rayforce.sdk.js # ES6 SDK module
64+ │ ├── rayforce.umd.js # UMD bundle for CDN
65+ │ └── index.js # Main entry point
6366├── build/
6467│ ├── rayforce-c/ # Cloned RayforceDB repo
6568│ ├── obj/ # Compiled object files
6669│ └── librayforce.a # Static library
6770├── dist/
6871│ ├── rayforce.js # ES6 WASM module loader
6972│ ├── rayforce.wasm # WebAssembly binary
70- │ └── rayforce-debug.js # Debug version
73+ │ ├── rayforce.sdk.js # SDK module
74+ │ ├── rayforce.umd.js # UMD bundle
75+ │ └── index.js # Entry point
7176└── examples/ # Usage examples
7277```
7378
74- ### Exported Functions
79+ ## SDK Usage
7580
76- The WASM module exports these C functions for JavaScript:
77-
78- - ` _main ` - Entry point
79- - ` _version_str ` - Get version string
80- - ` _null ` - Create null object
81- - ` _drop_obj ` - Free object memory
82- - ` _clone_obj ` - Clone an object
83- - ` _eval_str ` - Evaluate a RayforceDB expression (simple, no source tracking)
84- - ` _eval_cmd ` - Evaluate with source tracking for proper error locations (preferred)
85- - ` _get_cmd_counter ` - Get current command counter
86- - ` _reset_cmd_counter ` - Reset command counter
87- - ` _obj_fmt ` - Format object to string
88- - ` _strof_obj ` - Convert object to string representation
89-
90- #### Error Location Tracking
91-
92- The ` _eval_cmd ` function provides proper error location tracking similar to the native RayforceDB REPL:
81+ ### ES6 Module
9382
9483``` javascript
95- // Preferred: Evaluate with source tracking
96- const result = rayforce .ccall (' eval_cmd' , ' number' , [' string' , ' string' ], [code, ' myfile.ray' ]);
97-
98- // Errors will show source location like:
99- // ** [E002] error: object evaluation failed
100- // ╭──[1]──┬ myfile.ray:1..1 in function: @anonymous
101- // │ 1 │ (+ 1 undefined-var)
102- // │ ┴ ~~~~~~~~~~~~~ undefined symbol: 'undefined-var
103- ```
84+ import { createRayforceSDK , Types } from ' ./dist/rayforce.sdk.js' ;
10485
105- ### JavaScript Interface
86+ // Initialize WASM first
87+ const createRayforce = (await import (' ./dist/rayforce.js' )).default ;
88+ const wasm = await createRayforce ();
10689
107- The module is built with:
108- - ` MODULARIZE=1 ` - Factory function pattern
109- - ` EXPORT_ES6=1 ` - ES6 module syntax
110- - ` EXPORT_NAME="createRayforce" ` - Factory function name
111- - ` ALLOW_MEMORY_GROWTH=1 ` - Dynamic memory allocation
90+ // Create SDK instance
91+ const rf = createRayforceSDK (wasm);
11292
113- Usage:
114- ``` javascript
115- import createRayforce from ' ./rayforce.js ' ;
93+ // Evaluate expressions
94+ const result = rf . eval ( ' (+ 1 2 3) ' );
95+ console . log ( result . toJS ()); // 6
11696
117- const rayforce = await createRayforce ();
97+ // Zero-copy vector operations
98+ const vec = rf .vector (Types .I64 , [1 , 2 , 3 , 4 , 5 ]);
99+ const view = vec .typedArray ; // BigInt64Array - zero copy!
100+ view[0 ] = 100n ; // Mutate in place
118101
119- // Preferred: Use eval_cmd for proper error tracking
120- const result = rayforce .ccall (' eval_cmd' , ' number' , [' string' , ' string' ], [' (+ 1 2 3)' , ' repl' ]);
121- const formatted = rayforce .ccall (' strof_obj' , ' string' , [' number' ], [result]);
122- console .log (formatted); // 6
102+ // Create tables
103+ const table = rf .table ({
104+ id: [1 , 2 , 3 ],
105+ name: [' Alice' , ' Bob' , ' Carol' ],
106+ score: [95.5 , 87.3 , 92.1 ]
107+ });
123108
124- // Clean up
125- rayforce .ccall (' drop_obj' , null , [' number' ], [result]);
109+ console .log (table .toRows ());
110+ // [{ id: 1, name: 'Alice', score: 95.5 }, ...]
111+ ```
112+
113+ ### CDN/Script Tag
126114
127- // Simple evaluation (no source tracking)
128- const simple = rayforce .ccall (' eval_str' , ' number' , [' string' ], [' 1+2+3' ]);
115+ ``` html
116+ <script src =" https://cdn.../rayforce.umd.js" ></script >
117+ <script >
118+ Rayforce .init ({ wasmPath: ' ./rayforce.js' }).then (rf => {
119+ const result = rf .eval (' (sum (til 100))' );
120+ console .log (result .toJS ()); // 4950
121+ });
122+ </script >
129123```
130124
125+ ## Type System
126+
127+ ### Type Codes (matching Python bindings)
128+
129+ | Type | Code | TypedArray | Description |
130+ | ------| ------| ------------| -------------|
131+ | LIST | 0 | - | Mixed-type container |
132+ | B8 | 1 | Int8Array | Boolean |
133+ | U8 | 2 | Uint8Array | Unsigned byte |
134+ | I16 | 3 | Int16Array | 16-bit integer |
135+ | I32 | 4 | Int32Array | 32-bit integer |
136+ | I64 | 5 | BigInt64Array | 64-bit integer |
137+ | SYMBOL | 6 | BigInt64Array | Interned string |
138+ | DATE | 7 | Int32Array | Days since 2000-01-01 |
139+ | TIME | 8 | Int32Array | Milliseconds since midnight |
140+ | TIMESTAMP | 9 | BigInt64Array | Nanoseconds since 2000-01-01 |
141+ | F64 | 10 | Float64Array | 64-bit float |
142+ | GUID | 11 | - | 128-bit UUID |
143+ | C8 | 12 | Uint8Array | Character/String |
144+ | TABLE | 98 | - | Table |
145+ | DICT | 99 | - | Dictionary |
146+
147+ ### Atoms vs Vectors
148+
149+ - ** Atoms (scalars)** : Have negative type codes (e.g., -5 for I64 scalar)
150+ - ** Vectors** : Have positive type codes (e.g., 5 for I64 vector)
151+
152+ ## Exported WASM Functions
153+
154+ ### Core
155+ - ` eval_cmd(code, sourceName) ` - Evaluate with source tracking
156+ - ` eval_str(code) ` - Simple evaluation
157+ - ` strof_obj(ptr) ` - Format object to string
158+ - ` drop_obj(ptr) ` - Free object memory
159+ - ` clone_obj(ptr) ` - Clone object
160+
161+ ### Type Introspection
162+ - ` get_obj_type(ptr) ` - Get type code
163+ - ` get_obj_len(ptr) ` - Get length
164+ - ` is_obj_atom(ptr) ` - Check if scalar
165+ - ` is_obj_vector(ptr) ` - Check if vector
166+ - ` is_obj_null(ptr) ` - Check if null
167+ - ` is_obj_error(ptr) ` - Check if error
168+
169+ ### Memory Access (Zero-Copy)
170+ - ` get_data_ptr(ptr) ` - Get pointer to data array
171+ - ` get_element_size(type) ` - Get byte size of element
172+ - ` get_data_byte_size(ptr) ` - Get total data size
173+
174+ ### Constructors
175+ - ` init_b8 ` , ` init_u8 ` , ` init_c8 ` , ` init_i16 ` , ` init_i32 ` , ` init_i64 ` , ` init_f64 `
176+ - ` init_date ` , ` init_time ` , ` init_timestamp `
177+ - ` init_symbol_str ` , ` init_string_str `
178+ - ` init_vector ` , ` init_list ` , ` init_dict ` , ` init_table `
179+
180+ ### Readers
181+ - ` read_b8 ` , ` read_u8 ` , ` read_c8 ` , ` read_i16 ` , ` read_i32 ` , ` read_i64 ` , ` read_f64 `
182+ - ` read_date ` , ` read_time ` , ` read_timestamp `
183+ - ` read_symbol_id ` , ` symbol_to_str `
184+
185+ ### Vector Operations
186+ - ` vec_at_idx ` , ` vec_set_idx ` , ` vec_push ` , ` vec_insert ` , ` vec_resize `
187+ - ` fill_i64_vec ` , ` fill_i32_vec ` , ` fill_f64_vec `
188+
189+ ### Container Operations
190+ - ` dict_keys ` , ` dict_vals ` , ` dict_get `
191+ - ` table_keys ` , ` table_vals ` , ` table_col ` , ` table_row ` , ` table_count `
192+
193+ ### Query Operations
194+ - ` query_select ` , ` query_update `
195+ - ` table_insert ` , ` table_upsert `
196+
131197## Build Flags
132198
133199### Release Build
@@ -149,7 +215,7 @@ const simple = rayforce.ccall('eval_str', 'number', ['string'], ['1+2+3']);
149215
1502161 . Make changes in ` ../rayforce/ ` (main RayforceDB repo)
1512172 . Run ` make dev ` to sync and build
152- 3 . Test with ` make serve ` and open browser
218+ 3 . Test with ` make serve ` and open browser to examples/
1532194 . For production: ` make app ` builds from fresh GitHub clone
154220
155221## Platform Notes
@@ -158,4 +224,3 @@ const simple = rayforce.ccall('eval_str', 'number', ['string'], ['1+2+3']);
158224- ` emcc ` and ` emar ` must be available
159225- Built WASM requires CORS headers for cross-origin usage
160226- Use ` make serve ` for local testing (handles CORS)
161-
0 commit comments