@wcstack/upload 1.14.0 → 1.15.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/dist/index.d.ts CHANGED
@@ -1,19 +1,3 @@
1
- interface ITagNames {
2
- readonly upload: string;
3
- }
4
- interface IWritableTagNames {
5
- upload?: string;
6
- }
7
- interface IConfig {
8
- readonly autoTrigger: boolean;
9
- readonly triggerAttribute: string;
10
- readonly tagNames: ITagNames;
11
- }
12
- interface IWritableConfig {
13
- autoTrigger?: boolean;
14
- triggerAttribute?: string;
15
- tagNames?: IWritableTagNames;
16
- }
17
1
  interface IWcBindableProperty {
18
2
  readonly name: string;
19
3
  readonly event: string;
@@ -30,10 +14,28 @@ interface IWcBindableCommand {
30
14
  interface IWcBindable {
31
15
  readonly protocol: "wc-bindable";
32
16
  readonly version: 1;
33
- readonly properties: IWcBindableProperty[];
17
+ readonly properties: readonly IWcBindableProperty[];
34
18
  readonly inputs?: readonly IWcBindableInput[];
35
19
  readonly commands?: readonly IWcBindableCommand[];
36
20
  }
21
+
22
+ interface ITagNames {
23
+ readonly upload: string;
24
+ }
25
+ interface IWritableTagNames {
26
+ upload?: string;
27
+ }
28
+ interface IConfig {
29
+ readonly autoTrigger: boolean;
30
+ readonly triggerAttribute: string;
31
+ readonly tagNames: ITagNames;
32
+ }
33
+ interface IWritableConfig {
34
+ autoTrigger?: boolean;
35
+ triggerAttribute?: string;
36
+ tagNames?: IWritableTagNames;
37
+ }
38
+
37
39
  /**
38
40
  * Upload error object.
39
41
  */
@@ -86,7 +88,12 @@ declare class UploadCore extends EventTarget {
86
88
  private _status;
87
89
  private _xhr;
88
90
  private _promise;
91
+ private _gen;
92
+ private _ready;
89
93
  constructor(target?: EventTarget);
94
+ get ready(): Promise<void>;
95
+ observe(): Promise<void>;
96
+ dispose(): void;
90
97
  get value(): any;
91
98
  get loading(): boolean;
92
99
  get progress(): number;
@@ -109,7 +116,9 @@ declare class WcsUpload extends HTMLElement {
109
116
  private _core;
110
117
  private _files;
111
118
  private _trigger;
119
+ private _connectedCallbackPromise;
112
120
  constructor();
121
+ get connectedCallbackPromise(): Promise<void>;
113
122
  get url(): string;
114
123
  set url(value: string);
115
124
  get method(): string;
package/dist/index.esm.js CHANGED
@@ -49,10 +49,6 @@ function setConfig(partialConfig) {
49
49
  frozenConfig = null;
50
50
  }
51
51
 
52
- function raiseError(message) {
53
- throw new Error(`[@wcstack/upload] ${message}`);
54
- }
55
-
56
52
  class UploadCore extends EventTarget {
57
53
  static wcBindable = {
58
54
  protocol: "wc-bindable",
@@ -82,10 +78,30 @@ class UploadCore extends EventTarget {
82
78
  _status = 0;
83
79
  _xhr = null;
84
80
  _promise = Promise.resolve(null);
81
+ // Generation guard: bumped on dispose() (and each upload start). An in-flight
82
+ // request that settles after dispose / a superseding start has a stale `gen`
83
+ // and MUST NOT write state to a torn-down element. A boolean flag is
84
+ // insufficient (dispose→observe would let stale work slip through).
85
+ _gen = 0;
86
+ // SSR: no asynchronous probe to await, so readiness is immediate.
87
+ _ready = Promise.resolve();
85
88
  constructor(target) {
86
89
  super();
87
90
  this._target = target ?? this;
88
91
  }
92
+ get ready() {
93
+ return this._ready;
94
+ }
95
+ // Lifecycle (§3.5). Upload is command-driven with no subscription to
96
+ // establish, so observe() is an idempotent no-op that resolves once ready;
97
+ // dispose() invalidates any in-flight request and aborts it.
98
+ observe() {
99
+ return this._ready;
100
+ }
101
+ dispose() {
102
+ this._gen++;
103
+ this.abort();
104
+ }
89
105
  get value() {
90
106
  return this._value;
91
107
  }
@@ -148,11 +164,16 @@ class UploadCore extends EventTarget {
148
164
  }
149
165
  }
150
166
  async upload(url, files, options = {}) {
167
+ // never-throw: 引数バリデーション失敗は例外ではなく error プロパティに流し、
168
+ // サニタイズ値(null)を返す。command-token 経路からの呼び出しが unhandled
169
+ // rejection にならず、「upload() は全終了ケースで resolve」契約とも整合する。
151
170
  if (!url) {
152
- raiseError("url is required.");
171
+ this._setError({ message: "url is required." });
172
+ return null;
153
173
  }
154
174
  if (!files || files.length === 0) {
155
- raiseError("files are required.");
175
+ this._setError({ message: "files are required." });
176
+ return null;
156
177
  }
157
178
  const p = this._doUpload(url, files, options);
158
179
  this._promise = p;
@@ -170,10 +191,13 @@ class UploadCore extends EventTarget {
170
191
  for (let i = 0; i < files.length; i++) {
171
192
  formData.append(fieldName, files[i]);
172
193
  }
194
+ const gen = ++this._gen;
173
195
  return new Promise((resolve) => {
174
196
  const xhr = new XMLHttpRequest();
175
197
  this._xhr = xhr;
176
198
  xhr.upload.addEventListener("progress", (event) => {
199
+ if (gen !== this._gen)
200
+ return;
177
201
  if (event.lengthComputable) {
178
202
  const percent = Math.round((event.loaded / event.total) * 100);
179
203
  this._setProgress(percent);
@@ -181,6 +205,10 @@ class UploadCore extends EventTarget {
181
205
  });
182
206
  xhr.addEventListener("load", () => {
183
207
  this._xhr = null;
208
+ if (gen !== this._gen) {
209
+ resolve(null);
210
+ return;
211
+ }
184
212
  this._status = xhr.status;
185
213
  if (xhr.status >= 200 && xhr.status < 300) {
186
214
  let value = xhr.responseText;
@@ -211,12 +239,20 @@ class UploadCore extends EventTarget {
211
239
  });
212
240
  xhr.addEventListener("error", () => {
213
241
  this._xhr = null;
242
+ if (gen !== this._gen) {
243
+ resolve(null);
244
+ return;
245
+ }
214
246
  this._setError({ message: "Network error" });
215
247
  this._setLoading(false);
216
248
  resolve(null);
217
249
  });
218
250
  xhr.addEventListener("abort", () => {
219
251
  this._xhr = null;
252
+ if (gen !== this._gen) {
253
+ resolve(null);
254
+ return;
255
+ }
220
256
  this._setLoading(false);
221
257
  resolve(null);
222
258
  });
@@ -264,7 +300,7 @@ function registerAutoTrigger() {
264
300
  }
265
301
 
266
302
  class WcsUpload extends HTMLElement {
267
- static hasConnectedCallbackPromise = false;
303
+ static hasConnectedCallbackPromise = true;
268
304
  static wcBindable = {
269
305
  ...UploadCore.wcBindable,
270
306
  properties: [
@@ -298,10 +334,14 @@ class WcsUpload extends HTMLElement {
298
334
  _core;
299
335
  _files = null;
300
336
  _trigger = false;
337
+ _connectedCallbackPromise = Promise.resolve();
301
338
  constructor() {
302
339
  super();
303
340
  this._core = new UploadCore(this);
304
341
  }
342
+ get connectedCallbackPromise() {
343
+ return this._connectedCallbackPromise;
344
+ }
305
345
  // --- Attribute accessors ---
306
346
  get url() {
307
347
  return this.getAttribute("url") || "";
@@ -499,9 +539,10 @@ class WcsUpload extends HTMLElement {
499
539
  if (config.autoTrigger) {
500
540
  registerAutoTrigger();
501
541
  }
542
+ this._connectedCallbackPromise = this._core.observe();
502
543
  }
503
544
  disconnectedCallback() {
504
- this._core.abort();
545
+ this._core.dispose();
505
546
  }
506
547
  }
507
548
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/raiseError.ts","../src/core/UploadCore.ts","../src/autoTrigger.ts","../src/components/Upload.ts","../src/registerComponents.ts","../src/bootstrapUpload.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n upload: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-uploadtarget\",\n tagNames: {\n upload: \"wcs-upload\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// `config` は内部用のライブビュー(live view)。setConfig() の更新が即座に反映される\n// 実体 `_config` をそのまま公開しており、凍結もクローンもしていない。autoTrigger /\n// components など同パッケージ内のモジュールが最新値を読むための窓口であり、\n// 「変更不可なスナップショット」が必要な外部利用には getConfig()(凍結クローンを返す)\n// を使うこと。型が readonly なのは内部からの誤書き換えを抑止するための表明にすぎない。\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","export function raiseError(message: string): never {\n throw new Error(`[@wcstack/upload] ${message}`);\n}\n","import { raiseError } from \"../raiseError.js\";\nimport { IWcBindable } from \"../types.js\";\n\nexport interface UploadRequestOptions {\n method?: string;\n headers?: Record<string, string>;\n fieldName?: string;\n}\n\nexport class UploadCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-upload:loading-changed\" },\n { name: \"progress\", event: \"wcs-upload:progress\" },\n { name: \"error\", event: \"wcs-upload:error\" },\n { name: \"status\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.status },\n ],\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n ],\n commands: [\n { name: \"upload\", async: true },\n { name: \"abort\" },\n ],\n };\n\n private _target: EventTarget;\n private _value: any = null;\n private _loading: boolean = false;\n private _progress: number = 0;\n private _error: any = null;\n private _status: number = 0;\n private _xhr: XMLHttpRequest | null = null;\n private _promise: Promise<any> = Promise.resolve(null);\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get value(): any {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get progress(): number {\n return this._progress;\n }\n\n get error(): any {\n return this._error;\n }\n\n get status(): number {\n return this._status;\n }\n\n get promise(): Promise<any> {\n return this._promise;\n }\n\n // --- State setters with event dispatch ---\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n private _setProgress(progress: number): void {\n this._progress = progress;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:progress\", {\n detail: progress,\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setResponse(value: any, status: number): void {\n this._value = value;\n this._status = status;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:response\", {\n detail: { value, status },\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n abort(): void {\n // `_xhr` は send() の直前に同期で代入されるため、send 前に外部から abort が\n // 割り込む余地はない(割り込み点となる await が存在しない)。よって XHR.abort()\n // は常に進行中のリクエストに対して呼ばれ、abort イベントが発火して loading を\n // 解除する。loading の解除を abort イベントハンドラに集約しているのは、\n // ネットワークエラー/HTTP エラー/正常完了/中断のすべてで解除経路を一本化し、\n // FetchCore.abort() と挙動を揃えるため。\n if (this._xhr) {\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n async upload(url: string, files: FileList | File[], options: UploadRequestOptions = {}): Promise<any> {\n if (!url) {\n raiseError(\"url is required.\");\n }\n if (!files || files.length === 0) {\n raiseError(\"files are required.\");\n }\n\n const p = this._doUpload(url, files, options);\n this._promise = p;\n return p;\n }\n\n // --- Internal ---\n\n private _doUpload(url: string, files: FileList | File[], options: UploadRequestOptions): Promise<any> {\n // 既存のアップロードを中止\n this.abort();\n\n this._setLoading(true);\n this._setProgress(0);\n this._setError(null);\n\n const {\n method = \"POST\",\n headers = {},\n fieldName = \"file\",\n } = options;\n\n const formData = new FormData();\n for (let i = 0; i < files.length; i++) {\n formData.append(fieldName, files[i]);\n }\n\n return new Promise<any>((resolve) => {\n const xhr = new XMLHttpRequest();\n this._xhr = xhr;\n\n xhr.upload.addEventListener(\"progress\", (event: ProgressEvent) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded / event.total) * 100);\n this._setProgress(percent);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n this._xhr = null;\n this._status = xhr.status;\n\n if (xhr.status >= 200 && xhr.status < 300) {\n let value: any = xhr.responseText;\n const contentType = xhr.getResponseHeader(\"Content-Type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n value = JSON.parse(xhr.responseText);\n } catch {\n // テキストのまま\n }\n }\n this._setProgress(100);\n this._setResponse(value, xhr.status);\n this._setLoading(false);\n resolve(value);\n } else {\n const error = {\n status: xhr.status,\n statusText: xhr.statusText,\n body: xhr.responseText,\n };\n this._setError(error);\n this._setLoading(false);\n resolve(null);\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n this._xhr = null;\n this._setError({ message: \"Network error\" });\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.addEventListener(\"abort\", () => {\n this._xhr = null;\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.open(method, url);\n\n for (const [name, value] of Object.entries(headers)) {\n xhr.setRequestHeader(name, value);\n }\n\n xhr.send(formData);\n });\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsUpload } from \"./components/Upload.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const uploadId = triggerElement.getAttribute(config.triggerAttribute);\n if (!uploadId) return;\n\n // Resolve the registered constructor at call time instead of importing WcsUpload\n // as a value. The value import created a components/Upload.ts ⇄ autoTrigger.ts\n // cycle (WcsUpload.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-upload> class matches — without the import cycle.\n const UploadCtor = customElements.get(config.tagNames.upload);\n const el = document.getElementById(uploadId);\n if (!UploadCtor || !(el instanceof UploadCtor)) return;\n const uploadElement = el as WcsUpload;\n\n // ファイルと URL が揃っている場合のみ既定動作を抑止\n if (uploadElement.files && uploadElement.files.length > 0 && uploadElement.url) {\n event.preventDefault();\n }\n uploadElement.upload();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, WcsUploadError } from \"../types.js\";\nimport { UploadCore } from \"../core/UploadCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nexport class WcsUpload extends HTMLElement {\n static hasConnectedCallbackPromise = false;\n static wcBindable: IWcBindable = {\n ...UploadCore.wcBindable,\n properties: [\n ...UploadCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-upload:trigger-changed\" },\n { name: \"files\", event: \"wcs-upload:files-changed\" },\n ],\n // Shell-level input surface. The Core declares only the portable `url` / `method` /\n // `fieldName`; the Shell adds the DOM-driven settable surface. No `attribute` hints\n // are given: the `url` / `method` / `fieldName` / `multiple` / `maxSize` / `accept` /\n // `manual` setters already reflect to their attributes, so a binding system that\n // mirrors inputs[].attribute would set the attribute twice (`files` / `trigger` are\n // not attribute-backed). `commands` (upload / abort) are inherited unchanged from the\n // Core via the spread above.\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n { name: \"multiple\" },\n { name: \"maxSize\" },\n { name: \"accept\" },\n { name: \"manual\" },\n { name: \"files\" },\n { name: \"trigger\" },\n ],\n };\n // `url` を観測するのは FetchCore のシェルと構造を揃えるためだが、upload は\n // url 変更だけでは送信できない(files が必須)。そのため attributeChangedCallback は\n // 意図的に何もしない。url 変更で自動送信しないことは仕様であり、テストで担保している。\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: UploadCore;\n private _files: FileList | File[] | null = null;\n private _trigger: boolean = false;\n\n constructor() {\n super();\n this._core = new UploadCore(this);\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get method(): string {\n return (this.getAttribute(\"method\") || \"POST\").toUpperCase();\n }\n\n set method(value: string) {\n this.setAttribute(\"method\", value);\n }\n\n get fieldName(): string {\n return this.getAttribute(\"field-name\") || \"file\";\n }\n\n set fieldName(value: string) {\n this.setAttribute(\"field-name\", value);\n }\n\n get multiple(): boolean {\n return this.hasAttribute(\"multiple\");\n }\n\n set multiple(value: boolean) {\n if (value) {\n this.setAttribute(\"multiple\", \"\");\n } else {\n this.removeAttribute(\"multiple\");\n }\n }\n\n get maxSize(): number {\n const attr = this.getAttribute(\"max-size\");\n if (attr === null) {\n return Infinity;\n }\n // 不正値(NaN になる \"abc\" など)や負数は「制限なし」(Infinity) として扱う。\n // NaN を返すと `size > NaN` が常に false になりサイズ検証が無言で無効化され、\n // 負数を返すと全ファイルが拒否されるため、いずれも安全側の Infinity に丸める。\n const n = parseInt(attr, 10);\n return Number.isFinite(n) && n >= 0 ? n : Infinity;\n }\n\n set maxSize(value: number) {\n this.setAttribute(\"max-size\", String(value));\n }\n\n get accept(): string {\n return this.getAttribute(\"accept\") || \"\";\n }\n\n set accept(value: string) {\n this.setAttribute(\"accept\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get progress(): number {\n return this._core.progress;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get status(): number {\n return this._core.status;\n }\n\n get promise(): Promise<any> {\n return this._core.promise;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // 進行中に再度 trigger=true が来ても再入ガードはしない(FetchCore シェルと同一)。\n // upload() → _core.upload() が先頭で既存リクエストを abort し新規開始するため、\n // 連続トリガは「前回を中止して新しいアップロードを開始する」挙動になる。\n // 各 upload() の settle ごとに trigger-changed(false) が 1 回発火する。\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.upload().finally(() => {\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n });\n }\n }\n\n get files(): FileList | File[] | null {\n return this._files;\n }\n\n set files(value: FileList | File[] | null) {\n this._files = value;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: value,\n bubbles: true,\n }));\n if (!this.manual && this.url && value && value.length > 0) {\n this.upload();\n }\n }\n\n // --- Validation ---\n\n private _validate(files: FileList | File[]): WcsUploadError | null {\n const maxSize = this.maxSize;\n if (maxSize !== Infinity) {\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > maxSize) {\n return { message: `File \"${files[i].name}\" exceeds maximum size of ${maxSize} bytes.` };\n }\n }\n }\n\n const accept = this.accept;\n if (accept) {\n const acceptList = accept.split(\",\").map(s => s.trim().toLowerCase());\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n // file.type が空文字(OS が MIME を判定できないファイル)の場合、MIME 系\n // パターン(`image/*` / 厳密 MIME)は一致しない。その場合でも accept に\n // 拡張子パターン(`.pdf` 等)が含まれ拡張子が一致すれば受理される。\n // accept が MIME 系のみのときは型を確認できないため拒否する(安全側)。\n const matched = acceptList.some(pattern => {\n if (pattern.startsWith(\".\")) {\n return fileName.endsWith(pattern);\n }\n if (pattern.endsWith(\"/*\")) {\n return fileType !== \"\" && fileType.startsWith(pattern.slice(0, -1));\n }\n return fileType !== \"\" && fileType === pattern;\n });\n if (!matched) {\n return { message: `File \"${file.name}\" does not match accepted types: ${accept}` };\n }\n }\n }\n\n return null;\n }\n\n // --- Public methods ---\n\n abort(): void {\n this._core.abort();\n }\n\n async upload(): Promise<any> {\n const files = this._files;\n // url 未設定は no-op(null)。Core は url 空で throw するが、Shell は url/files の\n // ライフサイクルを所有しており「送信先が無い」を「ファイル無し」と同じ無操作として扱う。\n // これにより set trigger / set files の fire-and-forget 経路で unhandled rejection が\n // 発生せず、README の「upload() は全終了ケースで resolve し never reject」契約とも整合する。\n if (!files || files.length === 0 || !this.url) {\n return null;\n }\n\n const validationError = this._validate(files);\n if (validationError) {\n this.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: validationError,\n bubbles: true,\n }));\n return null;\n }\n\n const result = await this._core.upload(this.url, files, {\n method: this.method,\n fieldName: this.fieldName,\n });\n\n // 自分が開始したアップロードのファイルだけをリセット\n // (途中で新しい files がセットされていたら触らない)\n if (this._files === files) {\n this._files = null;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n return result;\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null): void {\n // 意図的に空。url 変更ではアップロードを自動実行しない(files が必要なため)。\n // observedAttributes のコメント参照。\n }\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n }\n\n disconnectedCallback(): void {\n this._core.abort();\n }\n}\n","import { WcsUpload } from \"./components/Upload.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.upload)) {\n customElements.define(config.tagNames.upload, WcsUpload);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapUpload(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/UploadCore.ts","../src/autoTrigger.ts","../src/components/Upload.ts","../src/registerComponents.ts","../src/bootstrapUpload.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n upload: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-uploadtarget\",\n tagNames: {\n upload: \"wcs-upload\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// `config` は内部用のライブビュー(live view)。setConfig() の更新が即座に反映される\n// 実体 `_config` をそのまま公開しており、凍結もクローンもしていない。autoTrigger /\n// components など同パッケージ内のモジュールが最新値を読むための窓口であり、\n// 「変更不可なスナップショット」が必要な外部利用には getConfig()(凍結クローンを返す)\n// を使うこと。型が readonly なのは内部からの誤書き換えを抑止するための表明にすぎない。\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface UploadRequestOptions {\n method?: string;\n headers?: Record<string, string>;\n fieldName?: string;\n}\n\nexport class UploadCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-upload:loading-changed\" },\n { name: \"progress\", event: \"wcs-upload:progress\" },\n { name: \"error\", event: \"wcs-upload:error\" },\n { name: \"status\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.status },\n ],\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n ],\n commands: [\n { name: \"upload\", async: true },\n { name: \"abort\" },\n ],\n };\n\n private _target: EventTarget;\n private _value: any = null;\n private _loading: boolean = false;\n private _progress: number = 0;\n private _error: any = null;\n private _status: number = 0;\n private _xhr: XMLHttpRequest | null = null;\n private _promise: Promise<any> = Promise.resolve(null);\n // Generation guard: bumped on dispose() (and each upload start). An in-flight\n // request that settles after dispose / a superseding start has a stale `gen`\n // and MUST NOT write state to a torn-down element. A boolean flag is\n // insufficient (dispose→observe would let stale work slip through).\n private _gen = 0;\n // SSR: no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). Upload is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() invalidates any in-flight request and aborts it.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.abort();\n }\n\n get value(): any {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get progress(): number {\n return this._progress;\n }\n\n get error(): any {\n return this._error;\n }\n\n get status(): number {\n return this._status;\n }\n\n get promise(): Promise<any> {\n return this._promise;\n }\n\n // --- State setters with event dispatch ---\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n private _setProgress(progress: number): void {\n this._progress = progress;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:progress\", {\n detail: progress,\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setResponse(value: any, status: number): void {\n this._value = value;\n this._status = status;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:response\", {\n detail: { value, status },\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n abort(): void {\n // `_xhr` は send() の直前に同期で代入されるため、send 前に外部から abort が\n // 割り込む余地はない(割り込み点となる await が存在しない)。よって XHR.abort()\n // は常に進行中のリクエストに対して呼ばれ、abort イベントが発火して loading を\n // 解除する。loading の解除を abort イベントハンドラに集約しているのは、\n // ネットワークエラー/HTTP エラー/正常完了/中断のすべてで解除経路を一本化し、\n // FetchCore.abort() と挙動を揃えるため。\n if (this._xhr) {\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n async upload(url: string, files: FileList | File[], options: UploadRequestOptions = {}): Promise<any> {\n // never-throw: 引数バリデーション失敗は例外ではなく error プロパティに流し、\n // サニタイズ値(null)を返す。command-token 経路からの呼び出しが unhandled\n // rejection にならず、「upload() は全終了ケースで resolve」契約とも整合する。\n if (!url) {\n this._setError({ message: \"url is required.\" });\n return null;\n }\n if (!files || files.length === 0) {\n this._setError({ message: \"files are required.\" });\n return null;\n }\n\n const p = this._doUpload(url, files, options);\n this._promise = p;\n return p;\n }\n\n // --- Internal ---\n\n private _doUpload(url: string, files: FileList | File[], options: UploadRequestOptions): Promise<any> {\n // 既存のアップロードを中止\n this.abort();\n\n this._setLoading(true);\n this._setProgress(0);\n this._setError(null);\n\n const {\n method = \"POST\",\n headers = {},\n fieldName = \"file\",\n } = options;\n\n const formData = new FormData();\n for (let i = 0; i < files.length; i++) {\n formData.append(fieldName, files[i]);\n }\n\n const gen = ++this._gen;\n\n return new Promise<any>((resolve) => {\n const xhr = new XMLHttpRequest();\n this._xhr = xhr;\n\n xhr.upload.addEventListener(\"progress\", (event: ProgressEvent) => {\n if (gen !== this._gen) return;\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded / event.total) * 100);\n this._setProgress(percent);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._status = xhr.status;\n\n if (xhr.status >= 200 && xhr.status < 300) {\n let value: any = xhr.responseText;\n const contentType = xhr.getResponseHeader(\"Content-Type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n value = JSON.parse(xhr.responseText);\n } catch {\n // テキストのまま\n }\n }\n this._setProgress(100);\n this._setResponse(value, xhr.status);\n this._setLoading(false);\n resolve(value);\n } else {\n const error = {\n status: xhr.status,\n statusText: xhr.statusText,\n body: xhr.responseText,\n };\n this._setError(error);\n this._setLoading(false);\n resolve(null);\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._setError({ message: \"Network error\" });\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.addEventListener(\"abort\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.open(method, url);\n\n for (const [name, value] of Object.entries(headers)) {\n xhr.setRequestHeader(name, value);\n }\n\n xhr.send(formData);\n });\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsUpload } from \"./components/Upload.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const uploadId = triggerElement.getAttribute(config.triggerAttribute);\n if (!uploadId) return;\n\n // Resolve the registered constructor at call time instead of importing WcsUpload\n // as a value. The value import created a components/Upload.ts ⇄ autoTrigger.ts\n // cycle (WcsUpload.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-upload> class matches — without the import cycle.\n const UploadCtor = customElements.get(config.tagNames.upload);\n const el = document.getElementById(uploadId);\n if (!UploadCtor || !(el instanceof UploadCtor)) return;\n const uploadElement = el as WcsUpload;\n\n // ファイルと URL が揃っている場合のみ既定動作を抑止\n if (uploadElement.files && uploadElement.files.length > 0 && uploadElement.url) {\n event.preventDefault();\n }\n uploadElement.upload();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, WcsUploadError } from \"../types.js\";\nimport { UploadCore } from \"../core/UploadCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nexport class WcsUpload extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...UploadCore.wcBindable,\n properties: [\n ...UploadCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-upload:trigger-changed\" },\n { name: \"files\", event: \"wcs-upload:files-changed\" },\n ],\n // Shell-level input surface. The Core declares only the portable `url` / `method` /\n // `fieldName`; the Shell adds the DOM-driven settable surface. No `attribute` hints\n // are given: the `url` / `method` / `fieldName` / `multiple` / `maxSize` / `accept` /\n // `manual` setters already reflect to their attributes, so a binding system that\n // mirrors inputs[].attribute would set the attribute twice (`files` / `trigger` are\n // not attribute-backed). `commands` (upload / abort) are inherited unchanged from the\n // Core via the spread above.\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n { name: \"multiple\" },\n { name: \"maxSize\" },\n { name: \"accept\" },\n { name: \"manual\" },\n { name: \"files\" },\n { name: \"trigger\" },\n ],\n };\n // `url` を観測するのは FetchCore のシェルと構造を揃えるためだが、upload は\n // url 変更だけでは送信できない(files が必須)。そのため attributeChangedCallback は\n // 意図的に何もしない。url 変更で自動送信しないことは仕様であり、テストで担保している。\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: UploadCore;\n private _files: FileList | File[] | null = null;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new UploadCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get method(): string {\n return (this.getAttribute(\"method\") || \"POST\").toUpperCase();\n }\n\n set method(value: string) {\n this.setAttribute(\"method\", value);\n }\n\n get fieldName(): string {\n return this.getAttribute(\"field-name\") || \"file\";\n }\n\n set fieldName(value: string) {\n this.setAttribute(\"field-name\", value);\n }\n\n get multiple(): boolean {\n return this.hasAttribute(\"multiple\");\n }\n\n set multiple(value: boolean) {\n if (value) {\n this.setAttribute(\"multiple\", \"\");\n } else {\n this.removeAttribute(\"multiple\");\n }\n }\n\n get maxSize(): number {\n const attr = this.getAttribute(\"max-size\");\n if (attr === null) {\n return Infinity;\n }\n // 不正値(NaN になる \"abc\" など)や負数は「制限なし」(Infinity) として扱う。\n // NaN を返すと `size > NaN` が常に false になりサイズ検証が無言で無効化され、\n // 負数を返すと全ファイルが拒否されるため、いずれも安全側の Infinity に丸める。\n const n = parseInt(attr, 10);\n return Number.isFinite(n) && n >= 0 ? n : Infinity;\n }\n\n set maxSize(value: number) {\n this.setAttribute(\"max-size\", String(value));\n }\n\n get accept(): string {\n return this.getAttribute(\"accept\") || \"\";\n }\n\n set accept(value: string) {\n this.setAttribute(\"accept\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get progress(): number {\n return this._core.progress;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get status(): number {\n return this._core.status;\n }\n\n get promise(): Promise<any> {\n return this._core.promise;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // 進行中に再度 trigger=true が来ても再入ガードはしない(FetchCore シェルと同一)。\n // upload() → _core.upload() が先頭で既存リクエストを abort し新規開始するため、\n // 連続トリガは「前回を中止して新しいアップロードを開始する」挙動になる。\n // 各 upload() の settle ごとに trigger-changed(false) が 1 回発火する。\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.upload().finally(() => {\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n });\n }\n }\n\n get files(): FileList | File[] | null {\n return this._files;\n }\n\n set files(value: FileList | File[] | null) {\n this._files = value;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: value,\n bubbles: true,\n }));\n if (!this.manual && this.url && value && value.length > 0) {\n this.upload();\n }\n }\n\n // --- Validation ---\n\n private _validate(files: FileList | File[]): WcsUploadError | null {\n const maxSize = this.maxSize;\n if (maxSize !== Infinity) {\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > maxSize) {\n return { message: `File \"${files[i].name}\" exceeds maximum size of ${maxSize} bytes.` };\n }\n }\n }\n\n const accept = this.accept;\n if (accept) {\n const acceptList = accept.split(\",\").map(s => s.trim().toLowerCase());\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n // file.type が空文字(OS が MIME を判定できないファイル)の場合、MIME 系\n // パターン(`image/*` / 厳密 MIME)は一致しない。その場合でも accept に\n // 拡張子パターン(`.pdf` 等)が含まれ拡張子が一致すれば受理される。\n // accept が MIME 系のみのときは型を確認できないため拒否する(安全側)。\n const matched = acceptList.some(pattern => {\n if (pattern.startsWith(\".\")) {\n return fileName.endsWith(pattern);\n }\n if (pattern.endsWith(\"/*\")) {\n return fileType !== \"\" && fileType.startsWith(pattern.slice(0, -1));\n }\n return fileType !== \"\" && fileType === pattern;\n });\n if (!matched) {\n return { message: `File \"${file.name}\" does not match accepted types: ${accept}` };\n }\n }\n }\n\n return null;\n }\n\n // --- Public methods ---\n\n abort(): void {\n this._core.abort();\n }\n\n async upload(): Promise<any> {\n const files = this._files;\n // url 未設定は no-op(null)。Core は url 空で throw するが、Shell は url/files の\n // ライフサイクルを所有しており「送信先が無い」を「ファイル無し」と同じ無操作として扱う。\n // これにより set trigger / set files の fire-and-forget 経路で unhandled rejection が\n // 発生せず、README の「upload() は全終了ケースで resolve し never reject」契約とも整合する。\n if (!files || files.length === 0 || !this.url) {\n return null;\n }\n\n const validationError = this._validate(files);\n if (validationError) {\n this.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: validationError,\n bubbles: true,\n }));\n return null;\n }\n\n const result = await this._core.upload(this.url, files, {\n method: this.method,\n fieldName: this.fieldName,\n });\n\n // 自分が開始したアップロードのファイルだけをリセット\n // (途中で新しい files がセットされていたら触らない)\n if (this._files === files) {\n this._files = null;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n return result;\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null): void {\n // 意図的に空。url 変更ではアップロードを自動実行しない(files が必要なため)。\n // observedAttributes のコメント参照。\n }\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsUpload } from \"./components/Upload.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.upload)) {\n customElements.define(config.tagNames.upload, WcsUpload);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapUpload(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const t={autoTrigger:!0,triggerAttribute:"data-uploadtarget",tagNames:{upload:"wcs-upload"}};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const s of Object.keys(t))e(t[s]);return t}function s(t){if(null===t||"object"!=typeof t)return t;const e={};for(const r of Object.keys(t))e[r]=s(t[r]);return e}let r=null;const i=t;function n(){return r||(r=e(s(t))),r}function a(t){throw new Error(`[@wcstack/upload] ${t}`)}class o extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-upload:response",getter:t=>t.detail.value},{name:"loading",event:"wcs-upload:loading-changed"},{name:"progress",event:"wcs-upload:progress"},{name:"error",event:"wcs-upload:error"},{name:"status",event:"wcs-upload:response",getter:t=>t.detail.status}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"}],commands:[{name:"upload",async:!0},{name:"abort"}]};_target;_value=null;_loading=!1;_progress=0;_error=null;_status=0;_xhr=null;_promise=Promise.resolve(null);constructor(t){super(),this._target=t??this}get value(){return this._value}get loading(){return this._loading}get progress(){return this._progress}get error(){return this._error}get status(){return this._status}get promise(){return this._promise}_setLoading(t){this._loading=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:loading-changed",{detail:t,bubbles:!0}))}_setProgress(t){this._progress=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:progress",{detail:t,bubbles:!0}))}_setError(t){this._error=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:t,bubbles:!0}))}_setResponse(t,e){this._value=t,this._status=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:response",{detail:{value:t,status:e},bubbles:!0}))}abort(){this._xhr&&(this._xhr.abort(),this._xhr=null)}async upload(t,e,s={}){t||a("url is required."),e&&0!==e.length||a("files are required.");const r=this._doUpload(t,e,s);return this._promise=r,r}_doUpload(t,e,s){this.abort(),this._setLoading(!0),this._setProgress(0),this._setError(null);const{method:r="POST",headers:i={},fieldName:n="file"}=s,a=new FormData;for(let t=0;t<e.length;t++)a.append(n,e[t]);return new Promise(e=>{const s=new XMLHttpRequest;this._xhr=s,s.upload.addEventListener("progress",t=>{if(t.lengthComputable){const e=Math.round(t.loaded/t.total*100);this._setProgress(e)}}),s.addEventListener("load",()=>{if(this._xhr=null,this._status=s.status,s.status>=200&&s.status<300){let t=s.responseText;if((s.getResponseHeader("Content-Type")||"").includes("application/json"))try{t=JSON.parse(s.responseText)}catch{}this._setProgress(100),this._setResponse(t,s.status),this._setLoading(!1),e(t)}else{const t={status:s.status,statusText:s.statusText,body:s.responseText};this._setError(t),this._setLoading(!1),e(null)}}),s.addEventListener("error",()=>{this._xhr=null,this._setError({message:"Network error"}),this._setLoading(!1),e(null)}),s.addEventListener("abort",()=>{this._xhr=null,this._setLoading(!1),e(null)}),s.open(r,t);for(const[t,e]of Object.entries(i))s.setRequestHeader(t,e);s.send(a)})}}let l=!1;function u(t){const e=t.target;if(!(e instanceof Element))return;const s=e.closest(`[${i.triggerAttribute}]`);if(!s)return;const r=s.getAttribute(i.triggerAttribute);if(!r)return;const n=customElements.get(i.tagNames.upload),a=document.getElementById(r);if(!(n&&a instanceof n))return;const o=a;o.files&&o.files.length>0&&o.url&&t.preventDefault(),o.upload()}class h extends HTMLElement{static hasConnectedCallbackPromise=!1;static wcBindable={...o.wcBindable,properties:[...o.wcBindable.properties,{name:"trigger",event:"wcs-upload:trigger-changed"},{name:"files",event:"wcs-upload:files-changed"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"},{name:"multiple"},{name:"maxSize"},{name:"accept"},{name:"manual"},{name:"files"},{name:"trigger"}]};static get observedAttributes(){return["url"]}_core;_files=null;_trigger=!1;constructor(){super(),this._core=new o(this)}get url(){return this.getAttribute("url")||""}set url(t){this.setAttribute("url",t)}get method(){return(this.getAttribute("method")||"POST").toUpperCase()}set method(t){this.setAttribute("method",t)}get fieldName(){return this.getAttribute("field-name")||"file"}set fieldName(t){this.setAttribute("field-name",t)}get multiple(){return this.hasAttribute("multiple")}set multiple(t){t?this.setAttribute("multiple",""):this.removeAttribute("multiple")}get maxSize(){const t=this.getAttribute("max-size");if(null===t)return 1/0;const e=parseInt(t,10);return Number.isFinite(e)&&e>=0?e:1/0}set maxSize(t){this.setAttribute("max-size",String(t))}get accept(){return this.getAttribute("accept")||""}set accept(t){this.setAttribute("accept",t)}get manual(){return this.hasAttribute("manual")}set manual(t){t?this.setAttribute("manual",""):this.removeAttribute("manual")}get value(){return this._core.value}get loading(){return this._core.loading}get progress(){return this._core.progress}get error(){return this._core.error}get status(){return this._core.status}get promise(){return this._core.promise}get trigger(){return this._trigger}set trigger(t){!!t&&(this._trigger=!0,this.upload().finally(()=>{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-upload:trigger-changed",{detail:!1,bubbles:!0}))}))}get files(){return this._files}set files(t){this._files=t,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:t,bubbles:!0})),!this.manual&&this.url&&t&&t.length>0&&this.upload()}_validate(t){const e=this.maxSize;if(e!==1/0)for(let s=0;s<t.length;s++)if(t[s].size>e)return{message:`File "${t[s].name}" exceeds maximum size of ${e} bytes.`};const s=this.accept;if(s){const e=s.split(",").map(t=>t.trim().toLowerCase());for(let r=0;r<t.length;r++){const i=t[r],n=i.type.toLowerCase(),a=i.name.toLowerCase();if(!e.some(t=>t.startsWith(".")?a.endsWith(t):t.endsWith("/*")?""!==n&&n.startsWith(t.slice(0,-1)):""!==n&&n===t))return{message:`File "${i.name}" does not match accepted types: ${s}`}}}return null}abort(){this._core.abort()}async upload(){const t=this._files;if(!t||0===t.length||!this.url)return null;const e=this._validate(t);if(e)return this.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:e,bubbles:!0})),null;const s=await this._core.upload(this.url,t,{method:this.method,fieldName:this.fieldName});return this._files===t&&(this._files=null,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:null,bubbles:!0}))),s}attributeChangedCallback(t,e,s){}connectedCallback(){this.style.display="none",i.autoTrigger&&(l||(l=!0,document.addEventListener("click",u)))}disconnectedCallback(){this._core.abort()}}function g(e){var s;e&&("boolean"==typeof(s=e).autoTrigger&&(t.autoTrigger=s.autoTrigger),"string"==typeof s.triggerAttribute&&(t.triggerAttribute=s.triggerAttribute),s.tagNames&&Object.assign(t.tagNames,s.tagNames),r=null),customElements.get(i.tagNames.upload)||customElements.define(i.tagNames.upload,h)}export{o as UploadCore,h as WcsUpload,g as bootstrapUpload,n as getConfig};
1
+ const e={autoTrigger:!0,triggerAttribute:"data-uploadtarget",tagNames:{upload:"wcs-upload"}};function t(e){if(null===e||"object"!=typeof e)return e;Object.freeze(e);for(const s of Object.keys(e))t(e[s]);return e}function s(e){if(null===e||"object"!=typeof e)return e;const t={};for(const r of Object.keys(e))t[r]=s(e[r]);return t}let r=null;const i=e;function n(){return r||(r=t(s(e))),r}class a extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"value",event:"wcs-upload:response",getter:e=>e.detail.value},{name:"loading",event:"wcs-upload:loading-changed"},{name:"progress",event:"wcs-upload:progress"},{name:"error",event:"wcs-upload:error"},{name:"status",event:"wcs-upload:response",getter:e=>e.detail.status}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"}],commands:[{name:"upload",async:!0},{name:"abort"}]};_target;_value=null;_loading=!1;_progress=0;_error=null;_status=0;_xhr=null;_promise=Promise.resolve(null);_gen=0;_ready=Promise.resolve();constructor(e){super(),this._target=e??this}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.abort()}get value(){return this._value}get loading(){return this._loading}get progress(){return this._progress}get error(){return this._error}get status(){return this._status}get promise(){return this._promise}_setLoading(e){this._loading=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:loading-changed",{detail:e,bubbles:!0}))}_setProgress(e){this._progress=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:progress",{detail:e,bubbles:!0}))}_setError(e){this._error=e,this._target.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:e,bubbles:!0}))}_setResponse(e,t){this._value=e,this._status=t,this._target.dispatchEvent(new CustomEvent("wcs-upload:response",{detail:{value:e,status:t},bubbles:!0}))}abort(){this._xhr&&(this._xhr.abort(),this._xhr=null)}async upload(e,t,s={}){if(!e)return this._setError({message:"url is required."}),null;if(!t||0===t.length)return this._setError({message:"files are required."}),null;const r=this._doUpload(e,t,s);return this._promise=r,r}_doUpload(e,t,s){this.abort(),this._setLoading(!0),this._setProgress(0),this._setError(null);const{method:r="POST",headers:i={},fieldName:n="file"}=s,a=new FormData;for(let e=0;e<t.length;e++)a.append(n,t[e]);const o=++this._gen;return new Promise(t=>{const s=new XMLHttpRequest;this._xhr=s,s.upload.addEventListener("progress",e=>{if(o===this._gen&&e.lengthComputable){const t=Math.round(e.loaded/e.total*100);this._setProgress(t)}}),s.addEventListener("load",()=>{if(this._xhr=null,o===this._gen)if(this._status=s.status,s.status>=200&&s.status<300){let e=s.responseText;if((s.getResponseHeader("Content-Type")||"").includes("application/json"))try{e=JSON.parse(s.responseText)}catch{}this._setProgress(100),this._setResponse(e,s.status),this._setLoading(!1),t(e)}else{const e={status:s.status,statusText:s.statusText,body:s.responseText};this._setError(e),this._setLoading(!1),t(null)}else t(null)}),s.addEventListener("error",()=>{this._xhr=null,o===this._gen?(this._setError({message:"Network error"}),this._setLoading(!1),t(null)):t(null)}),s.addEventListener("abort",()=>{this._xhr=null,o===this._gen?(this._setLoading(!1),t(null)):t(null)}),s.open(r,e);for(const[e,t]of Object.entries(i))s.setRequestHeader(e,t);s.send(a)})}}let o=!1;function l(e){const t=e.target;if(!(t instanceof Element))return;const s=t.closest(`[${i.triggerAttribute}]`);if(!s)return;const r=s.getAttribute(i.triggerAttribute);if(!r)return;const n=customElements.get(i.tagNames.upload),a=document.getElementById(r);if(!(n&&a instanceof n))return;const o=a;o.files&&o.files.length>0&&o.url&&e.preventDefault(),o.upload()}class u extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...a.wcBindable,properties:[...a.wcBindable.properties,{name:"trigger",event:"wcs-upload:trigger-changed"},{name:"files",event:"wcs-upload:files-changed"}],inputs:[{name:"url"},{name:"method"},{name:"fieldName"},{name:"multiple"},{name:"maxSize"},{name:"accept"},{name:"manual"},{name:"files"},{name:"trigger"}]};static get observedAttributes(){return["url"]}_core;_files=null;_trigger=!1;_connectedCallbackPromise=Promise.resolve();constructor(){super(),this._core=new a(this)}get connectedCallbackPromise(){return this._connectedCallbackPromise}get url(){return this.getAttribute("url")||""}set url(e){this.setAttribute("url",e)}get method(){return(this.getAttribute("method")||"POST").toUpperCase()}set method(e){this.setAttribute("method",e)}get fieldName(){return this.getAttribute("field-name")||"file"}set fieldName(e){this.setAttribute("field-name",e)}get multiple(){return this.hasAttribute("multiple")}set multiple(e){e?this.setAttribute("multiple",""):this.removeAttribute("multiple")}get maxSize(){const e=this.getAttribute("max-size");if(null===e)return 1/0;const t=parseInt(e,10);return Number.isFinite(t)&&t>=0?t:1/0}set maxSize(e){this.setAttribute("max-size",String(e))}get accept(){return this.getAttribute("accept")||""}set accept(e){this.setAttribute("accept",e)}get manual(){return this.hasAttribute("manual")}set manual(e){e?this.setAttribute("manual",""):this.removeAttribute("manual")}get value(){return this._core.value}get loading(){return this._core.loading}get progress(){return this._core.progress}get error(){return this._core.error}get status(){return this._core.status}get promise(){return this._core.promise}get trigger(){return this._trigger}set trigger(e){!!e&&(this._trigger=!0,this.upload().finally(()=>{this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-upload:trigger-changed",{detail:!1,bubbles:!0}))}))}get files(){return this._files}set files(e){this._files=e,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:e,bubbles:!0})),!this.manual&&this.url&&e&&e.length>0&&this.upload()}_validate(e){const t=this.maxSize;if(t!==1/0)for(let s=0;s<e.length;s++)if(e[s].size>t)return{message:`File "${e[s].name}" exceeds maximum size of ${t} bytes.`};const s=this.accept;if(s){const t=s.split(",").map(e=>e.trim().toLowerCase());for(let r=0;r<e.length;r++){const i=e[r],n=i.type.toLowerCase(),a=i.name.toLowerCase();if(!t.some(e=>e.startsWith(".")?a.endsWith(e):e.endsWith("/*")?""!==n&&n.startsWith(e.slice(0,-1)):""!==n&&n===e))return{message:`File "${i.name}" does not match accepted types: ${s}`}}}return null}abort(){this._core.abort()}async upload(){const e=this._files;if(!e||0===e.length||!this.url)return null;const t=this._validate(e);if(t)return this.dispatchEvent(new CustomEvent("wcs-upload:error",{detail:t,bubbles:!0})),null;const s=await this._core.upload(this.url,e,{method:this.method,fieldName:this.fieldName});return this._files===e&&(this._files=null,this.dispatchEvent(new CustomEvent("wcs-upload:files-changed",{detail:null,bubbles:!0}))),s}attributeChangedCallback(e,t,s){}connectedCallback(){this.style.display="none",i.autoTrigger&&(o||(o=!0,document.addEventListener("click",l))),this._connectedCallbackPromise=this._core.observe()}disconnectedCallback(){this._core.dispose()}}function h(t){var s;t&&("boolean"==typeof(s=t).autoTrigger&&(e.autoTrigger=s.autoTrigger),"string"==typeof s.triggerAttribute&&(e.triggerAttribute=s.triggerAttribute),s.tagNames&&Object.assign(e.tagNames,s.tagNames),r=null),customElements.get(i.tagNames.upload)||customElements.define(i.tagNames.upload,u)}export{a as UploadCore,u as WcsUpload,h as bootstrapUpload,n as getConfig};
2
2
  //# sourceMappingURL=index.esm.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/raiseError.ts","../src/core/UploadCore.ts","../src/autoTrigger.ts","../src/components/Upload.ts","../src/bootstrapUpload.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n upload: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-uploadtarget\",\n tagNames: {\n upload: \"wcs-upload\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// `config` は内部用のライブビュー(live view)。setConfig() の更新が即座に反映される\n// 実体 `_config` をそのまま公開しており、凍結もクローンもしていない。autoTrigger /\n// components など同パッケージ内のモジュールが最新値を読むための窓口であり、\n// 「変更不可なスナップショット」が必要な外部利用には getConfig()(凍結クローンを返す)\n// を使うこと。型が readonly なのは内部からの誤書き換えを抑止するための表明にすぎない。\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","export function raiseError(message: string): never {\n throw new Error(`[@wcstack/upload] ${message}`);\n}\n","import { raiseError } from \"../raiseError.js\";\nimport { IWcBindable } from \"../types.js\";\n\nexport interface UploadRequestOptions {\n method?: string;\n headers?: Record<string, string>;\n fieldName?: string;\n}\n\nexport class UploadCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-upload:loading-changed\" },\n { name: \"progress\", event: \"wcs-upload:progress\" },\n { name: \"error\", event: \"wcs-upload:error\" },\n { name: \"status\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.status },\n ],\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n ],\n commands: [\n { name: \"upload\", async: true },\n { name: \"abort\" },\n ],\n };\n\n private _target: EventTarget;\n private _value: any = null;\n private _loading: boolean = false;\n private _progress: number = 0;\n private _error: any = null;\n private _status: number = 0;\n private _xhr: XMLHttpRequest | null = null;\n private _promise: Promise<any> = Promise.resolve(null);\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get value(): any {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get progress(): number {\n return this._progress;\n }\n\n get error(): any {\n return this._error;\n }\n\n get status(): number {\n return this._status;\n }\n\n get promise(): Promise<any> {\n return this._promise;\n }\n\n // --- State setters with event dispatch ---\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n private _setProgress(progress: number): void {\n this._progress = progress;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:progress\", {\n detail: progress,\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setResponse(value: any, status: number): void {\n this._value = value;\n this._status = status;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:response\", {\n detail: { value, status },\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n abort(): void {\n // `_xhr` は send() の直前に同期で代入されるため、send 前に外部から abort が\n // 割り込む余地はない(割り込み点となる await が存在しない)。よって XHR.abort()\n // は常に進行中のリクエストに対して呼ばれ、abort イベントが発火して loading を\n // 解除する。loading の解除を abort イベントハンドラに集約しているのは、\n // ネットワークエラー/HTTP エラー/正常完了/中断のすべてで解除経路を一本化し、\n // FetchCore.abort() と挙動を揃えるため。\n if (this._xhr) {\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n async upload(url: string, files: FileList | File[], options: UploadRequestOptions = {}): Promise<any> {\n if (!url) {\n raiseError(\"url is required.\");\n }\n if (!files || files.length === 0) {\n raiseError(\"files are required.\");\n }\n\n const p = this._doUpload(url, files, options);\n this._promise = p;\n return p;\n }\n\n // --- Internal ---\n\n private _doUpload(url: string, files: FileList | File[], options: UploadRequestOptions): Promise<any> {\n // 既存のアップロードを中止\n this.abort();\n\n this._setLoading(true);\n this._setProgress(0);\n this._setError(null);\n\n const {\n method = \"POST\",\n headers = {},\n fieldName = \"file\",\n } = options;\n\n const formData = new FormData();\n for (let i = 0; i < files.length; i++) {\n formData.append(fieldName, files[i]);\n }\n\n return new Promise<any>((resolve) => {\n const xhr = new XMLHttpRequest();\n this._xhr = xhr;\n\n xhr.upload.addEventListener(\"progress\", (event: ProgressEvent) => {\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded / event.total) * 100);\n this._setProgress(percent);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n this._xhr = null;\n this._status = xhr.status;\n\n if (xhr.status >= 200 && xhr.status < 300) {\n let value: any = xhr.responseText;\n const contentType = xhr.getResponseHeader(\"Content-Type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n value = JSON.parse(xhr.responseText);\n } catch {\n // テキストのまま\n }\n }\n this._setProgress(100);\n this._setResponse(value, xhr.status);\n this._setLoading(false);\n resolve(value);\n } else {\n const error = {\n status: xhr.status,\n statusText: xhr.statusText,\n body: xhr.responseText,\n };\n this._setError(error);\n this._setLoading(false);\n resolve(null);\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n this._xhr = null;\n this._setError({ message: \"Network error\" });\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.addEventListener(\"abort\", () => {\n this._xhr = null;\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.open(method, url);\n\n for (const [name, value] of Object.entries(headers)) {\n xhr.setRequestHeader(name, value);\n }\n\n xhr.send(formData);\n });\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsUpload } from \"./components/Upload.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const uploadId = triggerElement.getAttribute(config.triggerAttribute);\n if (!uploadId) return;\n\n // Resolve the registered constructor at call time instead of importing WcsUpload\n // as a value. The value import created a components/Upload.ts ⇄ autoTrigger.ts\n // cycle (WcsUpload.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-upload> class matches — without the import cycle.\n const UploadCtor = customElements.get(config.tagNames.upload);\n const el = document.getElementById(uploadId);\n if (!UploadCtor || !(el instanceof UploadCtor)) return;\n const uploadElement = el as WcsUpload;\n\n // ファイルと URL が揃っている場合のみ既定動作を抑止\n if (uploadElement.files && uploadElement.files.length > 0 && uploadElement.url) {\n event.preventDefault();\n }\n uploadElement.upload();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, WcsUploadError } from \"../types.js\";\nimport { UploadCore } from \"../core/UploadCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nexport class WcsUpload extends HTMLElement {\n static hasConnectedCallbackPromise = false;\n static wcBindable: IWcBindable = {\n ...UploadCore.wcBindable,\n properties: [\n ...UploadCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-upload:trigger-changed\" },\n { name: \"files\", event: \"wcs-upload:files-changed\" },\n ],\n // Shell-level input surface. The Core declares only the portable `url` / `method` /\n // `fieldName`; the Shell adds the DOM-driven settable surface. No `attribute` hints\n // are given: the `url` / `method` / `fieldName` / `multiple` / `maxSize` / `accept` /\n // `manual` setters already reflect to their attributes, so a binding system that\n // mirrors inputs[].attribute would set the attribute twice (`files` / `trigger` are\n // not attribute-backed). `commands` (upload / abort) are inherited unchanged from the\n // Core via the spread above.\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n { name: \"multiple\" },\n { name: \"maxSize\" },\n { name: \"accept\" },\n { name: \"manual\" },\n { name: \"files\" },\n { name: \"trigger\" },\n ],\n };\n // `url` を観測するのは FetchCore のシェルと構造を揃えるためだが、upload は\n // url 変更だけでは送信できない(files が必須)。そのため attributeChangedCallback は\n // 意図的に何もしない。url 変更で自動送信しないことは仕様であり、テストで担保している。\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: UploadCore;\n private _files: FileList | File[] | null = null;\n private _trigger: boolean = false;\n\n constructor() {\n super();\n this._core = new UploadCore(this);\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get method(): string {\n return (this.getAttribute(\"method\") || \"POST\").toUpperCase();\n }\n\n set method(value: string) {\n this.setAttribute(\"method\", value);\n }\n\n get fieldName(): string {\n return this.getAttribute(\"field-name\") || \"file\";\n }\n\n set fieldName(value: string) {\n this.setAttribute(\"field-name\", value);\n }\n\n get multiple(): boolean {\n return this.hasAttribute(\"multiple\");\n }\n\n set multiple(value: boolean) {\n if (value) {\n this.setAttribute(\"multiple\", \"\");\n } else {\n this.removeAttribute(\"multiple\");\n }\n }\n\n get maxSize(): number {\n const attr = this.getAttribute(\"max-size\");\n if (attr === null) {\n return Infinity;\n }\n // 不正値(NaN になる \"abc\" など)や負数は「制限なし」(Infinity) として扱う。\n // NaN を返すと `size > NaN` が常に false になりサイズ検証が無言で無効化され、\n // 負数を返すと全ファイルが拒否されるため、いずれも安全側の Infinity に丸める。\n const n = parseInt(attr, 10);\n return Number.isFinite(n) && n >= 0 ? n : Infinity;\n }\n\n set maxSize(value: number) {\n this.setAttribute(\"max-size\", String(value));\n }\n\n get accept(): string {\n return this.getAttribute(\"accept\") || \"\";\n }\n\n set accept(value: string) {\n this.setAttribute(\"accept\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get progress(): number {\n return this._core.progress;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get status(): number {\n return this._core.status;\n }\n\n get promise(): Promise<any> {\n return this._core.promise;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // 進行中に再度 trigger=true が来ても再入ガードはしない(FetchCore シェルと同一)。\n // upload() → _core.upload() が先頭で既存リクエストを abort し新規開始するため、\n // 連続トリガは「前回を中止して新しいアップロードを開始する」挙動になる。\n // 各 upload() の settle ごとに trigger-changed(false) が 1 回発火する。\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.upload().finally(() => {\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n });\n }\n }\n\n get files(): FileList | File[] | null {\n return this._files;\n }\n\n set files(value: FileList | File[] | null) {\n this._files = value;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: value,\n bubbles: true,\n }));\n if (!this.manual && this.url && value && value.length > 0) {\n this.upload();\n }\n }\n\n // --- Validation ---\n\n private _validate(files: FileList | File[]): WcsUploadError | null {\n const maxSize = this.maxSize;\n if (maxSize !== Infinity) {\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > maxSize) {\n return { message: `File \"${files[i].name}\" exceeds maximum size of ${maxSize} bytes.` };\n }\n }\n }\n\n const accept = this.accept;\n if (accept) {\n const acceptList = accept.split(\",\").map(s => s.trim().toLowerCase());\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n // file.type が空文字(OS が MIME を判定できないファイル)の場合、MIME 系\n // パターン(`image/*` / 厳密 MIME)は一致しない。その場合でも accept に\n // 拡張子パターン(`.pdf` 等)が含まれ拡張子が一致すれば受理される。\n // accept が MIME 系のみのときは型を確認できないため拒否する(安全側)。\n const matched = acceptList.some(pattern => {\n if (pattern.startsWith(\".\")) {\n return fileName.endsWith(pattern);\n }\n if (pattern.endsWith(\"/*\")) {\n return fileType !== \"\" && fileType.startsWith(pattern.slice(0, -1));\n }\n return fileType !== \"\" && fileType === pattern;\n });\n if (!matched) {\n return { message: `File \"${file.name}\" does not match accepted types: ${accept}` };\n }\n }\n }\n\n return null;\n }\n\n // --- Public methods ---\n\n abort(): void {\n this._core.abort();\n }\n\n async upload(): Promise<any> {\n const files = this._files;\n // url 未設定は no-op(null)。Core は url 空で throw するが、Shell は url/files の\n // ライフサイクルを所有しており「送信先が無い」を「ファイル無し」と同じ無操作として扱う。\n // これにより set trigger / set files の fire-and-forget 経路で unhandled rejection が\n // 発生せず、README の「upload() は全終了ケースで resolve し never reject」契約とも整合する。\n if (!files || files.length === 0 || !this.url) {\n return null;\n }\n\n const validationError = this._validate(files);\n if (validationError) {\n this.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: validationError,\n bubbles: true,\n }));\n return null;\n }\n\n const result = await this._core.upload(this.url, files, {\n method: this.method,\n fieldName: this.fieldName,\n });\n\n // 自分が開始したアップロードのファイルだけをリセット\n // (途中で新しい files がセットされていたら触らない)\n if (this._files === files) {\n this._files = null;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n return result;\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null): void {\n // 意図的に空。url 変更ではアップロードを自動実行しない(files が必要なため)。\n // observedAttributes のコメント参照。\n }\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n }\n\n disconnectedCallback(): void {\n this._core.abort();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapUpload(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsUpload } from \"./components/Upload.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.upload)) {\n customElements.define(config.tagNames.upload, WcsUpload);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","upload","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","raiseError","message","Error","UploadCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","value","status","inputs","commands","async","_target","_value","_loading","_progress","_error","_status","_xhr","_promise","Promise","resolve","constructor","target","super","this","loading","progress","error","promise","_setLoading","dispatchEvent","CustomEvent","bubbles","_setProgress","_setError","_setResponse","abort","url","files","options","length","p","_doUpload","method","headers","fieldName","formData","FormData","i","append","xhr","XMLHttpRequest","addEventListener","lengthComputable","percent","Math","round","loaded","total","responseText","getResponseHeader","includes","JSON","parse","statusText","body","open","entries","setRequestHeader","send","registered","handleClick","Element","triggerElement","closest","uploadId","getAttribute","UploadCtor","customElements","get","el","document","getElementById","uploadElement","preventDefault","WcsUpload","HTMLElement","wcBindable","observedAttributes","_core","_files","_trigger","setAttribute","toUpperCase","multiple","hasAttribute","removeAttribute","maxSize","attr","Infinity","n","parseInt","Number","isFinite","String","accept","manual","trigger","finally","_validate","size","acceptList","split","map","s","trim","toLowerCase","file","fileType","type","fileName","some","pattern","startsWith","endsWith","slice","validationError","result","attributeChangedCallback","_name","_oldValue","_newValue","connectedCallback","style","display","disconnectedCallback","bootstrapUpload","userConfig","partialConfig","assign","define"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.min.js","sources":["../src/config.ts","../src/core/UploadCore.ts","../src/autoTrigger.ts","../src/components/Upload.ts","../src/bootstrapUpload.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n upload: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-uploadtarget\",\n tagNames: {\n upload: \"wcs-upload\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// `config` は内部用のライブビュー(live view)。setConfig() の更新が即座に反映される\n// 実体 `_config` をそのまま公開しており、凍結もクローンもしていない。autoTrigger /\n// components など同パッケージ内のモジュールが最新値を読むための窓口であり、\n// 「変更不可なスナップショット」が必要な外部利用には getConfig()(凍結クローンを返す)\n// を使うこと。型が readonly なのは内部からの誤書き換えを抑止するための表明にすぎない。\nexport const config: IConfig = _config as IConfig;\n\nexport function getConfig(): IConfig {\n if (!frozenConfig) {\n frozenConfig = deepFreeze(deepClone(_config));\n }\n return frozenConfig;\n}\n\nexport function setConfig(partialConfig: IWritableConfig): void {\n if (typeof partialConfig.autoTrigger === \"boolean\") {\n _config.autoTrigger = partialConfig.autoTrigger;\n }\n if (typeof partialConfig.triggerAttribute === \"string\") {\n _config.triggerAttribute = partialConfig.triggerAttribute;\n }\n if (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface UploadRequestOptions {\n method?: string;\n headers?: Record<string, string>;\n fieldName?: string;\n}\n\nexport class UploadCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"value\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.value },\n { name: \"loading\", event: \"wcs-upload:loading-changed\" },\n { name: \"progress\", event: \"wcs-upload:progress\" },\n { name: \"error\", event: \"wcs-upload:error\" },\n { name: \"status\", event: \"wcs-upload:response\", getter: (e: Event) => (e as CustomEvent).detail.status },\n ],\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n ],\n commands: [\n { name: \"upload\", async: true },\n { name: \"abort\" },\n ],\n };\n\n private _target: EventTarget;\n private _value: any = null;\n private _loading: boolean = false;\n private _progress: number = 0;\n private _error: any = null;\n private _status: number = 0;\n private _xhr: XMLHttpRequest | null = null;\n private _promise: Promise<any> = Promise.resolve(null);\n // Generation guard: bumped on dispose() (and each upload start). An in-flight\n // request that settles after dispose / a superseding start has a stale `gen`\n // and MUST NOT write state to a torn-down element. A boolean flag is\n // insufficient (dispose→observe would let stale work slip through).\n private _gen = 0;\n // SSR: no asynchronous probe to await, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). Upload is command-driven with no subscription to\n // establish, so observe() is an idempotent no-op that resolves once ready;\n // dispose() invalidates any in-flight request and aborts it.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.abort();\n }\n\n get value(): any {\n return this._value;\n }\n\n get loading(): boolean {\n return this._loading;\n }\n\n get progress(): number {\n return this._progress;\n }\n\n get error(): any {\n return this._error;\n }\n\n get status(): number {\n return this._status;\n }\n\n get promise(): Promise<any> {\n return this._promise;\n }\n\n // --- State setters with event dispatch ---\n\n private _setLoading(loading: boolean): void {\n this._loading = loading;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:loading-changed\", {\n detail: loading,\n bubbles: true,\n }));\n }\n\n private _setProgress(progress: number): void {\n this._progress = progress;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:progress\", {\n detail: progress,\n bubbles: true,\n }));\n }\n\n private _setError(error: any): void {\n this._error = error;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: error,\n bubbles: true,\n }));\n }\n\n private _setResponse(value: any, status: number): void {\n this._value = value;\n this._status = status;\n this._target.dispatchEvent(new CustomEvent(\"wcs-upload:response\", {\n detail: { value, status },\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n abort(): void {\n // `_xhr` は send() の直前に同期で代入されるため、send 前に外部から abort が\n // 割り込む余地はない(割り込み点となる await が存在しない)。よって XHR.abort()\n // は常に進行中のリクエストに対して呼ばれ、abort イベントが発火して loading を\n // 解除する。loading の解除を abort イベントハンドラに集約しているのは、\n // ネットワークエラー/HTTP エラー/正常完了/中断のすべてで解除経路を一本化し、\n // FetchCore.abort() と挙動を揃えるため。\n if (this._xhr) {\n this._xhr.abort();\n this._xhr = null;\n }\n }\n\n async upload(url: string, files: FileList | File[], options: UploadRequestOptions = {}): Promise<any> {\n // never-throw: 引数バリデーション失敗は例外ではなく error プロパティに流し、\n // サニタイズ値(null)を返す。command-token 経路からの呼び出しが unhandled\n // rejection にならず、「upload() は全終了ケースで resolve」契約とも整合する。\n if (!url) {\n this._setError({ message: \"url is required.\" });\n return null;\n }\n if (!files || files.length === 0) {\n this._setError({ message: \"files are required.\" });\n return null;\n }\n\n const p = this._doUpload(url, files, options);\n this._promise = p;\n return p;\n }\n\n // --- Internal ---\n\n private _doUpload(url: string, files: FileList | File[], options: UploadRequestOptions): Promise<any> {\n // 既存のアップロードを中止\n this.abort();\n\n this._setLoading(true);\n this._setProgress(0);\n this._setError(null);\n\n const {\n method = \"POST\",\n headers = {},\n fieldName = \"file\",\n } = options;\n\n const formData = new FormData();\n for (let i = 0; i < files.length; i++) {\n formData.append(fieldName, files[i]);\n }\n\n const gen = ++this._gen;\n\n return new Promise<any>((resolve) => {\n const xhr = new XMLHttpRequest();\n this._xhr = xhr;\n\n xhr.upload.addEventListener(\"progress\", (event: ProgressEvent) => {\n if (gen !== this._gen) return;\n if (event.lengthComputable) {\n const percent = Math.round((event.loaded / event.total) * 100);\n this._setProgress(percent);\n }\n });\n\n xhr.addEventListener(\"load\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._status = xhr.status;\n\n if (xhr.status >= 200 && xhr.status < 300) {\n let value: any = xhr.responseText;\n const contentType = xhr.getResponseHeader(\"Content-Type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n value = JSON.parse(xhr.responseText);\n } catch {\n // テキストのまま\n }\n }\n this._setProgress(100);\n this._setResponse(value, xhr.status);\n this._setLoading(false);\n resolve(value);\n } else {\n const error = {\n status: xhr.status,\n statusText: xhr.statusText,\n body: xhr.responseText,\n };\n this._setError(error);\n this._setLoading(false);\n resolve(null);\n }\n });\n\n xhr.addEventListener(\"error\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._setError({ message: \"Network error\" });\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.addEventListener(\"abort\", () => {\n this._xhr = null;\n if (gen !== this._gen) { resolve(null); return; }\n this._setLoading(false);\n resolve(null);\n });\n\n xhr.open(method, url);\n\n for (const [name, value] of Object.entries(headers)) {\n xhr.setRequestHeader(name, value);\n }\n\n xhr.send(formData);\n });\n }\n}\n","import { config } from \"./config.js\";\nimport type { WcsUpload } from \"./components/Upload.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const uploadId = triggerElement.getAttribute(config.triggerAttribute);\n if (!uploadId) return;\n\n // Resolve the registered constructor at call time instead of importing WcsUpload\n // as a value. The value import created a components/Upload.ts ⇄ autoTrigger.ts\n // cycle (WcsUpload.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-upload> class matches — without the import cycle.\n const UploadCtor = customElements.get(config.tagNames.upload);\n const el = document.getElementById(uploadId);\n if (!UploadCtor || !(el instanceof UploadCtor)) return;\n const uploadElement = el as WcsUpload;\n\n // ファイルと URL が揃っている場合のみ既定動作を抑止\n if (uploadElement.files && uploadElement.files.length > 0 && uploadElement.url) {\n event.preventDefault();\n }\n uploadElement.upload();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable, WcsUploadError } from \"../types.js\";\nimport { UploadCore } from \"../core/UploadCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\n\nexport class WcsUpload extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...UploadCore.wcBindable,\n properties: [\n ...UploadCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-upload:trigger-changed\" },\n { name: \"files\", event: \"wcs-upload:files-changed\" },\n ],\n // Shell-level input surface. The Core declares only the portable `url` / `method` /\n // `fieldName`; the Shell adds the DOM-driven settable surface. No `attribute` hints\n // are given: the `url` / `method` / `fieldName` / `multiple` / `maxSize` / `accept` /\n // `manual` setters already reflect to their attributes, so a binding system that\n // mirrors inputs[].attribute would set the attribute twice (`files` / `trigger` are\n // not attribute-backed). `commands` (upload / abort) are inherited unchanged from the\n // Core via the spread above.\n inputs: [\n { name: \"url\" },\n { name: \"method\" },\n { name: \"fieldName\" },\n { name: \"multiple\" },\n { name: \"maxSize\" },\n { name: \"accept\" },\n { name: \"manual\" },\n { name: \"files\" },\n { name: \"trigger\" },\n ],\n };\n // `url` を観測するのは FetchCore のシェルと構造を揃えるためだが、upload は\n // url 変更だけでは送信できない(files が必須)。そのため attributeChangedCallback は\n // 意図的に何もしない。url 変更で自動送信しないことは仕様であり、テストで担保している。\n static get observedAttributes(): string[] { return [\"url\"]; }\n\n private _core: UploadCore;\n private _files: FileList | File[] | null = null;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n\n constructor() {\n super();\n this._core = new UploadCore(this);\n }\n\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n\n get url(): string {\n return this.getAttribute(\"url\") || \"\";\n }\n\n set url(value: string) {\n this.setAttribute(\"url\", value);\n }\n\n get method(): string {\n return (this.getAttribute(\"method\") || \"POST\").toUpperCase();\n }\n\n set method(value: string) {\n this.setAttribute(\"method\", value);\n }\n\n get fieldName(): string {\n return this.getAttribute(\"field-name\") || \"file\";\n }\n\n set fieldName(value: string) {\n this.setAttribute(\"field-name\", value);\n }\n\n get multiple(): boolean {\n return this.hasAttribute(\"multiple\");\n }\n\n set multiple(value: boolean) {\n if (value) {\n this.setAttribute(\"multiple\", \"\");\n } else {\n this.removeAttribute(\"multiple\");\n }\n }\n\n get maxSize(): number {\n const attr = this.getAttribute(\"max-size\");\n if (attr === null) {\n return Infinity;\n }\n // 不正値(NaN になる \"abc\" など)や負数は「制限なし」(Infinity) として扱う。\n // NaN を返すと `size > NaN` が常に false になりサイズ検証が無言で無効化され、\n // 負数を返すと全ファイルが拒否されるため、いずれも安全側の Infinity に丸める。\n const n = parseInt(attr, 10);\n return Number.isFinite(n) && n >= 0 ? n : Infinity;\n }\n\n set maxSize(value: number) {\n this.setAttribute(\"max-size\", String(value));\n }\n\n get accept(): string {\n return this.getAttribute(\"accept\") || \"\";\n }\n\n set accept(value: string) {\n this.setAttribute(\"accept\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean) {\n if (value) {\n this.setAttribute(\"manual\", \"\");\n } else {\n this.removeAttribute(\"manual\");\n }\n }\n\n // --- Core delegated getters ---\n\n get value(): any {\n return this._core.value;\n }\n\n get loading(): boolean {\n return this._core.loading;\n }\n\n get progress(): number {\n return this._core.progress;\n }\n\n get error(): any {\n return this._core.error;\n }\n\n get status(): number {\n return this._core.status;\n }\n\n get promise(): Promise<any> {\n return this._core.promise;\n }\n\n // --- Command properties ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // 進行中に再度 trigger=true が来ても再入ガードはしない(FetchCore シェルと同一)。\n // upload() → _core.upload() が先頭で既存リクエストを abort し新規開始するため、\n // 連続トリガは「前回を中止して新しいアップロードを開始する」挙動になる。\n // 各 upload() の settle ごとに trigger-changed(false) が 1 回発火する。\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.upload().finally(() => {\n this._trigger = false;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n });\n }\n }\n\n get files(): FileList | File[] | null {\n return this._files;\n }\n\n set files(value: FileList | File[] | null) {\n this._files = value;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: value,\n bubbles: true,\n }));\n if (!this.manual && this.url && value && value.length > 0) {\n this.upload();\n }\n }\n\n // --- Validation ---\n\n private _validate(files: FileList | File[]): WcsUploadError | null {\n const maxSize = this.maxSize;\n if (maxSize !== Infinity) {\n for (let i = 0; i < files.length; i++) {\n if (files[i].size > maxSize) {\n return { message: `File \"${files[i].name}\" exceeds maximum size of ${maxSize} bytes.` };\n }\n }\n }\n\n const accept = this.accept;\n if (accept) {\n const acceptList = accept.split(\",\").map(s => s.trim().toLowerCase());\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const fileType = file.type.toLowerCase();\n const fileName = file.name.toLowerCase();\n // file.type が空文字(OS が MIME を判定できないファイル)の場合、MIME 系\n // パターン(`image/*` / 厳密 MIME)は一致しない。その場合でも accept に\n // 拡張子パターン(`.pdf` 等)が含まれ拡張子が一致すれば受理される。\n // accept が MIME 系のみのときは型を確認できないため拒否する(安全側)。\n const matched = acceptList.some(pattern => {\n if (pattern.startsWith(\".\")) {\n return fileName.endsWith(pattern);\n }\n if (pattern.endsWith(\"/*\")) {\n return fileType !== \"\" && fileType.startsWith(pattern.slice(0, -1));\n }\n return fileType !== \"\" && fileType === pattern;\n });\n if (!matched) {\n return { message: `File \"${file.name}\" does not match accepted types: ${accept}` };\n }\n }\n }\n\n return null;\n }\n\n // --- Public methods ---\n\n abort(): void {\n this._core.abort();\n }\n\n async upload(): Promise<any> {\n const files = this._files;\n // url 未設定は no-op(null)。Core は url 空で throw するが、Shell は url/files の\n // ライフサイクルを所有しており「送信先が無い」を「ファイル無し」と同じ無操作として扱う。\n // これにより set trigger / set files の fire-and-forget 経路で unhandled rejection が\n // 発生せず、README の「upload() は全終了ケースで resolve し never reject」契約とも整合する。\n if (!files || files.length === 0 || !this.url) {\n return null;\n }\n\n const validationError = this._validate(files);\n if (validationError) {\n this.dispatchEvent(new CustomEvent(\"wcs-upload:error\", {\n detail: validationError,\n bubbles: true,\n }));\n return null;\n }\n\n const result = await this._core.upload(this.url, files, {\n method: this.method,\n fieldName: this.fieldName,\n });\n\n // 自分が開始したアップロードのファイルだけをリセット\n // (途中で新しい files がセットされていたら触らない)\n if (this._files === files) {\n this._files = null;\n this.dispatchEvent(new CustomEvent(\"wcs-upload:files-changed\", {\n detail: null,\n bubbles: true,\n }));\n }\n\n return result;\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(_name: string, _oldValue: string | null, _newValue: string | null): void {\n // 意図的に空。url 変更ではアップロードを自動実行しない(files が必要なため)。\n // observedAttributes のコメント参照。\n }\n\n connectedCallback(): void {\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n this._connectedCallbackPromise = this._core.observe();\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapUpload(userConfig?: IWritableConfig): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents();\n}\n","import { WcsUpload } from \"./components/Upload.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.upload)) {\n customElements.define(config.tagNames.upload, WcsUpload);\n }\n}\n"],"names":["_config","autoTrigger","triggerAttribute","tagNames","upload","deepFreeze","obj","Object","freeze","key","keys","deepClone","clone","frozenConfig","config","getConfig","UploadCore","EventTarget","static","protocol","version","properties","name","event","getter","e","detail","value","status","inputs","commands","async","_target","_value","_loading","_progress","_error","_status","_xhr","_promise","Promise","resolve","_gen","_ready","constructor","target","super","this","ready","observe","dispose","abort","loading","progress","error","promise","_setLoading","dispatchEvent","CustomEvent","bubbles","_setProgress","_setError","_setResponse","url","files","options","message","length","p","_doUpload","method","headers","fieldName","formData","FormData","i","append","gen","xhr","XMLHttpRequest","addEventListener","lengthComputable","percent","Math","round","loaded","total","responseText","getResponseHeader","includes","JSON","parse","statusText","body","open","entries","setRequestHeader","send","registered","handleClick","Element","triggerElement","closest","uploadId","getAttribute","UploadCtor","customElements","get","el","document","getElementById","uploadElement","preventDefault","WcsUpload","HTMLElement","wcBindable","observedAttributes","_core","_files","_trigger","_connectedCallbackPromise","connectedCallbackPromise","setAttribute","toUpperCase","multiple","hasAttribute","removeAttribute","maxSize","attr","Infinity","n","parseInt","Number","isFinite","String","accept","manual","trigger","finally","_validate","size","acceptList","split","map","s","trim","toLowerCase","file","fileType","type","fileName","some","pattern","startsWith","endsWith","slice","validationError","result","attributeChangedCallback","_name","_oldValue","_newValue","connectedCallback","style","display","disconnectedCallback","bootstrapUpload","userConfig","partialConfig","assign","define"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/upload",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "Declarative file upload component for Web Components. Framework-agnostic upload with progress tracking via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",