flatsql 3.11.0 → 3.12.0
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.
- package/README.md +61 -795
- package/bin/flatsql.mjs +76 -0
- package/cpp/README.md +18 -0
- package/cpp/include/flatsql/flatsql.h +162 -0
- package/cpp/include/flatsql/flatsql_io.h +159 -0
- package/docs/API-3.12.md +114 -0
- package/package.json +28 -123
- package/wasm/flatsql.wasm +0 -0
- package/wasm/index.d.ts +61 -548
- package/wasm/index.js +280 -1281
- package/wasm/integrity.json +6 -26
- package/wasm/runtime/LICENSE.sdk.txt +190 -0
- package/wasm/runtime/NOTICE.txt +2 -0
- package/wasm/runtime/browser-guest.mjs +1 -0
- package/wasm/runtime/browser-host.mjs +1 -0
- package/wasm/runtime/node-guest.mjs +2 -0
- package/wasm/runtime/node-host.mjs +5 -0
- package/wasm/runtime/opfsIoWorker.mjs +1 -0
- package/wasm/runtime/wasiThreadBrowserWorker.mjs +1 -0
- package/dist/artifacts/index.d.ts +0 -3
- package/dist/artifacts/index.d.ts.map +0 -1
- package/dist/artifacts/index.js +0 -3
- package/dist/artifacts/index.js.map +0 -1
- package/dist/artifacts/transport.d.ts +0 -5
- package/dist/artifacts/transport.d.ts.map +0 -1
- package/dist/artifacts/transport.js +0 -45
- package/dist/artifacts/transport.js.map +0 -1
- package/dist/artifacts/types.d.ts +0 -34
- package/dist/artifacts/types.d.ts.map +0 -1
- package/dist/artifacts/types.js +0 -2
- package/dist/artifacts/types.js.map +0 -1
- package/dist/btree/btree.d.ts +0 -34
- package/dist/btree/btree.d.ts.map +0 -1
- package/dist/btree/btree.js +0 -234
- package/dist/btree/btree.js.map +0 -1
- package/dist/btree/index.d.ts +0 -3
- package/dist/btree/index.d.ts.map +0 -1
- package/dist/btree/index.js +0 -3
- package/dist/btree/index.js.map +0 -1
- package/dist/btree/types.d.ts +0 -36
- package/dist/btree/types.d.ts.map +0 -1
- package/dist/btree/types.js +0 -55
- package/dist/btree/types.js.map +0 -1
- package/dist/cluster/index.d.ts +0 -11
- package/dist/cluster/index.d.ts.map +0 -1
- package/dist/cluster/index.js +0 -59
- package/dist/cluster/index.js.map +0 -1
- package/dist/response/artifact.d.ts +0 -4
- package/dist/response/artifact.d.ts.map +0 -1
- package/dist/response/artifact.js +0 -102
- package/dist/response/artifact.js.map +0 -1
- package/dist/response/cache-key.d.ts +0 -6
- package/dist/response/cache-key.d.ts.map +0 -1
- package/dist/response/cache-key.js +0 -114
- package/dist/response/cache-key.js.map +0 -1
- package/dist/response/index.d.ts +0 -5
- package/dist/response/index.d.ts.map +0 -1
- package/dist/response/index.js +0 -5
- package/dist/response/index.js.map +0 -1
- package/dist/response/memory-cache.d.ts +0 -17
- package/dist/response/memory-cache.d.ts.map +0 -1
- package/dist/response/memory-cache.js +0 -76
- package/dist/response/memory-cache.js.map +0 -1
- package/dist/response/types.d.ts +0 -57
- package/dist/response/types.d.ts.map +0 -1
- package/dist/response/types.js +0 -2
- package/dist/response/types.js.map +0 -1
- package/dist/schema/index.d.ts +0 -3
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -3
- package/dist/schema/index.js.map +0 -1
- package/dist/schema/parser.d.ts +0 -25
- package/dist/schema/parser.d.ts.map +0 -1
- package/dist/schema/parser.js +0 -474
- package/dist/schema/parser.js.map +0 -1
- package/dist/schema/types.d.ts +0 -33
- package/dist/schema/types.d.ts.map +0 -1
- package/dist/schema/types.js +0 -29
- package/dist/schema/types.js.map +0 -1
- package/dist/standalone/index.d.ts +0 -3
- package/dist/standalone/index.d.ts.map +0 -1
- package/dist/standalone/index.js +0 -3
- package/dist/standalone/index.js.map +0 -1
- package/dist/standalone/process-client.d.ts +0 -85
- package/dist/standalone/process-client.d.ts.map +0 -1
- package/dist/standalone/process-client.js +0 -537
- package/dist/standalone/process-client.js.map +0 -1
- package/dist/standalone/wasmedge-runner.d.ts +0 -19
- package/dist/standalone/wasmedge-runner.d.ts.map +0 -1
- package/dist/standalone/wasmedge-runner.js +0 -108
- package/dist/standalone/wasmedge-runner.js.map +0 -1
- package/dist/storage/index.d.ts +0 -3
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js +0 -3
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/stacked-flatbuffers.d.ts +0 -38
- package/dist/storage/stacked-flatbuffers.d.ts.map +0 -1
- package/dist/storage/stacked-flatbuffers.js +0 -253
- package/dist/storage/stacked-flatbuffers.js.map +0 -1
- package/dist/storage/types.d.ts +0 -23
- package/dist/storage/types.d.ts.map +0 -1
- package/dist/storage/types.js +0 -27
- package/dist/storage/types.js.map +0 -1
- package/dist/stress/aggregate.d.ts +0 -3
- package/dist/stress/aggregate.d.ts.map +0 -1
- package/dist/stress/aggregate.js +0 -61
- package/dist/stress/aggregate.js.map +0 -1
- package/dist/stress/docker-compose.d.ts +0 -17
- package/dist/stress/docker-compose.d.ts.map +0 -1
- package/dist/stress/docker-compose.js +0 -156
- package/dist/stress/docker-compose.js.map +0 -1
- package/dist/stress/index.d.ts +0 -10
- package/dist/stress/index.d.ts.map +0 -1
- package/dist/stress/index.js +0 -10
- package/dist/stress/index.js.map +0 -1
- package/dist/stress/metrics.d.ts +0 -3
- package/dist/stress/metrics.d.ts.map +0 -1
- package/dist/stress/metrics.js +0 -83
- package/dist/stress/metrics.js.map +0 -1
- package/dist/stress/native-publish-event-workload.d.ts +0 -3
- package/dist/stress/native-publish-event-workload.d.ts.map +0 -1
- package/dist/stress/native-publish-event-workload.js +0 -465
- package/dist/stress/native-publish-event-workload.js.map +0 -1
- package/dist/stress/production-gate.d.ts +0 -4
- package/dist/stress/production-gate.d.ts.map +0 -1
- package/dist/stress/production-gate.js +0 -12
- package/dist/stress/production-gate.js.map +0 -1
- package/dist/stress/report.d.ts +0 -3
- package/dist/stress/report.d.ts.map +0 -1
- package/dist/stress/report.js +0 -174
- package/dist/stress/report.js.map +0 -1
- package/dist/stress/sds-discovery.d.ts +0 -4
- package/dist/stress/sds-discovery.d.ts.map +0 -1
- package/dist/stress/sds-discovery.js +0 -40
- package/dist/stress/sds-discovery.js.map +0 -1
- package/dist/stress/smoke-runner.d.ts +0 -3
- package/dist/stress/smoke-runner.d.ts.map +0 -1
- package/dist/stress/smoke-runner.js +0 -64
- package/dist/stress/smoke-runner.js.map +0 -1
- package/dist/stress/types.d.ts +0 -219
- package/dist/stress/types.d.ts.map +0 -1
- package/dist/stress/types.js +0 -2
- package/dist/stress/types.js.map +0 -1
- package/dist/stress/workload.d.ts +0 -6
- package/dist/stress/workload.d.ts.map +0 -1
- package/dist/stress/workload.js +0 -144
- package/dist/stress/workload.js.map +0 -1
- package/docs/PARTITION-STORE-WASM.md +0 -338
- package/docs/PARTITION-STORE.md +0 -2380
- package/docs/agents/response-artifacts.md +0 -65
- package/docs/response-artifacts.md +0 -86
- package/scripts/stress-docker.sh +0 -279
- package/sdm/flatsql-spatial.wasm +0 -0
- package/sdm/index.d.ts +0 -88
- package/sdm/index.js +0 -253
- package/sdm/manifest.json +0 -402
- package/stress/docker/Dockerfile +0 -11
- package/stress/docker/docker-compose.yml +0 -51
- package/stress/sds/aggregate.mjs +0 -97
- package/stress/sds/run.mjs +0 -105
- package/stress/sds/write-compose.mjs +0 -96
- package/wasm/flatsql-client.js +0 -280
- package/wasm/flatsql-io.d.ts +0 -97
- package/wasm/flatsql-io.js +0 -621
- package/wasm/flatsql-p4-threads.wasm +0 -0
- package/wasm/flatsql-ps-threads.wasm +0 -0
- package/wasm/flatsql-wasi-noeh.wasm +0 -0
- package/wasm/flatsql-wasi.wasm +0 -0
- package/wasm/flatsql.js +0 -2
- package/wasm/flatsql.worker.js +0 -209
- package/wasm/native/flatsql_wasmedge_runner.cpp +0 -858
- package/wasm/ps-node-fault.d.mts +0 -23
- package/wasm/ps-node-fault.mjs +0 -381
- package/wasm/ps-node-guest.mjs +0 -173
- package/wasm/ps-node-host.d.mts +0 -95
- package/wasm/ps-node-host.mjs +0 -476
- package/wasm/ps-node-imports.mjs +0 -847
- package/wasm/ps.d.ts +0 -21
- package/wasm/ps.js +0 -75
- package/wasm/wasi.d.ts +0 -11
- package/wasm/wasi.js +0 -51
package/bin/flatsql.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Binary streams only. Schema/text conversion is a separate program.
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import { once } from 'node:events';
|
|
5
|
+
import { FlatSQL } from '../wasm/index.js';
|
|
6
|
+
|
|
7
|
+
const help = `Usage:
|
|
8
|
+
flatsql ingest --root DIR --schema FILE.bfbs --type NAME --id '$FID' < records.fb > receipts.fb
|
|
9
|
+
flatsql query --root DIR [--records] [--request FILE.fb] > results.fb
|
|
10
|
+
|
|
11
|
+
Ingest reads concatenated size-prefixed FlatBuffers from stdin.
|
|
12
|
+
Query reads one SDS QRP FlatBuffer request from stdin or --request.
|
|
13
|
+
Results are size-prefixed SDS QRP pages, or unchanged record frames with --records.
|
|
14
|
+
Optional ingest metadata: --provider NAME --source NAME --producer NAME --batch NAME.
|
|
15
|
+
Use a separate converter such as flatc-wasm for text input and output.
|
|
16
|
+
`;
|
|
17
|
+
async function main() {
|
|
18
|
+
const [command,...args]=process.argv.slice(2), options={};
|
|
19
|
+
if (!command || command==='--help' || command==='-h') { process.stdout.write(help); return; }
|
|
20
|
+
const allowed=new Set(['root','schema','type','id','request','provider','source','producer','batch']);
|
|
21
|
+
for (let i=0;i<args.length;i++) {
|
|
22
|
+
const key=args[i].slice(2);
|
|
23
|
+
if (args[i]==='--records') { options.records=true; continue; }
|
|
24
|
+
if (!args[i].startsWith('--') || !allowed.has(key) || !args[i+1] || args[i+1].startsWith('--'))
|
|
25
|
+
throw new Error(`Unknown or incomplete option: ${args[i]}`);
|
|
26
|
+
options[key]=args[++i];
|
|
27
|
+
}
|
|
28
|
+
if (!options.root || !['ingest','query'].includes(command)) throw new Error(help);
|
|
29
|
+
if (command==='ingest' && (!options.schema || !options.type || !options.id)) throw new Error(help);
|
|
30
|
+
const signal=new AbortController();
|
|
31
|
+
const interrupt=()=>signal.abort();
|
|
32
|
+
process.once('SIGINT',interrupt); process.once('SIGTERM',interrupt);
|
|
33
|
+
const write=async data=>{ if (!process.stdout.write(data)) await once(process.stdout,'drain'); };
|
|
34
|
+
const db=await FlatSQL.open({root:options.root});
|
|
35
|
+
try {
|
|
36
|
+
if (command==='query') {
|
|
37
|
+
let request;
|
|
38
|
+
if (options.request) {
|
|
39
|
+
if ((await fs.stat(options.request)).size>8*1024*1024) throw new Error('QRP request exceeds 8 MiB');
|
|
40
|
+
request=await fs.readFile(options.request);
|
|
41
|
+
} else {
|
|
42
|
+
const parts=[];let size=0;
|
|
43
|
+
for await (const chunk of process.stdin) {
|
|
44
|
+
size+=chunk.length;if(size>8*1024*1024)throw new Error('QRP request exceeds 8 MiB');parts.push(chunk);
|
|
45
|
+
}
|
|
46
|
+
request=Buffer.concat(parts);
|
|
47
|
+
}
|
|
48
|
+
for await (const chunk of db.query(request,{records:options.records,signal:signal.signal})) await write(chunk);
|
|
49
|
+
} else {
|
|
50
|
+
await db.registerSchema({name:options.type,fileIdentifier:options.id,bfbs:await fs.readFile(options.schema)});
|
|
51
|
+
const limit=4*1024*1024;
|
|
52
|
+
let pending=Buffer.alloc(0),batch=[],size=0;
|
|
53
|
+
const flush=async()=>{
|
|
54
|
+
if(!size)return;
|
|
55
|
+
await write(await db.ingest(options.type,Buffer.concat(batch,size),{...options,signal:signal.signal}));
|
|
56
|
+
batch=[];size=0;
|
|
57
|
+
};
|
|
58
|
+
for await(const chunk of process.stdin) {
|
|
59
|
+
pending=Buffer.concat([pending,chunk]);let at=0;
|
|
60
|
+
while(pending.length-at>=4) {
|
|
61
|
+
const n=pending.readUInt32LE(at)+4;
|
|
62
|
+
if(n<12 || n>limit)throw new Error('Record frame must be between 12 bytes and 4 MiB');
|
|
63
|
+
if(pending.length-at<n)break;
|
|
64
|
+
if(size+n>limit)await flush();
|
|
65
|
+
batch.push(Buffer.from(pending.subarray(at,at+n)));size+=n;at+=n;
|
|
66
|
+
}
|
|
67
|
+
pending=Buffer.from(pending.subarray(at));
|
|
68
|
+
}
|
|
69
|
+
if(pending.length)throw new Error('Truncated FlatBuffer record frame');
|
|
70
|
+
await flush();
|
|
71
|
+
}
|
|
72
|
+
} finally {
|
|
73
|
+
await db.close();process.removeListener('SIGINT',interrupt);process.removeListener('SIGTERM',interrupt);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
main().catch(error=>{process.stderr.write(`flatsql: ${error.message}\n`);process.exitCode=1;});
|
package/cpp/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# FlatSQL native engine
|
|
2
|
+
|
|
3
|
+
FlatSQL 3.12 has one public C ABI: `include/flatsql/flatsql.h`.
|
|
4
|
+
Build the `flatsql` static library with CMake and the pinned DigitalArsenal
|
|
5
|
+
FlatBuffers checkout at `8af3053eb8400de4a0a654805b8257e93fae3a8e`.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
cmake -S cpp -B cpp/build -DFLATBUFFERS_DIR=/path/to/flatbuffers -DCMAKE_BUILD_TYPE=Release
|
|
9
|
+
cmake --build cpp/build --target flatsql
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The same engine builds as `wasm/flatsql.wasm` using wasi-sdk 30.
|
|
13
|
+
Native hosts provide the seven filesystem imports described in the ABI header.
|
|
14
|
+
Public SQL requests/results use SDS QRP; records are size-prefixed FlatBuffers.
|
|
15
|
+
See `docs/API-3.12.md` for the binary and geospatial contracts.
|
|
16
|
+
|
|
17
|
+
The private source directory names `p4` and `p4sql` identify the storage
|
|
18
|
+
implementation. They are not alternate engines or public entry points.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/* FlatSQL: one engine and one ABI for binary records and SQL.
|
|
2
|
+
* SQL input is SDS QRP; all projected results are size-prefixed SDS QRP.
|
|
3
|
+
* Record streams contain unchanged size-prefixed FlatBuffers. Configuration,
|
|
4
|
+
* registration and storage metadata use the documented packed control layout;
|
|
5
|
+
* they never parse or render record text. Mailboxes keep queries off the host
|
|
6
|
+
* executor thread and retain independent cancellation and resource budgets.
|
|
7
|
+
*/
|
|
8
|
+
#ifndef FLATSQL_H
|
|
9
|
+
#define FLATSQL_H
|
|
10
|
+
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
|
|
13
|
+
#if defined(__wasm__)
|
|
14
|
+
# define FLATSQL_EXPORT(name) __attribute__((export_name(name)))
|
|
15
|
+
#else
|
|
16
|
+
# define FLATSQL_EXPORT(name)
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#ifdef __cplusplus
|
|
20
|
+
extern "C" {
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
/* ---- §3.2 Status and reject codes ------------------------------------- */
|
|
24
|
+
|
|
25
|
+
#define FLATSQL_OK 0
|
|
26
|
+
#define FLATSQL_E_ARG -1 /* malformed request or config */
|
|
27
|
+
#define FLATSQL_E_NOMEM -2
|
|
28
|
+
#define FLATSQL_E_IO -3
|
|
29
|
+
#define FLATSQL_E_CORRUPT -4 /* the file is quarantined, never rewritten; reads elsewhere continue */
|
|
30
|
+
#define FLATSQL_E_FORMAT -5 /* unsupported store/file format or layout; marker/state mismatch; C-5 rule change */
|
|
31
|
+
#define FLATSQL_E_BUSY -6 /* a queue or partition credit is full: nothing was done, retry; reader paths never wait */
|
|
32
|
+
#define FLATSQL_E_CANCELLED -7
|
|
33
|
+
#define FLATSQL_E_BUDGET -8 /* rows-examined, bytes-read, result rows/bytes, work or heap cap */
|
|
34
|
+
#define FLATSQL_E_UNSUPPORTED -9
|
|
35
|
+
#define FLATSQL_E_NOTYPE -10 /* type not registered */
|
|
36
|
+
#define FLATSQL_E_STOPPED -11 /* stop word set, or the instance is stopping */
|
|
37
|
+
#define FLATSQL_E_NOSPACE -12 /* quota or device full: writes refuse, reads continue */
|
|
38
|
+
#define FLATSQL_E_SQL -13 /* SQL error; the text is in the slot's err */
|
|
39
|
+
#define FLATSQL_E_INTERNAL -14
|
|
40
|
+
|
|
41
|
+
/* Per-record rejects (PUT rows, `reject` column). -100..-109 are
|
|
42
|
+
* ps::RejectCode from flatsql/typecfg/extract.h, unchanged. */
|
|
43
|
+
#define FLATSQL_REJ_BAD_ENTRY -100
|
|
44
|
+
#define FLATSQL_REJ_FRAME_SIZE -101
|
|
45
|
+
#define FLATSQL_REJ_FID -102
|
|
46
|
+
#define FLATSQL_REJ_VERIFY -103
|
|
47
|
+
#define FLATSQL_REJ_CID -104
|
|
48
|
+
#define FLATSQL_REJ_SEALED -105
|
|
49
|
+
#define FLATSQL_REJ_ATTR -106
|
|
50
|
+
#define FLATSQL_REJ_QUARANTINED -107
|
|
51
|
+
#define FLATSQL_REJ_NO_TYPE -108
|
|
52
|
+
#define FLATSQL_REJ_TXN_TOO_LARGE -109
|
|
53
|
+
#define FLATSQL_REJ_CID_FORM -110 /* the CID is not a CIDv1 raw sha2-256 (bafkrei...) */
|
|
54
|
+
#define FLATSQL_REJ_SEQ -111 /* a migrate-mode seq is missing, <= 0, or held by a different CID */
|
|
55
|
+
#define FLATSQL_REJ_TOO_LARGE -112 /* above the type's max frame, or above the write pool's request area (C-6) */
|
|
56
|
+
#define FLATSQL_REJ_TAG -113 /* a tag without provider or source, a tag index out of range, or a record
|
|
57
|
+
PEER whose token differs from the call peer's */
|
|
58
|
+
|
|
59
|
+
/* ---- §3.5 Ops, classes, slot states -------------------------------------- */
|
|
60
|
+
|
|
61
|
+
enum {
|
|
62
|
+
FLATSQL_OPC_PUT = 1, FLATSQL_OPC_SUPERSEDE = 2, FLATSQL_OPC_DELETE = 3, FLATSQL_OPC_QUOTA_GC = 4, FLATSQL_OPC_REBUILD = 5,
|
|
63
|
+
FLATSQL_OPC_GET = 10, FLATSQL_OPC_TAGS = 11, FLATSQL_OPC_SCAN = 12, FLATSQL_OPC_HEAD = 13, FLATSQL_OPC_WINDOW = 14,
|
|
64
|
+
FLATSQL_OPC_INDEX_PAGE = 15, FLATSQL_OPC_EPOCH = 16, FLATSQL_OPC_SUMMARY = 17,
|
|
65
|
+
FLATSQL_OPC_RANGES = 18, FLATSQL_OPC_FEED_ROOT = 19, FLATSQL_OPC_DROPS = 20,
|
|
66
|
+
FLATSQL_OPC_EXPOSURE = 21, FLATSQL_OPC_RELEASE = 22,
|
|
67
|
+
FLATSQL_OPC_SQL = 30, FLATSQL_OPC_SURFACE = 31
|
|
68
|
+
};
|
|
69
|
+
/* IPFS ops: tag 1 type; tags 3/4 provider/source (both omitted = every feed,
|
|
70
|
+
* both empty = local). Tag 80 u64: inclusive from-commit for RANGES/DROPS,
|
|
71
|
+
* through-commit for RELEASE. Tag 81 u8: EXPOSURE (0 default, 1 on).
|
|
72
|
+
* Tag 82 u32: RELEASE generation (default current); offsets are generation-local.
|
|
73
|
+
* RELEASE of a generation older than the current one releases that whole
|
|
74
|
+
* (immutable) generation; tag 80 is ignored. RELEASE of the current generation
|
|
75
|
+
* releases every older one once tag 80 reaches its compaction checkpoint (the
|
|
76
|
+
* first FCK after genesis), and is a no-op before that.
|
|
77
|
+
* RANGES: path,offset,length,cid,kind,unit,block,provider,source,generation.
|
|
78
|
+
* Paths are relative to config root; inline block bytes only for dag-pb nodes.
|
|
79
|
+
* LINK unit is its publication/change commit, including rewrites of old units.
|
|
80
|
+
* FEED_ROOT: provider,source,cid,unit,generation,blocked_generations.
|
|
81
|
+
* DROPS: cid,unit,provider,source,generation. Includes removed records, large
|
|
82
|
+
* roots/leaves and obsolete raw metadata. Derived LINK blocks are reclaimed
|
|
83
|
+
* by pin-update/GC. Unit names the removal or replacement checkpoint.
|
|
84
|
+
* RANGES is the live closure in the current generation, filtered by unit.
|
|
85
|
+
* Reset the cursor when FEED_ROOT reports a changed generation.
|
|
86
|
+
* Exposure is runtime policy: the node must reapply it after opening a store
|
|
87
|
+
* before the 30-second retired-reader window expires.
|
|
88
|
+
* EXPOSURE/RELEASE return no rows. These run on a read lane; exposure/release
|
|
89
|
+
* change only the node's generation-release bookkeeping, never stream bytes.
|
|
90
|
+
*/
|
|
91
|
+
enum { FLATSQL_RANGE_RECORD=1, FLATSQL_RANGE_LARGE_LEAF=2, FLATSQL_RANGE_LARGE_ROOT=3,
|
|
92
|
+
FLATSQL_RANGE_FMB=4, FLATSQL_RANGE_FCK=5, FLATSQL_RANGE_FSG=6, FLATSQL_RANGE_LINK=7 };
|
|
93
|
+
enum { FLATSQL_CLASS_WRITE = 1, FLATSQL_CLASS_INTERACTIVE = 2, FLATSQL_CLASS_BULK = 3, FLATSQL_CLASS_SANDBOX = 4,
|
|
94
|
+
FLATSQL_CLASS_MAINTENANCE = 5 };
|
|
95
|
+
enum { FLATSQL_SLOT_FREE = 0, FLATSQL_SLOT_CLAIMED = 1, FLATSQL_SLOT_QUEUED = 2, FLATSQL_SLOT_RUNNING = 3, FLATSQL_SLOT_DONE = 5 };
|
|
96
|
+
enum { FLATSQL_ACT_REJECTED = 0, FLATSQL_ACT_NEW = 1, FLATSQL_ACT_COPY = 2, FLATSQL_ACT_RETAG = 3, FLATSQL_ACT_DUP = 4,
|
|
97
|
+
FLATSQL_ACT_IDENT_DUP = 5, FLATSQL_ACT_MIGRATED = 6 };
|
|
98
|
+
|
|
99
|
+
/* ---- §3.4 The mailbox ------------------------------------------------------ */
|
|
100
|
+
|
|
101
|
+
#define FLATSQL_LAYOUT_VERSION 1
|
|
102
|
+
#define FLATSQL_SLOT_HEADER 448
|
|
103
|
+
typedef struct FlatSQLLayout {
|
|
104
|
+
uint32_t version; /* 0: 1 */
|
|
105
|
+
uint32_t size; /* 4: 640 */
|
|
106
|
+
uint32_t headerSize; /* 8: 448 */
|
|
107
|
+
uint32_t stopWord; /* 12: address of the u32 stop word */
|
|
108
|
+
uint32_t nSlots[2]; /* 16: [0] write pool, [1] read pool */
|
|
109
|
+
uint32_t slotBase[2]; /* 24 */
|
|
110
|
+
uint32_t slotStride[2]; /* 32: headerSize + reqBytes + ringBytes, 64-aligned */
|
|
111
|
+
uint32_t reqBytes[2]; /* 40 */
|
|
112
|
+
uint32_t ringBytes[2]; /* 48: powers of two */
|
|
113
|
+
uint32_t queueCells[4]; /* 56: per class, index = class-1 */
|
|
114
|
+
uint32_t queueMask[4]; /* 72 */
|
|
115
|
+
uint32_t queueEnq[4]; /* 88: address of the u64 enqueue counter */
|
|
116
|
+
uint32_t queueDeq[4]; /* 104: address of the u64 dequeue counter */
|
|
117
|
+
uint32_t nThreads; /* 120: service threads (writers, lanes, maintenance), <= 64 */
|
|
118
|
+
uint32_t rsv; /* 124: 0 */
|
|
119
|
+
uint32_t threadClass[64]; /* 128: 1 write, 2 interactive, 3 bulk, 4 sandbox, 5 maintenance */
|
|
120
|
+
uint32_t doorbell[64]; /* 384: address of the thread's doorbell u32; its state u32 is at doorbell+4
|
|
121
|
+
(0 idle, 1 busy, 2 stopped) */
|
|
122
|
+
} FlatSQLLayout;
|
|
123
|
+
|
|
124
|
+
/* Slot header byte offsets (version 1). */
|
|
125
|
+
enum {
|
|
126
|
+
FLATSQL_SLOT_OFF_STATE = 0, FLATSQL_SLOT_OFF_CANCEL = 4, FLATSQL_SLOT_OFF_OUTSEQ = 8, FLATSQL_SLOT_OFF_SPACESEQ = 12,
|
|
127
|
+
FLATSQL_SLOT_OFF_OP = 16, FLATSQL_SLOT_OFF_CLASS = 20, FLATSQL_SLOT_OFF_FLAGS = 24, FLATSQL_SLOT_OFF_REQLEN = 28,
|
|
128
|
+
FLATSQL_SLOT_OFF_REQID = 32, FLATSQL_SLOT_OFF_MAX_ROWS_EXAMINED = 40, FLATSQL_SLOT_OFF_MAX_BYTES_READ = 48,
|
|
129
|
+
FLATSQL_SLOT_OFF_MAX_RESULT_ROWS = 56, FLATSQL_SLOT_OFF_MAX_RESULT_BYTES = 64, FLATSQL_SLOT_OFF_RING_HEAD = 72,
|
|
130
|
+
FLATSQL_SLOT_OFF_RING_TAIL = 80, FLATSQL_SLOT_OFF_STATUS = 88, FLATSQL_SLOT_OFF_ERRLEN = 92, FLATSQL_SLOT_OFF_ROWS_OUT = 96,
|
|
131
|
+
FLATSQL_SLOT_OFF_ROWS_EXAMINED = 104, FLATSQL_SLOT_OFF_BYTES_READ = 112, FLATSQL_SLOT_OFF_SUBMIT_NS = 120,
|
|
132
|
+
FLATSQL_SLOT_OFF_START_NS = 128, FLATSQL_SLOT_OFF_END_NS = 136, FLATSQL_SLOT_OFF_ERR = 144, FLATSQL_SLOT_ERR_CAP = 256,
|
|
133
|
+
FLATSQL_SLOT_OFF_THREAD = 400
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/* ---- §3.3 Exports (exact) ------------------------------------------------ */
|
|
137
|
+
|
|
138
|
+
FLATSQL_EXPORT("flatsql_init") int32_t flatsql_init(const uint8_t* cfg, int32_t cfgLen);
|
|
139
|
+
FLATSQL_EXPORT("flatsql_start") int32_t flatsql_start(void); /* >= 0: threads started */
|
|
140
|
+
FLATSQL_EXPORT("flatsql_layout") int32_t flatsql_layout(FlatSQLLayout* out); /* bytes written = 640 */
|
|
141
|
+
FLATSQL_EXPORT("flatsql_wake") int32_t flatsql_wake(uint32_t* addr, int32_t n); /* memory.atomic.notify; woken count */
|
|
142
|
+
FLATSQL_EXPORT("flatsql_register_type") int32_t flatsql_register_type(const uint8_t* spec, int32_t specLen);
|
|
143
|
+
FLATSQL_EXPORT("flatsql_set_quota") int32_t flatsql_set_quota(double bytes); /* 0 = none */
|
|
144
|
+
FLATSQL_EXPORT("flatsql_activate") int32_t flatsql_activate(void); /* create mode 2 only */
|
|
145
|
+
FLATSQL_EXPORT("flatsql_stats") int32_t flatsql_stats(uint8_t* out, int32_t cap); /* bytes written; u64 LE array §3.10 */
|
|
146
|
+
FLATSQL_EXPORT("flatsql_stop") int32_t flatsql_stop(double deadlineMs); /* FLATSQL_OK, or FLATSQL_E_BUSY at the deadline */
|
|
147
|
+
FLATSQL_EXPORT("flatsql_alloc") void* flatsql_alloc(int32_t n); /* wasm only */
|
|
148
|
+
FLATSQL_EXPORT("flatsql_free") void flatsql_free(void* p); /* wasm only */
|
|
149
|
+
|
|
150
|
+
/* Prepare a PUT or DELETE mailbox request from an unchanged stream of size-prefixed
|
|
151
|
+
* records. Metadata is the control TLV (type, producer, source tags, timestamp;
|
|
152
|
+
* tag 55: u32 signature count, then u16 length + bytes per PUT record).
|
|
153
|
+
* CID computation stays in the guest. Returns status and an allocated buffer.
|
|
154
|
+
* Caller frees *output with flatsql_free. */
|
|
155
|
+
FLATSQL_EXPORT("flatsql_record_request") int32_t flatsql_record_request(
|
|
156
|
+
int32_t opcode, const uint8_t* frames, int32_t size, const uint8_t* metadata, int32_t metadataSize, uint8_t** output, uint32_t* outLen);
|
|
157
|
+
|
|
158
|
+
#ifdef __cplusplus
|
|
159
|
+
}
|
|
160
|
+
#endif
|
|
161
|
+
|
|
162
|
+
#endif
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#ifndef FLATSQL_IO_H
|
|
2
|
+
#define FLATSQL_IO_H
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* FlatSQL host I/O contract — SEVEN imports, one contract, every host.
|
|
6
|
+
* =====================================================================
|
|
7
|
+
*
|
|
8
|
+
* FlatSQL does not use emscripten's filesystem and does not use WASI file
|
|
9
|
+
* descriptors. It registers its OWN sqlite3_vfs ("flatsql_io") whose methods
|
|
10
|
+
* call out through the seven functions declared below. Every host — the
|
|
11
|
+
* browser JS shim, the standalone WASI shim, WasmEdge/wazero in the Go node —
|
|
12
|
+
* satisfies the SAME seven names with the SAME signatures. There is no runtime
|
|
13
|
+
* detection anywhere in module code; the difference between a browser
|
|
14
|
+
* key->bytes store and a real POSIX file lives entirely in the host shim.
|
|
15
|
+
* See docs/STORAGE-DURABILITY.md §3.5.
|
|
16
|
+
*
|
|
17
|
+
* WHY NOT WASI path_open: MEASURED (§3.5). `-s WASMFS=1` routes file I/O to an
|
|
18
|
+
* in-memory backend that looks durable and is not; `-s FORCE_FILESYSTEM=1`
|
|
19
|
+
* emits ten emscripten `__syscall_*` imports that no host satisfies and still
|
|
20
|
+
* never emits path_open. Both were reverted.
|
|
21
|
+
*
|
|
22
|
+
* SIGNATURE LAW — i32 and f64 ONLY.
|
|
23
|
+
* Offsets and sizes are `double`, never `int64_t`. Emscripten legalizes i64 at
|
|
24
|
+
* the JS boundary for the browser target (splitting one i64 parameter into two
|
|
25
|
+
* i32s) but NOT for STANDALONE_WASM. An i64 in this contract would therefore
|
|
26
|
+
* give the two lanes genuinely different wasm signatures for the same function
|
|
27
|
+
* name — the exact divergence class this design exists to prevent. f64 is
|
|
28
|
+
* exact to 2^53 (9 PB), passes through JS unmodified, and is identical in
|
|
29
|
+
* every lane.
|
|
30
|
+
*
|
|
31
|
+
* ERROR LAW: errors are return values, never traps. The -fignore-exceptions
|
|
32
|
+
* WASI artifact turns any throw into a guest-poisoning `unreachable`
|
|
33
|
+
* (commit b26ed45), so nothing below may throw.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
#include <stdint.h>
|
|
37
|
+
|
|
38
|
+
/* ---- open flags ------------------------------------------------------- */
|
|
39
|
+
#define FLATSQL_IO_READ 0x0001
|
|
40
|
+
#define FLATSQL_IO_WRITE 0x0002
|
|
41
|
+
#define FLATSQL_IO_CREATE 0x0004
|
|
42
|
+
#define FLATSQL_IO_EXCL 0x0008
|
|
43
|
+
#define FLATSQL_IO_TRUNC 0x0010
|
|
44
|
+
/* Advisory: the host may drop the file when the handle is closed. */
|
|
45
|
+
#define FLATSQL_IO_DELETE_ON_CLOSE 0x0020
|
|
46
|
+
|
|
47
|
+
/* Namespace operations. These are carried on `open` rather than spent as two
|
|
48
|
+
* more imports: a VFS needs xAccess and xDelete, and both are pure
|
|
49
|
+
* path->status questions that allocate no handle. With either bit set,
|
|
50
|
+
* flatsql_io_open returns a STATUS (0 = success/exists, negative = error or
|
|
51
|
+
* absent) and no handle is created. Hosts must not allocate for them. */
|
|
52
|
+
#define FLATSQL_IO_PROBE 0x0040 /* xAccess: does the path exist? */
|
|
53
|
+
#define FLATSQL_IO_UNLINK 0x0080 /* xDelete: remove the path */
|
|
54
|
+
|
|
55
|
+
/* Partition store flags (docs/PARTITION-STORE.md §5.4, design A12/A38).
|
|
56
|
+
* They are flags, not imports: the import set stays seven. The values are the
|
|
57
|
+
* ones every space-data-module-sdk host implements (module-sdk 0.8.22,
|
|
58
|
+
* docs/isomorphic-pthreads.md "Flags and statuses"); they must not diverge.
|
|
59
|
+
*
|
|
60
|
+
* CREATE_PARENTS: create every missing parent directory (fsyncing the parent
|
|
61
|
+
* of each one created) and, when the file itself is newly created, fsync its
|
|
62
|
+
* parent directory before returning. Best effort on OPFS.
|
|
63
|
+
* UNLINK_IF_UNUSED: unlink, or FLATSQL_IO_ERR_BUSY while any handle names the
|
|
64
|
+
* path. After a successful unlink a POSIX host fsyncs the parent directory.
|
|
65
|
+
* (A plain UNLINK of an open path is BUSY on OPFS and allowed on POSIX: the
|
|
66
|
+
* engine never unlinks a path it holds open.)
|
|
67
|
+
* OPEN_DEFERRED: return a handle before the open finishes; the first use
|
|
68
|
+
* waits, or fails with the open's status. Synchronous hosts treat it as a
|
|
69
|
+
* plain open. */
|
|
70
|
+
#define FLATSQL_IO_CREATE_PARENTS 0x0100
|
|
71
|
+
#define FLATSQL_IO_UNLINK_IF_UNUSED 0x0200
|
|
72
|
+
#define FLATSQL_IO_OPEN_DEFERRED 0x0400
|
|
73
|
+
|
|
74
|
+
/* ---- status codes (all negative; every call may return any of them) ---- */
|
|
75
|
+
#define FLATSQL_IO_ERR_GENERIC (-1)
|
|
76
|
+
#define FLATSQL_IO_ERR_NOENT (-2)
|
|
77
|
+
#define FLATSQL_IO_ERR_ACCESS (-3)
|
|
78
|
+
#define FLATSQL_IO_ERR_IO (-4)
|
|
79
|
+
#define FLATSQL_IO_ERR_NOSPACE (-5)
|
|
80
|
+
#define FLATSQL_IO_ERR_BADHANDLE (-6)
|
|
81
|
+
#define FLATSQL_IO_ERR_BUSY (-7) /* path in use, or its lock held elsewhere */
|
|
82
|
+
/* EEXIST (CREATE|EXCL on an existing path) maps to GENERIC on every host. */
|
|
83
|
+
|
|
84
|
+
#if defined(__wasm__)
|
|
85
|
+
# define FLATSQL_IO_IMPORT(name) \
|
|
86
|
+
__attribute__((import_module("env"), import_name(name)))
|
|
87
|
+
#else
|
|
88
|
+
# define FLATSQL_IO_IMPORT(name)
|
|
89
|
+
#endif
|
|
90
|
+
|
|
91
|
+
#ifdef __cplusplus
|
|
92
|
+
extern "C" {
|
|
93
|
+
#endif
|
|
94
|
+
|
|
95
|
+
/* Open (or probe/unlink) `path`. Returns a non-negative opaque handle, or a
|
|
96
|
+
* negative status. `pathLen` is explicit: hosts never scan for NUL. */
|
|
97
|
+
FLATSQL_IO_IMPORT("flatsql_io_open")
|
|
98
|
+
int32_t flatsql_io_open(const char* path, int32_t pathLen, int32_t flags);
|
|
99
|
+
|
|
100
|
+
/* Offset-addressed read. Returns bytes actually read (may be < len at EOF), or
|
|
101
|
+
* a negative status. Never moves an implicit cursor — there isn't one. */
|
|
102
|
+
FLATSQL_IO_IMPORT("flatsql_io_read")
|
|
103
|
+
int32_t flatsql_io_read(int32_t handle, void* dst, int32_t len, double offset);
|
|
104
|
+
|
|
105
|
+
/* Offset-addressed write. Writing past EOF extends the file (the gap reads as
|
|
106
|
+
* zeroes). Returns bytes written or a negative status. */
|
|
107
|
+
FLATSQL_IO_IMPORT("flatsql_io_write")
|
|
108
|
+
int32_t flatsql_io_write(int32_t handle, const void* src, int32_t len,
|
|
109
|
+
double offset);
|
|
110
|
+
|
|
111
|
+
/* Set the file length exactly (grow or shrink). */
|
|
112
|
+
FLATSQL_IO_IMPORT("flatsql_io_truncate")
|
|
113
|
+
int32_t flatsql_io_truncate(int32_t handle, double size);
|
|
114
|
+
|
|
115
|
+
/* Durability barrier. Returns 0 only when prior writes are durable. */
|
|
116
|
+
FLATSQL_IO_IMPORT("flatsql_io_sync")
|
|
117
|
+
int32_t flatsql_io_sync(int32_t handle);
|
|
118
|
+
|
|
119
|
+
/* Current length in bytes, or a negative status. */
|
|
120
|
+
FLATSQL_IO_IMPORT("flatsql_io_size")
|
|
121
|
+
double flatsql_io_size(int32_t handle);
|
|
122
|
+
|
|
123
|
+
/* Release the handle. */
|
|
124
|
+
FLATSQL_IO_IMPORT("flatsql_io_close")
|
|
125
|
+
int32_t flatsql_io_close(int32_t handle);
|
|
126
|
+
|
|
127
|
+
#ifdef __cplusplus
|
|
128
|
+
} /* extern "C" */
|
|
129
|
+
|
|
130
|
+
namespace flatsql {
|
|
131
|
+
|
|
132
|
+
/* Name of the VFS registered over the seven imports above. */
|
|
133
|
+
extern const char* const kFlatSqlVfsName; /* "flatsql_io" */
|
|
134
|
+
|
|
135
|
+
/* Idempotent. Registers the VFS with SQLite. `makeDefault` decides whether an
|
|
136
|
+
* open with a NULL vfs name lands here. Returns SQLITE_OK on success. Never
|
|
137
|
+
* throws. */
|
|
138
|
+
int registerFlatSqlIoVfs(bool makeDefault);
|
|
139
|
+
|
|
140
|
+
/* Connections opened with the URI parameter ra=1 read ahead sequentially:
|
|
141
|
+
* up to `streams` streams per connection (1..8, default 2), `bytes` per
|
|
142
|
+
* read-ahead (default 1 MiB). Applies to reads after the call. */
|
|
143
|
+
void setFlatSqlIoReadahead(int streams, int bytes);
|
|
144
|
+
|
|
145
|
+
/* Process-wide VFS counters. */
|
|
146
|
+
struct FlatSqlIoVfsStats {
|
|
147
|
+
int64_t walIndexBytes; /* heap WAL-index regions mapped now */
|
|
148
|
+
int64_t walIndexBytesPeak;
|
|
149
|
+
int64_t readaheadReads; /* host reads issued by readahead */
|
|
150
|
+
int64_t readaheadHits; /* SQLite reads served from readahead buffers */
|
|
151
|
+
int64_t readaheadBytes;
|
|
152
|
+
int64_t nodes; /* paths with an open database file */
|
|
153
|
+
};
|
|
154
|
+
FlatSqlIoVfsStats flatSqlIoVfsStats();
|
|
155
|
+
|
|
156
|
+
} /* namespace flatsql */
|
|
157
|
+
#endif /* __cplusplus */
|
|
158
|
+
|
|
159
|
+
#endif /* FLATSQL_IO_H */
|
package/docs/API-3.12.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# FlatSQL 3.12 binary API
|
|
2
|
+
|
|
3
|
+
FlatSQL has one public JavaScript entry point, `flatsql`, exporting `FlatSQL`
|
|
4
|
+
and `FlatSQLError`, and one native ABI, `cpp/include/flatsql/flatsql.h`.
|
|
5
|
+
`flatsql/flatsql.wasm` identifies the same WASI threads artifact on every host.
|
|
6
|
+
There are no PS/P4 selectors, old engine aliases, or compatibility modes.
|
|
7
|
+
|
|
8
|
+
## Schemas, records, and queries
|
|
9
|
+
|
|
10
|
+
- `FlatSQL.open(options)` opens persistent host storage. Node `root` is a
|
|
11
|
+
filesystem directory; browser `root` is an OPFS directory. Node without a
|
|
12
|
+
root creates a temporary store. `close()` drains/cancels operations and stops
|
|
13
|
+
the engine. Close an instance before opening the same directory again.
|
|
14
|
+
- `registerSchema({name, fileIdentifier, bfbs, ...})` registers a binary
|
|
15
|
+
reflection schema. Type names are SQL identifiers, up to 64 characters; the
|
|
16
|
+
file identifier is four bytes. Indexed extraction rules and full-text
|
|
17
|
+
indexing are schema configuration, executed inside the guest.
|
|
18
|
+
- `ingest(type, records, metadata)` accepts concatenated frames:
|
|
19
|
+
`[u32 little-endian payload length][FlatBuffer payload]`. The guest validates
|
|
20
|
+
records, computes identities, persists streams and updates indexes. Provider,
|
|
21
|
+
source, producer, batch and timestamp metadata are optional. `signatures`
|
|
22
|
+
supplies one opaque byte array per record, retained in `_signature`.
|
|
23
|
+
- `remove(type, records)` deletes those original binary payloads and returns a
|
|
24
|
+
QRP receipt. Record hashing and deletion stay inside the engine.
|
|
25
|
+
- `query(request, options)` returns an async stream of byte chunks; `execute`
|
|
26
|
+
collects it within a byte budget. Requests are canonical SDS QRP buffers,
|
|
27
|
+
optionally size-prefixed, with `KIND=Request` and `REPRESENTATION=FlatBuffer`
|
|
28
|
+
(or their schema defaults). `SQL` and `PARAMETERS` drive the query. Express
|
|
29
|
+
filters, sort, selection, and paging in SQL; unrelated QRP selection fields
|
|
30
|
+
are rejected instead of silently ignored.
|
|
31
|
+
- Projection output is a stream of size-prefixed SDS QRP pages: column names,
|
|
32
|
+
typed rows, and a final summary containing counts, status and truncation.
|
|
33
|
+
Chunk boundaries need not coincide with frame boundaries. QRP null, integer,
|
|
34
|
+
float, text and bytes preserve SQLite values; boolean parameters bind as
|
|
35
|
+
SQLite integers 0/1. Integers remain signed 64-bit values.
|
|
36
|
+
- `SELECT _data` with `{records:true}` streams original record frames unchanged.
|
|
37
|
+
IDs, properties, altitude, null geometry and bounding boxes are preserved
|
|
38
|
+
byte for byte. Derived geometry has the separate semantics below.
|
|
39
|
+
- With `registerSchema({..., fullText:true})`, SQL `_search MATCH ?1` uses the
|
|
40
|
+
engine's FTS5 index over the record's text fields, including nested text.
|
|
41
|
+
The engine returns `BUSY` while its background index catches up; retry the
|
|
42
|
+
query, and never treat that condition as zero matches.
|
|
43
|
+
- Hidden metadata columns `_cid`, `_seq`, `_ts`, `_epoch`, `_producer`, `_peer`
|
|
44
|
+
and `_signature` are available alongside `_source`, `_rowid` and `_data`.
|
|
45
|
+
- Root scalar/string/byte-vector fields are exposed by BFBS reflection.
|
|
46
|
+
Complex/nested fields remain in `_data`. Unsigned integers above the SQLite
|
|
47
|
+
signed 64-bit range produce an error; retrieve `_data` to preserve them.
|
|
48
|
+
- `surface()` returns the SQL catalog in QRP pages. `setQuota(bytes)` changes the
|
|
49
|
+
disk budget; zero removes that budget. Low-level mailbox maintenance and
|
|
50
|
+
storage controls are documented in the C header, behind the same engine.
|
|
51
|
+
|
|
52
|
+
`QueryOptions` provides cancellation (`AbortSignal`), elapsed timeout,
|
|
53
|
+
rows/result bytes, rows examined, bytes read, and bulk/sandbox lane selection.
|
|
54
|
+
QRP `MAX_ROWS`, `LIMIT`, `MAX_BYTES`, and `MAX_ELAPSED_MS` are enforced by the
|
|
55
|
+
engine. Breaking a stream cancels and drains its lane before its slot is reused.
|
|
56
|
+
`execute` defaults to a 16 MiB collected result budget, with bounded room for
|
|
57
|
+
terminal framing. A budget failure throws `FlatSQLError`; already streamed
|
|
58
|
+
chunks are partial, never a successful complete answer.
|
|
59
|
+
|
|
60
|
+
The data boundary accepts `Uint8Array`, not JavaScript rows or SQL strings.
|
|
61
|
+
The package does not parse or render JSON, GeoJSON or WKT, compile schema text,
|
|
62
|
+
or provide the SQLite JSON extension. Manifest JSON is tooling metadata.
|
|
63
|
+
Convert separately with flatc-wasm or generated SDS bindings. Private packed
|
|
64
|
+
control messages configure memory and files; they do not carry a second public
|
|
65
|
+
record or SQL result format.
|
|
66
|
+
|
|
67
|
+
## Geometry
|
|
68
|
+
|
|
69
|
+
Geometry arguments are canonical SDS GJN (`$GJN`, root `GJN`) FlatBuffers,
|
|
70
|
+
provided as a payload or one size-prefixed frame. Results are GJN payloads in
|
|
71
|
+
QRP `Bytes` values. Every result verifies against the same SDS schema. No
|
|
72
|
+
custom geometry blob or JSON parser exists inside the engine.
|
|
73
|
+
|
|
74
|
+
All seven GJN geometry kinds are decoded, including multi-geometries and
|
|
75
|
+
collections. Multiple features are evaluated as a collection; null feature
|
|
76
|
+
geometries contribute no points. SQL NULL propagates. Malformed buffers,
|
|
77
|
+
non-finite positions, open polygon rings, and unsupported combinations produce
|
|
78
|
+
SQL errors. Properties remain opaque, including SDS `JSON_VALUE` strings.
|
|
79
|
+
|
|
80
|
+
| Function | Behavior |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `geo_distance`, `geo_within_radius`, `geo_bearing` | Spherical calculations; distances/radii in kilometers, coordinates in latitude/longitude order. |
|
|
83
|
+
| `geo_bbox_contains`, `geo_area_bbox` | Scalar bounding-box predicates and spherical area. |
|
|
84
|
+
| `geo_contains(g,lat,lon)` | Point/polygon membership, including polygon holes and collection members. |
|
|
85
|
+
| `geo_area_geom(g)` | Sum of planar polygon areas minus holes, in square degrees. Non-area members contribute zero. |
|
|
86
|
+
| `geo_length_geom(g)` | Haversine line length in kilometers; collection members contribute their lengths. |
|
|
87
|
+
| `geo_envelope(g)`, `geo_convex_hull(g)` | Two-dimensional envelope/hull over every member's coordinates. |
|
|
88
|
+
| `geo_centroid(g)` | Planar centroid, weighted by polygon area minus holes, then line length, then point count. Highest-dimensional members contribute; empty/degenerate input returns NULL. |
|
|
89
|
+
| `geo_intersection`, `geo_union`, `geo_difference`, `geo_sym_difference` | Convex, hole-free polygon operands, either winding. Exact clipped pieces; concave or holed operands are rejected. Results may contain multiple polygon pieces with touching boundaries. |
|
|
90
|
+
| `geo_buffer(g,d)` | Point buffer with positive distance in degrees, approximated by a 16-segment circle. Other geometry kinds are rejected. |
|
|
91
|
+
| `geo_voronoi`, `geo_delaunay` | Point/multipoint sites in the longitude/latitude plane. Voronoi bounds must be a convex, hole-free polygon. |
|
|
92
|
+
| `geo_destination`, `geo_midpoint` | GJN point results from spherical calculations. |
|
|
93
|
+
| `geo_to_ecef_x/y/z(lat,lon,alt)` | Separate numeric Cartesian components in meters; altitude input is meters. |
|
|
94
|
+
| `geo_from_ecef(x,y,z)` | GJN point with WGS84 longitude, latitude and altitude in meters. |
|
|
95
|
+
|
|
96
|
+
Derived map geometry is explicitly 2D: it contains newly computed coordinates
|
|
97
|
+
and no feature IDs, properties, source bbox or altitude. `geo_from_ecef` computes
|
|
98
|
+
altitude. Scalar map measurements ignore altitude. Original record queries
|
|
99
|
+
preserve the complete original 3D record. Geometry computations are planar
|
|
100
|
+
unless explicitly described as spherical; they do not unwrap antimeridian
|
|
101
|
+
crossings or act as a global spherical topology engine.
|
|
102
|
+
|
|
103
|
+
## Integrity and hosts
|
|
104
|
+
|
|
105
|
+
Default loads verify the adjacent `integrity.json`: browser Fetch SRI and Node
|
|
106
|
+
SHA-256. Supplying `wasmBytes` requires a verification callback, allowing a host
|
|
107
|
+
to enforce its signed artifact policy before instantiation. Generic adapters
|
|
108
|
+
provide threads, memory, filesystem I/O and transport; query, geometry, indexing,
|
|
109
|
+
and record identity logic stay inside C++/WASM.
|
|
110
|
+
|
|
111
|
+
Browser hosting requires shared memory and cross-origin isolation. Worker URLs
|
|
112
|
+
can be supplied explicitly for bundlers. The distributed private runtime
|
|
113
|
+
adapters bundle only the necessary published SDK host code and its license;
|
|
114
|
+
they do not bring the SDK's legacy FlatSQL dependency into the package.
|