@wcstack/typescript 4.0.0-rc.4 → 4.0.0-rc.5

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.esm.js CHANGED
@@ -572,7 +572,7 @@ function loadSchemaCore() {
572
572
  return cached;
573
573
  }
574
574
 
575
- var version = "4.0.0-rc.4";
575
+ var version = "4.0.0-rc.5";
576
576
  var pkg = {
577
577
  version: version};
578
578
 
@@ -1377,10 +1377,11 @@ var SENTENCES = {
1377
1377
  1201
1378
1378
  /* CommandRightSide */
1379
1379
  ]: (prop, p) => `"${prop}: ${p}": the right-hand side must be $command.<name>`,
1380
+ // a native element's command (no hyphen: never a custom element) is the native-commands add-on's
1380
1381
  [
1381
1382
  1202
1382
1383
  /* NoBindable */
1383
- ]: (tag, what) => `<${tag}> declares no static wcBindable (${what}).`,
1384
+ ]: (tag, what) => `<${tag}> declares no static wcBindable (${what}).${!tag.includes("-") && what.startsWith("command.") ? " A native element's command needs the add-on @wcstack/state/features/native-commands." : ""}`,
1384
1385
  [
1385
1386
  1203
1386
1387
  /* NoCommand */
@@ -1389,6 +1390,10 @@ var SENTENCES = {
1389
1390
  1204
1390
1391
  /* NoProperty */
1391
1392
  ]: (tag, prop) => `<${tag}> declares no property "${prop}".`,
1393
+ [
1394
+ 1205
1395
+ /* NativeNoCommand */
1396
+ ]: (tag, method, allowed) => `<${tag}> has no command "${method}" (a native <${tag}>'s commands: ${allowed}).`,
1392
1397
  [
1393
1398
  1301
1394
1399
  /* EventTokenUndeclared */
@@ -2066,7 +2071,17 @@ var config = {
2066
2071
  locale: typeof document !== "undefined" ? document.documentElement?.lang || "en" : "en",
2067
2072
  enableContractAnalyzer: false
2068
2073
  };
2069
- var FEATURE_NAMES = ["formats", "diagnostics", "temporal", "list-keys", "scopes", "recursion", "ssr", "devtools"];
2074
+ var FEATURE_NAMES = ["formats", "diagnostics", "temporal", "list-keys", "scopes", "recursion", "ssr", "devtools", "native-commands"];
2075
+ var NATIVE_COMMANDS = {
2076
+ "*": ["focus", "blur", "click", "scrollIntoView", "showPopover", "hidePopover", "togglePopover"],
2077
+ "dialog": ["show", "showModal", "close", "requestClose"],
2078
+ "form": ["requestSubmit", "checkValidity", "reportValidity"],
2079
+ "input": ["select", "setSelectionRange", "showPicker", "setCustomValidity", "checkValidity", "reportValidity"],
2080
+ "textarea": ["select", "setSelectionRange", "setCustomValidity", "checkValidity", "reportValidity"],
2081
+ "select": ["showPicker", "setCustomValidity", "checkValidity", "reportValidity"],
2082
+ "audio": ["play", "pause", "load"],
2083
+ "video": ["play", "pause", "load"]
2084
+ };
2070
2085
  var WILDCARD2 = "*";
2071
2086
  function optionsRequired(fnName) {
2072
2087
  raise2(26, [fnName]);
@@ -2578,10 +2593,18 @@ function getWcsManifest() {
2578
2593
  ],
2579
2594
  // every option is a boolean, true when left out (engine.ts `loadTarget`: `typeof … === "boolean"`, `?? true`)
2580
2595
  behaviorOptions: Object.fromEntries(BEHAVIOR_OPTION_KEYS.map((key) => [key, { type: "boolean", default: true }])),
2581
- features: [...FEATURE_NAMES]
2596
+ features: [...FEATURE_NAMES],
2597
+ nativeCommands: Object.fromEntries(Object.entries(NATIVE_COMMANDS).map(([tag, methods]) => [tag, [...methods]]))
2582
2598
  };
2583
2599
  }
2584
2600
 
2601
+ // src/service/wcsManifest.ts
2602
+ var NATIVE_COMMANDS2 = getWcsManifest().nativeCommands ?? null;
2603
+ function nativeCommandsOf(tag) {
2604
+ if (NATIVE_COMMANDS2 === null) return null;
2605
+ return [...NATIVE_COMMANDS2["*"] ?? [], ...Object.hasOwn(NATIVE_COMMANDS2, tag) ? NATIVE_COMMANDS2[tag] : []];
2606
+ }
2607
+
2585
2608
  // src/service/completionData.ts
2586
2609
  var BUILTIN_FILTERS = Object.entries(builtinFilterMeta).map(
2587
2610
  ([name, meta]) => ({ name, ...meta })
@@ -2597,6 +2620,41 @@ var STRUCTURAL_DIRECTIVES = [...STRUCTURAL_BINDING_TYPE_SET2].map((name) => ({
2597
2620
  ...STRUCTURAL_DIRECTIVE_INFO[name]
2598
2621
  }));
2599
2622
 
2623
+ // src/service/suggestion.ts
2624
+ function suggestion(input, candidates, msgs) {
2625
+ let best = null;
2626
+ let bestDistance = 3;
2627
+ for (const c of candidates) {
2628
+ const d = editDistance2(input.toLowerCase(), c.toLowerCase(), bestDistance);
2629
+ if (d < bestDistance) {
2630
+ best = c;
2631
+ bestDistance = d;
2632
+ }
2633
+ }
2634
+ return best !== null ? msgs.didYouMean(best) : "";
2635
+ }
2636
+ function editDistance2(a, b, bound) {
2637
+ if (Math.abs(a.length - b.length) >= bound) return bound;
2638
+ const prev = new Array(b.length + 1);
2639
+ const curr = new Array(b.length + 1);
2640
+ for (let j = 0; j <= b.length; j++) prev[j] = j;
2641
+ for (let i = 1; i <= a.length; i++) {
2642
+ curr[0] = i;
2643
+ let rowMin = curr[0];
2644
+ for (let j = 1; j <= b.length; j++) {
2645
+ curr[j] = Math.min(
2646
+ prev[j] + 1,
2647
+ curr[j - 1] + 1,
2648
+ prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
2649
+ );
2650
+ if (curr[j] < rowMin) rowMin = curr[j];
2651
+ }
2652
+ if (rowMin >= bound) return bound;
2653
+ for (let j = 0; j <= b.length; j++) prev[j] = curr[j];
2654
+ }
2655
+ return Math.min(prev[b.length], bound);
2656
+ }
2657
+
2600
2658
  // src/service/recursionPaths.ts
2601
2659
  var RECURSION_WILDCARD2 = "**";
2602
2660
  var RECURSION_KEY = "$recursion";
@@ -10324,6 +10382,7 @@ var ja = {
10324
10382
  featuresAttrNotRoot: () => `features \u5C5E\u6027\u3092\u8AAD\u3080\u306E\u306F\u6587\u66F8\u306E root \u306E <wcs-state>\uFF08mount \u3068 bind-component \u3092\u6301\u305F\u306A\u3044\u6700\u521D\u306E\u3082\u306E\uFF09\u3060\u3051\u3067\u3059\u3002\u3053\u306E\u8981\u7D20\u306E features \u306F\u7121\u8996\u3055\u308C\u307E\u3059 \u2014 root \u306E <wcs-state> \u306B\u66F8\u3044\u3066\u304F\u3060\u3055\u3044`,
10325
10383
  onPrefixedMember: (member, tag, modifiers) => `"${member}" \u306F <${tag}> \u306E\u30E1\u30F3\u30D0\u30FC\u3067\u3059\u304C\u3001"on" \u3067\u59CB\u307E\u308B\u540D\u524D\u306F\u30A4\u30D9\u30F3\u30C8\u675F\u7E1B\u306B\u306A\u308A\uFF08"${member.slice(2)}" \u30A4\u30D9\u30F3\u30C8\u3092\u5F85\u3064\uFF09\u3001\u5024\u306F\u5C4A\u304D\u307E\u305B\u3093\u3002\u30D7\u30ED\u30D1\u30C6\u30A3\u3068\u3057\u3066\u675F\u7E1B\u3059\u308B\u306B\u306F ".${member}${modifiers ? `#${modifiers}` : ""}:" \u3068\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF08@wcstack/state 3.1\uFF09`,
10326
10384
  tagCommandUnknown: (name, tag, declared) => `"${name}" \u306F <${tag}> \u306E command \u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u5BA3\u8A00\u6E08\u307F: ${declared}\uFF09`,
10385
+ nativeCommandUnknown: (method, tag, allowed) => `"${method}" \u306F\u30CD\u30A4\u30C6\u30A3\u30D6\u306E <${tag}> \u306B command \u3067\u547C\u3079\u308B\u30E1\u30BD\u30C3\u30C9\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08\u547C\u3079\u308B\u306E\u306F ${allowed}\u3002\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u521D\u671F\u5316\u3067 wcs/token-misconfigured \u3092\u6295\u3052\u307E\u3059\uFF09`,
10327
10386
  spreadNoBindable: (tag) => `'...'\uFF08spread\uFF09\u306F <${tag}> \u306B\u6709\u52B9\u306A wcBindable \u5BA3\u8A00\u304C\u5FC5\u8981\u3067\u3059 \u2014 \u3053\u306E\u30BF\u30B0\u306F\u5BA3\u8A00\u3092\u6301\u305F\u306A\u3044\u305F\u3081\u3001\u30E9\u30F3\u30BF\u30A4\u30E0\u306F\u30A8\u30E9\u30FC\u3092\u9001\u51FA\u3057\u307E\u3059`,
10328
10387
  tagEventTokenKeyUnknown: (name, tag, declared) => `eventToken \u306E\u30AD\u30FC "${name}" \u306F <${tag}> \u306E wcBindable \u30D7\u30ED\u30D1\u30C6\u30A3\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u751F DOM \u30A4\u30D9\u30F3\u30C8\u540D\u306F\u767A\u706B\u3057\u307E\u305B\u3093 \u2014 \u30D7\u30ED\u30D1\u30C6\u30A3\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5BA3\u8A00\u6E08\u307F: ${declared}\uFF09`,
10329
10388
  ariaAttrUnknown: (name) => `"${name}" \u306F WAI-ARIA \u306E\u5C5E\u6027\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002setAttribute \u306F\u305D\u306E\u307E\u307E\u66F8\u304D\u8FBC\u307F\u307E\u3059\u304C\u3001\u652F\u63F4\u6280\u8853\u306B\u306F\u9ED9\u3063\u3066\u7121\u8996\u3055\u308C\u307E\u3059`,
@@ -10509,6 +10568,7 @@ var en = {
10509
10568
  featuresAttrNotRoot: () => `The features attribute is read only on the document's root <wcs-state> (the first one without mount and bind-component); it is ignored here \u2014 put it on the root <wcs-state>`,
10510
10569
  onPrefixedMember: (member, tag, modifiers) => `"${member}" is a member of <${tag}>, but a name starting with "on" makes an event binding (it listens for a "${member.slice(2)}" event) and the value never arrives. Write ".${member}${modifiers ? `#${modifiers}` : ""}:" to bind the property (@wcstack/state 3.1)`,
10511
10570
  tagCommandUnknown: (name, tag, declared) => `"${name}" is not a command of <${tag}> (declared: ${declared})`,
10571
+ nativeCommandUnknown: (method, tag, allowed) => `"${method}" is not a command of a native <${tag}> (its commands: ${allowed}; the runtime throws wcs/token-misconfigured at initialization)`,
10512
10572
  spreadNoBindable: (tag) => `'...' (spread) requires <${tag}> to expose a valid wcBindable declaration \u2014 this tag declares none, so the runtime raises an error`,
10513
10573
  tagEventTokenKeyUnknown: (name, tag, declared) => `eventToken key "${name}" is not a wcBindable property of <${tag}>. Raw DOM event names never fire \u2014 use the property name (declared: ${declared})`,
10514
10574
  ariaAttrUnknown: (name) => `"${name}" is not a WAI-ARIA attribute. setAttribute writes it anyway, and assistive technology silently ignores it`,
@@ -10899,6 +10959,18 @@ function validateBindings(html, attrName, stateTagName = "wcs-state", locale2, f
10899
10959
  scopedPaths.filter((p) => p.kind === "command").map((p) => p.path)
10900
10960
  );
10901
10961
  if (propNoMod.startsWith("command.")) {
10962
+ const allowed = attr.tagName !== void 0 && !attr.tagName.includes("-") ? nativeCommandsOf(attr.tagName) : null;
10963
+ const method = propNoMod.slice("command.".length);
10964
+ if (allowed !== null && !allowed.includes(method)) {
10965
+ const methodStart = bindingStart + binding.indexOf("command.") + "command.".length;
10966
+ diagnostics.push({
10967
+ code: WcsDiagnosticCode.TokenMisconfigured,
10968
+ start: methodStart,
10969
+ end: methodStart + method.length,
10970
+ message: msgs.nativeCommandUnknown(method, attr.tagName, allowed.join(", ")) + suggestion(method, allowed, msgs),
10971
+ severity: "error"
10972
+ });
10973
+ }
10902
10974
  const tokenPath = parsed.path?.trim() ?? "";
10903
10975
  if (tokenPath) {
10904
10976
  const pathOffset = binding.indexOf(parsed.path);
@@ -13509,39 +13581,6 @@ function normalizeSeed(raw) {
13509
13581
  const compact = raw.replace(/\s+/g, "");
13510
13582
  return compact === "" ? raw : compact;
13511
13583
  }
13512
- function suggestion(input, candidates, msgs) {
13513
- let best = null;
13514
- let bestDistance = 3;
13515
- for (const c of candidates) {
13516
- const d = editDistance2(input.toLowerCase(), c.toLowerCase(), bestDistance);
13517
- if (d < bestDistance) {
13518
- best = c;
13519
- bestDistance = d;
13520
- }
13521
- }
13522
- return best !== null ? msgs.didYouMean(best) : "";
13523
- }
13524
- function editDistance2(a, b, bound) {
13525
- if (Math.abs(a.length - b.length) >= bound) return bound;
13526
- const prev = new Array(b.length + 1);
13527
- const curr = new Array(b.length + 1);
13528
- for (let j = 0; j <= b.length; j++) prev[j] = j;
13529
- for (let i = 1; i <= a.length; i++) {
13530
- curr[0] = i;
13531
- let rowMin = curr[0];
13532
- for (let j = 1; j <= b.length; j++) {
13533
- curr[j] = Math.min(
13534
- prev[j] + 1,
13535
- curr[j - 1] + 1,
13536
- prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
13537
- );
13538
- if (curr[j] < rowMin) rowMin = curr[j];
13539
- }
13540
- if (rowMin >= bound) return bound;
13541
- for (let j = 0; j <= b.length; j++) prev[j] = curr[j];
13542
- }
13543
- return Math.min(prev[b.length], bound);
13544
- }
13545
13584
  function findBuiltinTagOccurrences(html) {
13546
13585
  const out = [];
13547
13586
  const regex = /<(wcs-[a-z0-9-]+)((?:"[^"]*"|'[^']*'|[^>"'])*)>/gi;
package/dist/tsc-core.cjs CHANGED
@@ -237,7 +237,17 @@ var config = {
237
237
  locale: typeof document !== "undefined" ? document.documentElement?.lang || "en" : "en",
238
238
  enableContractAnalyzer: false
239
239
  };
240
- var FEATURE_NAMES = ["formats", "diagnostics", "temporal", "list-keys", "scopes", "recursion", "ssr", "devtools"];
240
+ var FEATURE_NAMES = ["formats", "diagnostics", "temporal", "list-keys", "scopes", "recursion", "ssr", "devtools", "native-commands"];
241
+ var NATIVE_COMMANDS = {
242
+ "*": ["focus", "blur", "click", "scrollIntoView", "showPopover", "hidePopover", "togglePopover"],
243
+ "dialog": ["show", "showModal", "close", "requestClose"],
244
+ "form": ["requestSubmit", "checkValidity", "reportValidity"],
245
+ "input": ["select", "setSelectionRange", "showPicker", "setCustomValidity", "checkValidity", "reportValidity"],
246
+ "textarea": ["select", "setSelectionRange", "setCustomValidity", "checkValidity", "reportValidity"],
247
+ "select": ["showPicker", "setCustomValidity", "checkValidity", "reportValidity"],
248
+ "audio": ["play", "pause", "load"],
249
+ "video": ["play", "pause", "load"]
250
+ };
241
251
  var WILDCARD = "*";
242
252
  function optionsRequired(fnName) {
243
253
  raise(26, [fnName]);
@@ -749,10 +759,14 @@ function getWcsManifest() {
749
759
  ],
750
760
  // every option is a boolean, true when left out (engine.ts `loadTarget`: `typeof … === "boolean"`, `?? true`)
751
761
  behaviorOptions: Object.fromEntries(BEHAVIOR_OPTION_KEYS.map((key) => [key, { type: "boolean", default: true }])),
752
- features: [...FEATURE_NAMES]
762
+ features: [...FEATURE_NAMES],
763
+ nativeCommands: Object.fromEntries(Object.entries(NATIVE_COMMANDS).map(([tag, methods]) => [tag, [...methods]]))
753
764
  };
754
765
  }
755
766
 
767
+ // src/service/wcsManifest.ts
768
+ var NATIVE_COMMANDS2 = getWcsManifest().nativeCommands ?? null;
769
+
756
770
  // src/language/preamble.ts
757
771
  var manifest = getWcsManifest();
758
772
  var BEHAVIOR_TYPE = `{ ${Object.entries(manifest.behaviorOptions).map(([key, option]) => `${key}?: ${option.type}`).join("; ")} }`;
@@ -573,7 +573,7 @@ function loadSchemaCore() {
573
573
  return cached;
574
574
  }
575
575
 
576
- var version = "4.0.0-rc.4";
576
+ var version = "4.0.0-rc.5";
577
577
  var pkg = {
578
578
  version: version};
579
579
 
package/dist/wcs-tsc.mjs CHANGED
@@ -5,7 +5,7 @@ import { tmpdir } from 'node:os';
5
5
  import { dirname, join, isAbsolute, resolve, basename } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
- var version = "4.0.0-rc.4";
8
+ var version = "4.0.0-rc.5";
9
9
  var pkg = {
10
10
  version: version};
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/typescript",
3
- "version": "4.0.0-rc.4",
3
+ "version": "4.0.0-rc.5",
4
4
  "description": "TypeScript tooling for wcstack apps: wcs-schema generates the sidecar stateSchema from a typed state file, so wcs-validate checks data-wcs paths against real types in CI and every editor.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",