mason-parser 1.0.0 → 1.0.2

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/README.md CHANGED
@@ -1,11 +1,37 @@
1
1
  # mason-parser
2
2
 
3
- > Markdown Structured Object Notation (MSON) — The human-centric serialization format that bridges natural markdown visual structure and lightweight, structured JSON.
3
+ > Markdown Structured Object Notation (MaSON) — A human-centric serialization format bridging natural markdown visual hierarchy and structured JSON.
4
4
 
5
5
  [![License](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6
6
  [![NPM Version](https://img.shields.io/npm/v/mason-parser.svg)](https://www.npmjs.com/package/mason-parser)
7
7
 
8
- MSON is a super-lightweight alternative to JSON/YAML/TOML designed specifically for **configuration files**, **static content documents**, and **efficient Prompting / Context storage for Large Language Models (LLMs)**. It reduces token overhead by **15% to 30%** compared to standard JSON by replacing heavy syntactic delimiters (such as braces, brackets, and redundant key quotes) with standard, beautiful Markdown headers and itemized lists.
8
+ MaSON is a lightweight serialization format designed for **human-authored hierarchical documents**, **application configurations**, and **clean context-sharing for Large Language Models (LLMs)**. It replaces structural punctuation (such as curly braces, brackets, and redundant double-quoted keys) with natural Markdown headings and bulleted lists.
9
+
10
+ ---
11
+
12
+ ## 🎯 What Problem Does MaSON Solve?
13
+
14
+ MaSON fits a specific niche: **human-authored hierarchical documents where visual readability and writeability are more important than representing every complex or strict academic data type.**
15
+
16
+ ### How it Compares:
17
+ * **Why not JSON?** JSON is a fantastic machine-to-machine format but is tedious for humans to author or edit. Forgetting a trailing comma, double quote, or bracket results in immediate syntax errors. MaSON allows writing hierarchy naturally.
18
+ * **Why not YAML?** YAML is powerful, but its specification is substantially more complex than MaSON's. Its indentation-sensitive syntax can also lead to subtle formatting errors when editing by hand. MaSON uses standard Markdown headings to nest structures safely.
19
+ * **Why not TOML?** TOML is highly readable for flat structures, but its readability degrades rapidly when representing deeply nested hierarchies (requiring verbose table brackets like `[servers.database.credentials]`). MaSON utilizes standard Markdown heading depths (`#`, `##`, `###`) to establish nesting levels.
20
+
21
+ ---
22
+
23
+ ## 🎨 Design Philosophy
24
+
25
+ ### Design Goals
26
+ - **Easy to read in plain text:** Looks like regular Markdown documentation.
27
+ - **Easy to author manually:** No strict whitespace parsing, bracket-matching, or comma rules.
28
+ - **Easy to parse:** Extremely small parser footprint (under 2KB gzipped) with a small, maintainable grammar.
29
+ - **Deterministic & Round-trip Safe:** Standard structures parse and stringify back-and-forth cleanly.
30
+
31
+ ### Non-Goals
32
+ - **Full YAML/JSON feature-parity:** No support for advanced data types or custom type tagging.
33
+ - **Anchors, aliases, or references:** No complex object graphs or internal links.
34
+ - **YAML-style indentation rules:** No complex multi-space layout rules. MaSON prefers simple explicit visual suffixes (`[]`) or top-level annotations over indentation-sensitive arrays.
9
35
 
10
36
  ---
11
37
 
@@ -13,9 +39,9 @@ MSON is a super-lightweight alternative to JSON/YAML/TOML designed specifically
13
39
 
14
40
  - **Zero-Bracket Nesting:** Structure child objects implicitly via standard Markdown headings (`#`, `##`, `###`).
15
41
  - **Natural Array Triggers:** Bulleted lists (`*`, `-`, `+`) automatically morph parent containers into ordered arrays.
16
- - **Implicit Type Casting:** Native scanning of numbers, floats, booleans (`true`/`false`), and `null` values without tedious string conversions.
17
- - **LLM-Token Friendly:** Eliminates redundant nested syntax, resulting in massive prompt and response cost reductions when feeding data to Gemini, GPT, or Claude.
18
- - **Bi-directional Integrity:** Safely stringifies complex objects back to MSON, complete with sorted parameters and beautiful spaced structure.
42
+ - **Implicit Type Inference:** Native detection of numbers, floats, booleans (`true`/`false`), and `null` values without tedious string conversions.
43
+ - **Grounded Token Efficiency:** In nested configuration files and content-rich documents, MaSON can reduce raw characters compared to equivalent JSON by eliminating repeated brackets, braces, and quotation marks. This is especially useful in LLM workflows, where concise representations can help maximize available context and minimize token overhead.
44
+ - **Bi-directional Integrity:** Safely stringifies standard JavaScript objects back to MaSON, complete with sorted parameters and clean spacing.
19
45
 
20
46
  ---
21
47
 
@@ -52,7 +78,7 @@ host: localhost
52
78
  * BackupNode2
53
79
  ```
54
80
 
55
- ### 2. Parse MSON into JSON
81
+ ### 2. Parse MaSON into JSON
56
82
  ```typescript
57
83
  import { parse } from 'mason-parser';
58
84
  import fs from 'fs';
@@ -86,7 +112,7 @@ console.log(data);
86
112
  */
87
113
  ```
88
114
 
89
- ### 3. Stringify back to MSON
115
+ ### 3. Stringify back to MaSON
90
116
  ```typescript
91
117
  import { stringify } from 'mason-parser';
92
118
 
@@ -112,14 +138,91 @@ active: true
112
138
 
113
139
  ## 📜 Grammar & Formatting Rules
114
140
 
115
- 1. **Parameters:** Represented by `key: value` pairs. Value is implicitly parsed as a primitive (`number`, `boolean`, `null`, or `string`).
116
- 2. **Quoting:** To force any numerical sequence or boolean value to stay a string, simply wrap it in quotes: `zipCode: "16801"`.
141
+ At a high level, a MaSON document is parsed line-by-line using a small, deterministic grammar.
142
+
143
+ ```text
144
+ Document
145
+ ├── Line (Comment / Empty) -> Ignored
146
+ ├── Line (Top-Level Array: []) -> Initializes the document as an anonymous Array
147
+ ├── Line (Heading: #+) -> Opens a nested Object or Object within an Array
148
+ ├── Line (Bullet: *, -, +) -> Pushes a primitive value to an active array
149
+ └── Line (Property: k: v) -> Sets a property on the active container
150
+ ```
151
+
152
+ 1. **Parameters:** Represented by `key: value` pairs. The value is implicitly parsed as a primitive (`number`, `boolean`, `null`, or `string`).
153
+ 2. **Quoting:** To force any numerical sequence or boolean value to remain a string, wrap it in double or single quotes: `zipCode: "16801"`.
117
154
  3. **Headings:**
118
155
  - Any property before the first `#` is declared at the root level.
119
156
  - `#` headings denote level 1 object parameters.
120
157
  - `##` headings nest themselves inside the active `#` parent object.
121
- - If there is no active `#` heading, `##` headings fall back to root.
122
- 4. **Lists:** Bullet elements (`*`, `-`, `+`) immediately turn the nearest active heading key into an ordered array of typed primitives or objects.
158
+ - If there is no active parent at the required depth, headings fall back to root or nearest sibling.
159
+ 4. **Lists:** Bullet elements (`*`, `-`, `+`) immediately convert the nearest active heading key into an ordered array of typed primitives.
160
+ 5. **Explicit Array Suffix (`[]`):** To define an array of complex objects, append `[]` to the heading name (e.g., `# Users[]`). Any nested heading under it (e.g. `## User` or `##`) pushes a new object into that array.
161
+ 6. **Top-Level Anonymous Arrays:** To make the entire document parse as a top-level array, define `[]` on the very first non-empty line of the file. Each subsequent item header (like `##`) directly pushes a new anonymous object into this array.
162
+ 7. **Anonymous & Descriptive Heading Labels:** When defining elements of an array (explicit or top-level), heading names are fully optional. You can use empty heading lines (e.g., `## ` or `##`) or descriptive notes (e.g., `## Alice (Admin)`) without affecting the structured JSON properties.
163
+ 8. **Multiline Values:** Wrap any multi-line text block or formatted string in backticks (`` ` ``). The parser will automatically preserve formatting and newlines within the block.
164
+
165
+ ---
166
+
167
+ ## 🔍 Edge-Case Specification
168
+
169
+ To ensure predictable behavior, `mason-parser` handles edge cases according to the following rules:
170
+
171
+ ### 1. Duplicate Headings
172
+ ```markdown
173
+ # User
174
+ name: Alice
175
+
176
+ # User
177
+ name: Bob
178
+ ```
179
+ * **Behavior:** Overwrites. The second `# User` initializes a fresh object under the `User` key, overwriting the first one. To represent list-like collections, use bullet points under a single heading instead.
180
+
181
+ ### 2. Mixed-Type Arrays
182
+ ```markdown
183
+ # Items
184
+ * 1
185
+ * true
186
+ * hello
187
+ ```
188
+ * **Behavior:** Allowed. Bullets are parsed individually. The parser yields `[1, true, "hello"]`.
189
+
190
+ ### 3. Arrays of Objects
191
+ * **Behavior:** MaSON supports arrays of complex objects using the explicit array suffix (`[]`) or a top-level array modifier (`[]`). Inside these arrays, heading names can be customized with descriptive labels or left completely empty (anonymous objects). For example:
192
+ ```markdown
193
+ # Users[]
194
+
195
+ ## Administrator
196
+ name: Alice
197
+ role: admin
198
+
199
+ ##
200
+ name: Bob
201
+ role: user
202
+ ```
203
+ This parses directly into an array containing both objects under the key `"Users"`.
204
+
205
+ ### 4. Empty Headings
206
+ ```markdown
207
+ # Settings
208
+ ```
209
+ * **Behavior:** Resolves to `{}`. Encountering a heading immediately instantiates an empty object placeholder in the parent node.
210
+
211
+ ### 5. Backtick Delimiters (Matching)
212
+ MaSON handles backticks dynamically based on matching the count of opening and closing backticks:
213
+ * **Matching Delimiters & Language Tags:** A block or string starts with any count of backticks `N` (e.g. `1` backtick or `3` backticks) and ends with exactly `N` backticks. The surrounding delimiters on both ends are completely stripped.
214
+ * **Language Tag Stripping:** If opening with 3 or more backticks (e.g. ```` ```javascript ````), a single alphanumeric language identifier following the backticks is automatically stripped to enable seamless Markdown copying.
215
+ ```markdown
216
+ script: ```javascript
217
+ function calculateTotal() {}
218
+ ```
219
+ ```
220
+ * **Behavior:** Resolves to `"function calculateTotal() {}"`.
221
+ * **Embedding Backticks:** By using `N` backticks as the delimiter, you can easily embed backticks of other lengths (such as code spans of length `1`) without them being treated as delimiters.
222
+ ```markdown
223
+ literalText: `` `code` ``
224
+ ```
225
+ * **Behavior:** Resolves to `"`code`"`.
123
226
 
124
227
  ---
125
228
 
package/dist/index.d.mts CHANGED
@@ -24,11 +24,21 @@ interface ParseResult {
24
24
  tokenSavingsPercent: number;
25
25
  };
26
26
  }
27
+ interface ParseOptions {
28
+ noTrace?: boolean;
29
+ }
27
30
  /**
28
31
  * Casts a string value to its implicit primitive type or returns the string.
29
- * Strips quotes if they enclose the string explicitly.
32
+ * Strips quotes if they enclose the string explicitly and restores escaped characters.
30
33
  */
31
34
  declare function parsePrimitiveValue(val: string): any;
35
+ /**
36
+ * Parses a single-line or multiline value, advancing the line reader index if needed.
37
+ */
38
+ declare function parseValueWithMultiline(initialValStr: string, lines: string[], currentLineIndex: number): {
39
+ value: any;
40
+ nextLineIndex: number;
41
+ };
32
42
  /**
33
43
  * Formats a value for MSON stringification.
34
44
  * Wraps in quotes if it has special characters or looks like a keyword but is a string.
@@ -37,14 +47,18 @@ declare function stringifyPrimitiveValue(val: any): string;
37
47
  /**
38
48
  * Parses MSON text into a JavaScript Object / Array.
39
49
  */
40
- declare function parse(text: string): any;
50
+ declare function parse(text: string, options?: ParseOptions): any;
51
+ /**
52
+ * Ultra-performance, trace-free parser for MSON.
53
+ */
54
+ declare function fastParseWithTrace(text: string): ParseResult;
41
55
  /**
42
56
  * Parses MSON text into a JavaScript Object / Array with step-by-step trace info.
43
57
  */
44
- declare function parseWithTrace(text: string): ParseResult;
58
+ declare function parseWithTrace(text: string, options?: ParseOptions): ParseResult;
45
59
  /**
46
60
  * Stringifies a JavaScript object/array back into MSON text recursively.
47
61
  */
48
- declare function stringify(obj: any, level?: number): string;
62
+ declare function stringify(obj: any, level?: number, parentKey?: string): string;
49
63
 
50
- export { type ParseResult, type ParserTraceStep, parse, parse as parseMSON, parsePrimitiveValue, parseWithTrace, stringify, stringify as stringifyMSON, stringifyPrimitiveValue };
64
+ export { type ParseOptions, type ParseResult, type ParserTraceStep, fastParseWithTrace, parse, parse as parseMSON, parseWithTrace as parseMaSON, parsePrimitiveValue, parseValueWithMultiline, parseWithTrace, stringify, stringify as stringifyMSON, stringify as stringifyMaSON, stringifyPrimitiveValue };
package/dist/index.d.ts CHANGED
@@ -24,11 +24,21 @@ interface ParseResult {
24
24
  tokenSavingsPercent: number;
25
25
  };
26
26
  }
27
+ interface ParseOptions {
28
+ noTrace?: boolean;
29
+ }
27
30
  /**
28
31
  * Casts a string value to its implicit primitive type or returns the string.
29
- * Strips quotes if they enclose the string explicitly.
32
+ * Strips quotes if they enclose the string explicitly and restores escaped characters.
30
33
  */
31
34
  declare function parsePrimitiveValue(val: string): any;
35
+ /**
36
+ * Parses a single-line or multiline value, advancing the line reader index if needed.
37
+ */
38
+ declare function parseValueWithMultiline(initialValStr: string, lines: string[], currentLineIndex: number): {
39
+ value: any;
40
+ nextLineIndex: number;
41
+ };
32
42
  /**
33
43
  * Formats a value for MSON stringification.
34
44
  * Wraps in quotes if it has special characters or looks like a keyword but is a string.
@@ -37,14 +47,18 @@ declare function stringifyPrimitiveValue(val: any): string;
37
47
  /**
38
48
  * Parses MSON text into a JavaScript Object / Array.
39
49
  */
40
- declare function parse(text: string): any;
50
+ declare function parse(text: string, options?: ParseOptions): any;
51
+ /**
52
+ * Ultra-performance, trace-free parser for MSON.
53
+ */
54
+ declare function fastParseWithTrace(text: string): ParseResult;
41
55
  /**
42
56
  * Parses MSON text into a JavaScript Object / Array with step-by-step trace info.
43
57
  */
44
- declare function parseWithTrace(text: string): ParseResult;
58
+ declare function parseWithTrace(text: string, options?: ParseOptions): ParseResult;
45
59
  /**
46
60
  * Stringifies a JavaScript object/array back into MSON text recursively.
47
61
  */
48
- declare function stringify(obj: any, level?: number): string;
62
+ declare function stringify(obj: any, level?: number, parentKey?: string): string;
49
63
 
50
- export { type ParseResult, type ParserTraceStep, parse, parse as parseMSON, parsePrimitiveValue, parseWithTrace, stringify, stringify as stringifyMSON, stringifyPrimitiveValue };
64
+ export { type ParseOptions, type ParseResult, type ParserTraceStep, fastParseWithTrace, parse, parse as parseMSON, parseWithTrace as parseMaSON, parsePrimitiveValue, parseValueWithMultiline, parseWithTrace, stringify, stringify as stringifyMSON, stringify as stringifyMaSON, stringifyPrimitiveValue };