jsonc-effect 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,1983 +1,1933 @@
1
- /**
2
- * jsonc-effect
3
- *
4
- * Pure Effect-TS implementation of a JSONC (JSON with Comments) parser.
5
- * No external parser dependencies scanner, parser, AST, and formatting
6
- * are all implemented natively in Effect.
7
- *
8
- * @packageDocumentation
9
- */
10
-
11
- import { Effect } from 'effect';
12
- import { Equals } from 'effect/Types';
13
- import { Option } from 'effect';
14
- import { Schema } from 'effect';
15
- import { Stream } from 'effect';
16
- import { YieldableError } from 'effect/Cause';
17
-
18
- /**
19
- * Apply an array of text edits to JSONC source text.
20
- *
21
- * This is a {@link https://effect.website/docs/function-dual | Function.dual}
22
- * that supports both data-first and data-last (pipeline) usage.
23
- *
24
- * @param text - The original JSONC source text.
25
- * @param edits - A read-only array of {@link JsoncEdit} objects, typically
26
- * produced by {@link format} or {@link modify}.
27
- * @returns An `Effect` that succeeds with the edited string.
28
- *
29
- * @remarks
30
- * Edits are sorted in reverse offset order before application so that
31
- * earlier edits do not shift the offsets of later ones. The original `edits`
32
- * array is not mutated.
33
- *
34
- * @see {@link format} to compute formatting edits.
35
- * @see {@link modify} to compute structural edits (insert, replace, remove).
36
- *
37
- * @example Data-first usage
38
- * ```ts
39
- * import { Effect } from "effect";
40
- * import { format, applyEdits } from "jsonc-effect";
41
- *
42
- * const input = '{"a":1}';
43
- * const edits = Effect.runSync(format(input));
44
- * const result: string = Effect.runSync(applyEdits(input, edits));
45
- * ```
46
- *
47
- * @example Pipeline with modify
48
- * ```ts
49
- * import { Effect, pipe } from "effect";
50
- * import { modify, applyEdits } from "jsonc-effect";
51
- *
52
- * const input = '{ "a": 1 }';
53
- * const result = pipe(
54
- * input,
55
- * modify(["a"], 42),
56
- * Effect.flatMap((edits) => applyEdits(input, edits)),
57
- * Effect.runSync,
58
- * );
59
- * ```
60
- *
61
- * @public
62
- */
63
- export declare const applyEdits: {
64
- (edits: ReadonlyArray<JsoncEdit>): (text: string) => Effect.Effect<string>;
65
- (text: string, edits: ReadonlyArray<JsoncEdit>): Effect.Effect<string>;
66
- };
67
-
68
- /**
69
- * Create a stateful {@link JsoncScanner} for the given JSONC string.
70
- *
71
- * @param text - JSONC string to tokenize
72
- * @param ignoreTrivia - If `true`, the scanner automatically skips whitespace,
73
- * line-break, and comment tokens so that only structural tokens are returned
74
- * (default: `false`).
75
- * @returns A stateful {@link JsoncScanner} positioned before the first token.
76
- *
77
- * @remarks
78
- * When `ignoreTrivia` is `true` the scanner is suitable for building parsers
79
- * that only care about structural tokens (`OpenBrace`, `String`, `Number`,
80
- * etc.). Set it to `false` (the default) when you need to preserve comments
81
- * or whitespace — for example in a formatter or a comment-stripping pass.
82
- *
83
- * @see {@link JsoncScanner} — the interface returned by this factory
84
- * @see {@link parse} higher-level API that uses a scanner internally
85
- *
86
- * @example
87
- * Tokenizing a JSONC string and printing each token:
88
- * ```ts
89
- * import type { JsoncSyntaxKind } from "jsonc-effect";
90
- * import { createScanner } from "jsonc-effect";
91
- *
92
- * const scanner = createScanner('{ "name": "jsonc" }', true);
93
- * let kind: JsoncSyntaxKind;
94
- * do {
95
- * kind = scanner.scan();
96
- * console.log(kind, scanner.getTokenValue());
97
- * } while (kind !== "EOF");
98
- * ```
99
- *
100
- * @privateRemarks
101
- * Ported from Microsoft's jsonc-parser (MIT), adapted to use string literal
102
- * token types instead of numeric enums.
103
- *
104
- * @public
105
- */
106
- export declare const createScanner: (text: string, ignoreTrivia?: boolean) => JsoncScanner;
107
-
108
- /**
109
- * Compare two JSONC strings for semantic equality.
110
- *
111
- * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
112
- * for both data-first and data-last (pipeline) usage.
113
- *
114
- * @param self - The first JSONC string.
115
- * @param that - The second JSONC string.
116
- *
117
- * @returns `Effect<boolean, JsoncParseError>` — `true` when both strings parse to
118
- * semantically equivalent values, `false` otherwise. Fails with
119
- * {@link JsoncParseError} if either string is malformed.
120
- *
121
- * @remarks
122
- * Both strings are parsed via {@link parse} and then deep-compared. The comparison
123
- * ignores comments, whitespace, formatting, and object key ordering. Array order
124
- * IS significant. Uses `Effect.all` internally, so the effect fails on the first
125
- * parse error encountered.
126
- *
127
- * @see {@link equalsValue} — compare a JSONC string against an existing JS value
128
- * @see {@link parse} — the underlying parser used for both strings
129
- *
130
- * @example Data-first comparison
131
- * ```ts
132
- * import { Effect } from "effect";
133
- * import { equals } from "jsonc-effect";
134
- *
135
- * const result = Effect.runSync(
136
- * equals('{ "a": 1, "b": 2 }', '{"b":2,"a":1}')
137
- * );
138
- * // result is true
139
- * ```
140
- *
141
- * @example Key-order independence
142
- * ```ts
143
- * import { Effect } from "effect";
144
- * import { equals } from "jsonc-effect";
145
- *
146
- * // Object key order does not matter
147
- * const sameKeys = Effect.runSync(
148
- * equals('{"z":1,"a":2}', '{"a":2,"z":1}')
149
- * );
150
- * // sameKeys is true
151
- *
152
- * // Array order DOES matter
153
- * const differentOrder = Effect.runSync(
154
- * equals('[1, 2]', '[2, 1]')
155
- * );
156
- * // differentOrder is false
157
- * ```
158
- *
159
- * @example Error handling
160
- * ```ts
161
- * import { Effect, Either } from "effect";
162
- * import type { JsoncParseError } from "jsonc-effect";
163
- * import { equals } from "jsonc-effect";
164
- *
165
- * const result: Either.Either<boolean, JsoncParseError> = Effect.runSync(
166
- * Effect.either(equals('{ invalid }', '{}'))
167
- * );
168
- * // result is Either.left(JsoncParseError)
169
- * ```
170
- *
171
- * @privateRemarks
172
- * Uses a simple recursive `deepEqual` helper rather than Effect's `Equal` module
173
- * because the parsed values are plain JS objects and arrays, not Effect data types.
174
- *
175
- * @public
176
- */
177
- export declare const equals: {
178
- (that: string): (self: string) => Effect.Effect<boolean, JsoncParseError>;
179
- (self: string, that: string): Effect.Effect<boolean, JsoncParseError>;
180
- };
181
-
182
- /**
183
- * Compare a JSONC string against a JavaScript value for semantic equality.
184
- *
185
- * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
186
- * for both data-first and data-last (pipeline) usage.
187
- *
188
- * @param self - The JSONC string to parse.
189
- * @param value - The JavaScript value to compare against.
190
- *
191
- * @returns `Effect<boolean, JsoncParseError>` — `true` when the parsed JSONC
192
- * is semantically equivalent to the provided value, `false` otherwise.
193
- * Fails with {@link JsoncParseError} if the string is malformed.
194
- *
195
- * @remarks
196
- * Only the JSONC string is parsed; the JS value is used as-is. This makes
197
- * `equalsValue` useful for assertions and testing where the expected value
198
- * is already a JS object. The comparison semantics are the same as
199
- * {@link equals}: comments, whitespace, formatting, and object key ordering
200
- * are ignored, while array order IS significant.
201
- *
202
- * @see {@link equals} — compare two JSONC strings against each other
203
- * @see {@link parse} — the underlying parser
204
- *
205
- * @example Basic comparison
206
- * ```ts
207
- * import { Effect } from "effect";
208
- * import { equalsValue } from "jsonc-effect";
209
- *
210
- * const result = Effect.runSync(
211
- * equalsValue('{"port": 3000, "host": "localhost"}', { host: "localhost", port: 3000 })
212
- * );
213
- * // result is true
214
- * ```
215
- *
216
- * @example Pipeline usage for testing
217
- * ```ts
218
- * import { Effect, pipe } from "effect";
219
- * import { equalsValue } from "jsonc-effect";
220
- *
221
- * const jsonc = '{ "enabled": true, "count": 5 }';
222
- * const expected = { enabled: true, count: 5 };
223
- *
224
- * const result = Effect.runSync(
225
- * pipe(jsonc, equalsValue(expected))
226
- * );
227
- * // result is true
228
- * ```
229
- *
230
- * @public
231
- */
232
- export declare const equalsValue: {
233
- (value: unknown): (self: string) => Effect.Effect<boolean, JsoncParseError>;
234
- (self: string, value: unknown): Effect.Effect<boolean, JsoncParseError>;
235
- };
236
-
237
- /**
238
- * Find an AST node at a specific JSON path.
239
- *
240
- * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
241
- * for both data-first and data-last (pipeline) usage.
242
- *
243
- * @param root - The AST root node obtained from {@link parseTree}.
244
- * @param path - An array of string keys and numeric indices describing the path to traverse.
245
- *
246
- * @returns `Effect<Option<JsoncNode>>`the node at the given path, or `Option.none()` if the
247
- * path does not exist in the tree.
248
- *
249
- * @remarks
250
- * String segments navigate object properties and number segments navigate array indices.
251
- * Returns `Option.none()` when any segment along the path cannot be resolved — for example,
252
- * accessing a property on a non-object node or an out-of-bounds array index.
253
- *
254
- * @see {@link parseTree} — produces the AST root this function operates on
255
- * @see {@link getNodeValue} reconstructs a JS value from a found node
256
- * @see {@link JsoncNode} the AST node type
257
- * @see {@link JsoncPath} — the path segment array type
258
- *
259
- * @example Data-first usage
260
- * ```ts
261
- * import { Effect, Option } from "effect";
262
- * import type { JsoncNode } from "jsonc-effect";
263
- * import { parseTree, findNode } from "jsonc-effect";
264
- *
265
- * const program = Effect.gen(function* () {
266
- * const root: Option.Option<JsoncNode> = yield* parseTree('{ "a": { "b": 1 } }');
267
- * if (Option.isNone(root)) return Option.none();
268
- * return yield* findNode(root.value, ["a", "b"]);
269
- * });
270
- *
271
- * const result = Effect.runSync(program);
272
- * // result is Option.some(node) where node.value === 1
273
- * ```
274
- *
275
- * @example Data-last pipeline usage
276
- * ```ts
277
- * import { Effect, Option, pipe } from "effect";
278
- * import type { JsoncNode } from "jsonc-effect";
279
- * import { parseTree, findNode } from "jsonc-effect";
280
- *
281
- * const program = Effect.gen(function* () {
282
- * const root: Option.Option<JsoncNode> = yield* parseTree('{ "x": [10, 20] }');
283
- * if (Option.isNone(root)) return Option.none();
284
- * return yield* pipe(root.value, findNode(["x", 1]));
285
- * });
286
- *
287
- * const result = Effect.runSync(program);
288
- * // result is Option.some(node) where node.value === 20
289
- * ```
290
- *
291
- * @privateRemarks
292
- * Wrapped in `Effect.sync`; the underlying traversal is fully synchronous.
293
- *
294
- * @public
295
- */
296
- export declare const findNode: {
297
- (path: JsoncPath): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncNode>>;
298
- (root: JsoncNode, path: JsoncPath): Effect.Effect<Option.Option<JsoncNode>>;
299
- };
300
-
301
- /**
302
- * Find the innermost AST node covering a character offset.
303
- *
304
- * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
305
- * for both data-first and data-last (pipeline) usage.
306
- *
307
- * @param root - The AST root node obtained from {@link parseTree}.
308
- * @param offset - A zero-based character offset into the original JSONC string.
309
- *
310
- * @returns `Effect<Option<JsoncNode>>` — the most deeply nested node whose span
311
- * includes the offset, or `Option.none()` if the offset is outside the tree.
312
- *
313
- * @remarks
314
- * This is useful for editor integrations such as hover information, go-to-definition,
315
- * and code completions where you need to identify the token under the cursor.
316
- *
317
- * @see {@link parseTree} — produces the AST root this function operates on
318
- * @see {@link getNodePath} — returns the JSON path to the node at an offset
319
- *
320
- * @example Finding a node at an offset
321
- * ```ts
322
- * import { Effect, Option } from "effect";
323
- * import type { JsoncNode } from "jsonc-effect";
324
- * import { parseTree, findNodeAtOffset } from "jsonc-effect";
325
- *
326
- * const program = Effect.gen(function* () {
327
- * const root: Option.Option<JsoncNode> = yield* parseTree('{ "key": "value" }');
328
- * if (Option.isNone(root)) return Option.none();
329
- * // Offset 10 is inside the "value" string literal
330
- * return yield* findNodeAtOffset(root.value, 10);
331
- * });
332
- *
333
- * const result = Effect.runSync(program);
334
- * // result is Option.some(node) where node.type === "string"
335
- * ```
336
- *
337
- * @privateRemarks
338
- * Wrapped in `Effect.sync`; the underlying traversal is fully synchronous.
339
- *
340
- * @public
341
- */
342
- export declare const findNodeAtOffset: {
343
- (offset: number): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncNode>>;
344
- (root: JsoncNode, offset: number): Effect.Effect<Option.Option<JsoncNode>>;
345
- };
346
-
347
- /**
348
- * Compute formatting edits for a JSONC document.
349
- *
350
- * Returns an array of {@link JsoncEdit} objects describing text replacements
351
- * that, when applied, produce a well-formatted document. The input text is
352
- * never mutated — apply the returned edits with {@link applyEdits}.
353
- *
354
- * @param text - The JSONC source text to format.
355
- * @param range - Optional sub-range to format. When provided, only edits
356
- * within the range are returned.
357
- * @param options - Partial {@link JsoncFormattingOptions} controlling indent
358
- * size, tabs vs. spaces, EOL style, and final-newline insertion.
359
- * @returns An `Effect` that succeeds with a read-only array of
360
- * {@link JsoncEdit} objects.
361
- *
362
- * @remarks
363
- * This function is non-mutating by design. It computes a minimal set of
364
- * whitespace edits; structural changes (inserting or removing properties)
365
- * are handled by {@link modify}. The `range` parameter allows formatting a
366
- * subset of the document without touching surrounding text.
367
- *
368
- * @see {@link applyEdits} to apply the returned edits to the source text.
369
- * @see {@link formatAndApply} for a one-step format-and-apply convenience.
370
- * @see {@link JsoncFormattingOptions} for available formatting controls.
371
- *
372
- * @example
373
- * ```ts
374
- * import { Effect } from "effect";
375
- * import type { JsoncEdit } from "jsonc-effect";
376
- * import { format, applyEdits } from "jsonc-effect";
377
- *
378
- * const input = '{"a":1, "b" :2}';
379
- * const edits: ReadonlyArray<JsoncEdit> = Effect.runSync(format(input));
380
- * const formatted: string = Effect.runSync(applyEdits(input, edits));
381
- * ```
382
- *
383
- * @privateRemarks
384
- * Uses {@link createScanner} internally to tokenize the input and compute
385
- * whitespace adjustments between consecutive non-trivia tokens.
386
- *
387
- * @public
388
- */
389
- export declare const format: (text: string, range?: JsoncRange | undefined, options?: Partial<JsoncFormattingOptions> | undefined) => Effect.Effect<readonly JsoncEdit[], never, never>;
390
-
391
- /**
392
- * Format a JSONC document in one step by computing edits and immediately
393
- * applying them.
394
- *
395
- * This is a convenience that combines {@link format} and {@link applyEdits}
396
- * into a single call.
397
- *
398
- * @param text - The JSONC source text to format.
399
- * @param range - Optional sub-range to restrict formatting to.
400
- * @param options - Partial {@link JsoncFormattingOptions} controlling indent
401
- * size, tabs vs. spaces, EOL style, and final-newline insertion.
402
- * @returns An `Effect` that succeeds with the fully formatted string.
403
- *
404
- * @see {@link format} to obtain the edits without applying them.
405
- * @see {@link applyEdits} to apply edits separately.
406
- *
407
- * @example
408
- * ```ts
409
- * import { Effect } from "effect";
410
- * import { formatAndApply } from "jsonc-effect";
411
- *
412
- * const input = '{"a":1, "b" :2}';
413
- * const formatted: string = Effect.runSync(formatAndApply(input));
414
- * ```
415
- *
416
- * @public
417
- */
418
- export declare const formatAndApply: (text: string, range?: JsoncRange | undefined, options?: Partial<JsoncFormattingOptions> | undefined) => Effect.Effect<string, never, never>;
419
-
420
- /**
421
- * Get the JSON path to the node at a specific character offset.
422
- *
423
- * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
424
- * for both data-first and data-last (pipeline) usage.
425
- *
426
- * @param root - The AST root node obtained from {@link parseTree}.
427
- * @param targetOffset - A zero-based character offset into the original JSONC string.
428
- *
429
- * @returns `Effect<Option<JsoncPath>>` — an array of path segments (string keys
430
- * and numeric indices) leading to the innermost node at the offset, or
431
- * `Option.none()` if the offset is outside the tree.
432
- *
433
- * @remarks
434
- * Returns the path segments leading to the innermost node that spans the given
435
- * offset. This is the inverse of {@link findNode} — given an offset you get the path,
436
- * and given a path you get the node.
437
- *
438
- * @see {@link findNodeAtOffset} — returns the node itself rather than its path
439
- * @see {@link JsoncPath} — the path segment array type
440
- *
441
- * @example Getting the path at an offset
442
- * ```ts
443
- * import { Effect, Option } from "effect";
444
- * import type { JsoncNode, JsoncPath } from "jsonc-effect";
445
- * import { parseTree, getNodePath } from "jsonc-effect";
446
- *
447
- * const program = Effect.gen(function* () {
448
- * const root: Option.Option<JsoncNode> = yield* parseTree('{ "a": { "b": 42 } }');
449
- * if (Option.isNone(root)) return Option.none();
450
- * // Offset 15 points inside the value 42
451
- * return yield* getNodePath(root.value, 15);
452
- * });
453
- *
454
- * const result: Option.Option<JsoncPath> = Effect.runSync(program);
455
- * // result is Option.some(["a", "b"])
456
- * ```
457
- *
458
- * @public
459
- */
460
- export declare const getNodePath: {
461
- (targetOffset: number): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncPath>>;
462
- (root: JsoncNode, targetOffset: number): Effect.Effect<Option.Option<JsoncPath>>;
463
- };
464
-
465
- /**
466
- * Reconstruct a plain JavaScript value from an AST subtree.
467
- *
468
- * @param node - The AST node to evaluate, typically obtained via {@link findNode} or
469
- * as the root from {@link parseTree}.
470
- *
471
- * @returns `Effect<unknown>` — the reconstructed JS value (object, array, string,
472
- * number, boolean, or null).
473
- *
474
- * @remarks
475
- * Recursively evaluates the node tree to produce a plain JavaScript value.
476
- * This is the inverse of {@link parseTree}: where `parseTree` turns a JSONC string
477
- * into an AST, `getNodeValue` turns an AST subtree back into a JS value.
478
- *
479
- * @see {@link parseTree} — produces the AST that this function evaluates
480
- * @see {@link findNode} — locates a subtree to pass to this function
481
- *
482
- * @example Extracting the value of a found node
483
- * ```ts
484
- * import { Effect, Option } from "effect";
485
- * import type { JsoncNode } from "jsonc-effect";
486
- * import { parseTree, findNode, getNodeValue } from "jsonc-effect";
487
- *
488
- * const program = Effect.gen(function* () {
489
- * const root: Option.Option<JsoncNode> = yield* parseTree('{ "items": [1, 2, 3] }');
490
- * if (Option.isNone(root)) return undefined;
491
- * const node: Option.Option<JsoncNode> = yield* findNode(root.value, ["items"]);
492
- * if (Option.isNone(node)) return undefined;
493
- * return yield* getNodeValue(node.value);
494
- * });
495
- *
496
- * const result = Effect.runSync(program);
497
- * // result is [1, 2, 3]
498
- * ```
499
- *
500
- * @privateRemarks
501
- * Useful after {@link findNode} to extract a subtree's value without manual
502
- * AST traversal.
503
- *
504
- * @public
505
- */
506
- export declare const getNodeValue: (node: JsoncNode) => Effect.Effect<unknown, never, never>;
507
-
508
- /**
509
- * A non-mutating text edit describing a replacement within a JSONC document.
510
- *
511
- * @remarks
512
- * Edits use zero-based `offset` and `length` to identify the span of text
513
- * to replace, and `content` for the replacement string. To insert without
514
- * removing text, set `length` to `0`. To delete without inserting, set
515
- * `content` to `""`.
516
- *
517
- * Edits returned by {@link format} and {@link modify} should be applied
518
- * via {@link applyEdits}, which processes them in reverse order so that
519
- * earlier offsets remain valid.
520
- *
521
- * @see {@link format} — produces edits for formatting
522
- * @see {@link modify} produces edits for value changes
523
- * @see {@link applyEdits} applies an array of edits to a source string
524
- *
525
- * @example
526
- * ```ts
527
- * import { JsoncEdit } from "jsonc-effect";
528
- *
529
- * // An edit that inserts ", true" at offset 10
530
- * const edit = new JsoncEdit({ offset: 10, length: 0, content: ", true" });
531
- *
532
- * console.log(edit.offset); // 10
533
- * console.log(edit.length); // 0
534
- * console.log(edit.content); // ", true"
535
- * ```
536
- *
537
- * @public
538
- */
539
- export declare class JsoncEdit extends JsoncEdit_base {
540
- }
541
-
542
- declare const JsoncEdit_base: Schema.Class<JsoncEdit, {
543
- offset: typeof Schema.Number;
544
- length: typeof Schema.Number;
545
- content: typeof Schema.String;
546
- }, Schema.Struct.Encoded<{
547
- offset: typeof Schema.Number;
548
- length: typeof Schema.Number;
549
- content: typeof Schema.String;
550
- }>, never, {
551
- readonly content: string;
552
- } & {
553
- readonly length: number;
554
- } & {
555
- readonly offset: number;
556
- }, {}, {}>;
557
-
558
- /**
559
- * Union of all JSONC error types, useful for exhaustive error handling
560
- * with `Effect.catchTags`.
561
- *
562
- * @see {@link JsoncParseError}
563
- * @see {@link JsoncNodeNotFoundError}
564
- * @see {@link JsoncModificationError}
565
- *
566
- * @example
567
- * ```ts
568
- * import { Effect } from "effect";
569
- * import type { JsoncError } from "jsonc-effect";
570
- * import { parse, parseTree, findNode, modify } from "jsonc-effect";
571
- *
572
- * const program = parse("{}").pipe(
573
- * Effect.catchTags({
574
- * JsoncParseError: (e) => Effect.succeed("parse failed"),
575
- * JsoncModificationError: (e) => Effect.succeed("modify failed"),
576
- * JsoncNodeNotFoundError: (e) => Effect.succeed("node not found"),
577
- * }),
578
- * );
579
- * ```
580
- *
581
- * @public
582
- */
583
- export declare type JsoncError = JsoncParseError | JsoncNodeNotFoundError | JsoncModificationError;
584
-
585
- /**
586
- * Options controlling JSONC formatting behavior.
587
- *
588
- * @remarks
589
- * - `tabSize` — number of spaces per indentation level. Defaults to `2`.
590
- * - `insertSpaces` — when `true`, use spaces for indentation; when `false`,
591
- * use tab characters. Defaults to `true`.
592
- * - `eol` — the end-of-line sequence. Defaults to `"\n"`.
593
- * - `insertFinalNewline` when `true`, ensure the formatted output ends
594
- * with a newline. Defaults to `false`.
595
- * - `keepLines` — when `true`, preserve existing line breaks in the source
596
- * rather than reflowing. Defaults to `false`.
597
- *
598
- * @see {@link format} — uses these options to produce formatting edits
599
- * @see {@link formatAndApply} formats and applies edits in one step
600
- *
601
- * @example
602
- * ```ts
603
- * import { Effect } from "effect";
604
- * import { formatAndApply, JsoncFormattingOptions } from "jsonc-effect";
605
- *
606
- * const options = new JsoncFormattingOptions({
607
- * tabSize: 4,
608
- * insertSpaces: true,
609
- * insertFinalNewline: true,
610
- * });
611
- *
612
- * const program = formatAndApply('{"key":"value"}', options).pipe(
613
- * Effect.map((formatted) => console.log(formatted)),
614
- * );
615
- * ```
616
- *
617
- * @public
618
- */
619
- export declare class JsoncFormattingOptions extends JsoncFormattingOptions_base {
620
- }
621
-
622
- declare const JsoncFormattingOptions_base: Schema.Class<JsoncFormattingOptions, {
623
- tabSize: Schema.optionalWith<typeof Schema.Number, {
624
- default: () => number;
625
- }>;
626
- insertSpaces: Schema.optionalWith<typeof Schema.Boolean, {
627
- default: () => true;
628
- }>;
629
- eol: Schema.optionalWith<typeof Schema.String, {
630
- default: () => string;
631
- }>;
632
- insertFinalNewline: Schema.optionalWith<typeof Schema.Boolean, {
633
- default: () => false;
634
- }>;
635
- keepLines: Schema.optionalWith<typeof Schema.Boolean, {
636
- default: () => false;
637
- }>;
638
- }, Schema.Struct.Encoded<{
639
- tabSize: Schema.optionalWith<typeof Schema.Number, {
640
- default: () => number;
641
- }>;
642
- insertSpaces: Schema.optionalWith<typeof Schema.Boolean, {
643
- default: () => true;
644
- }>;
645
- eol: Schema.optionalWith<typeof Schema.String, {
646
- default: () => string;
647
- }>;
648
- insertFinalNewline: Schema.optionalWith<typeof Schema.Boolean, {
649
- default: () => false;
650
- }>;
651
- keepLines: Schema.optionalWith<typeof Schema.Boolean, {
652
- default: () => false;
653
- }>;
654
- }>, never, {
655
- readonly eol?: string;
656
- } & {
657
- readonly insertFinalNewline?: boolean;
658
- } & {
659
- readonly insertSpaces?: boolean;
660
- } & {
661
- readonly keepLines?: boolean;
662
- } & {
663
- readonly tabSize?: number;
664
- }, {}, {}>;
665
-
666
- /**
667
- * Pre-built `Schema<unknown, string>` that decodes a JSONC string into an
668
- * unknown JavaScript value using default parse options.
669
- *
670
- * This is the first stage of a typical parsing pipeline:
671
- *
672
- * ```
673
- * JSONC string --JsoncFromString--> unknown --YourSchema--> A
674
- * ```
675
- *
676
- * @remarks
677
- * Default parse options are used (comments allowed, trailing commas
678
- * allowed). The encode direction uses `JSON.stringify` with 2-space
679
- * indentation, which means comments present in the original JSONC
680
- * input are not preserved during a round-trip encode.
681
- *
682
- * For custom parse options, use {@link makeJsoncFromString} instead.
683
- *
684
- * @see {@link makeJsoncFromString} to create a schema with custom options.
685
- * @see {@link makeJsoncSchema} to compose JSONC parsing with a domain schema
686
- * in one step.
687
- *
688
- * @example Decode a JSONC string
689
- * ```ts
690
- * import { Schema } from "effect";
691
- * import { JsoncFromString } from "jsonc-effect";
692
- *
693
- * const value: unknown = Schema.decodeUnknownSync(JsoncFromString)(
694
- * '{ "key": 42 // comment\n}',
695
- * );
696
- * ```
697
- *
698
- * @example Compose with a domain schema
699
- * ```ts
700
- * import { Schema } from "effect";
701
- * import { JsoncFromString } from "jsonc-effect";
702
- *
703
- * const MyConfig = Schema.Struct({
704
- * name: Schema.String,
705
- * version: Schema.Number,
706
- * });
707
- *
708
- * const MyConfigFromJsonc = Schema.compose(JsoncFromString, MyConfig);
709
- * const config = Schema.decodeUnknownSync(MyConfigFromJsonc)(
710
- * '{ "name": "app", "version": 1 }',
711
- * );
712
- * ```
713
- *
714
- * @public
715
- */
716
- export declare const JsoncFromString: Schema.Schema<unknown, string>;
717
-
718
- /**
719
- * Error raised when {@link modify} produces invalid edits or encounters
720
- * an unsupported modification scenario.
721
- *
722
- * @remarks
723
- * Contains the `path` where modification was attempted and a `reason`
724
- * string explaining why it failed.
725
- *
726
- * @see {@link modify} — may fail with this error
727
- *
728
- * @example
729
- * ```ts
730
- * import { Effect } from "effect";
731
- * import { modify } from "jsonc-effect";
732
- *
733
- * const program = modify("{}", ["deep", "path"], 42).pipe(
734
- * Effect.catchTag("JsoncModificationError", (e) => {
735
- * console.error(`Failed at [${e.path.join(", ")}]: ${e.reason}`);
736
- * return Effect.succeed([]);
737
- * }),
738
- * );
739
- * ```
740
- *
741
- * @public
742
- */
743
- export declare class JsoncModificationError extends JsoncModificationErrorBase<{
744
- readonly path: ReadonlyArray<string | number>;
745
- readonly reason: string;
746
- }> {
747
- get message(): string;
748
- }
749
-
750
- /**
751
- * Base class for {@link JsoncModificationError}.
752
- *
753
- * @privateRemarks
754
- * Uses the same `*Base` pattern as {@link JsoncParseErrorBase} to work
755
- * around api-extractor's inability to roll up the complex type produced
756
- * by `Data.TaggedError` into a single `.d.ts` declaration.
757
- *
758
- * @internal
759
- */
760
- export declare const JsoncModificationErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
761
- readonly _tag: "JsoncModificationError";
762
- } & Readonly<A>;
763
-
764
- /**
765
- * AST node representing a parsed JSONC element, produced by {@link parseTree}.
766
- *
767
- * @remarks
768
- * The `parent` field present in Microsoft's `jsonc-parser` is intentionally
769
- * omitted here to avoid circular references, which would break structural
770
- * equality, serialization, and Effect's `Schema.encode`/`Schema.decode`
771
- * pipelines. Child relationships are expressed via the `children` array,
772
- * and the recursive type is handled with `Schema.suspend`.
773
- *
774
- * - `type` — the {@link JsoncNodeType} discriminator.
775
- * - `value` — the decoded JavaScript value for leaf nodes (`string`,
776
- * `number`, `boolean`, `null`); `undefined` for structural nodes.
777
- * - `offset` zero-based character offset of this node in the source.
778
- * - `length` — character length of this node in the source.
779
- * - `colonOffset` — for `"property"` nodes, the offset of the `:` separator.
780
- * - `children` — child nodes; present for `"object"`, `"array"`, and
781
- * `"property"` nodes.
782
- *
783
- * @see {@link parseTree} — produces the root `JsoncNode`
784
- * @see {@link findNode} locates a descendant by path
785
- *
786
- * @example
787
- * ```ts
788
- * import { Effect } from "effect";
789
- * import { parseTree } from "jsonc-effect";
790
- *
791
- * const program = parseTree('{ "key": [1, 2] }').pipe(
792
- * Effect.map((root) => {
793
- * // root.type === "object"
794
- * const property = root.children?.[0]; // "property" node
795
- * const array = property?.children?.[1]; // "array" node
796
- * console.log(array?.children?.length); // 2
797
- * }),
798
- * );
799
- * ```
800
- *
801
- * @privateRemarks
802
- * Unlike the `*Base` pattern needed for `Data.TaggedError` subclasses,
803
- * `Schema.Class` works directly for data types — api-extractor can roll up
804
- * the generated `.d.ts` without issues. The `Schema.suspend` call for
805
- * `children` is required to break the circular type reference at the schema
806
- * level while still allowing recursive decode/encode.
807
- *
808
- * @public
809
- */
810
- export declare class JsoncNode extends JsoncNode_base {
811
- }
812
-
813
- declare const JsoncNode_base: Schema.Class<JsoncNode, {
814
- type: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
815
- value: Schema.optional<typeof Schema.Unknown>;
816
- offset: typeof Schema.Number;
817
- length: typeof Schema.Number;
818
- colonOffset: Schema.optional<typeof Schema.Number>;
819
- children: Schema.optional<Schema.Array$<Schema.suspend<JsoncNode, JsoncNode, never>>>;
820
- }, Schema.Struct.Encoded<{
821
- type: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
822
- value: Schema.optional<typeof Schema.Unknown>;
823
- offset: typeof Schema.Number;
824
- length: typeof Schema.Number;
825
- colonOffset: Schema.optional<typeof Schema.Number>;
826
- children: Schema.optional<Schema.Array$<Schema.suspend<JsoncNode, JsoncNode, never>>>;
827
- }>, never, {
828
- readonly children?: readonly JsoncNode[] | undefined;
829
- } & {
830
- readonly colonOffset?: number | undefined;
831
- } & {
832
- readonly value?: unknown;
833
- } & {
834
- readonly length: number;
835
- } & {
836
- readonly offset: number;
837
- } & {
838
- readonly type: "array" | "boolean" | "null" | "number" | "object" | "property" | "string";
839
- }, {}, {}>;
840
-
841
- /**
842
- * Error raised when AST navigation fails to find a node at the given path.
843
- *
844
- * @remarks
845
- * Contains the `path` that was searched and the `rootNodeType` of the tree
846
- * that was traversed.
847
- *
848
- * @see {@link findNode} — may fail with this error
849
- *
850
- * @example
851
- * ```ts
852
- * import { Effect } from "effect";
853
- * import { parseTree, findNode } from "jsonc-effect";
854
- *
855
- * const program = parseTree('{ "a": 1 }').pipe(
856
- * Effect.flatMap((root) => findNode(root, ["missing", "path"])),
857
- * Effect.catchTag("JsoncNodeNotFoundError", (e) => {
858
- * console.error(`Not found: [${e.path.join(", ")}] in ${e.rootNodeType}`);
859
- * return Effect.succeed(undefined);
860
- * }),
861
- * );
862
- * ```
863
- *
864
- * @public
865
- */
866
- export declare class JsoncNodeNotFoundError extends JsoncNodeNotFoundErrorBase<{
867
- readonly path: ReadonlyArray<string | number>;
868
- readonly rootNodeType: string;
869
- }> {
870
- get message(): string;
871
- }
872
-
873
- /**
874
- * Base class for {@link JsoncNodeNotFoundError}.
875
- *
876
- * @privateRemarks
877
- * Uses the same `*Base` pattern as {@link JsoncParseErrorBase} to work
878
- * around api-extractor's inability to roll up the complex type produced
879
- * by `Data.TaggedError` into a single `.d.ts` declaration.
880
- *
881
- * @internal
882
- */
883
- export declare const JsoncNodeNotFoundErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
884
- readonly _tag: "JsoncNodeNotFoundError";
885
- } & Readonly<A>;
886
-
887
- /**
888
- * Discriminator values for JSONC AST node types.
889
- *
890
- * @remarks
891
- * These correspond to the JSON value types (`"string"`, `"number"`,
892
- * `"boolean"`, `"null"`) plus structural types (`"object"`, `"array"`)
893
- * and the special `"property"` type representing a key-value pair inside
894
- * an object.
895
- *
896
- * @see {@link JsoncNode} the AST node that carries this discriminator
897
- *
898
- * @public
899
- */
900
- export declare const JsoncNodeType: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
901
-
902
- /**
903
- * The union of all JSONC AST node type string literals.
904
- *
905
- * @see {@link JsoncNodeType}
906
- *
907
- * @public
908
- */
909
- export declare type JsoncNodeType = Schema.Schema.Type<typeof JsoncNodeType>;
910
-
911
- /**
912
- * Error raised when JSONC parsing encounters one or more syntax errors.
913
- *
914
- * @remarks
915
- * Contains the full source `text`, the `options` used for parsing, and an
916
- * `errors` array of {@link JsoncParseErrorDetail} instances with precise
917
- * position information for each problem found.
918
- *
919
- * @see {@link parse} — may fail with this error
920
- * @see {@link parseTree} — may fail with this error
921
- *
922
- * @example Catching with `Effect.catchTag`
923
- * ```ts
924
- * import { Effect } from "effect";
925
- * import { parse } from "jsonc-effect";
926
- *
927
- * const program = parse("{ invalid }").pipe(
928
- * Effect.catchTag("JsoncParseError", (e) => {
929
- * console.error(e.errors); // Array of JsoncParseErrorDetail
930
- * return Effect.succeed({});
931
- * }),
932
- * );
933
- * ```
934
- *
935
- * @example Inspecting error details
936
- * ```ts
937
- * import { Effect } from "effect";
938
- * import { parse } from "jsonc-effect";
939
- *
940
- * const program = parse("{ invalid }").pipe(
941
- * Effect.catchTag("JsoncParseError", (e) => {
942
- * for (const detail of e.errors) {
943
- * console.error(
944
- * `[${detail.code}] ${detail.message} at line ${detail.startLine}:${detail.startCharacter}`,
945
- * );
946
- * }
947
- * return Effect.succeed({});
948
- * }),
949
- * );
950
- * ```
951
- *
952
- * @public
953
- */
954
- export declare class JsoncParseError extends JsoncParseErrorBase<{
955
- readonly errors: ReadonlyArray<JsoncParseErrorDetail>;
956
- readonly text: string;
957
- readonly options?: Partial<JsoncParseOptions>;
958
- }> {
959
- get message(): string;
960
- }
961
-
962
- /**
963
- * Base class for {@link JsoncParseError}.
964
- *
965
- * @privateRemarks
966
- * The `*Base` pattern is required because `Data.TaggedError` produces complex
967
- * type signatures involving intersection types and branded generics that
968
- * api-extractor cannot roll up into a single `.d.ts` bundle. By exporting
969
- * the base separately as `@internal`, the public `JsoncParseError` class
970
- * extends it with concrete fields, giving api-extractor a simple class
971
- * declaration to work with.
972
- *
973
- * @internal
974
- */
975
- export declare const JsoncParseErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
976
- readonly _tag: "JsoncParseError";
977
- } & Readonly<A>;
978
-
979
- /**
980
- * Error codes representing specific JSONC parse failures.
981
- *
982
- * @remarks
983
- * Each code maps to a distinct syntactic error the parser can encounter,
984
- * from invalid symbols and number formats to missing delimiters and
985
- * unexpected end-of-input conditions.
986
- *
987
- * @see {@link JsoncParseErrorDetail} — carries one of these codes alongside
988
- * position information
989
- *
990
- * @public
991
- */
992
- export declare const JsoncParseErrorCode: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
993
-
994
- /**
995
- * The union of all JSONC parse error code string literals.
996
- *
997
- * @see {@link JsoncParseErrorCode}
998
- *
999
- * @public
1000
- */
1001
- export declare type JsoncParseErrorCode = Schema.Schema.Type<typeof JsoncParseErrorCode>;
1002
-
1003
- /**
1004
- * Detail for a single parse error, including the error code, a human-readable
1005
- * message, and the exact position within the source document.
1006
- *
1007
- * @remarks
1008
- * - `code` — a {@link JsoncParseErrorCode} identifying the error kind.
1009
- * - `message` — a descriptive message suitable for display.
1010
- * - `offset` zero-based character offset where the error occurred.
1011
- * - `length` — character length of the problematic span.
1012
- * - `startLine` — zero-based line number of the error.
1013
- * - `startCharacter` — zero-based column within `startLine`.
1014
- *
1015
- * @see {@link JsoncParseError} aggregates an array of these details
1016
- *
1017
- * @example
1018
- * ```ts
1019
- * import { JsoncParseErrorDetail } from "jsonc-effect";
1020
- *
1021
- * const detail = new JsoncParseErrorDetail({
1022
- * code: "ValueExpected",
1023
- * message: "Value expected",
1024
- * offset: 5,
1025
- * length: 1,
1026
- * startLine: 0,
1027
- * startCharacter: 5,
1028
- * });
1029
- *
1030
- * console.log(detail.code); // "ValueExpected"
1031
- * console.log(detail.offset); // 5
1032
- * ```
1033
- *
1034
- * @public
1035
- */
1036
- export declare class JsoncParseErrorDetail extends JsoncParseErrorDetail_base {
1037
- }
1038
-
1039
- declare const JsoncParseErrorDetail_base: Schema.Class<JsoncParseErrorDetail, {
1040
- code: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
1041
- message: typeof Schema.String;
1042
- offset: typeof Schema.Number;
1043
- length: typeof Schema.Number;
1044
- startLine: typeof Schema.Number;
1045
- startCharacter: typeof Schema.Number;
1046
- }, Schema.Struct.Encoded<{
1047
- code: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
1048
- message: typeof Schema.String;
1049
- offset: typeof Schema.Number;
1050
- length: typeof Schema.Number;
1051
- startLine: typeof Schema.Number;
1052
- startCharacter: typeof Schema.Number;
1053
- }>, never, {
1054
- readonly code: "CloseBraceExpected" | "CloseBracketExpected" | "ColonExpected" | "CommaExpected" | "EndOfFileExpected" | "InvalidCharacter" | "InvalidCommentToken" | "InvalidEscapeCharacter" | "InvalidNumberFormat" | "InvalidSymbol" | "InvalidUnicode" | "PropertyNameExpected" | "UnexpectedEndOfComment" | "UnexpectedEndOfNumber" | "UnexpectedEndOfString" | "ValueExpected";
1055
- } & {
1056
- readonly length: number;
1057
- } & {
1058
- readonly message: string;
1059
- } & {
1060
- readonly offset: number;
1061
- } & {
1062
- readonly startCharacter: number;
1063
- } & {
1064
- readonly startLine: number;
1065
- }, {}, {}>;
1066
-
1067
- /**
1068
- * Options controlling JSONC parse behavior.
1069
- *
1070
- * @remarks
1071
- * - `disallowComments` — when `true`, line and block comments are treated
1072
- * as parse errors. Defaults to `false`.
1073
- * - `allowTrailingComma` — when `true`, trailing commas after the last
1074
- * element in arrays and objects are permitted. Defaults to `true`, which
1075
- * differs from Microsoft's `jsonc-parser` (where the default is `false`).
1076
- * - `allowEmptyContent` — when `true`, an empty string parses as
1077
- * `undefined` rather than producing an error. Defaults to `false`.
1078
- *
1079
- * @see {@link parse} — parses JSONC text into a JavaScript value
1080
- * @see {@link parseTree} parses JSONC text into an AST
1081
- *
1082
- * @example
1083
- * ```ts
1084
- * import { Effect } from "effect";
1085
- * import { parse, JsoncParseOptions } from "jsonc-effect";
1086
- *
1087
- * const options = new JsoncParseOptions({
1088
- * disallowComments: true,
1089
- * allowTrailingComma: false,
1090
- * });
1091
- *
1092
- * const program = parse('{ "key": "value" }', options).pipe(
1093
- * Effect.map((value) => console.log(value)),
1094
- * );
1095
- * ```
1096
- *
1097
- * @public
1098
- */
1099
- export declare class JsoncParseOptions extends JsoncParseOptions_base {
1100
- }
1101
-
1102
- declare const JsoncParseOptions_base: Schema.Class<JsoncParseOptions, {
1103
- disallowComments: Schema.optionalWith<typeof Schema.Boolean, {
1104
- default: () => false;
1105
- }>;
1106
- allowTrailingComma: Schema.optionalWith<typeof Schema.Boolean, {
1107
- default: () => true;
1108
- }>;
1109
- allowEmptyContent: Schema.optionalWith<typeof Schema.Boolean, {
1110
- default: () => false;
1111
- }>;
1112
- }, Schema.Struct.Encoded<{
1113
- disallowComments: Schema.optionalWith<typeof Schema.Boolean, {
1114
- default: () => false;
1115
- }>;
1116
- allowTrailingComma: Schema.optionalWith<typeof Schema.Boolean, {
1117
- default: () => true;
1118
- }>;
1119
- allowEmptyContent: Schema.optionalWith<typeof Schema.Boolean, {
1120
- default: () => false;
1121
- }>;
1122
- }>, never, {
1123
- readonly allowEmptyContent?: boolean;
1124
- } & {
1125
- readonly allowTrailingComma?: boolean;
1126
- } & {
1127
- readonly disallowComments?: boolean;
1128
- }, {}, {}>;
1129
-
1130
- /**
1131
- * An ordered sequence of {@link JsoncSegment} values describing a location
1132
- * within a JSONC document tree.
1133
- *
1134
- * @see {@link findNode} resolves a `JsoncPath` to an AST node
1135
- * @see {@link modify} applies a modification at a `JsoncPath`
1136
- *
1137
- * @example
1138
- * ```ts
1139
- * import type { JsoncPath } from "jsonc-effect";
1140
- *
1141
- * // Path to the "strict" property inside "compilerOptions"
1142
- * const path: JsoncPath = ["compilerOptions", "strict"];
1143
- *
1144
- * // Path to the second element of the "include" array
1145
- * const arrayPath: JsoncPath = ["include", 1];
1146
- * ```
1147
- *
1148
- * @public
1149
- */
1150
- export declare const JsoncPath: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
1151
-
1152
- /**
1153
- * An array of path segments `ReadonlyArray<string | number>`.
1154
- *
1155
- * @see {@link JsoncPath}
1156
- *
1157
- * @public
1158
- */
1159
- export declare type JsoncPath = Schema.Schema.Type<typeof JsoncPath>;
1160
-
1161
- /**
1162
- * A range within a JSONC document, expressed as a zero-based character
1163
- * offset and a length in characters.
1164
- *
1165
- * @remarks
1166
- * Both `offset` and `length` are measured in UTF-16 code units (JavaScript
1167
- * string indices). Pass a `JsoncRange` to {@link format} to restrict
1168
- * formatting to a specific region of the document rather than the whole file.
1169
- *
1170
- * @see {@link format} — accepts an optional `JsoncRange` parameter
1171
- *
1172
- * @public
1173
- */
1174
- export declare class JsoncRange extends JsoncRange_base {
1175
- }
1176
-
1177
- declare const JsoncRange_base: Schema.Class<JsoncRange, {
1178
- offset: typeof Schema.Number;
1179
- length: typeof Schema.Number;
1180
- }, Schema.Struct.Encoded<{
1181
- offset: typeof Schema.Number;
1182
- length: typeof Schema.Number;
1183
- }>, never, {
1184
- readonly length: number;
1185
- } & {
1186
- readonly offset: number;
1187
- }, {}, {}>;
1188
-
1189
- /**
1190
- * Scanner error codes produced by the JSONC scanner.
1191
- *
1192
- * @remarks
1193
- * `"None"` indicates a successful scan with no errors. All other values
1194
- * describe a specific lexical error encountered while tokenizing input.
1195
- *
1196
- * @see {@link JsoncScanner} — the scanner interface that reports these errors
1197
- *
1198
- * @public
1199
- */
1200
- export declare const JsoncScanError: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
1201
-
1202
- /**
1203
- * The union of all JSONC scan error string literals.
1204
- *
1205
- * @see {@link JsoncScanError}
1206
- *
1207
- * @public
1208
- */
1209
- export declare type JsoncScanError = Schema.Schema.Type<typeof JsoncScanError>;
1210
-
1211
- /**
1212
- * Stateful cursor over JSONC text that produces tokens on demand.
1213
- *
1214
- * @remarks
1215
- * The scanner is the lowest-level API in jsonc-effect. It exposes an
1216
- * imperative scan-loop pattern: call {@link JsoncScanner.scan | scan()} in a
1217
- * loop until it returns `"EOF"`, inspecting the current token with the
1218
- * getter methods after each call.
1219
- *
1220
- * Unlike the rest of the library, the scanner is **mutable** — each call to
1221
- * `scan()` advances an internal cursor and updates all token-related state.
1222
- *
1223
- * @see {@link createScanner} — factory function that produces a `JsoncScanner`
1224
- * @see {@link JsoncSyntaxKind} string literal union of all token types
1225
- *
1226
- * @example
1227
- * Collecting all structural tokens from a JSONC string:
1228
- * ```ts
1229
- * import type { JsoncSyntaxKind } from "jsonc-effect";
1230
- * import { createScanner } from "jsonc-effect";
1231
- *
1232
- * const scanner = createScanner('{ "key": 42 }', true);
1233
- * const tokens: JsoncSyntaxKind[] = [];
1234
- * let kind: JsoncSyntaxKind;
1235
- * do {
1236
- * kind = scanner.scan();
1237
- * tokens.push(kind);
1238
- * } while (kind !== "EOF");
1239
- * console.log(tokens);
1240
- * // ["OpenBrace", "String", "Colon", "Number", "CloseBrace", "EOF"]
1241
- * ```
1242
- *
1243
- * @privateRemarks
1244
- * The scanner is the only mutable/stateful part of the library. All other
1245
- * APIs are pure Effect pipelines built on top of it.
1246
- *
1247
- * @public
1248
- */
1249
- export declare interface JsoncScanner {
1250
- /** Advance the cursor to the next token and return its {@link JsoncSyntaxKind}. */
1251
- scan(): JsoncSyntaxKind;
1252
- /** Return the {@link JsoncSyntaxKind} of the current token without advancing. */
1253
- getToken(): JsoncSyntaxKind;
1254
- /** Return the string value of the current token (e.g. the unescaped content of a string literal). */
1255
- getTokenValue(): string;
1256
- /** Return the zero-based character offset where the current token begins. */
1257
- getTokenOffset(): number;
1258
- /** Return the character length of the current token. */
1259
- getTokenLength(): number;
1260
- /** Return the zero-based line number where the current token starts. */
1261
- getTokenStartLine(): number;
1262
- /** Return the zero-based character position within the line where the current token starts. */
1263
- getTokenStartCharacter(): number;
1264
- /** Return the {@link JsoncScanError} for the current token, or `"None"` if no error. */
1265
- getTokenError(): JsoncScanError;
1266
- /** Return the current cursor position (byte offset into the source text). */
1267
- getPosition(): number;
1268
- /** Set the cursor position, resetting the current token state. */
1269
- setPosition(pos: number): void;
1270
- }
1271
-
1272
- /**
1273
- * A single segment of a {@link JsoncPath}: a `string` for object property
1274
- * keys or a `number` for array indices.
1275
- *
1276
- * @see {@link findNode} — resolves a path to an AST node
1277
- * @see {@link modify} — applies a value change at a path
1278
- *
1279
- * @example
1280
- * ```ts
1281
- * import type { JsoncSegment } from "jsonc-effect";
1282
- *
1283
- * const objectKey: JsoncSegment = "compilerOptions";
1284
- * const arrayIndex: JsoncSegment = 0;
1285
- * ```
1286
- *
1287
- * @public
1288
- */
1289
- export declare const JsoncSegment: Schema.Union<[typeof Schema.String, typeof Schema.Number]>;
1290
-
1291
- /**
1292
- * A single path segment type `string | number`.
1293
- *
1294
- * @see {@link JsoncSegment}
1295
- *
1296
- * @public
1297
- */
1298
- export declare type JsoncSegment = Schema.Schema.Type<typeof JsoncSegment>;
1299
-
1300
- /**
1301
- * Token types produced by the JSONC scanner.
1302
- *
1303
- * @remarks
1304
- * Uses string literals instead of numeric enums so that token kinds are
1305
- * self-documenting in debug output, log messages, and test assertions.
1306
- * This avoids the "reverse-mapping" confusion of TypeScript numeric enums
1307
- * and makes pattern-matching with `Schema.Literal` straightforward.
1308
- *
1309
- * @see {@link createScanner} — creates a scanner that emits these token types
1310
- *
1311
- * @public
1312
- */
1313
- export declare const JsoncSyntaxKind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
1314
-
1315
- /**
1316
- * The union of all JSONC token kind string literals.
1317
- *
1318
- * @see {@link JsoncSyntaxKind}
1319
- *
1320
- * @public
1321
- */
1322
- export declare type JsoncSyntaxKind = Schema.Schema.Type<typeof JsoncSyntaxKind>;
1323
-
1324
- /**
1325
- * A single token produced by the JSONC scanner, carrying its kind, textual
1326
- * value, position within the source, and any scan error.
1327
- *
1328
- * @remarks
1329
- * - `kind` the {@link JsoncSyntaxKind} discriminator for this token.
1330
- * - `value` — the raw text slice from the source document.
1331
- * - `offset` zero-based character offset from the start of the document.
1332
- * - `length` — character length of this token in the source.
1333
- * - `startLine` zero-based line number where the token begins.
1334
- * - `startCharacter` — zero-based column within `startLine`.
1335
- * - `error` — a {@link JsoncScanError} code; `"None"` when the token is valid.
1336
- *
1337
- * @see {@link createScanner} — produces a stream of `JsoncToken` instances
1338
- *
1339
- * @example
1340
- * ```ts
1341
- * import { JsoncToken } from "jsonc-effect";
1342
- *
1343
- * const token = new JsoncToken({
1344
- * kind: "String",
1345
- * value: '"hello"',
1346
- * offset: 0,
1347
- * length: 7,
1348
- * startLine: 0,
1349
- * startCharacter: 0,
1350
- * error: "None",
1351
- * });
1352
- *
1353
- * console.log(token.kind); // "String"
1354
- * console.log(token.value); // '"hello"'
1355
- * ```
1356
- *
1357
- * @privateRemarks
1358
- * `Schema.Class` gives `JsoncToken` structural equality via `Data.Class`
1359
- * under the hood, so two tokens with identical fields are considered equal
1360
- * by `Equal.equals`. This is essential for test assertions and Effect's
1361
- * structural comparison semantics.
1362
- *
1363
- * @public
1364
- */
1365
- export declare class JsoncToken extends JsoncToken_base {
1366
- }
1367
-
1368
- declare const JsoncToken_base: Schema.Class<JsoncToken, {
1369
- kind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
1370
- value: typeof Schema.String;
1371
- offset: typeof Schema.Number;
1372
- length: typeof Schema.Number;
1373
- startLine: typeof Schema.Number;
1374
- startCharacter: typeof Schema.Number;
1375
- error: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
1376
- }, Schema.Struct.Encoded<{
1377
- kind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
1378
- value: typeof Schema.String;
1379
- offset: typeof Schema.Number;
1380
- length: typeof Schema.Number;
1381
- startLine: typeof Schema.Number;
1382
- startCharacter: typeof Schema.Number;
1383
- error: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
1384
- }>, never, {
1385
- readonly error: "InvalidCharacter" | "InvalidEscapeCharacter" | "InvalidSymbol" | "InvalidUnicode" | "None" | "UnexpectedEndOfComment" | "UnexpectedEndOfNumber" | "UnexpectedEndOfString";
1386
- } & {
1387
- readonly kind: "BlockComment" | "CloseBrace" | "CloseBracket" | "Colon" | "Comma" | "EOF" | "False" | "LineBreak" | "LineComment" | "Null" | "Number" | "OpenBrace" | "OpenBracket" | "String" | "Trivia" | "True" | "Unknown";
1388
- } & {
1389
- readonly length: number;
1390
- } & {
1391
- readonly offset: number;
1392
- } & {
1393
- readonly startCharacter: number;
1394
- } & {
1395
- readonly startLine: number;
1396
- } & {
1397
- readonly value: string;
1398
- }, {}, {}>;
1399
-
1400
- /**
1401
- * Discriminated union of JSONC visitor events.
1402
- *
1403
- * Each variant carries an `_tag` discriminant, an `offset`, and a `length`
1404
- * describing where the event occurred in the source text. Some variants
1405
- * include additional fields such as `path`, `value`, or `property`.
1406
- *
1407
- * @remarks
1408
- * The nine event types are:
1409
- *
1410
- * - **ObjectBegin** — opening `{` of an object, includes `path`.
1411
- * - **ObjectEnd** closing `}` of an object.
1412
- * - **ObjectProperty** a property key, includes `property` and `path`.
1413
- * - **ArrayBegin** — opening `[` of an array, includes `path`.
1414
- * - **ArrayEnd** — closing `]` of an array.
1415
- * - **LiteralValue** — a string, number, boolean, or null literal,
1416
- * includes `value` and `path`.
1417
- * - **Separator** — a `,` or `:` character.
1418
- * - **Comment** a line or block comment.
1419
- * - **Error** — a parse error, includes a {@link JsoncParseErrorCode} `code`.
1420
- *
1421
- * Use the `_tag` field to discriminate between variants in `switch`
1422
- * statements or {@link https://effect.website/docs/stream/operations | Stream}
1423
- * filter predicates.
1424
- *
1425
- * @see {@link visit} to produce a stream of these events.
1426
- * @see {@link visitCollect} to collect matching events in one step.
1427
- *
1428
- * @example Filtering events by tag
1429
- * ```ts
1430
- * import { Chunk, Effect, Stream } from "effect";
1431
- * import type { JsoncVisitorEvent } from "jsonc-effect";
1432
- * import { visit } from "jsonc-effect";
1433
- *
1434
- * const literals = Effect.runSync(
1435
- * visit('{ "a": 1 }').pipe(
1436
- * Stream.filter(
1437
- * (e): e is Extract<JsoncVisitorEvent, { _tag: "LiteralValue" }> =>
1438
- * e._tag === "LiteralValue",
1439
- * ),
1440
- * Stream.runCollect,
1441
- * Effect.map(Chunk.toReadonlyArray),
1442
- * ),
1443
- * );
1444
- * ```
1445
- *
1446
- * @public
1447
- */
1448
- export declare type JsoncVisitorEvent = {
1449
- readonly _tag: "ObjectBegin";
1450
- readonly offset: number;
1451
- readonly length: number;
1452
- readonly path: ReadonlyArray<string | number>;
1453
- } | {
1454
- readonly _tag: "ObjectEnd";
1455
- readonly offset: number;
1456
- readonly length: number;
1457
- } | {
1458
- readonly _tag: "ObjectProperty";
1459
- readonly property: string;
1460
- readonly offset: number;
1461
- readonly length: number;
1462
- readonly path: ReadonlyArray<string | number>;
1463
- } | {
1464
- readonly _tag: "ArrayBegin";
1465
- readonly offset: number;
1466
- readonly length: number;
1467
- readonly path: ReadonlyArray<string | number>;
1468
- } | {
1469
- readonly _tag: "ArrayEnd";
1470
- readonly offset: number;
1471
- readonly length: number;
1472
- } | {
1473
- readonly _tag: "LiteralValue";
1474
- readonly value: unknown;
1475
- readonly offset: number;
1476
- readonly length: number;
1477
- readonly path: ReadonlyArray<string | number>;
1478
- } | {
1479
- readonly _tag: "Separator";
1480
- readonly character: string;
1481
- readonly offset: number;
1482
- readonly length: number;
1483
- } | {
1484
- readonly _tag: "Comment";
1485
- readonly offset: number;
1486
- readonly length: number;
1487
- } | {
1488
- readonly _tag: "Error";
1489
- readonly code: JsoncParseErrorCode;
1490
- readonly offset: number;
1491
- readonly length: number;
1492
- };
1493
-
1494
- /**
1495
- * Create a `Schema<unknown, string>` that decodes JSONC with custom
1496
- * parse options.
1497
- *
1498
- * @param options - Partial {@link JsoncParseOptions} controlling comment
1499
- * handling and trailing-comma tolerance.
1500
- * @returns A `Schema<unknown, string>` configured with the given options.
1501
- *
1502
- * @remarks
1503
- * The encode direction uses `JSON.stringify` with 2-space indentation,
1504
- * which produces standard JSON. Comments present in the original JSONC
1505
- * input are not preserved during a round-trip encode.
1506
- *
1507
- * @see {@link JsoncFromString} for a zero-config default instance.
1508
- * @see {@link makeJsoncSchema} to compose JSONC parsing with a domain
1509
- * schema in one step.
1510
- *
1511
- * @example Strict mode (no comments, no trailing commas)
1512
- * ```ts
1513
- * import { Schema } from "effect";
1514
- * import { makeJsoncFromString } from "jsonc-effect";
1515
- *
1516
- * const StrictJsoncFromString = makeJsoncFromString({
1517
- * disallowComments: true,
1518
- * allowTrailingComma: false,
1519
- * });
1520
- *
1521
- * const value: unknown = Schema.decodeUnknownSync(StrictJsoncFromString)(
1522
- * '{ "key": 42 }',
1523
- * );
1524
- * ```
1525
- *
1526
- * @privateRemarks
1527
- * Internally delegates to `Schema.transformOrFail` to wire up the decode
1528
- * and encode directions.
1529
- *
1530
- * @public
1531
- */
1532
- export declare function makeJsoncFromString(options?: Partial<JsoncParseOptions>): Schema.Schema<unknown, string>;
1533
-
1534
- /**
1535
- * Create a composed `Schema<A, string>` that parses a JSONC string and
1536
- * validates the result against a target domain schema in one step.
1537
- *
1538
- * @param targetSchema - The domain schema to validate the parsed value
1539
- * against. Its input type `I` must be assignable from `unknown`.
1540
- * @param options - Optional partial {@link JsoncParseOptions} forwarded to
1541
- * the underlying JSONC parser.
1542
- * @returns A `Schema<A, string>` that goes directly from a JSONC string
1543
- * to a fully validated domain value of type `A`.
1544
- *
1545
- * @remarks
1546
- * Internally composes two schema stages:
1547
- *
1548
- * 1. JSONC string to `unknown` (via {@link makeJsoncFromString}).
1549
- * 2. `unknown` to `A` (via the provided `targetSchema`).
1550
- *
1551
- * This avoids the need to manually call `Schema.compose`.
1552
- *
1553
- * @see {@link makeJsoncFromString} for the first stage of the pipeline.
1554
- *
1555
- * @example Typed configuration from JSONC
1556
- * ```ts
1557
- * import { Schema } from "effect";
1558
- * import { makeJsoncSchema } from "jsonc-effect";
1559
- *
1560
- * const MyConfig = Schema.Struct({
1561
- * name: Schema.String,
1562
- * version: Schema.Number,
1563
- * });
1564
- *
1565
- * const MyConfigFromJsonc = makeJsoncSchema(MyConfig);
1566
- * const config = Schema.decodeUnknownSync(MyConfigFromJsonc)(
1567
- * '{ "name": "app", "version": 1 }',
1568
- * );
1569
- * ```
1570
- *
1571
- * @example With custom parse options
1572
- * ```ts
1573
- * import { Schema } from "effect";
1574
- * import { makeJsoncSchema } from "jsonc-effect";
1575
- *
1576
- * const MyConfig = Schema.Struct({ debug: Schema.Boolean });
1577
- *
1578
- * const StrictConfig = makeJsoncSchema(MyConfig, {
1579
- * disallowComments: true,
1580
- * allowTrailingComma: false,
1581
- * });
1582
- *
1583
- * const config = Schema.decodeUnknownSync(StrictConfig)(
1584
- * '{ "debug": true }',
1585
- * );
1586
- * ```
1587
- *
1588
- * @privateRemarks
1589
- * Uses `Schema.compose` internally to chain the JSONC-from-string schema
1590
- * with the provided target schema.
1591
- *
1592
- * @public
1593
- */
1594
- export declare const makeJsoncSchema: <A, I>(targetSchema: Schema.Schema<A, I, never>, options?: Partial<JsoncParseOptions> | undefined) => Schema.Schema<A, string, never>;
1595
-
1596
- /**
1597
- * Compute edits to insert, replace, or remove a value at a JSON path.
1598
- *
1599
- * This is a {@link https://effect.website/docs/function-dual | Function.dual}
1600
- * that supports both data-first and data-last (pipeline) usage.
1601
- *
1602
- * @param text - The JSONC source text to modify.
1603
- * @param path - A {@link JsoncPath} (array of string keys and numeric indices)
1604
- * identifying the target location in the JSON structure.
1605
- * @param value - The value to set. Pass `undefined` to remove the
1606
- * property or array element at the given path.
1607
- * @param options - Optional object with `formattingOptions` controlling
1608
- * indent size, tabs vs. spaces, and EOL style for generated text.
1609
- * @returns An `Effect` that succeeds with a read-only array of
1610
- * {@link JsoncEdit} objects, or fails with a
1611
- * {@link JsoncModificationError} if the path cannot be navigated.
1612
- *
1613
- * @remarks
1614
- * Setting `value` to `undefined` removes the targeted property or element,
1615
- * including its surrounding comma. When inserting a new property into an
1616
- * object, it is appended after the last existing property.
1617
- *
1618
- * @see {@link applyEdits} to apply the returned edits to the source text.
1619
- * @see {@link JsoncModificationError} for the error type on navigation failure.
1620
- *
1621
- * @example Update an existing property
1622
- * ```ts
1623
- * import { Effect } from "effect";
1624
- * import { modify, applyEdits } from "jsonc-effect";
1625
- *
1626
- * const input = '{ "a": 1 }';
1627
- * const edits = Effect.runSync(modify(input, ["a"], 2));
1628
- * const result: string = Effect.runSync(applyEdits(input, edits));
1629
- * ```
1630
- *
1631
- * @example Insert a new property
1632
- * ```ts
1633
- * import { Effect } from "effect";
1634
- * import { modify, applyEdits } from "jsonc-effect";
1635
- *
1636
- * const input = '{ "a": 1 }';
1637
- * const edits = Effect.runSync(modify(input, ["b"], "hello"));
1638
- * const result: string = Effect.runSync(applyEdits(input, edits));
1639
- * ```
1640
- *
1641
- * @example Remove a property
1642
- * ```ts
1643
- * import { Effect } from "effect";
1644
- * import { modify, applyEdits } from "jsonc-effect";
1645
- *
1646
- * const input = '{ "a": 1, "b": 2 }';
1647
- * const edits = Effect.runSync(modify(input, ["a"], undefined));
1648
- * const result: string = Effect.runSync(applyEdits(input, edits));
1649
- * ```
1650
- *
1651
- * @example Pipeline (data-last) usage
1652
- * ```ts
1653
- * import { Effect, pipe } from "effect";
1654
- * import { modify, applyEdits } from "jsonc-effect";
1655
- *
1656
- * const input = '{ "a": 1 }';
1657
- * const result = pipe(
1658
- * input,
1659
- * modify(["a"], 42),
1660
- * Effect.flatMap((edits) => applyEdits(input, edits)),
1661
- * Effect.runSync,
1662
- * );
1663
- * ```
1664
- *
1665
- * @privateRemarks
1666
- * Uses its own scanner-based navigation to locate the target path rather
1667
- * than building a full AST via `parseTree`. This keeps the implementation
1668
- * lightweight and avoids an intermediate allocation.
1669
- *
1670
- * @public
1671
- */
1672
- export declare const modify: {
1673
- (path: JsoncPath, value: unknown, options?: {
1674
- formattingOptions?: Partial<JsoncFormattingOptions>;
1675
- }): (text: string) => Effect.Effect<ReadonlyArray<JsoncEdit>, JsoncModificationError>;
1676
- (text: string, path: JsoncPath, value: unknown, options?: {
1677
- formattingOptions?: Partial<JsoncFormattingOptions>;
1678
- }): Effect.Effect<ReadonlyArray<JsoncEdit>, JsoncModificationError>;
1679
- };
1680
-
1681
- /**
1682
- * Parse a JSONC string into a JavaScript value.
1683
- *
1684
- * @param text - JSONC string to parse
1685
- * @param options - Optional {@link JsoncParseOptions} controlling comment and
1686
- * trailing-comma handling.
1687
- * @returns `Effect<unknown, JsoncParseError>` — succeeds with the parsed value
1688
- * or fails with a {@link JsoncParseError} containing every error encountered.
1689
- *
1690
- * @remarks
1691
- * The return type is `unknown` (not `any`) so consumers are forced to narrow
1692
- * the result, which is safer in Effect pipelines. By default
1693
- * `allowTrailingComma` is `true`, matching common JSONC conventions used in
1694
- * VS Code settings and `tsconfig.json`.
1695
- *
1696
- * @see {@link parseTree} — parse into an AST instead of a plain value
1697
- * @see {@link JsoncParseOptions} — available parse options
1698
- * @see {@link JsoncParseError} the tagged error type on the failure channel
1699
- *
1700
- * @example
1701
- * Basic parsing:
1702
- * ```ts
1703
- * import { Effect } from "effect";
1704
- * import { parse } from "jsonc-effect";
1705
- *
1706
- * const value = Effect.runSync(parse('{ "key": 42 }'));
1707
- * console.log(value); // { key: 42 }
1708
- * ```
1709
- *
1710
- * @example
1711
- * Parsing with options:
1712
- * ```ts
1713
- * import { Effect } from "effect";
1714
- * import { parse } from "jsonc-effect";
1715
- *
1716
- * const value = Effect.runSync(
1717
- * parse('{ "key": 42 }', { disallowComments: true }),
1718
- * );
1719
- * ```
1720
- *
1721
- * @example
1722
- * Error handling with `catchTag`:
1723
- * ```ts
1724
- * import { Effect } from "effect";
1725
- * import { parse } from "jsonc-effect";
1726
- *
1727
- * const program = parse("{ bad }").pipe(
1728
- * Effect.catchTag("JsoncParseError", (err) =>
1729
- * Effect.succeed({ fallback: true, errors: err.errors }),
1730
- * ),
1731
- * );
1732
- *
1733
- * const result = Effect.runSync(program);
1734
- * console.log(result);
1735
- * ```
1736
- *
1737
- * @example
1738
- * Using `Effect.gen`:
1739
- * ```ts
1740
- * import { Effect } from "effect";
1741
- * import { parse } from "jsonc-effect";
1742
- *
1743
- * const program = Effect.gen(function* () {
1744
- * const config = yield* parse('{ "port": 3000 }');
1745
- * return config;
1746
- * });
1747
- *
1748
- * const result = Effect.runSync(program);
1749
- * console.log(result); // { port: 3000 }
1750
- * ```
1751
- *
1752
- * @privateRemarks
1753
- * Uses {@link createScanner} internally with a recursive descent parser.
1754
- * The scanner is created with `ignoreTrivia = false` so the parser can
1755
- * report comment-related errors when `disallowComments` is set.
1756
- *
1757
- * @public
1758
- */
1759
- export declare const parse: {
1760
- (text: string): Effect.Effect<unknown, JsoncParseError>;
1761
- (text: string, options: Partial<JsoncParseOptions>): Effect.Effect<unknown, JsoncParseError>;
1762
- };
1763
-
1764
- /**
1765
- * Parse a JSONC string into an immutable AST.
1766
- *
1767
- * @param text - JSONC string to parse
1768
- * @param options - Optional {@link JsoncParseOptions} controlling comment and
1769
- * trailing-comma handling.
1770
- * @returns `Effect<Option<JsoncNode>, JsoncParseError>` — succeeds with
1771
- * `Option.some(root)` for non-empty documents or `Option.none()` when the
1772
- * input is empty (and `allowEmptyContent` is set).
1773
- *
1774
- * @remarks
1775
- * The returned AST is immutable and does **not** contain parent pointers, which
1776
- * keeps nodes safe to share across fibers. Use the AST navigation helpers
1777
- * ({@link findNode}, {@link getNodeValue}) to traverse and extract values from
1778
- * the tree.
1779
- *
1780
- * `Option.none()` is returned only when the document contains no value tokens
1781
- * and `allowEmptyContent` is enabled; otherwise an empty document produces a
1782
- * {@link JsoncParseError}.
1783
- *
1784
- * @see {@link parse} — parse into a plain JavaScript value instead of an AST
1785
- * @see {@link findNode} — locate a node by JSON path segments
1786
- * @see {@link getNodeValue} — extract the JavaScript value from a subtree
1787
- * @see {@link JsoncNode} — the AST node type
1788
- *
1789
- * @example
1790
- * Parsing a JSONC string and navigating the tree:
1791
- * ```ts
1792
- * import { Effect, Option } from "effect";
1793
- * import { parseTree } from "jsonc-effect";
1794
- *
1795
- * const program = Effect.gen(function* () {
1796
- * const maybeRoot = yield* parseTree('{ "a": [1, 2, 3] }');
1797
- * if (Option.isSome(maybeRoot)) {
1798
- * const root = maybeRoot.value;
1799
- * console.log(root.type); // "object"
1800
- * console.log(root.children?.length); // 1
1801
- * }
1802
- * });
1803
- *
1804
- * Effect.runSync(program);
1805
- * ```
1806
- *
1807
- * @privateRemarks
1808
- * Internally the parser builds a mutable tree using `MutableJsoncNode` and
1809
- * casts to the readonly `JsoncNode` on output.
1810
- *
1811
- * @public
1812
- */
1813
- export declare const parseTree: {
1814
- (text: string): Effect.Effect<Option.Option<JsoncNode>, JsoncParseError>;
1815
- (text: string, options: Partial<JsoncParseOptions>): Effect.Effect<Option.Option<JsoncNode>, JsoncParseError>;
1816
- };
1817
-
1818
- /**
1819
- * Remove all comments from JSONC text, producing valid JSON.
1820
- *
1821
- * @param text - JSONC string to strip comments from
1822
- * @param replaceCh - Optional single character used to replace each character of
1823
- * every comment. When provided, the output has the **same length** as the
1824
- * input so that all offsets are preserved (line breaks inside block comments
1825
- * are kept as-is).
1826
- * @returns `Effect<string>` the text with all comments removed (or replaced).
1827
- *
1828
- * @remarks
1829
- * When `replaceCh` is omitted the comment text is simply deleted, which means
1830
- * character offsets in the output no longer match the original document. Pass a
1831
- * space (`" "`) as `replaceCh` to keep offsets stable this is useful when you
1832
- * need to correlate positions between the original JSONC and the stripped JSON.
1833
- *
1834
- * @see {@link parse} — parse JSONC directly without a stripping step
1835
- *
1836
- * @example
1837
- * Basic comment stripping:
1838
- * ```ts
1839
- * import { Effect } from "effect";
1840
- * import { stripComments } from "jsonc-effect";
1841
- *
1842
- * const json = Effect.runSync(
1843
- * stripComments('{ "a": 1 // comment\n}'),
1844
- * );
1845
- * console.log(json); // '{ "a": 1 \n}'
1846
- * ```
1847
- *
1848
- * @example
1849
- * Using a replacement character to preserve offsets:
1850
- * ```ts
1851
- * import { Effect } from "effect";
1852
- * import { stripComments } from "jsonc-effect";
1853
- *
1854
- * const json = Effect.runSync(
1855
- * stripComments('{ "a": 1 // comment\n}', " "),
1856
- * );
1857
- * console.log(json.length === '{ "a": 1 // comment\n}'.length); // true
1858
- * ```
1859
- *
1860
- * @public
1861
- */
1862
- export declare const stripComments: {
1863
- (text: string): Effect.Effect<string>;
1864
- (text: string, replaceCh: string): Effect.Effect<string>;
1865
- };
1866
-
1867
- /**
1868
- * Create a lazy `Stream` of {@link JsoncVisitorEvent} from JSONC text.
1869
- *
1870
- * Events are produced on demand as the stream is consumed, not
1871
- * pre-collected into memory. This makes `visit` suitable for large
1872
- * documents and supports early termination via `Stream.take` or
1873
- * `Stream.takeWhile` without scanning the entire input.
1874
- *
1875
- * @param text - The JSONC source text to visit.
1876
- * @param options - Optional partial {@link JsoncParseOptions} controlling
1877
- * comment handling and trailing-comma tolerance.
1878
- * @returns A `Stream` of {@link JsoncVisitorEvent} objects.
1879
- *
1880
- * @remarks
1881
- * The stream is backed by a lazy generator — no work is performed until
1882
- * the stream is consumed. Because evaluation is demand-driven, combining
1883
- * `visit` with `Stream.take` allows efficient partial scans of large
1884
- * documents without allocating a full AST.
1885
- *
1886
- * @see {@link visitCollect} for a one-step filter-and-collect convenience.
1887
- * @see {@link JsoncVisitorEvent} for the event type definitions.
1888
- *
1889
- * @example Collect all events
1890
- * ```ts
1891
- * import { Chunk, Effect, Stream } from "effect";
1892
- * import { visit } from "jsonc-effect";
1893
- *
1894
- * const all = Effect.runSync(
1895
- * visit('{ "a": 1 }').pipe(
1896
- * Stream.runCollect,
1897
- * Effect.map(Chunk.toReadonlyArray),
1898
- * ),
1899
- * );
1900
- * ```
1901
- *
1902
- * @example Filter and take the first match
1903
- * ```ts
1904
- * import { Chunk, Effect, Stream } from "effect";
1905
- * import { visit } from "jsonc-effect";
1906
- *
1907
- * const firstLiteral = Effect.runSync(
1908
- * visit('{ "a": 1, "b": 2 }').pipe(
1909
- * Stream.filter((e) => e._tag === "LiteralValue"),
1910
- * Stream.take(1),
1911
- * Stream.runCollect,
1912
- * Effect.map(Chunk.toReadonlyArray),
1913
- * ),
1914
- * );
1915
- * ```
1916
- *
1917
- * @example Extract property names
1918
- * ```ts
1919
- * import { Chunk, Effect, Stream } from "effect";
1920
- * import { visit } from "jsonc-effect";
1921
- *
1922
- * const propertyNames = Effect.runSync(
1923
- * visit('{ "name": "Alice", "age": 30 }').pipe(
1924
- * Stream.filter((e) => e._tag === "ObjectProperty"),
1925
- * Stream.map((e) => (e as { property: string }).property),
1926
- * Stream.runCollect,
1927
- * Effect.map(Chunk.toReadonlyArray),
1928
- * ),
1929
- * );
1930
- * ```
1931
- *
1932
- * @privateRemarks
1933
- * Internally wraps a generator function with `Stream.fromIterable`,
1934
- * preserving laziness. The generator yields events as it encounters
1935
- * tokens from the scanner.
1936
- *
1937
- * @public
1938
- */
1939
- export declare const visit: (text: string, options?: Partial<JsoncParseOptions> | undefined) => Stream.Stream<JsoncVisitorEvent, never, never>;
1940
-
1941
- /**
1942
- * Visit JSONC text and collect all events matching a type-guard predicate.
1943
- *
1944
- * This is a convenience that composes {@link visit}, `Stream.filter`, and
1945
- * `Stream.runCollect` into a single call.
1946
- *
1947
- * @param text - The JSONC source text to visit.
1948
- * @param predicate - A type-guard function that narrows
1949
- * {@link JsoncVisitorEvent} to the desired subtype `A`.
1950
- * @param options - Optional partial {@link JsoncParseOptions}.
1951
- * @returns An `Effect` that succeeds with a read-only array of the
1952
- * matched events.
1953
- *
1954
- * @remarks
1955
- * Equivalent to:
1956
- * ```
1957
- * visit(text, options) |> Stream.filter(predicate) |> Stream.runCollect
1958
- * ```
1959
- * Use this when you need all matching events and do not require
1960
- * intermediate stream transformations.
1961
- *
1962
- * @see {@link visit} for full stream-level control.
1963
- *
1964
- * @example Collecting literal values
1965
- * ```ts
1966
- * import { Effect } from "effect";
1967
- * import type { JsoncVisitorEvent } from "jsonc-effect";
1968
- * import { visitCollect } from "jsonc-effect";
1969
- *
1970
- * const literals = Effect.runSync(
1971
- * visitCollect(
1972
- * '{ "a": 1, "b": true }',
1973
- * (e): e is Extract<JsoncVisitorEvent, { _tag: "LiteralValue" }> =>
1974
- * e._tag === "LiteralValue",
1975
- * ),
1976
- * );
1977
- * ```
1978
- *
1979
- * @public
1980
- */
1981
- export declare const visitCollect: <A extends JsoncVisitorEvent>(text: string, predicate: (event: JsoncVisitorEvent) => event is A, options?: Partial<JsoncParseOptions> | undefined) => Effect.Effect<readonly A[], never, never>;
1982
-
1983
- export { }
1
+ import { Effect, Option, Schema, Stream } from "effect";
2
+
3
+ //#region src/schemas.d.ts
4
+ /**
5
+ * Token types produced by the JSONC scanner.
6
+ *
7
+ * @remarks
8
+ * Uses string literals instead of numeric enums so that token kinds are
9
+ * self-documenting in debug output, log messages, and test assertions.
10
+ * This avoids the "reverse-mapping" confusion of TypeScript numeric enums
11
+ * and makes pattern-matching with `Schema.Literal` straightforward.
12
+ *
13
+ * @see {@link createScanner} creates a scanner that emits these token types
14
+ *
15
+ * @public
16
+ */
17
+ declare const JsoncSyntaxKind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
18
+ /**
19
+ * The union of all JSONC token kind string literals.
20
+ *
21
+ * @see {@link (JsoncSyntaxKind:variable)}
22
+ *
23
+ * @public
24
+ */
25
+ type JsoncSyntaxKind = Schema.Schema.Type<typeof JsoncSyntaxKind>;
26
+ /**
27
+ * Scanner error codes produced by the JSONC scanner.
28
+ *
29
+ * @remarks
30
+ * `"None"` indicates a successful scan with no errors. All other values
31
+ * describe a specific lexical error encountered while tokenizing input.
32
+ *
33
+ * @see {@link JsoncScanner} — the scanner interface that reports these errors
34
+ *
35
+ * @public
36
+ */
37
+ declare const JsoncScanError: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
38
+ /**
39
+ * The union of all JSONC scan error string literals.
40
+ *
41
+ * @see {@link (JsoncScanError:variable)}
42
+ *
43
+ * @public
44
+ */
45
+ type JsoncScanError = Schema.Schema.Type<typeof JsoncScanError>;
46
+ declare const JsoncToken_base: Schema.Class<JsoncToken, {
47
+ kind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
48
+ value: typeof Schema.String;
49
+ offset: typeof Schema.Number;
50
+ length: typeof Schema.Number;
51
+ startLine: typeof Schema.Number;
52
+ startCharacter: typeof Schema.Number;
53
+ error: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
54
+ }, Schema.Struct.Encoded<{
55
+ kind: Schema.Literal<["OpenBrace", "CloseBrace", "OpenBracket", "CloseBracket", "Comma", "Colon", "Null", "True", "False", "String", "Number", "LineComment", "BlockComment", "LineBreak", "Trivia", "Unknown", "EOF"]>;
56
+ value: typeof Schema.String;
57
+ offset: typeof Schema.Number;
58
+ length: typeof Schema.Number;
59
+ startLine: typeof Schema.Number;
60
+ startCharacter: typeof Schema.Number;
61
+ error: Schema.Literal<["None", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter", "InvalidSymbol"]>;
62
+ }>, never, {
63
+ readonly error: "InvalidCharacter" | "InvalidEscapeCharacter" | "InvalidSymbol" | "InvalidUnicode" | "None" | "UnexpectedEndOfComment" | "UnexpectedEndOfNumber" | "UnexpectedEndOfString";
64
+ } & {
65
+ readonly kind: "BlockComment" | "CloseBrace" | "CloseBracket" | "Colon" | "Comma" | "EOF" | "False" | "LineBreak" | "LineComment" | "Null" | "Number" | "OpenBrace" | "OpenBracket" | "String" | "Trivia" | "True" | "Unknown";
66
+ } & {
67
+ readonly length: number;
68
+ } & {
69
+ readonly offset: number;
70
+ } & {
71
+ readonly startCharacter: number;
72
+ } & {
73
+ readonly startLine: number;
74
+ } & {
75
+ readonly value: string;
76
+ }, {}, {}>;
77
+ /**
78
+ * A single token produced by the JSONC scanner, carrying its kind, textual
79
+ * value, position within the source, and any scan error.
80
+ *
81
+ * @remarks
82
+ * - `kind` — the {@link (JsoncSyntaxKind:type)} discriminator for this token.
83
+ * - `value` — the raw text slice from the source document.
84
+ * - `offset`zero-based character offset from the start of the document.
85
+ * - `length` — character length of this token in the source.
86
+ * - `startLine` — zero-based line number where the token begins.
87
+ * - `startCharacter` zero-based column within `startLine`.
88
+ * - `error` — a {@link (JsoncScanError:type)} code; `"None"` when the token is valid.
89
+ *
90
+ * @see {@link createScanner} produces a stream of `JsoncToken` instances
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * import { JsoncToken } from "jsonc-effect";
95
+ *
96
+ * const token = new JsoncToken({
97
+ * kind: "String",
98
+ * value: '"hello"',
99
+ * offset: 0,
100
+ * length: 7,
101
+ * startLine: 0,
102
+ * startCharacter: 0,
103
+ * error: "None",
104
+ * });
105
+ *
106
+ * console.log(token.kind); // "String"
107
+ * console.log(token.value); // '"hello"'
108
+ * ```
109
+ *
110
+ * @privateRemarks
111
+ * `Schema.Class` gives `JsoncToken` structural equality via `Data.Class`
112
+ * under the hood, so two tokens with identical fields are considered equal
113
+ * by `Equal.equals`. This is essential for test assertions and Effect's
114
+ * structural comparison semantics.
115
+ *
116
+ * @public
117
+ */
118
+ declare class JsoncToken extends JsoncToken_base {}
119
+ /**
120
+ * Discriminator values for JSONC AST node types.
121
+ *
122
+ * @remarks
123
+ * These correspond to the JSON value types (`"string"`, `"number"`,
124
+ * `"boolean"`, `"null"`) plus structural types (`"object"`, `"array"`)
125
+ * and the special `"property"` type representing a key-value pair inside
126
+ * an object.
127
+ *
128
+ * @see {@link JsoncNode} — the AST node that carries this discriminator
129
+ *
130
+ * @public
131
+ */
132
+ declare const JsoncNodeType: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
133
+ /**
134
+ * The union of all JSONC AST node type string literals.
135
+ *
136
+ * @see {@link (JsoncNodeType:variable)}
137
+ *
138
+ * @public
139
+ */
140
+ type JsoncNodeType = Schema.Schema.Type<typeof JsoncNodeType>;
141
+ declare const JsoncNode_base: Schema.Class<JsoncNode, {
142
+ type: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
143
+ value: Schema.optional<typeof Schema.Unknown>;
144
+ offset: typeof Schema.Number;
145
+ length: typeof Schema.Number;
146
+ colonOffset: Schema.optional<typeof Schema.Number>;
147
+ children: Schema.optional<Schema.Array$<Schema.suspend<JsoncNode, JsoncNode, never>>>;
148
+ }, Schema.Struct.Encoded<{
149
+ type: Schema.Literal<["object", "array", "property", "string", "number", "boolean", "null"]>;
150
+ value: Schema.optional<typeof Schema.Unknown>;
151
+ offset: typeof Schema.Number;
152
+ length: typeof Schema.Number;
153
+ colonOffset: Schema.optional<typeof Schema.Number>;
154
+ children: Schema.optional<Schema.Array$<Schema.suspend<JsoncNode, JsoncNode, never>>>;
155
+ }>, never, {
156
+ readonly children?: readonly JsoncNode[] | undefined;
157
+ } & {
158
+ readonly colonOffset?: number | undefined;
159
+ } & {
160
+ readonly value?: unknown;
161
+ } & {
162
+ readonly length: number;
163
+ } & {
164
+ readonly offset: number;
165
+ } & {
166
+ readonly type: "array" | "boolean" | "null" | "number" | "object" | "property" | "string";
167
+ }, {}, {}>;
168
+ /**
169
+ * AST node representing a parsed JSONC element, produced by {@link parseTree}.
170
+ *
171
+ * @remarks
172
+ * The `parent` field present in Microsoft's `jsonc-parser` is intentionally
173
+ * omitted here to avoid circular references, which would break structural
174
+ * equality, serialization, and Effect's `Schema.encode`/`Schema.decode`
175
+ * pipelines. Child relationships are expressed via the `children` array,
176
+ * and the recursive type is handled with `Schema.suspend`.
177
+ *
178
+ * - `type` — the {@link (JsoncNodeType:type)} discriminator.
179
+ * - `value` the decoded JavaScript value for leaf nodes (`string`,
180
+ * `number`, `boolean`, `null`); `undefined` for structural nodes.
181
+ * - `offset` — zero-based character offset of this node in the source.
182
+ * - `length` — character length of this node in the source.
183
+ * - `colonOffset` for `"property"` nodes, the offset of the `:` separator.
184
+ * - `children` — child nodes; present for `"object"`, `"array"`, and
185
+ * `"property"` nodes.
186
+ *
187
+ * @see {@link parseTree} — produces the root `JsoncNode`
188
+ * @see {@link findNode} locates a descendant by path
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * import { Effect } from "effect";
193
+ * import { parseTree } from "jsonc-effect";
194
+ *
195
+ * const program = parseTree('{ "key": [1, 2] }').pipe(
196
+ * Effect.map((root) => {
197
+ * // root.type === "object"
198
+ * const property = root.children?.[0]; // "property" node
199
+ * const array = property?.children?.[1]; // "array" node
200
+ * console.log(array?.children?.length); // 2
201
+ * }),
202
+ * );
203
+ * ```
204
+ *
205
+ * @privateRemarks
206
+ * Unlike the `*Base` pattern needed for `Data.TaggedError` subclasses,
207
+ * `Schema.Class` works directly for data types — api-extractor can roll up
208
+ * the generated `.d.ts` without issues. The `Schema.suspend` call for
209
+ * `children` is required to break the circular type reference at the schema
210
+ * level while still allowing recursive decode/encode.
211
+ *
212
+ * @public
213
+ */
214
+ declare class JsoncNode extends JsoncNode_base {}
215
+ /**
216
+ * A single segment of a {@link (JsoncPath:type)}: a `string` for object property
217
+ * keys or a `number` for array indices.
218
+ *
219
+ * @see {@link findNode} resolves a path to an AST node
220
+ * @see {@link modify} — applies a value change at a path
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import type { JsoncSegment } from "jsonc-effect";
225
+ *
226
+ * const objectKey: JsoncSegment = "compilerOptions";
227
+ * const arrayIndex: JsoncSegment = 0;
228
+ * ```
229
+ *
230
+ * @public
231
+ */
232
+ declare const JsoncSegment: Schema.Union<[typeof Schema.String, typeof Schema.Number]>;
233
+ /**
234
+ * A single path segment type — `string | number`.
235
+ *
236
+ * @see {@link (JsoncSegment:variable)}
237
+ *
238
+ * @public
239
+ */
240
+ type JsoncSegment = Schema.Schema.Type<typeof JsoncSegment>;
241
+ /**
242
+ * An ordered sequence of {@link (JsoncSegment:type)} values describing a location
243
+ * within a JSONC document tree.
244
+ *
245
+ * @see {@link findNode} — resolves a `JsoncPath` to an AST node
246
+ * @see {@link modify} applies a modification at a `JsoncPath`
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * import type { JsoncPath } from "jsonc-effect";
251
+ *
252
+ * // Path to the "strict" property inside "compilerOptions"
253
+ * const path: JsoncPath = ["compilerOptions", "strict"];
254
+ *
255
+ * // Path to the second element of the "include" array
256
+ * const arrayPath: JsoncPath = ["include", 1];
257
+ * ```
258
+ *
259
+ * @public
260
+ */
261
+ declare const JsoncPath: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
262
+ /**
263
+ * An array of path segments `ReadonlyArray<string | number>`.
264
+ *
265
+ * @see {@link (JsoncPath:variable)}
266
+ *
267
+ * @public
268
+ */
269
+ type JsoncPath = Schema.Schema.Type<typeof JsoncPath>;
270
+ declare const JsoncEdit_base: Schema.Class<JsoncEdit, {
271
+ offset: typeof Schema.Number;
272
+ length: typeof Schema.Number;
273
+ content: typeof Schema.String;
274
+ }, Schema.Struct.Encoded<{
275
+ offset: typeof Schema.Number;
276
+ length: typeof Schema.Number;
277
+ content: typeof Schema.String;
278
+ }>, never, {
279
+ readonly content: string;
280
+ } & {
281
+ readonly length: number;
282
+ } & {
283
+ readonly offset: number;
284
+ }, {}, {}>;
285
+ /**
286
+ * A non-mutating text edit describing a replacement within a JSONC document.
287
+ *
288
+ * @remarks
289
+ * Edits use zero-based `offset` and `length` to identify the span of text
290
+ * to replace, and `content` for the replacement string. To insert without
291
+ * removing text, set `length` to `0`. To delete without inserting, set
292
+ * `content` to `""`.
293
+ *
294
+ * Edits returned by {@link format} and {@link modify} should be applied
295
+ * via {@link applyEdits}, which processes them in reverse order so that
296
+ * earlier offsets remain valid.
297
+ *
298
+ * @see {@link format} — produces edits for formatting
299
+ * @see {@link modify} — produces edits for value changes
300
+ * @see {@link applyEdits} — applies an array of edits to a source string
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * import { JsoncEdit } from "jsonc-effect";
305
+ *
306
+ * // An edit that inserts ", true" at offset 10
307
+ * const edit = new JsoncEdit({ offset: 10, length: 0, content: ", true" });
308
+ *
309
+ * console.log(edit.offset); // 10
310
+ * console.log(edit.length); // 0
311
+ * console.log(edit.content); // ", true"
312
+ * ```
313
+ *
314
+ * @public
315
+ */
316
+ declare class JsoncEdit extends JsoncEdit_base {}
317
+ declare const JsoncRange_base: Schema.Class<JsoncRange, {
318
+ offset: typeof Schema.Number;
319
+ length: typeof Schema.Number;
320
+ }, Schema.Struct.Encoded<{
321
+ offset: typeof Schema.Number;
322
+ length: typeof Schema.Number;
323
+ }>, never, {
324
+ readonly length: number;
325
+ } & {
326
+ readonly offset: number;
327
+ }, {}, {}>;
328
+ /**
329
+ * A range within a JSONC document, expressed as a zero-based character
330
+ * offset and a length in characters.
331
+ *
332
+ * @remarks
333
+ * Both `offset` and `length` are measured in UTF-16 code units (JavaScript
334
+ * string indices). Pass a `JsoncRange` to {@link format} to restrict
335
+ * formatting to a specific region of the document rather than the whole file.
336
+ *
337
+ * @see {@link format} — accepts an optional `JsoncRange` parameter
338
+ *
339
+ * @public
340
+ */
341
+ declare class JsoncRange extends JsoncRange_base {}
342
+ declare const JsoncParseOptions_base: Schema.Class<JsoncParseOptions, {
343
+ disallowComments: Schema.optionalWith<typeof Schema.Boolean, {
344
+ default: () => false;
345
+ }>;
346
+ allowTrailingComma: Schema.optionalWith<typeof Schema.Boolean, {
347
+ default: () => true;
348
+ }>;
349
+ allowEmptyContent: Schema.optionalWith<typeof Schema.Boolean, {
350
+ default: () => false;
351
+ }>;
352
+ }, Schema.Struct.Encoded<{
353
+ disallowComments: Schema.optionalWith<typeof Schema.Boolean, {
354
+ default: () => false;
355
+ }>;
356
+ allowTrailingComma: Schema.optionalWith<typeof Schema.Boolean, {
357
+ default: () => true;
358
+ }>;
359
+ allowEmptyContent: Schema.optionalWith<typeof Schema.Boolean, {
360
+ default: () => false;
361
+ }>;
362
+ }>, never, {
363
+ readonly allowEmptyContent?: boolean | undefined;
364
+ } & {
365
+ readonly allowTrailingComma?: boolean | undefined;
366
+ } & {
367
+ readonly disallowComments?: boolean | undefined;
368
+ }, {}, {}>;
369
+ /**
370
+ * Options controlling JSONC parse behavior.
371
+ *
372
+ * @remarks
373
+ * - `disallowComments` — when `true`, line and block comments are treated
374
+ * as parse errors. Defaults to `false`.
375
+ * - `allowTrailingComma` when `true`, trailing commas after the last
376
+ * element in arrays and objects are permitted. Defaults to `true`, which
377
+ * differs from Microsoft's `jsonc-parser` (where the default is `false`).
378
+ * - `allowEmptyContent` when `true`, an empty string parses as
379
+ * `undefined` rather than producing an error. Defaults to `false`.
380
+ *
381
+ * @see {@link parse} — parses JSONC text into a JavaScript value
382
+ * @see {@link parseTree} — parses JSONC text into an AST
383
+ *
384
+ * @example
385
+ * ```ts
386
+ * import { Effect } from "effect";
387
+ * import { parse, JsoncParseOptions } from "jsonc-effect";
388
+ *
389
+ * const options = new JsoncParseOptions({
390
+ * disallowComments: true,
391
+ * allowTrailingComma: false,
392
+ * });
393
+ *
394
+ * const program = parse('{ "key": "value" }', options).pipe(
395
+ * Effect.map((value) => console.log(value)),
396
+ * );
397
+ * ```
398
+ *
399
+ * @public
400
+ */
401
+ declare class JsoncParseOptions extends JsoncParseOptions_base {}
402
+ declare const JsoncFormattingOptions_base: Schema.Class<JsoncFormattingOptions, {
403
+ tabSize: Schema.optionalWith<typeof Schema.Number, {
404
+ default: () => number;
405
+ }>;
406
+ insertSpaces: Schema.optionalWith<typeof Schema.Boolean, {
407
+ default: () => true;
408
+ }>;
409
+ eol: Schema.optionalWith<typeof Schema.String, {
410
+ default: () => string;
411
+ }>;
412
+ insertFinalNewline: Schema.optionalWith<typeof Schema.Boolean, {
413
+ default: () => false;
414
+ }>;
415
+ keepLines: Schema.optionalWith<typeof Schema.Boolean, {
416
+ default: () => false;
417
+ }>;
418
+ }, Schema.Struct.Encoded<{
419
+ tabSize: Schema.optionalWith<typeof Schema.Number, {
420
+ default: () => number;
421
+ }>;
422
+ insertSpaces: Schema.optionalWith<typeof Schema.Boolean, {
423
+ default: () => true;
424
+ }>;
425
+ eol: Schema.optionalWith<typeof Schema.String, {
426
+ default: () => string;
427
+ }>;
428
+ insertFinalNewline: Schema.optionalWith<typeof Schema.Boolean, {
429
+ default: () => false;
430
+ }>;
431
+ keepLines: Schema.optionalWith<typeof Schema.Boolean, {
432
+ default: () => false;
433
+ }>;
434
+ }>, never, {
435
+ readonly eol?: string | undefined;
436
+ } & {
437
+ readonly insertFinalNewline?: boolean | undefined;
438
+ } & {
439
+ readonly insertSpaces?: boolean | undefined;
440
+ } & {
441
+ readonly keepLines?: boolean | undefined;
442
+ } & {
443
+ readonly tabSize?: number | undefined;
444
+ }, {}, {}>;
445
+ /**
446
+ * Options controlling JSONC formatting behavior.
447
+ *
448
+ * @remarks
449
+ * - `tabSize` — number of spaces per indentation level. Defaults to `2`.
450
+ * - `insertSpaces` when `true`, use spaces for indentation; when `false`,
451
+ * use tab characters. Defaults to `true`.
452
+ * - `eol` — the end-of-line sequence. Defaults to `"\n"`.
453
+ * - `insertFinalNewline` — when `true`, ensure the formatted output ends
454
+ * with a newline. Defaults to `false`.
455
+ * - `keepLines` when `true`, preserve existing line breaks in the source
456
+ * rather than reflowing. Defaults to `false`.
457
+ *
458
+ * @see {@link format} — uses these options to produce formatting edits
459
+ * @see {@link formatAndApply} — formats and applies edits in one step
460
+ *
461
+ * @example
462
+ * ```ts
463
+ * import { Effect } from "effect";
464
+ * import { formatAndApply, JsoncFormattingOptions } from "jsonc-effect";
465
+ *
466
+ * const options = new JsoncFormattingOptions({
467
+ * tabSize: 4,
468
+ * insertSpaces: true,
469
+ * insertFinalNewline: true,
470
+ * });
471
+ *
472
+ * const program = formatAndApply('{"key":"value"}', options).pipe(
473
+ * Effect.map((formatted) => console.log(formatted)),
474
+ * );
475
+ * ```
476
+ *
477
+ * @public
478
+ */
479
+ declare class JsoncFormattingOptions extends JsoncFormattingOptions_base {}
480
+ //#endregion
481
+ //#region src/ast.d.ts
482
+ /**
483
+ * Find an AST node at a specific JSON path.
484
+ *
485
+ * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
486
+ * for both data-first and data-last (pipeline) usage.
487
+ *
488
+ * @param root - The AST root node obtained from {@link parseTree}.
489
+ * @param path - An array of string keys and numeric indices describing the path to traverse.
490
+ *
491
+ * @returns `Effect<Option<JsoncNode>>` the node at the given path, or `Option.none()` if the
492
+ * path does not exist in the tree.
493
+ *
494
+ * @remarks
495
+ * String segments navigate object properties and number segments navigate array indices.
496
+ * Returns `Option.none()` when any segment along the path cannot be resolved — for example,
497
+ * accessing a property on a non-object node or an out-of-bounds array index.
498
+ *
499
+ * @see {@link parseTree} — produces the AST root this function operates on
500
+ * @see {@link getNodeValue} — reconstructs a JS value from a found node
501
+ * @see {@link JsoncNode} the AST node type
502
+ * @see {@link (JsoncPath:type)} — the path segment array type
503
+ *
504
+ * @example Data-first usage
505
+ * ```ts
506
+ * import { Effect, Option } from "effect";
507
+ * import type { JsoncNode } from "jsonc-effect";
508
+ * import { parseTree, findNode } from "jsonc-effect";
509
+ *
510
+ * const program = Effect.gen(function* () {
511
+ * const root: Option.Option<JsoncNode> = yield* parseTree('{ "a": { "b": 1 } }');
512
+ * if (Option.isNone(root)) return Option.none();
513
+ * return yield* findNode(root.value, ["a", "b"]);
514
+ * });
515
+ *
516
+ * const result = Effect.runSync(program);
517
+ * // result is Option.some(node) where node.value === 1
518
+ * ```
519
+ *
520
+ * @example Data-last pipeline usage
521
+ * ```ts
522
+ * import { Effect, Option, pipe } from "effect";
523
+ * import type { JsoncNode } from "jsonc-effect";
524
+ * import { parseTree, findNode } from "jsonc-effect";
525
+ *
526
+ * const program = Effect.gen(function* () {
527
+ * const root: Option.Option<JsoncNode> = yield* parseTree('{ "x": [10, 20] }');
528
+ * if (Option.isNone(root)) return Option.none();
529
+ * return yield* pipe(root.value, findNode(["x", 1]));
530
+ * });
531
+ *
532
+ * const result = Effect.runSync(program);
533
+ * // result is Option.some(node) where node.value === 20
534
+ * ```
535
+ *
536
+ * @privateRemarks
537
+ * Wrapped in `Effect.sync`; the underlying traversal is fully synchronous.
538
+ *
539
+ * @public
540
+ */
541
+ declare const findNode: {
542
+ (path: JsoncPath): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncNode>>;
543
+ (root: JsoncNode, path: JsoncPath): Effect.Effect<Option.Option<JsoncNode>>;
544
+ };
545
+ /**
546
+ * Find the innermost AST node covering a character offset.
547
+ *
548
+ * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
549
+ * for both data-first and data-last (pipeline) usage.
550
+ *
551
+ * @param root - The AST root node obtained from {@link parseTree}.
552
+ * @param offset - A zero-based character offset into the original JSONC string.
553
+ *
554
+ * @returns `Effect<Option<JsoncNode>>` — the most deeply nested node whose span
555
+ * includes the offset, or `Option.none()` if the offset is outside the tree.
556
+ *
557
+ * @remarks
558
+ * This is useful for editor integrations such as hover information, go-to-definition,
559
+ * and code completions where you need to identify the token under the cursor.
560
+ *
561
+ * @see {@link parseTree} — produces the AST root this function operates on
562
+ * @see {@link getNodePath} — returns the JSON path to the node at an offset
563
+ *
564
+ * @example Finding a node at an offset
565
+ * ```ts
566
+ * import { Effect, Option } from "effect";
567
+ * import type { JsoncNode } from "jsonc-effect";
568
+ * import { parseTree, findNodeAtOffset } from "jsonc-effect";
569
+ *
570
+ * const program = Effect.gen(function* () {
571
+ * const root: Option.Option<JsoncNode> = yield* parseTree('{ "key": "value" }');
572
+ * if (Option.isNone(root)) return Option.none();
573
+ * // Offset 10 is inside the "value" string literal
574
+ * return yield* findNodeAtOffset(root.value, 10);
575
+ * });
576
+ *
577
+ * const result = Effect.runSync(program);
578
+ * // result is Option.some(node) where node.type === "string"
579
+ * ```
580
+ *
581
+ * @privateRemarks
582
+ * Wrapped in `Effect.sync`; the underlying traversal is fully synchronous.
583
+ *
584
+ * @public
585
+ */
586
+ declare const findNodeAtOffset: {
587
+ (offset: number): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncNode>>;
588
+ (root: JsoncNode, offset: number): Effect.Effect<Option.Option<JsoncNode>>;
589
+ };
590
+ /**
591
+ * Get the JSON path to the node at a specific character offset.
592
+ *
593
+ * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
594
+ * for both data-first and data-last (pipeline) usage.
595
+ *
596
+ * @param root - The AST root node obtained from {@link parseTree}.
597
+ * @param targetOffset - A zero-based character offset into the original JSONC string.
598
+ *
599
+ * @returns `Effect<Option<JsoncPath>>`an array of path segments (string keys
600
+ * and numeric indices) leading to the innermost node at the offset, or
601
+ * `Option.none()` if the offset is outside the tree.
602
+ *
603
+ * @remarks
604
+ * Returns the path segments leading to the innermost node that spans the given
605
+ * offset. This is the inverse of {@link findNode} — given an offset you get the path,
606
+ * and given a path you get the node.
607
+ *
608
+ * @see {@link findNodeAtOffset} — returns the node itself rather than its path
609
+ * @see {@link (JsoncPath:type)} — the path segment array type
610
+ *
611
+ * @example Getting the path at an offset
612
+ * ```ts
613
+ * import { Effect, Option } from "effect";
614
+ * import type { JsoncNode, JsoncPath } from "jsonc-effect";
615
+ * import { parseTree, getNodePath } from "jsonc-effect";
616
+ *
617
+ * const program = Effect.gen(function* () {
618
+ * const root: Option.Option<JsoncNode> = yield* parseTree('{ "a": { "b": 42 } }');
619
+ * if (Option.isNone(root)) return Option.none();
620
+ * // Offset 15 points inside the value 42
621
+ * return yield* getNodePath(root.value, 15);
622
+ * });
623
+ *
624
+ * const result: Option.Option<JsoncPath> = Effect.runSync(program);
625
+ * // result is Option.some(["a", "b"])
626
+ * ```
627
+ *
628
+ * @public
629
+ */
630
+ declare const getNodePath: {
631
+ (targetOffset: number): (root: JsoncNode) => Effect.Effect<Option.Option<JsoncPath>>;
632
+ (root: JsoncNode, targetOffset: number): Effect.Effect<Option.Option<JsoncPath>>;
633
+ };
634
+ /**
635
+ * Reconstruct a plain JavaScript value from an AST subtree.
636
+ *
637
+ * @param node - The AST node to evaluate, typically obtained via {@link findNode} or
638
+ * as the root from {@link parseTree}.
639
+ *
640
+ * @returns `Effect<unknown>` — the reconstructed JS value (object, array, string,
641
+ * number, boolean, or null).
642
+ *
643
+ * @remarks
644
+ * Recursively evaluates the node tree to produce a plain JavaScript value.
645
+ * This is the inverse of {@link parseTree}: where `parseTree` turns a JSONC string
646
+ * into an AST, `getNodeValue` turns an AST subtree back into a JS value.
647
+ *
648
+ * @see {@link parseTree} — produces the AST that this function evaluates
649
+ * @see {@link findNode} — locates a subtree to pass to this function
650
+ *
651
+ * @example Extracting the value of a found node
652
+ * ```ts
653
+ * import { Effect, Option } from "effect";
654
+ * import type { JsoncNode } from "jsonc-effect";
655
+ * import { parseTree, findNode, getNodeValue } from "jsonc-effect";
656
+ *
657
+ * const program = Effect.gen(function* () {
658
+ * const root: Option.Option<JsoncNode> = yield* parseTree('{ "items": [1, 2, 3] }');
659
+ * if (Option.isNone(root)) return undefined;
660
+ * const node: Option.Option<JsoncNode> = yield* findNode(root.value, ["items"]);
661
+ * if (Option.isNone(node)) return undefined;
662
+ * return yield* getNodeValue(node.value);
663
+ * });
664
+ *
665
+ * const result = Effect.runSync(program);
666
+ * // result is [1, 2, 3]
667
+ * ```
668
+ *
669
+ * @privateRemarks
670
+ * Useful after {@link findNode} to extract a subtree's value without manual
671
+ * AST traversal.
672
+ *
673
+ * @public
674
+ */
675
+ declare const getNodeValue: (node: JsoncNode) => Effect.Effect<unknown>;
676
+ //#endregion
677
+ //#region src/errors.d.ts
678
+ /**
679
+ * Error codes representing specific JSONC parse failures.
680
+ *
681
+ * @remarks
682
+ * Each code maps to a distinct syntactic error the parser can encounter,
683
+ * from invalid symbols and number formats to missing delimiters and
684
+ * unexpected end-of-input conditions.
685
+ *
686
+ * @see {@link JsoncParseErrorDetail} — carries one of these codes alongside
687
+ * position information
688
+ *
689
+ * @public
690
+ */
691
+ declare const JsoncParseErrorCode: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
692
+ /**
693
+ * The union of all JSONC parse error code string literals.
694
+ *
695
+ * @see {@link (JsoncParseErrorCode:variable)}
696
+ *
697
+ * @public
698
+ */
699
+ type JsoncParseErrorCode = Schema.Schema.Type<typeof JsoncParseErrorCode>;
700
+ declare const JsoncParseErrorDetail_base: Schema.Class<JsoncParseErrorDetail, {
701
+ code: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
702
+ message: typeof Schema.String;
703
+ offset: typeof Schema.Number;
704
+ length: typeof Schema.Number;
705
+ startLine: typeof Schema.Number;
706
+ startCharacter: typeof Schema.Number;
707
+ }, Schema.Struct.Encoded<{
708
+ code: Schema.Literal<["InvalidSymbol", "InvalidNumberFormat", "PropertyNameExpected", "ValueExpected", "ColonExpected", "CommaExpected", "CloseBraceExpected", "CloseBracketExpected", "EndOfFileExpected", "InvalidCommentToken", "UnexpectedEndOfComment", "UnexpectedEndOfString", "UnexpectedEndOfNumber", "InvalidUnicode", "InvalidEscapeCharacter", "InvalidCharacter"]>;
709
+ message: typeof Schema.String;
710
+ offset: typeof Schema.Number;
711
+ length: typeof Schema.Number;
712
+ startLine: typeof Schema.Number;
713
+ startCharacter: typeof Schema.Number;
714
+ }>, never, {
715
+ readonly code: "CloseBraceExpected" | "CloseBracketExpected" | "ColonExpected" | "CommaExpected" | "EndOfFileExpected" | "InvalidCharacter" | "InvalidCommentToken" | "InvalidEscapeCharacter" | "InvalidNumberFormat" | "InvalidSymbol" | "InvalidUnicode" | "PropertyNameExpected" | "UnexpectedEndOfComment" | "UnexpectedEndOfNumber" | "UnexpectedEndOfString" | "ValueExpected";
716
+ } & {
717
+ readonly length: number;
718
+ } & {
719
+ readonly message: string;
720
+ } & {
721
+ readonly offset: number;
722
+ } & {
723
+ readonly startCharacter: number;
724
+ } & {
725
+ readonly startLine: number;
726
+ }, {}, {}>;
727
+ /**
728
+ * Detail for a single parse error, including the error code, a human-readable
729
+ * message, and the exact position within the source document.
730
+ *
731
+ * @remarks
732
+ * - `code` — a {@link (JsoncParseErrorCode:type)} identifying the error kind.
733
+ * - `message` a descriptive message suitable for display.
734
+ * - `offset` — zero-based character offset where the error occurred.
735
+ * - `length` character length of the problematic span.
736
+ * - `startLine` — zero-based line number of the error.
737
+ * - `startCharacter` — zero-based column within `startLine`.
738
+ *
739
+ * @see {@link JsoncParseError} — aggregates an array of these details
740
+ *
741
+ * @example
742
+ * ```ts
743
+ * import { JsoncParseErrorDetail } from "jsonc-effect";
744
+ *
745
+ * const detail = new JsoncParseErrorDetail({
746
+ * code: "ValueExpected",
747
+ * message: "Value expected",
748
+ * offset: 5,
749
+ * length: 1,
750
+ * startLine: 0,
751
+ * startCharacter: 5,
752
+ * });
753
+ *
754
+ * console.log(detail.code); // "ValueExpected"
755
+ * console.log(detail.offset); // 5
756
+ * ```
757
+ *
758
+ * @public
759
+ */
760
+ declare class JsoncParseErrorDetail extends JsoncParseErrorDetail_base {}
761
+ /**
762
+ * Base class for {@link JsoncParseError}; not intended to be constructed or
763
+ * caught directly — use `JsoncParseError` instead.
764
+ *
765
+ * @privateRemarks
766
+ * The `*Base` pattern is required because `Data.TaggedError` produces complex
767
+ * type signatures involving intersection types and branded generics that
768
+ * api-extractor cannot roll up into a single `.d.ts` bundle. Exporting the
769
+ * base separately lets the public `JsoncParseError` class extend it with
770
+ * concrete fields, giving api-extractor a simple class declaration to work
771
+ * with. It is tagged `@public` (rather than `@internal`) because it appears
772
+ * in `JsoncParseError`'s heritage clause in the public `.d.ts`, and API
773
+ * Extractor requires release tags to be compatible across a signature.
774
+ *
775
+ * @public
776
+ */
777
+ declare const JsoncParseErrorBase: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
778
+ readonly _tag: "JsoncParseError";
779
+ } & Readonly<A>;
780
+ /**
781
+ * Error raised when JSONC parsing encounters one or more syntax errors.
782
+ *
783
+ * @remarks
784
+ * Contains the full source `text`, the `options` used for parsing, and an
785
+ * `errors` array of {@link JsoncParseErrorDetail} instances with precise
786
+ * position information for each problem found.
787
+ *
788
+ * @see {@link parse} may fail with this error
789
+ * @see {@link parseTree} may fail with this error
790
+ *
791
+ * @example Catching with `Effect.catchTag`
792
+ * ```ts
793
+ * import { Effect } from "effect";
794
+ * import { parse } from "jsonc-effect";
795
+ *
796
+ * const program = parse("{ invalid }").pipe(
797
+ * Effect.catchTag("JsoncParseError", (e) => {
798
+ * console.error(e.errors); // Array of JsoncParseErrorDetail
799
+ * return Effect.succeed({});
800
+ * }),
801
+ * );
802
+ * ```
803
+ *
804
+ * @example Inspecting error details
805
+ * ```ts
806
+ * import { Effect } from "effect";
807
+ * import { parse } from "jsonc-effect";
808
+ *
809
+ * const program = parse("{ invalid }").pipe(
810
+ * Effect.catchTag("JsoncParseError", (e) => {
811
+ * for (const detail of e.errors) {
812
+ * console.error(
813
+ * `[${detail.code}] ${detail.message} at line ${detail.startLine}:${detail.startCharacter}`,
814
+ * );
815
+ * }
816
+ * return Effect.succeed({});
817
+ * }),
818
+ * );
819
+ * ```
820
+ *
821
+ * @public
822
+ */
823
+ declare class JsoncParseError extends JsoncParseErrorBase<{
824
+ readonly errors: ReadonlyArray<JsoncParseErrorDetail>;
825
+ readonly text: string;
826
+ readonly options?: Partial<JsoncParseOptions>;
827
+ }> {
828
+ get message(): string;
829
+ }
830
+ /**
831
+ * Base class for {@link JsoncNodeNotFoundError}; not intended to be
832
+ * constructed or caught directly — use `JsoncNodeNotFoundError` instead.
833
+ *
834
+ * @privateRemarks
835
+ * Uses the same `*Base` pattern as {@link JsoncParseErrorBase} to work
836
+ * around api-extractor's inability to roll up the complex type produced
837
+ * by `Data.TaggedError` into a single `.d.ts` declaration. Tagged `@public`
838
+ * for the same heritage-clause-compatibility reason as `JsoncParseErrorBase`.
839
+ *
840
+ * @public
841
+ */
842
+ declare const JsoncNodeNotFoundErrorBase: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
843
+ readonly _tag: "JsoncNodeNotFoundError";
844
+ } & Readonly<A>;
845
+ /**
846
+ * Error raised when AST navigation fails to find a node at the given path.
847
+ *
848
+ * @remarks
849
+ * Contains the `path` that was searched and the `rootNodeType` of the tree
850
+ * that was traversed.
851
+ *
852
+ * @see {@link findNode} may fail with this error
853
+ *
854
+ * @example
855
+ * ```ts
856
+ * import { Effect } from "effect";
857
+ * import { parseTree, findNode } from "jsonc-effect";
858
+ *
859
+ * const program = parseTree('{ "a": 1 }').pipe(
860
+ * Effect.flatMap((root) => findNode(root, ["missing", "path"])),
861
+ * Effect.catchTag("JsoncNodeNotFoundError", (e) => {
862
+ * console.error(`Not found: [${e.path.join(", ")}] in ${e.rootNodeType}`);
863
+ * return Effect.succeed(undefined);
864
+ * }),
865
+ * );
866
+ * ```
867
+ *
868
+ * @public
869
+ */
870
+ declare class JsoncNodeNotFoundError extends JsoncNodeNotFoundErrorBase<{
871
+ readonly path: ReadonlyArray<string | number>;
872
+ readonly rootNodeType: string;
873
+ }> {
874
+ get message(): string;
875
+ }
876
+ /**
877
+ * Base class for {@link JsoncModificationError}; not intended to be
878
+ * constructed or caught directly use `JsoncModificationError` instead.
879
+ *
880
+ * @privateRemarks
881
+ * Uses the same `*Base` pattern as {@link JsoncParseErrorBase} to work
882
+ * around api-extractor's inability to roll up the complex type produced
883
+ * by `Data.TaggedError` into a single `.d.ts` declaration. Tagged `@public`
884
+ * for the same heritage-clause-compatibility reason as `JsoncParseErrorBase`.
885
+ *
886
+ * @public
887
+ */
888
+ declare const JsoncModificationErrorBase: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
889
+ readonly _tag: "JsoncModificationError";
890
+ } & Readonly<A>;
891
+ /**
892
+ * Error raised when {@link modify} produces invalid edits or encounters
893
+ * an unsupported modification scenario.
894
+ *
895
+ * @remarks
896
+ * Contains the `path` where modification was attempted and a `reason`
897
+ * string explaining why it failed.
898
+ *
899
+ * @see {@link modify} — may fail with this error
900
+ *
901
+ * @example
902
+ * ```ts
903
+ * import { Effect } from "effect";
904
+ * import { modify } from "jsonc-effect";
905
+ *
906
+ * const program = modify("{}", ["deep", "path"], 42).pipe(
907
+ * Effect.catchTag("JsoncModificationError", (e) => {
908
+ * console.error(`Failed at [${e.path.join(", ")}]: ${e.reason}`);
909
+ * return Effect.succeed([]);
910
+ * }),
911
+ * );
912
+ * ```
913
+ *
914
+ * @public
915
+ */
916
+ declare class JsoncModificationError extends JsoncModificationErrorBase<{
917
+ readonly path: ReadonlyArray<string | number>;
918
+ readonly reason: string;
919
+ }> {
920
+ get message(): string;
921
+ }
922
+ /**
923
+ * Union of all JSONC error types, useful for exhaustive error handling
924
+ * with `Effect.catchTags`.
925
+ *
926
+ * @see {@link JsoncParseError}
927
+ * @see {@link JsoncNodeNotFoundError}
928
+ * @see {@link JsoncModificationError}
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * import { Effect } from "effect";
933
+ * import type { JsoncError } from "jsonc-effect";
934
+ * import { parse, parseTree, findNode, modify } from "jsonc-effect";
935
+ *
936
+ * const program = parse("{}").pipe(
937
+ * Effect.catchTags({
938
+ * JsoncParseError: (e) => Effect.succeed("parse failed"),
939
+ * JsoncModificationError: (e) => Effect.succeed("modify failed"),
940
+ * JsoncNodeNotFoundError: (e) => Effect.succeed("node not found"),
941
+ * }),
942
+ * );
943
+ * ```
944
+ *
945
+ * @public
946
+ */
947
+ type JsoncError = JsoncParseError | JsoncNodeNotFoundError | JsoncModificationError;
948
+ //#endregion
949
+ //#region src/equality.d.ts
950
+ /**
951
+ * Compare two JSONC strings for semantic equality.
952
+ *
953
+ * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
954
+ * for both data-first and data-last (pipeline) usage.
955
+ *
956
+ * @param self - The first JSONC string.
957
+ * @param that - The second JSONC string.
958
+ *
959
+ * @returns `Effect<boolean, JsoncParseError>` — `true` when both strings parse to
960
+ * semantically equivalent values, `false` otherwise. Fails with
961
+ * {@link JsoncParseError} if either string is malformed.
962
+ *
963
+ * @remarks
964
+ * Both strings are parsed via {@link parse} and then deep-compared. The comparison
965
+ * ignores comments, whitespace, formatting, and object key ordering. Array order
966
+ * IS significant. Uses `Effect.all` internally, so the effect fails on the first
967
+ * parse error encountered.
968
+ *
969
+ * @see {@link equalsValue} compare a JSONC string against an existing JS value
970
+ * @see {@link parse} the underlying parser used for both strings
971
+ *
972
+ * @example Data-first comparison
973
+ * ```ts
974
+ * import { Effect } from "effect";
975
+ * import { equals } from "jsonc-effect";
976
+ *
977
+ * const result = Effect.runSync(
978
+ * equals('{ "a": 1, "b": 2 }', '{"b":2,"a":1}')
979
+ * );
980
+ * // result is true
981
+ * ```
982
+ *
983
+ * @example Key-order independence
984
+ * ```ts
985
+ * import { Effect } from "effect";
986
+ * import { equals } from "jsonc-effect";
987
+ *
988
+ * // Object key order does not matter
989
+ * const sameKeys = Effect.runSync(
990
+ * equals('{"z":1,"a":2}', '{"a":2,"z":1}')
991
+ * );
992
+ * // sameKeys is true
993
+ *
994
+ * // Array order DOES matter
995
+ * const differentOrder = Effect.runSync(
996
+ * equals('[1, 2]', '[2, 1]')
997
+ * );
998
+ * // differentOrder is false
999
+ * ```
1000
+ *
1001
+ * @example Error handling
1002
+ * ```ts
1003
+ * import { Effect, Either } from "effect";
1004
+ * import type { JsoncParseError } from "jsonc-effect";
1005
+ * import { equals } from "jsonc-effect";
1006
+ *
1007
+ * const result: Either.Either<boolean, JsoncParseError> = Effect.runSync(
1008
+ * Effect.either(equals('{ invalid }', '{}'))
1009
+ * );
1010
+ * // result is Either.left(JsoncParseError)
1011
+ * ```
1012
+ *
1013
+ * @privateRemarks
1014
+ * Uses a simple recursive `deepEqual` helper rather than Effect's `Equal` module
1015
+ * because the parsed values are plain JS objects and arrays, not Effect data types.
1016
+ *
1017
+ * @public
1018
+ */
1019
+ declare const equals: {
1020
+ (that: string): (self: string) => Effect.Effect<boolean, JsoncParseError>;
1021
+ (self: string, that: string): Effect.Effect<boolean, JsoncParseError>;
1022
+ };
1023
+ /**
1024
+ * Compare a JSONC string against a JavaScript value for semantic equality.
1025
+ *
1026
+ * Supports {@link https://effect.website/docs/effect/function#dual | Function.dual}
1027
+ * for both data-first and data-last (pipeline) usage.
1028
+ *
1029
+ * @param self - The JSONC string to parse.
1030
+ * @param value - The JavaScript value to compare against.
1031
+ *
1032
+ * @returns `Effect<boolean, JsoncParseError>` — `true` when the parsed JSONC
1033
+ * is semantically equivalent to the provided value, `false` otherwise.
1034
+ * Fails with {@link JsoncParseError} if the string is malformed.
1035
+ *
1036
+ * @remarks
1037
+ * Only the JSONC string is parsed; the JS value is used as-is. This makes
1038
+ * `equalsValue` useful for assertions and testing where the expected value
1039
+ * is already a JS object. The comparison semantics are the same as
1040
+ * {@link equals}: comments, whitespace, formatting, and object key ordering
1041
+ * are ignored, while array order IS significant.
1042
+ *
1043
+ * @see {@link equals} — compare two JSONC strings against each other
1044
+ * @see {@link parse} — the underlying parser
1045
+ *
1046
+ * @example Basic comparison
1047
+ * ```ts
1048
+ * import { Effect } from "effect";
1049
+ * import { equalsValue } from "jsonc-effect";
1050
+ *
1051
+ * const result = Effect.runSync(
1052
+ * equalsValue('{"port": 3000, "host": "localhost"}', { host: "localhost", port: 3000 })
1053
+ * );
1054
+ * // result is true
1055
+ * ```
1056
+ *
1057
+ * @example Pipeline usage for testing
1058
+ * ```ts
1059
+ * import { Effect, pipe } from "effect";
1060
+ * import { equalsValue } from "jsonc-effect";
1061
+ *
1062
+ * const jsonc = '{ "enabled": true, "count": 5 }';
1063
+ * const expected = { enabled: true, count: 5 };
1064
+ *
1065
+ * const result = Effect.runSync(
1066
+ * pipe(jsonc, equalsValue(expected))
1067
+ * );
1068
+ * // result is true
1069
+ * ```
1070
+ *
1071
+ * @public
1072
+ */
1073
+ declare const equalsValue: {
1074
+ (value: unknown): (self: string) => Effect.Effect<boolean, JsoncParseError>;
1075
+ (self: string, value: unknown): Effect.Effect<boolean, JsoncParseError>;
1076
+ };
1077
+ //#endregion
1078
+ //#region src/format.d.ts
1079
+ /**
1080
+ * Compute formatting edits for a JSONC document.
1081
+ *
1082
+ * Returns an array of {@link JsoncEdit} objects describing text replacements
1083
+ * that, when applied, produce a well-formatted document. The input text is
1084
+ * never mutated apply the returned edits with {@link applyEdits}.
1085
+ *
1086
+ * @param text - The JSONC source text to format.
1087
+ * @param range - Optional sub-range to format. When provided, only edits
1088
+ * within the range are returned.
1089
+ * @param options - Partial {@link JsoncFormattingOptions} controlling indent
1090
+ * size, tabs vs. spaces, EOL style, and final-newline insertion.
1091
+ * @returns An `Effect` that succeeds with a read-only array of
1092
+ * {@link JsoncEdit} objects.
1093
+ *
1094
+ * @remarks
1095
+ * This function is non-mutating by design. It computes a minimal set of
1096
+ * whitespace edits; structural changes (inserting or removing properties)
1097
+ * are handled by {@link modify}. The `range` parameter allows formatting a
1098
+ * subset of the document without touching surrounding text.
1099
+ *
1100
+ * @see {@link applyEdits} to apply the returned edits to the source text.
1101
+ * @see {@link formatAndApply} for a one-step format-and-apply convenience.
1102
+ * @see {@link JsoncFormattingOptions} for available formatting controls.
1103
+ *
1104
+ * @example
1105
+ * ```ts
1106
+ * import { Effect } from "effect";
1107
+ * import type { JsoncEdit } from "jsonc-effect";
1108
+ * import { format, applyEdits } from "jsonc-effect";
1109
+ *
1110
+ * const input = '{"a":1, "b" :2}';
1111
+ * const edits: ReadonlyArray<JsoncEdit> = Effect.runSync(format(input));
1112
+ * const formatted: string = Effect.runSync(applyEdits(input, edits));
1113
+ * ```
1114
+ *
1115
+ * @privateRemarks
1116
+ * Uses {@link createScanner} internally to tokenize the input and compute
1117
+ * whitespace adjustments between consecutive non-trivia tokens.
1118
+ *
1119
+ * @public
1120
+ */
1121
+ declare const format: (text: string, range?: JsoncRange, options?: Partial<JsoncFormattingOptions>) => Effect.Effect<ReadonlyArray<JsoncEdit>>;
1122
+ /**
1123
+ * Apply an array of text edits to JSONC source text.
1124
+ *
1125
+ * This is a {@link https://effect.website/docs/function-dual | Function.dual}
1126
+ * that supports both data-first and data-last (pipeline) usage.
1127
+ *
1128
+ * @param text - The original JSONC source text.
1129
+ * @param edits - A read-only array of {@link JsoncEdit} objects, typically
1130
+ * produced by {@link format} or {@link modify}.
1131
+ * @returns An `Effect` that succeeds with the edited string.
1132
+ *
1133
+ * @remarks
1134
+ * Edits are sorted in reverse offset order before application so that
1135
+ * earlier edits do not shift the offsets of later ones. The original `edits`
1136
+ * array is not mutated.
1137
+ *
1138
+ * @see {@link format} to compute formatting edits.
1139
+ * @see {@link modify} to compute structural edits (insert, replace, remove).
1140
+ *
1141
+ * @example Data-first usage
1142
+ * ```ts
1143
+ * import { Effect } from "effect";
1144
+ * import { format, applyEdits } from "jsonc-effect";
1145
+ *
1146
+ * const input = '{"a":1}';
1147
+ * const edits = Effect.runSync(format(input));
1148
+ * const result: string = Effect.runSync(applyEdits(input, edits));
1149
+ * ```
1150
+ *
1151
+ * @example Pipeline with modify
1152
+ * ```ts
1153
+ * import { Effect, pipe } from "effect";
1154
+ * import { modify, applyEdits } from "jsonc-effect";
1155
+ *
1156
+ * const input = '{ "a": 1 }';
1157
+ * const result = pipe(
1158
+ * input,
1159
+ * modify(["a"], 42),
1160
+ * Effect.flatMap((edits) => applyEdits(input, edits)),
1161
+ * Effect.runSync,
1162
+ * );
1163
+ * ```
1164
+ *
1165
+ * @public
1166
+ */
1167
+ declare const applyEdits: {
1168
+ (edits: ReadonlyArray<JsoncEdit>): (text: string) => Effect.Effect<string>;
1169
+ (text: string, edits: ReadonlyArray<JsoncEdit>): Effect.Effect<string>;
1170
+ };
1171
+ /**
1172
+ * Format a JSONC document in one step by computing edits and immediately
1173
+ * applying them.
1174
+ *
1175
+ * This is a convenience that combines {@link format} and {@link applyEdits}
1176
+ * into a single call.
1177
+ *
1178
+ * @param text - The JSONC source text to format.
1179
+ * @param range - Optional sub-range to restrict formatting to.
1180
+ * @param options - Partial {@link JsoncFormattingOptions} controlling indent
1181
+ * size, tabs vs. spaces, EOL style, and final-newline insertion.
1182
+ * @returns An `Effect` that succeeds with the fully formatted string.
1183
+ *
1184
+ * @see {@link format} to obtain the edits without applying them.
1185
+ * @see {@link applyEdits} to apply edits separately.
1186
+ *
1187
+ * @example
1188
+ * ```ts
1189
+ * import { Effect } from "effect";
1190
+ * import { formatAndApply } from "jsonc-effect";
1191
+ *
1192
+ * const input = '{"a":1, "b" :2}';
1193
+ * const formatted: string = Effect.runSync(formatAndApply(input));
1194
+ * ```
1195
+ *
1196
+ * @public
1197
+ */
1198
+ declare const formatAndApply: (text: string, range?: JsoncRange, options?: Partial<JsoncFormattingOptions>) => Effect.Effect<string>;
1199
+ /**
1200
+ * Compute edits to insert, replace, or remove a value at a JSON path.
1201
+ *
1202
+ * This is a {@link https://effect.website/docs/function-dual | Function.dual}
1203
+ * that supports both data-first and data-last (pipeline) usage.
1204
+ *
1205
+ * @param text - The JSONC source text to modify.
1206
+ * @param path - A {@link (JsoncPath:type)} (array of string keys and numeric indices)
1207
+ * identifying the target location in the JSON structure.
1208
+ * @param value - The value to set. Pass `undefined` to remove the
1209
+ * property or array element at the given path.
1210
+ * @param options - Optional object with `formattingOptions` controlling
1211
+ * indent size, tabs vs. spaces, and EOL style for generated text.
1212
+ * @returns An `Effect` that succeeds with a read-only array of
1213
+ * {@link JsoncEdit} objects, or fails with a
1214
+ * {@link JsoncModificationError} if the path cannot be navigated.
1215
+ *
1216
+ * @remarks
1217
+ * Setting `value` to `undefined` removes the targeted property or element,
1218
+ * including its surrounding comma. When inserting a new property into an
1219
+ * object, it is appended after the last existing property.
1220
+ *
1221
+ * @see {@link applyEdits} to apply the returned edits to the source text.
1222
+ * @see {@link JsoncModificationError} for the error type on navigation failure.
1223
+ *
1224
+ * @example Update an existing property
1225
+ * ```ts
1226
+ * import { Effect } from "effect";
1227
+ * import { modify, applyEdits } from "jsonc-effect";
1228
+ *
1229
+ * const input = '{ "a": 1 }';
1230
+ * const edits = Effect.runSync(modify(input, ["a"], 2));
1231
+ * const result: string = Effect.runSync(applyEdits(input, edits));
1232
+ * ```
1233
+ *
1234
+ * @example Insert a new property
1235
+ * ```ts
1236
+ * import { Effect } from "effect";
1237
+ * import { modify, applyEdits } from "jsonc-effect";
1238
+ *
1239
+ * const input = '{ "a": 1 }';
1240
+ * const edits = Effect.runSync(modify(input, ["b"], "hello"));
1241
+ * const result: string = Effect.runSync(applyEdits(input, edits));
1242
+ * ```
1243
+ *
1244
+ * @example Remove a property
1245
+ * ```ts
1246
+ * import { Effect } from "effect";
1247
+ * import { modify, applyEdits } from "jsonc-effect";
1248
+ *
1249
+ * const input = '{ "a": 1, "b": 2 }';
1250
+ * const edits = Effect.runSync(modify(input, ["a"], undefined));
1251
+ * const result: string = Effect.runSync(applyEdits(input, edits));
1252
+ * ```
1253
+ *
1254
+ * @example Pipeline (data-last) usage
1255
+ * ```ts
1256
+ * import { Effect, pipe } from "effect";
1257
+ * import { modify, applyEdits } from "jsonc-effect";
1258
+ *
1259
+ * const input = '{ "a": 1 }';
1260
+ * const result = pipe(
1261
+ * input,
1262
+ * modify(["a"], 42),
1263
+ * Effect.flatMap((edits) => applyEdits(input, edits)),
1264
+ * Effect.runSync,
1265
+ * );
1266
+ * ```
1267
+ *
1268
+ * @privateRemarks
1269
+ * Uses its own scanner-based navigation to locate the target path rather
1270
+ * than building a full AST via `parseTree`. This keeps the implementation
1271
+ * lightweight and avoids an intermediate allocation.
1272
+ *
1273
+ * @public
1274
+ */
1275
+ declare const modify: {
1276
+ (path: JsoncPath, value: unknown, options?: {
1277
+ formattingOptions?: Partial<JsoncFormattingOptions>;
1278
+ }): (text: string) => Effect.Effect<ReadonlyArray<JsoncEdit>, JsoncModificationError>;
1279
+ (text: string, path: JsoncPath, value: unknown, options?: {
1280
+ formattingOptions?: Partial<JsoncFormattingOptions>;
1281
+ }): Effect.Effect<ReadonlyArray<JsoncEdit>, JsoncModificationError>;
1282
+ };
1283
+ //#endregion
1284
+ //#region src/parse.d.ts
1285
+ /**
1286
+ * Parse a JSONC string into a JavaScript value.
1287
+ *
1288
+ * @param text - JSONC string to parse
1289
+ * @param options - Optional {@link JsoncParseOptions} controlling comment and
1290
+ * trailing-comma handling.
1291
+ * @returns `Effect<unknown, JsoncParseError>` — succeeds with the parsed value
1292
+ * or fails with a {@link JsoncParseError} containing every error encountered.
1293
+ *
1294
+ * @remarks
1295
+ * The return type is `unknown` (not `any`) so consumers are forced to narrow
1296
+ * the result, which is safer in Effect pipelines. By default
1297
+ * `allowTrailingComma` is `true`, matching common JSONC conventions used in
1298
+ * VS Code settings and `tsconfig.json`.
1299
+ *
1300
+ * @see {@link parseTree} — parse into an AST instead of a plain value
1301
+ * @see {@link JsoncParseOptions} available parse options
1302
+ * @see {@link JsoncParseError} — the tagged error type on the failure channel
1303
+ *
1304
+ * @example
1305
+ * Basic parsing:
1306
+ * ```ts
1307
+ * import { Effect } from "effect";
1308
+ * import { parse } from "jsonc-effect";
1309
+ *
1310
+ * const value = Effect.runSync(parse('{ "key": 42 }'));
1311
+ * console.log(value); // { key: 42 }
1312
+ * ```
1313
+ *
1314
+ * @example
1315
+ * Parsing with options:
1316
+ * ```ts
1317
+ * import { Effect } from "effect";
1318
+ * import { parse } from "jsonc-effect";
1319
+ *
1320
+ * const value = Effect.runSync(
1321
+ * parse('{ "key": 42 }', { disallowComments: true }),
1322
+ * );
1323
+ * ```
1324
+ *
1325
+ * @example
1326
+ * Error handling with `catchTag`:
1327
+ * ```ts
1328
+ * import { Effect } from "effect";
1329
+ * import { parse } from "jsonc-effect";
1330
+ *
1331
+ * const program = parse("{ bad }").pipe(
1332
+ * Effect.catchTag("JsoncParseError", (err) =>
1333
+ * Effect.succeed({ fallback: true, errors: err.errors }),
1334
+ * ),
1335
+ * );
1336
+ *
1337
+ * const result = Effect.runSync(program);
1338
+ * console.log(result);
1339
+ * ```
1340
+ *
1341
+ * @example
1342
+ * Using `Effect.gen`:
1343
+ * ```ts
1344
+ * import { Effect } from "effect";
1345
+ * import { parse } from "jsonc-effect";
1346
+ *
1347
+ * const program = Effect.gen(function* () {
1348
+ * const config = yield* parse('{ "port": 3000 }');
1349
+ * return config;
1350
+ * });
1351
+ *
1352
+ * const result = Effect.runSync(program);
1353
+ * console.log(result); // { port: 3000 }
1354
+ * ```
1355
+ *
1356
+ * @privateRemarks
1357
+ * Uses {@link createScanner} internally with a recursive descent parser.
1358
+ * The scanner is created with `ignoreTrivia = false` so the parser can
1359
+ * report comment-related errors when `disallowComments` is set.
1360
+ *
1361
+ * @public
1362
+ */
1363
+ declare const parse: {
1364
+ (text: string): Effect.Effect<unknown, JsoncParseError>;
1365
+ (text: string, options: Partial<JsoncParseOptions>): Effect.Effect<unknown, JsoncParseError>;
1366
+ };
1367
+ /**
1368
+ * Parse a JSONC string into an immutable AST.
1369
+ *
1370
+ * @param text - JSONC string to parse
1371
+ * @param options - Optional {@link JsoncParseOptions} controlling comment and
1372
+ * trailing-comma handling.
1373
+ * @returns `Effect<Option<JsoncNode>, JsoncParseError>` — succeeds with
1374
+ * `Option.some(root)` for non-empty documents or `Option.none()` when the
1375
+ * input is empty (and `allowEmptyContent` is set).
1376
+ *
1377
+ * @remarks
1378
+ * The returned AST is immutable and does **not** contain parent pointers, which
1379
+ * keeps nodes safe to share across fibers. Use the AST navigation helpers
1380
+ * ({@link findNode}, {@link getNodeValue}) to traverse and extract values from
1381
+ * the tree.
1382
+ *
1383
+ * `Option.none()` is returned only when the document contains no value tokens
1384
+ * and `allowEmptyContent` is enabled; otherwise an empty document produces a
1385
+ * {@link JsoncParseError}.
1386
+ *
1387
+ * @see {@link parse} parse into a plain JavaScript value instead of an AST
1388
+ * @see {@link findNode} locate a node by JSON path segments
1389
+ * @see {@link getNodeValue} — extract the JavaScript value from a subtree
1390
+ * @see {@link JsoncNode} the AST node type
1391
+ *
1392
+ * @example
1393
+ * Parsing a JSONC string and navigating the tree:
1394
+ * ```ts
1395
+ * import { Effect, Option } from "effect";
1396
+ * import { parseTree } from "jsonc-effect";
1397
+ *
1398
+ * const program = Effect.gen(function* () {
1399
+ * const maybeRoot = yield* parseTree('{ "a": [1, 2, 3] }');
1400
+ * if (Option.isSome(maybeRoot)) {
1401
+ * const root = maybeRoot.value;
1402
+ * console.log(root.type); // "object"
1403
+ * console.log(root.children?.length); // 1
1404
+ * }
1405
+ * });
1406
+ *
1407
+ * Effect.runSync(program);
1408
+ * ```
1409
+ *
1410
+ * @privateRemarks
1411
+ * Internally the parser builds a mutable tree using `MutableJsoncNode` and
1412
+ * casts to the readonly `JsoncNode` on output.
1413
+ *
1414
+ * @public
1415
+ */
1416
+ declare const parseTree: {
1417
+ (text: string): Effect.Effect<Option.Option<JsoncNode>, JsoncParseError>;
1418
+ (text: string, options: Partial<JsoncParseOptions>): Effect.Effect<Option.Option<JsoncNode>, JsoncParseError>;
1419
+ };
1420
+ /**
1421
+ * Remove all comments from JSONC text, producing valid JSON.
1422
+ *
1423
+ * @param text - JSONC string to strip comments from
1424
+ * @param replaceCh - Optional single character used to replace each character of
1425
+ * every comment. When provided, the output has the **same length** as the
1426
+ * input so that all offsets are preserved (line breaks inside block comments
1427
+ * are kept as-is).
1428
+ * @returns `Effect<string>` the text with all comments removed (or replaced).
1429
+ *
1430
+ * @remarks
1431
+ * When `replaceCh` is omitted the comment text is simply deleted, which means
1432
+ * character offsets in the output no longer match the original document. Pass a
1433
+ * space (`" "`) as `replaceCh` to keep offsets stable — this is useful when you
1434
+ * need to correlate positions between the original JSONC and the stripped JSON.
1435
+ *
1436
+ * @see {@link parse} — parse JSONC directly without a stripping step
1437
+ *
1438
+ * @example
1439
+ * Basic comment stripping:
1440
+ * ```ts
1441
+ * import { Effect } from "effect";
1442
+ * import { stripComments } from "jsonc-effect";
1443
+ *
1444
+ * const json = Effect.runSync(
1445
+ * stripComments('{ "a": 1 // comment\n}'),
1446
+ * );
1447
+ * console.log(json); // '{ "a": 1 \n}'
1448
+ * ```
1449
+ *
1450
+ * @example
1451
+ * Using a replacement character to preserve offsets:
1452
+ * ```ts
1453
+ * import { Effect } from "effect";
1454
+ * import { stripComments } from "jsonc-effect";
1455
+ *
1456
+ * const json = Effect.runSync(
1457
+ * stripComments('{ "a": 1 // comment\n}', " "),
1458
+ * );
1459
+ * console.log(json.length === '{ "a": 1 // comment\n}'.length); // true
1460
+ * ```
1461
+ *
1462
+ * @public
1463
+ */
1464
+ declare const stripComments: {
1465
+ (text: string): Effect.Effect<string>;
1466
+ (text: string, replaceCh: string): Effect.Effect<string>;
1467
+ };
1468
+ //#endregion
1469
+ //#region src/scanner.d.ts
1470
+ /**
1471
+ * Stateful cursor over JSONC text that produces tokens on demand.
1472
+ *
1473
+ * @remarks
1474
+ * The scanner is the lowest-level API in jsonc-effect. It exposes an
1475
+ * imperative scan-loop pattern: call {@link JsoncScanner.scan | scan()} in a
1476
+ * loop until it returns `"EOF"`, inspecting the current token with the
1477
+ * getter methods after each call.
1478
+ *
1479
+ * Unlike the rest of the library, the scanner is **mutable** — each call to
1480
+ * `scan()` advances an internal cursor and updates all token-related state.
1481
+ *
1482
+ * @see {@link createScanner} — factory function that produces a `JsoncScanner`
1483
+ * @see {@link (JsoncSyntaxKind:type)} string literal union of all token types
1484
+ *
1485
+ * @example
1486
+ * Collecting all structural tokens from a JSONC string:
1487
+ * ```ts
1488
+ * import type { JsoncSyntaxKind } from "jsonc-effect";
1489
+ * import { createScanner } from "jsonc-effect";
1490
+ *
1491
+ * const scanner = createScanner('{ "key": 42 }', true);
1492
+ * const tokens: JsoncSyntaxKind[] = [];
1493
+ * let kind: JsoncSyntaxKind;
1494
+ * do {
1495
+ * kind = scanner.scan();
1496
+ * tokens.push(kind);
1497
+ * } while (kind !== "EOF");
1498
+ * console.log(tokens);
1499
+ * // ["OpenBrace", "String", "Colon", "Number", "CloseBrace", "EOF"]
1500
+ * ```
1501
+ *
1502
+ * @privateRemarks
1503
+ * The scanner is the only mutable/stateful part of the library. All other
1504
+ * APIs are pure Effect pipelines built on top of it.
1505
+ *
1506
+ * @public
1507
+ */
1508
+ interface JsoncScanner {
1509
+ /** Advance the cursor to the next token and return its {@link (JsoncSyntaxKind:type)}. */
1510
+ scan(): JsoncSyntaxKind;
1511
+ /** Return the {@link (JsoncSyntaxKind:type)} of the current token without advancing. */
1512
+ getToken(): JsoncSyntaxKind;
1513
+ /** Return the string value of the current token (e.g. the unescaped content of a string literal). */
1514
+ getTokenValue(): string;
1515
+ /** Return the zero-based character offset where the current token begins. */
1516
+ getTokenOffset(): number;
1517
+ /** Return the character length of the current token. */
1518
+ getTokenLength(): number;
1519
+ /** Return the zero-based line number where the current token starts. */
1520
+ getTokenStartLine(): number;
1521
+ /** Return the zero-based character position within the line where the current token starts. */
1522
+ getTokenStartCharacter(): number;
1523
+ /** Return the {@link (JsoncScanError:type)} for the current token, or `"None"` if no error. */
1524
+ getTokenError(): JsoncScanError;
1525
+ /** Return the current cursor position (byte offset into the source text). */
1526
+ getPosition(): number;
1527
+ /** Set the cursor position, resetting the current token state. */
1528
+ setPosition(pos: number): void;
1529
+ }
1530
+ /**
1531
+ * Create a stateful {@link JsoncScanner} for the given JSONC string.
1532
+ *
1533
+ * @param text - JSONC string to tokenize
1534
+ * @param ignoreTrivia - If `true`, the scanner automatically skips whitespace,
1535
+ * line-break, and comment tokens so that only structural tokens are returned
1536
+ * (default: `false`).
1537
+ * @returns A stateful {@link JsoncScanner} positioned before the first token.
1538
+ *
1539
+ * @remarks
1540
+ * When `ignoreTrivia` is `true` the scanner is suitable for building parsers
1541
+ * that only care about structural tokens (`OpenBrace`, `String`, `Number`,
1542
+ * etc.). Set it to `false` (the default) when you need to preserve comments
1543
+ * or whitespace for example in a formatter or a comment-stripping pass.
1544
+ *
1545
+ * @see {@link JsoncScanner} — the interface returned by this factory
1546
+ * @see {@link parse} higher-level API that uses a scanner internally
1547
+ *
1548
+ * @example
1549
+ * Tokenizing a JSONC string and printing each token:
1550
+ * ```ts
1551
+ * import type { JsoncSyntaxKind } from "jsonc-effect";
1552
+ * import { createScanner } from "jsonc-effect";
1553
+ *
1554
+ * const scanner = createScanner('{ "name": "jsonc" }', true);
1555
+ * let kind: JsoncSyntaxKind;
1556
+ * do {
1557
+ * kind = scanner.scan();
1558
+ * console.log(kind, scanner.getTokenValue());
1559
+ * } while (kind !== "EOF");
1560
+ * ```
1561
+ *
1562
+ * @privateRemarks
1563
+ * Ported from Microsoft's jsonc-parser (MIT), adapted to use string literal
1564
+ * token types instead of numeric enums.
1565
+ *
1566
+ * @public
1567
+ */
1568
+ declare const createScanner: (text: string, ignoreTrivia?: boolean) => JsoncScanner;
1569
+ //#endregion
1570
+ //#region src/schema-integration.d.ts
1571
+ /**
1572
+ * Pre-built `Schema<unknown, string>` that decodes a JSONC string into an
1573
+ * unknown JavaScript value using default parse options.
1574
+ *
1575
+ * This is the first stage of a typical parsing pipeline:
1576
+ *
1577
+ * ```
1578
+ * JSONC string --JsoncFromString--> unknown --YourSchema--> A
1579
+ * ```
1580
+ *
1581
+ * @remarks
1582
+ * Default parse options are used (comments allowed, trailing commas
1583
+ * allowed). The encode direction uses `JSON.stringify` with 2-space
1584
+ * indentation, which means comments present in the original JSONC
1585
+ * input are not preserved during a round-trip encode.
1586
+ *
1587
+ * For custom parse options, use {@link makeJsoncFromString} instead.
1588
+ *
1589
+ * @see {@link makeJsoncFromString} to create a schema with custom options.
1590
+ * @see {@link makeJsoncSchema} to compose JSONC parsing with a domain schema
1591
+ * in one step.
1592
+ *
1593
+ * @example Decode a JSONC string
1594
+ * ```ts
1595
+ * import { Schema } from "effect";
1596
+ * import { JsoncFromString } from "jsonc-effect";
1597
+ *
1598
+ * const value: unknown = Schema.decodeUnknownSync(JsoncFromString)(
1599
+ * '{ "key": 42 // comment\n}',
1600
+ * );
1601
+ * ```
1602
+ *
1603
+ * @example Compose with a domain schema
1604
+ * ```ts
1605
+ * import { Schema } from "effect";
1606
+ * import { JsoncFromString } from "jsonc-effect";
1607
+ *
1608
+ * const MyConfig = Schema.Struct({
1609
+ * name: Schema.String,
1610
+ * version: Schema.Number,
1611
+ * });
1612
+ *
1613
+ * const MyConfigFromJsonc = Schema.compose(JsoncFromString, MyConfig);
1614
+ * const config = Schema.decodeUnknownSync(MyConfigFromJsonc)(
1615
+ * '{ "name": "app", "version": 1 }',
1616
+ * );
1617
+ * ```
1618
+ *
1619
+ * @public
1620
+ */
1621
+ declare const JsoncFromString: Schema.Schema<unknown, string>;
1622
+ /**
1623
+ * Create a `Schema<unknown, string>` that decodes JSONC with custom
1624
+ * parse options.
1625
+ *
1626
+ * @param options - Partial {@link JsoncParseOptions} controlling comment
1627
+ * handling and trailing-comma tolerance.
1628
+ * @returns A `Schema<unknown, string>` configured with the given options.
1629
+ *
1630
+ * @remarks
1631
+ * The encode direction uses `JSON.stringify` with 2-space indentation,
1632
+ * which produces standard JSON. Comments present in the original JSONC
1633
+ * input are not preserved during a round-trip encode.
1634
+ *
1635
+ * @see {@link JsoncFromString} for a zero-config default instance.
1636
+ * @see {@link makeJsoncSchema} to compose JSONC parsing with a domain
1637
+ * schema in one step.
1638
+ *
1639
+ * @example Strict mode (no comments, no trailing commas)
1640
+ * ```ts
1641
+ * import { Schema } from "effect";
1642
+ * import { makeJsoncFromString } from "jsonc-effect";
1643
+ *
1644
+ * const StrictJsoncFromString = makeJsoncFromString({
1645
+ * disallowComments: true,
1646
+ * allowTrailingComma: false,
1647
+ * });
1648
+ *
1649
+ * const value: unknown = Schema.decodeUnknownSync(StrictJsoncFromString)(
1650
+ * '{ "key": 42 }',
1651
+ * );
1652
+ * ```
1653
+ *
1654
+ * @privateRemarks
1655
+ * Internally delegates to `Schema.transformOrFail` to wire up the decode
1656
+ * and encode directions.
1657
+ *
1658
+ * @public
1659
+ */
1660
+ declare function makeJsoncFromString(options?: Partial<JsoncParseOptions>): Schema.Schema<unknown, string>;
1661
+ /**
1662
+ * Create a composed `Schema<A, string>` that parses a JSONC string and
1663
+ * validates the result against a target domain schema in one step.
1664
+ *
1665
+ * @param targetSchema - The domain schema to validate the parsed value
1666
+ * against. Its input type `I` must be assignable from `unknown`.
1667
+ * @param options - Optional partial {@link JsoncParseOptions} forwarded to
1668
+ * the underlying JSONC parser.
1669
+ * @returns A `Schema<A, string>` that goes directly from a JSONC string
1670
+ * to a fully validated domain value of type `A`.
1671
+ *
1672
+ * @remarks
1673
+ * Internally composes two schema stages:
1674
+ *
1675
+ * 1. JSONC string to `unknown` (via {@link makeJsoncFromString}).
1676
+ * 2. `unknown` to `A` (via the provided `targetSchema`).
1677
+ *
1678
+ * This avoids the need to manually call `Schema.compose`.
1679
+ *
1680
+ * @see {@link makeJsoncFromString} for the first stage of the pipeline.
1681
+ *
1682
+ * @example Typed configuration from JSONC
1683
+ * ```ts
1684
+ * import { Schema } from "effect";
1685
+ * import { makeJsoncSchema } from "jsonc-effect";
1686
+ *
1687
+ * const MyConfig = Schema.Struct({
1688
+ * name: Schema.String,
1689
+ * version: Schema.Number,
1690
+ * });
1691
+ *
1692
+ * const MyConfigFromJsonc = makeJsoncSchema(MyConfig);
1693
+ * const config = Schema.decodeUnknownSync(MyConfigFromJsonc)(
1694
+ * '{ "name": "app", "version": 1 }',
1695
+ * );
1696
+ * ```
1697
+ *
1698
+ * @example With custom parse options
1699
+ * ```ts
1700
+ * import { Schema } from "effect";
1701
+ * import { makeJsoncSchema } from "jsonc-effect";
1702
+ *
1703
+ * const MyConfig = Schema.Struct({ debug: Schema.Boolean });
1704
+ *
1705
+ * const StrictConfig = makeJsoncSchema(MyConfig, {
1706
+ * disallowComments: true,
1707
+ * allowTrailingComma: false,
1708
+ * });
1709
+ *
1710
+ * const config = Schema.decodeUnknownSync(StrictConfig)(
1711
+ * '{ "debug": true }',
1712
+ * );
1713
+ * ```
1714
+ *
1715
+ * @privateRemarks
1716
+ * Uses `Schema.compose` internally to chain the JSONC-from-string schema
1717
+ * with the provided target schema.
1718
+ *
1719
+ * @public
1720
+ */
1721
+ declare const makeJsoncSchema: <A, I>(targetSchema: Schema.Schema<A, I>, options?: Partial<JsoncParseOptions>) => Schema.Schema<A, string>;
1722
+ //#endregion
1723
+ //#region src/visitor.d.ts
1724
+ /**
1725
+ * Discriminated union of JSONC visitor events.
1726
+ *
1727
+ * Each variant carries an `_tag` discriminant, an `offset`, and a `length`
1728
+ * describing where the event occurred in the source text. Some variants
1729
+ * include additional fields such as `path`, `value`, or `property`.
1730
+ *
1731
+ * @remarks
1732
+ * The nine event types are:
1733
+ *
1734
+ * - **ObjectBegin** — opening `{` of an object, includes `path`.
1735
+ * - **ObjectEnd** — closing `}` of an object.
1736
+ * - **ObjectProperty** — a property key, includes `property` and `path`.
1737
+ * - **ArrayBegin** — opening `[` of an array, includes `path`.
1738
+ * - **ArrayEnd** — closing `]` of an array.
1739
+ * - **LiteralValue** — a string, number, boolean, or null literal,
1740
+ * includes `value` and `path`.
1741
+ * - **Separator** a `,` or `:` character.
1742
+ * - **Comment** — a line or block comment.
1743
+ * - **Error** a parse error, includes a {@link (JsoncParseErrorCode:type)} `code`.
1744
+ *
1745
+ * Use the `_tag` field to discriminate between variants in `switch`
1746
+ * statements or {@link https://effect.website/docs/stream/operations | Stream}
1747
+ * filter predicates.
1748
+ *
1749
+ * @see {@link visit} to produce a stream of these events.
1750
+ * @see {@link visitCollect} to collect matching events in one step.
1751
+ *
1752
+ * @example Filtering events by tag
1753
+ * ```ts
1754
+ * import { Chunk, Effect, Stream } from "effect";
1755
+ * import type { JsoncVisitorEvent } from "jsonc-effect";
1756
+ * import { visit } from "jsonc-effect";
1757
+ *
1758
+ * const literals = Effect.runSync(
1759
+ * visit('{ "a": 1 }').pipe(
1760
+ * Stream.filter(
1761
+ * (e): e is Extract<JsoncVisitorEvent, { _tag: "LiteralValue" }> =>
1762
+ * e._tag === "LiteralValue",
1763
+ * ),
1764
+ * Stream.runCollect,
1765
+ * Effect.map(Chunk.toReadonlyArray),
1766
+ * ),
1767
+ * );
1768
+ * ```
1769
+ *
1770
+ * @public
1771
+ */
1772
+ type JsoncVisitorEvent = {
1773
+ readonly _tag: "ObjectBegin";
1774
+ readonly offset: number;
1775
+ readonly length: number;
1776
+ readonly path: ReadonlyArray<string | number>;
1777
+ } | {
1778
+ readonly _tag: "ObjectEnd";
1779
+ readonly offset: number;
1780
+ readonly length: number;
1781
+ } | {
1782
+ readonly _tag: "ObjectProperty";
1783
+ readonly property: string;
1784
+ readonly offset: number;
1785
+ readonly length: number;
1786
+ readonly path: ReadonlyArray<string | number>;
1787
+ } | {
1788
+ readonly _tag: "ArrayBegin";
1789
+ readonly offset: number;
1790
+ readonly length: number;
1791
+ readonly path: ReadonlyArray<string | number>;
1792
+ } | {
1793
+ readonly _tag: "ArrayEnd";
1794
+ readonly offset: number;
1795
+ readonly length: number;
1796
+ } | {
1797
+ readonly _tag: "LiteralValue";
1798
+ readonly value: unknown;
1799
+ readonly offset: number;
1800
+ readonly length: number;
1801
+ readonly path: ReadonlyArray<string | number>;
1802
+ } | {
1803
+ readonly _tag: "Separator";
1804
+ readonly character: string;
1805
+ readonly offset: number;
1806
+ readonly length: number;
1807
+ } | {
1808
+ readonly _tag: "Comment";
1809
+ readonly offset: number;
1810
+ readonly length: number;
1811
+ } | {
1812
+ readonly _tag: "Error";
1813
+ readonly code: JsoncParseErrorCode;
1814
+ readonly offset: number;
1815
+ readonly length: number;
1816
+ };
1817
+ /**
1818
+ * Create a lazy `Stream` of {@link JsoncVisitorEvent} from JSONC text.
1819
+ *
1820
+ * Events are produced on demand as the stream is consumed, not
1821
+ * pre-collected into memory. This makes `visit` suitable for large
1822
+ * documents and supports early termination via `Stream.take` or
1823
+ * `Stream.takeWhile` without scanning the entire input.
1824
+ *
1825
+ * @param text - The JSONC source text to visit.
1826
+ * @param options - Optional partial {@link JsoncParseOptions} controlling
1827
+ * comment handling and trailing-comma tolerance.
1828
+ * @returns A `Stream` of {@link JsoncVisitorEvent} objects.
1829
+ *
1830
+ * @remarks
1831
+ * The stream is backed by a lazy generatorno work is performed until
1832
+ * the stream is consumed. Because evaluation is demand-driven, combining
1833
+ * `visit` with `Stream.take` allows efficient partial scans of large
1834
+ * documents without allocating a full AST.
1835
+ *
1836
+ * @see {@link visitCollect} for a one-step filter-and-collect convenience.
1837
+ * @see {@link JsoncVisitorEvent} for the event type definitions.
1838
+ *
1839
+ * @example Collect all events
1840
+ * ```ts
1841
+ * import { Chunk, Effect, Stream } from "effect";
1842
+ * import { visit } from "jsonc-effect";
1843
+ *
1844
+ * const all = Effect.runSync(
1845
+ * visit('{ "a": 1 }').pipe(
1846
+ * Stream.runCollect,
1847
+ * Effect.map(Chunk.toReadonlyArray),
1848
+ * ),
1849
+ * );
1850
+ * ```
1851
+ *
1852
+ * @example Filter and take the first match
1853
+ * ```ts
1854
+ * import { Chunk, Effect, Stream } from "effect";
1855
+ * import { visit } from "jsonc-effect";
1856
+ *
1857
+ * const firstLiteral = Effect.runSync(
1858
+ * visit('{ "a": 1, "b": 2 }').pipe(
1859
+ * Stream.filter((e) => e._tag === "LiteralValue"),
1860
+ * Stream.take(1),
1861
+ * Stream.runCollect,
1862
+ * Effect.map(Chunk.toReadonlyArray),
1863
+ * ),
1864
+ * );
1865
+ * ```
1866
+ *
1867
+ * @example Extract property names
1868
+ * ```ts
1869
+ * import { Chunk, Effect, Stream } from "effect";
1870
+ * import { visit } from "jsonc-effect";
1871
+ *
1872
+ * const propertyNames = Effect.runSync(
1873
+ * visit('{ "name": "Alice", "age": 30 }').pipe(
1874
+ * Stream.filter((e) => e._tag === "ObjectProperty"),
1875
+ * Stream.map((e) => (e as { property: string }).property),
1876
+ * Stream.runCollect,
1877
+ * Effect.map(Chunk.toReadonlyArray),
1878
+ * ),
1879
+ * );
1880
+ * ```
1881
+ *
1882
+ * @privateRemarks
1883
+ * Internally wraps a generator function with `Stream.fromIterable`,
1884
+ * preserving laziness. The generator yields events as it encounters
1885
+ * tokens from the scanner.
1886
+ *
1887
+ * @public
1888
+ */
1889
+ declare const visit: (text: string, options?: Partial<JsoncParseOptions>) => Stream.Stream<JsoncVisitorEvent>;
1890
+ /**
1891
+ * Visit JSONC text and collect all events matching a type-guard predicate.
1892
+ *
1893
+ * This is a convenience that composes {@link visit}, `Stream.filter`, and
1894
+ * `Stream.runCollect` into a single call.
1895
+ *
1896
+ * @param text - The JSONC source text to visit.
1897
+ * @param predicate - A type-guard function that narrows
1898
+ * {@link JsoncVisitorEvent} to the desired subtype `A`.
1899
+ * @param options - Optional partial {@link JsoncParseOptions}.
1900
+ * @returns An `Effect` that succeeds with a read-only array of the
1901
+ * matched events.
1902
+ *
1903
+ * @remarks
1904
+ * Equivalent to:
1905
+ * ```
1906
+ * visit(text, options) |> Stream.filter(predicate) |> Stream.runCollect
1907
+ * ```
1908
+ * Use this when you need all matching events and do not require
1909
+ * intermediate stream transformations.
1910
+ *
1911
+ * @see {@link visit} for full stream-level control.
1912
+ *
1913
+ * @example Collecting literal values
1914
+ * ```ts
1915
+ * import { Effect } from "effect";
1916
+ * import type { JsoncVisitorEvent } from "jsonc-effect";
1917
+ * import { visitCollect } from "jsonc-effect";
1918
+ *
1919
+ * const literals = Effect.runSync(
1920
+ * visitCollect(
1921
+ * '{ "a": 1, "b": true }',
1922
+ * (e): e is Extract<JsoncVisitorEvent, { _tag: "LiteralValue" }> =>
1923
+ * e._tag === "LiteralValue",
1924
+ * ),
1925
+ * );
1926
+ * ```
1927
+ *
1928
+ * @public
1929
+ */
1930
+ declare const visitCollect: <A extends JsoncVisitorEvent>(text: string, predicate: (event: JsoncVisitorEvent) => event is A, options?: Partial<JsoncParseOptions>) => Effect.Effect<ReadonlyArray<A>>;
1931
+ //#endregion
1932
+ export { JsoncEdit, type JsoncError, JsoncFormattingOptions, JsoncFromString, JsoncModificationError, JsoncModificationErrorBase, JsoncNode, JsoncNodeNotFoundError, JsoncNodeNotFoundErrorBase, type JsoncNodeType, JsoncParseError, JsoncParseErrorBase, type JsoncParseErrorCode, JsoncParseErrorDetail, JsoncParseOptions, type JsoncPath, JsoncRange, type JsoncScanError, type JsoncScanner, type JsoncSegment, type JsoncSyntaxKind, JsoncToken, type JsoncVisitorEvent, applyEdits, createScanner, equals, equalsValue, findNode, findNodeAtOffset, format, formatAndApply, getNodePath, getNodeValue, makeJsoncFromString, makeJsoncSchema, modify, parse, parseTree, stripComments, visit, visitCollect };
1933
+ //# sourceMappingURL=index.d.ts.map