this repo has no description
1/**
2 * Example usage of TaggedStringParser
3 * Demonstrates basic usage, schema definition, formatters, and type inference
4 *
5 * Run with: node src/examples.ts
6 */
7
8import { TaggedStringParser } from './TaggedStringParser.ts'
9import type { EntitySchema } from './types.ts'
10
11// ============================================================================
12// Example 1: Basic Usage with Schema and Simple String Formatters
13// ============================================================================
14
15console.log('=== Example 1: Basic Usage with String Formatters ===\n')
16
17const basicSchema: EntitySchema = {
18 operation: { type: 'string', format: (v) => String(v).toUpperCase() },
19 stack: { type: 'string', format: (v) => String(v).trim() },
20 changes: { type: 'number', format: (n) => `${n} changes` },
21 status: 'string', // Shorthand without formatter
22}
23
24const basicParser = new TaggedStringParser({ schema: basicSchema })
25const result1 = basicParser.parse(
26 '[operation:deploy] started with [changes:5] to [stack: prod-stack ]',
27)
28
29console.log('Original message:', result1.originalMessage)
30console.log('Formatted message:', result1.format())
31console.log('\nParsed entities:')
32result1.entities.forEach((entity) => {
33 console.log(` - Type: ${entity.type}`)
34 console.log(` Raw value: "${entity.value}"`)
35 console.log(
36 ` Parsed value: ${entity.parsedValue} (${entity.inferredType})`,
37 )
38 console.log(` Formatted value: "${entity.formattedValue}"`)
39 console.log(` Position: ${entity.position}`)
40})
41
42// ============================================================================
43// Example 2: Automatic Type Inference for Unknown Entities
44// ============================================================================
45
46console.log('\n\n=== Example 2: Automatic Type Inference ===\n')
47
48const inferenceParser = new TaggedStringParser() // No schema
49const result2 = inferenceParser.parse(
50 '[count:42] items processed, [enabled:true] flag set, [name:test-service]',
51)
52
53console.log('Message:', result2.originalMessage)
54console.log('\nInferred types:')
55result2.entities.forEach((entity) => {
56 console.log(
57 ` - [${entity.type}:${entity.value}] → ${entity.inferredType} (${typeof entity.parsedValue})`,
58 )
59 console.log(` Parsed value: ${JSON.stringify(entity.parsedValue)}`)
60})
61
62// ============================================================================
63// Example 3: Entity Filtering by Type
64// ============================================================================
65
66console.log('\n\n=== Example 3: Entity Filtering ===\n')
67
68const filterSchema: EntitySchema = {
69 resource: 'string',
70 action: 'string',
71 count: 'number',
72}
73
74const filterParser = new TaggedStringParser({ schema: filterSchema })
75const result3 = filterParser.parse(
76 '[action:create] [resource:function] with [count:3] instances, [action:update] [resource:database]',
77)
78
79console.log('All entity types:', result3.getAllTypes())
80console.log(
81 '\nActions:',
82 result3.getEntitiesByType('action').map((e) => e.parsedValue),
83)
84console.log(
85 'Resources:',
86 result3.getEntitiesByType('resource').map((e) => e.parsedValue),
87)
88console.log(
89 'Counts:',
90 result3.getEntitiesByType('count').map((e) => e.parsedValue),
91)
92console.log('Non-existent type:', result3.getEntitiesByType('missing'))
93
94// ============================================================================
95// Example 4: IaC Logging Examples (from design document)
96// ============================================================================
97
98console.log('\n\n=== Example 4: IaC Logging Examples ===\n')
99
100const iacSchema: EntitySchema = {
101 operation: { type: 'string', format: (v) => `OP:${v}` },
102 stack: { type: 'string', format: (v) => `Stack(${v})` },
103 changes: { type: 'number', format: (n) => `${n} change(s)` },
104 blueprint: { type: 'string', format: (v) => `BP:${v}` },
105 create: 'number',
106 update: 'number',
107 destroy: 'number',
108 action: 'string',
109 resource: 'string',
110 resourceName: 'string',
111 type: 'string',
112 externalId: 'string',
113 reason: 'string',
114 error: 'string',
115}
116
117const iacParser = new TaggedStringParser({ schema: iacSchema })
118
119// Operation lifecycle
120console.log('Operation Lifecycle:')
121const op1 = iacParser.parse(
122 '[operation:OP-123] started with [changes:5] to [stack:ST-456]',
123)
124console.log(' ', op1.format())
125
126const op2 = iacParser.parse(
127 '[operation:OP-123] completed [changes:5] to [stack:ST-456]',
128)
129console.log(' ', op2.format())
130
131const op3 = iacParser.parse('[operation:OP-123] failed: [reason:Timeout error]')
132console.log(' ', op3.format())
133
134// Planning
135console.log('\nPlanning:')
136const plan1 = iacParser.parse('[blueprint:BP-123] planning for [stack:ST-456]')
137console.log(' ', plan1.format())
138
139const plan2 = iacParser.parse(
140 '[blueprint:BP-123] plan complete with [create:2] [update:3] [destroy:1] for [stack:ST-456]',
141)
142console.log(' ', plan2.format())
143console.log(' Plan summary:', {
144 create: plan2.getEntitiesByType('create')[0]?.parsedValue,
145 update: plan2.getEntitiesByType('update')[0]?.parsedValue,
146 destroy: plan2.getEntitiesByType('destroy')[0]?.parsedValue,
147})
148
149// Resource commands
150console.log('\nResource Commands:')
151const res1 = iacParser.parse(
152 '[action:create] executing for [resource:RS-123] [resourceName:my-function] [type:function]',
153)
154console.log(' ', res1.format())
155
156const res2 = iacParser.parse(
157 '[action:create] completed for [resource:RS-123] [externalId:EXT-789]',
158)
159console.log(' ', res2.format())
160
161const res3 = iacParser.parse(
162 '[action:create] failed for [resource:RS-123]: [error:Connection timeout]',
163)
164console.log(' ', res3.format())
165
166// ============================================================================
167// Example 5: Custom Configuration (Delimiters with Formatting)
168// ============================================================================
169
170console.log('\n\n=== Example 5: Custom Delimiters with Formatting ===\n')
171
172// This example demonstrates the fix for custom delimiter formatting
173// Previously, format() was hardcoded to use ']' and wouldn't work with custom delimiters
174// Now it correctly uses the configured delimiters to reconstruct messages
175
176const customParser = new TaggedStringParser({
177 openDelimiter: '{{',
178 closeDelimiter: '}}',
179 typeSeparator: '=',
180 schema: {
181 user: { type: 'string', format: (v) => `@${v}` },
182 count: { type: 'number', format: (v) => String(v) },
183 },
184})
185
186const result5 = customParser.parse(
187 'User {{user=john}} performed {{count=10}} actions',
188)
189console.log('Original message:', result5.originalMessage)
190console.log('Formatted message:', result5.format())
191console.log(' ✓ Custom delimiters {{}} work correctly with format()')
192console.log(' ✓ Formatters applied: user → @john, count → 10')
193
194console.log('\nParsed entities:')
195result5.entities.forEach((entity) => {
196 console.log(
197 ` - {{${entity.type}=${entity.value}}} at position ${entity.position}-${entity.endPosition}`,
198 )
199 console.log(` Formatted as: "${entity.formattedValue}"`)
200})
201
202// Additional custom delimiter examples
203console.log('\nOther custom delimiter configurations:')
204
205const angleParser = new TaggedStringParser({
206 openDelimiter: '<<',
207 closeDelimiter: '>>',
208 typeSeparator: ':',
209 schema: {
210 status: { type: 'string', format: (v) => String(v).toUpperCase() },
211 },
212})
213const angleResult = angleParser.parse('Operation <<status:success>> completed')
214console.log(' Angle brackets:', angleResult.format())
215
216const parenParser = new TaggedStringParser({
217 openDelimiter: '(',
218 closeDelimiter: ')',
219 typeSeparator: ':',
220 schema: {
221 code: { type: 'number', format: (n) => `#${n}` },
222 },
223})
224const parenResult = parenParser.parse('Error (code:404) occurred')
225console.log(' Parentheses:', parenResult.format())
226
227// ============================================================================
228// Example 6: Mixed Known and Unknown Entities
229// ============================================================================
230
231console.log('\n\n=== Example 6: Mixed Known and Unknown Entities ===\n')
232
233const mixedSchema: EntitySchema = {
234 operation: { type: 'string', format: (v) => `[OP: ${v}]` },
235 // Other entity types will be inferred
236}
237
238const mixedParser = new TaggedStringParser({ schema: mixedSchema })
239const result6 = mixedParser.parse(
240 '[operation:deploy] with [timeout:30] seconds and [retry:true] flag',
241)
242
243console.log('Formatted:', result6.format())
244console.log('\nEntity details:')
245result6.entities.forEach((entity) => {
246 const source = mixedSchema[entity.type] ? 'schema' : 'inferred'
247 console.log(
248 ` - ${entity.type}: ${entity.parsedValue} (${entity.inferredType}, ${source})`,
249 )
250})
251
252// ============================================================================
253// Example 7: Accessing Entity Properties
254// ============================================================================
255
256console.log('\n\n=== Example 7: Accessing Entity Properties ===\n')
257
258const propsSchema: EntitySchema = {
259 price: { type: 'number', format: (n) => `$${Number(n).toFixed(2)}` },
260 available: { type: 'boolean', format: (b) => (b ? '✓' : '✗') },
261 product: 'string',
262}
263
264const propsParser = new TaggedStringParser({ schema: propsSchema })
265const result7 = propsParser.parse(
266 '[product:Widget] is [available:true] at [price:29.99]',
267)
268
269console.log('Original message:', result7.originalMessage)
270console.log('Formatted message:', result7.format())
271console.log('\nDetailed entity properties:')
272result7.entities.forEach((entity) => {
273 console.log(`\n Entity: ${entity.type}`)
274 console.log(` value (raw string): "${entity.value}"`)
275 console.log(
276 ` parsedValue (typed): ${JSON.stringify(entity.parsedValue)} (${typeof entity.parsedValue})`,
277 )
278 console.log(` formattedValue (display): "${entity.formattedValue}"`)
279 console.log(` inferredType: ${entity.inferredType}`)
280 console.log(` position: ${entity.position}`)
281})
282
283// ============================================================================
284// Example 8: Handling Quoted Values
285// ============================================================================
286
287console.log('\n\n=== Example 8: Handling Quoted Values ===\n')
288
289const quotedParser = new TaggedStringParser({
290 schema: {
291 resourceName: 'string',
292 error: 'string',
293 },
294})
295
296const result8 = quotedParser.parse(
297 '[resourceName:"my-function"] failed with [error:"Connection timeout"]',
298)
299console.log('Original:', result8.originalMessage)
300console.log('\nEntity values (quotes preserved):')
301result8.entities.forEach((entity) => {
302 console.log(` ${entity.type}: ${entity.value}`)
303})
304
305console.log('\n=== Examples Complete ===\n')
306// ============================================================================
307// Example 9: Producer-Consumer Pattern with Generator
308// ============================================================================
309
310console.log('\n\n=== Example 9: Producer-Consumer Pattern ===\n')
311
312import { TaggedStringGenerator } from './TaggedStringGenerator.ts'
313
314// Producer: Generate tagged strings
315const generator = new TaggedStringGenerator()
316
317console.log('Producer generating tagged strings:')
318const generatedMessage1 = generator.embed('Starting ', 'operation', 'deploy')
319console.log(' ', generatedMessage1)
320
321const generatedMessage2 = generator.embed('Processing ', 'stack', 'prod-stack')
322console.log(' ', generatedMessage2)
323
324const generatedMessage3 = `${generator.tag('operation', 'deploy')} completed with ${generator.tag('changes', 5)} to ${generator.tag('stack', 'prod-stack')}`
325console.log(' ', generatedMessage3)
326
327// Consumer: Parse the generated strings
328const consumerSchema: EntitySchema = {
329 operation: { type: 'string', format: (v) => String(v).toUpperCase() },
330 stack: { type: 'string', format: (v) => `Stack(${v})` },
331 changes: { type: 'number', format: (n) => `${n} change(s)` },
332}
333
334const consumerParser = new TaggedStringParser({ schema: consumerSchema })
335
336console.log('\nConsumer parsing generated strings:')
337const parsed1 = consumerParser.parse(generatedMessage1)
338console.log(' Original:', parsed1.originalMessage)
339console.log(' Formatted:', parsed1.format())
340console.log(
341 ' Entities:',
342 parsed1.entities.map((e) => `${e.type}=${e.parsedValue}`),
343)
344
345const parsed3 = consumerParser.parse(generatedMessage3)
346console.log('\n Original:', parsed3.originalMessage)
347console.log(' Formatted:', parsed3.format())
348console.log(
349 ' Entities:',
350 parsed3.entities.map((e) => `${e.type}=${e.parsedValue}`),
351)
352
353// Demonstrate matching configurations
354console.log('\n✓ Producer and consumer use matching default configuration')
355console.log('✓ Generated tags are correctly parsed and formatted')
356
357// ============================================================================
358// Example 10: Custom Delimiters with Generator and Parser
359// ============================================================================
360
361console.log('\n\n=== Example 10: Custom Delimiters with Generator ===\n')
362
363// Producer with custom delimiters
364const customConfig = {
365 openDelimiter: '{{',
366 closeDelimiter: '}}',
367 typeSeparator: '=',
368}
369
370const customGenerator = new TaggedStringGenerator(customConfig)
371
372console.log('Producer generating with custom delimiters {{}}:')
373const customMessage1 = customGenerator.embed('User ', 'user', 'alice')
374console.log(' ', customMessage1)
375
376const customMessage2 = `${customGenerator.tag('action', 'login')} by ${customGenerator.tag('user', 'alice')} at ${customGenerator.tag('timestamp', 1699999999)}`
377console.log(' ', customMessage2)
378
379// Consumer with matching custom delimiters
380const customConsumerParser = new TaggedStringParser({
381 ...customConfig,
382 schema: {
383 user: { type: 'string', format: (v) => `@${v}` },
384 action: { type: 'string', format: (v) => String(v).toUpperCase() },
385 timestamp: {
386 type: 'number',
387 format: (n) => new Date(Number(n) * 1000).toISOString(),
388 },
389 },
390})
391
392console.log('\nConsumer parsing with matching custom delimiters:')
393const customParsed1 = customConsumerParser.parse(customMessage1)
394console.log(' Original:', customParsed1.originalMessage)
395console.log(' Formatted:', customParsed1.format())
396
397const customParsed2 = customConsumerParser.parse(customMessage2)
398console.log('\n Original:', customParsed2.originalMessage)
399console.log(' Formatted:', customParsed2.format())
400console.log(
401 ' Entities:',
402 customParsed2.entities.map((e) => `${e.type}=${e.parsedValue}`),
403)
404
405console.log('\n✓ Custom delimiters work correctly with generator and parser')
406console.log('✓ Configuration consistency ensures proper round-trip')
407
408// ============================================================================
409// Example 11: Delimiter-Free Mode - Basic Usage
410// ============================================================================
411
412console.log('\n\n=== Example 11: Delimiter-Free Mode - Basic Usage ===\n')
413
414const delimiterFreeParser = new TaggedStringParser({
415 delimiters: false,
416 typeSeparator: '=',
417 schema: {
418 order: 'number',
419 status: 'string',
420 user: 'string',
421 },
422})
423
424const result11 = delimiterFreeParser.parse(
425 'Processing order=1337 with status=pending for user=alice',
426)
427
428console.log('Original message:', result11.originalMessage)
429console.log('Formatted message:', result11.format())
430console.log('\nExtracted entities:')
431result11.entities.forEach((entity) => {
432 console.log(
433 ` - ${entity.type}=${entity.value} (${entity.inferredType}) at position ${entity.position}`,
434 )
435})
436
437// ============================================================================
438// Example 12: Delimiter-Free Mode - Natural Language
439// ============================================================================
440
441console.log('\n\n=== Example 12: Delimiter-Free Mode - Natural Language ===\n')
442
443const naturalParser = new TaggedStringParser({
444 delimiters: [],
445 typeSeparator: '=',
446 schema: {
447 order: { type: 'number', format: (n) => `Order #${n}` },
448 status: { type: 'string', format: (v) => String(v).toUpperCase() },
449 },
450})
451
452const result12 = naturalParser.parse(
453 'An order=1337 was placed and status=confirmed',
454)
455
456console.log('Original:', result12.originalMessage)
457console.log('Formatted:', result12.format())
458console.log(
459 '\nEntities:',
460 result12.entities.map((e) => `${e.type}=${e.parsedValue}`),
461)
462
463// ============================================================================
464// Example 13: Quoted Values with Spaces
465// ============================================================================
466
467console.log('\n\n=== Example 13: Quoted Values with Spaces ===\n')
468
469const quotedValuesParser = new TaggedStringParser({
470 delimiters: false,
471 typeSeparator: '=',
472})
473
474const result13a = quotedValuesParser.parse(
475 'description="high priority task" created',
476)
477console.log('Quoted value:', result13a.entities[0].value)
478console.log(' ✓ Spaces preserved in quoted value')
479
480const result13b = quotedValuesParser.parse('order="number 42" was processed')
481console.log('\nQuoted value with number:', result13b.entities[0].value)
482console.log(' ✓ Type separator preserved in quoted value')
483
484const result13c = quotedValuesParser.parse(
485 'Multiple entities: name="John Doe" age=30 city="New York"',
486)
487console.log('\nMultiple entities with quoted values:')
488result13c.entities.forEach((entity) => {
489 console.log(` - ${entity.type}: "${entity.value}"`)
490})
491
492// ============================================================================
493// Example 14: Quoted Keys with Spaces
494// ============================================================================
495
496console.log('\n\n=== Example 14: Quoted Keys with Spaces ===\n')
497
498const quotedKeysParser = new TaggedStringParser({
499 delimiters: false,
500 typeSeparator: '=',
501})
502
503const result14a = quotedKeysParser.parse('"user name"=alice logged in')
504console.log('Quoted key:', result14a.entities[0].type)
505console.log(' ✓ Spaces preserved in quoted key')
506
507const result14b = quotedKeysParser.parse(
508 '"store order"=1337 and "customer id"=42 recorded',
509)
510console.log('\nMultiple quoted keys:')
511result14b.entities.forEach((entity) => {
512 console.log(` - "${entity.type}" = ${entity.value}`)
513})
514
515// Both key and value quoted
516const result14c = quotedKeysParser.parse(
517 '"order type"="express delivery" selected',
518)
519console.log('\nBoth key and value quoted:')
520console.log(
521 ` - "${result14c.entities[0].type}" = "${result14c.entities[0].value}"`,
522)
523
524// ============================================================================
525// Example 15: Escape Sequences
526// ============================================================================
527
528console.log('\n\n=== Example 15: Escape Sequences ===\n')
529
530const escapeParser = new TaggedStringParser({
531 delimiters: false,
532 typeSeparator: '=',
533})
534
535// Escaped quotes
536const result15a = escapeParser.parse('message="She said \\"hello\\"" sent')
537console.log('Escaped quotes:', result15a.entities[0].value)
538console.log(' ✓ Literal quotes preserved: She said "hello"')
539
540// Escaped backslashes
541const result15b = escapeParser.parse(
542 'path="C:\\\\Program Files\\\\app.exe" opened',
543)
544console.log('\nEscaped backslashes:', result15b.entities[0].value)
545console.log(' ✓ Literal backslashes preserved: C:\\Program Files\\app.exe')
546
547// Mixed escapes
548const result15c = escapeParser.parse('text="Line 1\\nLine 2" contains \\n')
549console.log('\nMixed escapes:', result15c.entities[0].value)
550console.log(' ✓ Escape sequences processed: Line 1\\nLine 2')
551
552// Escape at end
553const result15d = escapeParser.parse('note="ends with backslash\\\\" saved')
554console.log('\nBackslash at end:', result15d.entities[0].value)
555console.log(' ✓ Trailing backslash preserved: ends with backslash\\')
556
557// ============================================================================
558// Example 16: Quoted Strings in Delimited Mode
559// ============================================================================
560
561console.log('\n\n=== Example 16: Quoted Strings in Delimited Mode ===\n')
562
563const delimitedQuotedParser = new TaggedStringParser({
564 delimiters: ['[', ']'],
565 typeSeparator: '=',
566})
567
568const result16a = delimitedQuotedParser.parse(
569 'Server ["linux server"=home] is running',
570)
571if (result16a.entities.length > 0) {
572 console.log('Quoted key in delimited mode:', result16a.entities[0].type)
573 console.log(' ✓ Spaces in type name: "linux server"')
574} else {
575 console.log('Note: Quoted keys in delimited mode require implementation')
576}
577
578const result16b = delimitedQuotedParser.parse('[server="web server"] is active')
579if (result16b.entities.length > 0) {
580 console.log('\nQuoted value in delimited mode:', result16b.entities[0].value)
581 console.log(' ✓ Spaces in value: "web server"')
582} else {
583 console.log('\nNote: Quoted values in delimited mode require implementation')
584}
585
586const result16c = delimitedQuotedParser.parse(
587 '["linux server"="production server"] configured',
588)
589if (result16c.entities.length > 0) {
590 console.log('\nBoth quoted in delimited mode:')
591 console.log(` - Type: "${result16c.entities[0].type}"`)
592 console.log(` - Value: "${result16c.entities[0].value}"`)
593} else {
594 console.log('\nNote: Both quoted in delimited mode requires implementation')
595}
596
597// ============================================================================
598// Example 17: Delimiter-Free vs Delimited Mode Comparison
599// ============================================================================
600
601console.log('\n\n=== Example 17: Mode Comparison ===\n')
602
603const message = 'order=1337 was placed'
604
605// Delimiter-free mode extracts the pattern
606const freeParser = new TaggedStringParser({
607 delimiters: false,
608 typeSeparator: '=',
609})
610const freeResult = freeParser.parse(message)
611console.log('Delimiter-free mode:')
612console.log(' Input:', message)
613console.log(' Entities found:', freeResult.entities.length)
614console.log(
615 ' Extracted:',
616 freeResult.entities.map((e) => `${e.type}=${e.value}`),
617)
618
619// Delimited mode ignores the pattern
620const delimitedParser = new TaggedStringParser({ delimiters: ['[', ']'] })
621const delimitedResult = delimitedParser.parse(message)
622console.log('\nDelimited mode:')
623console.log(' Input:', message)
624console.log(' Entities found:', delimitedResult.entities.length)
625console.log(' ✓ Delimiter-free patterns ignored in delimited mode')
626
627// Delimited mode with proper tags
628const delimitedMessage = '[order:1337] was placed'
629const delimitedResult2 = delimitedParser.parse(delimitedMessage)
630console.log('\nDelimited mode with tags:')
631console.log(' Input:', delimitedMessage)
632console.log(' Entities found:', delimitedResult2.entities.length)
633console.log(
634 ' Extracted:',
635 delimitedResult2.entities.map((e) => `${e.type}:${e.value}`),
636)
637
638// ============================================================================
639// Example 18: Delimiter-Free with Custom Type Separator
640// ============================================================================
641
642console.log('\n\n=== Example 18: Custom Type Separator ===\n')
643
644const colonParser = new TaggedStringParser({
645 delimiters: false,
646 typeSeparator: ':',
647})
648
649const result18 = colonParser.parse('Processing order:1337 with status:pending')
650console.log('Using colon separator:')
651console.log(' Input:', result18.originalMessage)
652console.log(
653 ' Entities:',
654 result18.entities.map((e) => `${e.type}:${e.value}`),
655)
656
657// ============================================================================
658// Example 19: Error Handling in Delimiter-Free Mode
659// ============================================================================
660
661console.log('\n\n=== Example 19: Error Handling ===\n')
662
663const errorParser = new TaggedStringParser({
664 delimiters: false,
665 typeSeparator: '=',
666})
667
668// Unclosed quote - entity skipped
669const result19a = errorParser.parse('order="unclosed value was placed')
670console.log('Unclosed quote:')
671console.log(' Input: order="unclosed value was placed')
672console.log(' Entities found:', result19a.entities.length)
673console.log(' ✓ Malformed entity skipped, parsing continues')
674
675// Key without value - skipped
676const result19b = errorParser.parse('order= status=pending')
677console.log('\nEmpty value:')
678console.log(' Input: order= status=pending')
679console.log(' Entities found:', result19b.entities.length)
680console.log(
681 ' Extracted:',
682 result19b.entities.map((e) => `${e.type}=${e.value}`),
683)
684console.log(' ✓ Empty value skipped, valid entity extracted')
685
686// Mixed valid and invalid
687const result19c = errorParser.parse('valid=123 invalid="unclosed another=456')
688console.log('\nMixed valid and invalid:')
689console.log(' Input: valid=123 invalid="unclosed another=456')
690console.log(
691 ' Entities:',
692 result19c.entities.map((e) => `${e.type}=${e.value}`),
693)
694console.log(' ✓ Parser continues after errors')
695
696// ============================================================================
697// Example 20: Real-World Use Case - Log Parsing
698// ============================================================================
699
700console.log('\n\n=== Example 20: Real-World Log Parsing ===\n')
701
702const logParser = new TaggedStringParser({
703 delimiters: false,
704 typeSeparator: '=',
705 schema: {
706 user: { type: 'string', format: (v) => `@${v}` },
707 order: { type: 'number', format: (n) => `Order #${n}` },
708 status: { type: 'string', format: (v) => String(v).toUpperCase() },
709 amount: { type: 'number', format: (n) => `$${Number(n).toFixed(2)}` },
710 },
711})
712
713const logs = [
714 'User user=alice placed order=1337 with amount=99.99',
715 'Order order=1337 status=confirmed for user=alice',
716 'Payment amount=99.99 processed for order=1337',
717 'Order order=1337 status=shipped to user=alice',
718]
719
720console.log('Parsing application logs:')
721logs.forEach((log, i) => {
722 const result = logParser.parse(log)
723 console.log(`\n Log ${i + 1}:`, log)
724 console.log(' Formatted:', result.format())
725 console.log(
726 ' Entities:',
727 result.entities.map((e) => `${e.type}=${e.parsedValue}`).join(', '),
728 )
729})
730
731console.log('\n✓ Delimiter-free mode ideal for natural language logs')
732console.log('✓ Schema formatters enhance readability')
733
734console.log('\n=== All Examples Complete ===\n')