@fuzdev/mdz 0.1.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.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/dist/Mdz.svelte +39 -0
  4. package/dist/Mdz.svelte.d.ts +17 -0
  5. package/dist/Mdz.svelte.d.ts.map +1 -0
  6. package/dist/MdzNodeView.svelte +140 -0
  7. package/dist/MdzNodeView.svelte.d.ts +9 -0
  8. package/dist/MdzNodeView.svelte.d.ts.map +1 -0
  9. package/dist/MdzPrecompiled.svelte +33 -0
  10. package/dist/MdzPrecompiled.svelte.d.ts +17 -0
  11. package/dist/MdzPrecompiled.svelte.d.ts.map +1 -0
  12. package/dist/MdzRoot.svelte +40 -0
  13. package/dist/MdzRoot.svelte.d.ts +14 -0
  14. package/dist/MdzRoot.svelte.d.ts.map +1 -0
  15. package/dist/MdzStream.svelte +37 -0
  16. package/dist/MdzStream.svelte.d.ts +18 -0
  17. package/dist/MdzStream.svelte.d.ts.map +1 -0
  18. package/dist/MdzStreamNodeView.svelte +150 -0
  19. package/dist/MdzStreamNodeView.svelte.d.ts +9 -0
  20. package/dist/MdzStreamNodeView.svelte.d.ts.map +1 -0
  21. package/dist/context_helpers.d.ts +23 -0
  22. package/dist/context_helpers.d.ts.map +1 -0
  23. package/dist/context_helpers.js +19 -0
  24. package/dist/mdz.d.ts +152 -0
  25. package/dist/mdz.d.ts.map +1 -0
  26. package/dist/mdz.js +61 -0
  27. package/dist/mdz_contexts.d.ts +106 -0
  28. package/dist/mdz_contexts.d.ts.map +1 -0
  29. package/dist/mdz_contexts.js +42 -0
  30. package/dist/mdz_helpers.d.ts +321 -0
  31. package/dist/mdz_helpers.d.ts.map +1 -0
  32. package/dist/mdz_helpers.js +668 -0
  33. package/dist/mdz_lexer.d.ts +123 -0
  34. package/dist/mdz_lexer.d.ts.map +1 -0
  35. package/dist/mdz_lexer.js +1405 -0
  36. package/dist/mdz_opcodes.d.ts +193 -0
  37. package/dist/mdz_opcodes.d.ts.map +1 -0
  38. package/dist/mdz_opcodes.js +14 -0
  39. package/dist/mdz_opcodes_to_nodes.d.ts +26 -0
  40. package/dist/mdz_opcodes_to_nodes.d.ts.map +1 -0
  41. package/dist/mdz_opcodes_to_nodes.js +410 -0
  42. package/dist/mdz_stream_parser.d.ts +109 -0
  43. package/dist/mdz_stream_parser.d.ts.map +1 -0
  44. package/dist/mdz_stream_parser.js +699 -0
  45. package/dist/mdz_stream_parser_block.d.ts +99 -0
  46. package/dist/mdz_stream_parser_block.d.ts.map +1 -0
  47. package/dist/mdz_stream_parser_block.js +437 -0
  48. package/dist/mdz_stream_parser_inline.d.ts +98 -0
  49. package/dist/mdz_stream_parser_inline.d.ts.map +1 -0
  50. package/dist/mdz_stream_parser_inline.js +481 -0
  51. package/dist/mdz_stream_parser_link.d.ts +29 -0
  52. package/dist/mdz_stream_parser_link.d.ts.map +1 -0
  53. package/dist/mdz_stream_parser_link.js +227 -0
  54. package/dist/mdz_stream_parser_list.d.ts +106 -0
  55. package/dist/mdz_stream_parser_list.d.ts.map +1 -0
  56. package/dist/mdz_stream_parser_list.js +438 -0
  57. package/dist/mdz_stream_parser_state.d.ts +476 -0
  58. package/dist/mdz_stream_parser_state.d.ts.map +1 -0
  59. package/dist/mdz_stream_parser_state.js +651 -0
  60. package/dist/mdz_stream_parser_text.d.ts +25 -0
  61. package/dist/mdz_stream_parser_text.d.ts.map +1 -0
  62. package/dist/mdz_stream_parser_text.js +67 -0
  63. package/dist/mdz_stream_parser_url.d.ts +76 -0
  64. package/dist/mdz_stream_parser_url.d.ts.map +1 -0
  65. package/dist/mdz_stream_parser_url.js +328 -0
  66. package/dist/mdz_stream_state.svelte.d.ts +53 -0
  67. package/dist/mdz_stream_state.svelte.d.ts.map +1 -0
  68. package/dist/mdz_stream_state.svelte.js +360 -0
  69. package/dist/mdz_to_svelte.d.ts +71 -0
  70. package/dist/mdz_to_svelte.d.ts.map +1 -0
  71. package/dist/mdz_to_svelte.js +127 -0
  72. package/dist/mdz_token_parser.d.ts +20 -0
  73. package/dist/mdz_token_parser.d.ts.map +1 -0
  74. package/dist/mdz_token_parser.js +449 -0
  75. package/dist/svelte_preprocess_mdz.d.ts +80 -0
  76. package/dist/svelte_preprocess_mdz.d.ts.map +1 -0
  77. package/dist/svelte_preprocess_mdz.js +543 -0
  78. package/dist/tsdoc_mdz.d.ts +45 -0
  79. package/dist/tsdoc_mdz.d.ts.map +1 -0
  80. package/dist/tsdoc_mdz.js +88 -0
  81. package/package.json +131 -0
  82. package/src/lib/context_helpers.ts +52 -0
  83. package/src/lib/mdz.ts +190 -0
  84. package/src/lib/mdz_contexts.ts +99 -0
  85. package/src/lib/mdz_helpers.ts +727 -0
  86. package/src/lib/mdz_lexer.ts +1761 -0
  87. package/src/lib/mdz_opcodes.ts +227 -0
  88. package/src/lib/mdz_opcodes_to_nodes.ts +470 -0
  89. package/src/lib/mdz_stream_parser.ts +766 -0
  90. package/src/lib/mdz_stream_parser_block.ts +490 -0
  91. package/src/lib/mdz_stream_parser_inline.ts +527 -0
  92. package/src/lib/mdz_stream_parser_link.ts +283 -0
  93. package/src/lib/mdz_stream_parser_list.ts +525 -0
  94. package/src/lib/mdz_stream_parser_state.ts +957 -0
  95. package/src/lib/mdz_stream_parser_text.ts +95 -0
  96. package/src/lib/mdz_stream_parser_url.ts +386 -0
  97. package/src/lib/mdz_stream_state.svelte.ts +383 -0
  98. package/src/lib/mdz_to_svelte.ts +213 -0
  99. package/src/lib/mdz_token_parser.ts +544 -0
  100. package/src/lib/svelte_preprocess_mdz.ts +777 -0
  101. package/src/lib/tsdoc_mdz.ts +97 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Streaming opcode parser for mdz.
3
+ *
4
+ * Fed chunks of text (e.g., from LLM output), emits opcodes as rendering
5
+ * instructions. Makes optimistic assumptions about ambiguous syntax and
6
+ * emits `revert` opcodes to correct when wrong. Never re-parses —
7
+ * corrections are bounded, explicit opcodes (`revert`, `wrap`, `trim_text`).
8
+ *
9
+ * The design is derived from
10
+ * {@link https://bsky.app/profile/pngwn.at/post/3mi527zntb22n @pngwn.at}'s
11
+ * ideas: restrict the syntax so streaming is tractable, render
12
+ * optimistically and correct when wrong, emit serializable opcodes to avoid
13
+ * re-parsing, and keep the opcodes target-agnostic so any renderer can
14
+ * consume them. mdz diverges in one respect: the Svelte consumer
15
+ * (`MdzStreamState`) does build a reactive tree from opcodes — the platform
16
+ * dictates this — but mutations are fine-grained via `$state`, not diffed.
17
+ *
18
+ * The parser is split across sibling modules: this file holds the public
19
+ * `MdzStreamParser` class and the `process_loop` / `process_inline`
20
+ * orchestrators. Per-category handlers (block / inline / link / url / text)
21
+ * live in `mdz_stream_parser_*.ts` as free functions taking the shared
22
+ * `MdzStreamParserState` as first argument.
23
+ *
24
+ * Usage:
25
+ * ```ts
26
+ * const parser = new MdzStreamParser();
27
+ * parser.feed('hello **bold');
28
+ * const ops1 = parser.take_opcodes(); // open Paragraph, text "hello ", open Bold, text "bold"
29
+ * parser.feed('** world');
30
+ * const ops2 = parser.take_opcodes(); // close Bold, text " world"
31
+ * parser.finish();
32
+ * const ops3 = parser.take_opcodes(); // close Paragraph
33
+ * ```
34
+ *
35
+ * @module
36
+ */
37
+ import type { MdzOpcode } from './mdz_opcodes.js';
38
+ /**
39
+ * Streaming opcode parser for mdz content.
40
+ * Feed chunks via `feed()`, retrieve opcodes via `take_opcodes()`, call `finish()` at end.
41
+ *
42
+ * The opcode sequence is not deterministic across chunk boundaries — the same input
43
+ * fed in different chunk sizes may produce different `text`/`append_text` splits and
44
+ * different optimistic/revert sequences. The final tree (via `mdz_opcodes_to_nodes`)
45
+ * matches the one-shot result: optimistic opens are corrected by `revert` opcodes
46
+ * at the first failed closer, at run close (paragraph, heading, or list-item
47
+ * run), or at EOF, and at EOF the delimiter-paired opens
48
+ * (bold/italic/strikethrough) and inline-code candidates are gated on a closer
49
+ * scan of the complete final buffer, so held tails parse like the one-shot
50
+ * parse. The residual divergence classes are:
51
+ *
52
+ * - **Backtick-adjacent chunking** — an inline-code candidate held across
53
+ * chunks can make its text-vs-code decision bounded by a wrongly-optimistic
54
+ * italic (opened before its failed closer was visible), where the one-shot
55
+ * parse greedy-rejects that italic and scans unbounded — `` _`__` ``
56
+ * chunked at the italic stays flat text where one-shot parses the code span.
57
+ * Italic is the only wedge (the only delimiter whose one-shot form rejects
58
+ * on a failed first closer); see `try_code`'s hold and `code_search_limit`.
59
+ * - **Optimistic inline code unclosed at EOF** — a `` ` `` that opened
60
+ * optimistically consumes its tail as raw code text, so formatting inside it
61
+ * never forms (`` h `x **b** z `` stays flat where one-shot parses the bold);
62
+ * the parser never re-parses, so the EOF revert can only flatten it to text.
63
+ * - **Link/tag opens at EOF** — `finish()` doesn't open links or tags, so a held
64
+ * tail containing complete `[text](url)` / `<Tag>…</Tag>` syntax parses flat.
65
+ * - **Block elements interrupt optimistic inlines** — at column 0 a
66
+ * heading/HR/fence/list/blockquote line interrupts the open paragraph even when an
67
+ * optimistic inline container spans it (`**a\n# h\nb**` parses the heading
68
+ * here; the one-shot parse, knowing the closer exists, swallows the line as
69
+ * bold text). Inherent: the swallow is only correct when a closer eventually
70
+ * arrives, which streaming can't know — interrupting matches the one-shot
71
+ * parse on the no-closer flip side (`**a\n# h`) and renders blocks promptly.
72
+ *
73
+ * Lifecycle: one parser instance per stream — `feed()` any number of times,
74
+ * `finish()` exactly once, then a final `take_opcodes()`. There is no
75
+ * `reset()`; calling `feed()` or `finish()` after `finish()` is undefined.
76
+ * To restart, construct a new parser (and a new consumer — see
77
+ * `MdzStreamState`).
78
+ */
79
+ export declare class MdzStreamParser {
80
+ #private;
81
+ /**
82
+ * Feed a chunk of text to the parser.
83
+ * Opcodes are accumulated and retrieved via `take_opcodes()`.
84
+ */
85
+ feed(chunk: string): void;
86
+ /**
87
+ * Signal end of input. Resolves all pending state: closes open blocks,
88
+ * reverts unclosed optimistic opens, trims trailing newlines.
89
+ *
90
+ * Trailing-newline trimming is handled in one place: `trim_trailing_newline()`
91
+ * called at the top of `close_paragraph()` and `close_codeblock_at_eof()`,
92
+ * before either function reverts its inner stack. The trim sees the
93
+ * just-flushed text node's `last_text_id` (or a still-accumulated `\n`) and
94
+ * emits a `trim_text` opcode. Revert opcodes only fire after.
95
+ *
96
+ * Optimistic-container revert is handled by `close_paragraph` and
97
+ * `close_heading` (each reverts everything above its own block frame via
98
+ * `revert_above`), so no separate revert pass is needed — optimistic
99
+ * containers can only exist inside an open Paragraph or Heading (parser
100
+ * invariant).
101
+ */
102
+ finish(): void;
103
+ /**
104
+ * Drain and return all accumulated opcodes.
105
+ * Destructive — empties the internal queue. The returned array is owned by the caller.
106
+ */
107
+ take_opcodes(): Array<MdzOpcode>;
108
+ }
109
+ //# sourceMappingURL=mdz_stream_parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdz_stream_parser.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/mdz_stream_parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAC;AA+EhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAAa,eAAe;;IAG3B;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;CAKhC"}