@wcstack/permission 1.30.0 → 1.31.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/auto.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const t={tagNames:{permission:"wcs-permission"}};class e extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"state",event:"wcs-permission:change",semantics:"state"},{name:"granted",event:"wcs-permission:change",semantics:"state",getter:t=>"granted"===t.detail},{name:"denied",event:"wcs-permission:change",semantics:"state",getter:t=>"denied"===t.detail},{name:"prompt",event:"wcs-permission:change",semantics:"state",getter:t=>"prompt"===t.detail},{name:"unsupported",event:"wcs-permission:change",semantics:"state",getter:t=>"unsupported"===t.detail}],commands:[]};_target;_descriptor=null;_state="prompt";_permissionStatus=null;_permissionSubscribed=!1;_permGen=0;_ready=Promise.resolve();constructor(t,e){super(),this._target=e??this,t&&(this._descriptor=t,this._ready=this._initPermission())}get state(){return this._state}get granted(){return"granted"===this._state}get denied(){return"denied"===this._state}get prompt(){return"prompt"===this._state}get unsupported(){return"unsupported"===this._state}get ready(){return this._ready}_setState(t){this._state!==t&&(this._state=t,this._target.dispatchEvent(new CustomEvent("wcs-permission:change",{detail:t,bubbles:!0})))}observe(t){return this._descriptor=t,this._permissionSubscribed||(this._ready=this._initPermission()),this._ready}dispose(){this._permissionSubscribed=!1,this._permGen++,this._permissionStatus&&(this._permissionStatus.removeEventListener("change",this._onPermissionChange),this._permissionStatus=null)}_initPermission(){if(!this._descriptor||!this._descriptor.name)return this._setState("unsupported"),Promise.resolve();if("undefined"==typeof navigator||!navigator.permissions||"function"!=typeof navigator.permissions.query)return this._setState("unsupported"),Promise.resolve();this._permissionSubscribed=!0;const t=++this._permGen;return navigator.permissions.query(this._descriptor).then(e=>{t===this._permGen&&(this._permissionStatus=e,this._setState(e.state),e.addEventListener("change",this._onPermissionChange))},()=>{t===this._permGen&&this._setState("unsupported")})}_onPermissionChange=t=>{const e=t.target;this._setState(e.state)}}function s(t,e){let s=Object.getPrototypeOf(t);for(;null!==s;){const t=Object.getOwnPropertyDescriptor(s,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;s=Object.getPrototypeOf(s)}return!1}class i extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...e.wcBindable,inputs:[{name:"name",attribute:"name"},{name:"userVisibleOnly",attribute:"user-visible-only"},{name:"sysex",attribute:"sysex"}],commands:[]};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new e(null,this),this._internals=this._initInternals(),this._wireStates({"wcs-permission:change":t=>({granted:"granted"===t,denied:"denied"===t,prompt:"prompt"===t,unsupported:"unsupported"===t})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[s,i]of Object.entries(t))this.addEventListener(s,t=>{const s=this.hasAttribute("debug-states");for(const[n,r]of Object.entries(i(t.detail))){try{r?e.add(n):e.delete(n)}catch{}s&&this.toggleAttribute(`data-wcs-state-${n}`,r)}})}get name(){return this.getAttribute("name")??""}set name(t){this.setAttribute("name",t)}get userVisibleOnly(){return this.hasAttribute("user-visible-only")}set userVisibleOnly(t){t?this.setAttribute("user-visible-only",""):this.removeAttribute("user-visible-only")}get sysex(){return this.hasAttribute("sysex")}set sysex(t){t?this.setAttribute("sysex",""):this.removeAttribute("sysex")}get state(){return this._core.state}get granted(){return this._core.granted}get denied(){return this._core.denied}get prompt(){return this._core.prompt}get unsupported(){return this._core.unsupported}get connectedCallbackPromise(){return this._connectedCallbackPromise}_descriptor(){const t={name:this.name};return this.userVisibleOnly&&(t.userVisibleOnly=!0),this.sysex&&(t.sysex=!0),t}connectedCallback(){!function(t){const e=t.constructor?.wcBindable,i=e?.inputs;if(void 0!==i)for(const e of i){const i=e.name;if(!Object.prototype.hasOwnProperty.call(t,i))continue;if(!s(t,i))continue;const n=t,r=n[i];delete n[i],n[i]=r}}(this),this.style.display="none",this._connectedCallbackPromise=this._core.observe(this._descriptor())}disconnectedCallback(){this._core.dispose()}}customElements.get(t.tagNames.permission)||customElements.define(t.tagNames.permission,i);
1
+ const t={tagNames:{permission:"wcs-permission"}};class e extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"state",event:"wcs-permission:change",semantics:"state"},{name:"granted",event:"wcs-permission:change",semantics:"state",getter:t=>"granted"===t.detail},{name:"denied",event:"wcs-permission:change",semantics:"state",getter:t=>"denied"===t.detail},{name:"prompt",event:"wcs-permission:change",semantics:"state",getter:t=>"prompt"===t.detail},{name:"unsupported",event:"wcs-permission:change",semantics:"state",getter:t=>"unsupported"===t.detail}],commands:[]};_target;_descriptor=null;_state="prompt";_permissionStatus=null;_permissionSubscribed=!1;_permGen=0;_ready=Promise.resolve();constructor(t,e){super(),this._target=e??this,t&&(this._descriptor=t,this._ready=this._initPermission())}get state(){return this._state}get granted(){return"granted"===this._state}get denied(){return"denied"===this._state}get prompt(){return"prompt"===this._state}get unsupported(){return"unsupported"===this._state}get ready(){return this._ready}_setState(t){this._state!==t&&(this._state=t,this._target.dispatchEvent(new CustomEvent("wcs-permission:change",{detail:t,bubbles:!0})))}observe(t){return this._descriptor=t,this._permissionSubscribed||(this._ready=this._initPermission()),this._ready}dispose(){this._permissionSubscribed=!1,this._permGen++,this._permissionStatus&&(this._permissionStatus.removeEventListener("change",this._onPermissionChange),this._permissionStatus=null)}_initPermission(){if(!this._descriptor||!this._descriptor.name)return this._setState("unsupported"),Promise.resolve();if("undefined"==typeof navigator||!navigator.permissions||"function"!=typeof navigator.permissions.query)return this._setState("unsupported"),Promise.resolve();this._permissionSubscribed=!0;const t=++this._permGen;return navigator.permissions.query(this._descriptor).then(e=>{t===this._permGen&&(this._permissionStatus=e,this._setState(e.state),e.addEventListener("change",this._onPermissionChange))},()=>{t===this._permGen&&this._setState("unsupported")})}_onPermissionChange=t=>{const e=t.target;this._setState(e.state)}}function s(t,e){let s=Object.getPrototypeOf(t);for(;null!==s;){const t=Object.getOwnPropertyDescriptor(s,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;s=Object.getPrototypeOf(s)}return!1}class i extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...e.wcBindable,inputs:[{name:"name",attribute:"name"},{name:"userVisibleOnly",attribute:"user-visible-only"},{name:"sysex",attribute:"sysex"}],commands:[]};_core;_connectedCallbackPromise=Promise.resolve();_internals=null;constructor(){super(),this._core=new e(null,this),this._internals=this._initInternals(),this._wireStates({"wcs-permission:change":t=>({granted:"granted"===t,denied:"denied"===t,prompt:"prompt"===t,unsupported:"unsupported"===t})})}get debugStates(){return this._internals?[...this._internals.states]:[]}_initInternals(){try{if("function"!=typeof this.attachInternals)return null;const t=this.attachInternals();return t.states.add("wcs-probe"),t.states.delete("wcs-probe"),t}catch{return null}}_wireStates(t){if(null===this._internals)return;const e=this._internals.states;for(const[s,i]of Object.entries(t))this.addEventListener(s,t=>{const s=this.hasAttribute("debug-states");for(const[n,r]of Object.entries(i(t.detail))){try{r?e.add(n):e.delete(n)}catch{}s&&this.toggleAttribute(`data-wcs-state-${n}`,r)}})}get name(){return this.getAttribute("name")??""}set name(t){this.setAttribute("name",t)}get userVisibleOnly(){return this.hasAttribute("user-visible-only")}set userVisibleOnly(t){t?this.setAttribute("user-visible-only",""):this.removeAttribute("user-visible-only")}get sysex(){return this.hasAttribute("sysex")}set sysex(t){t?this.setAttribute("sysex",""):this.removeAttribute("sysex")}get state(){return this._core.state}get granted(){return this._core.granted}get denied(){return this._core.denied}get prompt(){return this._core.prompt}get unsupported(){return this._core.unsupported}get connectedCallbackPromise(){return this._connectedCallbackPromise}_descriptor(){const t={name:this.name};return this.userVisibleOnly&&(t.userVisibleOnly=!0),this.sysex&&(t.sysex=!0),t}connectedCallback(){!function(t){const e=t.constructor?.wcBindable,i=e?.inputs;if(void 0!==i)for(const e of i){const i=e.name;if(!Object.prototype.hasOwnProperty.call(t,i))continue;if(!s(t,i))continue;const n=t,r=n[i];delete n[i],n[i]=r}}(this),this.style.display="none",this._connectedCallbackPromise=this._core.observe(this._descriptor())}disconnectedCallback(){this._core.dispose()}}var n;!function(e=customElements){e.get(t.tagNames.permission)||e.define(t.tagNames.permission,i)}(n);
2
2
  //# sourceMappingURL=auto.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/PermissionCore.ts","../src/protocol/upgradeProperties.ts","../src/components/Permission.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n permission: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n permission: \"wcs-permission\",\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\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import {\n IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor,\n} from \"../types.js\";\n\n/**\n * Headless permission-state primitive. A thin, framework-agnostic wrapper around\n * the Permissions API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack IO nodes (geolocation / clipboard / sse / …), the\n * Permissions API is **read-only**: it has `query()` but no standard `request()`.\n * Asking the user for a grant is the job of the feature node (`<wcs-geo>` etc.);\n * this node only *observes*. It is therefore a pure element → state monitor with\n * **no commands** — command-token does not apply, only event-token.\n *\n * The single observable is `state` (`navigator.permissions.query(descriptor)`'s\n * `PermissionState`, or `\"unsupported\"`), published via the `wcs-permission:change`\n * event. `granted` / `denied` / `prompt` / `unsupported` are convenience booleans\n * derived from that one event (mirroring how GeolocationCore exposes latitude/…\n * from one `wcs-geo:position` event), so a binding like `hidden@granted` works\n * directly. The live `change` event of the PermissionStatus is tracked so a grant\n * flipping in browser settings flows into the declarative state.\n */\nexport class PermissionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"state\", event: \"wcs-permission:change\", semantics: \"state\" },\n { name: \"granted\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"granted\" },\n { name: \"denied\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"denied\" },\n { name: \"prompt\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"prompt\" },\n { name: \"unsupported\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"unsupported\" },\n ],\n // No commands: the Permissions API is read-only (query-only). See class docs.\n commands: [],\n };\n\n private _target: EventTarget;\n private _descriptor: WcsPermissionDescriptor | null = null;\n\n private _state: PermissionStateOrUnsupported = \"prompt\";\n\n // Live PermissionStatus handle (when the Permissions API is available), kept so\n // the `change` listener can be removed on dispose().\n private _permissionStatus: PermissionStatus | null = null;\n\n // True once a permission subscription has been (or is being) established, and\n // reset by dispose(). Guards observe() so a reconnect after dispose() re-queries\n // while a redundant observe() on an already-live subscription does not.\n private _permissionSubscribed: boolean = false;\n\n // Monotonic id of the current permission query. Bumped by every _initPermission()\n // and by dispose(). Each in-flight query captures its id and, on resolve, bails\n // unless it is still current — so a query superseded by a rapid (synchronous)\n // disconnect→reconnect, or one that resolves after dispose(), never attaches a\n // listener. A plain boolean cannot cover this: dispose()→observe() flips it\n // false→true again, reopening the window for the stale query to slip through.\n private _permGen: number = 0;\n\n // Resolves once the most recent query settles (or immediately when the API is\n // unsupported). The Shell exposes this as connectedCallbackPromise so SSR can\n // await the first probe before snapshotting the HTML.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(descriptor?: WcsPermissionDescriptor | null, target?: EventTarget) {\n super();\n this._target = target ?? this;\n // Headless ergonomics: when a descriptor is supplied up front, probe the\n // permission state immediately so observers see the real value before the\n // first read. The Shell passes nothing and drives the first query from\n // connectedCallback via observe(), once the element's attributes resolve.\n if (descriptor) {\n this._descriptor = descriptor;\n this._ready = this._initPermission();\n }\n }\n\n get state(): PermissionStateOrUnsupported {\n return this._state;\n }\n\n get granted(): boolean {\n return this._state === \"granted\";\n }\n\n get denied(): boolean {\n return this._state === \"denied\";\n }\n\n get prompt(): boolean {\n return this._state === \"prompt\";\n }\n\n get unsupported(): boolean {\n return this._state === \"unsupported\";\n }\n\n /** Resolves once the current (or initial) query settles. */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // --- State setter with event dispatch ---\n\n private _setState(state: PermissionStateOrUnsupported): void {\n // Same-value guard: `state` is the only stored value and the derived booleans\n // change in lockstep with it, so suppressing identical re-dispatches is safe.\n if (this._state === state) return;\n this._state = state;\n this._target.dispatchEvent(new CustomEvent(\"wcs-permission:change\", {\n detail: state,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `descriptor` (e.g. `{ name: \"geolocation\" }`). Idempotent\n * while already subscribed — calling it again only updates the stored descriptor\n * for a *future* re-subscription; it does **not** re-query, even when called with\n * a different descriptor (the Shell binds at a fixed connect-time descriptor and\n * does not re-query on a `name` change in v1). To switch permission mid-life,\n * dispose() first, then observe() the new descriptor. On the first call, or after\n * a dispose(), it issues the query and subscribes to the live `change` event.\n * Returns a promise that resolves once that query settles, for SSR.\n */\n observe(descriptor: WcsPermissionDescriptor): Promise<void> {\n this._descriptor = descriptor;\n if (!this._permissionSubscribed) {\n this._ready = this._initPermission();\n }\n return this._ready;\n }\n\n /**\n * Detach the live permission `change` listener. Call from the Shell's\n * `disconnectedCallback` so a removed element does not leak the subscription.\n * A later reconnect can re-subscribe via observe().\n *\n * Headless callers (using PermissionCore directly, without the Shell) own this\n * lifecycle themselves: call dispose() when the observer is no longer needed,\n * otherwise the live PermissionStatus `change` listener keeps this instance\n * reachable for as long as the status is alive. dispose() is safe to call when\n * never subscribed and may be paired with a later observe() to resume.\n */\n dispose(): void {\n this._permissionSubscribed = false;\n // Invalidate any in-flight query so its .then() bails instead of attaching a\n // listener after teardown.\n this._permGen++;\n if (this._permissionStatus) {\n this._permissionStatus.removeEventListener(\"change\", this._onPermissionChange);\n this._permissionStatus = null;\n }\n }\n\n // --- Internal ---\n\n private _initPermission(): Promise<void> {\n // Guard a missing/empty permission name (e.g. a `<wcs-permission>` with no\n // `name` attribute). Such a descriptor would only ever reject at query() and\n // silently fall back to \"unsupported\", which is hard to diagnose. Short-circuit\n // to \"unsupported\" without issuing a doomed query so the misconfiguration\n // surfaces deterministically and no listener is attached.\n if (!this._descriptor || !this._descriptor.name) {\n this._setState(\"unsupported\");\n return Promise.resolve();\n }\n // The Permissions API is optional. When absent (or it rejects, e.g. the\n // browser does not accept the requested permission name), report \"unsupported\"\n // and leave it at that — there is nothing to retry.\n if (typeof navigator === \"undefined\" || !navigator.permissions || typeof navigator.permissions.query !== \"function\") {\n // Route through _setState (not a bare assignment) so observers stay in sync\n // with the public state. The same-value guard means no redundant dispatch\n // when the state does not actually change.\n this._setState(\"unsupported\");\n // Intentionally does NOT set _permissionSubscribed: there is no listener to\n // tear down, so a reconnect simply re-probes (idempotent — the same-value\n // guard suppresses any dispatch and no listener is ever attached). Mirrors\n // GeolocationCore's reinitPermission behavior in unsupported environments.\n return Promise.resolve();\n }\n this._permissionSubscribed = true;\n const gen = ++this._permGen;\n // Cast: WcsPermissionDescriptor widens `name` to string (and allows extra\n // descriptor members like userVisibleOnly / sysex) where the lib DOM type\n // expects the PermissionName union.\n return navigator.permissions.query(this._descriptor as unknown as PermissionDescriptor).then(\n (status) => {\n // Stale resolution: this query was superseded (rapid reconnect) or the\n // element was disposed while it was in flight. Drop it so only the current\n // subscription attaches a listener.\n if (gen !== this._permGen) return;\n this._permissionStatus = status;\n this._setState(status.state as PermissionStateOrUnsupported);\n status.addEventListener(\"change\", this._onPermissionChange);\n },\n () => {\n if (gen !== this._permGen) return;\n this._setState(\"unsupported\");\n },\n );\n }\n\n private _onPermissionChange = (event: Event): void => {\n const status = event.target as PermissionStatus;\n this._setState(status.state as PermissionStateOrUnsupported);\n };\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor } from \"../types.js\";\nimport { PermissionCore } from \"../core/PermissionCore.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\n\n// Named WcsPermission (not `Permission`) so the class does not shadow any global,\n// and to match the <wcs-geo> / <wcs-ws> convention (WcsGeolocation /\n// WcsWebSocket). The public export keeps the `WcsPermission` name unchanged.\nexport class WcsPermission extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...PermissionCore.wcBindable,\n // Shell-level settable surface. `name` is the permission name; the descriptor\n // extras `user-visible-only` (push) and `sysex` (midi) are boolean flags that\n // reflect idempotently, so a binding system that writes through\n // inputs[].attribute is safe.\n inputs: [\n { name: \"name\", attribute: \"name\" },\n { name: \"userVisibleOnly\", attribute: \"user-visible-only\" },\n { name: \"sysex\", attribute: \"sysex\" },\n ],\n // No commands: read-only monitor (see PermissionCore). The Permissions API has\n // no request() — acquiring a grant is the feature node's job.\n commands: [],\n };\n\n // Created in the Shell constructor with no descriptor so the delegated getters\n // work before connect (returning the default \"prompt\" / false). The actual\n // query is driven from connectedCallback once the element's attributes resolve\n // (programmatically-created elements have no attributes at construction time).\n private _core: PermissionCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PermissionCore(null, this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-permission:change\": (d) => ({\n granted: d === \"granted\",\n denied: d === \"denied\",\n prompt: d === \"prompt\",\n unsupported: d === \"unsupported\",\n }),\n });\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get name(): string {\n return this.getAttribute(\"name\") ?? \"\";\n }\n\n set name(value: string) {\n this.setAttribute(\"name\", value);\n }\n\n get userVisibleOnly(): boolean {\n return this.hasAttribute(\"user-visible-only\");\n }\n\n set userVisibleOnly(value: boolean) {\n if (value) {\n this.setAttribute(\"user-visible-only\", \"\");\n } else {\n this.removeAttribute(\"user-visible-only\");\n }\n }\n\n get sysex(): boolean {\n return this.hasAttribute(\"sysex\");\n }\n\n set sysex(value: boolean) {\n if (value) {\n this.setAttribute(\"sysex\", \"\");\n } else {\n this.removeAttribute(\"sysex\");\n }\n }\n\n // --- Core delegated getters ---\n\n get state(): PermissionStateOrUnsupported {\n return this._core.state;\n }\n\n get granted(): boolean {\n return this._core.granted;\n }\n\n get denied(): boolean {\n return this._core.denied;\n }\n\n get prompt(): boolean {\n return this._core.prompt;\n }\n\n get unsupported(): boolean {\n return this._core.unsupported;\n }\n\n // wc-bindable connectedCallbackPromise protocol: resolves once the connect-time\n // query settles, so SSR (@wcstack/server render.ts) waits for the first probe\n // before snapshotting the HTML. Mirrors WcsGeolocation.connectedCallbackPromise.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Internal ---\n\n // Build the query descriptor from the current attributes. Only present extras\n // are included so a bare `{ name }` is passed for permissions that take no\n // additional members. The descriptor is fixed at connect time (v1 does not\n // re-query on a `name` change — see README).\n private _descriptor(): WcsPermissionDescriptor {\n const descriptor: WcsPermissionDescriptor = { name: this.name };\n if (this.userVisibleOnly) descriptor.userVisibleOnly = true;\n if (this.sysex) descriptor.sysex = true;\n return descriptor;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n // Begin observing (or revive the subscription after a reconnect). The\n // returned promise is held as connectedCallbackPromise for SSR. query() never\n // rejects in a way that escapes — failures surface as the `unsupported`\n // state — so no .catch() is needed.\n this._connectedCallbackPromise = this._core.observe(this._descriptor());\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsPermission } from \"./components/Permission.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.permission)) {\n customElements.define(config.tagNames.permission, WcsPermission);\n }\n}\n"],"names":["config","tagNames","permission","PermissionCore","EventTarget","static","protocol","version","properties","name","event","semantics","getter","e","detail","commands","_target","_descriptor","_state","_permissionStatus","_permissionSubscribed","_permGen","_ready","Promise","resolve","constructor","descriptor","target","super","this","_initPermission","state","granted","denied","prompt","unsupported","ready","_setState","dispatchEvent","CustomEvent","bubbles","observe","dispose","removeEventListener","_onPermissionChange","navigator","permissions","query","gen","then","status","addEventListener","hasAccessorOnPrototype","proto","Object","getPrototypeOf","getOwnPropertyDescriptor","undefined","get","set","WcsPermission","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","getAttribute","value","setAttribute","userVisibleOnly","removeAttribute","sysex","connectedCallbackPromise","connectedCallback","element","declaration","input","prototype","hasOwnProperty","call","record","upgradeProperties","style","display","disconnectedCallback","customElements","define"],"mappings":"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"}
1
+ {"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/PermissionCore.ts","../src/protocol/upgradeProperties.ts","../src/components/Permission.ts","../src/bootstrapPermission.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n permission: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n permission: \"wcs-permission\",\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\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import {\n IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor,\n} from \"../types.js\";\n\n/**\n * Headless permission-state primitive. A thin, framework-agnostic wrapper around\n * the Permissions API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack IO nodes (geolocation / clipboard / sse / …), the\n * Permissions API is **read-only**: it has `query()` but no standard `request()`.\n * Asking the user for a grant is the job of the feature node (`<wcs-geo>` etc.);\n * this node only *observes*. It is therefore a pure element → state monitor with\n * **no commands** — command-token does not apply, only event-token.\n *\n * The single observable is `state` (`navigator.permissions.query(descriptor)`'s\n * `PermissionState`, or `\"unsupported\"`), published via the `wcs-permission:change`\n * event. `granted` / `denied` / `prompt` / `unsupported` are convenience booleans\n * derived from that one event (mirroring how GeolocationCore exposes latitude/…\n * from one `wcs-geo:position` event), so a binding like `hidden@granted` works\n * directly. The live `change` event of the PermissionStatus is tracked so a grant\n * flipping in browser settings flows into the declarative state.\n */\nexport class PermissionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"state\", event: \"wcs-permission:change\", semantics: \"state\" },\n { name: \"granted\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"granted\" },\n { name: \"denied\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"denied\" },\n { name: \"prompt\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"prompt\" },\n { name: \"unsupported\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"unsupported\" },\n ],\n // No commands: the Permissions API is read-only (query-only). See class docs.\n commands: [],\n };\n\n private _target: EventTarget;\n private _descriptor: WcsPermissionDescriptor | null = null;\n\n private _state: PermissionStateOrUnsupported = \"prompt\";\n\n // Live PermissionStatus handle (when the Permissions API is available), kept so\n // the `change` listener can be removed on dispose().\n private _permissionStatus: PermissionStatus | null = null;\n\n // True once a permission subscription has been (or is being) established, and\n // reset by dispose(). Guards observe() so a reconnect after dispose() re-queries\n // while a redundant observe() on an already-live subscription does not.\n private _permissionSubscribed: boolean = false;\n\n // Monotonic id of the current permission query. Bumped by every _initPermission()\n // and by dispose(). Each in-flight query captures its id and, on resolve, bails\n // unless it is still current — so a query superseded by a rapid (synchronous)\n // disconnect→reconnect, or one that resolves after dispose(), never attaches a\n // listener. A plain boolean cannot cover this: dispose()→observe() flips it\n // false→true again, reopening the window for the stale query to slip through.\n private _permGen: number = 0;\n\n // Resolves once the most recent query settles (or immediately when the API is\n // unsupported). The Shell exposes this as connectedCallbackPromise so SSR can\n // await the first probe before snapshotting the HTML.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(descriptor?: WcsPermissionDescriptor | null, target?: EventTarget) {\n super();\n this._target = target ?? this;\n // Headless ergonomics: when a descriptor is supplied up front, probe the\n // permission state immediately so observers see the real value before the\n // first read. The Shell passes nothing and drives the first query from\n // connectedCallback via observe(), once the element's attributes resolve.\n if (descriptor) {\n this._descriptor = descriptor;\n this._ready = this._initPermission();\n }\n }\n\n get state(): PermissionStateOrUnsupported {\n return this._state;\n }\n\n get granted(): boolean {\n return this._state === \"granted\";\n }\n\n get denied(): boolean {\n return this._state === \"denied\";\n }\n\n get prompt(): boolean {\n return this._state === \"prompt\";\n }\n\n get unsupported(): boolean {\n return this._state === \"unsupported\";\n }\n\n /** Resolves once the current (or initial) query settles. */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // --- State setter with event dispatch ---\n\n private _setState(state: PermissionStateOrUnsupported): void {\n // Same-value guard: `state` is the only stored value and the derived booleans\n // change in lockstep with it, so suppressing identical re-dispatches is safe.\n if (this._state === state) return;\n this._state = state;\n this._target.dispatchEvent(new CustomEvent(\"wcs-permission:change\", {\n detail: state,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `descriptor` (e.g. `{ name: \"geolocation\" }`). Idempotent\n * while already subscribed — calling it again only updates the stored descriptor\n * for a *future* re-subscription; it does **not** re-query, even when called with\n * a different descriptor (the Shell binds at a fixed connect-time descriptor and\n * does not re-query on a `name` change in v1). To switch permission mid-life,\n * dispose() first, then observe() the new descriptor. On the first call, or after\n * a dispose(), it issues the query and subscribes to the live `change` event.\n * Returns a promise that resolves once that query settles, for SSR.\n */\n observe(descriptor: WcsPermissionDescriptor): Promise<void> {\n this._descriptor = descriptor;\n if (!this._permissionSubscribed) {\n this._ready = this._initPermission();\n }\n return this._ready;\n }\n\n /**\n * Detach the live permission `change` listener. Call from the Shell's\n * `disconnectedCallback` so a removed element does not leak the subscription.\n * A later reconnect can re-subscribe via observe().\n *\n * Headless callers (using PermissionCore directly, without the Shell) own this\n * lifecycle themselves: call dispose() when the observer is no longer needed,\n * otherwise the live PermissionStatus `change` listener keeps this instance\n * reachable for as long as the status is alive. dispose() is safe to call when\n * never subscribed and may be paired with a later observe() to resume.\n */\n dispose(): void {\n this._permissionSubscribed = false;\n // Invalidate any in-flight query so its .then() bails instead of attaching a\n // listener after teardown.\n this._permGen++;\n if (this._permissionStatus) {\n this._permissionStatus.removeEventListener(\"change\", this._onPermissionChange);\n this._permissionStatus = null;\n }\n }\n\n // --- Internal ---\n\n private _initPermission(): Promise<void> {\n // Guard a missing/empty permission name (e.g. a `<wcs-permission>` with no\n // `name` attribute). Such a descriptor would only ever reject at query() and\n // silently fall back to \"unsupported\", which is hard to diagnose. Short-circuit\n // to \"unsupported\" without issuing a doomed query so the misconfiguration\n // surfaces deterministically and no listener is attached.\n if (!this._descriptor || !this._descriptor.name) {\n this._setState(\"unsupported\");\n return Promise.resolve();\n }\n // The Permissions API is optional. When absent (or it rejects, e.g. the\n // browser does not accept the requested permission name), report \"unsupported\"\n // and leave it at that — there is nothing to retry.\n if (typeof navigator === \"undefined\" || !navigator.permissions || typeof navigator.permissions.query !== \"function\") {\n // Route through _setState (not a bare assignment) so observers stay in sync\n // with the public state. The same-value guard means no redundant dispatch\n // when the state does not actually change.\n this._setState(\"unsupported\");\n // Intentionally does NOT set _permissionSubscribed: there is no listener to\n // tear down, so a reconnect simply re-probes (idempotent — the same-value\n // guard suppresses any dispatch and no listener is ever attached). Mirrors\n // GeolocationCore's reinitPermission behavior in unsupported environments.\n return Promise.resolve();\n }\n this._permissionSubscribed = true;\n const gen = ++this._permGen;\n // Cast: WcsPermissionDescriptor widens `name` to string (and allows extra\n // descriptor members like userVisibleOnly / sysex) where the lib DOM type\n // expects the PermissionName union.\n return navigator.permissions.query(this._descriptor as unknown as PermissionDescriptor).then(\n (status) => {\n // Stale resolution: this query was superseded (rapid reconnect) or the\n // element was disposed while it was in flight. Drop it so only the current\n // subscription attaches a listener.\n if (gen !== this._permGen) return;\n this._permissionStatus = status;\n this._setState(status.state as PermissionStateOrUnsupported);\n status.addEventListener(\"change\", this._onPermissionChange);\n },\n () => {\n if (gen !== this._permGen) return;\n this._setState(\"unsupported\");\n },\n );\n }\n\n private _onPermissionChange = (event: Event): void => {\n const status = event.target as PermissionStatus;\n this._setState(status.state as PermissionStateOrUnsupported);\n };\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor } from \"../types.js\";\nimport { PermissionCore } from \"../core/PermissionCore.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\n\n// Named WcsPermission (not `Permission`) so the class does not shadow any global,\n// and to match the <wcs-geo> / <wcs-ws> convention (WcsGeolocation /\n// WcsWebSocket). The public export keeps the `WcsPermission` name unchanged.\nexport class WcsPermission extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...PermissionCore.wcBindable,\n // Shell-level settable surface. `name` is the permission name; the descriptor\n // extras `user-visible-only` (push) and `sysex` (midi) are boolean flags that\n // reflect idempotently, so a binding system that writes through\n // inputs[].attribute is safe.\n inputs: [\n { name: \"name\", attribute: \"name\" },\n { name: \"userVisibleOnly\", attribute: \"user-visible-only\" },\n { name: \"sysex\", attribute: \"sysex\" },\n ],\n // No commands: read-only monitor (see PermissionCore). The Permissions API has\n // no request() — acquiring a grant is the feature node's job.\n commands: [],\n };\n\n // Created in the Shell constructor with no descriptor so the delegated getters\n // work before connect (returning the default \"prompt\" / false). The actual\n // query is driven from connectedCallback once the element's attributes resolve\n // (programmatically-created elements have no attributes at construction time).\n private _core: PermissionCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PermissionCore(null, this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-permission:change\": (d) => ({\n granted: d === \"granted\",\n denied: d === \"denied\",\n prompt: d === \"prompt\",\n unsupported: d === \"unsupported\",\n }),\n });\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get name(): string {\n return this.getAttribute(\"name\") ?? \"\";\n }\n\n set name(value: string) {\n this.setAttribute(\"name\", value);\n }\n\n get userVisibleOnly(): boolean {\n return this.hasAttribute(\"user-visible-only\");\n }\n\n set userVisibleOnly(value: boolean) {\n if (value) {\n this.setAttribute(\"user-visible-only\", \"\");\n } else {\n this.removeAttribute(\"user-visible-only\");\n }\n }\n\n get sysex(): boolean {\n return this.hasAttribute(\"sysex\");\n }\n\n set sysex(value: boolean) {\n if (value) {\n this.setAttribute(\"sysex\", \"\");\n } else {\n this.removeAttribute(\"sysex\");\n }\n }\n\n // --- Core delegated getters ---\n\n get state(): PermissionStateOrUnsupported {\n return this._core.state;\n }\n\n get granted(): boolean {\n return this._core.granted;\n }\n\n get denied(): boolean {\n return this._core.denied;\n }\n\n get prompt(): boolean {\n return this._core.prompt;\n }\n\n get unsupported(): boolean {\n return this._core.unsupported;\n }\n\n // wc-bindable connectedCallbackPromise protocol: resolves once the connect-time\n // query settles, so SSR (@wcstack/server render.ts) waits for the first probe\n // before snapshotting the HTML. Mirrors WcsGeolocation.connectedCallbackPromise.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Internal ---\n\n // Build the query descriptor from the current attributes. Only present extras\n // are included so a bare `{ name }` is passed for permissions that take no\n // additional members. The descriptor is fixed at connect time (v1 does not\n // re-query on a `name` change — see README).\n private _descriptor(): WcsPermissionDescriptor {\n const descriptor: WcsPermissionDescriptor = { name: this.name };\n if (this.userVisibleOnly) descriptor.userVisibleOnly = true;\n if (this.sysex) descriptor.sysex = true;\n return descriptor;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n // Begin observing (or revive the subscription after a reconnect). The\n // returned promise is held as connectedCallbackPromise for SSR. query() never\n // rejects in a way that escapes — failures surface as the `unsupported`\n // state — so no .catch() is needed.\n this._connectedCallbackPromise = this._core.observe(this._descriptor());\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 bootstrapPermission(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { WcsPermission } from \"./components/Permission.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.permission)) {\n registry.define(config.tagNames.permission, WcsPermission);\n }\n}\n"],"names":["config","tagNames","permission","PermissionCore","EventTarget","static","protocol","version","properties","name","event","semantics","getter","e","detail","commands","_target","_descriptor","_state","_permissionStatus","_permissionSubscribed","_permGen","_ready","Promise","resolve","constructor","descriptor","target","super","this","_initPermission","state","granted","denied","prompt","unsupported","ready","_setState","dispatchEvent","CustomEvent","bubbles","observe","dispose","removeEventListener","_onPermissionChange","navigator","permissions","query","gen","then","status","addEventListener","hasAccessorOnPrototype","proto","Object","getPrototypeOf","getOwnPropertyDescriptor","undefined","get","set","WcsPermission","HTMLElement","wcBindable","inputs","attribute","_core","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","add","delete","map","toStates","entries","debug","hasAttribute","on","toggleAttribute","getAttribute","value","setAttribute","userVisibleOnly","removeAttribute","sysex","connectedCallbackPromise","connectedCallback","element","declaration","input","prototype","hasOwnProperty","call","record","upgradeProperties","style","display","disconnectedCallback","registry","customElements","define","registerComponents"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -109,7 +109,7 @@ interface WcsPermissionInputs {
109
109
  sysex: boolean;
110
110
  }
111
111
 
112
- declare function bootstrapPermission(userConfig?: IWritableConfig): void;
112
+ declare function bootstrapPermission(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void;
113
113
 
114
114
  declare function getConfig(): IConfig;
115
115
 
package/dist/index.esm.js CHANGED
@@ -432,17 +432,22 @@ class WcsPermission extends HTMLElement {
432
432
  }
433
433
  }
434
434
 
435
- function registerComponents() {
436
- if (!customElements.get(config.tagNames.permission)) {
437
- customElements.define(config.tagNames.permission, WcsPermission);
435
+ /**
436
+ * Register this package's tags. Pass a scoped `CustomElementRegistry` to define
437
+ * them for a single shadow tree -- scoped registries do not inherit the global
438
+ * one, so a tree using one needs its own definitions.
439
+ */
440
+ function registerComponents(registry = customElements) {
441
+ if (!registry.get(config.tagNames.permission)) {
442
+ registry.define(config.tagNames.permission, WcsPermission);
438
443
  }
439
444
  }
440
445
 
441
- function bootstrapPermission(userConfig) {
446
+ function bootstrapPermission(userConfig, registry) {
442
447
  if (userConfig) {
443
448
  setConfig(userConfig);
444
449
  }
445
- registerComponents();
450
+ registerComponents(registry);
446
451
  }
447
452
 
448
453
  export { PermissionCore, WcsPermission, bootstrapPermission, getConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/PermissionCore.ts","../src/protocol/upgradeProperties.ts","../src/components/Permission.ts","../src/registerComponents.ts","../src/bootstrapPermission.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n permission: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n permission: \"wcs-permission\",\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\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import {\n IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor,\n} from \"../types.js\";\n\n/**\n * Headless permission-state primitive. A thin, framework-agnostic wrapper around\n * the Permissions API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack IO nodes (geolocation / clipboard / sse / …), the\n * Permissions API is **read-only**: it has `query()` but no standard `request()`.\n * Asking the user for a grant is the job of the feature node (`<wcs-geo>` etc.);\n * this node only *observes*. It is therefore a pure element → state monitor with\n * **no commands** — command-token does not apply, only event-token.\n *\n * The single observable is `state` (`navigator.permissions.query(descriptor)`'s\n * `PermissionState`, or `\"unsupported\"`), published via the `wcs-permission:change`\n * event. `granted` / `denied` / `prompt` / `unsupported` are convenience booleans\n * derived from that one event (mirroring how GeolocationCore exposes latitude/…\n * from one `wcs-geo:position` event), so a binding like `hidden@granted` works\n * directly. The live `change` event of the PermissionStatus is tracked so a grant\n * flipping in browser settings flows into the declarative state.\n */\nexport class PermissionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"state\", event: \"wcs-permission:change\", semantics: \"state\" },\n { name: \"granted\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"granted\" },\n { name: \"denied\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"denied\" },\n { name: \"prompt\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"prompt\" },\n { name: \"unsupported\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"unsupported\" },\n ],\n // No commands: the Permissions API is read-only (query-only). See class docs.\n commands: [],\n };\n\n private _target: EventTarget;\n private _descriptor: WcsPermissionDescriptor | null = null;\n\n private _state: PermissionStateOrUnsupported = \"prompt\";\n\n // Live PermissionStatus handle (when the Permissions API is available), kept so\n // the `change` listener can be removed on dispose().\n private _permissionStatus: PermissionStatus | null = null;\n\n // True once a permission subscription has been (or is being) established, and\n // reset by dispose(). Guards observe() so a reconnect after dispose() re-queries\n // while a redundant observe() on an already-live subscription does not.\n private _permissionSubscribed: boolean = false;\n\n // Monotonic id of the current permission query. Bumped by every _initPermission()\n // and by dispose(). Each in-flight query captures its id and, on resolve, bails\n // unless it is still current — so a query superseded by a rapid (synchronous)\n // disconnect→reconnect, or one that resolves after dispose(), never attaches a\n // listener. A plain boolean cannot cover this: dispose()→observe() flips it\n // false→true again, reopening the window for the stale query to slip through.\n private _permGen: number = 0;\n\n // Resolves once the most recent query settles (or immediately when the API is\n // unsupported). The Shell exposes this as connectedCallbackPromise so SSR can\n // await the first probe before snapshotting the HTML.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(descriptor?: WcsPermissionDescriptor | null, target?: EventTarget) {\n super();\n this._target = target ?? this;\n // Headless ergonomics: when a descriptor is supplied up front, probe the\n // permission state immediately so observers see the real value before the\n // first read. The Shell passes nothing and drives the first query from\n // connectedCallback via observe(), once the element's attributes resolve.\n if (descriptor) {\n this._descriptor = descriptor;\n this._ready = this._initPermission();\n }\n }\n\n get state(): PermissionStateOrUnsupported {\n return this._state;\n }\n\n get granted(): boolean {\n return this._state === \"granted\";\n }\n\n get denied(): boolean {\n return this._state === \"denied\";\n }\n\n get prompt(): boolean {\n return this._state === \"prompt\";\n }\n\n get unsupported(): boolean {\n return this._state === \"unsupported\";\n }\n\n /** Resolves once the current (or initial) query settles. */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // --- State setter with event dispatch ---\n\n private _setState(state: PermissionStateOrUnsupported): void {\n // Same-value guard: `state` is the only stored value and the derived booleans\n // change in lockstep with it, so suppressing identical re-dispatches is safe.\n if (this._state === state) return;\n this._state = state;\n this._target.dispatchEvent(new CustomEvent(\"wcs-permission:change\", {\n detail: state,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `descriptor` (e.g. `{ name: \"geolocation\" }`). Idempotent\n * while already subscribed — calling it again only updates the stored descriptor\n * for a *future* re-subscription; it does **not** re-query, even when called with\n * a different descriptor (the Shell binds at a fixed connect-time descriptor and\n * does not re-query on a `name` change in v1). To switch permission mid-life,\n * dispose() first, then observe() the new descriptor. On the first call, or after\n * a dispose(), it issues the query and subscribes to the live `change` event.\n * Returns a promise that resolves once that query settles, for SSR.\n */\n observe(descriptor: WcsPermissionDescriptor): Promise<void> {\n this._descriptor = descriptor;\n if (!this._permissionSubscribed) {\n this._ready = this._initPermission();\n }\n return this._ready;\n }\n\n /**\n * Detach the live permission `change` listener. Call from the Shell's\n * `disconnectedCallback` so a removed element does not leak the subscription.\n * A later reconnect can re-subscribe via observe().\n *\n * Headless callers (using PermissionCore directly, without the Shell) own this\n * lifecycle themselves: call dispose() when the observer is no longer needed,\n * otherwise the live PermissionStatus `change` listener keeps this instance\n * reachable for as long as the status is alive. dispose() is safe to call when\n * never subscribed and may be paired with a later observe() to resume.\n */\n dispose(): void {\n this._permissionSubscribed = false;\n // Invalidate any in-flight query so its .then() bails instead of attaching a\n // listener after teardown.\n this._permGen++;\n if (this._permissionStatus) {\n this._permissionStatus.removeEventListener(\"change\", this._onPermissionChange);\n this._permissionStatus = null;\n }\n }\n\n // --- Internal ---\n\n private _initPermission(): Promise<void> {\n // Guard a missing/empty permission name (e.g. a `<wcs-permission>` with no\n // `name` attribute). Such a descriptor would only ever reject at query() and\n // silently fall back to \"unsupported\", which is hard to diagnose. Short-circuit\n // to \"unsupported\" without issuing a doomed query so the misconfiguration\n // surfaces deterministically and no listener is attached.\n if (!this._descriptor || !this._descriptor.name) {\n this._setState(\"unsupported\");\n return Promise.resolve();\n }\n // The Permissions API is optional. When absent (or it rejects, e.g. the\n // browser does not accept the requested permission name), report \"unsupported\"\n // and leave it at that — there is nothing to retry.\n if (typeof navigator === \"undefined\" || !navigator.permissions || typeof navigator.permissions.query !== \"function\") {\n // Route through _setState (not a bare assignment) so observers stay in sync\n // with the public state. The same-value guard means no redundant dispatch\n // when the state does not actually change.\n this._setState(\"unsupported\");\n // Intentionally does NOT set _permissionSubscribed: there is no listener to\n // tear down, so a reconnect simply re-probes (idempotent — the same-value\n // guard suppresses any dispatch and no listener is ever attached). Mirrors\n // GeolocationCore's reinitPermission behavior in unsupported environments.\n return Promise.resolve();\n }\n this._permissionSubscribed = true;\n const gen = ++this._permGen;\n // Cast: WcsPermissionDescriptor widens `name` to string (and allows extra\n // descriptor members like userVisibleOnly / sysex) where the lib DOM type\n // expects the PermissionName union.\n return navigator.permissions.query(this._descriptor as unknown as PermissionDescriptor).then(\n (status) => {\n // Stale resolution: this query was superseded (rapid reconnect) or the\n // element was disposed while it was in flight. Drop it so only the current\n // subscription attaches a listener.\n if (gen !== this._permGen) return;\n this._permissionStatus = status;\n this._setState(status.state as PermissionStateOrUnsupported);\n status.addEventListener(\"change\", this._onPermissionChange);\n },\n () => {\n if (gen !== this._permGen) return;\n this._setState(\"unsupported\");\n },\n );\n }\n\n private _onPermissionChange = (event: Event): void => {\n const status = event.target as PermissionStatus;\n this._setState(status.state as PermissionStateOrUnsupported);\n };\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor } from \"../types.js\";\nimport { PermissionCore } from \"../core/PermissionCore.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\n\n// Named WcsPermission (not `Permission`) so the class does not shadow any global,\n// and to match the <wcs-geo> / <wcs-ws> convention (WcsGeolocation /\n// WcsWebSocket). The public export keeps the `WcsPermission` name unchanged.\nexport class WcsPermission extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...PermissionCore.wcBindable,\n // Shell-level settable surface. `name` is the permission name; the descriptor\n // extras `user-visible-only` (push) and `sysex` (midi) are boolean flags that\n // reflect idempotently, so a binding system that writes through\n // inputs[].attribute is safe.\n inputs: [\n { name: \"name\", attribute: \"name\" },\n { name: \"userVisibleOnly\", attribute: \"user-visible-only\" },\n { name: \"sysex\", attribute: \"sysex\" },\n ],\n // No commands: read-only monitor (see PermissionCore). The Permissions API has\n // no request() — acquiring a grant is the feature node's job.\n commands: [],\n };\n\n // Created in the Shell constructor with no descriptor so the delegated getters\n // work before connect (returning the default \"prompt\" / false). The actual\n // query is driven from connectedCallback once the element's attributes resolve\n // (programmatically-created elements have no attributes at construction time).\n private _core: PermissionCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PermissionCore(null, this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-permission:change\": (d) => ({\n granted: d === \"granted\",\n denied: d === \"denied\",\n prompt: d === \"prompt\",\n unsupported: d === \"unsupported\",\n }),\n });\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get name(): string {\n return this.getAttribute(\"name\") ?? \"\";\n }\n\n set name(value: string) {\n this.setAttribute(\"name\", value);\n }\n\n get userVisibleOnly(): boolean {\n return this.hasAttribute(\"user-visible-only\");\n }\n\n set userVisibleOnly(value: boolean) {\n if (value) {\n this.setAttribute(\"user-visible-only\", \"\");\n } else {\n this.removeAttribute(\"user-visible-only\");\n }\n }\n\n get sysex(): boolean {\n return this.hasAttribute(\"sysex\");\n }\n\n set sysex(value: boolean) {\n if (value) {\n this.setAttribute(\"sysex\", \"\");\n } else {\n this.removeAttribute(\"sysex\");\n }\n }\n\n // --- Core delegated getters ---\n\n get state(): PermissionStateOrUnsupported {\n return this._core.state;\n }\n\n get granted(): boolean {\n return this._core.granted;\n }\n\n get denied(): boolean {\n return this._core.denied;\n }\n\n get prompt(): boolean {\n return this._core.prompt;\n }\n\n get unsupported(): boolean {\n return this._core.unsupported;\n }\n\n // wc-bindable connectedCallbackPromise protocol: resolves once the connect-time\n // query settles, so SSR (@wcstack/server render.ts) waits for the first probe\n // before snapshotting the HTML. Mirrors WcsGeolocation.connectedCallbackPromise.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Internal ---\n\n // Build the query descriptor from the current attributes. Only present extras\n // are included so a bare `{ name }` is passed for permissions that take no\n // additional members. The descriptor is fixed at connect time (v1 does not\n // re-query on a `name` change — see README).\n private _descriptor(): WcsPermissionDescriptor {\n const descriptor: WcsPermissionDescriptor = { name: this.name };\n if (this.userVisibleOnly) descriptor.userVisibleOnly = true;\n if (this.sysex) descriptor.sysex = true;\n return descriptor;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n // Begin observing (or revive the subscription after a reconnect). The\n // returned promise is held as connectedCallbackPromise for SSR. query() never\n // rejects in a way that escapes — failures surface as the `unsupported`\n // state — so no .catch() is needed.\n this._connectedCallbackPromise = this._core.observe(this._descriptor());\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsPermission } from \"./components/Permission.js\";\nimport { config } from \"./config.js\";\n\nexport function registerComponents(): void {\n if (!customElements.get(config.tagNames.permission)) {\n customElements.define(config.tagNames.permission, WcsPermission);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPermission(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/PermissionCore.ts","../src/protocol/upgradeProperties.ts","../src/components/Permission.ts","../src/registerComponents.ts","../src/bootstrapPermission.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n tagNames: {\n permission: string;\n };\n}\n\nconst _config: IInternalConfig = {\n tagNames: {\n permission: \"wcs-permission\",\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\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 (partialConfig.tagNames) {\n Object.assign(_config.tagNames, partialConfig.tagNames);\n }\n frozenConfig = null;\n}\n","import {\n IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor,\n} from \"../types.js\";\n\n/**\n * Headless permission-state primitive. A thin, framework-agnostic wrapper around\n * the Permissions API exposed through the wc-bindable protocol.\n *\n * Unlike the other @wcstack IO nodes (geolocation / clipboard / sse / …), the\n * Permissions API is **read-only**: it has `query()` but no standard `request()`.\n * Asking the user for a grant is the job of the feature node (`<wcs-geo>` etc.);\n * this node only *observes*. It is therefore a pure element → state monitor with\n * **no commands** — command-token does not apply, only event-token.\n *\n * The single observable is `state` (`navigator.permissions.query(descriptor)`'s\n * `PermissionState`, or `\"unsupported\"`), published via the `wcs-permission:change`\n * event. `granted` / `denied` / `prompt` / `unsupported` are convenience booleans\n * derived from that one event (mirroring how GeolocationCore exposes latitude/…\n * from one `wcs-geo:position` event), so a binding like `hidden@granted` works\n * directly. The live `change` event of the PermissionStatus is tracked so a grant\n * flipping in browser settings flows into the declarative state.\n */\nexport class PermissionCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"state\", event: \"wcs-permission:change\", semantics: \"state\" },\n { name: \"granted\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"granted\" },\n { name: \"denied\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"denied\" },\n { name: \"prompt\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"prompt\" },\n { name: \"unsupported\", event: \"wcs-permission:change\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail === \"unsupported\" },\n ],\n // No commands: the Permissions API is read-only (query-only). See class docs.\n commands: [],\n };\n\n private _target: EventTarget;\n private _descriptor: WcsPermissionDescriptor | null = null;\n\n private _state: PermissionStateOrUnsupported = \"prompt\";\n\n // Live PermissionStatus handle (when the Permissions API is available), kept so\n // the `change` listener can be removed on dispose().\n private _permissionStatus: PermissionStatus | null = null;\n\n // True once a permission subscription has been (or is being) established, and\n // reset by dispose(). Guards observe() so a reconnect after dispose() re-queries\n // while a redundant observe() on an already-live subscription does not.\n private _permissionSubscribed: boolean = false;\n\n // Monotonic id of the current permission query. Bumped by every _initPermission()\n // and by dispose(). Each in-flight query captures its id and, on resolve, bails\n // unless it is still current — so a query superseded by a rapid (synchronous)\n // disconnect→reconnect, or one that resolves after dispose(), never attaches a\n // listener. A plain boolean cannot cover this: dispose()→observe() flips it\n // false→true again, reopening the window for the stale query to slip through.\n private _permGen: number = 0;\n\n // Resolves once the most recent query settles (or immediately when the API is\n // unsupported). The Shell exposes this as connectedCallbackPromise so SSR can\n // await the first probe before snapshotting the HTML.\n private _ready: Promise<void> = Promise.resolve();\n\n constructor(descriptor?: WcsPermissionDescriptor | null, target?: EventTarget) {\n super();\n this._target = target ?? this;\n // Headless ergonomics: when a descriptor is supplied up front, probe the\n // permission state immediately so observers see the real value before the\n // first read. The Shell passes nothing and drives the first query from\n // connectedCallback via observe(), once the element's attributes resolve.\n if (descriptor) {\n this._descriptor = descriptor;\n this._ready = this._initPermission();\n }\n }\n\n get state(): PermissionStateOrUnsupported {\n return this._state;\n }\n\n get granted(): boolean {\n return this._state === \"granted\";\n }\n\n get denied(): boolean {\n return this._state === \"denied\";\n }\n\n get prompt(): boolean {\n return this._state === \"prompt\";\n }\n\n get unsupported(): boolean {\n return this._state === \"unsupported\";\n }\n\n /** Resolves once the current (or initial) query settles. */\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // --- State setter with event dispatch ---\n\n private _setState(state: PermissionStateOrUnsupported): void {\n // Same-value guard: `state` is the only stored value and the derived booleans\n // change in lockstep with it, so suppressing identical re-dispatches is safe.\n if (this._state === state) return;\n this._state = state;\n this._target.dispatchEvent(new CustomEvent(\"wcs-permission:change\", {\n detail: state,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n /**\n * Start observing `descriptor` (e.g. `{ name: \"geolocation\" }`). Idempotent\n * while already subscribed — calling it again only updates the stored descriptor\n * for a *future* re-subscription; it does **not** re-query, even when called with\n * a different descriptor (the Shell binds at a fixed connect-time descriptor and\n * does not re-query on a `name` change in v1). To switch permission mid-life,\n * dispose() first, then observe() the new descriptor. On the first call, or after\n * a dispose(), it issues the query and subscribes to the live `change` event.\n * Returns a promise that resolves once that query settles, for SSR.\n */\n observe(descriptor: WcsPermissionDescriptor): Promise<void> {\n this._descriptor = descriptor;\n if (!this._permissionSubscribed) {\n this._ready = this._initPermission();\n }\n return this._ready;\n }\n\n /**\n * Detach the live permission `change` listener. Call from the Shell's\n * `disconnectedCallback` so a removed element does not leak the subscription.\n * A later reconnect can re-subscribe via observe().\n *\n * Headless callers (using PermissionCore directly, without the Shell) own this\n * lifecycle themselves: call dispose() when the observer is no longer needed,\n * otherwise the live PermissionStatus `change` listener keeps this instance\n * reachable for as long as the status is alive. dispose() is safe to call when\n * never subscribed and may be paired with a later observe() to resume.\n */\n dispose(): void {\n this._permissionSubscribed = false;\n // Invalidate any in-flight query so its .then() bails instead of attaching a\n // listener after teardown.\n this._permGen++;\n if (this._permissionStatus) {\n this._permissionStatus.removeEventListener(\"change\", this._onPermissionChange);\n this._permissionStatus = null;\n }\n }\n\n // --- Internal ---\n\n private _initPermission(): Promise<void> {\n // Guard a missing/empty permission name (e.g. a `<wcs-permission>` with no\n // `name` attribute). Such a descriptor would only ever reject at query() and\n // silently fall back to \"unsupported\", which is hard to diagnose. Short-circuit\n // to \"unsupported\" without issuing a doomed query so the misconfiguration\n // surfaces deterministically and no listener is attached.\n if (!this._descriptor || !this._descriptor.name) {\n this._setState(\"unsupported\");\n return Promise.resolve();\n }\n // The Permissions API is optional. When absent (or it rejects, e.g. the\n // browser does not accept the requested permission name), report \"unsupported\"\n // and leave it at that — there is nothing to retry.\n if (typeof navigator === \"undefined\" || !navigator.permissions || typeof navigator.permissions.query !== \"function\") {\n // Route through _setState (not a bare assignment) so observers stay in sync\n // with the public state. The same-value guard means no redundant dispatch\n // when the state does not actually change.\n this._setState(\"unsupported\");\n // Intentionally does NOT set _permissionSubscribed: there is no listener to\n // tear down, so a reconnect simply re-probes (idempotent — the same-value\n // guard suppresses any dispatch and no listener is ever attached). Mirrors\n // GeolocationCore's reinitPermission behavior in unsupported environments.\n return Promise.resolve();\n }\n this._permissionSubscribed = true;\n const gen = ++this._permGen;\n // Cast: WcsPermissionDescriptor widens `name` to string (and allows extra\n // descriptor members like userVisibleOnly / sysex) where the lib DOM type\n // expects the PermissionName union.\n return navigator.permissions.query(this._descriptor as unknown as PermissionDescriptor).then(\n (status) => {\n // Stale resolution: this query was superseded (rapid reconnect) or the\n // element was disposed while it was in flight. Drop it so only the current\n // subscription attaches a listener.\n if (gen !== this._permGen) return;\n this._permissionStatus = status;\n this._setState(status.state as PermissionStateOrUnsupported);\n status.addEventListener(\"change\", this._onPermissionChange);\n },\n () => {\n if (gen !== this._permGen) return;\n this._setState(\"unsupported\");\n },\n );\n }\n\n private _onPermissionChange = (event: Event): void => {\n const status = event.target as PermissionStatus;\n this._setState(status.state as PermissionStateOrUnsupported);\n };\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/upgrade-properties.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// custom element の property upgrade — `static wcBindable.inputs` に宣言した入力のうち、\n// 要素が upgrade される前に代入された own データプロパティを取り込み直す。\n//\n// なぜ必要か:\n// 未定義タグの要素は素の HTMLElement なので、`el.url = \"...\"` は own データプロパティを作る。\n// upgrade 後にクラスの accessor が prototype へ入っても own プロパティが優先されるため、\n// setter は二度と呼ばれず、値は要素へ届かないまま消える(エラーも警告も出ない)。\n// 常にプロパティ代入を行う framework(Angular の `[prop]`、Lit の `.prop=`、\n// Solid の `prop:`、Vue の `.prop` 修飾子)× 遅延定義(autoloader / CDN / code-split)で\n// 常態的に起きる。docs/architecture-hardening/13-framework-adapter-binding-constraints.md §1.2。\n//\n// 安全側の判定:\n// own プロパティがあっても、prototype チェーンに accessor が無ければ「シャドウ」ではなく\n// その own プロパティ自体が正規の格納先なので触らない(public class field を壊さない)。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/upgrade-properties.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/upgradeProperties.ts). Those copies are generated — do not edit them.\nimport { IWcBindable } from \"./wcBindable.js\";\n\nfunction hasAccessorOnPrototype(target: object, name: string): boolean {\n let proto = Object.getPrototypeOf(target);\n while (proto !== null) {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name);\n if (descriptor !== undefined) {\n return typeof descriptor.get === \"function\" || typeof descriptor.set === \"function\";\n }\n proto = Object.getPrototypeOf(proto);\n }\n return false;\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n */\nexport function upgradeProperties(element: object): void {\n const declaration = (element as { constructor?: { wcBindable?: IWcBindable } }).constructor?.wcBindable;\n const inputs = declaration?.inputs;\n if (inputs === undefined) return;\n for (const input of inputs) {\n const name = input.name;\n if (!Object.prototype.hasOwnProperty.call(element, name)) continue;\n if (!hasAccessorOnPrototype(element, name)) continue;\n const record = element as Record<string, unknown>;\n const value = record[name];\n delete record[name];\n record[name] = value;\n }\n}\n","import { IWcBindable, PermissionStateOrUnsupported, WcsPermissionDescriptor } from \"../types.js\";\nimport { PermissionCore } from \"../core/PermissionCore.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\n\n// Named WcsPermission (not `Permission`) so the class does not shadow any global,\n// and to match the <wcs-geo> / <wcs-ws> convention (WcsGeolocation /\n// WcsWebSocket). The public export keeps the `WcsPermission` name unchanged.\nexport class WcsPermission extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...PermissionCore.wcBindable,\n // Shell-level settable surface. `name` is the permission name; the descriptor\n // extras `user-visible-only` (push) and `sysex` (midi) are boolean flags that\n // reflect idempotently, so a binding system that writes through\n // inputs[].attribute is safe.\n inputs: [\n { name: \"name\", attribute: \"name\" },\n { name: \"userVisibleOnly\", attribute: \"user-visible-only\" },\n { name: \"sysex\", attribute: \"sysex\" },\n ],\n // No commands: read-only monitor (see PermissionCore). The Permissions API has\n // no request() — acquiring a grant is the feature node's job.\n commands: [],\n };\n\n // Created in the Shell constructor with no descriptor so the delegated getters\n // work before connect (returning the default \"prompt\" / false). The actual\n // query is driven from connectedCallback once the element's attributes resolve\n // (programmatically-created elements have no attributes at construction time).\n private _core: PermissionCore;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new PermissionCore(null, this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-permission:change\": (d) => ({\n granted: d === \"granted\",\n denied: d === \"denied\",\n prompt: d === \"prompt\",\n unsupported: d === \"unsupported\",\n }),\n });\n }\n\n // CSS state reflection (:state()) — debug-only snapshot getter. NOT part of\n // wc-bindable (not a bind target); see README \"CSS styling with :state()\".\n // MUST NOT return the live CustomStateSet (that would let callers write\n // states from outside, defeating the point of :state() being read-only).\n get debugStates(): string[] {\n return this._internals ? [...this._internals.states] : [];\n }\n\n private _initInternals(): ElementInternals | null {\n // never-throw (async-io-node-guidelines.md §3.6): attachInternals is absent\n // in happy-dom / older environments, and pre-125 Chromium rejects\n // non-dashed state names from states.add() (probed and discarded here).\n // Either case silently disables reflection — the component still works,\n // it just doesn't expose :state() selectors.\n try {\n if (typeof this.attachInternals !== \"function\") return null;\n const internals = this.attachInternals();\n internals.states.add(\"wcs-probe\");\n internals.states.delete(\"wcs-probe\");\n return internals;\n } catch {\n return null;\n }\n }\n\n private _wireStates(map: Record<string, (detail: any) => Record<string, boolean>>): void {\n if (this._internals === null) return;\n const states = this._internals.states;\n for (const [event, toStates] of Object.entries(map)) {\n this.addEventListener(event, (e) => {\n const debug = this.hasAttribute(\"debug-states\");\n for (const [name, on] of Object.entries(toStates((e as CustomEvent).detail))) {\n try {\n if (on) { states.add(name); } else { states.delete(name); }\n } catch { /* never-throw */ }\n if (debug) this.toggleAttribute(`data-wcs-state-${name}`, on);\n }\n });\n }\n }\n\n // --- Attribute accessors ---\n\n get name(): string {\n return this.getAttribute(\"name\") ?? \"\";\n }\n\n set name(value: string) {\n this.setAttribute(\"name\", value);\n }\n\n get userVisibleOnly(): boolean {\n return this.hasAttribute(\"user-visible-only\");\n }\n\n set userVisibleOnly(value: boolean) {\n if (value) {\n this.setAttribute(\"user-visible-only\", \"\");\n } else {\n this.removeAttribute(\"user-visible-only\");\n }\n }\n\n get sysex(): boolean {\n return this.hasAttribute(\"sysex\");\n }\n\n set sysex(value: boolean) {\n if (value) {\n this.setAttribute(\"sysex\", \"\");\n } else {\n this.removeAttribute(\"sysex\");\n }\n }\n\n // --- Core delegated getters ---\n\n get state(): PermissionStateOrUnsupported {\n return this._core.state;\n }\n\n get granted(): boolean {\n return this._core.granted;\n }\n\n get denied(): boolean {\n return this._core.denied;\n }\n\n get prompt(): boolean {\n return this._core.prompt;\n }\n\n get unsupported(): boolean {\n return this._core.unsupported;\n }\n\n // wc-bindable connectedCallbackPromise protocol: resolves once the connect-time\n // query settles, so SSR (@wcstack/server render.ts) waits for the first probe\n // before snapshotting the HTML. Mirrors WcsGeolocation.connectedCallbackPromise.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Internal ---\n\n // Build the query descriptor from the current attributes. Only present extras\n // are included so a bare `{ name }` is passed for permissions that take no\n // additional members. The descriptor is fixed at connect time (v1 does not\n // re-query on a `name` change — see README).\n private _descriptor(): WcsPermissionDescriptor {\n const descriptor: WcsPermissionDescriptor = { name: this.name };\n if (this.userVisibleOnly) descriptor.userVisibleOnly = true;\n if (this.sysex) descriptor.sysex = true;\n return descriptor;\n }\n\n // --- Lifecycle ---\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n // Begin observing (or revive the subscription after a reconnect). The\n // returned promise is held as connectedCallbackPromise for SSR. query() never\n // rejects in a way that escapes — failures surface as the `unsupported`\n // state — so no .catch() is needed.\n this._connectedCallbackPromise = this._core.observe(this._descriptor());\n }\n\n disconnectedCallback(): void {\n this._core.dispose();\n }\n}\n","import { WcsPermission } from \"./components/Permission.js\";\nimport { config } from \"./config.js\";\n\n/**\n * Register this package's tags. Pass a scoped `CustomElementRegistry` to define\n * them for a single shadow tree -- scoped registries do not inherit the global\n * one, so a tree using one needs its own definitions.\n */\nexport function registerComponents(registry: CustomElementRegistry = customElements): void {\n if (!registry.get(config.tagNames.permission)) {\n registry.define(config.tagNames.permission, WcsPermission);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapPermission(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wcstack/permission",
3
- "version": "1.30.0",
3
+ "version": "1.31.0",
4
4
  "description": "Declarative permission-state component for Web Components. Framework-agnostic Permissions API monitor via wc-bindable-protocol.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",