@samva/markup 0.5.0 → 0.7.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 (85) hide show
  1. package/AGENTS.md +80 -45
  2. package/README.md +1 -1
  3. package/dist/{ast-BLybiDxp.d.ts → ast-BrDtApwS.d.ts} +2 -2
  4. package/dist/ast.d.ts +1 -1
  5. package/dist/ast.js +1 -1
  6. package/dist/{catalog-Db0UcCTg.d.ts → catalog-60eaYC7b.d.ts} +2 -2
  7. package/dist/{checks-CmmITP6j.js → checks-DBweSIPN.js} +12 -14
  8. package/dist/checks.d.ts +1 -1
  9. package/dist/checks.js +1 -1
  10. package/dist/classes.d.ts +1 -1
  11. package/dist/compile-sms.d.ts +3 -3
  12. package/dist/compile-whatsapp.d.ts +3 -3
  13. package/dist/compile.d.ts +2 -2
  14. package/dist/compiler.d.ts +7 -4
  15. package/dist/compiler.js +67 -46
  16. package/dist/components.d.ts +5 -5
  17. package/dist/conditionals.js +55 -23
  18. package/dist/{corpus-CM7rKX41.d.ts → corpus-BjYMqOoY.d.ts} +2 -2
  19. package/dist/{css-DoNc7CiC.d.ts → css-COcFOT1y.d.ts} +3 -3
  20. package/dist/{diagnostics-eFM9A_TU.d.ts → diagnostics-BMYtBCQk.d.ts} +2 -2
  21. package/dist/{diagnostics-CqepLcpI.d.ts → diagnostics-OcQKQYSY.d.ts} +4 -2
  22. package/dist/diagnostics.d.ts +2 -2
  23. package/dist/diagnostics.js +10 -5
  24. package/dist/{elements-ChJULZlh.d.ts → elements-BzjjnoCS.d.ts} +3 -3
  25. package/dist/email/components.d.ts +1 -1
  26. package/dist/email/components.js +40 -10
  27. package/dist/email/diagnostics.d.ts +1 -1
  28. package/dist/email/elements.d.ts +1 -1
  29. package/dist/email/html.d.ts +2 -2
  30. package/dist/email/html.js +2 -1
  31. package/dist/email/jsx-dev-runtime.d.ts +2 -2
  32. package/dist/email/jsx-runtime.d.ts +1 -1
  33. package/dist/email/render.d.ts +4 -4
  34. package/dist/email/render.js +1 -1
  35. package/dist/email/selection.d.ts +1 -1
  36. package/dist/email/source-edit.d.ts +1 -1
  37. package/dist/email/stylesheets.d.ts +1 -1
  38. package/dist/email/text.d.ts +1 -1
  39. package/dist/emit.d.ts +2 -2
  40. package/dist/emit.js +2 -2
  41. package/dist/footer.d.ts +3 -3
  42. package/dist/footer.js +9 -6
  43. package/dist/jsx-dev-runtime.d.ts +2 -2
  44. package/dist/{jsx-runtime-BI4gI19E.d.ts → jsx-runtime-I-1nCtl2.d.ts} +3 -3
  45. package/dist/jsx-runtime.d.ts +1 -1
  46. package/dist/lexer.js +17 -5
  47. package/dist/model.d.ts +1 -1
  48. package/dist/ops-2aiiYO7m.js +630 -0
  49. package/dist/ops.d.ts +2 -2
  50. package/dist/ops.js +1 -479
  51. package/dist/{parser-b_Kp5MT6.d.ts → parser-t29cHLVL.d.ts} +4 -4
  52. package/dist/parser.d.ts +1 -1
  53. package/dist/parser.js +2 -3
  54. package/dist/{predicate-DwXzmqIY.js → predicate-BI6uRRM-.js} +14 -4
  55. package/dist/{predicate-Bmvgw7Ao.d.ts → predicate-M-05Nd7R.d.ts} +2 -2
  56. package/dist/predicate.d.ts +1 -1
  57. package/dist/predicate.js +1 -1
  58. package/dist/presets/category-mapping.d.ts +1 -1
  59. package/dist/presets/corpus.d.ts +1 -1
  60. package/dist/presets/public-gallery.d.ts +2 -2
  61. package/dist/presets/public-gallery.js +10 -2
  62. package/dist/presets/public-handoff.d.ts +2 -2
  63. package/dist/presets/public-preview-artifacts.d.ts +3 -1
  64. package/dist/presets/public-preview-artifacts.js +1 -0
  65. package/dist/presets/showcase.d.ts +1 -1
  66. package/dist/presets.d.ts +1 -1
  67. package/dist/printer.d.ts +1 -1
  68. package/dist/{render-T6IFPnP4.js → render-aaJBnsXK.js} +33 -16
  69. package/dist/render-template.d.ts +5 -5
  70. package/dist/render-template.js +1 -1
  71. package/dist/{showcase-dvJMn-Lo.d.ts → showcase-DGZAWn4Z.d.ts} +2 -2
  72. package/dist/{source-locations-D6Te6Gy1.d.ts → source-locations-DrCM82Ym.d.ts} +2 -2
  73. package/dist/source-locations.d.ts +1 -1
  74. package/dist/{template-G-QPcfmn.d.ts → template-DWftqh4x.d.ts} +2 -2
  75. package/dist/template.d.ts +1 -1
  76. package/dist/theme-css.d.ts +1 -1
  77. package/dist/theme.js +25 -2
  78. package/dist/tsx-source-instrumentation.d.ts +9 -0
  79. package/dist/tsx-source-instrumentation.js +20 -2
  80. package/dist/tsx-tracer.d.ts +1 -1
  81. package/dist/tsx-tracer.js +3 -3
  82. package/dist/{variables-BnKs1iqb.d.ts → variables-J_L3qxRa.d.ts} +2 -2
  83. package/dist/variables.d.ts +1 -1
  84. package/dist/variables.js +1 -1
  85. package/package.json +4 -4
@@ -1,2 +1,2 @@
1
- import { a as ShowcaseProjectId, c as showcaseProject, d as showcaseSourcePath, i as ShowcaseProject, l as showcaseProjectPaths, n as OwnedShowcaseId, o as ShowcaseProvenance, r as SHOWCASE_ROOT, s as isShowcaseProjectId, t as BrandRecreationShowcaseId, u as showcaseProjects } from "../showcase-dvJMn-Lo.js";
1
+ import { a as ShowcaseProjectId, c as showcaseProject, d as showcaseSourcePath, i as ShowcaseProject, l as showcaseProjectPaths, n as OwnedShowcaseId, o as ShowcaseProvenance, r as SHOWCASE_ROOT, s as isShowcaseProjectId, t as BrandRecreationShowcaseId, u as showcaseProjects } from "../showcase-DGZAWn4Z.js";
2
2
  export { BrandRecreationShowcaseId, OwnedShowcaseId, SHOWCASE_ROOT, ShowcaseProject, ShowcaseProjectId, ShowcaseProvenance, isShowcaseProjectId, showcaseProject, showcaseProjectPaths, showcaseProjects, showcaseSourcePath };
package/dist/presets.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as PresetMeta, c as presetCatalog, i as PresetId, n as EmailPresetVariable, o as PresetVariable, r as PresetCategory, s as RECOMMENDED_THEME, t as EmailPresetId } from "./catalog-Db0UcCTg.js";
1
+ import { a as PresetMeta, c as presetCatalog, i as PresetId, n as EmailPresetVariable, o as PresetVariable, r as PresetCategory, s as RECOMMENDED_THEME, t as EmailPresetId } from "./catalog-60eaYC7b.js";
2
2
  export { EmailPresetId, EmailPresetVariable, PresetCategory, PresetId, PresetMeta, PresetVariable, RECOMMENDED_THEME, presetCatalog };
package/dist/printer.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as SmlDocument } from "./ast-BLybiDxp.js";
1
+ import { b as SmlDocument } from "./ast-BrDtApwS.js";
2
2
  //#region src/printer.d.ts
3
3
  declare const printSml: (document: SmlDocument) => string;
4
4
  //#endregion
@@ -6,22 +6,33 @@ import { EmailCompileError, hasBlockingDiagnostic } from "./email/diagnostics.js
6
6
  import { snapshotStylesheets } from "./email/stylesheets.js";
7
7
  import { deriveEmailText } from "./email/text.js";
8
8
  //#region src/email/css-values.ts
9
- /** Expand `var(--x, fallback)` against the collected custom properties. */
10
- const resolveVariables = (value, variables, depth = 0) => {
9
+ const MAX_RESOLVED_VALUE_LENGTH = 65536;
10
+ const MAX_RESOLUTION_WORK = 262144;
11
+ const resolveVariablesWithin = (value, variables, depth, budget, work) => {
12
+ if (value.length > work.remaining) return void 0;
13
+ work.remaining -= value.length;
14
+ if (value.length > budget) return void 0;
11
15
  if (depth > 8 || !value.includes("var(")) return value;
12
- let result = "";
13
- let rest = value;
14
- while (rest.length > 0) {
15
- const start = rest.indexOf("var(");
16
+ const chunks = [];
17
+ let length = 0;
18
+ const append = (chunk) => {
19
+ length += chunk.length;
20
+ if (length > budget) return false;
21
+ chunks.push(chunk);
22
+ return true;
23
+ };
24
+ let cursor = 0;
25
+ while (cursor < value.length) {
26
+ const start = value.indexOf("var(", cursor);
16
27
  if (start < 0) {
17
- result += rest;
28
+ if (!append(value.slice(cursor))) return void 0;
18
29
  break;
19
30
  }
20
- result += rest.slice(0, start);
31
+ if (!append(value.slice(cursor, start))) return void 0;
21
32
  let level = 0;
22
33
  let end = -1;
23
- for (let index = start + 3; index < rest.length; index++) if (rest[index] === "(") level += 1;
24
- else if (rest[index] === ")") {
34
+ for (let index = start + 3; index < value.length; index++) if (value[index] === "(") level += 1;
35
+ else if (value[index] === ")") {
25
36
  level -= 1;
26
37
  if (level === 0) {
27
38
  end = index;
@@ -29,20 +40,26 @@ const resolveVariables = (value, variables, depth = 0) => {
29
40
  }
30
41
  }
31
42
  if (end < 0) {
32
- result += rest.slice(start);
43
+ if (!append(value.slice(start))) return void 0;
33
44
  break;
34
45
  }
35
- const body = rest.slice(start + 4, end);
46
+ const body = value.slice(start + 4, end);
36
47
  const comma = body.indexOf(",");
37
48
  const name = (comma < 0 ? body : body.slice(0, comma)).trim();
38
49
  const fallback = comma < 0 ? void 0 : body.slice(comma + 1).trim();
39
50
  const replacement = variables[name] ?? fallback;
40
- result += replacement === void 0 ? rest.slice(start, end + 1) : resolveVariables(replacement, variables, depth + 1);
41
- rest = rest.slice(end + 1);
51
+ const resolved = replacement === void 0 ? value.slice(start, end + 1) : resolveVariablesWithin(replacement, variables, depth + 1, budget - length, work);
52
+ if (resolved === void 0 || !append(resolved)) return void 0;
53
+ cursor = end + 1;
42
54
  }
43
- return result;
55
+ return chunks.join("");
44
56
  };
45
57
  /**
58
+ * Expand `var(--x, fallback)` against the collected custom properties.
59
+ * Values whose expansion exceeds the render-time budget are left as authored.
60
+ */
61
+ const resolveVariables = (value, variables, depth = 0) => resolveVariablesWithin(value, variables, depth, MAX_RESOLVED_VALUE_LENGTH, { remaining: MAX_RESOLUTION_WORK }) ?? value;
62
+ /**
46
63
  * Fold a constant `calc()` to a plain value. Tailwind writes every spacing
47
64
  * utility as `calc(var(--spacing) * n)`, and classic Outlook does not implement
48
65
  * `calc()` at all, so an unfolded value is a silently missing style. An
@@ -589,4 +606,4 @@ const renderEmailWith = (stylesheet, template, data, options) => {
589
606
  //#endregion
590
607
  export { applyStylesheet as a, downlevelMediaQuery as c, renderHeadCss as d, resolveVariables as f, renderEmail as i, finalizeValue as l, bindStylesheets as n, classListOf as o, compileEmail as r, matchesSelector as s, EMAIL_DOCTYPE as t, foldCalc as u };
591
608
 
592
- //# sourceMappingURL=render-T6IFPnP4.js.map
609
+ //# sourceMappingURL=render-aaJBnsXK.js.map
@@ -1,8 +1,8 @@
1
- import { i as SmlParseError } from "./diagnostics-CqepLcpI.js";
2
- import { b as SmlDocument } from "./ast-BLybiDxp.js";
3
- import { s as UnboundTemplateSourceLocations } from "./source-locations-D6Te6Gy1.js";
4
- import { a as VariableKind, l as Variables } from "./variables-BnKs1iqb.js";
5
- import { a as JsxResult } from "./jsx-runtime-BI4gI19E.js";
1
+ import { i as SmlParseError } from "./diagnostics-OcQKQYSY.js";
2
+ import { b as SmlDocument } from "./ast-BrDtApwS.js";
3
+ import { s as UnboundTemplateSourceLocations } from "./source-locations-DrCM82Ym.js";
4
+ import { a as VariableKind, l as Variables } from "./variables-J_L3qxRa.js";
5
+ import { a as JsxResult } from "./jsx-runtime-I-1nCtl2.js";
6
6
  import { Result } from "better-result";
7
7
  //#region src/render-template.d.ts
8
8
  /**
@@ -1,5 +1,5 @@
1
1
  import { mapJsxSourceLocations } from "./source-locations.js";
2
- import { i as parsePredicate, n as collectPredicateVariables } from "./predicate-DwXzmqIY.js";
2
+ import { i as parsePredicate, n as collectPredicateVariables } from "./predicate-BI6uRRM-.js";
3
3
  import { isRootTag } from "./ast.js";
4
4
  import { createVariablesProxy } from "./variables.js";
5
5
  import { parseSml } from "./parser.js";
@@ -1,4 +1,4 @@
1
- import { r as PresetCategory } from "./catalog-Db0UcCTg.js";
1
+ import { r as PresetCategory } from "./catalog-60eaYC7b.js";
2
2
  //#region presets/showcase.d.ts
3
3
  /**
4
4
  * The showcase projects: presets authored as complete editable projects under
@@ -453,4 +453,4 @@ declare const showcaseSourcePath: (project: ShowcaseProject) => string;
453
453
  declare const showcaseProjectPaths: (project: ShowcaseProject) => ReadonlyArray<string>;
454
454
  //#endregion
455
455
  export { ShowcaseProjectId as a, showcaseProject as c, showcaseSourcePath as d, ShowcaseProject as i, showcaseProjectPaths as l, OwnedShowcaseId as n, ShowcaseProvenance as o, SHOWCASE_ROOT as r, isShowcaseProjectId as s, BrandRecreationShowcaseId as t, showcaseProjects as u };
456
- //# sourceMappingURL=showcase-dvJMn-Lo.d.ts.map
456
+ //# sourceMappingURL=showcase-DGZAWn4Z.d.ts.map
@@ -1,4 +1,4 @@
1
- import { f as ElementNode, x as SmlNode } from "./ast-BLybiDxp.js";
1
+ import { f as ElementNode, x as SmlNode } from "./ast-BrDtApwS.js";
2
2
  //#region src/source-locations.d.ts
3
3
  /**
4
4
  * The source payload emitted by the JSX development transform. The transform
@@ -64,4 +64,4 @@ declare const mapJsxSourceLocations: (draft: ElementNode, parsed: ElementNode) =
64
64
  declare const sameTemplateSourceLocations: (left: UnboundTemplateSourceLocations, right: UnboundTemplateSourceLocations) => boolean;
65
65
  //#endregion
66
66
  export { SourceLocationUnavailableReason as a, attachJsxSourceLocation as c, mapJsxSourceLocations as d, sameTemplateSourceLocations as f, JsxSourceLocation as i, completeJsxSourceLocation as l, JSX_SOURCE_LOCATION_PROP as n, TemplateSourceLocations as o, JsxSource as r, UnboundTemplateSourceLocations as s, JSX_SOURCE_LOCATION as t, jsxSourceLocationOf as u };
67
- //# sourceMappingURL=source-locations-D6Te6Gy1.d.ts.map
67
+ //# sourceMappingURL=source-locations-DrCM82Ym.d.ts.map
@@ -1,2 +1,2 @@
1
- import { a as SourceLocationUnavailableReason, c as attachJsxSourceLocation, d as mapJsxSourceLocations, f as sameTemplateSourceLocations, i as JsxSourceLocation, l as completeJsxSourceLocation, n as JSX_SOURCE_LOCATION_PROP, o as TemplateSourceLocations, r as JsxSource, s as UnboundTemplateSourceLocations, t as JSX_SOURCE_LOCATION, u as jsxSourceLocationOf } from "./source-locations-D6Te6Gy1.js";
1
+ import { a as SourceLocationUnavailableReason, c as attachJsxSourceLocation, d as mapJsxSourceLocations, f as sameTemplateSourceLocations, i as JsxSourceLocation, l as completeJsxSourceLocation, n as JSX_SOURCE_LOCATION_PROP, o as TemplateSourceLocations, r as JsxSource, s as UnboundTemplateSourceLocations, t as JSX_SOURCE_LOCATION, u as jsxSourceLocationOf } from "./source-locations-DrCM82Ym.js";
2
2
  export { JSX_SOURCE_LOCATION, JSX_SOURCE_LOCATION_PROP, JsxSource, JsxSourceLocation, SourceLocationUnavailableReason, TemplateSourceLocations, UnboundTemplateSourceLocations, attachJsxSourceLocation, completeJsxSourceLocation, jsxSourceLocationOf, mapJsxSourceLocations, sameTemplateSourceLocations };
@@ -1,4 +1,4 @@
1
- import { m as EmailNode } from "./elements-ChJULZlh.js";
1
+ import { m as EmailNode } from "./elements-BzjjnoCS.js";
2
2
  import { r as InputSchema } from "./input-schema-7dPFVvNE.js";
3
3
  import { StandardJSONSchemaV1 } from "@standard-schema/spec";
4
4
  //#region src/template.d.ts
@@ -57,4 +57,4 @@ type TemplateInput<T extends {
57
57
  }> = Parameters<T["render"]>[0];
58
58
  //#endregion
59
59
  export { TemplateRuntime as a, TemplateInput as i, TEMPLATE_NAME_PATTERN as n, defineEmail as o, TemplateDefinition as r, isTemplateDefinition as s, EmailContent as t };
60
- //# sourceMappingURL=template-G-QPcfmn.d.ts.map
60
+ //# sourceMappingURL=template-DWftqh4x.d.ts.map
@@ -1,2 +1,2 @@
1
- import { a as TemplateRuntime, i as TemplateInput, n as TEMPLATE_NAME_PATTERN, o as defineEmail, r as TemplateDefinition, s as isTemplateDefinition, t as EmailContent } from "./template-G-QPcfmn.js";
1
+ import { a as TemplateRuntime, i as TemplateInput, n as TEMPLATE_NAME_PATTERN, o as defineEmail, r as TemplateDefinition, s as isTemplateDefinition, t as EmailContent } from "./template-DWftqh4x.js";
2
2
  export { EmailContent, TEMPLATE_NAME_PATTERN, TemplateDefinition, TemplateInput, TemplateRuntime, defineEmail, isTemplateDefinition };
@@ -1,4 +1,4 @@
1
- import { t as Diagnostic } from "./diagnostics-CqepLcpI.js";
1
+ import { t as Diagnostic } from "./diagnostics-OcQKQYSY.js";
2
2
  import { o as TokenOverrides } from "./theme-6ApjjiBo.js";
3
3
  import { Result } from "better-result";
4
4
  //#region src/theme-css.d.ts
package/dist/theme.js CHANGED
@@ -16,7 +16,30 @@
16
16
  * quoted CSS string `\/` is identical to `/`, but the HTML tokenizer no longer
17
17
  * matches `<\/style>` as a raw-text end tag.
18
18
  */
19
- const escapeCssString = (value) => value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/<\//g, "<\\/");
19
+ const escapeCssString = (value) => value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/[\u0000-\u001f\u007f]/g, (character) => `\\${character.charCodeAt(0).toString(16)} `).replace(/<\//g, "<\\/");
20
+ const FONT_FAMILY_NAME = /^-?[a-zA-Z][a-zA-Z0-9 -]*$/;
21
+ const SINGLE_QUOTED_FONT_FAMILY = /^'[^'\\<\u0000-\u001f\u007f]*'$/;
22
+ const DOUBLE_QUOTED_FONT_FAMILY = /^"[^"\\<\u0000-\u001f\u007f]*"$/;
23
+ const splitFontStack = (value) => {
24
+ const families = [];
25
+ let start = 0;
26
+ let quote;
27
+ for (let index = 0; index < value.length; index++) {
28
+ const character = value[index];
29
+ if (quote !== void 0) {
30
+ if (character === quote) quote = void 0;
31
+ } else if (character === "'" || character === "\"") quote = character;
32
+ else if (character === ",") {
33
+ families.push(value.slice(start, index).trim());
34
+ start = index + 1;
35
+ }
36
+ }
37
+ families.push(value.slice(start).trim());
38
+ return families;
39
+ };
40
+ const safeFontStack = (value) => {
41
+ return splitFontStack(value).every((family) => FONT_FAMILY_NAME.test(family) || SINGLE_QUOTED_FONT_FAMILY.test(family) || DOUBLE_QUOTED_FONT_FAMILY.test(family)) ? value : `'${escapeCssString(value)}'`;
42
+ };
20
43
  /**
21
44
  * Flatten persisted font tokens into the compiler's two font fields, so the
22
45
  * server (apps/api) and the in-browser canvas (apps/web) produce byte-identical
@@ -31,7 +54,7 @@ const flattenFontTokens = (tokens) => {
31
54
  const fontFamilies = {};
32
55
  const fontFaces = {};
33
56
  for (const [name, token] of Object.entries(tokens)) {
34
- fontFamilies[name] = `'${escapeCssString(token.family)}', ${token.fallback}`;
57
+ fontFamilies[name] = `'${escapeCssString(token.family)}', ${safeFontStack(token.fallback)}`;
35
58
  if (token.faces != null) fontFaces[name] = {
36
59
  family: token.family,
37
60
  faces: token.faces
@@ -1,7 +1,16 @@
1
1
  //#region src/tsx-source-instrumentation.d.ts
2
2
  declare const TsxSourceInstrumentationError_base: import("better-result").TaggedErrorClass<"TsxSourceInstrumentationError">;
3
+ /**
4
+ * The authored TSX could not be instrumented. `location` is the 1-based line
5
+ * and column the refusal points at, when the parser or the offending attribute
6
+ * names one.
7
+ */
3
8
  declare class TsxSourceInstrumentationError extends TsxSourceInstrumentationError_base<{
4
9
  readonly message: string;
10
+ readonly location: {
11
+ readonly line: number;
12
+ readonly column: number;
13
+ } | undefined;
5
14
  readonly cause?: unknown;
6
15
  }> {}
7
16
  /**
@@ -4,6 +4,11 @@ import { buildLineMap, lineColumn } from "./diagnostics.js";
4
4
  import { TaggedError } from "better-result";
5
5
  import { parse } from "@babel/parser";
6
6
  //#region src/tsx-source-instrumentation.ts
7
+ /**
8
+ * The authored TSX could not be instrumented. `location` is the 1-based line
9
+ * and column the refusal points at, when the parser or the offending attribute
10
+ * names one.
11
+ */
7
12
  var TsxSourceInstrumentationError = class extends TaggedError("TsxSourceInstrumentationError") {};
8
13
  const isAstNode = (value) => isObject(value) && typeof value.type === "string" && typeof value.start === "number" && typeof value.end === "number";
9
14
  const walkAst = (value, visit) => {
@@ -23,6 +28,15 @@ const jsxIdentifier = (value) => {
23
28
  return typeof value.name === "string" ? value.name : void 0;
24
29
  };
25
30
  const parseErrorMessage = (error) => isObject(error) && typeof error.message === "string" ? error.message : "The authored TSX could not be parsed for preview instrumentation.";
31
+ /** Babel reports a 1-based line and a 0-based column. */
32
+ const parseErrorLocation = (error) => {
33
+ if (!isObject(error) || !isObject(error.loc)) return void 0;
34
+ const { line, column } = error.loc;
35
+ return typeof line === "number" && typeof column === "number" ? {
36
+ line,
37
+ column: column + 1
38
+ } : void 0;
39
+ };
26
40
  const marker = (fileName, source, offset, token) => {
27
41
  const position = lineColumn(buildLineMap(source), offset);
28
42
  return ` ${JSX_SOURCE_LOCATION_PROP}={${JSON.stringify({
@@ -53,7 +67,8 @@ const instrumentTsxSourceForPreview = (source, fileName, token, jsxImportSource
53
67
  } catch (error) {
54
68
  throw new TsxSourceInstrumentationError({
55
69
  cause: error,
56
- message: parseErrorMessage(error)
70
+ message: parseErrorMessage(error),
71
+ location: parseErrorLocation(error)
57
72
  });
58
73
  }
59
74
  const edits = [];
@@ -78,7 +93,10 @@ const instrumentTsxSourceForPreview = (source, fileName, token, jsxImportSource
78
93
  const attributes = openingElement.attributes;
79
94
  if (Array.isArray(attributes)) for (const attribute of attributes) {
80
95
  if (!isAstNode(attribute) || attribute.type !== "JSXAttribute") continue;
81
- if (jsxIdentifier(attribute.name) === "__samva_source_location") throw new TsxSourceInstrumentationError({ message: `The reserved JSX prop ${JSX_SOURCE_LOCATION_PROP} cannot be authored directly.` });
96
+ if (jsxIdentifier(attribute.name) === "__samva_source_location") throw new TsxSourceInstrumentationError({
97
+ message: `The reserved JSX prop ${JSX_SOURCE_LOCATION_PROP} cannot be authored directly.`,
98
+ location: lineColumn(buildLineMap(source), attribute.start)
99
+ });
82
100
  }
83
101
  const closingLength = source.slice(openingElement.end - 2, openingElement.end) === "/>" ? 2 : 1;
84
102
  edits.push({
@@ -1,4 +1,4 @@
1
- import { a as Span } from "./diagnostics-CqepLcpI.js";
1
+ import { a as Span } from "./diagnostics-OcQKQYSY.js";
2
2
  import { SmlOp } from "./ops.js";
3
3
  import { Result } from "better-result";
4
4
  //#region src/tsx-tracer.d.ts
@@ -3,7 +3,7 @@ import { buildLineMap } from "./diagnostics.js";
3
3
  import { SML_TAGS, componentNameForSmlTag, smlTagForComponentName } from "./ast.js";
4
4
  import { decodeEntities } from "./lexer.js";
5
5
  import { parseSml } from "./parser.js";
6
- import { applyOps } from "./ops.js";
6
+ import { r as applyOps } from "./ops-2aiiYO7m.js";
7
7
  import { Result, TaggedError } from "better-result";
8
8
  import { parse } from "@babel/parser";
9
9
  //#region src/tsx-tracer.ts
@@ -138,11 +138,11 @@ const headingText = (node) => {
138
138
  };
139
139
  const parseAuthored = (source) => {
140
140
  try {
141
- const parsed = parse(source, {
141
+ const { program } = parse(source, {
142
142
  plugins: ["typescript", "jsx"],
143
143
  sourceType: "module"
144
144
  });
145
- return Result.ok(parsed.program);
145
+ return isAstNode(program) ? Result.ok(program) : Result.err(diagnostic("tsx-invalid-authored-source", "The authored TSX parsed without a location."));
146
146
  } catch (error) {
147
147
  return Result.err(diagnostic("tsx-invalid-authored-source", error instanceof Error ? error.message : "The authored TSX could not be parsed."));
148
148
  }
@@ -1,4 +1,4 @@
1
- import { r as PredicateAst } from "./predicate-Bmvgw7Ao.js";
1
+ import { r as PredicateAst } from "./predicate-M-05Nd7R.js";
2
2
  //#region src/variables.d.ts
3
3
  /** Brand carried by every VariableRef, keyed off a private symbol. */
4
4
  declare const VARIABLE_REF: unique symbol;
@@ -74,4 +74,4 @@ declare const createVariablesProxy: <T extends Record<string, unknown>>() => {
74
74
  };
75
75
  //#endregion
76
76
  export { VariableKind as a, VariableRefBrand as c, isPredicateRef as d, isVariableRef as f, VARIABLE_REF as i, Variables as l, PREDICATE_REF as n, VariableRecorder as o, printPredicateRef as p, PredicateRef as r, VariableRef as s, CollectedVariable as t, createVariablesProxy as u };
77
- //# sourceMappingURL=variables-BnKs1iqb.d.ts.map
77
+ //# sourceMappingURL=variables-J_L3qxRa.d.ts.map
@@ -1,2 +1,2 @@
1
- import { a as VariableKind, c as VariableRefBrand, d as isPredicateRef, f as isVariableRef, i as VARIABLE_REF, l as Variables, n as PREDICATE_REF, o as VariableRecorder, p as printPredicateRef, r as PredicateRef, s as VariableRef, t as CollectedVariable, u as createVariablesProxy } from "./variables-BnKs1iqb.js";
1
+ import { a as VariableKind, c as VariableRefBrand, d as isPredicateRef, f as isVariableRef, i as VARIABLE_REF, l as Variables, n as PREDICATE_REF, o as VariableRecorder, p as printPredicateRef, r as PredicateRef, s as VariableRef, t as CollectedVariable, u as createVariablesProxy } from "./variables-J_L3qxRa.js";
2
2
  export { CollectedVariable, PREDICATE_REF, PredicateRef, VARIABLE_REF, VariableKind, VariableRecorder, VariableRef, VariableRefBrand, Variables, createVariablesProxy, isPredicateRef, isVariableRef, printPredicateRef };
package/dist/variables.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as hasProperty } from "./guards-eV1qLbf2.js";
2
- import { a as printPredicate } from "./predicate-DwXzmqIY.js";
2
+ import { a as printPredicate } from "./predicate-BI6uRRM-.js";
3
3
  //#region src/variables.ts
4
4
  const PLACEHOLDER_SPAN = {
5
5
  start: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samva/markup",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Type-safe authoring and compilation primitives for Samva templates",
5
5
  "keywords": [
6
6
  "email",
@@ -279,16 +279,16 @@
279
279
  "devDependencies": {
280
280
  "@babel/parser": "^8.0.4",
281
281
  "@css-inline/css-inline-wasm": "0.15.0",
282
- "@effect/vitest": "4.0.0-rc.112",
282
+ "@effect/vitest": "4.0.0-rc.117",
283
283
  "@types/css-tree": "3.2.0",
284
284
  "caniemail": "2.0.2",
285
285
  "css-tree": "3.2.1",
286
- "effect": "4.0.0-rc.112",
286
+ "effect": "4.0.0-rc.117",
287
287
  "tailwindcss": "^4.3.3",
288
288
  "tsdown": "^0.22.13",
289
289
  "typescript": "^7.0.2",
290
290
  "vitest": "^4.1.11",
291
- "zod": "4.5.2"
291
+ "zod": "4.6.5"
292
292
  },
293
293
  "peerDependencies": {
294
294
  "@babel/parser": "^8.0.4",