@vortex-rdf/vortex-rdf-store 0.3.0 → 0.5.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.
Files changed (2) hide show
  1. package/README.md +39 -0
  2. package/package.json +9 -2
package/README.md CHANGED
@@ -212,6 +212,45 @@ npm test
212
212
 
213
213
  There's no separate Node-targeted wasm build to maintain.
214
214
 
215
+ Types are checked separately from the build, since `wasm-pack` doesn't run `tsc`:
216
+
217
+ ```bash
218
+ npm run typecheck # tests and benchmarks, both against the published API
219
+ ```
220
+
221
+ ## Benchmarks
222
+
223
+ Three surfaces, kept separate because they answer different questions and are trustworthy in different ways. All require `npm run build` first.
224
+
225
+ | Command | Question | Output |
226
+ | --- | --- | --- |
227
+ | `npm run bench` | How do we compare to other JS RDF stores? | `bench/results.json`, rendered to the dashboard |
228
+ | `npm run bench:codspeed` | Did this PR regress anything? | uploaded to CodSpeed |
229
+ | `npm run bench:dict-memory` | Where is wasm memory actually going? | printed; `bench/dict-memory.json` |
230
+
231
+ **`npm run bench`** runs each store — the Vortex build variants, [rdf-stores.js](https://github.com/rubensworks/rdf-stores.js), and [oxigraph](https://github.com/oxigraph/oxigraph) — through the same query, mutation, and serialization workload, one adapter per child process so peak RSS is attributable and no store's garbage taints another's timings. It is wall-clock, so it is only as stable as the machine it runs on; it is deliberately **not** uploaded to CodSpeed. `scripts/render_bench_dashboard.py` turns its `results.json` plus a `cargo bench --bench benchmark` run into `public/index.html`.
232
+
233
+ The dataset is generated by `genDataset` in [bench/shared.ts](bench/shared.ts), with term cardinality as an explicit knob — real RDF has terms scaling with rows, and a generator that draws millions of quads from a handful of IRIs makes every store's term handling invisible. Tunable by env var:
234
+
235
+ | Var | Default | Meaning |
236
+ | --- | --- | --- |
237
+ | `BENCH_DIM` | 128 | triples dataset is `D³` rows |
238
+ | `BENCH_DIM_QUADS` | 32 | quads dataset is `Dq⁴` rows |
239
+ | `BENCH_SUBJ_RATIO` | 0.1 | distinct subjects / rows — the reciprocal of triples per subject |
240
+ | `BENCH_OBJ_RATIO` | 0.5 | distinct objects / rows |
241
+ | `BENCH_PREDICATES` | 32 | distinct predicates (a closed vocabulary) |
242
+ | `BENCH_GRAPHS` | 1 | distinct named graphs; 1 means default graph only |
243
+ | `BENCH_LITERAL_FRAC` | 0.4 | fraction of objects that are literals |
244
+ | `MUT_BATCH` | 10000 | quads per add/delete batch |
245
+
246
+ The two ratios decide how much of the dataset is *terms*: the dictionary holds `subjectRatio + objectRatio` of them per quad. At the defaults that is 2,097,152 triples over ~1.26M distinct terms, ten triples describing each subject, and probes spanning five orders of magnitude of selectivity (1 row for a fully-bound pattern, ~10 for a subject, ~3% for a predicate).
247
+
248
+ `BENCH_SUBJ_RATIO=1.0` gives every row its own subject, which puts more distinct terms in the dictionary than there are rows. That is a useful dictionary-stress configuration — it is what `bench:dict-memory` asks for — but a poor default for the comparison: it makes five of the seven probes match two rows or fewer, so the timings become almost entirely query setup with the decode path barely exercised.
249
+
250
+ Each adapter process peaks at 3–6 GB — check available memory before running, because a swapping run produces numbers that look like regressions.
251
+
252
+ **`npm run bench:dict-memory`** is the only instrument that can attribute wasm memory; `peakRssMb` in the comparative run is the right cross-library number but cannot say *what* holds the memory. Wasm linear memory never shrinks, so it works by differentials — several stores held live at once, memory read after each, slope against store count — and every config runs in its own process. It defaults to a single config as a regression check against the figures recorded when FSST landed; passing several `DICT_MEM_RATIOS` sweeps term cardinality instead and fits the per-term cost. The header of [bench/dict-memory.bench.ts](bench/dict-memory.bench.ts) documents the method and the invocations.
253
+
215
254
  ## License
216
255
 
217
256
  MIT
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@vortex-rdf/vortex-rdf-store",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "High-performance, zero-copy columnar RDF serialization format",
5
5
  "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/vortex-rdf/vortex-rdf.git",
9
+ "directory": "js"
10
+ },
6
11
  "publishConfig": {
7
12
  "access": "public"
8
13
  },
@@ -35,9 +40,11 @@
35
40
  "build:fast": "npm run build:wasm:fast && npm run build:clean-manifest",
36
41
  "prepublishOnly": "npm run build",
37
42
  "test": "vitest run",
43
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.bench.json",
38
44
  "bench": "tsx --expose-gc --max-old-space-size=8192 bench/compare.bench.ts",
39
45
  "bench:build": "npm run build && npm run bench",
40
- "bench:codspeed": "tsx --expose-gc bench/codspeed.bench.ts"
46
+ "bench:codspeed": "tsx --expose-gc bench/codspeed.bench.ts",
47
+ "bench:dict-memory": "tsx --expose-gc bench/dict-memory.bench.ts"
41
48
  },
42
49
  "keywords": [
43
50
  "rdf",