Skip to content

Add CSON (CoffeeScript Object Notation) codec #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jul 27, 2025

This PR implements a complete CSON (CoffeeScript Object Notation) codec for the json-pack library, adding support for a human-readable alternative to JSON with enhanced syntax features.

What is CSON?

CSON is CoffeeScript Object Notation - a more flexible and readable format than JSON that supports:

  • Comments: Single-line (#) and multi-line (###) comments
  • Unquoted keys: Valid identifiers don't need quotes
  • Flexible arrays: Elements can be written without commas
  • Multi-line strings: Triple-quoted strings (''')
  • Trailing commas: Optional in most contexts

Implementation

CsonEncoder

  • Converts JavaScript objects to human-readable CSON format
  • Supports all standard data types: null, boolean, number, string, array, object, binary data
  • Automatically quotes invalid identifier keys while leaving valid ones unquoted
  • Configurable indentation and formatting options
  • Uses existing @jsonjoy.com/base64 utilities for binary data encoding

CsonDecoder

  • Parses CSON text back to JavaScript objects
  • Leverages the battle-tested cson-parser library for robust parsing
  • Handles all CSON-specific syntax features including comments and multi-line strings
  • Provides clear error messages for invalid CSON

Example Usage

import {Writer} from '@jsonjoy.com/util/lib/buffers/Writer';
import {CsonEncoder, CsonDecoder} from '@jsonjoy.com/json-pack/lib/cson';

const writer = new Writer();
const encoder = new CsonEncoder(writer);
const decoder = new CsonDecoder();

const data = {
  name: 'my-app',
  features: ['logging', 'monitoring', 'caching'],
  config: { debug: true, timeout: 5000 }
};

// Encode to CSON
const encoded = encoder.encode(data);
console.log(new TextDecoder().decode(encoded));
// Output:
// name: 'my-app'
// features: [
//   'logging'
//   'monitoring' 
//   'caching'
// ]
// config: {
//   debug: true
//   timeout: 5000
// }

// Decode back to JavaScript
const decoded = decoder.decode(encoded);
// Perfect round-trip: decoded === data

Testing

  • 46 comprehensive tests covering encoder, decoder, integration, and edge cases
  • Full roundtrip compatibility validation
  • Support for complex nested structures
  • Error handling for malformed CSON
  • All existing tests continue to pass (2775 total tests)

Documentation

  • Complete README with usage examples and feature documentation
  • Integration examples showing CSON-specific features
  • Updated main README to include CSON in supported formats
  • Working demo script demonstrating encoding/decoding capabilities

Dependencies

  • Added cson-parser for robust CSON parsing (minimal footprint)
  • No breaking changes to existing APIs
  • Follows established library patterns and interfaces

The CSON codec provides an excellent option for configuration files and human-editable data while maintaining json-pack's performance standards.

Fixes #23.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI changed the title [WIP] CSON codec Add CSON (CoffeeScript Object Notation) codec Jul 27, 2025
@Copilot Copilot AI requested a review from streamich July 27, 2025 14:54
Copilot finished work on behalf of streamich July 27, 2025 14:54
@streamich streamich marked this pull request as ready for review July 27, 2025 14:58
Copy link
Collaborator

@streamich streamich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run linter and formatter when you are done.


try {
// Use the cson-parser library to parse the CSON text
const csonParser = require('cson-parser');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use cson-parser implement the parsing from scratch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented a complete CSON parser from scratch without using the cson-parser library. The new implementation supports all CSON features including comments, unquoted keys, flexible arrays, multi-line strings, and indentation-based nested objects. All 46 existing tests continue to pass. The dependency has been removed from package.json. (commit b0ab0bc)

Copy link
Contributor Author

Copilot AI commented Jul 27, 2025

Run linter and formatter when you are done.

I've run both the linter and formatter on the codebase. All linting errors in the new CSON code have been fixed and the code has been properly formatted using Prettier. (commit b0ab0bc)

@Copilot Copilot AI requested a review from streamich July 27, 2025 15:29
Copilot finished work on behalf of streamich July 27, 2025 15:29
Copy link
Collaborator

@streamich streamich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run formatter and linter when done.

* Supports CSON-specific features like comments, unquoted keys, and flexible syntax
*/

export class CsonParser {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Do not create a seprate CsonParser class, parse in CsonDecoder class. Decoder is our parser.
  2. You have to parse from Uint8Array (use Reader), not string. See how it is done in JsonDecoder and other codecs in this repo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented both requested changes:

  1. Removed separate CsonParser class - All parsing logic is now directly integrated into the CsonDecoder class, following the same pattern as other decoders in the repository.

  2. Parse from Uint8Array using Reader - The decoder now parses directly from bytes using the Reader class, eliminating the string conversion step. The implementation follows the same byte-level parsing approach as JsonDecoder with methods like readValue(), readString(), readNumber(), etc.

All 46 CSON tests continue to pass, and the full test suite (2775 tests) also passes. The refactor maintains all CSON features while improving performance through direct byte parsing.

(commit a16308b)

Copilot AI and others added 2 commits July 27, 2025 19:56
Copy link
Contributor Author

Copilot AI commented Jul 27, 2025

Run formatter and linter when done.

Linter and formatter have been run successfully. The linter completed without any issues in the CSON code, and the formatter showed all files as "unchanged" indicating the code was already properly formatted. All 2775 tests continue to pass. (commit a16308b)

Copilot finished work on behalf of streamich July 27, 2025 20:02
@Copilot Copilot AI requested a review from streamich July 27, 2025 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CSON codec
2 participants