@wcstack/state 2.6.0 → 3.0.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/README.ja.md +97 -41
- package/README.md +99 -41
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/define.d.ts +295 -0
- package/dist/define.js +1 -0
- package/dist/index.d.ts +252 -94
- package/dist/index.esm.js +1 -23342
- package/dist/index.esm.js.map +1 -1
- package/dist/manifest.esm.js +21 -37
- package/dist/parser.d.ts +37 -39
- package/dist/parser.esm.js +147 -1153
- package/dist/split/chunks/binder.js +2 -0
- package/dist/split/chunks/binder.js.map +1 -0
- package/dist/split/chunks/checkDependency.js +2 -0
- package/dist/split/chunks/checkDependency.js.map +1 -0
- package/dist/split/chunks/diagnosticsHooks.js +2 -0
- package/dist/split/chunks/diagnosticsHooks.js.map +1 -0
- package/dist/split/chunks/errorGuidance.js +2 -0
- package/dist/split/chunks/errorGuidance.js.map +1 -0
- package/dist/split/chunks/features.d.ts +29 -0
- package/dist/split/chunks/filterRegistry.js +2 -0
- package/dist/split/chunks/filterRegistry.js.map +1 -0
- package/dist/split/chunks/getAllPropertyDescriptors.js +2 -0
- package/dist/split/chunks/getAllPropertyDescriptors.js.map +1 -0
- package/dist/split/chunks/lifecycleHooks.js +2 -0
- package/dist/split/chunks/lifecycleHooks.js.map +1 -0
- package/dist/split/chunks/mount.js +2 -0
- package/dist/split/chunks/mount.js.map +1 -0
- package/dist/split/chunks/pathDiagnostics.js +2 -0
- package/dist/split/chunks/pathDiagnostics.js.map +1 -0
- package/dist/split/chunks/registerComponents.js +2 -0
- package/dist/split/chunks/registerComponents.js.map +1 -0
- package/dist/split/chunks/setAll.js +2 -0
- package/dist/split/chunks/setAll.js.map +1 -0
- package/dist/split/chunks/version.js +2 -0
- package/dist/split/chunks/version.js.map +1 -0
- package/dist/split/chunks/watchRuntime.js +2 -0
- package/dist/split/chunks/watchRuntime.js.map +1 -0
- package/dist/split/core.d.ts +1417 -0
- package/dist/split/core.js +2 -0
- package/dist/split/core.js.map +1 -0
- package/dist/split/features/devtools.d.ts +9 -0
- package/dist/split/features/devtools.js +2 -0
- package/dist/split/features/devtools.js.map +1 -0
- package/dist/split/features/diagnostics.d.ts +11 -0
- package/dist/split/features/diagnostics.js +2 -0
- package/dist/split/features/diagnostics.js.map +1 -0
- package/dist/split/features/formats.d.ts +10 -0
- package/dist/split/features/formats.js +2 -0
- package/dist/split/features/formats.js.map +1 -0
- package/dist/split/features/recursion.d.ts +9 -0
- package/dist/split/features/recursion.js +2 -0
- package/dist/split/features/recursion.js.map +1 -0
- package/dist/split/features/scopes.d.ts +10 -0
- package/dist/split/features/scopes.js +2 -0
- package/dist/split/features/scopes.js.map +1 -0
- package/dist/split/features/ssr.d.ts +9 -0
- package/dist/split/features/ssr.js +2 -0
- package/dist/split/features/ssr.js.map +1 -0
- package/dist/split/features/temporal.d.ts +9 -0
- package/dist/split/features/temporal.js +2 -0
- package/dist/split/features/temporal.js.map +1 -0
- package/package.json +13 -1
package/dist/define.d.ts
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* defineState.ts
|
|
3
|
+
*
|
|
4
|
+
* 状態オブジェクトに型付けを提供するためのユーティリティ。
|
|
5
|
+
* defineState() はアイデンティティ関数で、ThisType<> を付与することで
|
|
6
|
+
* メソッド・computed getter 内の this に型補完を提供する。
|
|
7
|
+
*
|
|
8
|
+
* テンプレートリテラル型によるドットパスの型解決:
|
|
9
|
+
* - WcsPaths<T> : T から生成される全ドットパスの union
|
|
10
|
+
* - WcsPathValue<T,P>: パス P に対応する値の型
|
|
11
|
+
* - WcsPathAccessor<T>: ブラケットアクセス用マップ型
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* `any` 型を検出する。
|
|
15
|
+
* `0 extends (1 & T)` は T が `any` の場合のみ true になる。
|
|
16
|
+
*/
|
|
17
|
+
type IsAny<T> = 0 extends (1 & T) ? true : false;
|
|
18
|
+
/**
|
|
19
|
+
* T がドットパス再帰の対象となる「プレーンなデータオブジェクト」かどうかを判定する。
|
|
20
|
+
* プリミティブ、組み込みオブジェクト (Date, Map 等)、関数、配列、any は除外。
|
|
21
|
+
*/
|
|
22
|
+
type IsPlainObject<T> = IsAny<T> extends true ? false : T extends string | number | boolean | null | undefined | symbol | bigint | ((...args: any[]) => any) | Date | RegExp | Error | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | Promise<any> | readonly any[] ? false : T extends Record<string, any> ? true : false;
|
|
23
|
+
/**
|
|
24
|
+
* T のキーのうち、関数でないもの(データプロパティ・computed getter)を抽出する。
|
|
25
|
+
* メソッド(イベントハンドラ等)はドットパスの対象外。
|
|
26
|
+
* `$` プレフィックスキー($streams / $commandTokens / $on 等の予約宣言)もドットパスにならない。
|
|
27
|
+
* any 型のプロパティは除外せず保持する。
|
|
28
|
+
*/
|
|
29
|
+
type DataKeys<T> = {
|
|
30
|
+
[K in keyof T & string]: K extends `$${string}` ? never : IsAny<T[K]> extends true ? K : T[K] extends (...args: any[]) => any ? never : K;
|
|
31
|
+
}[keyof T & string];
|
|
32
|
+
/**
|
|
33
|
+
* 型 T から生成される全てのドットパスの union。
|
|
34
|
+
* 配列プロパティはワイルドカード `*` を使用: `items.*.name`
|
|
35
|
+
*
|
|
36
|
+
* 再帰の深さは最大4レベルに制限(コンパイル性能の確保)。
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* type S = {
|
|
41
|
+
* count: number;
|
|
42
|
+
* users: { name: string; age: number }[];
|
|
43
|
+
* cart: { items: { price: number }[] };
|
|
44
|
+
* };
|
|
45
|
+
* type P = WcsPaths<S>;
|
|
46
|
+
* // = "count" | "users" | "users.*" | "users.*.name" | "users.*.age"
|
|
47
|
+
* // | "cart" | "cart.items" | "cart.items.*" | "cart.items.*.price"
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
type WcsPaths<T, Depth extends readonly any[] = []> = Depth["length"] extends 4 ? never : {
|
|
51
|
+
[K in DataKeys<T>]: K | (T[K] extends readonly (infer E)[] ? IsPlainObject<E> extends true ? `${K}.*` | WcsSubPaths<E, `${K}.*.`, [...Depth, 0]> : `${K}.*` : IsPlainObject<T[K]> extends true ? WcsSubPaths<T[K], `${K}.`, [...Depth, 0]> : never);
|
|
52
|
+
}[DataKeys<T>];
|
|
53
|
+
/** @internal プレフィックス付きサブパスの生成ヘルパー */
|
|
54
|
+
type WcsSubPaths<T, Prefix extends string, Depth extends readonly any[]> = WcsPaths<T, Depth> extends infer P extends string ? `${Prefix}${P}` : never;
|
|
55
|
+
/**
|
|
56
|
+
* ドットパス P に対応する値の型を T から解決する。
|
|
57
|
+
*
|
|
58
|
+
* 解決順序:
|
|
59
|
+
* 1. T の直接キー(computed getter 含む)
|
|
60
|
+
* 2. `K.*` → 配列要素型
|
|
61
|
+
* 3. `K.rest` → オブジェクト/配列のネストを再帰的に辿る
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* type S = { cart: { items: { price: number; qty: number }[] } };
|
|
66
|
+
* type V1 = WcsPathValue<S, "cart.items.*.price">; // number
|
|
67
|
+
* type V2 = WcsPathValue<S, "cart.items.*">; // { price: number; qty: number }
|
|
68
|
+
* type V3 = WcsPathValue<S, "cart">; // { items: ... }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
type WcsPathValue<T, P extends string> = P extends keyof T ? T[P] : P extends `${infer K}.*` ? K extends keyof T ? T[K] extends readonly (infer E)[] ? E : never : never : P extends `${infer K}.${infer Rest}` ? K extends keyof T ? T[K] extends readonly (infer E)[] ? Rest extends `*.${infer SubRest}` ? WcsPathValue<E, SubRest> : Rest extends "*" ? E : never : T[K] extends Record<string, any> ? WcsPathValue<T[K], Rest> : never : never : never;
|
|
72
|
+
/**
|
|
73
|
+
* 全ドットパスに対する型付きブラケットアクセスを提供するマップ型。
|
|
74
|
+
*
|
|
75
|
+
* `this["users.*.name"]` のようなアクセスに対して、
|
|
76
|
+
* WcsPaths で生成されたパスに対応する値の型を返す。
|
|
77
|
+
*/
|
|
78
|
+
type WcsPathAccessor<T> = {
|
|
79
|
+
[P in WcsPaths<T>]: WcsPathValue<T, P>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* `<wcs-state>` の Proxy 経由で提供されるAPIメソッド。
|
|
83
|
+
* state定義オブジェクト内のメソッド・getter で `this.` 経由で利用可能。
|
|
84
|
+
*/
|
|
85
|
+
interface WcsStateApi {
|
|
86
|
+
/**
|
|
87
|
+
* ワイルドカードを含むパスにマッチする全要素を配列で取得する。
|
|
88
|
+
*
|
|
89
|
+
* @param path - ワイルドカードを含むパス
|
|
90
|
+
* @param indexes - 各ワイルドカード階層のインデックス(前方一致の接頭辞。`[]` は全階層を展開)。
|
|
91
|
+
* 省略時はループ文脈の添字(`[$1..$n]` 相当)のうち path と共有するワイルドカード連鎖の
|
|
92
|
+
* 分が接頭辞として敷かれる(文脈が path より深い分は切り詰め)。共有が無いのに文脈が
|
|
93
|
+
* 添字を持つ場合は throw する — 異なる文脈の添字は流用しない。
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* get "cart.totalPrice"() {
|
|
98
|
+
* return this.$getAll("cart.items.*.price").reduce((sum, v) => sum + v, 0);
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
$getAll<V = any>(path: string, indexes?: number[]): V[];
|
|
103
|
+
/**
|
|
104
|
+
* ワイルドカードを含むパスにマッチする**全アドレスへ一括で書き込む**(`$getAll` の対称形)。
|
|
105
|
+
*
|
|
106
|
+
* 配列を作り直さずに一括更新するための API。`this.users = this.users.map(...)` は
|
|
107
|
+
* ListIndex・行 getter キャッシュ・差分描画をまとめて作り直すが、`$setAll` は
|
|
108
|
+
* in-place な個別書き込みに分解するのでリストの同一性が保たれる。
|
|
109
|
+
*
|
|
110
|
+
* - `indexes` は `$getAll` と同じ**前方一致の接頭辞**(`[]` で全階層を展開)。省略は不可。
|
|
111
|
+
* - 関数を渡すと **mapper**(`(current, ...indexes) => next`)として要素ごとに評価される。
|
|
112
|
+
* - 配列は既定でブロードキャストされる。1 件ずつ配るには `{ spread: true }` を明示する。
|
|
113
|
+
* - `undefined` を書こうとした要素はスキップされる(クリアは `null`)。
|
|
114
|
+
*
|
|
115
|
+
* @returns 実際に書き込んだ件数(`undefined` でスキップした分を含まない)
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* toggleAll(e: Event) {
|
|
120
|
+
* this.$setAll("users.*.selected", [], (e.target as HTMLInputElement).checked);
|
|
121
|
+
* }
|
|
122
|
+
* invertAll() {
|
|
123
|
+
* this.$setAll("users.*.selected", [], cur => !cur);
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
$setAll<V = any>(path: string, indexes: number[], value: V | ((current: V, ...indexes: number[]) => V | undefined)): number;
|
|
128
|
+
$setAll<V = any>(path: string, indexes: number[], values: readonly V[], options: {
|
|
129
|
+
spread: true;
|
|
130
|
+
}): number;
|
|
131
|
+
/**
|
|
132
|
+
* 指定パスの更新を手動でトリガーする。
|
|
133
|
+
* Proxy の set トラップを経由せずに内部状態を変更した場合に使用。
|
|
134
|
+
*/
|
|
135
|
+
$postUpdate(path: string): void;
|
|
136
|
+
/**
|
|
137
|
+
* パスとインデックス配列を指定して、ワイルドカードを解決した値を取得・設定する。
|
|
138
|
+
*
|
|
139
|
+
* @param path - ワイルドカードを含むパス
|
|
140
|
+
* @param indexes - 各ワイルドカード階層のインデックス
|
|
141
|
+
* @param value - 設定する値(省略時は取得)
|
|
142
|
+
*/
|
|
143
|
+
$resolve(path: string, indexes: number[], value?: any): any;
|
|
144
|
+
/**
|
|
145
|
+
* 指定パスへの依存関係を明示的に登録する。
|
|
146
|
+
* computed getter 内で動的にパスを組み立てる場合に使用。
|
|
147
|
+
*/
|
|
148
|
+
$trackDependency(path: string): void;
|
|
149
|
+
/**
|
|
150
|
+
* コールバック実行中の依存追跡(動的依存・`$1` インデックス依存の登録)を
|
|
151
|
+
* 抑止して fn を実行し、その戻り値を返す(`$trackDependency` と対称)。
|
|
152
|
+
* リスト行 getter が「行外の単一値」を読みたいが、その値の変更で全行を
|
|
153
|
+
* 再評価させたくない場合に使う(該当行へ直接書き込む設計と組で用いる)。
|
|
154
|
+
*/
|
|
155
|
+
$untrackDependency<T>(fn: () => T): T;
|
|
156
|
+
/**
|
|
157
|
+
* 鍵付き購読: `path` の現在値が `key` に等しいかを返し、評価中のリスト行 getter を
|
|
158
|
+
* その鍵で購読する。`path` への書き込みは旧値・新値の鍵の行だけを再評価する
|
|
159
|
+
* (パターン依存なら全行)。`path` 自体は依存として追跡しない。
|
|
160
|
+
* 例: `get "items.*.selected"() { return this.$eq("selectedId", this.$untrackDependency(() => this["items.*.id"])); }`
|
|
161
|
+
*/
|
|
162
|
+
$eq(path: string, key: unknown): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* `$eq` の鍵を `keyPath`(ワイルドカードは評価中の行で解決)から依存を張らずに読む形。
|
|
165
|
+
* 例: `get "items.*.selected"() { return this.$eqPath("selectedId", "items.*.id"); }`
|
|
166
|
+
*/
|
|
167
|
+
$eqPath(path: string, keyPath: string): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* `$eq` の鍵を評価中の行の index(`$1` 相当。`level` でワイルドカード段を選ぶ)にする形。
|
|
170
|
+
* getter を index 依存には記録せず、行の移動時はリスト差分が鍵を付け替えるので、
|
|
171
|
+
* 1 行削除で再評価されるのは高々 2 行。
|
|
172
|
+
* 例: `get "items.*.selected"() { return this.$eqIndex("selectedIndex"); }`
|
|
173
|
+
*/
|
|
174
|
+
$eqIndex(path: string, level?: number): boolean;
|
|
175
|
+
/** `<wcs-state>` 要素への参照 */
|
|
176
|
+
readonly $stateElement: HTMLElement;
|
|
177
|
+
/**
|
|
178
|
+
* `$commandTokens` で宣言した command token の名前空間。
|
|
179
|
+
* `this.$command.<name>` で token を解決できる(バインディングでは
|
|
180
|
+
* `onclick: $command.<name>` / `command.<method>: $command.<name>`)。
|
|
181
|
+
*/
|
|
182
|
+
readonly $command: Record<string, {
|
|
183
|
+
emit(...args: any[]): any;
|
|
184
|
+
}>;
|
|
185
|
+
/** `$streams` 各エントリの状態("idle" | "active" | "done" | "error")を返す読み取り専用名前空間 */
|
|
186
|
+
readonly $streamStatus: Record<string, "idle" | "active" | "done" | "error">;
|
|
187
|
+
/** `$streams` 各エントリの直近エラーを返す読み取り専用名前空間 */
|
|
188
|
+
readonly $streamError: Record<string, unknown>;
|
|
189
|
+
readonly [key: `$streamStatus.${string}`]: "idle" | "active" | "done" | "error";
|
|
190
|
+
readonly [key: `$streamError.${string}`]: unknown;
|
|
191
|
+
readonly $1: number;
|
|
192
|
+
readonly $2: number;
|
|
193
|
+
readonly $3: number;
|
|
194
|
+
readonly $4: number;
|
|
195
|
+
readonly $5: number;
|
|
196
|
+
readonly $6: number;
|
|
197
|
+
readonly $7: number;
|
|
198
|
+
readonly $8: number;
|
|
199
|
+
readonly $9: number;
|
|
200
|
+
readonly [key: `${string}.**.${string}`]: any;
|
|
201
|
+
readonly [key: `${string}.**`]: any;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* state定義オブジェクト内の `this` の型。
|
|
205
|
+
*
|
|
206
|
+
* - `T` のプロパティに型付きでアクセス可能(直接キー)
|
|
207
|
+
* - `WcsPathAccessor<T>` によるネストされたドットパスの型付きアクセス
|
|
208
|
+
* - `WcsStateApi` のメソッド ($getAll, $postUpdate 等) にアクセス可能
|
|
209
|
+
* - 動的パス (`this[\`items.${i}.name\`]`) は型チェック対象外(キャストが必要)
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* defineState({
|
|
214
|
+
* count: 0,
|
|
215
|
+
* users: [] as { name: string; age: number }[],
|
|
216
|
+
* increment() {
|
|
217
|
+
* this.count++; // number
|
|
218
|
+
* this["users.*.name"]; // string (パス型解決)
|
|
219
|
+
* this.$getAll("users.*.age"); // API
|
|
220
|
+
* }
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
type WcsThis<T> = T & WcsStateApi & WcsPathAccessor<T>;
|
|
225
|
+
/**
|
|
226
|
+
* `<wcs-state>` 用の型付き状態オブジェクトを定義する。
|
|
227
|
+
*
|
|
228
|
+
* ランタイムではアイデンティティ関数(引数をそのまま返す)として動作し、
|
|
229
|
+
* コストはゼロ。TypeScript の `ThisType<>` を利用して、メソッド・getter 内の
|
|
230
|
+
* `this` に型補完を提供する。
|
|
231
|
+
*
|
|
232
|
+
* ### 基本的な使い方 (TypeScript)
|
|
233
|
+
* ```ts
|
|
234
|
+
* import { defineState } from '@wcstack/state';
|
|
235
|
+
*
|
|
236
|
+
* export default defineState({
|
|
237
|
+
* count: 0,
|
|
238
|
+
* users: [] as { name: string; age: number }[],
|
|
239
|
+
*
|
|
240
|
+
* increment() {
|
|
241
|
+
* this.count++; // ✅ number
|
|
242
|
+
* this["users.*.name"]; // ✅ string (ドットパス型解決)
|
|
243
|
+
* },
|
|
244
|
+
*
|
|
245
|
+
* get "users.*.ageCategory"() {
|
|
246
|
+
* return this["users.*.age"] < 25 ? "Young" : "Adult";
|
|
247
|
+
* }
|
|
248
|
+
* });
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* ### JavaScript (JSDoc)
|
|
252
|
+
* ```js
|
|
253
|
+
* import { defineState } from '@wcstack/state';
|
|
254
|
+
*
|
|
255
|
+
* export default defineState({
|
|
256
|
+
* count: 0,
|
|
257
|
+
* increment() {
|
|
258
|
+
* this.count++; // ✅ JSDoc + tsconfig checkJs で型補完
|
|
259
|
+
* }
|
|
260
|
+
* });
|
|
261
|
+
* ```
|
|
262
|
+
*
|
|
263
|
+
* ### HTML インラインスクリプト
|
|
264
|
+
* ```html
|
|
265
|
+
* <wcs-state>
|
|
266
|
+
* <script type="module">
|
|
267
|
+
* import { defineState } from '@wcstack/state';
|
|
268
|
+
* export default defineState({
|
|
269
|
+
* count: 0,
|
|
270
|
+
* increment() { this.count++; }
|
|
271
|
+
* });
|
|
272
|
+
* </script>
|
|
273
|
+
* </wcs-state>
|
|
274
|
+
* ```
|
|
275
|
+
*
|
|
276
|
+
* ### ライフサイクルコールバック
|
|
277
|
+
* ```ts
|
|
278
|
+
* export default defineState({
|
|
279
|
+
* data: null,
|
|
280
|
+
* async $connectedCallback() {
|
|
281
|
+
* this.data = await fetch('/api/data').then(r => r.json());
|
|
282
|
+
* },
|
|
283
|
+
* $disconnectedCallback() {
|
|
284
|
+
* // cleanup
|
|
285
|
+
* },
|
|
286
|
+
* $updatedCallback() {
|
|
287
|
+
* // called after DOM update
|
|
288
|
+
* }
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
declare function defineState<T extends Record<string, any>>(definition: T & ThisType<WcsThis<T>>): T;
|
|
293
|
+
|
|
294
|
+
export { defineState };
|
|
295
|
+
export type { WcsPathValue, WcsPaths, WcsStateApi, WcsThis };
|
package/dist/define.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function n(n){return n}export{n as defineState};
|