Add optional reviver and replacer callback parameters to jss.stringify() and jss.parse(), mirroring the native JSON.stringify(value, replacer) and JSON.parse(text, reviver) signatures.
Motivation
Sometimes users need lightweight, one-off transformations without registering a full custom type via jss.custom(). Common use cases:
- Redacting sensitive fields before serialization (e.g. stripping tokens or passwords)
- Transforming values on the fly during parsing (e.g. clamping numbers, normalising strings)
- Filtering keys from the output without mutating the original object
- Migration / versioning — reshaping legacy data during deserialization
The native JSON API already establishes this pattern, so supporting it keeps JsonSuperSet a true drop-in replacement.
Proposed API
// replacer — called during stringify, before type encoding
jss.stringify(data, {
replacer(key, value) {
if (key === 'password') return undefined // omit field
return value
}
})
// reviver — called during parse, after type decoding
jss.parse(json, {
reviver(key, value) {
if (key === 'count') return Math.max(0, value) // clamp
return value
}
})
Design Considerations
- Execution order:
replacer should run before the JSS type encoding so users see the original JS values. reviver should run after type decoding so users receive fully restored objects (Dates, Maps, etc.) rather than raw tagged values.
- Signature compatibility: Ideally the callbacks receive
(key, value) just like the native JSON equivalents to minimise surprise.
- Options object vs positional args: An options object (
{ replacer }) is more extensible than a positional second argument, but positional would be closer to native JSON. Worth deciding which style fits the library better.
- Interaction with
custom(): Hooks should compose cleanly with registered custom types — the hook runs in addition to, not instead of, custom encoders/decoders.
Alternatives
- Users can always wrap
jss.stringify / jss.parse themselves, but built-in support is cleaner and avoids double-parsing.
jss.custom() covers the "new type" case but is heavier than needed for simple field-level transforms.
Add optional
reviverandreplacercallback parameters tojss.stringify()andjss.parse(), mirroring the nativeJSON.stringify(value, replacer)andJSON.parse(text, reviver)signatures.Motivation
Sometimes users need lightweight, one-off transformations without registering a full custom type via
jss.custom(). Common use cases:The native JSON API already establishes this pattern, so supporting it keeps JsonSuperSet a true drop-in replacement.
Proposed API
Design Considerations
replacershould run before the JSS type encoding so users see the original JS values.revivershould run after type decoding so users receive fully restored objects (Dates, Maps, etc.) rather than raw tagged values.(key, value)just like the native JSON equivalents to minimise surprise.{ replacer }) is more extensible than a positional second argument, but positional would be closer to native JSON. Worth deciding which style fits the library better.custom(): Hooks should compose cleanly with registered custom types — the hook runs in addition to, not instead of, custom encoders/decoders.Alternatives
jss.stringify/jss.parsethemselves, but built-in support is cleaner and avoids double-parsing.jss.custom()covers the "new type" case but is heavier than needed for simple field-level transforms.