@wcstack/state 2.6.1 → 3.1.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 (66) hide show
  1. package/README.ja.md +112 -45
  2. package/README.md +114 -45
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/define.d.ts +295 -0
  6. package/dist/define.js +1 -0
  7. package/dist/index.d.ts +254 -94
  8. package/dist/index.esm.js +1 -23477
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/manifest.d.ts +2 -0
  11. package/dist/manifest.esm.js +22 -37
  12. package/dist/parser.d.ts +37 -39
  13. package/dist/parser.esm.js +172 -1153
  14. package/dist/split/chunks/binder.js +2 -0
  15. package/dist/split/chunks/binder.js.map +1 -0
  16. package/dist/split/chunks/checkDependency.js +2 -0
  17. package/dist/split/chunks/checkDependency.js.map +1 -0
  18. package/dist/split/chunks/diagnosticsHooks.js +2 -0
  19. package/dist/split/chunks/diagnosticsHooks.js.map +1 -0
  20. package/dist/split/chunks/errorGuidance.js +2 -0
  21. package/dist/split/chunks/errorGuidance.js.map +1 -0
  22. package/dist/split/chunks/features.d.ts +29 -0
  23. package/dist/split/chunks/filterRegistry.js +2 -0
  24. package/dist/split/chunks/filterRegistry.js.map +1 -0
  25. package/dist/split/chunks/getAllPropertyDescriptors.js +2 -0
  26. package/dist/split/chunks/getAllPropertyDescriptors.js.map +1 -0
  27. package/dist/split/chunks/lifecycleHooks.js +2 -0
  28. package/dist/split/chunks/lifecycleHooks.js.map +1 -0
  29. package/dist/split/chunks/mount.js +2 -0
  30. package/dist/split/chunks/mount.js.map +1 -0
  31. package/dist/split/chunks/pathDiagnostics.js +2 -0
  32. package/dist/split/chunks/pathDiagnostics.js.map +1 -0
  33. package/dist/split/chunks/registerComponents.js +2 -0
  34. package/dist/split/chunks/registerComponents.js.map +1 -0
  35. package/dist/split/chunks/setAll.js +2 -0
  36. package/dist/split/chunks/setAll.js.map +1 -0
  37. package/dist/split/chunks/version.js +2 -0
  38. package/dist/split/chunks/version.js.map +1 -0
  39. package/dist/split/chunks/watchRuntime.js +2 -0
  40. package/dist/split/chunks/watchRuntime.js.map +1 -0
  41. package/dist/split/core.d.ts +1417 -0
  42. package/dist/split/core.js +2 -0
  43. package/dist/split/core.js.map +1 -0
  44. package/dist/split/features/devtools.d.ts +9 -0
  45. package/dist/split/features/devtools.js +2 -0
  46. package/dist/split/features/devtools.js.map +1 -0
  47. package/dist/split/features/diagnostics.d.ts +11 -0
  48. package/dist/split/features/diagnostics.js +2 -0
  49. package/dist/split/features/diagnostics.js.map +1 -0
  50. package/dist/split/features/formats.d.ts +10 -0
  51. package/dist/split/features/formats.js +2 -0
  52. package/dist/split/features/formats.js.map +1 -0
  53. package/dist/split/features/recursion.d.ts +9 -0
  54. package/dist/split/features/recursion.js +2 -0
  55. package/dist/split/features/recursion.js.map +1 -0
  56. package/dist/split/features/scopes.d.ts +10 -0
  57. package/dist/split/features/scopes.js +2 -0
  58. package/dist/split/features/scopes.js.map +1 -0
  59. package/dist/split/features/ssr.d.ts +9 -0
  60. package/dist/split/features/ssr.js +2 -0
  61. package/dist/split/features/ssr.js.map +1 -0
  62. package/dist/split/features/temporal.d.ts +9 -0
  63. package/dist/split/features/temporal.js +2 -0
  64. package/dist/split/features/temporal.js.map +1 -0
  65. package/dist/wcs-manifest.json +1 -0
  66. package/package.json +13 -1
@@ -83,6 +83,8 @@ interface IWcsManifest {
83
83
  elseKeyword: string;
84
84
  spread: string;
85
85
  eventPropertyPrefix: string;
86
+ /** 左辺の先頭に付けると、名前が `on` で始まってもイベントにしない明示のプロパティ形(`.online:`、要件 B5) */
87
+ explicitPropertyPrefix: string;
86
88
  propNamespaces: {
87
89
  eventToken: string;
88
90
  command: string;
@@ -81,16 +81,6 @@ function valueMustBeArray(fnName) {
81
81
  raiseError(`filter ${fnName} requires an array value`);
82
82
  }
83
83
 
84
- const warned = new Set();
85
- /** 同じ文面は 1 回だけ警告する(文面は書き方とサイトを含むので、書き方・サイトごとに 1 回) */
86
- function warnV3Migration(message) {
87
- if (warned.has(message)) {
88
- return;
89
- }
90
- warned.add(message);
91
- console.warn(`[@wcstack/state] [wcs/v3-migration] ${message} See "Preparing for 3.0" in the @wcstack/state README.`);
92
- }
93
-
94
84
  /**
95
85
  * builtinFilters.ts
96
86
  *
@@ -119,8 +109,10 @@ function validateNumberString(value) {
119
109
  * @param options - Array with comparison value as first element
120
110
  * @returns Filter function that returns boolean
121
111
  */
122
- const eq = (options) => {
112
+ const eq = (options, literals) => {
123
113
  const opt = options?.[0] ?? optionsRequired('eq');
114
+ // The typed literal (B9): unquoted true / false / null / numbers are typed, quoted arguments are strings
115
+ const literal = literals !== undefined && literals.length > 0 ? literals[0] : opt;
124
116
  return (value) => {
125
117
  // Align types for comparison
126
118
  if (typeof value === 'number') {
@@ -132,8 +124,8 @@ const eq = (options) => {
132
124
  if (typeof value === 'string') {
133
125
  return value === opt;
134
126
  }
135
- // Strict equality for others
136
- return value === opt;
127
+ // Booleans, null and the rest compare with the typed literal: eq(true) matches true (B9)
128
+ return value === literal;
137
129
  };
138
130
  };
139
131
  /**
@@ -142,8 +134,9 @@ const eq = (options) => {
142
134
  * @param options - Array with comparison value as first element
143
135
  * @returns Filter function that returns boolean
144
136
  */
145
- const ne = (options) => {
137
+ const ne = (options, literals) => {
146
138
  const opt = options?.[0] ?? optionsRequired('ne');
139
+ const literal = literals !== undefined && literals.length > 0 ? literals[0] : opt;
147
140
  return (value) => {
148
141
  // Align types for comparison
149
142
  if (typeof value === 'number') {
@@ -155,8 +148,8 @@ const ne = (options) => {
155
148
  if (typeof value === 'string') {
156
149
  return value !== opt;
157
150
  }
158
- // Strict equality for others
159
- return value !== opt;
151
+ // Booleans, null and the rest compare with the typed literal (B9)
152
+ return value !== literal;
160
153
  };
161
154
  };
162
155
  /**
@@ -817,23 +810,15 @@ const hms = (options) => {
817
810
  return `${hours}${opt}${minutes}${opt}${seconds}`;
818
811
  };
819
812
  };
820
- /** 3.0 は truthy / falsy / defaults を JavaScript の真偽判定に揃える(要件 B10)— 0n の差を予告する */
821
- function warnBigIntZero(fnName, value) {
822
- if (value === 0n) {
823
- warnV3Migration(`"${fnName}" got 0n: 3.0 treats it as falsy.`);
824
- }
825
- }
826
813
  /**
827
- * Falsy filter - checks if value is falsy.
814
+ * Falsy filter - checks if value is falsy, by JavaScript's own truthiness (`!value`: false, null,
815
+ * undefined, 0, -0, 0n, '' and NaN). Before 3.0 the list was spelled out and missed 0n (B10).
828
816
  *
829
817
  * @param options - Unused
830
- * @returns Filter function that returns true for false/null/undefined/0/''/NaN
818
+ * @returns Filter function that returns true for falsy values
831
819
  */
832
820
  const falsy = (_options) => {
833
- return (value) => {
834
- warnBigIntZero('falsy', value);
835
- return value === false || value === null || value === undefined || value === 0 || value === '' || Number.isNaN(value);
836
- };
821
+ return (value) => !value;
837
822
  };
838
823
  /**
839
824
  * Truthy filter - checks if value is truthy.
@@ -842,23 +827,22 @@ const falsy = (_options) => {
842
827
  * @returns Filter function that returns true for non-falsy values
843
828
  */
844
829
  const truthy = (_options) => {
845
- return (value) => {
846
- warnBigIntZero('truthy', value);
847
- return value !== false && value !== null && value !== undefined && value !== 0 && value !== '' && !Number.isNaN(value);
848
- };
830
+ // JavaScript's truthiness, the same as the `boolean` filter (B10)
831
+ return (value) => !!value;
849
832
  };
850
833
  /**
851
- * Default filter - returns default value if input is falsy.
834
+ * Default filter - returns default value if input is falsy (JavaScript's truthiness, as `falsy`).
852
835
  *
853
836
  * @param options - Array with default value as first element
854
837
  * @returns Filter function that returns value or default
855
838
  */
856
- const defaults = (options) => {
839
+ const defaults = (options, literals) => {
857
840
  const opt = options?.[0] ?? optionsRequired('defaults');
841
+ // The fallback is the typed literal (B9): defaults(0) gives 0, defaults(null) gives null, defaults('0') gives "0"
842
+ const fallback = literals !== undefined && literals.length > 0 ? literals[0] : opt;
858
843
  return (value) => {
859
- warnBigIntZero('defaults', value);
860
- if (value === false || value === null || value === undefined || value === 0 || value === '' || Number.isNaN(value)) {
861
- return opt;
844
+ if (!value) {
845
+ return fallback;
862
846
  }
863
847
  return value;
864
848
  };
@@ -1153,6 +1137,7 @@ function getWcsManifest() {
1153
1137
  elseKeyword: ELSE_KEYWORD,
1154
1138
  spread: SPREAD_PROP,
1155
1139
  eventPropertyPrefix: EVENT_PROP_PREFIX,
1140
+ explicitPropertyPrefix: DELIMITER,
1156
1141
  propNamespaces: {
1157
1142
  eventToken: EVENT_TOKEN_NAMESPACE,
1158
1143
  command: COMMAND_NAMESPACE,
package/dist/parser.d.ts CHANGED
@@ -1,3 +1,19 @@
1
+ /**
2
+ * Filter/types.ts
3
+ *
4
+ * Type definition file for filter functions.
5
+ *
6
+ * Main responsibilities:
7
+ * - Defines types for filter functions (FilterFn) and filter functions with options (FilterWithOptionsFn)
8
+ * - Type-safe management of filter name-to-function mappings (FilterWithOptions) and filter function arrays (Filters)
9
+ * - Defines types for retrieving filter functions from built-in filter collections
10
+ *
11
+ * Design points:
12
+ * - Type design enabling flexible filter design and extension
13
+ * - Supports filters with options and combinations of multiple filters
14
+ */
15
+ type FilterFn<T = unknown> = (value: unknown) => T;
16
+
1
17
  interface IPathInfo {
2
18
  readonly id: number;
3
19
  readonly path: string;
@@ -24,26 +40,23 @@ interface IPathInfo {
24
40
  readonly wildcardCount: number;
25
41
  }
26
42
 
43
+ type BindingType = 'text' | 'prop' | 'event' | 'for' | 'if' | 'elseif' | 'else' | 'radio' | 'checkbox' | 'spread';
27
44
  /**
28
- * Filter/types.ts
29
- *
30
- * Type definition file for filter functions.
31
- *
32
- * Main responsibilities:
33
- * - Defines types for filter functions (FilterFn) and filter functions with options (FilterWithOptionsFn)
34
- * - Type-safe management of filter name-to-function mappings (FilterWithOptions) and filter function arrays (Filters)
35
- * - Defines types for retrieving filter functions from built-in filter collections
36
- *
37
- * Design points:
38
- * - Type design enabling flexible filter design and extension
39
- * - Supports filters with options and combinations of multiple filters
45
+ * 文法の段が読むフィルタ(名前と引数だけ。要件 D16)。実関数は束縛計画の段で
46
+ * 登録簿から解決される(`core/filterRegistry.ts`)ので、パース結果はここで止まる。
40
47
  */
41
- type FilterFn<T = unknown> = (value: unknown) => T;
42
-
43
- type BindingType = 'text' | 'prop' | 'event' | 'for' | 'if' | 'elseif' | 'else' | 'radio' | 'checkbox' | 'spread';
44
- interface IFilterInfo {
48
+ interface IParsedFilter {
45
49
  readonly filterName: string;
46
50
  readonly args: string[];
51
+ /**
52
+ * 引数の型付きの値(要件 B9)。引用符の無い `true` / `false` / `null` / 数値は型付き、引用符付きは
53
+ * 文字列のまま。`args` は引用符を外した原文(書式フィルタはこちらを読む)。組み立てた側が省略したら
54
+ * `args` と同じ扱い。
55
+ */
56
+ readonly literals?: readonly unknown[];
57
+ }
58
+ /** 束縛計画の段で実関数まで解決したフィルタ */
59
+ interface IFilterInfo extends IParsedFilter {
47
60
  readonly filterFn: FilterFn;
48
61
  }
49
62
  /**
@@ -57,40 +70,25 @@ interface IParsedBinding {
57
70
  readonly propModifiers: string[];
58
71
  readonly statePathName: string;
59
72
  readonly statePathInfo: IPathInfo;
60
- readonly inFilters: IFilterInfo[];
61
- readonly outFilters: IFilterInfo[];
73
+ readonly inFilters: IParsedFilter[];
74
+ readonly outFilters: IParsedFilter[];
62
75
  readonly bindingType: BindingType;
63
76
  readonly uuid?: string | null;
64
77
  }
65
78
 
66
79
  type ParseBindTextResult = IParsedBinding;
67
80
 
81
+ /**
82
+ * `data-wcs` の値をバインディングごとに区切る(前後の空白は残す — tooling が位置を数えられるように)。
83
+ * 引用符の中の `;` は区切りではない(要件 B1 — `join(';')`)。ランタイムと tooling(`@wcstack/state/parser`)で共有する
84
+ */
85
+ declare function splitBindTexts(bindText: string): string[];
68
86
  declare function parseBindTextsForElement(bindText: string): ParseBindTextResult[];
69
87
 
70
88
  declare function parseBindTextForEmbeddedNode(bindText: string): ParseBindTextResult;
71
89
 
72
90
  declare function getPathInfo(path: string): IPathInfo;
73
91
 
74
- /**
75
- * v3MigrationRules.ts — 3.0 で拒否される(または読み方が変わる)書き方の判定。純関数。
76
- *
77
- * ランタイム(v3Migration.ts が `[wcs/v3-migration]` として console に 1 回ずつ出す)と
78
- * tooling(`@wcstack/state/parser` 経由で lint が同じ判定を使う)の共通の正本。
79
- * ここは console に何も出さず、2.x の挙動も変えない(次期メジャーの要件 D2)。
80
- * 文面は短く保つ — 全文はランタイムのバンドルに載る。2.x との差と書き換え先の一覧は
81
- * state README の "Preparing for 3.0"(警告の末尾が案内する)。
82
- *
83
- * 式は 2.x の分割(`;` で無条件に割る)のまま受け取る — 引用符の中の `;` は 2.x では既に壊れている。
84
- */
85
-
86
- /**
87
- * `data-wcs` の式 1 つ(`;` を含まない、trim 済み)の判定。`parsed` があればフィルタの引数の個数も見る。
88
- * 区切りの無い式は 2.x のパーサが先に拒否するので何も言わない。
89
- */
90
- declare function findV3MigrationIssues(expr: string, parsed?: ParseBindTextResult | null): string[];
91
- /** mustache / コメントのテキストバインディング(右辺だけ、`;` で割らない)の判定 */
92
- declare function findEmbeddedV3MigrationIssues(expression: string, parsed?: ParseBindTextResult | null): string[];
93
-
94
92
  /**
95
93
  * parser.ts — `data-wcs` バインディング構文の正本パーサを tooling 向けに公開する
96
94
  * サブパスエントリ(`@wcstack/state/parser`)。
@@ -130,5 +128,5 @@ declare function findEmbeddedV3MigrationIssues(expression: string, parsed?: Pars
130
128
  */
131
129
  declare function clearParserCaches(): void;
132
130
 
133
- export { clearParserCaches, findEmbeddedV3MigrationIssues, findV3MigrationIssues, getPathInfo, parseBindTextForEmbeddedNode, parseBindTextsForElement };
131
+ export { clearParserCaches, getPathInfo, parseBindTextForEmbeddedNode, parseBindTextsForElement, splitBindTexts };
134
132
  export type { BindingType, IFilterInfo, IPathInfo, ParseBindTextResult };