@fuaran-ui/ops 0.8.0 → 0.19.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.
package/dist/index.cjs CHANGED
@@ -80,10 +80,11 @@ var formatFiniteDouble = (n) => {
80
80
  return neg ? "-" + out : out;
81
81
  };
82
82
  var num = (n) => {
83
- if (Number.isNaN(n)) return '"NaN"';
84
- if (n === Infinity) return '"Infinity"';
85
- if (n === -Infinity) return '"-Infinity"';
86
- return formatFiniteDouble(n);
83
+ const v = Number(n);
84
+ if (Number.isNaN(v)) return '"NaN"';
85
+ if (v === Infinity) return '"Infinity"';
86
+ if (v === -Infinity) return '"-Infinity"';
87
+ return formatFiniteDouble(v);
87
88
  };
88
89
  var bool = (b) => b ? "true" : "false";
89
90
  var jObject = (fields) => {
@@ -593,6 +594,9 @@ var pushWeightOptional = (fields, w) => {
593
594
  var pushEmphasisOptional = (fields, e) => {
594
595
  if (e !== "Normal") fields.push(["emphasis", str(e)]);
595
596
  };
597
+ var pushTrendPolarityOptional = (fields, p) => {
598
+ if (p !== "HigherIsBetter") fields.push(["trendPolarity", str(p)]);
599
+ };
596
600
  var pushCellFormatOptional = (fields, key, f) => {
597
601
  if (f.kind !== "None") fields.push([key, cellFormat(f)]);
598
602
  };
@@ -610,6 +614,7 @@ var metricSpec = (s) => {
610
614
  pushEmphasisOptional(fields, s.emphasis);
611
615
  if (s.trend !== void 0) fields.push(["trend", binding(s.trend)]);
612
616
  if (s.trendFormat !== void 0) fields.push(["trendFormat", cellFormat(s.trendFormat)]);
617
+ pushTrendPolarityOptional(fields, s.trendPolarity);
613
618
  if (s.icon !== void 0) fields.push(["icon", str(s.icon)]);
614
619
  if (s.subtext !== void 0) fields.push(["subtext", textSource(s.subtext)]);
615
620
  return jObject(fields);
@@ -656,11 +661,40 @@ var linkSpec = (s) => {
656
661
  if (s.protection !== void 0) fields.push(["protection", str(s.protection)]);
657
662
  return jObject(fields);
658
663
  };
659
- var imageSpec = (s) => jObject([
660
- ["alt", textSource(s.alt)],
661
- ["src", binding(s.src)],
662
- ["variant", str(s.variant)]
664
+ var srcSetEntry = (e) => jObject([
665
+ ["src", binding(e.src)],
666
+ ["width", num(e.width)]
663
667
  ]);
668
+ var imageSpec = (s) => {
669
+ const fields = [
670
+ ["alt", textSource(s.alt)],
671
+ ["src", binding(s.src)],
672
+ ["variant", str(s.variant)]
673
+ ];
674
+ if (s.fit !== "Natural") fields.push(["fit", str(s.fit)]);
675
+ if (s.aspectRatio !== "Natural") fields.push(["aspectRatio", str(s.aspectRatio)]);
676
+ if (s.loading !== "Eager") fields.push(["loading", str(s.loading)]);
677
+ if (s.caption !== void 0) fields.push(["caption", textSource(s.caption)]);
678
+ if (s.srcSet.length > 0) fields.push(["srcSet", jArray(s.srcSet.map(srcSetEntry))]);
679
+ if (s.expandable) fields.push(["expandable", bool(true)]);
680
+ return jObject(fields);
681
+ };
682
+ var mediaKind = (k) => {
683
+ if (k.$type === "Audio") return caseObj("Audio", []);
684
+ const fields = [];
685
+ if (k.autoplay) fields.push(["autoplay", bool(true)]);
686
+ if (k.poster !== void 0) fields.push(["poster", binding(k.poster)]);
687
+ return caseObj("Video", fields);
688
+ };
689
+ var mediaSpec = (s) => {
690
+ const fields = [];
691
+ if (!s.controls) fields.push(["controls", bool(false)]);
692
+ fields.push(["kind", mediaKind(s.kind)]);
693
+ fields.push(["label", textSource(s.label)]);
694
+ if (s.loop) fields.push(["loop", bool(true)]);
695
+ fields.push(["src", binding(s.src)]);
696
+ return jObject(fields);
697
+ };
664
698
  var listSpec = (s) => jObject([
665
699
  ["items", jArray(s.items.map(textSource))],
666
700
  ["ordered", bool(s.ordered)]
@@ -869,6 +903,8 @@ var displayKind = (d) => {
869
903
  return hoistSpec("Link", linkSpec(d.spec));
870
904
  case "Image":
871
905
  return hoistSpec("Image", imageSpec(d.spec));
906
+ case "Media":
907
+ return hoistSpec("Media", mediaSpec(d.spec));
872
908
  case "List":
873
909
  return hoistSpec("List", listSpec(d.spec));
874
910
  case "Toast":
@@ -996,6 +1032,20 @@ var formFieldKind = (autoBind, k) => {
996
1032
  return assertNever(k);
997
1033
  }
998
1034
  };
1035
+ var compareRule = (c) => jObject([
1036
+ ["against", binding(c.against)],
1037
+ ["op", str(c.op)]
1038
+ ]);
1039
+ var fieldRule = (r) => {
1040
+ const fields = [];
1041
+ if (r.compare !== void 0) fields.push(["compare", compareRule(r.compare)]);
1042
+ if (r.format !== void 0) fields.push(["format", str(r.format)]);
1043
+ if (r.maxLength !== void 0) fields.push(["maxLength", intLit(r.maxLength)]);
1044
+ if (r.message !== void 0) fields.push(["message", textSource(r.message)]);
1045
+ if (r.minLength !== void 0) fields.push(["minLength", intLit(r.minLength)]);
1046
+ if (r.pattern !== void 0) fields.push(["pattern", str(r.pattern)]);
1047
+ return jObject(fields);
1048
+ };
999
1049
  var formField = (f) => {
1000
1050
  const fields = [
1001
1051
  ["id", str(f.id)],
@@ -1004,6 +1054,7 @@ var formField = (f) => {
1004
1054
  ["required", bool(f.required)]
1005
1055
  ];
1006
1056
  if (f.help !== void 0) fields.push(["help", textSource(f.help)]);
1057
+ if (f.rule !== void 0) fields.push(["rule", fieldRule(f.rule)]);
1007
1058
  return jObject(fields);
1008
1059
  };
1009
1060
  var formSpec = (s) => {
@@ -1181,6 +1232,8 @@ var gridSpec = (s) => {
1181
1232
  ["columns", jArray(s.columns.map(columnErased))],
1182
1233
  // 0.2.0 omitted-when-false.
1183
1234
  ...s.editable ? [["editable", bool(true)]] : [],
1235
+ // Phase 934 — omit-when-false, exactly as `editable` above.
1236
+ ...s.reorderable ? [["reorderable", bool(true)]] : [],
1184
1237
  // fuaran#665 — rows are a typed Static payload now, not the opaque residual.
1185
1238
  ["source", binding(s.source, staticRowSeq)]
1186
1239
  ];
@@ -1269,6 +1322,11 @@ var boxLayout = (l) => {
1269
1322
  if (l.templateColumns !== void 0) fields.push(["templateColumns", str(l.templateColumns)]);
1270
1323
  return caseObj("Grid", fields);
1271
1324
  }
1325
+ case "Masonry": {
1326
+ const fields = [["cols", intLit(l.cols)]];
1327
+ if (l.gap !== void 0) fields.push(["gap", intLit(l.gap)]);
1328
+ return caseObj("Masonry", fields);
1329
+ }
1272
1330
  case "Auto":
1273
1331
  return caseObj("Auto", []);
1274
1332
  default:
@@ -2681,8 +2739,6 @@ var stepParams = (t) => {
2681
2739
  var pipelineParams = (pipeline) => [
2682
2740
  ...new Set(pipeline.flatMap((t) => stepParams(t)))
2683
2741
  ];
2684
-
2685
- // src/parse.ts
2686
2742
  var peek = (s) => s.pos < s.text.length ? s.text[s.pos] : " ";
2687
2743
  var advance = (s) => {
2688
2744
  s.pos += 1;
@@ -2697,6 +2753,10 @@ var skipWs = (s) => {
2697
2753
  }
2698
2754
  }
2699
2755
  };
2756
+ var failLimit = (s, message) => ({
2757
+ ok: false,
2758
+ error: { message, offset: s.pos, limit: true }
2759
+ });
2700
2760
  var fail = (s, message) => ({
2701
2761
  ok: false,
2702
2762
  error: { message, offset: s.pos }
@@ -2719,7 +2779,14 @@ var parseStringRaw = (s) => {
2719
2779
  advance(s);
2720
2780
  if (c === '"') {
2721
2781
  return { ok: true, value: out };
2722
- } else if (c === "\\") {
2782
+ }
2783
+ if (out.length > schema.MAX_STRING_LENGTH) {
2784
+ return failLimit(
2785
+ s,
2786
+ `string is longer than the wire limit MAX_STRING_LENGTH = ${schema.MAX_STRING_LENGTH}`
2787
+ );
2788
+ }
2789
+ if (c === "\\") {
2723
2790
  if (s.pos >= s.text.length) return fail(s, "unterminated escape");
2724
2791
  const esc = s.text[s.pos];
2725
2792
  advance(s);
@@ -2819,6 +2886,12 @@ var parseValue = (s) => {
2819
2886
  }
2820
2887
  };
2821
2888
  var parseObjectValue = (s) => {
2889
+ if (s.depth >= schema.MAX_JSON_DEPTH) {
2890
+ return failLimit(
2891
+ s,
2892
+ `JSON nesting deeper than the wire limit MAX_JSON_DEPTH = ${schema.MAX_JSON_DEPTH}`
2893
+ );
2894
+ }
2822
2895
  const open = expectChar(s, "{");
2823
2896
  if (!open.ok) return open;
2824
2897
  skipWs(s);
@@ -2827,15 +2900,34 @@ var parseObjectValue = (s) => {
2827
2900
  advance(s);
2828
2901
  return { ok: true, value: { kind: "JObject", fields } };
2829
2902
  }
2903
+ s.depth += 1;
2904
+ let count = 0;
2830
2905
  for (; ; ) {
2831
2906
  skipWs(s);
2832
2907
  const keyR = parseStringRaw(s);
2833
- if (!keyR.ok) return keyR;
2908
+ if (!keyR.ok) {
2909
+ s.depth -= 1;
2910
+ return keyR;
2911
+ }
2834
2912
  skipWs(s);
2835
2913
  const colon = expectChar(s, ":");
2836
- if (!colon.ok) return colon;
2914
+ if (!colon.ok) {
2915
+ s.depth -= 1;
2916
+ return colon;
2917
+ }
2837
2918
  const valR = parseValue(s);
2838
- if (!valR.ok) return valR;
2919
+ if (!valR.ok) {
2920
+ s.depth -= 1;
2921
+ return valR;
2922
+ }
2923
+ count += 1;
2924
+ if (count > schema.MAX_ARRAY_LENGTH) {
2925
+ s.depth -= 1;
2926
+ return failLimit(
2927
+ s,
2928
+ `object has more members than the wire limit MAX_ARRAY_LENGTH = ${schema.MAX_ARRAY_LENGTH}`
2929
+ );
2930
+ }
2839
2931
  fields.set(keyR.value, valR.value);
2840
2932
  skipWs(s);
2841
2933
  const c = peek(s);
@@ -2843,13 +2935,21 @@ var parseObjectValue = (s) => {
2843
2935
  advance(s);
2844
2936
  } else if (c === "}") {
2845
2937
  advance(s);
2938
+ s.depth -= 1;
2846
2939
  return { ok: true, value: { kind: "JObject", fields } };
2847
2940
  } else {
2941
+ s.depth -= 1;
2848
2942
  return fail(s, `expected ',' or '}' but found '${c}'`);
2849
2943
  }
2850
2944
  }
2851
2945
  };
2852
2946
  var parseArrayValue = (s) => {
2947
+ if (s.depth >= schema.MAX_JSON_DEPTH) {
2948
+ return failLimit(
2949
+ s,
2950
+ `JSON nesting deeper than the wire limit MAX_JSON_DEPTH = ${schema.MAX_JSON_DEPTH}`
2951
+ );
2952
+ }
2853
2953
  const open = expectChar(s, "[");
2854
2954
  if (!open.ok) return open;
2855
2955
  skipWs(s);
@@ -2858,24 +2958,37 @@ var parseArrayValue = (s) => {
2858
2958
  advance(s);
2859
2959
  return { ok: true, value: { kind: "JArray", items } };
2860
2960
  }
2961
+ s.depth += 1;
2861
2962
  for (; ; ) {
2862
2963
  const valR = parseValue(s);
2863
- if (!valR.ok) return valR;
2964
+ if (!valR.ok) {
2965
+ s.depth -= 1;
2966
+ return valR;
2967
+ }
2864
2968
  items.push(valR.value);
2969
+ if (items.length > schema.MAX_ARRAY_LENGTH) {
2970
+ s.depth -= 1;
2971
+ return failLimit(
2972
+ s,
2973
+ `array is longer than the wire limit MAX_ARRAY_LENGTH = ${schema.MAX_ARRAY_LENGTH}`
2974
+ );
2975
+ }
2865
2976
  skipWs(s);
2866
2977
  const c = peek(s);
2867
2978
  if (c === ",") {
2868
2979
  advance(s);
2869
2980
  } else if (c === "]") {
2870
2981
  advance(s);
2982
+ s.depth -= 1;
2871
2983
  return { ok: true, value: { kind: "JArray", items } };
2872
2984
  } else {
2985
+ s.depth -= 1;
2873
2986
  return fail(s, `expected ',' or ']' but found '${c}'`);
2874
2987
  }
2875
2988
  }
2876
2989
  };
2877
2990
  var parse = (input) => {
2878
- const s = { text: input, pos: 0 };
2991
+ const s = { text: input, pos: 0, depth: 0 };
2879
2992
  skipWs(s);
2880
2993
  if (s.pos >= s.text.length) {
2881
2994
  return { ok: false, error: { message: "input is empty", offset: 0 } };
@@ -2893,6 +3006,7 @@ var makeError = (code, path, message, expectedShape) => ({
2893
3006
  var missingField = (path, key, expected) => makeError("MISSING_FIELD", `${path}.${key}`, `missing required field '${key}'`, expected);
2894
3007
  var wrongType = (path, expected) => makeError("WRONG_TYPE", path, `expected ${expected}`, expected);
2895
3008
  var unknownDuCase = (path, got, expected) => makeError("UNKNOWN_DU_CASE", `${path}.$type`, `unknown discriminator '${got}'`, expected);
3009
+ var unknownEnumCase = (path, got, expected) => makeError("UNKNOWN_DU_CASE", path, `unknown discriminator '${got}'`, expected);
2896
3010
  var CLOSURE2 = "<closure>";
2897
3011
  var OPAQUE2 = "<opaque>";
2898
3012
  var requireObject = (path, j) => j.kind === "JObject" ? ok(j.fields) : wrongType(path, "JSON object");
@@ -3045,7 +3159,7 @@ var decodeJValMap = (path, j) => {
3045
3159
  var bareEnum = (path, j, valid, label) => {
3046
3160
  if (j.kind !== "JString") return wrongType(path, `JSON string (${label})`);
3047
3161
  if (valid.includes(j.value)) return ok(j.value);
3048
- return unknownDuCase(path, j.value, valid.join(" | "));
3162
+ return unknownEnumCase(path, j.value, valid.join(" | "));
3049
3163
  };
3050
3164
  var ORIENTATION_ALIASES = {
3051
3165
  // CSS flex-direction prior: a row lays out horizontally, a column vertically.
@@ -3083,6 +3197,14 @@ var decodeHeadingVariant = (p, j) => {
3083
3197
  return bareEnum(p, j, ["Standard", "Eyebrow", "Caption", "Lead"], "HeadingVariant");
3084
3198
  };
3085
3199
  var decodeImageVariant = (p, j) => bareEnum(p, j, ["Default", "Avatar", "Rounded"], "ImageVariant");
3200
+ var decodeImageFit = (p, j) => bareEnum(p, j, ["Natural", "Cover", "Contain"], "ImageFit");
3201
+ var decodeImageAspect = (p, j) => bareEnum(
3202
+ p,
3203
+ j,
3204
+ ["Natural", "Square", "FourThree", "ThreeTwo", "SixteenNine"],
3205
+ "ImageAspect"
3206
+ );
3207
+ var decodeImageLoading = (p, j) => bareEnum(p, j, ["Eager", "Lazy"], "ImageLoading");
3086
3208
  var decodeScrollOrientation = (p, j) => bareEnum(p, j, ["Vertical", "Horizontal", "Both"], "ScrollOrientation");
3087
3209
  var decodeDateVariant = (p, j) => bareEnum(p, j, ["Date", "Time", "DateTime"], "DateVariant");
3088
3210
  var decodeMathDisplay = (p, j) => bareEnum(p, j, ["Inline", "Block"], "MathDisplay");
@@ -3116,6 +3238,7 @@ var decodeWeight = (p, j) => (
3116
3238
  // Compact|Standard|Spacious means density (WIRE_FORMAT.md §3.6).
3117
3239
  bareEnum(p, j, ["Compact", "Standard", "Spacious"], "StyleWeight")
3118
3240
  );
3241
+ var decodeTrendPolarity = (p, j) => bareEnum(p, j, ["HigherIsBetter", "LowerIsBetter"], "TrendPolarity");
3119
3242
  var decodeEmphasis = (p, j) => {
3120
3243
  if (j.kind === "JString" && j.value in EMPHASIS_ALIASES) return ok(EMPHASIS_ALIASES[j.value]);
3121
3244
  if (j.kind === "JBool") return ok(j.value ? "Loud" : "Normal");
@@ -4317,29 +4440,43 @@ var decodeBinding = (path, j, parseStatic = (_p, v) => ok(decodeAstValue(v)), pl
4317
4440
  if (!pipeJ.ok) return pipeJ;
4318
4441
  const liveTagAst = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("$type") : void 0;
4319
4442
  const liveTag = liveTagAst !== void 0 && liveTagAst.kind === "JString" && (liveTagAst.value === "State" || liveTagAst.value === "Selection" || liveTagAst.value === "Query") ? liveTagAst.value : void 0;
4320
- const hasCarried = srcJ.value.kind === "JObject" && srcJ.value.fields.has("defaultValue");
4321
4443
  let source;
4322
- if (liveTag === void 0 || liveTag === "State" && !hasCarried) {
4444
+ if (liveTag === void 0) {
4323
4445
  const src = decodeDataSource(normaliseTransformSource(srcJ.value));
4324
4446
  if (!src.ok) return makeError("WRONG_TYPE", `${path}.source`, src.error);
4325
4447
  source = { kind: "Data", source: src.value };
4326
4448
  } else {
4327
4449
  const b2 = decodeBinding(`${path}.source`, srcJ.value, decodeJVal, void 0);
4328
4450
  if (!b2.ok) return b2;
4451
+ const liveBinding = (() => {
4452
+ const raw = b2.value;
4453
+ const declared = srcJ.value.kind === "JObject" && srcJ.value.fields.has("defaultValue");
4454
+ return raw.kind === "State" && !declared ? { ...raw, defaultValue: void 0 } : raw;
4455
+ })();
4329
4456
  if (liveTag === "State") {
4330
- const snap = decodeDataSource(normaliseTransformSource(srcJ.value));
4331
- if (!snap.ok) return makeError("WRONG_TYPE", `${path}.source`, snap.error);
4332
- source = {
4333
- kind: "Live",
4334
- binding: b2.value,
4335
- initial: snap.value
4336
- };
4457
+ const carriedJ = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("defaultValue") : void 0;
4458
+ const carriesNoData = carriedJ === void 0 || carriedJ.kind === "JArray" && carriedJ.items.length === 0;
4459
+ if (carriesNoData) {
4460
+ source = {
4461
+ kind: "Live",
4462
+ binding: liveBinding,
4463
+ initial: { kind: "Embedded", table: { schema: [], columns: [] } }
4464
+ };
4465
+ } else {
4466
+ const snap = decodeDataSource(normaliseTransformSource(srcJ.value));
4467
+ if (!snap.ok) return makeError("WRONG_TYPE", `${path}.source`, snap.error);
4468
+ source = {
4469
+ kind: "Live",
4470
+ binding: liveBinding,
4471
+ initial: snap.value
4472
+ };
4473
+ }
4337
4474
  } else {
4338
4475
  const dv = srcJ.value.kind === "JObject" ? srcJ.value.fields.get("defaultValue") : void 0;
4339
4476
  const snap = dv !== void 0 ? decodeDataSource(normaliseTransformSource(dv)) : void 0;
4340
4477
  source = {
4341
4478
  kind: "Live",
4342
- binding: b2.value,
4479
+ binding: liveBinding,
4343
4480
  initial: snap !== void 0 && snap.ok ? snap.value : { kind: "Embedded", table: { schema: [], columns: [] } }
4344
4481
  };
4345
4482
  }
@@ -4496,8 +4633,10 @@ var decodeBindingArgs = (path, j) => {
4496
4633
  }
4497
4634
  return ok(out);
4498
4635
  };
4499
- var decodeBindingString = (p, j) => decodeBinding(p, j);
4500
- var decodeBindingBool = (p, j) => decodeBinding(p, j);
4636
+ var decodeBindingString = (p, j) => decodeBinding(p, j, requireString, "");
4637
+ var decodeBindingBool = (p, j) => decodeBinding(p, j, requireBool, false);
4638
+ var decodeBindingFloat = (p, j) => decodeBinding(p, j, requireFloat, 0);
4639
+ var decodeBindingInt = (p, j) => decodeBinding(p, j, requireInt, 0);
4501
4640
  var OPTIONS_PLACEHOLDER = [
4502
4641
  { value: OPAQUE2, label: { kind: "Literal", value: OPAQUE2 } }
4503
4642
  ];
@@ -4840,7 +4979,14 @@ var decodeMetricSpec = (path, j) => {
4840
4979
  const f = fo.value;
4841
4980
  const label = reqField(path, f, "label", "Metric label TextSource", decodeTextSource);
4842
4981
  if (!label.ok) return label;
4843
- const source = reqFieldAliased(path, f, "value", ["data"], "Metric value binding", decodeBinding);
4982
+ const source = reqFieldAliased(
4983
+ path,
4984
+ f,
4985
+ "value",
4986
+ ["data"],
4987
+ "Metric value binding",
4988
+ decodeBindingFloat
4989
+ );
4844
4990
  if (!source.ok) {
4845
4991
  if (source.error.message.includes("expected JSON number")) {
4846
4992
  return {
@@ -4861,10 +5007,12 @@ var decodeMetricSpec = (path, j) => {
4861
5007
  if (!weight.ok) return weight;
4862
5008
  const emphasis = optField(path, f, "emphasis", decodeEmphasis);
4863
5009
  if (!emphasis.ok) return emphasis;
4864
- const trend = optField(path, f, "trend", decodeBinding);
5010
+ const trend = optField(path, f, "trend", decodeBindingFloat);
4865
5011
  if (!trend.ok) return trend;
4866
5012
  const trendFormat = optField(path, f, "trendFormat", decodeCellFormat);
4867
5013
  if (!trendFormat.ok) return trendFormat;
5014
+ const trendPolarity = optField(path, f, "trendPolarity", decodeTrendPolarity);
5015
+ if (!trendPolarity.ok) return trendPolarity;
4868
5016
  const icon = optField(path, f, "icon", decodeIconSource);
4869
5017
  if (!icon.ok) return icon;
4870
5018
  const subtext = optField(path, f, "subtext", decodeTextSource);
@@ -4878,6 +5026,7 @@ var decodeMetricSpec = (path, j) => {
4878
5026
  emphasis: emphasis.value ?? "Normal",
4879
5027
  ...trend.value !== void 0 ? { trend: trend.value } : {},
4880
5028
  ...trendFormat.value !== void 0 ? { trendFormat: trendFormat.value } : {},
5029
+ trendPolarity: trendPolarity.value ?? "HigherIsBetter",
4881
5030
  ...icon.value !== void 0 ? { icon: icon.value } : {},
4882
5031
  ...subtext.value !== void 0 ? { subtext: subtext.value } : {}
4883
5032
  });
@@ -4906,7 +5055,7 @@ var decodeLabelValueRowSpec = (path, j) => {
4906
5055
  "value",
4907
5056
  ["data"],
4908
5057
  "row Binding<float> value",
4909
- decodeBinding
5058
+ decodeBindingFloat
4910
5059
  );
4911
5060
  if (!source.ok) return source;
4912
5061
  const format = optField(path, f, "format", decodeCellFormat);
@@ -4995,6 +5144,23 @@ var decodeLinkSpec = (path, j) => {
4995
5144
  });
4996
5145
  };
4997
5146
  var decodeLinkProtection = (p, j) => bareEnum(p, j, ["email"], "LinkProtection");
5147
+ var decodeSrcSetEntry = (path, j) => {
5148
+ const fo = requireObject(path, j);
5149
+ if (!fo.ok) return fo;
5150
+ const src = reqField(
5151
+ path,
5152
+ fo.value,
5153
+ "src",
5154
+ "srcSet entry Binding<string> src",
5155
+ decodeBindingString
5156
+ );
5157
+ if (!src.ok) return src;
5158
+ const widthJ = tryField(fo.value, "width");
5159
+ if (widthJ === void 0) return missingField(path, "width", "positive intrinsic pixel width");
5160
+ if (widthJ.kind !== "JNumber" || widthJ.value <= 0 || !Number.isInteger(widthJ.value))
5161
+ return wrongType(`${path}.width`, "JSON number (positive integer pixel width)");
5162
+ return ok({ src: src.value, width: widthJ.value });
5163
+ };
4998
5164
  var decodeImageSpec = (path, j) => {
4999
5165
  const fo = requireObject(path, j);
5000
5166
  if (!fo.ok) return fo;
@@ -5005,7 +5171,90 @@ var decodeImageSpec = (path, j) => {
5005
5171
  if (!src.ok) return src;
5006
5172
  const variant = reqField(path, f, "variant", "ImageVariant", decodeImageVariant);
5007
5173
  if (!variant.ok) return variant;
5008
- return ok({ alt: alt.value, src: src.value, variant: variant.value });
5174
+ const fitJ = tryField(f, "fit");
5175
+ const fit = fitJ === void 0 ? ok("Natural") : decodeImageFit(`${path}.fit`, fitJ);
5176
+ if (!fit.ok) return fit;
5177
+ const aspectJ = tryField(f, "aspectRatio");
5178
+ const aspectRatio = aspectJ === void 0 ? ok("Natural") : decodeImageAspect(`${path}.aspectRatio`, aspectJ);
5179
+ if (!aspectRatio.ok) return aspectRatio;
5180
+ const loadingJ = tryField(f, "loading");
5181
+ const loading = loadingJ === void 0 ? ok("Eager") : decodeImageLoading(`${path}.loading`, loadingJ);
5182
+ if (!loading.ok) return loading;
5183
+ const caption = optField(path, f, "caption", decodeTextSource);
5184
+ if (!caption.ok) return caption;
5185
+ const srcSetJ = tryField(f, "srcSet");
5186
+ const srcSet = srcSetJ === void 0 ? ok([]) : (() => {
5187
+ const arr = requireArray(`${path}.srcSet`, srcSetJ);
5188
+ if (!arr.ok) return arr;
5189
+ return traverseIndexed(
5190
+ arr.value,
5191
+ (i, el) => decodeSrcSetEntry(`${path}.srcSet[${i}]`, el)
5192
+ );
5193
+ })();
5194
+ if (!srcSet.ok) return srcSet;
5195
+ const expandableJ = tryField(f, "expandable");
5196
+ const expandable = expandableJ === void 0 ? ok(false) : requireBool(`${path}.expandable`, expandableJ);
5197
+ if (!expandable.ok) return expandable;
5198
+ return ok({
5199
+ alt: alt.value,
5200
+ src: src.value,
5201
+ variant: variant.value,
5202
+ fit: fit.value,
5203
+ aspectRatio: aspectRatio.value,
5204
+ loading: loading.value,
5205
+ srcSet: srcSet.value,
5206
+ expandable: expandable.value,
5207
+ ...caption.value !== void 0 ? { caption: caption.value } : {}
5208
+ });
5209
+ };
5210
+ var decodeMediaKind = (path, j) => {
5211
+ const fo = requireObject(path, j);
5212
+ if (!fo.ok) return fo;
5213
+ const f = fo.value;
5214
+ const d = requireDiscriminator(path, f);
5215
+ if (!d.ok) return d;
5216
+ switch (d.value) {
5217
+ case "Video": {
5218
+ const autoplayJ = tryField(f, "autoplay");
5219
+ const autoplay = autoplayJ === void 0 ? ok(false) : requireBool(`${path}.autoplay`, autoplayJ);
5220
+ if (!autoplay.ok) return autoplay;
5221
+ const poster = optField(path, f, "poster", decodeBindingString);
5222
+ if (!poster.ok) return poster;
5223
+ return ok({
5224
+ $type: "Video",
5225
+ autoplay: autoplay.value,
5226
+ ...poster.value !== void 0 ? { poster: poster.value } : {}
5227
+ });
5228
+ }
5229
+ case "Audio":
5230
+ return ok({ $type: "Audio" });
5231
+ default:
5232
+ return unknownDuCase(path, d.value, "Video | Audio");
5233
+ }
5234
+ };
5235
+ var decodeMediaSpec = (path, j) => {
5236
+ const fo = requireObject(path, j);
5237
+ if (!fo.ok) return fo;
5238
+ const f = fo.value;
5239
+ const src = reqField(path, f, "src", "Media Binding<string> Src", decodeBindingString);
5240
+ if (!src.ok) return src;
5241
+ const label = reqField(path, f, "label", "Media accessible label TextSource", decodeTextSource);
5242
+ if (!label.ok) return label;
5243
+ const kind = reqField(path, f, "kind", "MediaKind (Video | Audio)", decodeMediaKind);
5244
+ if (!kind.ok) return kind;
5245
+ const controlsJ = tryField(f, "controls");
5246
+ const controls = controlsJ === void 0 ? ok(true) : requireBool(`${path}.controls`, controlsJ);
5247
+ if (!controls.ok) return controls;
5248
+ const loopJ = tryField(f, "loop");
5249
+ const loop = loopJ === void 0 ? ok(false) : requireBool(`${path}.loop`, loopJ);
5250
+ if (!loop.ok) return loop;
5251
+ return ok({
5252
+ src: src.value,
5253
+ label: label.value,
5254
+ controls: controls.value,
5255
+ loop: loop.value,
5256
+ kind: kind.value
5257
+ });
5009
5258
  };
5010
5259
  var decodeListSpec = (path, j) => {
5011
5260
  const fo = requireObject(path, j);
@@ -5149,7 +5398,7 @@ var decodeProgressSpec = (path, j) => {
5149
5398
  const fo = requireObject(path, j);
5150
5399
  if (!fo.ok) return fo;
5151
5400
  const f = fo.value;
5152
- const fraction = reqField(path, f, "fraction", "Progress fraction binding", decodeBinding);
5401
+ const fraction = reqField(path, f, "fraction", "Progress fraction binding", decodeBindingFloat);
5153
5402
  if (!fraction.ok) return fraction;
5154
5403
  const indeterminate = optField(path, f, "indeterminate", requireBool);
5155
5404
  if (!indeterminate.ok) return indeterminate;
@@ -5199,9 +5448,9 @@ var decodeDrawStyle = (path, j) => {
5199
5448
  if (!fill.ok) return fill;
5200
5449
  const stroke = optField(path, f, "stroke", decodeBindingString);
5201
5450
  if (!stroke.ok) return stroke;
5202
- const strokeWidth = optField(path, f, "strokeWidth", decodeBinding);
5451
+ const strokeWidth = optField(path, f, "strokeWidth", decodeBindingFloat);
5203
5452
  if (!strokeWidth.ok) return strokeWidth;
5204
- const opacity = optField(path, f, "opacity", decodeBinding);
5453
+ const opacity = optField(path, f, "opacity", decodeBindingFloat);
5205
5454
  if (!opacity.ok) return opacity;
5206
5455
  const textAnchor = optField(path, f, "textAnchor", decodeTextAnchor);
5207
5456
  if (!textAnchor.ok) return textAnchor;
@@ -5480,6 +5729,10 @@ var decodeDisplayKind = (path, j) => {
5480
5729
  const r = decodeImageSpec(path, j);
5481
5730
  return r.ok ? ok({ kind: "Image", spec: r.value }) : r;
5482
5731
  }
5732
+ case "Media": {
5733
+ const r = decodeMediaSpec(path, j);
5734
+ return r.ok ? ok({ kind: "Media", spec: r.value }) : r;
5735
+ }
5483
5736
  case "List": {
5484
5737
  const r = decodeListSpec(path, j);
5485
5738
  return r.ok ? ok({ kind: "List", spec: r.value }) : r;
@@ -5531,7 +5784,11 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5531
5784
  return v.ok ? ok({ kind: "Text", value: v.value, ...onChangeField }) : v;
5532
5785
  }
5533
5786
  case "Number": {
5534
- const v = valueOr(decodeBinding, schema.controlValueDefaults.number, "Number value binding");
5787
+ const v = valueOr(
5788
+ decodeBindingFloat,
5789
+ schema.controlValueDefaults.number,
5790
+ "Number value binding"
5791
+ );
5535
5792
  return v.ok ? ok({ kind: "Number", value: v.value, ...onChangeField }) : v;
5536
5793
  }
5537
5794
  case "Checkbox": {
@@ -5583,7 +5840,7 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5583
5840
  }
5584
5841
  case "RangedNumber": {
5585
5842
  const value = valueOr(
5586
- decodeBinding,
5843
+ decodeBindingFloat,
5587
5844
  schema.controlValueDefaults.number,
5588
5845
  "RangedNumber value binding"
5589
5846
  );
@@ -5697,6 +5954,77 @@ var decodeFormFieldKind = (autoBind, path, j) => {
5697
5954
  return unknownDuCase(path, d.value, WRONG_FORM_FIELD_KIND_HINT);
5698
5955
  }
5699
5956
  };
5957
+ var TEXT_FORMATS = ["email", "url", "tel"];
5958
+ var COMPARE_OPS = ["eq", "neq", "lt", "lte", "gt", "gte"];
5959
+ var decodeTextFormat = (path, j) => bareEnum(path, j, TEXT_FORMATS, "TextFormat");
5960
+ var decodeCompareOp = (path, j) => bareEnum(path, j, COMPARE_OPS, "CompareOp");
5961
+ var decodeCompareRule = (path, j) => {
5962
+ const fo = requireObject(path, j);
5963
+ if (!fo.ok) return fo;
5964
+ const f = fo.value;
5965
+ const op = reqField(path, f, "op", "CompareOp", decodeCompareOp);
5966
+ if (!op.ok) return op;
5967
+ const against = reqField(path, f, "against", "Binding", (p, v) => decodeBinding(p, v));
5968
+ if (!against.ok) return against;
5969
+ return ok({ op: op.value, against: against.value });
5970
+ };
5971
+ var decodeFieldRule = (path, j) => {
5972
+ const fo = requireObject(path, j);
5973
+ if (!fo.ok) return fo;
5974
+ const f = fo.value;
5975
+ const format = optField(path, f, "format", decodeTextFormat);
5976
+ if (!format.ok) return format;
5977
+ const pattern = optField(path, f, "pattern", requireString);
5978
+ if (!pattern.ok) return pattern;
5979
+ const minLength = optField(path, f, "minLength", requireInt);
5980
+ if (!minLength.ok) return minLength;
5981
+ const maxLength = optField(path, f, "maxLength", requireInt);
5982
+ if (!maxLength.ok) return maxLength;
5983
+ const compare = optField(path, f, "compare", decodeCompareRule);
5984
+ if (!compare.ok) return compare;
5985
+ const message = optField(path, f, "message", decodeTextSource);
5986
+ if (!message.ok) return message;
5987
+ const constrains = format.value !== void 0 || pattern.value !== void 0 || minLength.value !== void 0 || maxLength.value !== void 0 || compare.value !== void 0;
5988
+ if (!constrains)
5989
+ return makeError(
5990
+ "WRONG_TYPE",
5991
+ path,
5992
+ "a rule that constrains nothing is a defect, not a no-op \u2014 declare at least one of format / pattern / minLength / maxLength / compare, or omit 'rule' entirely",
5993
+ "FieldRule with at least one constraint slot"
5994
+ );
5995
+ if (minLength.value !== void 0 && maxLength.value !== void 0 && minLength.value > maxLength.value)
5996
+ return makeError(
5997
+ "WRONG_TYPE",
5998
+ path,
5999
+ `minLength ${minLength.value} is above maxLength ${maxLength.value} \u2014 an inverted length bound admits no value at all, so the field could never be submitted`,
6000
+ "minLength <= maxLength"
6001
+ );
6002
+ return ok({
6003
+ ...format.value !== void 0 ? { format: format.value } : {},
6004
+ ...pattern.value !== void 0 ? { pattern: pattern.value } : {},
6005
+ ...minLength.value !== void 0 ? { minLength: minLength.value } : {},
6006
+ ...maxLength.value !== void 0 ? { maxLength: maxLength.value } : {},
6007
+ ...compare.value !== void 0 ? { compare: compare.value } : {},
6008
+ ...message.value !== void 0 ? { message: message.value } : {}
6009
+ });
6010
+ };
6011
+ var FORM_FIELD_NEAR_MISSES = [
6012
+ ["validation", "rule"],
6013
+ ["constraints", "rule"],
6014
+ ["validate", "rule"]
6015
+ ];
6016
+ var checkFormFieldNearMisses = (path, f) => {
6017
+ for (const [name, canonical] of FORM_FIELD_NEAR_MISSES) {
6018
+ if (tryField(f, name) !== void 0)
6019
+ return makeError(
6020
+ "WRONG_TYPE",
6021
+ `${path}.${name}`,
6022
+ `'${name}' is not part of the form vocabulary \u2014 it would be ignored, not honoured, and the field would accept anything`,
6023
+ canonical
6024
+ );
6025
+ }
6026
+ return ok(void 0);
6027
+ };
5700
6028
  var decodeFormField = (path, j) => {
5701
6029
  const fo = requireObject(path, j);
5702
6030
  if (!fo.ok) return fo;
@@ -5718,12 +6046,17 @@ var decodeFormField = (path, j) => {
5718
6046
  if (!required.ok) return required;
5719
6047
  const help = optField(path, f, "help", decodeTextSource);
5720
6048
  if (!help.ok) return help;
6049
+ const nm = checkFormFieldNearMisses(path, f);
6050
+ if (!nm.ok) return nm;
6051
+ const rule = optField(path, f, "rule", decodeFieldRule);
6052
+ if (!rule.ok) return rule;
5721
6053
  return ok({
5722
6054
  id: id.value,
5723
6055
  kind: kind.value,
5724
6056
  label: label.value,
5725
6057
  required: required.value,
5726
- ...help.value !== void 0 ? { help: help.value } : {}
6058
+ ...help.value !== void 0 ? { help: help.value } : {},
6059
+ ...rule.value !== void 0 ? { rule: rule.value } : {}
5727
6060
  });
5728
6061
  };
5729
6062
  var decodeFormSpec = (path, j) => {
@@ -6217,6 +6550,8 @@ var decodeGridSpec = (path, j) => {
6217
6550
  if (!columns.ok) return columns;
6218
6551
  const editable = optField(path, f, "editable", requireBool);
6219
6552
  if (!editable.ok) return editable;
6553
+ const reorderable = optField(path, f, "reorderable", requireBool);
6554
+ if (!reorderable.ok) return reorderable;
6220
6555
  const source = reqFieldAliased(
6221
6556
  path,
6222
6557
  f,
@@ -6282,6 +6617,7 @@ var decodeGridSpec = (path, j) => {
6282
6617
  return ok({
6283
6618
  columns: columns.value,
6284
6619
  editable: editable.value ?? false,
6620
+ reorderable: reorderable.value ?? false,
6285
6621
  source: source.value,
6286
6622
  ...hasRowClick ? { onRowClick: () => placeholderAction } : {},
6287
6623
  ...hasRowKey ? { rowKey: () => CLOSURE2 } : {},
@@ -6459,10 +6795,23 @@ var decodeBoxLayout = (path, j) => {
6459
6795
  ...templateColumns.value !== void 0 ? { templateColumns: templateColumns.value } : {}
6460
6796
  });
6461
6797
  }
6798
+ case "Masonry": {
6799
+ const colsJ = tryField(f, "cols") ?? tryField(f, "columns");
6800
+ if (colsJ === void 0) return missingField(path, "cols", "positive integer column count");
6801
+ if (colsJ.kind !== "JNumber" || colsJ.value <= 0 || !Number.isInteger(colsJ.value))
6802
+ return wrongType(`${path}.cols`, "JSON number (positive integer column count)");
6803
+ const masonryGap = optField(path, f, "gap", requireInt);
6804
+ if (!masonryGap.ok) return masonryGap;
6805
+ return ok({
6806
+ kind: "Masonry",
6807
+ cols: colsJ.value,
6808
+ ...masonryGap.value !== void 0 ? { gap: masonryGap.value } : {}
6809
+ });
6810
+ }
6462
6811
  case "Auto":
6463
6812
  return ok({ kind: "Auto" });
6464
6813
  default:
6465
- return unknownDuCase(path, d.value, "Flex | Grid | Auto");
6814
+ return unknownDuCase(path, d.value, "Flex | Grid | Masonry | Auto");
6466
6815
  }
6467
6816
  };
6468
6817
  var decodeBoxRole = (path, j) => {
@@ -6475,7 +6824,7 @@ var decodeBoxRole = (path, j) => {
6475
6824
  case "Separator":
6476
6825
  return ok(s.value);
6477
6826
  default:
6478
- return unknownDuCase(path, s.value, "Group | Card | Dashboard | Separator");
6827
+ return unknownEnumCase(path, s.value, "Group | Card | Dashboard | Separator");
6479
6828
  }
6480
6829
  };
6481
6830
  var decodeBox = (path, j) => {
@@ -6558,7 +6907,7 @@ var decodeTabsSpec = (path, j) => {
6558
6907
  }
6559
6908
  const activeTag = optField(path, f, "activeTag", decodeBindingString);
6560
6909
  if (!activeTag.ok) return activeTag;
6561
- const activeIndex = optField(path, f, "activeIndex", decodeBinding);
6910
+ const activeIndex = optField(path, f, "activeIndex", decodeBindingInt);
6562
6911
  if (!activeIndex.ok) return activeIndex;
6563
6912
  return ok({
6564
6913
  children: children.value,
@@ -6575,7 +6924,7 @@ var decodeStepperSpec = (path, j) => {
6575
6924
  const fo = requireObject(path, j);
6576
6925
  if (!fo.ok) return fo;
6577
6926
  const f = fo.value;
6578
- const activeStep = reqField(path, f, "activeStep", "activeStep binding", decodeBinding);
6927
+ const activeStep = reqField(path, f, "activeStep", "activeStep binding", decodeBindingInt);
6579
6928
  if (!activeStep.ok) return activeStep;
6580
6929
  const children = decodeChildren(path, f);
6581
6930
  if (!children.ok) return children;
@@ -6740,7 +7089,7 @@ var decodeContentHash = (path, j) => {
6740
7089
  if (!strictnessR.ok) return strictnessR;
6741
7090
  const s = strictnessR.value;
6742
7091
  if (s !== "StrictReplay" && s !== "AdvisoryWarning" && s !== "Enforced") {
6743
- return unknownDuCase(`${path}.strictness`, s, "StrictReplay | AdvisoryWarning | Enforced");
7092
+ return unknownEnumCase(`${path}.strictness`, s, "StrictReplay | AdvisoryWarning | Enforced");
6744
7093
  }
6745
7094
  return ok({ algorithm: algorithm.value, hash: hash.value, strictness: s });
6746
7095
  };
@@ -6871,11 +7220,11 @@ var decodeEffectClass = (path, j) => {
6871
7220
  const host = reqField(path, fo.value, "hostEffect", "EffectClass hostEffect", requireString);
6872
7221
  if (!host.ok) return host;
6873
7222
  if (host.value !== "Pure" && host.value !== "ReadsHost" && host.value !== "WritesHost")
6874
- return unknownDuCase(`${path}.hostEffect`, host.value, "Pure | ReadsHost | WritesHost");
7223
+ return unknownEnumCase(`${path}.hostEffect`, host.value, "Pure | ReadsHost | WritesHost");
6875
7224
  const det = reqField(path, fo.value, "determinism", "EffectClass determinism", requireString);
6876
7225
  if (!det.ok) return det;
6877
7226
  if (det.value !== "Deterministic" && det.value !== "Clock" && det.value !== "Random" && det.value !== "Network")
6878
- return unknownDuCase(
7227
+ return unknownEnumCase(
6879
7228
  `${path}.determinism`,
6880
7229
  det.value,
6881
7230
  "Deterministic | Clock | Random | Network"
@@ -6895,6 +7244,14 @@ var decodeNodeKind = (path, j) => {
6895
7244
  const f = fo.value;
6896
7245
  const d = requireDiscriminator(path, f);
6897
7246
  if (!d.ok) return d;
7247
+ if (schema.narrows(walkPolicy) && schema.NODE_KIND_NAMES.includes(d.value) && !schema.admits(walkPolicy, d.value)) {
7248
+ return makeError(
7249
+ "KIND_NOT_ADMITTED",
7250
+ `${path}.$type`,
7251
+ `node kind '${d.value}' is not admitted by decode policy '${walkPolicy.identity}'`,
7252
+ schema.policyHint(walkPolicy)
7253
+ );
7254
+ }
6898
7255
  switch (d.value) {
6899
7256
  // The four behavioural categories are flat on the wire (WIRE_FORMAT §3.2):
6900
7257
  // the `kind` object carries the primitive discriminator directly, so route
@@ -6924,6 +7281,7 @@ var decodeNodeKind = (path, j) => {
6924
7281
  case "Fact":
6925
7282
  case "Link":
6926
7283
  case "Image":
7284
+ case "Media":
6927
7285
  case "List":
6928
7286
  case "Toast":
6929
7287
  case "CodeBlock":
@@ -7199,10 +7557,54 @@ var decodeSemanticStyle = (path, j) => {
7199
7557
  voice: voice.value ?? "Default"
7200
7558
  });
7201
7559
  };
7560
+ var A11Y_NEAR_MISSES = [
7561
+ [
7562
+ "aria-label",
7563
+ "label \u2014 the accessible name, a Binding<string> (a bare string is the \xA73.6 shorthand)"
7564
+ ],
7565
+ [
7566
+ "ariaLabel",
7567
+ "label \u2014 the accessible name, a Binding<string> (a bare string is the \xA73.6 shorthand)"
7568
+ ],
7569
+ ["aria-labelledby", "labelledBy \u2014 the id of a sibling node whose text carries the name"],
7570
+ ["ariaLabelledBy", "labelledBy \u2014 the id of a sibling node whose text carries the name"],
7571
+ [
7572
+ "labelledby",
7573
+ "labelledBy \u2014 the slot name is camelCase on the wire, not the ARIA attribute spelling"
7574
+ ],
7575
+ ["aria-describedby", "describedBy \u2014 the id of a sibling node whose text carries the description"],
7576
+ ["ariaDescribedBy", "describedBy \u2014 the id of a sibling node whose text carries the description"],
7577
+ [
7578
+ "describedby",
7579
+ "describedBy \u2014 the slot name is camelCase on the wire, not the ARIA attribute spelling"
7580
+ ],
7581
+ ["aria-role", "role \u2014 the ARIA role NAME as a bare string"],
7582
+ ["ariaRole", "role \u2014 the ARIA role NAME as a bare string"],
7583
+ ["aria-live", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
7584
+ ["ariaLive", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
7585
+ ["live", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
7586
+ ["liveregion", 'liveRegion \u2014 the closed token set "polite" / "assertive" / "off"'],
7587
+ ["aria-hidden", "hidden \u2014 a Binding<bool> (a bare bool is the \xA73.6 shorthand)"],
7588
+ ["ariaHidden", "hidden \u2014 a Binding<bool> (a bare bool is the \xA73.6 shorthand)"]
7589
+ ];
7590
+ var checkA11yNearMisses = (path, f) => {
7591
+ for (const [name, canonical] of A11Y_NEAR_MISSES) {
7592
+ if (tryField(f, name) !== void 0)
7593
+ return makeError(
7594
+ "WRONG_TYPE",
7595
+ `${path}.${name}`,
7596
+ `'${name}' is not part of the accessibility vocabulary \u2014 it would be ignored, not honoured, and the intent would reach assistive technology as nothing at all`,
7597
+ canonical
7598
+ );
7599
+ }
7600
+ return ok(void 0);
7601
+ };
7202
7602
  var decodeAccessibility = (path, j) => {
7203
7603
  const fo = requireObject(path, j);
7204
7604
  if (!fo.ok) return fo;
7205
7605
  const f = fo.value;
7606
+ const nearMiss2 = checkA11yNearMisses(path, f);
7607
+ if (!nearMiss2.ok) return nearMiss2;
7206
7608
  const label = optField(path, f, "label", decodeBindingString);
7207
7609
  if (!label.ok) return label;
7208
7610
  const labelledBy = optField(path, f, "labelledBy", requireString);
@@ -7247,7 +7649,39 @@ var placeholderClosureNode = {
7247
7649
  voice: "Default"
7248
7650
  }
7249
7651
  };
7652
+ var walkDepth = 0;
7653
+ var walkNodes = 0;
7654
+ var opDepth = 0;
7655
+ var walkPolicy = schema.admitAll;
7656
+ var resetWalk = (policy = schema.admitAll) => {
7657
+ walkDepth = 0;
7658
+ walkNodes = 0;
7659
+ opDepth = 0;
7660
+ walkPolicy = policy;
7661
+ };
7662
+ var limitError = (path, message, expected) => makeError("LIMIT_EXCEEDED", path, message, expected);
7250
7663
  var decodeNodeAst = (path, j) => {
7664
+ if (walkDepth >= schema.MAX_NODE_DEPTH) {
7665
+ return limitError(
7666
+ path,
7667
+ `node nesting deeper than the wire limit MAX_NODE_DEPTH = ${schema.MAX_NODE_DEPTH}`,
7668
+ `a tree nesting nodes no more than ${schema.MAX_NODE_DEPTH} levels deep`
7669
+ );
7670
+ }
7671
+ walkNodes += 1;
7672
+ if (walkNodes > schema.MAX_NODES) {
7673
+ return limitError(
7674
+ path,
7675
+ `the document holds more than the wire limit MAX_NODES = ${schema.MAX_NODES} nodes`,
7676
+ `a tree of no more than ${schema.MAX_NODES} nodes in total`
7677
+ );
7678
+ }
7679
+ walkDepth += 1;
7680
+ const r = decodeNodeAstInner(path, j);
7681
+ walkDepth -= 1;
7682
+ return r;
7683
+ };
7684
+ var decodeNodeAstInner = (path, j) => {
7251
7685
  const fo = requireObject(path, j);
7252
7686
  if (!fo.ok) return fo;
7253
7687
  const f = fo.value;
@@ -7275,6 +7709,25 @@ var decodeNodeAst = (path, j) => {
7275
7709
  });
7276
7710
  };
7277
7711
  var decodeTreeOpAst = (path, j) => {
7712
+ if (opDepth >= schema.MAX_NODE_DEPTH) {
7713
+ return limitError(
7714
+ path,
7715
+ `op nesting deeper than the wire limit MAX_NODE_DEPTH = ${schema.MAX_NODE_DEPTH}`,
7716
+ `a Batch nesting ops no more than ${schema.MAX_NODE_DEPTH} levels deep`
7717
+ );
7718
+ }
7719
+ opDepth += 1;
7720
+ const r = decodeTreeOpAstInner(path, j);
7721
+ opDepth -= 1;
7722
+ return r;
7723
+ };
7724
+ var retiredPositionalField = (path, f, name, opKind) => tryField(f, name) !== void 0 ? makeError(
7725
+ "WRONG_TYPE",
7726
+ `${path}.${name}`,
7727
+ `'${name}' was removed from the wire format \u2014 ${opKind} appends, and order is stated by naming ids with ReorderChildren`,
7728
+ "a Batch of the structural op followed by ReorderChildren"
7729
+ ) : ok(void 0);
7730
+ var decodeTreeOpAstInner = (path, j) => {
7278
7731
  const fo = requireObject(path, j);
7279
7732
  if (!fo.ok) return fo;
7280
7733
  const f = fo.value;
@@ -7327,6 +7780,8 @@ var decodeTreeOpAst = (path, j) => {
7327
7780
  return state.ok ? ok({ kind: "UpdateState", target: t.value, state: state.value }) : state;
7328
7781
  }
7329
7782
  case "InsertChild": {
7783
+ const retired = retiredPositionalField(path, f, "position", "InsertChild");
7784
+ if (!retired.ok) return retired;
7330
7785
  const parentJ = reqField(path, f, "parentId", "parent NodeId", requireString);
7331
7786
  if (!parentJ.ok) return parentJ;
7332
7787
  const child = reqField(path, f, "child", "child Node object", decodeNodeAst);
@@ -7341,6 +7796,8 @@ var decodeTreeOpAst = (path, j) => {
7341
7796
  return t.ok ? ok({ kind: "RemoveNode", target: t.value }) : t;
7342
7797
  }
7343
7798
  case "MoveNode": {
7799
+ const retired = retiredPositionalField(path, f, "newPosition", "MoveNode");
7800
+ if (!retired.ok) return retired;
7344
7801
  const t = target();
7345
7802
  if (!t.ok) return t;
7346
7803
  const newParent = reqField(path, f, "newParentId", "new parent NodeId", requireString);
@@ -7422,6 +7879,8 @@ var coerce = {
7422
7879
  tone: (v) => viaAst(v, decodeTone),
7423
7880
  weight: (v) => viaAst(v, decodeWeight),
7424
7881
  emphasis: (v) => viaAst(v, decodeEmphasis),
7882
+ /** `Metric.TrendPolarity` (Phase 867) - the UpdateProp twin of `decodeTrendPolarity`. */
7883
+ trendPolarity: (v) => viaAst(v, decodeTrendPolarity),
7425
7884
  /**
7426
7885
  * The behavioural `emphasis` BOOL on Fact / LabelValueRow — the UpdateProp
7427
7886
  * twin of `decodeEmphasisFlag`, so a TreeOp edit gets the same
@@ -7442,13 +7901,18 @@ var invalidJson = (parseMessage) => makeError(
7442
7901
  `input is not valid JSON: ${parseMessage}`,
7443
7902
  "well-formed JSON object per the canonical-JSON shape"
7444
7903
  );
7445
- var decodeNode = (json) => {
7904
+ var parseFailure = (e) => e.limit === true ? makeError("LIMIT_EXCEEDED", "$", e.message, "a document within the WIRE_FORMAT \xA721 limits") : invalidJson(e.message);
7905
+ var decodeNode = (json, policy) => {
7446
7906
  const parsed = parse(json);
7447
- return parsed.ok ? decodeNodeAst("$", parsed.value) : invalidJson(parsed.error.message);
7907
+ if (!parsed.ok) return parseFailure(parsed.error);
7908
+ resetWalk(policy);
7909
+ return decodeNodeAst("$", parsed.value);
7448
7910
  };
7449
- var decodeOp = (json) => {
7911
+ var decodeOp = (json, policy) => {
7450
7912
  const parsed = parse(json);
7451
- return parsed.ok ? decodeTreeOpAst("$", parsed.value) : invalidJson(parsed.error.message);
7913
+ if (!parsed.ok) return parseFailure(parsed.error);
7914
+ resetWalk(policy);
7915
+ return decodeTreeOpAst("$", parsed.value);
7452
7916
  };
7453
7917
 
7454
7918
  // src/apply.ts
@@ -7615,6 +8079,11 @@ var updateField = (field2, value, kind) => {
7615
8079
  coerce.cellFormat(value),
7616
8080
  (x) => disp({ kind: "Metric", spec: { ...s, trendFormat: x } })
7617
8081
  );
8082
+ case "TrendPolarity":
8083
+ return patch(
8084
+ coerce.trendPolarity(value),
8085
+ (x) => disp({ kind: "Metric", spec: { ...s, trendPolarity: x } })
8086
+ );
7618
8087
  case "Icon":
7619
8088
  return patch(
7620
8089
  coerce.iconSource(value),
@@ -7898,6 +8367,12 @@ var updateField = (field2, value, kind) => {
7898
8367
  (x) => lay({ kind: "Box", spec: { ...s, layout: { ...mode, cols: x } } })
7899
8368
  );
7900
8369
  }
8370
+ if (field2 === "Cols" && mode.kind === "Masonry") {
8371
+ return patch(
8372
+ coerce.int(value),
8373
+ (x) => lay({ kind: "Box", spec: { ...s, layout: { ...mode, cols: x } } })
8374
+ );
8375
+ }
7901
8376
  if (field2 === "TemplateColumns" && mode.kind === "Grid") {
7902
8377
  return patch(
7903
8378
  coerce.string(value),
@@ -9762,9 +10237,64 @@ var validateAnswerDocument = (json) => {
9762
10237
  if (!answer.ok) return answer;
9763
10238
  return validateAnswerAt("$.answer", contract.value, answer.value);
9764
10239
  };
10240
+ var HOST_RESERVED_PREFIX = "host.";
10241
+ var isHostReserved = (key) => typeof key === "string" && key.startsWith(HOST_RESERVED_PREFIX);
10242
+ var isPlainObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
10243
+ var isStateDeclaration = (v) => isPlainObject(v) && v["kind"] === "State" && typeof v["key"] === "string" && "defaultValue" in v && v["defaultValue"] !== void 0;
10244
+ var controlDefaults = Object.values(schema.controlValueDefaults);
10245
+ var deepEqual = (a, b) => {
10246
+ try {
10247
+ return JSON.stringify(a) === JSON.stringify(b);
10248
+ } catch {
10249
+ return false;
10250
+ }
10251
+ };
10252
+ var isAutoBoundFieldValue = (binding2, fieldId) => binding2.key === fieldId && controlDefaults.some((d) => deepEqual(d, binding2.defaultValue));
10253
+ var isEmptyDeclaration = (value) => {
10254
+ if (Array.isArray(value)) return value.length === 0;
10255
+ if (isPlainObject(value)) {
10256
+ const columns = value["columns"];
10257
+ if (isPlainObject(columns)) return Object.keys(columns).length === 0;
10258
+ }
10259
+ return false;
10260
+ };
10261
+ var collectStateSeeds = (tree) => {
10262
+ const seeds = {};
10263
+ const seen = /* @__PURE__ */ new Set();
10264
+ const visit = (value, autoBindFieldId) => {
10265
+ if (value === null || typeof value !== "object") return;
10266
+ if (seen.has(value)) return;
10267
+ seen.add(value);
10268
+ if (Array.isArray(value)) {
10269
+ for (const item of value) visit(item, autoBindFieldId);
10270
+ return;
10271
+ }
10272
+ const obj = value;
10273
+ if (isStateDeclaration(obj)) {
10274
+ const key = obj.key;
10275
+ const shouldSkip = isHostReserved(key) || Object.prototype.hasOwnProperty.call(seeds, key) || isEmptyDeclaration(obj.defaultValue) || autoBindFieldId !== void 0 && isAutoBoundFieldValue(obj, autoBindFieldId);
10276
+ if (!shouldSkip) seeds[key] = obj.defaultValue;
10277
+ }
10278
+ const record = obj;
10279
+ const ownId = record["id"];
10280
+ const fieldId = typeof ownId === "string" && typeof record["required"] === "boolean" ? ownId : void 0;
10281
+ for (const [k, v] of Object.entries(obj)) {
10282
+ const established = k === "kind" && fieldId !== void 0 ? fieldId : void 0;
10283
+ visit(v, established ?? autoBindFieldId);
10284
+ }
10285
+ };
10286
+ visit(tree, void 0);
10287
+ return seeds;
10288
+ };
10289
+ var withStateSeeds = (tree, sources) => {
10290
+ const seeds = collectStateSeeds(tree);
10291
+ if (Object.keys(seeds).length === 0) return sources;
10292
+ return { ...sources, state: { ...seeds, ...sources.state ?? {} } };
10293
+ };
9765
10294
 
9766
10295
  exports.ELICITATION_KEY = ELICITATION_KEY;
9767
10296
  exports.ELICITATION_VERSION = ELICITATION_VERSION;
10297
+ exports.HOST_RESERVED_PREFIX = HOST_RESERVED_PREFIX;
9768
10298
  exports.PAYLOAD_KEY = PAYLOAD_KEY;
9769
10299
  exports.PROFILE_KEY = PROFILE_KEY;
9770
10300
  exports.REQUIRED_PROFILE_KEY = REQUIRED_PROFILE_KEY;
@@ -9772,6 +10302,7 @@ exports.apply = apply;
9772
10302
  exports.canPlace = canPlace;
9773
10303
  exports.cellString = cellString;
9774
10304
  exports.coerce = coerce;
10305
+ exports.collectStateSeeds = collectStateSeeds;
9775
10306
  exports.coreV1 = coreV1;
9776
10307
  exports.decodeDagRecord = decodeDagRecord;
9777
10308
  exports.decodeElicitation = decodeElicitation;
@@ -9823,5 +10354,6 @@ exports.tryParseProfile = tryParseProfile;
9823
10354
  exports.validateAnswer = validateAnswer;
9824
10355
  exports.validateAnswerAt = validateAnswerAt;
9825
10356
  exports.validateAnswerDocument = validateAnswerDocument;
10357
+ exports.withStateSeeds = withStateSeeds;
9826
10358
  //# sourceMappingURL=index.cjs.map
9827
10359
  //# sourceMappingURL=index.cjs.map