JSON-Lines

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

	- Fix - when encoding an array of hashrefs with parse_headers enabled check all hash refs for keys to build the header

1.08	2025/05/20
	- Fix - get_line to return undef on end of file.

1.10	2026/01/10
	- Adds group_lines and get_line_at

1.11	2026/01/10
	- Fix regex to be string-aware, correctly handling unbalanced braces within JSON string values
	- Adds chunked/streaming input support with automatic buffering
	- Adds remaining() method to check buffer state
	- Adds clear_buffer() method to reset buffer between operations

lib/JSON/Lines.pm  view on Meta::CPAN


=head2 encode_file

Encode a perl struct into a json lines file.

	$jsonl->encode_file($file, $data);

=head2 decode

Decode a json lines string into a perl struct. Handles multiple JSON objects
per line (e.g., from streaming output that concatenates objects without newlines).
The decoder is string-aware, correctly handling unbalanced braces within JSON
string values (e.g., code snippets containing C<{> or C<}>).

	$jsonl->decode( $string );

	# Handles multiple objects on one line:
	my @data = $jsonl->decode('{"a":1}{"b":2}');
	# Returns: ({ a => 1 }, { b => 2 })

	# Handles code in strings:
	my @data = $jsonl->decode('{"code":"sub foo { }"}');
	# Correctly parses as single object

Supports chunked/streaming input - incomplete JSON is buffered and combined
with subsequent calls. Use C<remaining()> to check buffer state and
C<clear_buffer()> to reset.

=head2 decode_file

Decode a json lines file into a perl struct.

	$jsonl->decode_file( $file );

=head2 remaining

t/13-multi-object-line.t  view on Meta::CPAN

use Test::More;

use JSON::Lines;

my $jsonl = JSON::Lines->new(
	canonical => 1,
);

# Test: Multiple JSON objects on a single line (no newlines between them)
# This is the case when streaming output concatenates multiple JSON objects
subtest 'multiple objects on single line' => sub {
	my $string = q|{"type":"init","id":1}{"type":"message","id":2}{"type":"result","id":3}|;

	my @data = $jsonl->decode($string);

	is(scalar @data, 3, 'decoded 3 objects from single line');
	is_deeply($data[0], { type => 'init', id => 1 }, 'first object correct');
	is_deeply($data[1], { type => 'message', id => 2 }, 'second object correct');
	is_deeply($data[2], { type => 'result', id => 3 }, 'third object correct');
};



( run in 0.536 second using v1.01-cache-2.11-cpan-140bd7fdf52 )