Skip to content

Releases

v0.20.2

Choose a tag to compare

@github-actions github-actions released this 07 Nov 09:07

Full Changelog: v0.20.1...v0.20.2

v0.20.1

Choose a tag to compare

@mariuz mariuz released this 06 Nov 05:21

Patch release. Fixes a CompressionStream backpressure deadlock that hung encrypted/compressed replication journal segments (encodeEncryptedJournalSegment, exportJournalArchive) in browsers; fixes the Replication Simulator promoted badge and binary header dump; corrects the simulator E2E suite. See packages/firebird-wasm/CHANGELOG.md.

v0.20.0

Choose a tag to compare

@mariuz mariuz released this 06 Nov 05:08

Replication release: journal-based logical replication (slots, HLC + CRDTs, filters, HTTP/WS/BroadcastChannel transports), promoteReplica, time travel (asOfLsn/rewindToLsn), AES-256-GCM + Gzip segments, multi-node mesh/hub coordinator, dead-letter queue (FB_REPL_DLQ$), PII masking (transformRow), PITR archives, replication tab, Replication Simulator v2 + Playwright E2E. See packages/firebird-wasm/CHANGELOG.md and docs/replication.md.

v0.16.0

Choose a tag to compare

@mariuz mariuz released this 02 Nov 13:59

Added

  • JavaScript User-Defined Functions & Procedures (db.registerFunction() & db.registerProcedure()).
    • Added db.registerFunction(name, options, fn) and db.registerProcedure(name, options, fn) on both FirebirdBrowser and FirebirdLite, plus a static C++ "JS" IExternalEngine UDR plugin (JsExternalEngine in fb_wasm_api.cpp) and a transparent PSQL catalog stub + JS expression bridge (UdrManager) supporting scalar functions in SELECT, WHERE, and COMPUTED BY columns as well as selectable table-valued procedures (SELECT * FROM proc(...)) and EXECUTE PROCEDURE.
  • Client-side vector similarity & hybrid RAG search (firebird-wasm/vector).
    • Added the firebird-wasm/vector subpath export with encodeVector, decodeVector, formatVectorText, vectorColumnType, cosineDistance, cosineSimilarity, l2Distance, squaredL2Distance, dotProduct, innerProductDistance, vectorNorm, normalizeVector, registerVectorFunctions(db), and hybrid SQL + KNN vectorSearch(db, options).
  • Direct page-level OPFS VFS (OPFSVFS & SyncAccessHandle PIO).
    • Added OPFSVFS (firebird-wasm/browser) mounting an Emscripten filesystem node backed directly by FileSystemSyncAccessHandle.read(buf, { at }) and .write(buf, { at }) for zero-MEMFS-copy page-level I/O (readPage, writePage, importDatabase, exportDatabase).
  • WebCrypto AES-256-GCM page encryption at rest (encryptionKey & encryptionPassword).
    • Added transparent page-level AES-256-GCM encryption at rest (encryptPage, decryptPage, deriveEncryptionKey, generateEncryptionKey, exportEncryptionKey, importEncryptionKey) across IndexedDBVFS, OPFSVFS, and FirebirdBrowserOptions (encryptionKey, encryptionPassword, encryptionSalt) with per-page IVs and AAD binding page numbers to prevent page-swapping attacks.
  • Point-in-time Copy-on-Write snapshots & database branching (db.snapshot(), db.restoreSnapshot(), db.branch()).
    • Added content-addressable FNV-1a Copy-on-Write page snapshots (SnapshotStore, db.snapshot(), db.restoreSnapshot(), db.listSnapshots(), db.deleteSnapshot(), and db.branch()) on FirebirdBrowser and FirebirdLite for instant O(changed pages) rollback and isolated database branches.
  • Cross-tab reactive live queries (BroadcastChannel invalidation).
    • Extended createLiveQuery (firebird-wasm/browser, firebird-wasm/react, firebird-wasm/vue, firebird-wasm/svelte, firebird-wasm/solid) with automatic cross-tab BroadcastChannel table invalidation (crossTab, channelName, notifyTablesChanged) so writes in one browser tab immediately refresh subscribed queries in sibling tabs.
  • Multi-table transactional Electric shape sync (syncShapes).
    • Added syncShapes(db, options) (firebird-wasm/electric) coordinating multiple Electric shapes with topological foreign-key ordering (resolveShapeTableOrder) and shared atomic batch transactions across parent and child tables.
  • Pushed-down WHERE join filtering & batched delta queries in firebird-wasm/electric-server.
    • createShapeServer now pushes where predicates into a single ELECTRIC_CHANGES LEFT JOIN <table> SQL query during incremental delta syncs, batches primary-key lookups (IN (...)), and exposes server.applyWrite() and replica=full old-value diffs.
  • Query profiler & MON$ telemetry (db.onQuery(), db.monitorStats(), and <firebird-repl> Profiler tab).
    • Added QueryProfiler, db.onQuery(listener), db.monitorStats(), db.resetMonitorStats() (combining MON$IO_STATS, MON$MEMORY_USAGE, MON$TRANSACTIONS, MON$STATEMENTS, and prepare-cache hit rates), and an interactive Profiler tab in <firebird-repl>.
  • Svelte 5 & SolidJS reactive adapters (firebird-wasm/svelte & firebird-wasm/solid).
    • Added firebird-wasm/svelte (createFirebirdStore, createLiveQueryStore, createQueryStore) and firebird-wasm/solid (createFirebirdResource, createLiveQuerySignal).

Changed

  • Migrated the unit and WASM console integration test suite from Jest (ts-jest) to Vitest.

v0.14.0 — Zero-copy FBR\x01 binary result transfer across transports & Firebird 5.0 LTS / 6.0 WASM build matrix

Choose a tag to compare

@mariuz mariuz released this 27 Oct 18:08

This release wires zero-copy FBR\x01 binary result buffer transfer across DirectTransport, WorkerTransport, SharedEngineTransport, and serveEngine, and adds Firebird 5.0 LTS (v5.0-release, ODS 13.1) & Firebird 6.0 (master, ODS 14.0) WASM build support.


Added

  • Zero-copy FBR\x01 binary result buffer transfer across WorkerTransport and SharedEngineTransport.
    • DirectTransport, WorkerTransport, SharedEngineTransport, and serveEngine now execute query and cursor_fetch over the packed "FBR\x01" binary wire format (_fb_query_binary and _fb_cursor_fetch_binary), copying a single contiguous ArrayBuffer slice from HEAPU8, transferring its ownership zero-copy across Worker.postMessage / MessagePort.postMessage via the transfer list, and decoding on the consumer side with decodeBinaryResultSet + peekBinaryResultShapeId + lazy shape_columns hydration.
    • Added patchBinaryResultSetColumns(buffer, columns) in firebird-wasm/browser (binary-result.ts) to inline column descriptors into a shape-ID-addressed "FBR\x01" buffer when needed.
  • Firebird 5.0 LTS (v5.0-release, ODS 13.1) & Firebird 6.0 (master, ODS 14.0) WASM build support.
    • wasm/build.sh now accepts --firebird-ref <ref> (and FB_GIT_REF, with shorthands 5 / 5.0 / v5.0 → v5.0-release and 6 / 6.0 / v6.0 → master), detects Firebird's major version, selects version-specific patches under wasm/patches/v5.0/ when targeting Firebird 5.0, and automatically invalidates native bootstrap and Emscripten build caches when the Firebird HEAD commit changes.
    • wasm/CMakeLists.txt adapts source lists across Firebird 5.0 and 6.0 (conditional Schema.epp / Update.cpp, StatementMetadata.cpp, Savepoint.cpp, CharSetContainer.cpp, Monitoring.cpp, and LocalStatus.h shim for 5.0).
    • Added _fb_wasm_purge_cached_statements in fb_wasm_api.cpp so idle unpinned cached statements are released before DDL / database drop operations.
    • Added a build-wasm-v5 job to .github/workflows/build-wasm.yml that builds and tests the Firebird 5.0 LTS WASM engine (firebird-wasm-v5.0 artifact) alongside Firebird 6.0.

v0.13.0 — Binary Result Protocol, Segmented BLOB Streaming, Schema Introspection & Migrations, Sweep & Durable Write Queue

Choose a tag to compare

@mariuz mariuz released this 27 Oct 03:29

Added in v0.13.0

  • Prepared statement cursor streaming (stmt.queryStream(params?, options?)): PreparedStatement (db.prepare(sql) and tx.prepare(sql)) on both FirebirdBrowser and FirebirdLite now exposes stmt.queryStream(params?, options?) returning an AsyncIterableIterator<T> that streams rows in configurable batches (batchSize, rowMode) without re-preparing the SQL statement.
  • Schema introspection & transactional migrations (db.introspect() and migrate()): Added db.introspect(), db.migrate(migrations, options?), migrate(db, migrations, options?), and getAppliedMigrations(db, options?) across FirebirdBrowser and FirebirdLite, querying Firebird system catalogs into typed DatabaseSchema metadata (tables, views, sequences) and running ordered transactional SQL/callback migrations tracked in FB_MIGRATIONS$.
  • Database maintenance & garbage-collection sweep (db.sweep() and <firebird-repl> Sweep button): Exposes isc_dpb_sweep = isc_dpb_records via _fb_sweep in the WASM C bridge and db.sweep() on both FirebirdBrowser and FirebirdLite (plus a Sweep button in <firebird-repl>), returning a SweepResult with before/after DatabaseInfo snapshots, oitAdvancedBy, and reclaimedPages.
  • Durable offline write queue for Electric sync (createWriteQueue persistence & pre-image rollback): createWriteQueue in firebird-wasm/electric now persists pending mutations along with captured BEFORE_JSON row pre-images in a local FB_WRITE_QUEUE$ table inside Firebird, surviving page reloads, automatically restoring local rows on WriteRejected or discard(id) / clear(), and providing pause(), resume(), onFlush, and automatic online event flushing.
  • Segmented BLOB streaming (db.openBlobStream() and db.createBlobStream()): Exposes IBlob::getSegment and IBlob::putSegment through _fb_blob_create, _fb_blob_put_segment, _fb_blob_open_id, _fb_blob_open_query, _fb_blob_get_segment, and _fb_blob_close in the WASM C bridge and Web ReadableStream<Uint8Array> / BlobWritableStream APIs (db.openBlobStream(), tx.openBlobStream(), db.createBlobStream(), tx.createBlobStream()) on both FirebirdBrowser and FirebirdLite, with direct BlobHandle binding in parameterized INSERT/UPDATE statements.
  • Packed binary result buffer across the WASM C bridge (_fb_query_binary & _fb_cursor_fetch_binary): Added the "FBR\x01" binary result wire format (encodeBinaryResultSet() and decodeBinaryResultSet() in firebird-wasm/browser, plus _fb_query_binary and _fb_cursor_fetch_binary in fb_wasm_api.cpp), packing inline column descriptors or compact cached shapeId headers, per-row null bitmasks, and tagged BOOL, INT32, FLOAT64, UTF8, and BYTES cells in WASM linear memory.

v0.12.0 — Zero-Config Live Queries, Explain Plans, Database Diagnostics, Prepared Handles, Streaming Dump/Restore & ICU Locale Packs

Choose a tag to compare

@mariuz mariuz released this 26 Oct 15:04

This release completes Milestone 7 (M7 — Developer Experience, Performance & Ecosystem), adding zero-config reactive queries, query execution plans (db.explain()), Node describeQuery() input parameter metadata parity, database diagnostics (db.databaseInfo()), explicit prepared statement handles (db.prepare()), streaming/gzip database dump & restore (dumpDataStream() / loadDataStream()), and optional lazy-loaded ICU locale tailoring packs (db.loadIcuLocaleData() / buildIcuLocalePack()).


Added

  • Zero-config reactive queries (db.live(sql, onChange) and useLiveQuery(sql) without manual events).
    db.live() and useLiveQuery() (in firebird-wasm/react and
    firebird-wasm/vue) now make events optional. When omitted,
    extractReferencedTables() extracts the user tables referenced by the query
    (skipping CTEs, selectable procedures, and system tables) and auto-installs an
    idempotent AFTER INSERT OR UPDATE OR DELETE POSITION 32767 trigger
    (FB_LIVE$<hash>) once per table per session.
  • Query execution plans (db.explain(sql, options?) and <firebird-repl> Explain button).
    Exposes IStatement::getPlan(status, detailed) through _fb_explain in the
    WASM C bridge and db.explain(sql, { detailed?: boolean }) (plus tx.explain
    and sql tagged-template overloads) on both FirebirdBrowser and
    FirebirdLite, returning either the compact PLAN (...) string or Firebird's
    structured explained plan tree without executing the statement. Added an
    Explain button to <firebird-repl>.
  • Node describeQuery() input parameter metadata (params) parity.
    FirebirdLite.describeQuery(sql) and FirebirdTransaction.describeQuery(sql)
    now read statementHandle.getInputMetadataAsync and populate full FieldInfo[]
    metadata on params, matching FirebirdBrowser.describeQuery(sql).
  • Database diagnostics & OIT/OAT transaction health (db.databaseInfo() and <firebird-repl> Info button).
    Exposes IAttachment::getInfo via _fb_database_info in the WASM C bridge and
    db.databaseInfo() on both FirebirdBrowser and FirebirdLite (plus an
    Info button in <firebird-repl>), reporting pageSize, allocatedPages,
    databaseSizeBytes, odsVersion, odsMinorVersion, oldestTransaction
    (OIT), oldestActive (OAT), oldestSnapshot (OST), nextTransaction,
    transactionGap, currentMemory, maxMemory, pageBuffers, reads,
    writes, fetches, and marks.
  • Explicit prepared statement handles (db.prepare(sql) and tx.prepare(sql)).
    Complements the internal 64-entry SQL statement cache with an explicit
    PreparedStatement handle (stmt.sql, stmt.fields, stmt.params,
    stmt.statementType, stmt.hasResultSet, stmt.closed, stmt.query(params?, options?),
    stmt.exec(params?), stmt.execBatch(rows), stmt.close()) on
    FirebirdBrowser, FirebirdBrowserTransaction, FirebirdLite, and
    FirebirdTransaction, backed by _fb_prepare / _fb_stmt_close in the WASM
    C bridge and native Statement handles on Node.
  • Streaming & gzip-compressed database dump and restore (dumpDataStream() and loadDataStream()).
    db.dumpDataStream({ chunkSize?, compression?: 'none' | 'gzip' }),
    db.loadDataStream(source, options?), and options.loadDataStream on both
    FirebirdBrowser and FirebirdLite export and import database images in
    64 KiB page-aligned chunks (with automatic DecompressionStream('gzip')
    detection on 0x1f 0x8b headers) without allocating a single contiguous
    Uint8Array of the entire database file in memory.
  • Optional lazy-loaded ICU locale tailoring packs (db.loadIcuLocaleData() and buildIcuLocalePack()).
    Added wasm/tools/build-icu-data.sh --locales, _fb_load_icu_data
    (fb_wasm_register_icu_data registering a second udata_setCommonData() slot
    in fb_wasm_icu_data.cpp), db.loadIcuLocaleData(data),
    FirebirdBrowserOptions.icuLocaleData, and buildIcuLocalePack(locales?) so
    locale-specific collations (CREATE COLLATION ... FOR UTF8 FROM UNICODE 'LOCALE=de_DE', es_ES, fr_FR, ja_JP) can be lazy-loaded on demand
    (raw .dat or gzipped .dat.gz) without increasing the default WASM binary
    size.

v0.11.0 — Embedded ICU 68 Collation Data (UNICODE, UNICODE_CI, UNICODE_CI_AI)

Choose a tag to compare

@mariuz mariuz released this 25 Oct 21:29

This release embeds ICU 68 collation data (icudt68l.dat) into the WASM engine so Firebird's UNICODE, UNICODE_CI (case-insensitive), and UNICODE_CI_AI (case- and accent-insensitive) collations work out of the box on both firebird-embedded-st and firebird-embedded.


Added

  • Embedded ICU 68 collation data (UNICODE, UNICODE_CI, UNICODE_CI_AI).
    The WASM engine now ships a stripped ICU 68 common data package (icudt68l.dat, ~343 KB uncompressed / ~130 KB gzipped) containing the DUCET root collation table (coll/ucadata.icu, coll/root.res), Unicode normalization tables (nfc.nrm, nfkc.nrm), and character property resources, embedded at /icu/icudt68l.dat via --embed-file and registered with udata_setCommonData() inside fb_init():
    • COLLATE UNICODE, COLLATE UNICODE_CI (case-insensitive), and COLLATE UNICODE_CI_AI (case- and accent-insensitive) now work out of the box in CREATE TABLE, ORDER BY, WHERE (=, LIKE, CONTAINING, STARTING WITH), GROUP BY, DISTINCT, and expression indexes (CREATE INDEX) on both firebird-embedded-st and firebird-embedded.
    • Fixed the static-ICU function pointer signature mismatch on ucol_getContractionsAndExpansions (void in ICU 68 vs int32_t expected by Firebird's UnicodeUtil::ICU::ucolGetContractionsAndExpansions under WASM's strict indirect-call type checking) via the wasmUcolGetContractionsAndExpansions wrapper in patch 0002.

v0.10.1 — Rebuilt WASM binaries, ORM multi-row INSERT via execBatch, and native IBatch

Choose a tag to compare

@mariuz mariuz released this 25 Oct 00:23

This patch release rebuilds and ships the 0.10.x WASM binaries (firebird-embedded.{js,wasm} and firebird-embedded-st.{js,wasm}) in the published npm tarball, routes multi-row INSERTs in firebird-wasm/kysely and firebird-wasm/drizzle through execBatch, wires native IBatch + addBlobAsync into FirebirdLite.execBatch, and includes wasm/build.sh and CI runner fixes.


Fixed

  • Rebuilt WASM binaries in the published npm tarball. The 0.10.0 npm package was packed before the local WASM rebuild ran and shipped the 0.9.0 dist/wasm/firebird-embedded.{js,wasm} and dist/wasm/firebird-embedded-st.{js,wasm} binaries (missing _fb_cursor_open / _fb_cursor_fetch / _fb_cursor_close for queryStream(), DECFLOAT decoding, and C bridge formatting fast paths). 0.10.1 ships the rebuilt 0.10.x WASM artifacts in both the npm package and the GitHub release.
  • Multi-row INSERTs in Kysely and Drizzle now execute via execBatch. Multi-row INSERT statements without RETURNING in firebird-wasm/kysely and firebird-wasm/drizzle now route through db.execBatch('INSERT INTO … VALUES (?, …)', rows) instead of INSERT INTO … SELECT ? FROM RDB$DATABASE UNION ALL …, avoiding Firebird SQL error -804 (Data type unknown) on untyped ? parameter markers in SELECT projection lists.
  • Native IBatch in FirebirdLite.execBatch (node-firebird-drivers#178). When statementHandle.createBatchAsync is available on the native client (merged upstream in asfernandes/node-firebird-drivers#178), FirebirdLite.execBatch and FirebirdTransaction.execBatch execute batches through Firebird 4.0+'s IBatch API (including addBlobAsync with TAG_BLOB_POLICY = BLOB_ID_ENGINE so BLOB parameters take no per-row round trips), falling back automatically to EXECUTE BLOCK on older drivers or Firebird 3.0 servers.
  • WASM build script (wasm/build.sh) and CI fixes. Passes -C1 to git apply --reverse --check when verifying already-applied patches, passes -DCMAKE_C_FLAGS="-std=gnu11 -Wno-implicit-int" during the native host bootstrap configure for GCC 15 compatibility, and pins Playwright CI jobs to ubuntu-24.04.

v0.10.0 — Kysely & Drizzle dialects, queryStream(), Node types parity, native IBatch, and OPFS/C bridge fast paths

Choose a tag to compare

@mariuz mariuz released this 24 Oct 22:37

This release adds Kysely (firebird-wasm/kysely) and Drizzle (firebird-wasm/drizzle) ORM dialects, the cursor/streaming query API (queryStream()), full Node backend types and FieldInfo parity, replica=full and applyWrite on the Electric shape server (firebird-wasm/electric-server), native IBatch + addBlobAsync support on Node (asfernandes/node-firebird-drivers#178), zero-copy OPFS reads and writes on the default single-threaded build (firebird-embedded-st), C bridge fast paths (DECFLOAT, SQL_FLOAT std::to_chars, offset-based SQL_TIME_TZ / SQL_TIMESTAMP_TZ, in-place appendScaledDecimal), and incremental WASM rebuild support in wasm/build.sh and CI.


Added

  • Kysely and Drizzle ORM dialects (firebird-wasm/kysely and firebird-wasm/drizzle). Both run against FirebirdBrowser and FirebirdLite:
    • firebird-wasm/kysely exports FirebirdDialect, FirebirdDriver, FirebirdQueryCompiler, FirebirdAdapter, FirebirdIntrospector, and createKysely(db, config?). Compiles ? positional parameters, Firebird OFFSET ? ROWS FETCH NEXT ? ROWS ONLY pagination (and ROWS ? on UPDATE / DELETE), multi-row INSERT (routed through execBatch), UPDATE OR INSERT INTO … MATCHING (…) upserts on onConflict, INSERT / UPDATE / DELETE … RETURNING, Firebird DDL (GENERATED BY DEFAULT AS IDENTITY before PRIMARY KEY, CREATE GLOBAL TEMPORARY TABLE, ALTER TABLE … ADD / DROP / ALTER COLUMN … TO …), transactions with Firebird isolation levels and savepoints, cursor streaming over queryStream(), system-table introspection (RDB$RELATIONS / RDB$RELATION_FIELDS), and bijective lowercase/uppercase identifier folding (identifierCase: 'lower' | 'preserve').
    • firebird-wasm/drizzle exports drizzle(db, config?), FirebirdDrizzleDialect, FirebirdDrizzleSession, FirebirdDrizzlePreparedQuery, FirebirdDrizzleTransaction, FirebirdDrizzleDatabase, firebirdTable, column builders, and query operators. Supports relational queries (db.query.*.findMany()), multi-row inserts (routed through execBatch), omitted identity/default columns, onConflictDoUpdate via UPDATE OR INSERT … MATCHING, RETURNING, db.$count(), transactions, and nested savepoints.
  • Cursor / streaming query API (queryStream()). queryStream(sql, params?, options?) on FirebirdBrowser, FirebirdBrowserTransaction, FirebirdLite, and FirebirdTransaction (including sql tagged-template overloads) returns an AsyncIterable<QueryResult<T>> yielding batches of batchSize rows (default 500) over an open cursor (_fb_cursor_open, _fb_cursor_fetch, _fb_cursor_close in the WASM C bridge; ResultSet.fetch({ fetchSize }) on Node). Breaking out of for await early closes the cursor and finishes its autocommit transaction immediately without fetching the rest of the table.
  • Node backend types and FieldInfo parity. FirebirdLite and FirebirdTransaction now accept types: { bigint, dates, binary, parsers, serializers } at database construction and per-query (QueryOptions.types), populate full FieldInfo metadata (type, typeName, subType, scale, length, nullable) from the native statement metadata, and normalize wire values (BIGINT, INT128, scaled NUMERIC / DECIMAL, DATE, TIME, TIMESTAMP, TIME WITH TIME ZONE, TIMESTAMP WITH TIME ZONE, DECFLOAT, text/binary BLOBs, and OCTETS) to match FirebirdBrowser.
  • Shape server replica=full, applyWrite, DECFLOAT, and batched change fetches.
    • firebird-wasm/electric-server now supports ?replica=full: the update and delete triggers record prior column values in OLD_VALUES on ELECTRIC_CHANGES, and replica=full responses include old_value on updates (changed columns) and deletes (all non-key columns).
    • server.applyWrite(write) executes a PendingWrite from createWriteQueue directly against the Firebird source table in one transaction and returns { txid } for immediate write-queue confirmation.
    • changesAfter batches row fetches for changed keys with IN (?, …) in chunks of 200 instead of issuing one SELECT per changed key.
    • DECFLOAT(16) and DECFLOAT(34) (SQL_DEC16 = 260, SQL_DEC34 = 262) are decoded in the C bridge, mapped in firebird-wasm/electric-server, and accepted by firebird-wasm/electric.
  • Native IBatch in FirebirdLite.execBatch (node-firebird-drivers#178). When statementHandle.createBatchAsync is available on the native client (merged upstream in asfernandes/node-firebird-drivers#178), FirebirdLite.execBatch and FirebirdTransaction.execBatch execute batches through Firebird 4.0+'s IBatch API (including addBlobAsync with TAG_BLOB_POLICY = BLOB_ID_ENGINE so BLOB parameters take no per-row round trips), falling back automatically to EXECUTE BLOCK on older drivers or Firebird 3.0 servers.

Changed

  • Zero-copy OPFS reads and writes on the default single-threaded build. When HEAPU8.buffer is a plain ArrayBuffer (firebird-embedded-st), mountOpfs passes the WASM heap subarray directly to FileSystemSyncAccessHandle.read and .write without allocating or copying through an intermediate scratch buffer.
  • Faster C bridge value formatting. SQL_FLOAT uses std::to_chars, offset-based SQL_TIME_TZ and SQL_TIMESTAMP_TZ (0..2878) are decoded in C without IUtil, and appendScaledDecimal writes directly into the JSON buffer without temporary string shifts.
  • Incremental WASM rebuilds, GCC 15 host bootstrap, and CI verification. wasm/build.sh preserves the timestamps of unchanged autoconfig.h, parse.h / parse.cpp, and epp-generated outputs across native bootstrap rebuilds, passes -DCMAKE_C_FLAGS="-std=gnu11 -Wno-implicit-int" so Firebird's Configure.cmake checks succeed under GCC 15 (-std=gnu23), checks already-applied patches with -C1, and build-wasm.yml runs an incremental rebuild check after wiping build-native-config and .wasm-patches-applied and touching fb_wasm_api.cpp.