Versions and Compatibility - SmithSoft-Studios/JAZMIN GitHub Wiki
Versions and Compatibility
The JavaScript and .NET libraries share one version number, and every release of both reads and writes the same files. The file format has its own version: every 1.x release writes format 1.0.
| Release | Date | Format | Highlights |
|---|---|---|---|
| 1.7.1 | 2026-10-17 | 1.0 | Fixes (viewer): the npm package's viewer has its icons, manifest and offline files; page tabs follow jazmin.navigate(). estimate() in the browser reader |
| 1.7.0 | 2026-10-16 | 1.0 | Long reads and rewrites report progress and can be stopped; estimate() before a read; reading last first (reverse: true); sort orders that ignore case or compare numbers by value; large rewrites in bounded memory; a smaller browser script in parts; in shared files, stored files locked behind a password or a key service's 2FA, and masked columns the viewer reveals one value at a time; list: false and actions by file group; documents that need the internet (package.online); document pages, shown as tabs (package.pages) |
| 1.6.2 | 2026-10-15 | 1.0 | Fix (JavaScript): a sorted index on a column with more than about 8 million distinct values in no particular order ("Map maximum size exceeded") |
| 1.6.1 | 2026-10-15 | 1.0 | Fix: applying a change file to a shared file of several tables checks the sender against the table the document edits; sample key service without the owner key; two-factor demo |
| 1.6.0 | 2026-10-14 | 1.0 | Change a file you have in one rewrite: add, rename and remove tables, change indexes and the sort order, re-key across tables (set + where); links between tables kept in the file and checked; reader.storage(); documents read several tables; fileSubmission(); readerFeatures; .NET LINQ array.Contains on .NET 10 |
| 1.5.0 | 2026-10-11 | 1.0 | Export shapes saved in the file, each key seeing only those it can use; JavaScript queries with arrow functions (from()) that the indexes answer; exports and shapes in the browser and the viewer; the viewer opens files from disk and shows a filter's first rows at once; a demo gallery and a Blazor sample |
| 1.4.0 | 2026-10-09 | 1.0 + reader feature nested-columns |
Nested columns (opt-in): lists and objects stored as columns of their fields, filtered with any, all and match; print-ready and editable documents, with change files; text search twice as fast with a third of the memory; lookups as fast as SQLite once warm; Node writes indexed files with half the memory; .NET LINQ compiled once per query shape |
| 1.3.0 | 2026-10-08 | 1.0 | Export shapes across tables ($from, $on, $one); filtered queries decode returned columns only for matching rows; fast long in lists; .NET LINQ reads only the columns a query uses, sub-queries once, and JSON columns straight into your types; Node shapes 2–2.6× faster |
| 1.2.0 | 2026-10-08 | 1.0 | Memory-or-speed priority; rotateKey and rotateOwnerKey; .NET AsQueryable<T>(); serving embedded files and rendering PDFs; Jazmin.AspNetCore; opt-in compact indexes; streaming CSV and XML import; .NET JSON streams and tokens |
| 1.1.0 | 2026-10-06 | 1.0 | Records sent back from phones (submission keys, browser writer, filing service); columnArrays; advise; explain with analyze; the jazmin CLI; openUrl; compact({ regroup }) |
| 1.0.0 | 2026-10-04 | 1.0 | The first published release |
Releases before 1.0.0 (0.1–0.3) wrote pre-release draft formats. Current readers refuse those files with "This file uses a pre-release JAZMIN draft format": write them again from their source data.
Can this version read that file?
| File written by | Read by 1.0.x | Read by 1.1.x | Read by 1.2.x | Read by 1.3.x | Read by 1.4.x | Read by 1.5.x | Read by 1.6.x | Read by 1.7.x |
|---|---|---|---|---|---|---|---|---|
| 1.0.x | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| 1.1.x | ✔ (owner-only extras skipped) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| 1.2.x to 1.5.x, default options | ✔ | ✔ (reads and appends) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
1.2.x to 1.5.x with compactIndexes: true |
✘ refused, naming index-deltas |
✘ refused, naming index-deltas |
✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| 1.4.x and 1.5.x with nested columns | ✘ refused ("unknown type") | ✘ refused ("unknown type") | ✘ refused ("unknown type") | ✘ refused ("unknown type") | ✔ | ✔ | ✔ | ✔ |
| 1.5.x with saved shapes | ✔ (no shapes) | ✔ (no shapes) | ✔ (no shapes) | ✔ (no shapes) | ✔ (no shapes) | ✔ | ✔ | ✔ |
1.7.x with other text orders, list: false, actions by file group, keyService or online |
✔ (the order's plain part; the settings ignored) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ |
| 1.7.x with locked files | ✔ (locked files refused; don't append) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ |
| 1.7.x with masked columns | ✔ (masked columns never shown) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ (as 1.0.x) | ✔ |
1.3.0 adds nothing to the format: 1.2.0 reads the files it writes, and it reads 1.2.0's (tested with the published packages).
Which versions read a file: from 1.6.0, reader.readerFeatures (.NET reader.ReaderFeatures) lists the
reader features a file needs, such as index-deltas or nested-columns, and jazmin inspect prints them. An empty
list means every 1.x release reads it.
1.4.0 adds one reader feature, nested-columns, which only files with nested columns use. Every other file it writes is
read by 1.3.0 with the same tables, rows and embedded files (tested with the published npm and NuGet 1.3.0 on every
interop variant, written by both libraries and the browser writer). A file's new document settings (file actions,
package.pdf, package.edit) are ignored by 1.3 and older, which leave them out if they append to the file, update
or compact it: rewrite such files with 1.4.
1.5.0 adds nothing a reader must understand. Saved export shapes are a new optional member of the file directories, which 1.0 to 1.4 skip: the published npm 1.4.0 reads all 46 interop fixtures exactly as 1.5.0 does, with every key, including the files with saved shapes written by both libraries (which NuGet 1.4.0 reads too). 1.4 and older leave the shapes out when they append to, update or compact such a file: rewrite it with 1.5, or add the shapes again.
1.6.0 adds nothing a reader must understand. Links between tables are names in the file's metadata (jazmin.links),
which 1.0 to 1.5 read as ordinary metadata: every published npm release from 1.0.0 to 1.5.0 reads a 1.6 file with
links, added, renamed and re-keyed tables and a new sort order exactly as 1.6.0 does (NuGet 1.5.0 too), and keeps the
links when it appends, updates or compacts. The published npm 1.5.0 reads all 46 interop fixtures exactly as 1.6.0.
1.7.0 adds nothing a reader must understand, and reads every earlier file. The published npm and NuGet 1.6.2 read a 1.7 file of each new kind as their users expect (other text orders, the new package settings, stored-file options, locked files, and masked columns for an access key and for the owner): a locked file is refused, and masked values are never shown. What older releases must not do is change some of these files:
- Don't append to a file with locked files with 1.0 to 1.6. They don't check writer features (below), so they
would write the file without its locks, and the locked files' keys would be lost (1.7 says so, and
update({ removeFiles })takes them out). Theirupdateandcompactfail without changing the file. - Their rewrites of a file with masked columns hide those columns from keys: keys lose them, and never get them unmasked. The owner keeps the values.
- Their rewrites leave out the newer settings they don't know:
keyService,online,list, actions by file group (every group gets the first group's), and the rest of asortorder beyond its plain part (appends drop that too).
Change such files with 1.7.
- Optional additions go into the file as new catalog fields that older readers ignore, so files stay readable backwards.
- Anything a reader must understand is announced as a reader feature in the file. A reader that doesn't know a
feature refuses the file with a message naming it: "This file needs the 'x' feature, which this JAZMIN reader does not
support". The fix is to upgrade. The features so far are
index-deltas(compact indexes, 1.2) andnested-columns(nested columns, 1.4). - Writers refuse to modify a file with a feature they don't support, so an older writer can't damage a newer file.
- Writer features (1.7.0) name what a writer must understand to change a file, though readers need not: the first
are
file-locksandmasked-columns. From 1.7,append,update,compactandrotateKeyrefuse a file with a writer feature they don't know, andreader.writerFeatures(.NETWriterFeatures) lists them. 1.0 to 1.6 don't check them, hence the advice above. - Use compact indexes once every reader of your files is on 1.2. They are off by default until 2.0.
update(path, { compactIndexes: false })turns them off again for an existing file.
New in each version
| Feature | Since |
|---|---|
| Core format: chunks, statistics, sorted and trigram indexes, encryption, access control, expiry, embedded files, several tables, append and compact, export shapes, browser reader and viewer | 1.0 |
| Submission keys and writing files in the browser (Sending Records Back) | 1.1 |
columnArrays() for charts |
1.1 |
explain(filter, { analyze: true }) |
1.1 |
reader.advise() and jazmin advise |
1.1 |
The jazmin command-line tool |
1.1 |
JazminBrowser.openUrl() (range requests) |
1.1 |
compact({ regroup: true }) |
1.1 |
reader.writtenAt, access.groupColumns |
1.1 |
| Browsers refuse a shared file's owner key | 1.1 |
priority: 'memory' | 'balanced' | 'speed' |
1.2 |
rotateKey() / JazminFile.RotateKey |
1.2 |
rotateOwnerKey() / JazminFile.RotateOwnerKey |
1.2 |
.NET reader.AsQueryable<T>() |
1.2 |
serveFiles, createFileHandler, renderPdf, documentPolicy (Node) |
1.2 |
Jazmin.AspNetCore: MapJazminFiles |
1.2 |
compactIndexes (opt-in; readers need 1.2) |
1.2 |
importCSVFile / importXMLFile and .NET FromCsvFile / FromXmlFile at any size |
1.2 |
.NET JazminJsonStream and JazminJsonReader |
1.2 |
| Viewer: fonts and media from a package's allowed origins | 1.2 |
Export shapes across tables: $from, $on, $one (Export Shapes) |
1.3 |
Long in lists checked with a hash set |
1.3 |
| Filtered queries decode the columns they return only for matching rows | 1.3 |
| .NET LINQ reads only the columns the whole query uses | 1.3 |
| .NET JSON columns read straight from UTF-8 into typed members | 1.3 |
| .NET LINQ sub-queries inside lambdas read once (decorrelation) | 1.3 |
Nested columns: list and object columns (opt-in; readers need 1.4) |
1.4 |
Filters any, all and match on nested columns; .NET LINQ conditions on them |
1.4 |
| Nested fields added by appending | 1.4 |
Statistics of the fields inside nested columns: any and match skip chunks |
1.4 |
| .NET: a query that reads one chunk decodes it at once (lookups 0.70 → 0.60 ms) | 1.4 |
| .NET LINQ: a query's in-memory part compiled once per shape | 1.4 |
{ column: null } for json and binary columns |
1.4 |
Print-ready documents: file actions, page settings (package.pdf), a print mode, renderImage, portableHtml (Embedded Files and Documents) |
1.4 |
Editable documents: package.edit, change files, writeChanges / applyChanges and .NET JazminFile.WriteChanges / ApplyChanges |
1.4 |
| Text search reads only the parts of the trigram index it needs, and scans for common words | 1.4 |
| A query that needs a few rows of a chunk decodes only those rows (Node, the browser reader; .NET reads only as far as them) | 1.4 |
| Node writes indexed files with about half the memory | 1.4 |
Export shapes: priority: 'speed' collects unsorted groups in batches of 1,000,000 rows |
1.3 |
Export shapes saved in the file, listed per key; jazmin query --shape |
1.5 |
Queries with arrow functions: from(reader).where((t) => …), in Node and the browser |
1.5 |
| Browser reader and viewer: JSON, CSV and XML exports, export shapes, progress and Stop on long reads | 1.5 |
Viewer: opened from disk, in your page's iframe, or passed a file by your page (jazmin:open, jazmin:filter) |
1.5 |
Files as scripts for pages opened from disk: portableScript, jazmin script, JazminBrowser.openScript / scriptBytes |
1.5 |
| A Blazor WebAssembly sample: the .NET library and LINQ in the browser (unencrypted files) | 1.5 |
fileSubmission(): the filing rules as library API, with a dry run (.NET JazminFile.FileSubmission) |
1.6 |
Documents read every table: jazmin.tables, the table option; renderPdf tableFilters |
1.6 |
reader.storage(): is compacting worth it (.NET reader.Storage()) |
1.6 |
reader.readerFeatures: the reader features a file needs, so a tool can say which versions read it; jazmin inspect shows them |
1.6 |
The owner's grant list gives each key's extra file groups (grants[i].files, .NET JazminGrantInfo.Files) |
1.6 |
| Shared files with many chunks: a full read uses about a third less memory (JavaScript) | 1.6 |
Change an existing file's indexes and sort order: update({ indexes, sortedBy }), .NET JazminUpdate.Indexes / SortedBy |
1.6 |
Add, remove and rename tables in an existing file: addTables, removeTables, renameTables |
1.6 |
Links between tables, kept in the file and checked: links, reader.checkLinks() (.NET Links, CheckLinks()) |
1.6 |
Change several tables in one rewrite, and set + where: re-key across tables |
1.6 |
Progress and Stop on long reads: onProgress and signal, countAsync (.NET Progress, CancellationToken) |
1.7 |
Progress and Stop for rewrites: write, update, compact |
1.7 |
reader.estimate(): what a read would cost, without reading a row |
1.7 |
Reading last first: reverse: true, reverse(), LINQ Reverse() |
1.7 |
Text orders that ignore case or compare numbers: { column, nocase, natural }, reader.sort |
1.7 |
| Large rewrites in bounded memory: sorted indexes through temporary files | 1.7 |
| The browser script in parts: a core and add-ons; the viewer loads only what it uses | 1.7 |
list: false and actions by file group |
1.7 |
Locked stored files: locks, lock, unlock(), issueFileUnlockToken, in both libraries, the browser and the viewer |
1.7 |
Key services for locks: keyService, listFileUnlockTokens, the viewer's Sign in at … |
1.7 |
Masked columns: mask, reader.masked, package.masks, exports masked unless asked, update({ masks }) |
1.7 |
Documents that need the internet: package.online |
1.7 |
Document pages: package.pages as tabs, package.files, a file's page in shared files |
1.7 |
reader.writerFeatures: append, update, compact and rotateKey refuse a file with a writer feature they don't know |
1.7 |
Behaviour changes to know about
1.7.0
- Append, update, compact and
rotateKeyrefuse a file with a writer feature the library doesn't know; reading is unchanged. - .NET: the token passed to
FindAsyncnow also stops a read inside a batch. - .NET: package settings of the wrong type (a damaged file) are left out, as other settings are, instead of making
reader.Packagethrow.
1.5.0
- Saved shapes are left out when 1.4 or older appends to a file, updates or compacts it.
- .NET
JazminWriter.Createchecks its options before it opens the file: a refused option leaves an existing file as it was. In both libraries, a writer refused after it opened its file removes it, and a refused append leaves the file as it was.
1.4.0
- A file's new document settings are left out when 1.3 or older appends to the file, updates or compacts it.
explain()may report'scan'for a text search where it reported'index': when the word is in most rows, the reader scans. The rows are the same.- A query that reads a few rows of a chunk reads each column only as far as those rows, so damage further on in the chunk is not seen by that query. Reading every row still checks every value.
{ "column": null }(andnenull) filters work for json and binary columns; before, both libraries refused them.
1.2.0
- Readers refuse a file whose own JSON repeats a name (neither library writes one).
- .NET
ToXmldeclares UTF-8. - New files with
sortedByhave nosortedindex on their first sort column: chunk statistics already find its values, and readers never used it. Files are smaller as a result.
1.1.0
- Upgrade if you write decimals from JavaScript: 1.0.0 could damage decimals of more than about 20 digits.
- Browsers (the viewer and the browser reader) refuse a shared file's owner key.
Deprecated, removed in 2.0
| Deprecated | Use instead | Why |
|---|---|---|
Getting a key's secret with toString() / ToString() |
export() / Export() |
A key put into a log line or error message prints its full secret. From 2.0, toString() won't print it; an access key prints only its id |
The reader's clock option (JS now, .NET JazminReadOptions.Now) |
Nothing: expiry uses the system clock | Setting it back lets an expired key open the file |
.NET reports CS0618 where the clock option is used; TypeScript-aware editors strike both through.
Platforms
| Library | Needs |
|---|---|
@smithsoft-studios/jazmin |
Node.js 22 or later; ES modules; no dependencies |
@smithsoft-studios/jazmin/browser |
Chrome 103, Firefox 113, Safari 16.4 or later for compression; https:// or localhost for encryption |
Jazmin |
.NET 10; no third-party dependencies |
Jazmin.AspNetCore |
ASP.NET Core 10 |
Supported versions
Security fixes go into the latest minor release: currently 1.7.x. 1.6.x, 1.5.x, 1.4.x, 1.3.x, 1.2.x, 1.1.x and 1.0.x users should upgrade to 1.7: the same file format, and no breaking changes. See Security Model for how to report a problem.
The full history is in the repository's CHANGELOG.