Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,39 @@ This project follows [Semantic Versioning](https://semver.org/).

## Unreleased

## 3.0.0 — 2026-10-14

Stable release of the new incremental JSON/JSON5 API. Install with
`npm install @sapientpro/json-stream`. This is a breaking upgrade from 2.x;
see [migration](docs/v3-migration.md) and the [API reference](docs/v3-reference.md).

- Replace observable-style subscriptions with synchronous `onValue`/`onString`
callbacks, first-match `getValue()` promises and Web `stringStream()` output.
Register consumers before input; completed values are not replayed.
- Drive retention through value subscriptions. Subscribe to `$` for a complete
document; string-fragment subscriptions alone do not collect whole strings.
- Support strict JSON and JSON5, typed JSONPath selectors with recursive descent,
JSONL/prefix managers, and reusable selector plans. Filters, slices, unions and
negative indexes remain unsupported.
- Keep core input string-only; Web/Node and synchronous input adapters decode
UTF-8, reject malformed byte input and own transport pacing.
- Accept optional final text/UTF-8 chunks in `end(chunk?)` on record managers,
prefix filters and decoded-input adapters, matching core and Node input usage.
- Reorganize the developer guide, add methods/options and error-ownership
references, complete string/Web/Node examples, and clarify that `getValue()`
resolves a first match rather than proving whole-document validity.
- Preserve subscriptions through `reset()` between documents; validate EOF and
trailing input separately from root availability. A fulfilled `getValue()`
does not prove whole-input validity and cannot be revoked by later failures.
- Provide compact memory mode for selected short strings, bounded selector
caches, consistent cancellation and consumer-error handling.
- Reorganize the guide and reference with complete string/Web/Node recipes,
option defaults, error ownership, migration and contributor documentation.
- Add CodeQL, Dependabot, a private security-reporting policy, restricted CI
permissions and locked development tooling. Pin third-party Actions to SHA.
Upgrade development TypeScript to 6.0.3 and ts-jest to 29.4.14; retain Node 22 types.

Validated by 519 tests, Node/Bun/Deno checks, packed-consumer type checks, and a
live OpenAI Structured Outputs/tool-call spike covering field streaming,
cancellation and token-limited output. See the prerelease history below for
individual fixes and optimization details.

## 3.0.0-beta.1 — 2026-10-12

Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
Incremental JSON and JSON5 parsing with selective value callbacks, streaming
strings, JSONPath selectors and Web/Node input adapters. No runtime dependencies.

This README documents the **3.0.0-beta.1 prerelease**, with breaking changes from
2.x and the alpha releases. Core parsers accept strings; transports decode bytes.
For the stable 2.x API, see [2.0.1](https://github.com/sapientpro/json-stream/tree/2.0.1).

Install the beta explicitly; the stable 2.x release remains on `latest`:
This README documents **3.0.0**, with breaking changes from 2.x. Core parsers
accept strings; transports decode bytes. See the [migration guide](docs/v3-migration.md).
For the previous 2.x API, see [2.0.1](https://github.com/sapientpro/json-stream/tree/2.0.1).

```sh
npm install @sapientpro/json-stream@beta
npm install @sapientpro/json-stream
```

```ts
Expand Down Expand Up @@ -59,6 +57,6 @@ whole-document validity matters.
- [Approximate throughput](docs/performance.md) and [package comparison](benchmarks/capabilities.md)
- [Architecture](docs/v3-architecture.md), [contributing](CONTRIBUTING.md) and [security policy](SECURITY.md)

Documentation follows `main`; unreleased additions are marked in the reference.
Documentation describes 3.0.0; later changes are tracked in the changelog.

MIT licensed.
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ not guaranteed.

## Versions

Report issues affecting the latest stable 2.x release or the current 3.x
prerelease. Prereleases are still under development; a fix may require upgrading
to a newer prerelease. Older versions may require upgrading to receive a fix.
Report issues affecting the latest stable release. Reports for older versions
and prereleases are also welcome; include the exact affected version. A fix may
require upgrading to the latest stable release.
4 changes: 2 additions & 2 deletions benchmarks/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

Competitor capabilities were audited against the pinned installed versions on
2026-10-08, not necessarily their newest releases. Our column describes
`3.0.0-beta.1` (updated 2026-10-12), independently of the older measured
`3.0.0` (updated 2026-10-14), independently of the older measured
package-comparison snapshot. “Adapter” means
composition or consumer code. See [approximate current parser throughput](../docs/performance.md). `json-stream-lite` is excluded
from ongoing comparisons as requested; archived release reports remain unchanged.

| Capability | @sapientpro/json-stream 3.0.0-beta.1 | @streamparser/json 0.0.26 | stream-json 3.7.0 | json-web-streams 1.2.0 |
| Capability | @sapientpro/json-stream 3.0.0 | @streamparser/json 0.0.26 | stream-json 3.7.0 | json-web-streams 1.2.0 |
|---|---|---|---|---|
| Input | Text core; UTF-8 in adapters | Text / UTF-8 bytes | Text core; byte decoder / transports | Text; TextDecoderStream for bytes |
| Browser / Node transports | Web and Node wrappers | Core; separate wrappers | Web / Node pipelines | Web Streams |
Expand Down
4 changes: 2 additions & 2 deletions docs/v3-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ parser, bounded by 4,096 states and 65,536 transition slots. Once the cache is
full, uncached transitions preserve matching without growing the retained graph.
Plan compilation applies its budget while discovering each state and falls back
to lazy transitions if the prepared graph would exceed that budget. Slices,
filters, unions and negative indexes are rejected in this
candidate. Recursive descent is implemented in subscription contexts: the Rest
filters, unions and negative indexes are rejected by the supported
JSONPath subset. Recursive descent is implemented in subscription contexts: the Rest
state persists at each depth while its suffix advances independently. Exact suffix
edges are included in transition caches, with separate numeric indexes and property
names. Converging recursive routes deduplicate subscription nodes before dispatch;
Expand Down
3 changes: 1 addition & 2 deletions docs/v3-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ The [3.0 usage guide](v3.md) covers the new API; the [reference](v3-reference.md
`collectJson` and `maxDepth` remain options. `start` moves to an optional input manager; the core accepts only JSON/JSON5. `collectJson`
retains all decoded input and therefore defeats bounded input-memory usage.
`maxDepth` defaults to 1000 and accepts nonnegative safe integers or Infinity.
A core parser consumes one document. Optional managers below consume multiple documents.

A core parser consumes one document. Use [JSONL or prefix managers](v3.md#json-lines-and-prefixed-documents) for multiple documents.

There is no `root` getter or `retainRoot` option; passing the removed option throws `TypeError`. Subscribe to `$` before writing to build a complete result.
7 changes: 3 additions & 4 deletions docs/v3-reference.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# 3.0 API reference

For complete examples, start with the [usage guide](v3.md).
This reference follows `main`. **Unreleased since 3.0.0-beta.1:** optional final
chunks on record managers, `PrefixFilter` and `createDecodedInput`. Until the next
release, call `write(finalChunk); end()` on those inputs. Core `end(text?)` already
works in beta.1.
This reference describes **3.0.0**. Core parsers accept final text in `end(text?)`;
record managers, `PrefixFilter` and `createDecodedInput` also accept final UTF-8
bytes in `end(chunk?)`, following the same input mode as `write()`.

## Choose an input

Expand Down
5 changes: 2 additions & 3 deletions docs/v3.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# 3.0 usage guide

This guide follows the development branch. Install the published prerelease with
`npm install @sapientpro/json-stream@beta`. See the [API reference](v3-reference.md)
for defaults and explicitly marked unreleased additions.
This guide describes **3.0.0**. Install with `npm install @sapientpro/json-stream`.
The [API reference](v3-reference.md) lists methods, lifecycle and option defaults.

The parser consumes one JSON or JSON5 document incrementally. Parsing and callbacks
run synchronously inside `write()`. Register consumers first, feed chunks, then
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sapientpro/json-stream",
"version": "3.0.0-beta.1",
"version": "3.0.0",
"description": "Incremental JSON and JSON5 parser with selective value callbacks and streaming strings",
"license": "MIT",
"author": {
Expand Down
Loading