@wcstack/upload 1.9.0 → 1.9.1

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 CHANGED
@@ -1,283 +1,283 @@
1
- # @wcstack/upload
2
-
3
- `@wcstack/upload` は wcstack エコシステム向けの宣言的ファイルアップロードコンポーネントです。
4
-
5
- 視覚的な UI ウィジェットではありません。
6
- ファイルアップロードをバインド可能な状態へ変換する、隠れた **upload I/O ノード** です。
7
-
8
- `@wcstack/state` と組み合わせると、`<wcs-upload>` は次のような小さな非同期ステートサーフェスを公開します。
9
-
10
- - 入力 / コマンドサーフェス: `files`, `trigger`
11
- - 設定サーフェス: `url`, `method`, `field-name`, `accept`, `max-size`, `manual`, `multiple`
12
- - 出力ステートサーフェス: `value`, `loading`, `progress`, `error`, `status`
13
-
14
- つまり、ファイルアップロードを場当たり的な `XMLHttpRequest` のグルーコードではなく、状態遷移と DOM バインディングとして扱えます。
15
-
16
- `@wcstack/upload` は wcstack の他の I/O パッケージと同様に、HAWC 的な分割に従います。
17
-
18
- - **Core** (`UploadCore`) が XHR アップロード、進捗追跡、abort、非同期状態を処理
19
- - **Shell** (`<wcs-upload>`) がその状態をカスタム要素と `wc-bindable` サーフェスとして公開
20
- - フレームワークやバインディングシステムは `wc-bindable-protocol` 経由で利用
21
-
22
- ## なぜこれが存在するのか
23
-
24
- ファイルアップロードは、実際には複数の関心事に分散しがちです。
25
-
26
- - ファイル入力の取得
27
- - `FormData` の組み立て
28
- - progress イベント
29
- - loading フラグ
30
- - エラー処理
31
- - 切断時の abort
32
-
33
- `@wcstack/upload` はそのロジックを再利用可能なコンポーネントへ移し、結果をバインド可能な状態として公開します。
34
-
35
- ## インストール
36
-
37
- ```bash
38
- npm install @wcstack/upload
39
- ```
40
-
41
- ## クイックスタート
42
-
43
- ### 1. `files` を代入すると自動アップロード
44
-
45
- ```html
46
- <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
47
-
48
- <wcs-upload id="avatar-upload" url="/api/upload"></wcs-upload>
49
- <input id="avatar-input" type="file" accept="image/*">
50
-
51
- <script type="module">
52
- const upload = document.getElementById("avatar-upload");
53
- const input = document.getElementById("avatar-input");
54
-
55
- input.addEventListener("change", () => {
56
- upload.files = input.files;
57
- });
58
-
59
- upload.addEventListener("wcs-upload:progress", (event) => {
60
- console.log("progress", event.detail);
61
- });
62
-
63
- upload.addEventListener("wcs-upload:response", (event) => {
64
- console.log("uploaded", event.detail.value);
65
- });
66
- </script>
67
- ```
68
-
69
- デフォルト動作は次のとおりです。
70
-
71
- - `files` を代入すると即座にアップロード開始
72
- - 送信形式は `multipart/form-data`
73
- - リクエストメソッドのデフォルトは `POST`
74
- - フィールド名のデフォルトは `file`
75
-
76
- ### 2. `trigger` による手動アップロード
77
-
78
- 先にファイルを選び、後からアップロードしたい場合は `manual` を使います。
79
-
80
- ```html
81
- <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
82
-
83
- <wcs-upload id="resume-upload" url="/api/upload" manual></wcs-upload>
84
-
85
- <input id="resume-input" type="file">
86
- <button id="resume-button">Upload</button>
87
-
88
- <script type="module">
89
- const upload = document.getElementById("resume-upload");
90
- const input = document.getElementById("resume-input");
91
- const button = document.getElementById("resume-button");
92
-
93
- input.addEventListener("change", () => {
94
- upload.files = input.files;
95
- });
96
-
97
- button.addEventListener("click", () => {
98
- upload.trigger = true;
99
- });
100
- </script>
101
- ```
102
-
103
- `trigger` は単方向のコマンドサーフェスです。
104
-
105
- - `true` を書き込むと `upload()` を開始
106
- - 完了後に自動で `false` へ戻る
107
- - そのリセット時に `wcs-upload:trigger-changed` を発火
108
-
109
- ### 3. 宣言的なトリガーターゲット
110
-
111
- 自動トリガーが有効な場合、クリック可能な要素から id で `<wcs-upload>` を参照できます。
112
-
113
- ```html
114
- <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
115
-
116
- <wcs-upload id="photo-upload" url="/api/upload" manual></wcs-upload>
117
- <input id="photo-input" type="file">
118
- <button data-uploadtarget="photo-upload">Upload</button>
119
-
120
- <script type="module">
121
- const upload = document.getElementById("photo-upload");
122
- const input = document.getElementById("photo-input");
123
-
124
- input.addEventListener("change", () => {
125
- upload.files = input.files;
126
- });
127
- </script>
128
- ```
129
-
130
- デフォルトのトリガー属性名は `data-uploadtarget` です。
131
-
132
- ### 4. `@wcstack/state` と組み合わせる
133
-
134
- ```html
135
- <script type="module" src="https://esm.run/@wcstack/state/auto"></script>
136
- <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
137
-
138
- <wcs-state>
139
- <script type="module">
140
- export default {
141
- uploadResult: null,
142
- uploadLoading: false,
143
- uploadProgress: 0,
144
- uploadError: null,
145
- };
146
- </script>
147
-
148
- <wcs-upload
149
- id="state-upload"
150
- url="/api/upload"
151
- manual
152
- data-wcs="
153
- value: uploadResult;
154
- loading: uploadLoading;
155
- progress: uploadProgress;
156
- error: uploadError
157
- ">
158
- </wcs-upload>
159
-
160
- <input id="state-upload-input" type="file">
161
- <button data-uploadtarget="state-upload">Upload</button>
162
-
163
- <progress max="100" data-wcs="value: uploadProgress"></progress>
164
- <p data-wcs="textContent: uploadLoading"></p>
165
-
166
- <script type="module">
167
- const upload = document.getElementById("state-upload");
168
- const input = document.getElementById("state-upload-input");
169
-
170
- input.addEventListener("change", () => {
171
- upload.files = input.files;
172
- });
173
- </script>
174
- </wcs-state>
175
- ```
176
-
177
- この構成では、アップロードはバインド可能な非同期ノードになります。
178
-
179
- - 要素がリクエストを実行
180
- - 非同期状態が `value`, `loading`, `progress`, `error`, `status` として返る
181
- - UI はそれらのパスへ宣言的にバインド
182
-
183
- ## 公開 API
184
-
185
- ### 要素属性とプロパティ
186
-
187
- | 名前 | 型 | デフォルト | 説明 |
188
- |---|---|---|---|
189
- | `url` | `string` | `""` | アップロード先エンドポイント |
190
- | `method` | `string` | `"POST"` | HTTP メソッド |
191
- | `field-name` | `string` | `"file"` | FormData のフィールド名 |
192
- | `multiple` | `boolean` | `false` | 複数ファイル対応を表すフラグ |
193
- | `max-size` | `number` | `Infinity` | 許容最大ファイルサイズ(byte) |
194
- | `accept` | `string` | `""` | 許可する MIME type または拡張子 |
195
- | `manual` | `boolean` | `false` | `files` 代入時の自動アップロードを無効化 |
196
- | `files` | `FileList \| File[] \| null` | `null` | アップロード対象ファイル |
197
- | `trigger` | `boolean` | `false` | 手動アップロード用の書き込みコマンド面 |
198
- | `value` | `any` | `null` | パース済みレスポンスまたはレスポンステキスト |
199
- | `loading` | `boolean` | `false` | アップロード中フラグ |
200
- | `progress` | `number` | `0` | `0` から `100` の進捗率 |
201
- | `error` | `any` | `null` | バリデーション、ネットワーク、レスポンスのエラー |
202
- | `status` | `number` | `0` | HTTP レスポンスステータス |
203
- | `promise` | `Promise<any>` | resolved `null` | 現在のアップロード Promise |
204
-
205
- ### メソッド
206
-
207
- #### `upload()`
208
-
209
- 現在の `files` を使ってアップロードを開始し、promise を返します。
210
- ファイル未指定またはバリデーション失敗時は `null` を返します。
211
-
212
- #### `abort()`
213
-
214
- 現在のリクエストを中断します。
215
-
216
- ## イベント
217
-
218
- | イベント | `detail` | 説明 |
219
- |---|---|---|
220
- | `wcs-upload:files-changed` | `FileList \| File[] \| null` | `files` 変更時に発火 |
221
- | `wcs-upload:trigger-changed` | `boolean` | `trigger` が `false` に戻るとき発火 |
222
- | `wcs-upload:loading-changed` | `boolean` | loading 状態変更時に発火 |
223
- | `wcs-upload:progress` | `number` | アップロード進捗更新時に発火 |
224
- | `wcs-upload:error` | error object | バリデーション、ネットワーク、HTTP エラー時に発火 |
225
- | `wcs-upload:response` | `{ value, status }` | HTTP 成功レスポンス時に発火 |
226
-
227
- ## バリデーション
228
-
229
- `<wcs-upload>` は送信前にファイルを検証します。
230
-
231
- - `max-size` は指定 byte 数を超えるファイルを拒否
232
- - `accept` は `image/*` のような MIME 範囲、`application/pdf` のような厳密 MIME、`.pdf` のような拡張子をサポート
233
-
234
- バリデーションに失敗すると `wcs-upload:error` を発火し、リクエストは開始されません。
235
-
236
- ## wc-bindable サーフェス
237
-
238
- `<wcs-upload>` は次の bindable property を持つ `wcBindable` 定義を公開します。
239
-
240
- - `value`
241
- - `loading`
242
- - `progress`
243
- - `error`
244
- - `status`
245
- - `trigger`
246
- - `files`
247
-
248
- これにより、`@wcstack/state` を含む wc-bindable 対応システムから利用できます。
249
-
250
- ## Headless API
251
-
252
- カスタム要素の shell が不要な場合は、`UploadCore` を直接使えます。
253
-
254
- ```ts
255
- import { UploadCore } from "@wcstack/upload";
256
-
257
- const core = new UploadCore();
258
- const result = await core.upload("/api/upload", files, {
259
- method: "PUT",
260
- fieldName: "attachment",
261
- headers: {
262
- Authorization: "Bearer token",
263
- },
264
- });
265
- ```
266
-
267
- `UploadCore` は同じ非同期状態をプロパティとして公開し、同じイベントを発火します。
268
-
269
- ## 手動 bootstrap
270
-
271
- ```ts
272
- import { bootstrapUpload } from "@wcstack/upload";
273
-
274
- bootstrapUpload({
275
- autoTrigger: true,
276
- triggerAttribute: "data-uploadtarget",
277
- tagNames: {
278
- upload: "wcs-upload",
279
- },
280
- });
281
- ```
282
-
1
+ # @wcstack/upload
2
+
3
+ `@wcstack/upload` は wcstack エコシステム向けの宣言的ファイルアップロードコンポーネントです。
4
+
5
+ 視覚的な UI ウィジェットではありません。
6
+ ファイルアップロードをバインド可能な状態へ変換する、隠れた **upload I/O ノード** です。
7
+
8
+ `@wcstack/state` と組み合わせると、`<wcs-upload>` は次のような小さな非同期ステートサーフェスを公開します。
9
+
10
+ - 入力 / コマンドサーフェス: `files`, `trigger`
11
+ - 設定サーフェス: `url`, `method`, `field-name`, `accept`, `max-size`, `manual`, `multiple`
12
+ - 出力ステートサーフェス: `value`, `loading`, `progress`, `error`, `status`
13
+
14
+ つまり、ファイルアップロードを場当たり的な `XMLHttpRequest` のグルーコードではなく、状態遷移と DOM バインディングとして扱えます。
15
+
16
+ `@wcstack/upload` は wcstack の他の I/O パッケージと同様に、HAWC 的な分割に従います。
17
+
18
+ - **Core** (`UploadCore`) が XHR アップロード、進捗追跡、abort、非同期状態を処理
19
+ - **Shell** (`<wcs-upload>`) がその状態をカスタム要素と `wc-bindable` サーフェスとして公開
20
+ - フレームワークやバインディングシステムは `wc-bindable-protocol` 経由で利用
21
+
22
+ ## なぜこれが存在するのか
23
+
24
+ ファイルアップロードは、実際には複数の関心事に分散しがちです。
25
+
26
+ - ファイル入力の取得
27
+ - `FormData` の組み立て
28
+ - progress イベント
29
+ - loading フラグ
30
+ - エラー処理
31
+ - 切断時の abort
32
+
33
+ `@wcstack/upload` はそのロジックを再利用可能なコンポーネントへ移し、結果をバインド可能な状態として公開します。
34
+
35
+ ## インストール
36
+
37
+ ```bash
38
+ npm install @wcstack/upload
39
+ ```
40
+
41
+ ## クイックスタート
42
+
43
+ ### 1. `files` を代入すると自動アップロード
44
+
45
+ ```html
46
+ <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
47
+
48
+ <wcs-upload id="avatar-upload" url="/api/upload"></wcs-upload>
49
+ <input id="avatar-input" type="file" accept="image/*">
50
+
51
+ <script type="module">
52
+ const upload = document.getElementById("avatar-upload");
53
+ const input = document.getElementById("avatar-input");
54
+
55
+ input.addEventListener("change", () => {
56
+ upload.files = input.files;
57
+ });
58
+
59
+ upload.addEventListener("wcs-upload:progress", (event) => {
60
+ console.log("progress", event.detail);
61
+ });
62
+
63
+ upload.addEventListener("wcs-upload:response", (event) => {
64
+ console.log("uploaded", event.detail.value);
65
+ });
66
+ </script>
67
+ ```
68
+
69
+ デフォルト動作は次のとおりです。
70
+
71
+ - `files` を代入すると即座にアップロード開始
72
+ - 送信形式は `multipart/form-data`
73
+ - リクエストメソッドのデフォルトは `POST`
74
+ - フィールド名のデフォルトは `file`
75
+
76
+ ### 2. `trigger` による手動アップロード
77
+
78
+ 先にファイルを選び、後からアップロードしたい場合は `manual` を使います。
79
+
80
+ ```html
81
+ <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
82
+
83
+ <wcs-upload id="resume-upload" url="/api/upload" manual></wcs-upload>
84
+
85
+ <input id="resume-input" type="file">
86
+ <button id="resume-button">Upload</button>
87
+
88
+ <script type="module">
89
+ const upload = document.getElementById("resume-upload");
90
+ const input = document.getElementById("resume-input");
91
+ const button = document.getElementById("resume-button");
92
+
93
+ input.addEventListener("change", () => {
94
+ upload.files = input.files;
95
+ });
96
+
97
+ button.addEventListener("click", () => {
98
+ upload.trigger = true;
99
+ });
100
+ </script>
101
+ ```
102
+
103
+ `trigger` は単方向のコマンドサーフェスです。
104
+
105
+ - `true` を書き込むと `upload()` を開始
106
+ - 完了後に自動で `false` へ戻る
107
+ - そのリセット時に `wcs-upload:trigger-changed` を発火
108
+
109
+ ### 3. 宣言的なトリガーターゲット
110
+
111
+ 自動トリガーが有効な場合、クリック可能な要素から id で `<wcs-upload>` を参照できます。
112
+
113
+ ```html
114
+ <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
115
+
116
+ <wcs-upload id="photo-upload" url="/api/upload" manual></wcs-upload>
117
+ <input id="photo-input" type="file">
118
+ <button data-uploadtarget="photo-upload">Upload</button>
119
+
120
+ <script type="module">
121
+ const upload = document.getElementById("photo-upload");
122
+ const input = document.getElementById("photo-input");
123
+
124
+ input.addEventListener("change", () => {
125
+ upload.files = input.files;
126
+ });
127
+ </script>
128
+ ```
129
+
130
+ デフォルトのトリガー属性名は `data-uploadtarget` です。
131
+
132
+ ### 4. `@wcstack/state` と組み合わせる
133
+
134
+ ```html
135
+ <script type="module" src="https://esm.run/@wcstack/state/auto"></script>
136
+ <script type="module" src="https://esm.run/@wcstack/upload/auto"></script>
137
+
138
+ <wcs-state>
139
+ <script type="module">
140
+ export default {
141
+ uploadResult: null,
142
+ uploadLoading: false,
143
+ uploadProgress: 0,
144
+ uploadError: null,
145
+ };
146
+ </script>
147
+
148
+ <wcs-upload
149
+ id="state-upload"
150
+ url="/api/upload"
151
+ manual
152
+ data-wcs="
153
+ value: uploadResult;
154
+ loading: uploadLoading;
155
+ progress: uploadProgress;
156
+ error: uploadError
157
+ ">
158
+ </wcs-upload>
159
+
160
+ <input id="state-upload-input" type="file">
161
+ <button data-uploadtarget="state-upload">Upload</button>
162
+
163
+ <progress max="100" data-wcs="value: uploadProgress"></progress>
164
+ <p data-wcs="textContent: uploadLoading"></p>
165
+
166
+ <script type="module">
167
+ const upload = document.getElementById("state-upload");
168
+ const input = document.getElementById("state-upload-input");
169
+
170
+ input.addEventListener("change", () => {
171
+ upload.files = input.files;
172
+ });
173
+ </script>
174
+ </wcs-state>
175
+ ```
176
+
177
+ この構成では、アップロードはバインド可能な非同期ノードになります。
178
+
179
+ - 要素がリクエストを実行
180
+ - 非同期状態が `value`, `loading`, `progress`, `error`, `status` として返る
181
+ - UI はそれらのパスへ宣言的にバインド
182
+
183
+ ## 公開 API
184
+
185
+ ### 要素属性とプロパティ
186
+
187
+ | 名前 | 型 | デフォルト | 説明 |
188
+ |---|---|---|---|
189
+ | `url` | `string` | `""` | アップロード先エンドポイント |
190
+ | `method` | `string` | `"POST"` | HTTP メソッド |
191
+ | `field-name` | `string` | `"file"` | FormData のフィールド名 |
192
+ | `multiple` | `boolean` | `false` | 複数ファイル対応を表すフラグ |
193
+ | `max-size` | `number` | `Infinity` | 許容最大ファイルサイズ(byte) |
194
+ | `accept` | `string` | `""` | 許可する MIME type または拡張子 |
195
+ | `manual` | `boolean` | `false` | `files` 代入時の自動アップロードを無効化 |
196
+ | `files` | `FileList \| File[] \| null` | `null` | アップロード対象ファイル |
197
+ | `trigger` | `boolean` | `false` | 手動アップロード用の書き込みコマンド面 |
198
+ | `value` | `any` | `null` | パース済みレスポンスまたはレスポンステキスト |
199
+ | `loading` | `boolean` | `false` | アップロード中フラグ |
200
+ | `progress` | `number` | `0` | `0` から `100` の進捗率 |
201
+ | `error` | `any` | `null` | バリデーション、ネットワーク、レスポンスのエラー |
202
+ | `status` | `number` | `0` | HTTP レスポンスステータス |
203
+ | `promise` | `Promise<any>` | resolved `null` | 現在のアップロード Promise |
204
+
205
+ ### メソッド
206
+
207
+ #### `upload()`
208
+
209
+ 現在の `files` を使ってアップロードを開始し、promise を返します。
210
+ ファイル未指定またはバリデーション失敗時は `null` を返します。
211
+
212
+ #### `abort()`
213
+
214
+ 現在のリクエストを中断します。
215
+
216
+ ## イベント
217
+
218
+ | イベント | `detail` | 説明 |
219
+ |---|---|---|
220
+ | `wcs-upload:files-changed` | `FileList \| File[] \| null` | `files` 変更時に発火 |
221
+ | `wcs-upload:trigger-changed` | `boolean` | `trigger` が `false` に戻るとき発火 |
222
+ | `wcs-upload:loading-changed` | `boolean` | loading 状態変更時に発火 |
223
+ | `wcs-upload:progress` | `number` | アップロード進捗更新時に発火 |
224
+ | `wcs-upload:error` | error object | バリデーション、ネットワーク、HTTP エラー時に発火 |
225
+ | `wcs-upload:response` | `{ value, status }` | HTTP 成功レスポンス時に発火 |
226
+
227
+ ## バリデーション
228
+
229
+ `<wcs-upload>` は送信前にファイルを検証します。
230
+
231
+ - `max-size` は指定 byte 数を超えるファイルを拒否
232
+ - `accept` は `image/*` のような MIME 範囲、`application/pdf` のような厳密 MIME、`.pdf` のような拡張子をサポート
233
+
234
+ バリデーションに失敗すると `wcs-upload:error` を発火し、リクエストは開始されません。
235
+
236
+ ## wc-bindable サーフェス
237
+
238
+ `<wcs-upload>` は次の bindable property を持つ `wcBindable` 定義を公開します。
239
+
240
+ - `value`
241
+ - `loading`
242
+ - `progress`
243
+ - `error`
244
+ - `status`
245
+ - `trigger`
246
+ - `files`
247
+
248
+ これにより、`@wcstack/state` を含む wc-bindable 対応システムから利用できます。
249
+
250
+ ## Headless API
251
+
252
+ カスタム要素の shell が不要な場合は、`UploadCore` を直接使えます。
253
+
254
+ ```ts
255
+ import { UploadCore } from "@wcstack/upload";
256
+
257
+ const core = new UploadCore();
258
+ const result = await core.upload("/api/upload", files, {
259
+ method: "PUT",
260
+ fieldName: "attachment",
261
+ headers: {
262
+ Authorization: "Bearer token",
263
+ },
264
+ });
265
+ ```
266
+
267
+ `UploadCore` は同じ非同期状態をプロパティとして公開し、同じイベントを発火します。
268
+
269
+ ## 手動 bootstrap
270
+
271
+ ```ts
272
+ import { bootstrapUpload } from "@wcstack/upload";
273
+
274
+ bootstrapUpload({
275
+ autoTrigger: true,
276
+ triggerAttribute: "data-uploadtarget",
277
+ tagNames: {
278
+ upload: "wcs-upload",
279
+ },
280
+ });
281
+ ```
282
+
283
283
  `@wcstack/upload/auto` に頼らず、タグ名やトリガー属性名をカスタマイズしたい場合に使います。