flatsql 0.4.3 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +116 -6
  2. package/dist/artifacts/builder.d.ts +31 -0
  3. package/dist/artifacts/builder.d.ts.map +1 -0
  4. package/dist/artifacts/builder.js +514 -0
  5. package/dist/artifacts/builder.js.map +1 -0
  6. package/dist/artifacts/demo-extractors.d.ts +15 -0
  7. package/dist/artifacts/demo-extractors.d.ts.map +1 -0
  8. package/dist/artifacts/demo-extractors.js +238 -0
  9. package/dist/artifacts/demo-extractors.js.map +1 -0
  10. package/dist/artifacts/index.d.ts +5 -0
  11. package/dist/artifacts/index.d.ts.map +1 -0
  12. package/dist/artifacts/index.js +5 -0
  13. package/dist/artifacts/index.js.map +1 -0
  14. package/dist/artifacts/standalone-builder.d.ts +62 -0
  15. package/dist/artifacts/standalone-builder.d.ts.map +1 -0
  16. package/dist/artifacts/standalone-builder.js +144 -0
  17. package/dist/artifacts/standalone-builder.js.map +1 -0
  18. package/dist/artifacts/transport.d.ts +5 -0
  19. package/dist/artifacts/transport.d.ts.map +1 -0
  20. package/dist/artifacts/transport.js +45 -0
  21. package/dist/artifacts/transport.js.map +1 -0
  22. package/dist/artifacts/types.d.ts +34 -0
  23. package/dist/artifacts/types.d.ts.map +1 -0
  24. package/dist/artifacts/types.js +2 -0
  25. package/dist/artifacts/types.js.map +1 -0
  26. package/dist/artifacts/worker-client.d.ts +32 -0
  27. package/dist/artifacts/worker-client.d.ts.map +1 -0
  28. package/dist/artifacts/worker-client.js +415 -0
  29. package/dist/artifacts/worker-client.js.map +1 -0
  30. package/dist/btree/btree.d.ts.map +1 -1
  31. package/dist/btree/btree.js +13 -14
  32. package/dist/btree/btree.js.map +1 -1
  33. package/dist/core/database.d.ts +2 -0
  34. package/dist/core/database.d.ts.map +1 -1
  35. package/dist/core/database.js +18 -0
  36. package/dist/core/database.js.map +1 -1
  37. package/dist/core/table-store.d.ts +1 -0
  38. package/dist/core/table-store.d.ts.map +1 -1
  39. package/dist/core/table-store.js +31 -0
  40. package/dist/core/table-store.js.map +1 -1
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +3 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/response/artifact.d.ts +5 -0
  46. package/dist/response/artifact.d.ts.map +1 -0
  47. package/dist/response/artifact.js +102 -0
  48. package/dist/response/artifact.js.map +1 -0
  49. package/dist/response/cache-key.d.ts +6 -0
  50. package/dist/response/cache-key.d.ts.map +1 -0
  51. package/dist/response/cache-key.js +114 -0
  52. package/dist/response/cache-key.js.map +1 -0
  53. package/dist/response/index.d.ts +5 -0
  54. package/dist/response/index.d.ts.map +1 -0
  55. package/dist/response/index.js +5 -0
  56. package/dist/response/index.js.map +1 -0
  57. package/dist/response/memory-cache.d.ts +17 -0
  58. package/dist/response/memory-cache.d.ts.map +1 -0
  59. package/dist/response/memory-cache.js +76 -0
  60. package/dist/response/memory-cache.js.map +1 -0
  61. package/dist/response/types.d.ts +51 -0
  62. package/dist/response/types.d.ts.map +1 -0
  63. package/dist/response/types.js +2 -0
  64. package/dist/response/types.js.map +1 -0
  65. package/dist/standalone/index.d.ts +3 -0
  66. package/dist/standalone/index.d.ts.map +1 -0
  67. package/dist/standalone/index.js +3 -0
  68. package/dist/standalone/index.js.map +1 -0
  69. package/dist/standalone/process-client.d.ts +85 -0
  70. package/dist/standalone/process-client.d.ts.map +1 -0
  71. package/dist/standalone/process-client.js +537 -0
  72. package/dist/standalone/process-client.js.map +1 -0
  73. package/dist/standalone/wasmedge-runner.d.ts +19 -0
  74. package/dist/standalone/wasmedge-runner.d.ts.map +1 -0
  75. package/dist/standalone/wasmedge-runner.js +108 -0
  76. package/dist/standalone/wasmedge-runner.js.map +1 -0
  77. package/dist/stress/aggregate.d.ts +3 -0
  78. package/dist/stress/aggregate.d.ts.map +1 -0
  79. package/dist/stress/aggregate.js +61 -0
  80. package/dist/stress/aggregate.js.map +1 -0
  81. package/dist/stress/docker-compose.d.ts +17 -0
  82. package/dist/stress/docker-compose.d.ts.map +1 -0
  83. package/dist/stress/docker-compose.js +156 -0
  84. package/dist/stress/docker-compose.js.map +1 -0
  85. package/dist/stress/index.d.ts +11 -0
  86. package/dist/stress/index.d.ts.map +1 -0
  87. package/dist/stress/index.js +11 -0
  88. package/dist/stress/index.js.map +1 -0
  89. package/dist/stress/metrics.d.ts +3 -0
  90. package/dist/stress/metrics.d.ts.map +1 -0
  91. package/dist/stress/metrics.js +83 -0
  92. package/dist/stress/metrics.js.map +1 -0
  93. package/dist/stress/native-publish-event-workload.d.ts +3 -0
  94. package/dist/stress/native-publish-event-workload.d.ts.map +1 -0
  95. package/dist/stress/native-publish-event-workload.js +455 -0
  96. package/dist/stress/native-publish-event-workload.js.map +1 -0
  97. package/dist/stress/production-gate.d.ts +4 -0
  98. package/dist/stress/production-gate.d.ts.map +1 -0
  99. package/dist/stress/production-gate.js +12 -0
  100. package/dist/stress/production-gate.js.map +1 -0
  101. package/dist/stress/publish-event-workload.d.ts +3 -0
  102. package/dist/stress/publish-event-workload.d.ts.map +1 -0
  103. package/dist/stress/publish-event-workload.js +467 -0
  104. package/dist/stress/publish-event-workload.js.map +1 -0
  105. package/dist/stress/report.d.ts +3 -0
  106. package/dist/stress/report.d.ts.map +1 -0
  107. package/dist/stress/report.js +174 -0
  108. package/dist/stress/report.js.map +1 -0
  109. package/dist/stress/sds-discovery.d.ts +4 -0
  110. package/dist/stress/sds-discovery.d.ts.map +1 -0
  111. package/dist/stress/sds-discovery.js +40 -0
  112. package/dist/stress/sds-discovery.js.map +1 -0
  113. package/dist/stress/smoke-runner.d.ts +3 -0
  114. package/dist/stress/smoke-runner.d.ts.map +1 -0
  115. package/dist/stress/smoke-runner.js +63 -0
  116. package/dist/stress/smoke-runner.js.map +1 -0
  117. package/dist/stress/types.d.ts +219 -0
  118. package/dist/stress/types.d.ts.map +1 -0
  119. package/dist/stress/types.js +2 -0
  120. package/dist/stress/types.js.map +1 -0
  121. package/dist/stress/workload.d.ts +6 -0
  122. package/dist/stress/workload.d.ts.map +1 -0
  123. package/dist/stress/workload.js +144 -0
  124. package/dist/stress/workload.js.map +1 -0
  125. package/docs/agents/response-artifacts.md +65 -0
  126. package/docs/response-artifacts.md +86 -0
  127. package/package.json +36 -6
  128. package/scripts/stress-docker.sh +279 -0
  129. package/sdm/flatsql-spatial.wasm +0 -0
  130. package/stress/docker/Dockerfile +11 -0
  131. package/stress/docker/docker-compose.yml +51 -0
  132. package/stress/sds/aggregate.mjs +97 -0
  133. package/stress/sds/run.mjs +105 -0
  134. package/stress/sds/write-compose.mjs +96 -0
  135. package/wasm/flatsql-artifact.worker.js +847 -0
  136. package/wasm/flatsql-wasi.wasm +0 -0
  137. package/wasm/flatsql.js +2 -16
  138. package/wasm/flatsql.wasm +0 -0
  139. package/wasm/index.d.ts +119 -2
  140. package/wasm/index.js +450 -60
  141. package/wasm/native/flatsql_wasmedge_runner.cpp +858 -0
  142. package/wasm/standalone.d.ts +91 -0
  143. package/wasm/standalone.js +740 -0
package/README.md CHANGED
@@ -75,11 +75,118 @@ FlatBuffer → Query (via virtual table) → FlatBuffer
75
75
  ## Runtime Choices & Performance Gates
76
76
 
77
77
  - Production should prefer the SQLite-backed native/WASM path (`initFlatSQL` → `FlatSQL` → `createDatabase`). The pure TypeScript `FlatSQLDatabase` is preserved only as an explicit fallback/reference implementation for environments that cannot load the WASM module.
78
+ - Standalone deployments use the C++ WASI reactor at `flatsql/wasi.wasm`. Browser hosts load it through `flatsql/standalone`, while Node/WasmEdge hosts use a resident runner from `flatsql/standalone/wasmedge`.
79
+ - Artifact-builder cache behavior belongs to C++: query templates, result-cache keys, invalidation generation, hit/miss counters, SQL execution, and raw FlatBuffer lookup all live in the WASM database instance. JavaScript only marshals bytes and fills host capability gaps.
78
80
  - Use `db.ingestBuffers([...])` on the WASM path when your input is already a set of raw FlatBuffers. It feeds the native bulk-stream ingest path instead of looping through `ingestOne(...)`.
79
81
  - Run `npm run bench` (alias `npm run bench:perf`) as the single-command benchmark matrix for FlatSQL JS vs FlatSQL WASM. Use `npm run bench:perf:profile` to print the WASM ingest phase breakdown (`pack`, `decode`, `append`, `index`, `verify`) alongside the gate table.
80
82
  Profiling mode is diagnostic and includes instrumentation overhead; use the non-profile benchmark for merge-gate decisions.
81
83
  - Run `npm run test:cluster` for the native WAL-backed cluster validation workload, or `npm run test:cluster:smoke` for the short preflight run.
82
84
 
85
+ ## SDS Stress Harness
86
+
87
+ The Space Data Standards stress harness exercises every discoverable `main.fbs` under `../spacedatastandards.org/schema`, records bandwidth and storage-fill metrics, and keeps canonical schemas database-neutral. Results are written under `stress/results/<run-id>/`.
88
+
89
+ ```bash
90
+ # Local smoke path, no Docker required.
91
+ npm run stress:sds:smoke -- --run-id sds-smoke
92
+
93
+ # Existing single-controller Docker smoke path.
94
+ npm run stress:sds:docker-smoke -- --run-id sds-docker-smoke
95
+
96
+ # Container-per-node fleet path for small probes, e.g. 10 isolated nodes.
97
+ npm run stress:sds:docker-fleet -- --run-id sds-10-node --nodes 10 --storage-gb 1 --records-per-node 100000
98
+
99
+ # Generate and validate the 100-node / 1 GB-per-node production compose file without running it.
100
+ npm run stress:sds:full-config -- --run-id sds-full
101
+ docker compose -f stress/results/sds-full/docker-compose.full.yml config
102
+
103
+ # Run the full production gate. Requires Docker and enough local storage.
104
+ CONFIRM_FULL_STRESS=1 npm run stress:sds:full -- --run-id sds-full
105
+ ```
106
+
107
+ The production gate only passes when the aggregate report shows container isolation, Docker transport, at least 100 nodes, no metric errors, measured native/standalone/WasmEdge events, complete SDS schema-sweep coverage, at least 95% storage fill against the 1 GB/node target on every node, and bulk-ingest throughput at or above 75 fps on every node.
108
+
109
+ Full mode defaults to 20,000 records per node, or 2 million records across the 100-node fleet. In full mode the generated PublishEventRecord payload size scales from the configured storage budget so the run targets the requested per-node storage fill without requiring hundreds of millions of tiny records.
110
+
111
+ ## Agent Runtime Notes
112
+
113
+ Use these entrypoints when wiring agents or deployments:
114
+
115
+ | Import | Runtime | Use for |
116
+ |--------|---------|---------|
117
+ | `flatsql/wasm` | Emscripten JS wrapper + C++ WASM | Existing browser/Node API |
118
+ | `flatsql/standalone` | Raw `flatsql-wasi.wasm` + small JS WASI shim | Browser or Node direct WebAssembly API |
119
+ | `flatsql/artifacts/standalone` | C++ artifact builder facade | Cache-centric artifact workflows |
120
+ | `flatsql/response` | Response artifact bytes | ETags, chunks, and raw byte artifacts keyed by native runtime cache keys |
121
+ | `flatsql/standalone/wasmedge` | Native WasmEdge runner builder/client | Persistent standalone runtime in Node |
122
+ | `flatsql` `FlatSQLDatabase` | Pure TypeScript fallback | Reference or no-WASM environments only |
123
+
124
+ For repeated FILE_ID-style traffic, register a cacheable query template once and call `queryTemplate(...)` with positional params. Identical query IDs and params hit the C++ result cache; ingest, load, template changes, and explicit `clearQueryCache()` invalidate stale entries by generation.
125
+
126
+ ```javascript
127
+ import { createStandaloneArtifactBuilder } from 'flatsql/artifacts/standalone';
128
+
129
+ const builder = await createStandaloneArtifactBuilder(schema, { runtime: 'standalone' });
130
+ await builder.registerFileId('USER', 'User');
131
+ await builder.enableDemoExtractors();
132
+ await builder.ingestBuffers(buffers);
133
+ await builder.configureQueryCache({ maxEntries: 4096, maxRows: 5000 });
134
+ await builder.registerQueryTemplate('userByEmail', 'SELECT id FROM User WHERE email = ?', true);
135
+
136
+ await builder.queryTemplate('userByEmail', ['alice@example.com']); // miss
137
+ await builder.queryTemplate('userByEmail', ['alice@example.com']); // hit
138
+ console.log(await builder.getQueryCacheStats());
139
+ ```
140
+
141
+ The native cache defaults to 1024 entries and 1000 rows per cached result. Tune `maxEntries` and `maxRows` for production FILE_ID traffic instead of recompiling the C++ core.
142
+
143
+ For WasmEdge, build the small host runner and pass it to the same builder. The runner keeps one WASI module instance resident so cache state survives across requests.
144
+
145
+ ```javascript
146
+ import { createStandaloneArtifactBuilder } from 'flatsql/artifacts/standalone';
147
+ import { buildFlatSQLWasmEdgeRunner } from 'flatsql/standalone/wasmedge';
148
+
149
+ const runner = await buildFlatSQLWasmEdgeRunner({
150
+ outputPath: './build/flatsql-wasmedge-runner',
151
+ });
152
+
153
+ const builder = await createStandaloneArtifactBuilder(schema, {
154
+ runtime: 'wasmedge',
155
+ wasmEdgeRunnerBinary: runner.outputPath,
156
+ });
157
+ ```
158
+
159
+ WasmEdge must support WebAssembly exception handling for this artifact. The test runner uses `wasmedge --enable-exception-handling --reactor wasm/flatsql-wasi.wasm _initialize` for the smoke check and the native C API runner enables the same proposal programmatically. Some Node 24 builds require `node --experimental-wasm-exnref` when directly instantiating the standalone WASI artifact.
160
+
161
+ For high-volume repeated FILE_ID responses, build the cache key through the C++ runtime, wrap query results as response artifacts, and let edge/browser/WasmEdge host caches serve the immutable bytes by ETag or content hash. FlatSQL creates deterministic native cache keys and chunk metadata; deployment code owns CDN placement, routing, authorization, and global invalidation.
162
+
163
+ ```javascript
164
+ import { createQueryResponseArtifact } from 'flatsql/response';
165
+
166
+ const sql = 'SELECT _data FROM PublishEventRecord WHERE FILE_ID = ?';
167
+ const cacheKey = await builder.buildResponseArtifactCacheKey('PublishEventRecord', '1', sql, {
168
+ format: 'raw-flatbuffer-stream',
169
+ publishEventKey: 'publish-1',
170
+ projection: ['_data'],
171
+ params: ['publish-1'],
172
+ });
173
+ const result = await builder.query(sql, ['publish-1']);
174
+ const artifact = createQueryResponseArtifact(result, {
175
+ schemaName: 'PublishEventRecord',
176
+ schemaVersion: 1,
177
+ sql,
178
+ params: ['publish-1'],
179
+ format: 'raw-flatbuffer-stream',
180
+ publishEventKey: 'publish-1',
181
+ projection: ['_data'],
182
+ cacheKey,
183
+ });
184
+
185
+ console.log(artifact.metadata.cacheKey, artifact.metadata.etag);
186
+ ```
187
+
188
+ See `docs/response-artifacts.md` and `docs/agents/response-artifacts.md` for production and agent guidance.
189
+
83
190
 
84
191
  ## Source Code
85
192
 
@@ -457,7 +564,7 @@ The index stores `(key, sequence) → (offset, length)` mappings, allowing O(log
457
564
 
458
565
  ### Prerequisites
459
566
 
460
- - Node.js 18+
567
+ - Node.js 24+
461
568
  - CMake 3.20+ (for WASM builds)
462
569
  - Emscripten (for WASM builds)
463
570
 
@@ -475,13 +582,16 @@ npm test
475
582
  # Clone DA-FlatBuffers (required dependency)
476
583
  git clone https://github.com/DigitalArsenal/flatbuffers.git ../flatbuffers
477
584
 
478
- # Build WASM
479
- cd cpp
480
- emcmake cmake -B build-wasm -DCMAKE_BUILD_TYPE=Release
481
- cmake --build build-wasm
585
+ # Build browser, standalone WASI, and SDM artifacts
586
+ npm run build:wasm
587
+
588
+ # Verify standalone and package surfaces
589
+ npm run test:wasi
590
+ npm run test:wasmedge
591
+ npm test -- --runInBand --runTestsByPath test/package-exports.test.ts
482
592
  ```
483
593
 
484
- Output: `wasm/flatsql.js` and `wasm/flatsql.wasm`
594
+ Output: `wasm/flatsql.js`, `wasm/flatsql.wasm`, `wasm/flatsql-wasi.wasm`, `sdm/flatsql-spatial.wasm`, and docs copies for GitHub Pages.
485
595
 
486
596
  ### Run Demo Locally
487
597
 
@@ -0,0 +1,31 @@
1
+ import { type DatabaseSchema } from '../schema/index.js';
2
+ import { type ArtifactFieldExtractor } from './demo-extractors.js';
3
+ import type { ArtifactBuilderOptions, ArtifactIngestOptions, ArtifactQueryParams, ArtifactQuerySpec, ArtifactIngestResult, ArtifactQueryResult } from './types.js';
4
+ export declare class FlatSQLArtifactBuilder {
5
+ private readonly schema;
6
+ private readonly db;
7
+ private readonly beginTransactionSql;
8
+ private readonly tableByName;
9
+ private readonly fileIdToTable;
10
+ private readonly extractors;
11
+ private readonly queryCache;
12
+ private readonly queryResultCache;
13
+ private sequence;
14
+ static fromSchema(source: string, options: ArtifactBuilderOptions): FlatSQLArtifactBuilder;
15
+ constructor(schema: DatabaseSchema, options: ArtifactBuilderOptions);
16
+ registerFileId(fileId: string, tableName: string): void;
17
+ setFieldExtractor(tableName: string, extractor: ArtifactFieldExtractor): void;
18
+ enableDemoExtractors(): void;
19
+ ingestBuffers(buffers: Uint8Array[], options?: ArtifactIngestOptions): ArtifactIngestResult;
20
+ query(sql: string, params?: ArtifactQueryParams): ArtifactQueryResult;
21
+ queryMany(queries: readonly ArtifactQuerySpec[]): ArtifactQueryResult[];
22
+ close(): void;
23
+ private createIndexTables;
24
+ private indexTableName;
25
+ private recordTableName;
26
+ private coveringIndexName;
27
+ private createCoveringIndexes;
28
+ private dropCoveringIndexes;
29
+ private createIngestPlan;
30
+ }
31
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/artifacts/builder.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EAEpB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAyYpB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;IAClC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAC3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6C;IACxE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAItB;IACL,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA0C;IAC3E,OAAO,CAAC,QAAQ,CAAK;IAErB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,sBAAsB;gBAW9E,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,sBAAsB;IAcnE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAIvD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,GAAG,IAAI;IAI7E,oBAAoB,IAAI,IAAI;IAM5B,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,OAAO,GAAE,qBAA0B,GAAG,oBAAoB;IA6C/F,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,mBAAmB;IAyCrE,SAAS,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,mBAAmB,EAAE;IAIvE,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,gBAAgB;CAyCzB"}