Skip to content

Record upstream safe-stable-stringify 3.0.0 merge (all changes already ported) - #4

Open
claude[bot] wants to merge 11 commits into
mainfrom
fork-tender/BridgeAR-safe-stable-stringify
Open

claude[bot] wants to merge 11 commits into
mainfrom
fork-tender/BridgeAR-safe-stable-stringify

Conversation

@claude

@claude claude Bot commented Nov 9, 2026

Copy link
Copy Markdown

Summary

This merges upstream BridgeAR/safe-stable-stringify main at bdd585f (10 commits since merge base 8a02137) into the fork. It is a history-only merge: the merged tree is identical to the fork's current main (git diff HEAD^1 HEAD is empty).

All 10 upstream commits were already ported by hand in fork commit e756f37 ("Updates from upstream. (#3)"). Follow-up commits 4c440ba and efd73fe then brought the fork in line with upstream 3.0.0. That earlier sync was squash-merged, so git still saw these upstream commits as unmerged. Recording them as a real merge parent means future syncs only bring in commits newer than bdd585f.

Upstream commits included

One more check: the upstream tip's index.js and index.d.ts are byte-identical to the published safe-stable-stringify@3.0.0 that the fork already uses as a devDependency. test/upstream.test.ts checks the fork's output against that package directly.

Conflict resolution

Every conflict was resolved to the fork's side:

  • package.json: kept the fork's @kitschpatrol/safe-stable-stringify metadata, ESM-only dist/ exports, pnpm scripts and devDependencies. Dropped upstream's CJS wrapper.cjs/esm/wrapper.mjs exports, tap/standard scripts and version 3.0.0.
  • readme.md: kept the fork's mdat-managed readme. Upstream's API docs and benchmark output were not brought in (the fork links to the upstream readme instead).
  • changelog.md: kept the fork's version, which already includes upstream's new "Next" entries (Node 18 requirement, ESM fix, [Circular: N]). The rest of upstream's diff only changed link formatting (angle-bracketed autolinks vs. bare URLs).
  • tsconfig.json, .gitignore: kept the fork's versions. Upstream's changes covered .tap/, .cts/.mts fixtures and wrapper.cjs, none of which exist here.
  • Deleted in the fork, modified upstream (kept deleted): index.js, index.d.ts, esm/wrapper.mjs, test.js, benchmark.js, compare.js, .npmignore.
  • Added upstream (not adopted): wrapper.cjs, test-modules.js, test-fixtures/* (CJS/ESM dual-module consumer fixtures), benchmark-utils.js. These are CommonJS wrapper, Tape-style test and upstream benchmark tooling. They don't apply to the ESM-only TypeScript/Vitest layout, and their behavior is already covered by test/index.test.ts, test/upstream.test.ts and test/index.bench.ts.

Protected paths

  • .github/workflows/test.yml: upstream changed it (CI matrix/test command updates). The fork does not have this file and uses its own workflows, so the upstream change was dropped and the file stays deleted.

Verification

pnpm ci && pnpm build && pnpm lint && pnpm test: pass

  • build: tsdown produced dist/index.js and dist/index.d.ts; attw and publint reported no problems.
  • lint: all 8 ksc commands passed.
  • test: 2 files, 120 tests passed.

Benchmarks were not re-run. The merge changes no source, test or baseline files, so serialization performance is unchanged from main.


10 new commit(s) from BridgeAR/safe-stable-stringify · upstream compare

Verification Result
Baseline (main) pass
Mechanical pass on this branch skipped

See the report above for post-resolution verification.

Automated by fork-tender · outcome: resolved · confidence: high

spokodev and others added 11 commits October 12, 2026 04:39
`JSON.stringify` treats any numeric `space` below 1 as no indentation, but
`stringify` threw on it:

    JSON.stringify({ a: 1 }, null, -1) // '{"a":1}'
    stringify({ a: 1 }, null, -1)      // RangeError: Invalid count value: -1

The README documents the spacer as behaving "the same as with
JSON.stringify()". `space` was clamped to a maximum of 10 but not a minimum
of 0, so a negative count reached `String.prototype.repeat`, which throws
for counts <= -1. Clamp the lower bound to 0.
Looks like this was accidentally introduced in BridgeAR@132e76c
Circular references to different ancestors currently produce the same marker, which hides where each cycle closes. The new marker identifies the referenced ancestor's depth, starting at 0 for the root.

BREAKING CHANGE: The default marker changes from `[Circular]` to `[Circular: N]`. Set `circularValue: '[Circular]'` to retain the previous output.
…R#73)

* Serialize non-finite typed-array values consistently

Fixes: BridgeAR#68

* perf(typed-array): inline floating-point checks

A formatter closure adds finite checks to integer arrays and an extra call for floating-point values. Inline checks retain direct conversion for integer and BigInt arrays.

---------

Co-authored-by: Ferit <frtcm11@gmail.com>
Array indexes only need strings when they reach toJSON or function replacer
callbacks. A four-number array uses 86 ns instead of 107 ns on Node 26.3.1
(V8 14.6.202.34-node.20), a 20% CPU reduction. Measurements use 50,000 warmup
calls and seven alternating trials, with the fastest and slowest removed.

Drive-by fix: Mark intentional invalid-option assertions for TypeScript.
Disordered objects with up to 200 keys can spend most of their serialization
time shifting keys. A shuffled 200-key object uses 16.6 us instead of 45.6 us
on Node 26.3.1 (V8 14.6.202.34-node.20), a 64% CPU reduction. Measurements
use 50,000 warmup calls and seven alternating trials, with the fastest and
slowest removed. Nearly ordered keys retain the insertion path.

Drive-by fix: Mark intentional invalid-option assertions for TypeScript.
The implementation is cached after the first load, so removing its global
export leaves the other wrapper without an export. Retain a version-specific
symbol so ESM imports, CommonJS requires, and independent copies of one
version receive the same function.

BREAKING CHANGE: Require Node.js 18 or later.
Primitive array elements and object properties enter recursive serializers
even though they need no traversal. Share primitive formatting across
serialization modes while preserving toJSON ordering and per-value error
handling in safe mode.

Native string escaping becomes faster at shorter string lengths on
Node.js 22 and later. Select the cutoff once at module load so older
runtimes retain their existing fast path.
…der/BridgeAR-safe-stable-stringify

# Conflicts:
#	.github/workflows/test.yml
#	.gitignore
#	.npmignore
#	benchmark.js
#	changelog.md
#	compare.js
#	esm/wrapper.mjs
#	index.d.ts
#	index.js
#	package.json
#	readme.md
#	test.js
#	tsconfig.json

Fork-Tender: v1
@claude claude Bot added the fork-tender Automated upstream sync by fork-tender label Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork-tender Automated upstream sync by fork-tender

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants