@samva/markup 0.8.0 → 0.10.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 (172) hide show
  1. package/AGENTS.md +107 -46
  2. package/CHANGELOG.md +345 -0
  3. package/README.md +188 -52
  4. package/dist/{brand-DcoVkh_S.d.ts → assets-BIsyMQ92.d.ts} +41 -11
  5. package/dist/{email/brand.js → brand-C0MKTwmX.js} +64 -4
  6. package/dist/{theme-css.d.ts → brand.d.ts} +12 -3
  7. package/dist/brand.js +4 -0
  8. package/dist/channel-specs-C2feJwuP.d.ts +13 -0
  9. package/dist/compiler.d.ts +88 -115
  10. package/dist/compiler.js +750 -171
  11. package/dist/components-BZCqegS8.js +1864 -0
  12. package/dist/diagnostic-model-DJtqbETd.js +38 -0
  13. package/dist/{diagnostics-OcQKQYSY.d.ts → diagnostic-model-DxthUZBT.d.ts} +3 -21
  14. package/dist/{diagnostics-BMYtBCQk.d.ts → diagnostics-B-Gym34R.d.ts} +8 -4
  15. package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +4 -3
  16. package/dist/diagnostics.d.ts +410 -2
  17. package/dist/diagnostics.js +402 -52
  18. package/dist/edit.d.ts +234 -0
  19. package/dist/edit.js +947 -0
  20. package/dist/email/jsx-dev-runtime.d.ts +2 -2
  21. package/dist/email/jsx-dev-runtime.js +1 -2
  22. package/dist/email/jsx-runtime.d.ts +1 -1
  23. package/dist/email/jsx-runtime.js +1 -85
  24. package/dist/{email/components.d.ts → email.d.ts} +22 -11
  25. package/dist/email.js +2 -0
  26. package/dist/fmt.d.ts +32 -0
  27. package/dist/fmt.js +174 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +2 -0
  30. package/dist/{render-vAv_4r9v.js → ir-CLhlklKV.js} +96 -279
  31. package/dist/jsx-runtime-CBlexoeR.js +98 -0
  32. package/dist/{elements-BzjjnoCS.d.ts → jsx-runtime-ylIOnaSf.d.ts} +76 -76
  33. package/dist/profile-pWGtWZXF.js +3803 -0
  34. package/dist/render-BPonDpCl.d.ts +539 -0
  35. package/dist/render-BQmfh94k.js +257 -0
  36. package/dist/render.d.ts +35 -0
  37. package/dist/render.js +49 -0
  38. package/dist/sms.d.ts +16 -0
  39. package/dist/sms.js +12 -0
  40. package/dist/source-locations-C8wCsiAy.d.ts +23 -0
  41. package/dist/template-DMPwxMSq.d.ts +65 -0
  42. package/dist/template-zLUjcwfF.js +42 -0
  43. package/dist/{theme-css-hFqcPSar.js → theme-css-JtRCm1fb.js} +2 -2
  44. package/dist/whatsapp.d.ts +57 -0
  45. package/dist/whatsapp.js +22 -0
  46. package/generated/contract.json +1788 -0
  47. package/generated/reference.md +360 -0
  48. package/package.json +46 -239
  49. package/samva-brand.d.ts +4 -4
  50. package/skills/sml/SKILL.md +123 -0
  51. package/dist/ast-BrDtApwS.d.ts +0 -107
  52. package/dist/ast.d.ts +0 -2
  53. package/dist/ast.js +0 -124
  54. package/dist/candidate.d.ts +0 -29
  55. package/dist/candidate.js +0 -88
  56. package/dist/catalog-CKuOooB8.d.ts +0 -354
  57. package/dist/checks-D73Xizbw.js +0 -59366
  58. package/dist/checks.d.ts +0 -33
  59. package/dist/checks.js +0 -2
  60. package/dist/classes.d.ts +0 -26
  61. package/dist/classes.js +0 -184
  62. package/dist/compile-sms.d.ts +0 -28
  63. package/dist/compile-sms.js +0 -44
  64. package/dist/compile-whatsapp.d.ts +0 -56
  65. package/dist/compile-whatsapp.js +0 -186
  66. package/dist/compile.d.ts +0 -18
  67. package/dist/compile.js +0 -29
  68. package/dist/components.d.ts +0 -289
  69. package/dist/components.js +0 -106
  70. package/dist/conditionals.d.ts +0 -10
  71. package/dist/conditionals.js +0 -74
  72. package/dist/corpus-CPPfgAHN.d.ts +0 -106
  73. package/dist/css-CS2jLID6.d.ts +0 -109
  74. package/dist/email/assets.d.ts +0 -40
  75. package/dist/email/assets.js +0 -63
  76. package/dist/email/brand-footer.d.ts +0 -34
  77. package/dist/email/brand-footer.js +0 -62
  78. package/dist/email/brand.d.ts +0 -2
  79. package/dist/email/components.js +0 -240
  80. package/dist/email/diagnostics.d.ts +0 -2
  81. package/dist/email/elements.d.ts +0 -2
  82. package/dist/email/elements.js +0 -299
  83. package/dist/email/html.d.ts +0 -2
  84. package/dist/email/html.js +0 -278
  85. package/dist/email/render.d.ts +0 -50
  86. package/dist/email/render.js +0 -3
  87. package/dist/email/selection.d.ts +0 -2
  88. package/dist/email/selection.js +0 -91
  89. package/dist/email/source-edit.d.ts +0 -67
  90. package/dist/email/source-edit.js +0 -185
  91. package/dist/email/stylesheets.d.ts +0 -15
  92. package/dist/email/stylesheets.js +0 -48
  93. package/dist/email/text.d.ts +0 -7
  94. package/dist/email/text.js +0 -100
  95. package/dist/emit.d.ts +0 -51
  96. package/dist/emit.js +0 -151
  97. package/dist/html-Bl9BAdqc.d.ts +0 -42
  98. package/dist/interpolate.d.ts +0 -24
  99. package/dist/interpolate.js +0 -43
  100. package/dist/jsx-dev-runtime.d.ts +0 -11
  101. package/dist/jsx-dev-runtime.js +0 -15
  102. package/dist/jsx-runtime-I-1nCtl2.d.ts +0 -57
  103. package/dist/jsx-runtime.d.ts +0 -2
  104. package/dist/jsx-runtime.js +0 -121
  105. package/dist/lexer.d.ts +0 -60
  106. package/dist/lexer.js +0 -281
  107. package/dist/model.d.ts +0 -24
  108. package/dist/model.js +0 -77
  109. package/dist/ops-BvwqHl7V.js +0 -630
  110. package/dist/ops.d.ts +0 -114
  111. package/dist/ops.js +0 -2
  112. package/dist/parser-t29cHLVL.d.ts +0 -396
  113. package/dist/parser.d.ts +0 -2
  114. package/dist/parser.js +0 -859
  115. package/dist/predicate-BI6uRRM-.js +0 -549
  116. package/dist/predicate-M-05Nd7R.d.ts +0 -56
  117. package/dist/predicate.d.ts +0 -2
  118. package/dist/predicate.js +0 -2
  119. package/dist/printer.d.ts +0 -6
  120. package/dist/printer.js +0 -122
  121. package/dist/registry-Dcp6QEK_.d.ts +0 -73
  122. package/dist/registry.d.ts +0 -2
  123. package/dist/registry.js +0 -646
  124. package/dist/render-template.d.ts +0 -45
  125. package/dist/render-template.js +0 -76
  126. package/dist/selection-CCArx9lU.d.ts +0 -91
  127. package/dist/showcase-egkusQBf.d.ts +0 -415
  128. package/dist/sms-segments-y4FpPilJ.d.ts +0 -13
  129. package/dist/sms-segments.d.ts +0 -2
  130. package/dist/sms-segments.js +0 -46
  131. package/dist/source-locations-DrCM82Ym.d.ts +0 -67
  132. package/dist/source-locations.d.ts +0 -2
  133. package/dist/source-locations.js +0 -102
  134. package/dist/starters/category-mapping.d.ts +0 -13
  135. package/dist/starters/category-mapping.js +0 -49
  136. package/dist/starters/corpus.d.ts +0 -2
  137. package/dist/starters/corpus.js +0 -194
  138. package/dist/starters/library.d.ts +0 -18
  139. package/dist/starters/library.js +0 -692
  140. package/dist/starters/public-gallery.d.ts +0 -266
  141. package/dist/starters/public-gallery.js +0 -916
  142. package/dist/starters/public-handoff.d.ts +0 -164
  143. package/dist/starters/public-handoff.js +0 -361
  144. package/dist/starters/public-preview-artifacts.d.ts +0 -43
  145. package/dist/starters/public-preview-artifacts.js +0 -104
  146. package/dist/starters/public-preview.d.ts +0 -61
  147. package/dist/starters/public-preview.js +0 -83
  148. package/dist/starters/showcase.d.ts +0 -2
  149. package/dist/starters/showcase.js +0 -335
  150. package/dist/starters/sources.d.ts +0 -45
  151. package/dist/starters/sources.js +0 -7762
  152. package/dist/starters/theme.d.ts +0 -45
  153. package/dist/starters/theme.js +0 -77
  154. package/dist/starters.d.ts +0 -2
  155. package/dist/starters.js +0 -874
  156. package/dist/tailwind-BYq7Lo6u.js +0 -727
  157. package/dist/template-DWftqh4x.d.ts +0 -60
  158. package/dist/template.d.ts +0 -2
  159. package/dist/template.js +0 -37
  160. package/dist/theme-css.js +0 -2
  161. package/dist/tsx-source-instrumentation.d.ts +0 -30
  162. package/dist/tsx-source-instrumentation.js +0 -115
  163. package/dist/tsx-tracer.d.ts +0 -112
  164. package/dist/tsx-tracer.js +0 -985
  165. package/dist/variables-J_L3qxRa.d.ts +0 -77
  166. package/dist/variables.d.ts +0 -2
  167. package/dist/variables.js +0 -141
  168. package/dist/version-BITr58kk.js +0 -96
  169. package/generated/sml-agent-contract.json +0 -709
  170. package/generated/sml-email-agent-contract.json +0 -615
  171. package/generated/sml-email-language-reference.md +0 -94
  172. package/generated/sml-language-reference.md +0 -195
package/dist/lexer.js DELETED
@@ -1,281 +0,0 @@
1
- //#region src/lexer.ts
2
- const CHAR_TAB = 9;
3
- const CHAR_LINE_FEED = 10;
4
- const CHAR_CARRIAGE_RETURN = 13;
5
- const CHAR_SPACE = 32;
6
- const CHAR_BANG = 33;
7
- const CHAR_DOUBLE_QUOTE = 34;
8
- const CHAR_HASH = 35;
9
- const CHAR_DOLLAR = 36;
10
- const CHAR_AMPERSAND = 38;
11
- const CHAR_SINGLE_QUOTE = 39;
12
- const CHAR_SLASH = 47;
13
- const CHAR_SEMICOLON = 59;
14
- const CHAR_LESS_THAN = 60;
15
- const CHAR_EQUALS = 61;
16
- const CHAR_GREATER_THAN = 62;
17
- const CHAR_OPEN_BRACE = 123;
18
- const CHAR_CLOSE_BRACE = 125;
19
- const CHAR_DOT = 46;
20
- const CHAR_UNDERSCORE = 95;
21
- const CHAR_0 = 48;
22
- const CHAR_9 = 57;
23
- const CHAR_UPPER_A = 65;
24
- const CHAR_UPPER_X = 88;
25
- const CHAR_UPPER_Z = 90;
26
- const CHAR_LOWER_A = 97;
27
- const CHAR_LOWER_X = 120;
28
- const CHAR_LOWER_Z = 122;
29
- const TokenKind = {
30
- EndOfFile: 0,
31
- /** `<` opening a start tag (text mode). */
32
- LessThan: 1,
33
- /** `</` opening a close tag (text mode). */
34
- LessThanSlash: 2,
35
- GreaterThan: 3,
36
- SlashGreaterThan: 4,
37
- Identifier: 5,
38
- Equals: 6,
39
- /** Quoted attribute value; getStringValue decodes entities. */
40
- String: 7,
41
- OpenBrace: 8,
42
- CloseBrace: 9,
43
- /** Unsigned integer inside a brace attribute value. */
44
- Number: 10,
45
- /** Raw text run; getTextValue decodes entities. */
46
- Text: 11,
47
- /** `{{name}}` or `${name}`; name/syntax carried on the token. */
48
- Interpolation: 12,
49
- /** Lexically invalid input; error carried on the token. */
50
- Unknown: 13
51
- };
52
- const isWhitespace = (code) => code === CHAR_SPACE || code === CHAR_TAB || code === CHAR_LINE_FEED || code === CHAR_CARRIAGE_RETURN;
53
- const isDigit = (code) => code >= CHAR_0 && code <= CHAR_9;
54
- const isLetter = (code) => code >= CHAR_UPPER_A && code <= CHAR_UPPER_Z || code >= CHAR_LOWER_A && code <= CHAR_LOWER_Z;
55
- const isNameChar = (code) => isLetter(code) || isDigit(code) || code === CHAR_UNDERSCORE || code === CHAR_DOT;
56
- const NAMED_ENTITIES = {
57
- amp: "&",
58
- lt: "<",
59
- gt: ">",
60
- quot: "\"",
61
- apos: "'",
62
- nbsp: "\xA0"
63
- };
64
- const numericEntityCodePoint = (digits, radix) => {
65
- const codePoint = Number.parseInt(digits, radix);
66
- return Number.isFinite(codePoint) && codePoint <= 1114111 ? codePoint : void 0;
67
- };
68
- /**
69
- * Validates the entity starting at `offset` (which points at `&`).
70
- * Returns the end offset (past `;`) or -1 when malformed.
71
- */
72
- const scanEntity = (source, offset) => {
73
- let index = offset + 1;
74
- if (source.charCodeAt(index) === CHAR_HASH) {
75
- index++;
76
- const marker = source.charCodeAt(index);
77
- const hex = marker === CHAR_LOWER_X || marker === CHAR_UPPER_X;
78
- if (hex) index++;
79
- const digitsStart = index;
80
- while (index < source.length) {
81
- const code = source.charCodeAt(index);
82
- if (!(isDigit(code) || hex && (code >= 97 && code <= 102 || code >= 65 && code <= 70))) break;
83
- index++;
84
- }
85
- if (index === digitsStart) return -1;
86
- if (numericEntityCodePoint(source.slice(digitsStart, index), hex ? 16 : 10) === void 0) return -1;
87
- return source.charCodeAt(index) === CHAR_SEMICOLON ? index + 1 : -1;
88
- }
89
- const nameStart = index;
90
- while (index < source.length && isLetter(source.charCodeAt(index))) index++;
91
- const name = source.slice(nameStart, index);
92
- if (!Object.hasOwn(NAMED_ENTITIES, name)) return -1;
93
- return source.charCodeAt(index) === CHAR_SEMICOLON ? index + 1 : -1;
94
- };
95
- /** Decodes entities in text that already passed `scanEntity` validation. */
96
- const decodeEntities = (raw) => {
97
- if (!raw.includes("&")) return raw;
98
- let result = "";
99
- let index = 0;
100
- while (index < raw.length) {
101
- const ampersand = raw.indexOf("&", index);
102
- if (ampersand === -1) {
103
- result += raw.slice(index);
104
- break;
105
- }
106
- result += raw.slice(index, ampersand);
107
- const semicolon = raw.indexOf(";", ampersand);
108
- if (semicolon === -1) {
109
- result += raw.slice(ampersand);
110
- break;
111
- }
112
- const body = raw.slice(ampersand + 1, semicolon);
113
- if (body.startsWith("#x") || body.startsWith("#X")) {
114
- const codePoint = numericEntityCodePoint(body.slice(2), 16);
115
- result += codePoint === void 0 ? raw.slice(ampersand, semicolon + 1) : String.fromCodePoint(codePoint);
116
- } else if (body.startsWith("#")) {
117
- const codePoint = numericEntityCodePoint(body.slice(1), 10);
118
- result += codePoint === void 0 ? raw.slice(ampersand, semicolon + 1) : String.fromCodePoint(codePoint);
119
- } else result += Object.hasOwn(NAMED_ENTITIES, body) ? NAMED_ENTITIES[body] : raw.slice(ampersand, semicolon + 1);
120
- index = semicolon + 1;
121
- }
122
- return result;
123
- };
124
- const createLexer = (source) => {
125
- let position = 0;
126
- const length = source.length;
127
- const token = (kind, start, extra) => {
128
- return {
129
- kind,
130
- start,
131
- end: position,
132
- ...extra
133
- };
134
- };
135
- const unknown = (start, code, message) => {
136
- if (position === start) position = Math.min(start + 1, length);
137
- return token(TokenKind.Unknown, start, { error: {
138
- code,
139
- message
140
- } });
141
- };
142
- const scanInterpolation = (start, syntax) => {
143
- position = start + 2;
144
- while (position < length && isWhitespace(source.charCodeAt(position))) position++;
145
- if (syntax === "dollar" && source.charCodeAt(position) === CHAR_SLASH) position++;
146
- const nameStart = position;
147
- while (position < length && isNameChar(source.charCodeAt(position))) position++;
148
- const name = source.slice(nameStart, position);
149
- while (position < length && isWhitespace(source.charCodeAt(position))) position++;
150
- const closed = syntax === "curly" ? source.charCodeAt(position) === CHAR_CLOSE_BRACE && source.charCodeAt(position + 1) === CHAR_CLOSE_BRACE : source.charCodeAt(position) === CHAR_CLOSE_BRACE;
151
- if (name.length === 0 || !closed) {
152
- position = start;
153
- return unknown(start, "invalid-interpolation", `malformed interpolation — write ${syntax === "curly" ? "{{variableName}}" : "${variableName}"} using letters, digits, underscore, or dot`);
154
- }
155
- position += syntax === "curly" ? 2 : 1;
156
- return token(TokenKind.Interpolation, start, {
157
- name,
158
- syntax
159
- });
160
- };
161
- const scanTextToken = () => {
162
- const start = position;
163
- if (position >= length) return token(TokenKind.EndOfFile, start);
164
- const first = source.charCodeAt(position);
165
- if (first === CHAR_LESS_THAN) {
166
- const next = source.charCodeAt(position + 1);
167
- if (next === CHAR_SLASH) {
168
- position += 2;
169
- return token(TokenKind.LessThanSlash, start);
170
- }
171
- if (isLetter(next)) {
172
- position += 1;
173
- return token(TokenKind.LessThan, start);
174
- }
175
- if (next === CHAR_BANG) return unknown(start, "comment-not-supported", source.startsWith("<!--", position) ? "comments are not part of SML — remove the <!-- ... --> block" : "unexpected <! — SML has no doctype or declaration syntax; remove it");
176
- return unknown(start, "stray-angle-bracket", "stray < in text — escape it as &lt;");
177
- }
178
- if (first === CHAR_OPEN_BRACE && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) return scanInterpolation(start, "curly");
179
- if (first === CHAR_DOLLAR && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) return scanInterpolation(start, "dollar");
180
- while (position < length) {
181
- const code = source.charCodeAt(position);
182
- if (code === CHAR_LESS_THAN) break;
183
- if (code === CHAR_OPEN_BRACE && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) break;
184
- if (code === CHAR_DOLLAR && source.charCodeAt(position + 1) === CHAR_OPEN_BRACE) break;
185
- if (code === CHAR_AMPERSAND) {
186
- const entityEnd = scanEntity(source, position);
187
- if (entityEnd === -1) {
188
- if (position > start) return token(TokenKind.Text, start);
189
- return unknown(start, "bare-ampersand", "bare & in text — escape it as &amp; (or use a supported entity like &lt;)");
190
- }
191
- position = entityEnd;
192
- continue;
193
- }
194
- position++;
195
- }
196
- return token(TokenKind.Text, start);
197
- };
198
- const scanTagToken = () => {
199
- while (position < length && isWhitespace(source.charCodeAt(position))) position++;
200
- const start = position;
201
- if (position >= length) return token(TokenKind.EndOfFile, start);
202
- const code = source.charCodeAt(position);
203
- switch (code) {
204
- case CHAR_GREATER_THAN:
205
- position++;
206
- return token(TokenKind.GreaterThan, start);
207
- case CHAR_SLASH:
208
- if (source.charCodeAt(position + 1) === CHAR_GREATER_THAN) {
209
- position += 2;
210
- return token(TokenKind.SlashGreaterThan, start);
211
- }
212
- return unknown(start, "unexpected-character", "unexpected / inside tag — write /> to self-close");
213
- case CHAR_EQUALS:
214
- position++;
215
- return token(TokenKind.Equals, start);
216
- case CHAR_OPEN_BRACE:
217
- position++;
218
- return token(TokenKind.OpenBrace, start);
219
- case CHAR_CLOSE_BRACE:
220
- position++;
221
- return token(TokenKind.CloseBrace, start);
222
- case CHAR_DOUBLE_QUOTE:
223
- case CHAR_SINGLE_QUOTE:
224
- position++;
225
- while (position < length) {
226
- const current = source.charCodeAt(position);
227
- if (current === code) break;
228
- if (current === CHAR_AMPERSAND) {
229
- const entityEnd = scanEntity(source, position);
230
- if (entityEnd === -1) return unknown(position, "bare-ampersand", "bare & in attribute value — escape it as &amp;");
231
- position = entityEnd;
232
- continue;
233
- }
234
- if (current === CHAR_LESS_THAN || current === CHAR_LINE_FEED) break;
235
- position++;
236
- }
237
- if (source.charCodeAt(position) !== code) {
238
- const quote = String.fromCharCode(code);
239
- return {
240
- kind: TokenKind.Unknown,
241
- start,
242
- end: position,
243
- error: {
244
- code: "unterminated-string",
245
- message: `unterminated attribute value — add a closing ${quote}`
246
- }
247
- };
248
- }
249
- position++;
250
- return token(TokenKind.String, start);
251
- default:
252
- if (isLetter(code)) {
253
- position++;
254
- while (position < length) {
255
- const current = source.charCodeAt(position);
256
- if (!isLetter(current) && !isDigit(current)) break;
257
- position++;
258
- }
259
- return token(TokenKind.Identifier, start);
260
- }
261
- if (isDigit(code)) {
262
- position++;
263
- while (position < length && isDigit(source.charCodeAt(position))) position++;
264
- return token(TokenKind.Number, start);
265
- }
266
- return unknown(start, "unexpected-character", `unexpected character ${JSON.stringify(String.fromCharCode(code))} inside tag`);
267
- }
268
- };
269
- return {
270
- position: () => position,
271
- scanTextToken,
272
- scanTagToken,
273
- getText: (t) => source.slice(t.start, t.end),
274
- getTextValue: (t) => decodeEntities(source.slice(t.start, t.end)),
275
- getStringValue: (t) => decodeEntities(source.slice(t.start + 1, t.end - 1))
276
- };
277
- };
278
- //#endregion
279
- export { TokenKind, createLexer, decodeEntities };
280
-
281
- //# sourceMappingURL=lexer.js.map
package/dist/model.d.ts DELETED
@@ -1,24 +0,0 @@
1
- import { S as SmlTag, b as SmlDocument } from "./ast-BrDtApwS.js";
2
- import { Result } from "better-result";
3
- //#region src/model.d.ts
4
- /** The subset of an element's attributes the navigator and agent tools read. */
5
- type SmlNodeKeyAttrs = Readonly<Record<string, string | number>>;
6
- interface SmlNodeIndexEntry {
7
- readonly id: string;
8
- readonly tag: SmlTag;
9
- readonly order: number;
10
- readonly parentId: string | null;
11
- readonly childIndex: number;
12
- readonly depth: number;
13
- readonly path: string;
14
- readonly textPreview: string;
15
- readonly attrs: SmlNodeKeyAttrs;
16
- }
17
- interface SmlNodeIndex {
18
- readonly nodes: readonly SmlNodeIndexEntry[];
19
- }
20
- declare const deriveNodeIndexFromDocument: (document: SmlDocument) => SmlNodeIndex;
21
- declare const deriveNodeIndex: (source: string) => Result<SmlNodeIndex, string>;
22
- //#endregion
23
- export { SmlNodeIndex, SmlNodeIndexEntry, SmlNodeKeyAttrs, deriveNodeIndex, deriveNodeIndexFromDocument };
24
- //# sourceMappingURL=model.d.ts.map
package/dist/model.js DELETED
@@ -1,77 +0,0 @@
1
- import { parseSml } from "./parser.js";
2
- import { Result } from "better-result";
3
- //#region src/model.ts
4
- const KEY_ATTRS = /* @__PURE__ */ new Set([
5
- "alt",
6
- "class",
7
- "dir",
8
- "height",
9
- "hidden",
10
- "href",
11
- "label",
12
- "lang",
13
- "level",
14
- "name",
15
- "scheme",
16
- "src",
17
- "test",
18
- "valign",
19
- "width"
20
- ]);
21
- const attrValue = (value) => value.value;
22
- const truncate = (value, length) => value.length <= length ? value : `${value.slice(0, length - 3)}...`;
23
- const normalizePreview = (value) => truncate(value.replace(/\s+/g, " ").trim(), 96);
24
- const textPreview = (node) => {
25
- const parts = [];
26
- const visit = (child) => {
27
- if (child.kind === "text") {
28
- parts.push(child.value);
29
- return;
30
- }
31
- if (child.kind === "interpolation") {
32
- parts.push(`{{${child.name}}}`);
33
- return;
34
- }
35
- for (const nested of child.children) visit(nested);
36
- };
37
- for (const child of node.children) visit(child);
38
- return normalizePreview(parts.join(" "));
39
- };
40
- const keyAttrs = (node) => Object.fromEntries(node.attributes.filter((attribute) => KEY_ATTRS.has(attribute.name)).map((attribute) => [attribute.name, attrValue(attribute.value)]));
41
- const deriveNodeIndexFromDocument = (document) => {
42
- const nodes = [];
43
- let order = 0;
44
- const visit = (node, parentId, childIndex, depth, parentPath) => {
45
- if (node.kind !== "element") return;
46
- if (node.tag === "Source") return;
47
- const pathSegment = `${node.tag}[${childIndex}]`;
48
- const path = parentPath ? `${parentPath}/${pathSegment}` : pathSegment;
49
- nodes.push({
50
- id: node.id,
51
- tag: node.tag,
52
- order: order++,
53
- parentId,
54
- childIndex,
55
- depth,
56
- path,
57
- textPreview: textPreview(node),
58
- attrs: keyAttrs(node)
59
- });
60
- let elementChildIndex = 0;
61
- for (const child of node.children) if (child.kind === "element") {
62
- visit(child, node.id, elementChildIndex, depth + 1, path);
63
- elementChildIndex++;
64
- }
65
- };
66
- visit(document.root, null, 0, 0, "");
67
- return { nodes };
68
- };
69
- const deriveNodeIndex = (source) => {
70
- const parsed = parseSml(source);
71
- if (Result.isError(parsed)) return Result.err(parsed.error.diagnostics.map((diagnostic) => diagnostic.message).join("\n"));
72
- return Result.ok(deriveNodeIndexFromDocument(parsed.value));
73
- };
74
- //#endregion
75
- export { deriveNodeIndex, deriveNodeIndexFromDocument };
76
-
77
- //# sourceMappingURL=model.js.map