@wcstack/state 1.9.1 → 1.10.3

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/auto.js CHANGED
@@ -1,3 +1,3 @@
1
- import { bootstrapState } from "./index.esm.js";
2
-
3
- await bootstrapState();
1
+ import { bootstrapState } from "./index.esm.js";
2
+
3
+ await bootstrapState();
package/dist/auto.min.js CHANGED
@@ -1,3 +1,3 @@
1
- import { bootstrapState } from "./index.esm.min.js";
2
-
3
- await bootstrapState();
1
+ import { bootstrapState } from "./index.esm.min.js";
2
+
3
+ await bootstrapState();
package/dist/index.esm.js CHANGED
@@ -59,7 +59,7 @@ function setConfig(partialConfig) {
59
59
  }
60
60
  }
61
61
 
62
- var version$1 = "1.9.1";
62
+ var version$1 = "1.10.3";
63
63
  var pkg = {
64
64
  version: version$1};
65
65
 
@@ -2080,7 +2080,7 @@ function applyChangeToCommand(binding, _context, newValue) {
2080
2080
  if (bindable === null) {
2081
2081
  raiseError(`command binding requires a wc-bindable custom element. <${element.tagName.toLowerCase()}> is not wc-bindable.`);
2082
2082
  }
2083
- if (!Array.isArray(bindable.commands) || !bindable.commands.includes(methodName)) {
2083
+ if (!Array.isArray(bindable.commands) || !bindable.commands.some((c) => c.name === methodName)) {
2084
2084
  raiseError(`Command "${methodName}" is not declared in wcBindable.commands of <${element.tagName.toLowerCase()}>.`);
2085
2085
  }
2086
2086
  // ここまで来たら旧解除して新 subscribe に切り替える。
@@ -2975,6 +2975,65 @@ function applyChangeToIf(bindingInfo, context, rawNewValue) {
2975
2975
  }
2976
2976
  }
2977
2977
 
2978
+ /**
2979
+ * 要素 `element` の `propName` プロパティ書き込みに対して、
2980
+ * wc-bindable inputs の `attribute` ミラー先属性名を返す。
2981
+ *
2982
+ * - wc-bindable でないネイティブ要素や、inputs 未宣言、attribute フィールド無しは null
2983
+ * - inputs に同名宣言があっても `attribute` を持たないものはミラー対象外
2984
+ *
2985
+ * 戻り値の string がそのまま `setAttribute(name, value)` の name となる。
2986
+ */
2987
+ function getInputAttributeMirror(element, propName) {
2988
+ const customTagName = getCustomElement(element);
2989
+ if (customTagName === null) {
2990
+ return null;
2991
+ }
2992
+ const customClass = customElements.get(customTagName);
2993
+ if (typeof customClass === "undefined") {
2994
+ return null;
2995
+ }
2996
+ const bindable = customClass.wcBindable;
2997
+ if (bindable?.protocol !== "wc-bindable" || bindable?.version !== 1) {
2998
+ return null;
2999
+ }
3000
+ const inputs = bindable.inputs;
3001
+ if (!Array.isArray(inputs)) {
3002
+ return null;
3003
+ }
3004
+ for (const input of inputs) {
3005
+ if (input.name === propName && typeof input.attribute === "string" && input.attribute.length > 0) {
3006
+ return input.attribute;
3007
+ }
3008
+ }
3009
+ return null;
3010
+ }
3011
+ /**
3012
+ * mirror 属性値の表現を決める。
3013
+ * - null / undefined → 属性削除
3014
+ * - object / array → JSON.stringify (失敗時は String(value))
3015
+ * - その他 (string / number / boolean / bigint) → String(value)
3016
+ */
3017
+ function applyMirrorAttribute(element, attributeName, value) {
3018
+ if (value === null || typeof value === "undefined") {
3019
+ element.removeAttribute(attributeName);
3020
+ return;
3021
+ }
3022
+ let formatted;
3023
+ if (typeof value === "object") {
3024
+ try {
3025
+ formatted = JSON.stringify(value);
3026
+ }
3027
+ catch {
3028
+ formatted = String(value);
3029
+ }
3030
+ }
3031
+ else {
3032
+ formatted = String(value);
3033
+ }
3034
+ element.setAttribute(attributeName, formatted);
3035
+ }
3036
+
2978
3037
  /**
2979
3038
  * SSR 時に HTML 属性で表現できないプロパティバインディングを蓄積するストア。
2980
3039
  * ハイドレーション時にクライアント側で復元する。
@@ -3057,8 +3116,10 @@ function applyChangeToProperty(binding, _context, newValue) {
3057
3116
  if (propSegments.length === 1) {
3058
3117
  const firstSegment = propSegments[0];
3059
3118
  if (element[firstSegment] !== newValue) {
3119
+ let propertyWriteSucceeded = false;
3060
3120
  try {
3061
3121
  element[firstSegment] = newValue;
3122
+ propertyWriteSucceeded = true;
3062
3123
  }
3063
3124
  catch (error) {
3064
3125
  if (config.debug) {
@@ -3069,6 +3130,27 @@ function applyChangeToProperty(binding, _context, newValue) {
3069
3130
  });
3070
3131
  }
3071
3132
  }
3133
+ // wc-bindable inputs[].attribute ミラー。プロパティ書き込みが成功したときだけ
3134
+ // 属性へ反映する。setter が値を拒否した場合に属性だけ進んでしまうと
3135
+ // property と attribute が乖離し、attributeChangedCallback や CSS セレクタが
3136
+ // 実際のプロパティ値と矛盾した状態で発火するため、ここでガードする。
3137
+ if (propertyWriteSucceeded) {
3138
+ const mirrorAttr = getInputAttributeMirror(element, firstSegment);
3139
+ if (mirrorAttr !== null) {
3140
+ try {
3141
+ applyMirrorAttribute(element, mirrorAttr, newValue);
3142
+ }
3143
+ catch (error) {
3144
+ if (config.debug) {
3145
+ console.warn(`Failed to mirror attribute '${mirrorAttr}' on element.`, {
3146
+ element,
3147
+ newValue,
3148
+ error
3149
+ });
3150
+ }
3151
+ }
3152
+ }
3153
+ }
3072
3154
  }
3073
3155
  if (inSsr()) {
3074
3156
  const attrHandler = SSR_ATTR_PROPS[firstSegment];