WASM Procedures: Language SDKs
Part of: WASM Procedures User Guide
| Language | Published SDK |
|---|---|
| Go (TinyGo) | github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm |
| Rust | None. The heliosdb-sdk crate named in older pages does not exist on crates.io. |
| JavaScript / AssemblyScript | None. @heliosdb/wasm-sdk does not exist on npm. |
| Python | None. heliosdb-wasm-sdk does not exist on PyPI. |
Go SDK
The Go SDK is the Go module
github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm
(Apache-2.0, no dependencies). Procedures are compiled with
TinyGo 0.34 or later.
Setup
go mod init my-procedurego get github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm@latest| Package | Purpose |
|---|---|
github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm/heliosdb | Host functions: SQL statements, transactions, key-value writes, logging |
github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm/heliosdbtest | In-memory fake host for go test |
How Go procedures run
- A procedure is an exported function whose parameters and results are WASM
scalars (
int32,int64,float32,float64). Return a status code or a number, and write richer results to a table. - Export it with TinyGo’s
//exportdirective. The host calls exported functions directly and does not run_startor_initialize. - Build with
-target=wasm-unknown -gc=conservative. The host links only its ownenvfunctions and no WASI, so-target=wasip1modules (and modules from the standard Go toolchain) fail to instantiate. - Keep package-level state static (constants and literals), and avoid
init()functions with side effects. - SQL has no bind parameters at the ABI level, so build literals with
heliosdb.Quote,heliosdb.QuoteIdentandheliosdb.Int64. - Procedures run statements but cannot read result rows. The host functions
that return rows write them to a host-chosen address in the module’s
memory, so the SDK does not expose them. Use
INSERT ... SELECTorUPDATE ... FROMto work with data inside SQL.
Basic Procedure
package main
import "github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm/heliosdb"
//export apply_discountfunc applyDiscount(priceCents int64, percent int32) int64 { if percent <= 0 { return priceCents } if percent >= 100 { return 0 } return priceCents - priceCents*int64(percent)/100}
//export deactivate_stale_usersfunc deactivateStaleUsers(days int32) int64 { n, err := heliosdb.Exec("UPDATE users SET active = false WHERE last_seen < NOW() - INTERVAL '" + heliosdb.Int64(int64(days)) + " days'") if err != nil { heliosdb.LogError("deactivate_stale_users: " + err.Error()) return -1 } return n // rows affected}
func main() {}Transactions and Error Handling
package main
import "github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm/heliosdb"
//export record_orderfunc recordOrder(customerID, amountCents int64) int32 { if amountCents <= 0 { heliosdb.LogWarn("record_order: amount must be positive") return -1 }
// WithTx commits when the function returns nil and rolls back otherwise. err := heliosdb.WithTx(func(heliosdb.Tx) error { if _, err := heliosdb.Exec("INSERT INTO orders (customer_id, amount_cents) VALUES (" + heliosdb.Int64(customerID) + ", " + heliosdb.Int64(amountCents) + ")"); err != nil { return err } _, err := heliosdb.Exec("UPDATE customers SET order_count = order_count + 1 WHERE id = " + heliosdb.Int64(customerID)) return err }) if err != nil { // *heliosdb.HostError carries the host's return code. heliosdb.LogError("record_order: " + err.Error()) return -1 } return 0}
func main() {}heliosdb.StorageWrite(key, value) writes to the host key-value store.
Testing
Procedures are ordinary Go functions, so they can be unit-tested natively with the fake host:
package main
import ( "testing"
"github.com/HeliosDatabase/HeliosDB-SDKs/sdks/go/wasm/heliosdbtest")
func TestRecordOrder(t *testing.T) { fake := heliosdbtest.Install(t) if rc := recordOrder(7, 1999); rc != 0 { t.Fatalf("rc = %d", rc) } if len(fake.SQL) != 2 { t.Fatalf("sql = %v", fake.SQL) }}
func TestRecordOrderRollsBack(t *testing.T) { fake := heliosdbtest.Install(t) fake.FailSQL("UPDATE") if rc := recordOrder(7, 1999); rc != -1 { t.Fatalf("rc = %d", rc) } if fake.Tx[len(fake.Tx)-1].Op != "rollback" { t.Fatal("expected rollback") }}Build:
# Run unit tests (native, no WASM runtime needed)go test ./...
# Build the procedure moduletinygo build -target=wasm-unknown -gc=conservative -opt=z -no-debug -o procedure.wasm .The SDK repository also has an ABI conformance suite. It builds an example
procedure with TinyGo, checks every import against the host’s env
functions, and runs the procedure the way the host does.
Other languages
There are no published Rust, JavaScript/AssemblyScript or Python SDKs. A
module written in any language that compiles to a core WebAssembly module
(with no WASI imports) can import the host functions directly from the env
module. See Host Functions for their
signatures.
Navigation:
- Previous: Quick Start
- Next: Host Functions
- Index: WASM Procedures User Guide