@wcstack/timer 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +4 -0
- package/README.md +4 -0
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +38 -4
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -102,6 +102,10 @@ npm install @wcstack/timer
|
|
|
102
102
|
|
|
103
103
|
**`null` と `undefined`。** 属性に対応する入力(`interval`・`once`・`repeat`・`immediate`・`manual`)は、`null` を「クリア」として扱います。属性を外し、入力は既定値に戻ります。`undefined` は「値が無い」で、属性を最初の書き込みの前の状態 — マークアップに書かれた値、無ければ属性なし — に戻します。どちらも文字列 `"null"` / `"undefined"` として書くことはありません(`@wcstack/state` は `undefined` を書きませんが、React 19 は値のあった prop を外したときに書き、直接の代入でも届きます)。動作中のタイマーは、ほかの `interval` 変更と同じく、戻った値または既定値の周期にその場で張り直します。`trigger` はどちらも無視します。
|
|
104
104
|
|
|
105
|
+
**4.8 から、自動開始はマイクロタスクを 1 つ待つ。** 開始するか(`manual`)、どの `interval` / `repeat` / `once` / `immediate` でかは、`connectedCallback` の 1 マイクロタスク後に、そのときの入力で決める([タイミング契約](../../docs/timing-and-firing-contract.ja.md) §23)。`@wcstack/router` はパラメータだけの遷移でルートの要素を入れ直し、`@wcstack/state` が次のルートの入力を書くのはその後。同じタスクの `stop()` / `reset()` は開始を取り消し、`pause()` はその場で開始してから一時停止する。
|
|
106
|
+
|
|
107
|
+
**刻みは時間ではない。** 隠れたタブのタイマーは間引かれ(Chromium: 5 分隠れた後は 1 分に 1 回まで)、スリープ中のノートパソコンは 1 つも走らせないので、`tick` × `interval` は時計から遅れます — 1 秒のタイマーは、1 時間のスリープの間に数回しか数えません。時間を測るには、刻みごとに時計(`Date.now()`)を読んで state に持ちます。[開いたままのページ](../../docs/long-lived-pages.ja.md) を見てください。
|
|
108
|
+
|
|
105
109
|
## 観測プロパティ(出力)
|
|
106
110
|
|
|
107
111
|
| プロパティ | イベント | 説明 |
|
package/README.md
CHANGED
|
@@ -109,6 +109,10 @@ When `<wcs-timer>` is connected to the DOM, it automatically starts an interval
|
|
|
109
109
|
|
|
110
110
|
**`null` and `undefined`.** The inputs backed by an attribute (`interval`, `once`, `repeat`, `immediate`, `manual`) take `null` as "clear": the attribute is removed and the input falls back to its default. `undefined` means "no value supplied": the attribute goes back to what it was before the first write — the value written in the markup, or none. Neither is ever written as the string `"null"` / `"undefined"`. (`@wcstack/state` never writes `undefined`; React 19 does when a prop that had a value is removed, and so can a direct assignment.) A running timer swaps to the restored or default `interval` in place, like any other `interval` change; `trigger` ignores both.
|
|
111
111
|
|
|
112
|
+
**Since 4.8, the auto-start waits one microtask.** Whether to start (`manual`), and with which `interval` / `repeat` / `once` / `immediate`, is decided one microtask after `connectedCallback`, with the inputs as they are then ([timing contract](../../docs/timing-and-firing-contract.md) §23): `@wcstack/router` puts a route's elements back on a parameter-only navigation before `@wcstack/state` writes the next route's inputs. `stop()` / `reset()` in the same task cancel the start; `pause()` starts it then and pauses it.
|
|
113
|
+
|
|
114
|
+
**Ticks are not time.** A hidden tab's timers are throttled (Chromium: at most once a minute after five minutes hidden) and a sleeping laptop runs none, so `tick` × `interval` falls behind the clock — a 1-second timer counts a few ticks over an hour asleep. To measure time, read the clock (`Date.now()`) on each tick and keep it in state; see [Pages that stay open](../../docs/long-lived-pages.md).
|
|
115
|
+
|
|
112
116
|
## Observable Properties (outputs)
|
|
113
117
|
|
|
114
118
|
| Property | Event | Description |
|
package/dist/auto.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const t={triggerAttribute:"data-timertarget",tagNames:{timer:"wcs-timer"}};class e extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"tick",event:"wcs-timer:tick",semantics:"state",getter:t=>t.detail.count},{name:"elapsed",event:"wcs-timer:tick",semantics:"state",getter:t=>t.detail.elapsed},{name:"running",event:"wcs-timer:running-changed",semantics:"state"}],commands:[{name:"start"},{name:"stop"},{name:"reset"},{name:"pause"},{name:"resume"}]};_target;_timerId=null;_gen=0;_runGen=0;_ready=Promise.resolve();_tick=0;_running=!1;_paused=!1;_runStartTick=0;_interval=1e3;_repeat=0;_accumulatedElapsed=0;_segmentStart=null;constructor(t){super(),this._target=t??this}get tick(){return this._tick}get elapsed(){return this._currentElapsed()}get running(){return this._running}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.stop()}_dispatchTick(){this._target.dispatchEvent(new CustomEvent("wcs-timer:tick",{detail:{count:this._tick,elapsed:this._currentElapsed()},bubbles:!0}))}_setRunning(t){this._running!==t&&(this._running=t,this._target.dispatchEvent(new CustomEvent("wcs-timer:running-changed",{detail:t,bubbles:!0})))}start(t={}){if(this._running)return;this._paused=!1,"number"==typeof t.interval&&Number.isFinite(t.interval)&&t.interval>0&&(this._interval=t.interval),this._repeat="number"==typeof t.repeat&&t.repeat>0?t.repeat:0;const e=!0===t.immediate;this._setRunning(!0),this._segmentStart=Date.now(),this._runStartTick=this._tick,this._runGen=++this._gen,e&&this._fire(),this._running&&(this._timerId=setInterval(this._fire,this._interval))}changeInterval(t){this._running&&"number"==typeof t&&Number.isFinite(t)&&t>0&&t!==this._interval&&(this._interval=t,this._clearTimer(),this._timerId=setInterval(this._fire,this._interval))}stop(){this._clearTimer(),this._foldElapsed(),this._paused=!1,this._setRunning(!1)}reset(){this._clearTimer(),this._paused=!1,this._tick=0,this._accumulatedElapsed=0,this._segmentStart=null,this._setRunning(!1),this._dispatchTick()}pause(){this._running&&!this._paused&&(this._clearTimer(),this._foldElapsed(),this._paused=!0,this._setRunning(!1))}resume(){if(!this._paused)return;this._paused=!1,this._setRunning(!0),this._segmentStart=Date.now(),this._runGen=++this._gen;const t=this._interval-this._accumulatedElapsed%this._interval;this._timerId=setTimeout(this._onResumeBoundary,t)}_onResumeBoundary=()=>{this._runGen===this._gen&&(this._timerId=null,this._fire(),this._running&&(this._timerId=setInterval(this._fire,this._interval)))};_fire=()=>{this._runGen===this._gen&&(this._tick++,this._dispatchTick(),this._repeat>0&&this._tick-this._runStartTick>=this._repeat&&(this._clearTimer(),this._foldElapsed(),this._setRunning(!1)))};_clearTimer(){null!==this._timerId&&(clearTimeout(this._timerId),clearInterval(this._timerId),this._timerId=null)}_foldElapsed(){null!==this._segmentStart&&(this._accumulatedElapsed+=Date.now()-this._segmentStart,this._segmentStart=null)}_currentElapsed(){return this._accumulatedElapsed+(null!==this._segmentStart?Date.now()-this._segmentStart:0)}}let i=!1;function n(e){const i=e.target;if(!(i instanceof Element))return;const n=i.closest(`[${t.triggerAttribute}]`);if(!n)return;const s=n.getAttribute(t.triggerAttribute);if(!s)return;const r=customElements.get(t.tagNames.timer),a=document.getElementById(s);r&&a instanceof r&&(e.preventDefault(),a.start())}function s(t,e){let i=Object.getPrototypeOf(t);for(;null!==i;){const t=Object.getOwnPropertyDescriptor(i,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;i=Object.getPrototypeOf(i)}return!1}const r=new WeakSet;function a(t,e,i){if(r.has(t))return;r.add(t);const n=t.localName??"element";console.warn(`[wcs/input-as-attribute] <${n}> has the attribute ${e}="${i}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,t)}const c=new WeakMap;function u(t,e){let i=c.get(t);return void 0===i&&(i=new Map,c.set(t,i)),i.has(e)||i.set(e,t.getAttribute(e)),i.get(e)}function
|
|
1
|
+
const t={triggerAttribute:"data-timertarget",tagNames:{timer:"wcs-timer"}};class e extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"tick",event:"wcs-timer:tick",semantics:"state",getter:t=>t.detail.count},{name:"elapsed",event:"wcs-timer:tick",semantics:"state",getter:t=>t.detail.elapsed},{name:"running",event:"wcs-timer:running-changed",semantics:"state"}],commands:[{name:"start"},{name:"stop"},{name:"reset"},{name:"pause"},{name:"resume"}]};_target;_timerId=null;_gen=0;_runGen=0;_ready=Promise.resolve();_tick=0;_running=!1;_paused=!1;_runStartTick=0;_interval=1e3;_repeat=0;_accumulatedElapsed=0;_segmentStart=null;constructor(t){super(),this._target=t??this}get tick(){return this._tick}get elapsed(){return this._currentElapsed()}get running(){return this._running}get ready(){return this._ready}observe(){return this._ready}dispose(){this._gen++,this.stop()}_dispatchTick(){this._target.dispatchEvent(new CustomEvent("wcs-timer:tick",{detail:{count:this._tick,elapsed:this._currentElapsed()},bubbles:!0}))}_setRunning(t){this._running!==t&&(this._running=t,this._target.dispatchEvent(new CustomEvent("wcs-timer:running-changed",{detail:t,bubbles:!0})))}start(t={}){if(this._running)return;this._paused=!1,"number"==typeof t.interval&&Number.isFinite(t.interval)&&t.interval>0&&(this._interval=t.interval),this._repeat="number"==typeof t.repeat&&t.repeat>0?t.repeat:0;const e=!0===t.immediate;this._setRunning(!0),this._segmentStart=Date.now(),this._runStartTick=this._tick,this._runGen=++this._gen,e&&this._fire(),this._running&&(this._timerId=setInterval(this._fire,this._interval))}changeInterval(t){this._running&&"number"==typeof t&&Number.isFinite(t)&&t>0&&t!==this._interval&&(this._interval=t,this._clearTimer(),this._timerId=setInterval(this._fire,this._interval))}stop(){this._clearTimer(),this._foldElapsed(),this._paused=!1,this._setRunning(!1)}reset(){this._clearTimer(),this._paused=!1,this._tick=0,this._accumulatedElapsed=0,this._segmentStart=null,this._setRunning(!1),this._dispatchTick()}pause(){this._running&&!this._paused&&(this._clearTimer(),this._foldElapsed(),this._paused=!0,this._setRunning(!1))}resume(){if(!this._paused)return;this._paused=!1,this._setRunning(!0),this._segmentStart=Date.now(),this._runGen=++this._gen;const t=this._interval-this._accumulatedElapsed%this._interval;this._timerId=setTimeout(this._onResumeBoundary,t)}_onResumeBoundary=()=>{this._runGen===this._gen&&(this._timerId=null,this._fire(),this._running&&(this._timerId=setInterval(this._fire,this._interval)))};_fire=()=>{this._runGen===this._gen&&(this._tick++,this._dispatchTick(),this._repeat>0&&this._tick-this._runStartTick>=this._repeat&&(this._clearTimer(),this._foldElapsed(),this._setRunning(!1)))};_clearTimer(){null!==this._timerId&&(clearTimeout(this._timerId),clearInterval(this._timerId),this._timerId=null)}_foldElapsed(){null!==this._segmentStart&&(this._accumulatedElapsed+=Date.now()-this._segmentStart,this._segmentStart=null)}_currentElapsed(){return this._accumulatedElapsed+(null!==this._segmentStart?Date.now()-this._segmentStart:0)}}let i=!1;function n(e){const i=e.target;if(!(i instanceof Element))return;const n=i.closest(`[${t.triggerAttribute}]`);if(!n)return;const s=n.getAttribute(t.triggerAttribute);if(!s)return;const r=customElements.get(t.tagNames.timer),a=document.getElementById(s);r&&a instanceof r&&(e.preventDefault(),a.start())}function s(t,e){let i=Object.getPrototypeOf(t);for(;null!==i;){const t=Object.getOwnPropertyDescriptor(i,e);if(void 0!==t)return"function"==typeof t.get||"function"==typeof t.set;i=Object.getPrototypeOf(i)}return!1}const r=new WeakSet;function a(t,e,i){if(r.has(t))return;r.add(t);const n=t.localName??"element";console.warn(`[wcs/input-as-attribute] <${n}> has the attribute ${e}="${i}": an object was written as an attribute, so the element did not receive it. A framework does that when the property is set before the element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, or assign the property through a ref (Vue: .prop). (Said once per element.)`,t)}const c=new WeakMap;function u(t,e){let i=c.get(t);return void 0===i&&(i=new Map,c.set(t,i)),i.has(e)||i.set(e,t.getAttribute(e)),i.get(e)}function h(t,e,i){null===i?t.removeAttribute(e):t.setAttribute(e,i)}function l(t,e,i){const n=u(t,e);h(t,e,void 0===i?n:null===i?null:String(i))}function o(t,e,i){const n=u(t,e);h(t,e,void 0===i?n:i?"":null)}class _ extends HTMLElement{static hasConnectedCallbackPromise=!0;static wcBindable={...e.wcBindable,properties:[...e.wcBindable.properties,{name:"trigger",event:"wcs-timer:trigger-changed",semantics:"state"}],inputs:[{name:"interval",attribute:"interval"},{name:"once",attribute:"once"},{name:"repeat",attribute:"repeat"},{name:"immediate",attribute:"immediate"},{name:"manual",attribute:"manual"},{name:"trigger"}]};static get observedAttributes(){return["interval"]}_core;_trigger=!1;_connectedCallbackPromise=Promise.resolve();_startPending=!1;_internals=null;constructor(){super(),this._core=new e(this),this._internals=this._initInternals(),this._wireStates({"wcs-timer:running-changed":t=>({running:!0===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[i,n]of Object.entries(t))this.addEventListener(i,t=>{const i=this.hasAttribute("debug-states");for(const[s,r]of Object.entries(n(t.detail))){try{r?e.add(s):e.delete(s)}catch{}i&&this.toggleAttribute(`data-wcs-state-${s}`,r)}})}get connectedCallbackPromise(){return this._connectedCallbackPromise}get interval(){const t=this.getAttribute("interval");if(null===t||""===t.trim())return 1e3;const e=Number(t);return Number.isFinite(e)&&e>0?e:1e3}set interval(t){l(this,"interval",t)}get once(){return this.hasAttribute("once")}set once(t){o(this,"once",t)}get repeat(){const t=this.getAttribute("repeat");if(null===t||""===t.trim())return 0;const e=Number(t);return Number.isFinite(e)&&e>0?e:0}set repeat(t){l(this,"repeat",t)}get immediate(){return this.hasAttribute("immediate")}set immediate(t){o(this,"immediate",t)}get manual(){return this.hasAttribute("manual")}set manual(t){o(this,"manual",t)}get tick(){return this._core.tick}get elapsed(){return this._core.elapsed}get running(){return this._core.running}get trigger(){return this._trigger}set trigger(t){!!t&&(this._trigger=!0,this.start(),this._trigger=!1,this.dispatchEvent(new CustomEvent("wcs-timer:trigger-changed",{detail:!1,bubbles:!0})))}start(){const t=this.repeat>0?this.repeat:this.once?1:0;this._core.start({interval:this.interval,repeat:t,immediate:this.immediate})}stop(){this._startPending=!1,this._core.stop()}reset(){this._startPending=!1,this._core.reset()}pause(){this._startPending&&(this._startPending=!1,this.isConnected&&!this.manual&&this.start()),this._core.pause()}resume(){this._core.resume()}attributeChangedCallback(t,e,i){"interval"===t&&e!==i&&this.isConnected&&this.running&&this._core.changeInterval(this.interval)}connectedCallback(){!function(t){const e=t.constructor?.wcBindable,i=e?.inputs;if(void 0===i)return;const n=t.getAttribute;for(const e of i){const i=e.name,r="function"==typeof n?n.call(t,i.toLowerCase()):null;if(null!==r&&r.startsWith("[object ")&&a(t,i,r),!Object.prototype.hasOwnProperty.call(t,i))continue;if(!s(t,i))continue;const c=t,u=c[i];delete c[i],c[i]=u}}(this),this.style.display="none",i||(i=!0,document.addEventListener("click",n)),this._connectedCallbackPromise=this._core.observe(),this._scheduleStart()}_scheduleStart(){this._startPending||(this._startPending=!0,queueMicrotask(()=>{this._startPending&&(this._startPending=!1,this.isConnected&&!this.manual&&this.start())}))}disconnectedCallback(){this._core.dispose()}}var d;!function(e=customElements){e.get(t.tagNames.timer)||e.define(t.tagNames.timer,_)}(d);
|
|
2
2
|
//# sourceMappingURL=auto.min.js.map
|
package/dist/auto.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/TimerCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/Timer.ts","../src/bootstrapTimer.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n timer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-timertarget\",\n tagNames: {\n timer: \"wcs-timer\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// Internal-only live handle to the mutable config. NOT part of the public API\n// (deliberately absent from exports.ts) — it is exported solely so sibling\n// modules in this package can read current settings cheaply. External consumers\n// must use getConfig() (returns a deep-frozen snapshot) / setConfig(). Mutating\n// this object directly bypasses the frozenConfig cache and is unsupported.\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\n/** A misspelt option would otherwise do nothing: `bootstrapTimer` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/timer] bootstrapTimer: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface TimerStartOptions {\n interval?: number;\n repeat?: number;\n immediate?: boolean;\n}\n\n/**\n * Headless timer primitive. A thin, framework-agnostic wrapper around\n * `setInterval` exposed through the wc-bindable protocol: it streams `tick`\n * (a monotonically increasing counter), `elapsed` (running time in ms) and a\n * `running` flag, and is driven by the `start` / `stop` / `reset` / `pause` /\n * `resume` commands.\n *\n * `tick` and `elapsed` are both surfaced via the single `wcs-timer:tick` event\n * (read through getters, mirroring how FetchCore exposes value/status from one\n * `wcs-fetch:response` event), so an observer that binds either property is\n * notified on every fire.\n */\nexport class TimerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"tick\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.count },\n { name: \"elapsed\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.elapsed },\n { name: \"running\", event: \"wcs-timer:running-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"start\" },\n { name: \"stop\" },\n { name: \"reset\" },\n { name: \"pause\" },\n { name: \"resume\" },\n ],\n };\n\n private _target: EventTarget;\n private _timerId: ReturnType<typeof setInterval> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every async start\n // (start()/resume()). A scheduled callback (setInterval/setTimeout) captures the\n // generation live via `_gen`; a fire that was already queued when the timer was\n // torn down — or superseded by a new run — has a stale gen and MUST NOT mutate\n // state or dispatch on a disposed element. _clearTimer() removes the handle, but\n // the guard is the belt-and-braces defense for a callback already in the queue.\n private _gen = 0;\n // Generation captured for the currently scheduled run, set at each async start\n // (start()/resume()). A scheduled callback compares it against the live `_gen`;\n // a stale callback (dispose() bumped `_gen` after this run was armed) bails.\n private _runGen = 0;\n // SSR (§3.8): the timer does no asynchronous probe, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n private _tick: number = 0;\n private _running: boolean = false;\n private _paused: boolean = false;\n\n // `_tick` value captured at the start of the current run. `repeat` counts ticks\n // *per run*, so the stop condition compares against this baseline rather than the\n // cumulative `_tick` (which only resets on reset()). Without it, re-starting a\n // completed bounded timer would stop after a single tick.\n private _runStartTick: number = 0;\n\n // Timer configuration (captured on start, reused by pause/resume).\n // `_immediate` is intentionally NOT a field: it is per-run intent consumed\n // entirely within start() (fire once, then schedule), so it lives as a local\n // there rather than lingering as instance state no other method reads.\n private _interval: number = 1000;\n private _repeat: number = 0; // 0 = unlimited\n\n // Elapsed-time bookkeeping. `_accumulatedElapsed` holds the time folded from\n // already-finished running segments; `_segmentStart` is the timestamp the\n // current running segment began (null when not running). The live elapsed is\n // the sum of the two — see _currentElapsed().\n private _accumulatedElapsed: number = 0;\n private _segmentStart: number | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get tick(): number {\n return this._tick;\n }\n\n get elapsed(): number {\n return this._currentElapsed();\n }\n\n get running(): boolean {\n return this._running;\n }\n\n // SSR readiness (§3.8): resolves after the first probe. The timer is\n // command-driven with nothing to probe, so this is an already-resolved promise.\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). The timer is command-driven (start/stop/...) with no\n // ambient subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready (mirroring UploadCore). dispose() tears the timer down —\n // it stops any running interval and bumps the generation so a callback already\n // queued cannot fire onto a torn-down element.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.stop();\n }\n\n // --- State setters with event dispatch ---\n\n private _dispatchTick(): void {\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:tick\", {\n detail: { count: this._tick, elapsed: this._currentElapsed() },\n bubbles: true,\n }));\n }\n\n private _setRunning(running: boolean): void {\n if (this._running === running) return;\n this._running = running;\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:running-changed\", {\n detail: running,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n start(options: TimerStartOptions = {}): void {\n // Idempotent while running: a redundant start() must not stack a second\n // setInterval (which would leak and double the tick rate). Reconfiguring an\n // active timer is done via stop() + start().\n if (this._running) return;\n\n // start() begins a fresh running segment, so clear any lingering pause from a\n // prior pause()-without-resume(). Without this, the timer would run while\n // _paused stayed true, leaving pause() a no-op and letting resume() overwrite\n // the live timer handle (leak + double fire).\n this._paused = false;\n\n // `interval` is persistent configuration: a non-positive / non-finite value\n // (or an omitted option) keeps the previous interval (default 1000ms). The\n // guard rejects values that would turn setInterval into a hot loop and make\n // resume()'s `accumulated % interval` arithmetic produce NaN. The Shell already\n // falls back to 1000 for invalid attributes; this is the backstop for direct\n // Core API callers.\n if (typeof options.interval === \"number\" && Number.isFinite(options.interval) && options.interval > 0) {\n this._interval = options.interval;\n }\n\n // `repeat` / `immediate` are per-run intent, NOT persistent configuration:\n // every start() re-establishes them from the options, defaulting to\n // \"unlimited\" / \"no immediate fire\" when omitted. This keeps a bare start()\n // after a bounded or one-shot run from silently inheriting the old bounds.\n // `repeat` is a field (pause/resume/_fire read it across the run); `immediate`\n // is consumed here and now, so it stays a local.\n this._repeat = (typeof options.repeat === \"number\" && options.repeat > 0) ? options.repeat : 0;\n const immediate = options.immediate === true;\n\n this._setRunning(true);\n this._segmentStart = Date.now();\n // Baseline this run's per-run repeat counting (set after _setRunning so a\n // re-start of a completed bounded timer fires the full N ticks again).\n this._runStartTick = this._tick;\n // Capture this run's generation (§3.4): a scheduled fire that outlives a\n // dispose() (which bumps `_gen`) is then recognised as stale and ignored.\n this._runGen = ++this._gen;\n\n // Fire immediately on start when requested. _fire() may stop the timer (when\n // repeat is reached), so re-check _running before scheduling the interval.\n if (immediate) {\n this._fire();\n }\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n }\n\n // Swap the tick period of a live timer in place, WITHOUT re-running start().\n // Unlike stop() + start(), this leaves the per-run repeat progress in flight\n // (`_repeat` and its `_runStartTick` baseline) untouched, so a bounded\n // `repeat=\"N\"` run is not re-baselined to fire N more times. It also never goes\n // through start()'s `immediate` path, so an `immediate` timer does not fire an\n // extra tick. Only re-arms the steady interval; pause()/resume() and reset() are\n // unaffected. No-op when not running (interval is then plain config, captured on\n // the next start) or when the new period is non-positive / non-finite (which\n // would turn setInterval into a hot loop and break resume()'s modulo arithmetic).\n changeInterval(interval: number): void {\n if (!this._running) return;\n if (!(typeof interval === \"number\" && Number.isFinite(interval) && interval > 0)) return;\n if (interval === this._interval) return;\n this._interval = interval;\n // Re-arm the steady ticking at the new period. The current period's progress\n // is intentionally discarded (the next tick is a full new interval away),\n // matching the boundary reset of the previous stop()+start() behaviour.\n this._clearTimer();\n this._timerId = setInterval(this._fire, this._interval);\n }\n\n stop(): void {\n this._clearTimer();\n this._foldElapsed();\n this._paused = false;\n this._setRunning(false);\n }\n\n reset(): void {\n this._clearTimer();\n this._paused = false;\n this._tick = 0;\n this._accumulatedElapsed = 0;\n this._segmentStart = null;\n this._setRunning(false);\n // Notify observers that the counter/elapsed have returned to zero.\n this._dispatchTick();\n }\n\n pause(): void {\n // Pause only a live timer; a no-op otherwise so it composes safely with the\n // declarative lifecycle. Unlike stop(), it records `_paused` so resume() can\n // tell an intentional pause from a full stop.\n if (!this._running || this._paused) return;\n this._clearTimer();\n this._foldElapsed();\n this._paused = true;\n this._setRunning(false);\n }\n\n resume(): void {\n if (!this._paused) return;\n this._paused = false;\n this._setRunning(true);\n this._segmentStart = Date.now();\n // New scheduled run after a pause: capture its generation (§3.4) so a\n // post-dispose() boundary/interval callback is recognised as stale.\n this._runGen = ++this._gen;\n // Invariant: `_interval` is fixed at start() and stays constant for the whole\n // pause/resume cycle — changeInterval() only mutates it while *running* (never\n // while paused), so the remainder arithmetic below can safely assume the same\n // period was in effect across the paused segment. Consequence for the Shell:\n // because the live interval-attribute path (attributeChangedCallback ->\n // changeInterval) is gated on `running`, an `interval` change made *while\n // paused* is silently not applied here; it is picked up only on the next\n // start() as plain config. This is by design — see README \"Commands\".\n // Resume seamlessly: a tick fires every `interval` ms of *running* time, so\n // honour the partial period consumed before the pause. Wait only the\n // remainder to the next boundary, then fall back to the steady interval.\n // (`accumulated % interval === 0` — paused exactly on a boundary — yields a\n // full interval, which is correct: the next tick is a whole period away.)\n const remainder = this._interval - (this._accumulatedElapsed % this._interval);\n this._timerId = setTimeout(this._onResumeBoundary, remainder);\n }\n\n // --- Internal ---\n\n private _onResumeBoundary = (): void => {\n // Stale-run guard (§3.4): a resume-boundary timeout that fires after dispose()\n // belongs to a torn-down run — drop it without re-arming the interval.\n if (this._runGen !== this._gen) return;\n this._timerId = null;\n this._fire();\n // _fire() may have auto-stopped the timer (repeat reached); only re-arm the\n // steady interval while still running.\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n };\n\n private _fire = (): void => {\n // Stale-run guard (§3.4): an interval callback queued before dispose() (which\n // bumps `_gen`) must not tick or dispatch onto a torn-down element.\n if (this._runGen !== this._gen) return;\n this._tick++;\n this._dispatchTick();\n\n // Auto-stop once this run has fired the requested number of ticks (repeat=0\n // runs forever). Counted per-run via `_runStartTick`, so a re-start after a\n // completed bounded run fires N ticks again. `once` is expressed by the Shell\n // as repeat=1.\n if (this._repeat > 0 && (this._tick - this._runStartTick) >= this._repeat) {\n this._clearTimer();\n this._foldElapsed();\n this._setRunning(false);\n }\n };\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n // `_timerId` may hold a setInterval handle (steady ticking) or a setTimeout\n // handle (the resume remainder). Clear both — per the HTML spec timers\n // share one list and clearTimeout/clearInterval each remove the entry\n // regardless of which call created it.\n clearTimeout(this._timerId);\n clearInterval(this._timerId);\n this._timerId = null;\n }\n }\n\n private _foldElapsed(): void {\n if (this._segmentStart !== null) {\n this._accumulatedElapsed += Date.now() - this._segmentStart;\n this._segmentStart = null;\n }\n }\n\n private _currentElapsed(): number {\n return this._accumulatedElapsed +\n (this._segmentStart !== null ? Date.now() - this._segmentStart : 0);\n }\n}\n","import { config } from \"./config.js\";\nimport type { Timer } from \"./components/Timer.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const timerId = triggerElement.getAttribute(config.triggerAttribute);\n if (!timerId) return;\n\n // Resolve the registered constructor at call time instead of importing Timer\n // as a value. The value import created a components/Timer.ts ⇄ autoTrigger.ts\n // cycle (Timer.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-timer> class matches — without the import cycle.\n const TimerCtor = customElements.get(config.tagNames.timer);\n const timerElement = document.getElementById(timerId);\n if (!TimerCtor || !(timerElement instanceof TimerCtor)) return;\n\n // Suppress the element's default action so a timer can start without\n // navigating. Intentional: do not attach data-timertarget to an element whose\n // default action you also want (real <a href> link, form-submit button) — it\n // will be cancelled. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (timerElement as Timer).start();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\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// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\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 const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { TimerCore } from \"../core/TimerCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class Timer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...TimerCore.wcBindable,\n properties: [\n ...TimerCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-timer:trigger-changed\", semantics: \"state\" },\n ],\n // Shell-level settable surface. `attribute` is a purely descriptive hint\n // (per SPEC-extensions.md the binding core does not act on it) naming the\n // mirrored HTML attribute, matching <wcs-geo> / <wcs-debounce>. `trigger` is a\n // momentary command-property with no backing attribute, so it carries no hint\n // (same as those packages). `start` / `stop` / `reset` / `pause` / `resume`\n // commands are inherited from the Core above.\n inputs: [\n { name: \"interval\", attribute: \"interval\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"repeat\", attribute: \"repeat\" },\n { name: \"immediate\", attribute: \"immediate\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"interval\"]; }\n\n private _core: TimerCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new TimerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-timer:running-changed\": (d) => ({ running: d === true }),\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 // SSR (§4.1/§4.4): the Shell exposes the Core's readiness so a server-side\n // renderer can await the connect-time probe before snapshotting. The timer has\n // no async probe (observe() resolves immediately), but the contract is uniform\n // across IO nodes.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined: `null`\n // removes the attribute (the documented default), `undefined` restores the\n // attribute the element started with (wc-bindable producer guidance P1;\n // React 19 and a direct assignment deliver it, @wcstack/state does not).\n // An `interval` write still goes through attributeChangedCallback, so a\n // running timer swaps to the restored / default period in place.\n\n get interval(): number {\n const attr = this.getAttribute(\"interval\");\n if (attr === null || attr.trim() === \"\") return 1000;\n // Strict parse via Number() (unlike parseInt, \"100px\" -> NaN, not 100),\n // matching <wcs-geo> / <wcs-debounce>. Fall back to the 1000ms default for any\n // invalid period — not only NaN but also 0 / negative values, which would\n // otherwise reach setInterval as a hot loop and break resume()'s modulo\n // arithmetic in the Core.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 1000;\n }\n\n set interval(value: number | null | undefined) {\n reflectAttribute(this, \"interval\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"once\", value);\n }\n\n get repeat(): number {\n const attr = this.getAttribute(\"repeat\");\n if (attr === null || attr.trim() === \"\") return 0;\n // Strict parse via Number() (\"3px\" -> NaN, not 3), matching <wcs-geo> /\n // <wcs-debounce>. Normalise any non-positive / non-numeric value to 0\n // (= unlimited), mirroring the `interval` getter. Without this a negative\n // `repeat=\"-3\"` would leak through to start(); harmless today (Core treats\n // `_repeat <= 0` as unlimited) but the asymmetry is a trap.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 0;\n }\n\n set repeat(value: number | null | undefined) {\n reflectAttribute(this, \"repeat\", value);\n }\n\n get immediate(): boolean {\n return this.hasAttribute(\"immediate\");\n }\n\n set immediate(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"immediate\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get tick(): number {\n return this._core.tick;\n }\n\n get elapsed(): number {\n return this._core.elapsed;\n }\n\n get running(): boolean {\n return this._core.running;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write starts the timer. Mirrors\n // the trigger flag on <wcs-fetch> / <wcs-ws>. Prefer the command-token\n // protocol (`command.start: $command.tick`) for state-driven starts; this\n // exists mainly for the DOM click trigger and simple boolean bindings.\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.start();\n this._trigger = false;\n // The `trigger-changed` event reports the momentary flag returning to\n // false, i.e. that the trigger property *changed* — it is deliberately not\n // gated on whether start() actually began a new run. This keeps the\n // wcBindable `trigger` property's change-notification semantics consistent\n // (every false→true write produces exactly one change-back event), even\n // when start() was a no-op because the timer was already running.\n this.dispatchEvent(new CustomEvent(\"wcs-timer:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // --- Commands ---\n\n start(): void {\n // `once` is sugar for \"fire exactly one tick\": map it to repeat=1, but let an\n // explicit repeat attribute win when both are present.\n const repeat = this.repeat > 0 ? this.repeat : (this.once ? 1 : 0);\n this._core.start({\n interval: this.interval,\n repeat,\n immediate: this.immediate,\n });\n }\n\n stop(): void {\n this._core.stop();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n pause(): void {\n this._core.pause();\n }\n\n resume(): void {\n this._core.resume();\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // Live interval changes swap the underlying setInterval period in place.\n // `tick` / `elapsed` and the per-run `repeat` progress are preserved — we\n // deliberately do NOT stop()+start(), which would re-run start() and\n // re-evaluate per-run options (re-firing `immediate` and re-baselining\n // `repeat`). `running` alone gates this: swapping the period is orthogonal to\n // *how* the timer was started, so a `manual` timer the user has explicitly\n // started gets live period changes too. A non-running timer needs no swap —\n // its next start() picks up the new attribute as plain config.\n if (name === \"interval\" && oldValue !== newValue && this.isConnected && this.running) {\n this._core.changeInterval(this.interval);\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // Establish monitoring (§3.5). observe() is a no-op that resolves once ready;\n // expose it as connectedCallbackPromise for SSR.\n this._connectedCallbackPromise = this._core.observe();\n if (!this.manual) {\n this.start();\n }\n }\n\n disconnectedCallback(): void {\n // dispose() stops the timer and bumps the generation so a callback already\n // queued cannot fire onto a disconnected element (§3.5 / §4.4).\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 bootstrapTimer(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { Timer } from \"./components/Timer.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.timer)) {\n registry.define(config.tagNames.timer, Timer);\n }\n}\n"],"names":["config","triggerAttribute","tagNames","timer","TimerCore","EventTarget","static","protocol","version","properties","name","event","semantics","getter","e","detail","count","elapsed","commands","_target","_timerId","_gen","_runGen","_ready","Promise","resolve","_tick","_running","_paused","_runStartTick","_interval","_repeat","_accumulatedElapsed","_segmentStart","constructor","target","super","this","tick","_currentElapsed","running","ready","observe","dispose","stop","_dispatchTick","dispatchEvent","CustomEvent","bubbles","_setRunning","start","options","interval","Number","isFinite","repeat","immediate","Date","now","_fire","setInterval","changeInterval","_clearTimer","_foldElapsed","reset","pause","resume","remainder","setTimeout","_onResumeBoundary","clearTimeout","clearInterval","registered","handleClick","Element","triggerElement","closest","timerId","getAttribute","TimerCtor","customElements","get","timerElement","document","getElementById","preventDefault","hasAccessorOnPrototype","proto","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","undefined","set","toldObjectAttribute","WeakSet","warnObjectAttribute","element","value","has","add","tag","localName","console","warn","initialAttributes","WeakMap","initialAttribute","el","byName","Map","writeAttribute","removeAttribute","setAttribute","reflectAttribute","initial","String","reflectBooleanAttribute","Timer","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","delete","map","toStates","entries","addEventListener","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","attr","trim","parsed","once","manual","trigger","attributeChangedCallback","oldValue","newValue","isConnected","connectedCallback","declaration","input","call","toLowerCase","startsWith","prototype","hasOwnProperty","record","upgradeProperties","style","display","disconnectedCallback","registry","define","registerComponents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auto.min.js","sources":["../src/config.ts","../src/core/TimerCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/Timer.ts","../src/bootstrapTimer.ts","../src/registerComponents.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n timer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-timertarget\",\n tagNames: {\n timer: \"wcs-timer\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// Internal-only live handle to the mutable config. NOT part of the public API\n// (deliberately absent from exports.ts) — it is exported solely so sibling\n// modules in this package can read current settings cheaply. External consumers\n// must use getConfig() (returns a deep-frozen snapshot) / setConfig(). Mutating\n// this object directly bypasses the frozenConfig cache and is unsupported.\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\n/** A misspelt option would otherwise do nothing: `bootstrapTimer` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/timer] bootstrapTimer: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface TimerStartOptions {\n interval?: number;\n repeat?: number;\n immediate?: boolean;\n}\n\n/**\n * Headless timer primitive. A thin, framework-agnostic wrapper around\n * `setInterval` exposed through the wc-bindable protocol: it streams `tick`\n * (a monotonically increasing counter), `elapsed` (running time in ms) and a\n * `running` flag, and is driven by the `start` / `stop` / `reset` / `pause` /\n * `resume` commands.\n *\n * `tick` and `elapsed` are both surfaced via the single `wcs-timer:tick` event\n * (read through getters, mirroring how FetchCore exposes value/status from one\n * `wcs-fetch:response` event), so an observer that binds either property is\n * notified on every fire.\n */\nexport class TimerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"tick\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.count },\n { name: \"elapsed\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.elapsed },\n { name: \"running\", event: \"wcs-timer:running-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"start\" },\n { name: \"stop\" },\n { name: \"reset\" },\n { name: \"pause\" },\n { name: \"resume\" },\n ],\n };\n\n private _target: EventTarget;\n private _timerId: ReturnType<typeof setInterval> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every async start\n // (start()/resume()). A scheduled callback (setInterval/setTimeout) captures the\n // generation live via `_gen`; a fire that was already queued when the timer was\n // torn down — or superseded by a new run — has a stale gen and MUST NOT mutate\n // state or dispatch on a disposed element. _clearTimer() removes the handle, but\n // the guard is the belt-and-braces defense for a callback already in the queue.\n private _gen = 0;\n // Generation captured for the currently scheduled run, set at each async start\n // (start()/resume()). A scheduled callback compares it against the live `_gen`;\n // a stale callback (dispose() bumped `_gen` after this run was armed) bails.\n private _runGen = 0;\n // SSR (§3.8): the timer does no asynchronous probe, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n private _tick: number = 0;\n private _running: boolean = false;\n private _paused: boolean = false;\n\n // `_tick` value captured at the start of the current run. `repeat` counts ticks\n // *per run*, so the stop condition compares against this baseline rather than the\n // cumulative `_tick` (which only resets on reset()). Without it, re-starting a\n // completed bounded timer would stop after a single tick.\n private _runStartTick: number = 0;\n\n // Timer configuration (captured on start, reused by pause/resume).\n // `_immediate` is intentionally NOT a field: it is per-run intent consumed\n // entirely within start() (fire once, then schedule), so it lives as a local\n // there rather than lingering as instance state no other method reads.\n private _interval: number = 1000;\n private _repeat: number = 0; // 0 = unlimited\n\n // Elapsed-time bookkeeping. `_accumulatedElapsed` holds the time folded from\n // already-finished running segments; `_segmentStart` is the timestamp the\n // current running segment began (null when not running). The live elapsed is\n // the sum of the two — see _currentElapsed().\n private _accumulatedElapsed: number = 0;\n private _segmentStart: number | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get tick(): number {\n return this._tick;\n }\n\n get elapsed(): number {\n return this._currentElapsed();\n }\n\n get running(): boolean {\n return this._running;\n }\n\n // SSR readiness (§3.8): resolves after the first probe. The timer is\n // command-driven with nothing to probe, so this is an already-resolved promise.\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). The timer is command-driven (start/stop/...) with no\n // ambient subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready (mirroring UploadCore). dispose() tears the timer down —\n // it stops any running interval and bumps the generation so a callback already\n // queued cannot fire onto a torn-down element.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.stop();\n }\n\n // --- State setters with event dispatch ---\n\n private _dispatchTick(): void {\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:tick\", {\n detail: { count: this._tick, elapsed: this._currentElapsed() },\n bubbles: true,\n }));\n }\n\n private _setRunning(running: boolean): void {\n if (this._running === running) return;\n this._running = running;\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:running-changed\", {\n detail: running,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n start(options: TimerStartOptions = {}): void {\n // Idempotent while running: a redundant start() must not stack a second\n // setInterval (which would leak and double the tick rate). Reconfiguring an\n // active timer is done via stop() + start().\n if (this._running) return;\n\n // start() begins a fresh running segment, so clear any lingering pause from a\n // prior pause()-without-resume(). Without this, the timer would run while\n // _paused stayed true, leaving pause() a no-op and letting resume() overwrite\n // the live timer handle (leak + double fire).\n this._paused = false;\n\n // `interval` is persistent configuration: a non-positive / non-finite value\n // (or an omitted option) keeps the previous interval (default 1000ms). The\n // guard rejects values that would turn setInterval into a hot loop and make\n // resume()'s `accumulated % interval` arithmetic produce NaN. The Shell already\n // falls back to 1000 for invalid attributes; this is the backstop for direct\n // Core API callers.\n if (typeof options.interval === \"number\" && Number.isFinite(options.interval) && options.interval > 0) {\n this._interval = options.interval;\n }\n\n // `repeat` / `immediate` are per-run intent, NOT persistent configuration:\n // every start() re-establishes them from the options, defaulting to\n // \"unlimited\" / \"no immediate fire\" when omitted. This keeps a bare start()\n // after a bounded or one-shot run from silently inheriting the old bounds.\n // `repeat` is a field (pause/resume/_fire read it across the run); `immediate`\n // is consumed here and now, so it stays a local.\n this._repeat = (typeof options.repeat === \"number\" && options.repeat > 0) ? options.repeat : 0;\n const immediate = options.immediate === true;\n\n this._setRunning(true);\n this._segmentStart = Date.now();\n // Baseline this run's per-run repeat counting (set after _setRunning so a\n // re-start of a completed bounded timer fires the full N ticks again).\n this._runStartTick = this._tick;\n // Capture this run's generation (§3.4): a scheduled fire that outlives a\n // dispose() (which bumps `_gen`) is then recognised as stale and ignored.\n this._runGen = ++this._gen;\n\n // Fire immediately on start when requested. _fire() may stop the timer (when\n // repeat is reached), so re-check _running before scheduling the interval.\n if (immediate) {\n this._fire();\n }\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n }\n\n // Swap the tick period of a live timer in place, WITHOUT re-running start().\n // Unlike stop() + start(), this leaves the per-run repeat progress in flight\n // (`_repeat` and its `_runStartTick` baseline) untouched, so a bounded\n // `repeat=\"N\"` run is not re-baselined to fire N more times. It also never goes\n // through start()'s `immediate` path, so an `immediate` timer does not fire an\n // extra tick. Only re-arms the steady interval; pause()/resume() and reset() are\n // unaffected. No-op when not running (interval is then plain config, captured on\n // the next start) or when the new period is non-positive / non-finite (which\n // would turn setInterval into a hot loop and break resume()'s modulo arithmetic).\n changeInterval(interval: number): void {\n if (!this._running) return;\n if (!(typeof interval === \"number\" && Number.isFinite(interval) && interval > 0)) return;\n if (interval === this._interval) return;\n this._interval = interval;\n // Re-arm the steady ticking at the new period. The current period's progress\n // is intentionally discarded (the next tick is a full new interval away),\n // matching the boundary reset of the previous stop()+start() behaviour.\n this._clearTimer();\n this._timerId = setInterval(this._fire, this._interval);\n }\n\n stop(): void {\n this._clearTimer();\n this._foldElapsed();\n this._paused = false;\n this._setRunning(false);\n }\n\n reset(): void {\n this._clearTimer();\n this._paused = false;\n this._tick = 0;\n this._accumulatedElapsed = 0;\n this._segmentStart = null;\n this._setRunning(false);\n // Notify observers that the counter/elapsed have returned to zero.\n this._dispatchTick();\n }\n\n pause(): void {\n // Pause only a live timer; a no-op otherwise so it composes safely with the\n // declarative lifecycle. Unlike stop(), it records `_paused` so resume() can\n // tell an intentional pause from a full stop.\n if (!this._running || this._paused) return;\n this._clearTimer();\n this._foldElapsed();\n this._paused = true;\n this._setRunning(false);\n }\n\n resume(): void {\n if (!this._paused) return;\n this._paused = false;\n this._setRunning(true);\n this._segmentStart = Date.now();\n // New scheduled run after a pause: capture its generation (§3.4) so a\n // post-dispose() boundary/interval callback is recognised as stale.\n this._runGen = ++this._gen;\n // Invariant: `_interval` is fixed at start() and stays constant for the whole\n // pause/resume cycle — changeInterval() only mutates it while *running* (never\n // while paused), so the remainder arithmetic below can safely assume the same\n // period was in effect across the paused segment. Consequence for the Shell:\n // because the live interval-attribute path (attributeChangedCallback ->\n // changeInterval) is gated on `running`, an `interval` change made *while\n // paused* is silently not applied here; it is picked up only on the next\n // start() as plain config. This is by design — see README \"Commands\".\n // Resume seamlessly: a tick fires every `interval` ms of *running* time, so\n // honour the partial period consumed before the pause. Wait only the\n // remainder to the next boundary, then fall back to the steady interval.\n // (`accumulated % interval === 0` — paused exactly on a boundary — yields a\n // full interval, which is correct: the next tick is a whole period away.)\n const remainder = this._interval - (this._accumulatedElapsed % this._interval);\n this._timerId = setTimeout(this._onResumeBoundary, remainder);\n }\n\n // --- Internal ---\n\n private _onResumeBoundary = (): void => {\n // Stale-run guard (§3.4): a resume-boundary timeout that fires after dispose()\n // belongs to a torn-down run — drop it without re-arming the interval.\n if (this._runGen !== this._gen) return;\n this._timerId = null;\n this._fire();\n // _fire() may have auto-stopped the timer (repeat reached); only re-arm the\n // steady interval while still running.\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n };\n\n private _fire = (): void => {\n // Stale-run guard (§3.4): an interval callback queued before dispose() (which\n // bumps `_gen`) must not tick or dispatch onto a torn-down element.\n if (this._runGen !== this._gen) return;\n this._tick++;\n this._dispatchTick();\n\n // Auto-stop once this run has fired the requested number of ticks (repeat=0\n // runs forever). Counted per-run via `_runStartTick`, so a re-start after a\n // completed bounded run fires N ticks again. `once` is expressed by the Shell\n // as repeat=1.\n if (this._repeat > 0 && (this._tick - this._runStartTick) >= this._repeat) {\n this._clearTimer();\n this._foldElapsed();\n this._setRunning(false);\n }\n };\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n // `_timerId` may hold a setInterval handle (steady ticking) or a setTimeout\n // handle (the resume remainder). Clear both — per the HTML spec timers\n // share one list and clearTimeout/clearInterval each remove the entry\n // regardless of which call created it.\n clearTimeout(this._timerId);\n clearInterval(this._timerId);\n this._timerId = null;\n }\n }\n\n private _foldElapsed(): void {\n if (this._segmentStart !== null) {\n this._accumulatedElapsed += Date.now() - this._segmentStart;\n this._segmentStart = null;\n }\n }\n\n private _currentElapsed(): number {\n return this._accumulatedElapsed +\n (this._segmentStart !== null ? Date.now() - this._segmentStart : 0);\n }\n}\n","import { config } from \"./config.js\";\nimport type { Timer } from \"./components/Timer.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const timerId = triggerElement.getAttribute(config.triggerAttribute);\n if (!timerId) return;\n\n // Resolve the registered constructor at call time instead of importing Timer\n // as a value. The value import created a components/Timer.ts ⇄ autoTrigger.ts\n // cycle (Timer.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-timer> class matches — without the import cycle.\n const TimerCtor = customElements.get(config.tagNames.timer);\n const timerElement = document.getElementById(timerId);\n if (!TimerCtor || !(timerElement instanceof TimerCtor)) return;\n\n // Suppress the element's default action so a timer can start without\n // navigating. Intentional: do not attach data-timertarget to an element whose\n // default action you also want (real <a href> link, form-submit button) — it\n // will be cancelled. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (timerElement as Timer).start();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\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// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\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 const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { TimerCore } from \"../core/TimerCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class Timer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...TimerCore.wcBindable,\n properties: [\n ...TimerCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-timer:trigger-changed\", semantics: \"state\" },\n ],\n // Shell-level settable surface. `attribute` is a purely descriptive hint\n // (per SPEC-extensions.md the binding core does not act on it) naming the\n // mirrored HTML attribute, matching <wcs-geo> / <wcs-debounce>. `trigger` is a\n // momentary command-property with no backing attribute, so it carries no hint\n // (same as those packages). `start` / `stop` / `reset` / `pause` / `resume`\n // commands are inherited from the Core above.\n inputs: [\n { name: \"interval\", attribute: \"interval\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"repeat\", attribute: \"repeat\" },\n { name: \"immediate\", attribute: \"immediate\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"interval\"]; }\n\n private _core: TimerCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n // _scheduleStart のマイクロタスクが待っている間 true\n private _startPending = false;\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new TimerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-timer:running-changed\": (d) => ({ running: d === true }),\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 // SSR (§4.1/§4.4): the Shell exposes the Core's readiness so a server-side\n // renderer can await the connect-time probe before snapshotting. The timer has\n // no async probe (observe() resolves immediately), but the contract is uniform\n // across IO nodes.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined: `null`\n // removes the attribute (the documented default), `undefined` restores the\n // attribute the element started with (wc-bindable producer guidance P1;\n // React 19 and a direct assignment deliver it, @wcstack/state does not).\n // An `interval` write still goes through attributeChangedCallback, so a\n // running timer swaps to the restored / default period in place.\n\n get interval(): number {\n const attr = this.getAttribute(\"interval\");\n if (attr === null || attr.trim() === \"\") return 1000;\n // Strict parse via Number() (unlike parseInt, \"100px\" -> NaN, not 100),\n // matching <wcs-geo> / <wcs-debounce>. Fall back to the 1000ms default for any\n // invalid period — not only NaN but also 0 / negative values, which would\n // otherwise reach setInterval as a hot loop and break resume()'s modulo\n // arithmetic in the Core.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 1000;\n }\n\n set interval(value: number | null | undefined) {\n reflectAttribute(this, \"interval\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"once\", value);\n }\n\n get repeat(): number {\n const attr = this.getAttribute(\"repeat\");\n if (attr === null || attr.trim() === \"\") return 0;\n // Strict parse via Number() (\"3px\" -> NaN, not 3), matching <wcs-geo> /\n // <wcs-debounce>. Normalise any non-positive / non-numeric value to 0\n // (= unlimited), mirroring the `interval` getter. Without this a negative\n // `repeat=\"-3\"` would leak through to start(); harmless today (Core treats\n // `_repeat <= 0` as unlimited) but the asymmetry is a trap.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 0;\n }\n\n set repeat(value: number | null | undefined) {\n reflectAttribute(this, \"repeat\", value);\n }\n\n get immediate(): boolean {\n return this.hasAttribute(\"immediate\");\n }\n\n set immediate(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"immediate\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get tick(): number {\n return this._core.tick;\n }\n\n get elapsed(): number {\n return this._core.elapsed;\n }\n\n get running(): boolean {\n return this._core.running;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write starts the timer. Mirrors\n // the trigger flag on <wcs-fetch> / <wcs-ws>. Prefer the command-token\n // protocol (`command.start: $command.tick`) for state-driven starts; this\n // exists mainly for the DOM click trigger and simple boolean bindings.\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.start();\n this._trigger = false;\n // The `trigger-changed` event reports the momentary flag returning to\n // false, i.e. that the trigger property *changed* — it is deliberately not\n // gated on whether start() actually began a new run. This keeps the\n // wcBindable `trigger` property's change-notification semantics consistent\n // (every false→true write produces exactly one change-back event), even\n // when start() was a no-op because the timer was already running.\n this.dispatchEvent(new CustomEvent(\"wcs-timer:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // --- Commands ---\n\n start(): void {\n // `once` is sugar for \"fire exactly one tick\": map it to repeat=1, but let an\n // explicit repeat attribute win when both are present.\n const repeat = this.repeat > 0 ? this.repeat : (this.once ? 1 : 0);\n this._core.start({\n interval: this.interval,\n repeat,\n immediate: this.immediate,\n });\n }\n\n stop(): void {\n // 同じタスクで接続の後に止められたら、待っている自動開始も取り消す\n // (同期で start していた頃は、start → stop で止まったままだった)\n this._startPending = false;\n this._core.stop();\n }\n\n reset(): void {\n // reset も止める命令: 待っている自動開始を取り消す(stop と同じ)\n this._startPending = false;\n this._core.reset();\n }\n\n pause(): void {\n // 接続時の自動開始が待っているなら、ここでそのときの入力で判断してから止める。\n // 同期で start していた頃と同じく、append → pause() は resume() できる一時停止になる\n if (this._startPending) {\n this._startPending = false;\n if (this.isConnected && !this.manual) {\n this.start();\n }\n }\n this._core.pause();\n }\n\n resume(): void {\n this._core.resume();\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // Live interval changes swap the underlying setInterval period in place.\n // `tick` / `elapsed` and the per-run `repeat` progress are preserved — we\n // deliberately do NOT stop()+start(), which would re-run start() and\n // re-evaluate per-run options (re-firing `immediate` and re-baselining\n // `repeat`). `running` alone gates this: swapping the period is orthogonal to\n // *how* the timer was started, so a `manual` timer the user has explicitly\n // started gets live period changes too. A non-running timer needs no swap —\n // its next start() picks up the new attribute as plain config.\n if (name === \"interval\" && oldValue !== newValue && this.isConnected && this.running) {\n this._core.changeInterval(this.interval);\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // Establish monitoring (§3.5). observe() is a no-op that resolves once ready;\n // expose it as connectedCallbackPromise for SSR. (The auto-start below runs in a\n // microtask queued before any caller can await this promise, so it still\n // precedes the awaiter.)\n this._connectedCallbackPromise = this._core.observe();\n this._scheduleStart();\n }\n\n // 自動開始の判断はマイクロタスクで、そのときの manual / interval / repeat / once /\n // immediate で 1 回だけ行う(timing-and-firing-contract §23)。router は遷移で同じノードを\n // 入れ直し、新しいルートの params から state が入力を書くのはマイクロタスク — その場で\n // start すると、前の入力で動き出し(immediate なら前の入力で 1 tick 発火し)、manual も\n // 前のままで判断していた(docs/seam-apps.md、shift-desk)。その時点で外れていれば何もしない。\n private _scheduleStart(): void {\n if (this._startPending) return;\n this._startPending = true;\n queueMicrotask(() => {\n // stop() / reset() が取り消した(そのあと同じタスクで積み直されたら、それが判断する)\n if (!this._startPending) return;\n this._startPending = false;\n if (this.isConnected && !this.manual) {\n this.start();\n }\n });\n }\n\n disconnectedCallback(): void {\n // dispose() stops the timer and bumps the generation so a callback already\n // queued cannot fire onto a disconnected element (§3.5 / §4.4).\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 bootstrapTimer(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n","import { Timer } from \"./components/Timer.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.timer)) {\n registry.define(config.tagNames.timer, Timer);\n }\n}\n"],"names":["config","triggerAttribute","tagNames","timer","TimerCore","EventTarget","static","protocol","version","properties","name","event","semantics","getter","e","detail","count","elapsed","commands","_target","_timerId","_gen","_runGen","_ready","Promise","resolve","_tick","_running","_paused","_runStartTick","_interval","_repeat","_accumulatedElapsed","_segmentStart","constructor","target","super","this","tick","_currentElapsed","running","ready","observe","dispose","stop","_dispatchTick","dispatchEvent","CustomEvent","bubbles","_setRunning","start","options","interval","Number","isFinite","repeat","immediate","Date","now","_fire","setInterval","changeInterval","_clearTimer","_foldElapsed","reset","pause","resume","remainder","setTimeout","_onResumeBoundary","clearTimeout","clearInterval","registered","handleClick","Element","triggerElement","closest","timerId","getAttribute","TimerCtor","customElements","get","timerElement","document","getElementById","preventDefault","hasAccessorOnPrototype","proto","Object","getPrototypeOf","descriptor","getOwnPropertyDescriptor","undefined","set","toldObjectAttribute","WeakSet","warnObjectAttribute","element","value","has","add","tag","localName","console","warn","initialAttributes","WeakMap","initialAttribute","el","byName","Map","writeAttribute","removeAttribute","setAttribute","reflectAttribute","initial","String","reflectBooleanAttribute","Timer","HTMLElement","wcBindable","inputs","attribute","observedAttributes","_core","_trigger","_connectedCallbackPromise","_startPending","_internals","_initInternals","_wireStates","d","debugStates","states","attachInternals","internals","delete","map","toStates","entries","addEventListener","debug","hasAttribute","on","toggleAttribute","connectedCallbackPromise","attr","trim","parsed","once","manual","trigger","isConnected","attributeChangedCallback","oldValue","newValue","connectedCallback","declaration","input","call","toLowerCase","startsWith","prototype","hasOwnProperty","record","upgradeProperties","style","display","_scheduleStart","queueMicrotask","disconnectedCallback","registry","define","registerComponents"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -177,6 +177,7 @@ declare class Timer extends HTMLElement {
|
|
|
177
177
|
private _core;
|
|
178
178
|
private _trigger;
|
|
179
179
|
private _connectedCallbackPromise;
|
|
180
|
+
private _startPending;
|
|
180
181
|
private _internals;
|
|
181
182
|
constructor();
|
|
182
183
|
get debugStates(): string[];
|
|
@@ -205,6 +206,7 @@ declare class Timer extends HTMLElement {
|
|
|
205
206
|
resume(): void;
|
|
206
207
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
207
208
|
connectedCallback(): void;
|
|
209
|
+
private _scheduleStart;
|
|
208
210
|
disconnectedCallback(): void;
|
|
209
211
|
}
|
|
210
212
|
|
package/dist/index.esm.js
CHANGED
|
@@ -533,6 +533,8 @@ class Timer extends HTMLElement {
|
|
|
533
533
|
_core;
|
|
534
534
|
_trigger = false;
|
|
535
535
|
_connectedCallbackPromise = Promise.resolve();
|
|
536
|
+
// _scheduleStart のマイクロタスクが待っている間 true
|
|
537
|
+
_startPending = false;
|
|
536
538
|
_internals = null;
|
|
537
539
|
constructor() {
|
|
538
540
|
super();
|
|
@@ -701,12 +703,25 @@ class Timer extends HTMLElement {
|
|
|
701
703
|
});
|
|
702
704
|
}
|
|
703
705
|
stop() {
|
|
706
|
+
// 同じタスクで接続の後に止められたら、待っている自動開始も取り消す
|
|
707
|
+
// (同期で start していた頃は、start → stop で止まったままだった)
|
|
708
|
+
this._startPending = false;
|
|
704
709
|
this._core.stop();
|
|
705
710
|
}
|
|
706
711
|
reset() {
|
|
712
|
+
// reset も止める命令: 待っている自動開始を取り消す(stop と同じ)
|
|
713
|
+
this._startPending = false;
|
|
707
714
|
this._core.reset();
|
|
708
715
|
}
|
|
709
716
|
pause() {
|
|
717
|
+
// 接続時の自動開始が待っているなら、ここでそのときの入力で判断してから止める。
|
|
718
|
+
// 同期で start していた頃と同じく、append → pause() は resume() できる一時停止になる
|
|
719
|
+
if (this._startPending) {
|
|
720
|
+
this._startPending = false;
|
|
721
|
+
if (this.isConnected && !this.manual) {
|
|
722
|
+
this.start();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
710
725
|
this._core.pause();
|
|
711
726
|
}
|
|
712
727
|
resume() {
|
|
@@ -734,11 +749,30 @@ class Timer extends HTMLElement {
|
|
|
734
749
|
registerAutoTrigger();
|
|
735
750
|
}
|
|
736
751
|
// Establish monitoring (§3.5). observe() is a no-op that resolves once ready;
|
|
737
|
-
// expose it as connectedCallbackPromise for SSR.
|
|
752
|
+
// expose it as connectedCallbackPromise for SSR. (The auto-start below runs in a
|
|
753
|
+
// microtask queued before any caller can await this promise, so it still
|
|
754
|
+
// precedes the awaiter.)
|
|
738
755
|
this._connectedCallbackPromise = this._core.observe();
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
756
|
+
this._scheduleStart();
|
|
757
|
+
}
|
|
758
|
+
// 自動開始の判断はマイクロタスクで、そのときの manual / interval / repeat / once /
|
|
759
|
+
// immediate で 1 回だけ行う(timing-and-firing-contract §23)。router は遷移で同じノードを
|
|
760
|
+
// 入れ直し、新しいルートの params から state が入力を書くのはマイクロタスク — その場で
|
|
761
|
+
// start すると、前の入力で動き出し(immediate なら前の入力で 1 tick 発火し)、manual も
|
|
762
|
+
// 前のままで判断していた(docs/seam-apps.md、shift-desk)。その時点で外れていれば何もしない。
|
|
763
|
+
_scheduleStart() {
|
|
764
|
+
if (this._startPending)
|
|
765
|
+
return;
|
|
766
|
+
this._startPending = true;
|
|
767
|
+
queueMicrotask(() => {
|
|
768
|
+
// stop() / reset() が取り消した(そのあと同じタスクで積み直されたら、それが判断する)
|
|
769
|
+
if (!this._startPending)
|
|
770
|
+
return;
|
|
771
|
+
this._startPending = false;
|
|
772
|
+
if (this.isConnected && !this.manual) {
|
|
773
|
+
this.start();
|
|
774
|
+
}
|
|
775
|
+
});
|
|
742
776
|
}
|
|
743
777
|
disconnectedCallback() {
|
|
744
778
|
// dispose() stops the timer and bumps the generation so a callback already
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/TimerCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/Timer.ts","../src/registerComponents.ts","../src/bootstrapTimer.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n timer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-timertarget\",\n tagNames: {\n timer: \"wcs-timer\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// Internal-only live handle to the mutable config. NOT part of the public API\n// (deliberately absent from exports.ts) — it is exported solely so sibling\n// modules in this package can read current settings cheaply. External consumers\n// must use getConfig() (returns a deep-frozen snapshot) / setConfig(). Mutating\n// this object directly bypasses the frozenConfig cache and is unsupported.\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\n/** A misspelt option would otherwise do nothing: `bootstrapTimer` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/timer] bootstrapTimer: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface TimerStartOptions {\n interval?: number;\n repeat?: number;\n immediate?: boolean;\n}\n\n/**\n * Headless timer primitive. A thin, framework-agnostic wrapper around\n * `setInterval` exposed through the wc-bindable protocol: it streams `tick`\n * (a monotonically increasing counter), `elapsed` (running time in ms) and a\n * `running` flag, and is driven by the `start` / `stop` / `reset` / `pause` /\n * `resume` commands.\n *\n * `tick` and `elapsed` are both surfaced via the single `wcs-timer:tick` event\n * (read through getters, mirroring how FetchCore exposes value/status from one\n * `wcs-fetch:response` event), so an observer that binds either property is\n * notified on every fire.\n */\nexport class TimerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"tick\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.count },\n { name: \"elapsed\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.elapsed },\n { name: \"running\", event: \"wcs-timer:running-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"start\" },\n { name: \"stop\" },\n { name: \"reset\" },\n { name: \"pause\" },\n { name: \"resume\" },\n ],\n };\n\n private _target: EventTarget;\n private _timerId: ReturnType<typeof setInterval> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every async start\n // (start()/resume()). A scheduled callback (setInterval/setTimeout) captures the\n // generation live via `_gen`; a fire that was already queued when the timer was\n // torn down — or superseded by a new run — has a stale gen and MUST NOT mutate\n // state or dispatch on a disposed element. _clearTimer() removes the handle, but\n // the guard is the belt-and-braces defense for a callback already in the queue.\n private _gen = 0;\n // Generation captured for the currently scheduled run, set at each async start\n // (start()/resume()). A scheduled callback compares it against the live `_gen`;\n // a stale callback (dispose() bumped `_gen` after this run was armed) bails.\n private _runGen = 0;\n // SSR (§3.8): the timer does no asynchronous probe, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n private _tick: number = 0;\n private _running: boolean = false;\n private _paused: boolean = false;\n\n // `_tick` value captured at the start of the current run. `repeat` counts ticks\n // *per run*, so the stop condition compares against this baseline rather than the\n // cumulative `_tick` (which only resets on reset()). Without it, re-starting a\n // completed bounded timer would stop after a single tick.\n private _runStartTick: number = 0;\n\n // Timer configuration (captured on start, reused by pause/resume).\n // `_immediate` is intentionally NOT a field: it is per-run intent consumed\n // entirely within start() (fire once, then schedule), so it lives as a local\n // there rather than lingering as instance state no other method reads.\n private _interval: number = 1000;\n private _repeat: number = 0; // 0 = unlimited\n\n // Elapsed-time bookkeeping. `_accumulatedElapsed` holds the time folded from\n // already-finished running segments; `_segmentStart` is the timestamp the\n // current running segment began (null when not running). The live elapsed is\n // the sum of the two — see _currentElapsed().\n private _accumulatedElapsed: number = 0;\n private _segmentStart: number | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get tick(): number {\n return this._tick;\n }\n\n get elapsed(): number {\n return this._currentElapsed();\n }\n\n get running(): boolean {\n return this._running;\n }\n\n // SSR readiness (§3.8): resolves after the first probe. The timer is\n // command-driven with nothing to probe, so this is an already-resolved promise.\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). The timer is command-driven (start/stop/...) with no\n // ambient subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready (mirroring UploadCore). dispose() tears the timer down —\n // it stops any running interval and bumps the generation so a callback already\n // queued cannot fire onto a torn-down element.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.stop();\n }\n\n // --- State setters with event dispatch ---\n\n private _dispatchTick(): void {\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:tick\", {\n detail: { count: this._tick, elapsed: this._currentElapsed() },\n bubbles: true,\n }));\n }\n\n private _setRunning(running: boolean): void {\n if (this._running === running) return;\n this._running = running;\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:running-changed\", {\n detail: running,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n start(options: TimerStartOptions = {}): void {\n // Idempotent while running: a redundant start() must not stack a second\n // setInterval (which would leak and double the tick rate). Reconfiguring an\n // active timer is done via stop() + start().\n if (this._running) return;\n\n // start() begins a fresh running segment, so clear any lingering pause from a\n // prior pause()-without-resume(). Without this, the timer would run while\n // _paused stayed true, leaving pause() a no-op and letting resume() overwrite\n // the live timer handle (leak + double fire).\n this._paused = false;\n\n // `interval` is persistent configuration: a non-positive / non-finite value\n // (or an omitted option) keeps the previous interval (default 1000ms). The\n // guard rejects values that would turn setInterval into a hot loop and make\n // resume()'s `accumulated % interval` arithmetic produce NaN. The Shell already\n // falls back to 1000 for invalid attributes; this is the backstop for direct\n // Core API callers.\n if (typeof options.interval === \"number\" && Number.isFinite(options.interval) && options.interval > 0) {\n this._interval = options.interval;\n }\n\n // `repeat` / `immediate` are per-run intent, NOT persistent configuration:\n // every start() re-establishes them from the options, defaulting to\n // \"unlimited\" / \"no immediate fire\" when omitted. This keeps a bare start()\n // after a bounded or one-shot run from silently inheriting the old bounds.\n // `repeat` is a field (pause/resume/_fire read it across the run); `immediate`\n // is consumed here and now, so it stays a local.\n this._repeat = (typeof options.repeat === \"number\" && options.repeat > 0) ? options.repeat : 0;\n const immediate = options.immediate === true;\n\n this._setRunning(true);\n this._segmentStart = Date.now();\n // Baseline this run's per-run repeat counting (set after _setRunning so a\n // re-start of a completed bounded timer fires the full N ticks again).\n this._runStartTick = this._tick;\n // Capture this run's generation (§3.4): a scheduled fire that outlives a\n // dispose() (which bumps `_gen`) is then recognised as stale and ignored.\n this._runGen = ++this._gen;\n\n // Fire immediately on start when requested. _fire() may stop the timer (when\n // repeat is reached), so re-check _running before scheduling the interval.\n if (immediate) {\n this._fire();\n }\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n }\n\n // Swap the tick period of a live timer in place, WITHOUT re-running start().\n // Unlike stop() + start(), this leaves the per-run repeat progress in flight\n // (`_repeat` and its `_runStartTick` baseline) untouched, so a bounded\n // `repeat=\"N\"` run is not re-baselined to fire N more times. It also never goes\n // through start()'s `immediate` path, so an `immediate` timer does not fire an\n // extra tick. Only re-arms the steady interval; pause()/resume() and reset() are\n // unaffected. No-op when not running (interval is then plain config, captured on\n // the next start) or when the new period is non-positive / non-finite (which\n // would turn setInterval into a hot loop and break resume()'s modulo arithmetic).\n changeInterval(interval: number): void {\n if (!this._running) return;\n if (!(typeof interval === \"number\" && Number.isFinite(interval) && interval > 0)) return;\n if (interval === this._interval) return;\n this._interval = interval;\n // Re-arm the steady ticking at the new period. The current period's progress\n // is intentionally discarded (the next tick is a full new interval away),\n // matching the boundary reset of the previous stop()+start() behaviour.\n this._clearTimer();\n this._timerId = setInterval(this._fire, this._interval);\n }\n\n stop(): void {\n this._clearTimer();\n this._foldElapsed();\n this._paused = false;\n this._setRunning(false);\n }\n\n reset(): void {\n this._clearTimer();\n this._paused = false;\n this._tick = 0;\n this._accumulatedElapsed = 0;\n this._segmentStart = null;\n this._setRunning(false);\n // Notify observers that the counter/elapsed have returned to zero.\n this._dispatchTick();\n }\n\n pause(): void {\n // Pause only a live timer; a no-op otherwise so it composes safely with the\n // declarative lifecycle. Unlike stop(), it records `_paused` so resume() can\n // tell an intentional pause from a full stop.\n if (!this._running || this._paused) return;\n this._clearTimer();\n this._foldElapsed();\n this._paused = true;\n this._setRunning(false);\n }\n\n resume(): void {\n if (!this._paused) return;\n this._paused = false;\n this._setRunning(true);\n this._segmentStart = Date.now();\n // New scheduled run after a pause: capture its generation (§3.4) so a\n // post-dispose() boundary/interval callback is recognised as stale.\n this._runGen = ++this._gen;\n // Invariant: `_interval` is fixed at start() and stays constant for the whole\n // pause/resume cycle — changeInterval() only mutates it while *running* (never\n // while paused), so the remainder arithmetic below can safely assume the same\n // period was in effect across the paused segment. Consequence for the Shell:\n // because the live interval-attribute path (attributeChangedCallback ->\n // changeInterval) is gated on `running`, an `interval` change made *while\n // paused* is silently not applied here; it is picked up only on the next\n // start() as plain config. This is by design — see README \"Commands\".\n // Resume seamlessly: a tick fires every `interval` ms of *running* time, so\n // honour the partial period consumed before the pause. Wait only the\n // remainder to the next boundary, then fall back to the steady interval.\n // (`accumulated % interval === 0` — paused exactly on a boundary — yields a\n // full interval, which is correct: the next tick is a whole period away.)\n const remainder = this._interval - (this._accumulatedElapsed % this._interval);\n this._timerId = setTimeout(this._onResumeBoundary, remainder);\n }\n\n // --- Internal ---\n\n private _onResumeBoundary = (): void => {\n // Stale-run guard (§3.4): a resume-boundary timeout that fires after dispose()\n // belongs to a torn-down run — drop it without re-arming the interval.\n if (this._runGen !== this._gen) return;\n this._timerId = null;\n this._fire();\n // _fire() may have auto-stopped the timer (repeat reached); only re-arm the\n // steady interval while still running.\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n };\n\n private _fire = (): void => {\n // Stale-run guard (§3.4): an interval callback queued before dispose() (which\n // bumps `_gen`) must not tick or dispatch onto a torn-down element.\n if (this._runGen !== this._gen) return;\n this._tick++;\n this._dispatchTick();\n\n // Auto-stop once this run has fired the requested number of ticks (repeat=0\n // runs forever). Counted per-run via `_runStartTick`, so a re-start after a\n // completed bounded run fires N ticks again. `once` is expressed by the Shell\n // as repeat=1.\n if (this._repeat > 0 && (this._tick - this._runStartTick) >= this._repeat) {\n this._clearTimer();\n this._foldElapsed();\n this._setRunning(false);\n }\n };\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n // `_timerId` may hold a setInterval handle (steady ticking) or a setTimeout\n // handle (the resume remainder). Clear both — per the HTML spec timers\n // share one list and clearTimeout/clearInterval each remove the entry\n // regardless of which call created it.\n clearTimeout(this._timerId);\n clearInterval(this._timerId);\n this._timerId = null;\n }\n }\n\n private _foldElapsed(): void {\n if (this._segmentStart !== null) {\n this._accumulatedElapsed += Date.now() - this._segmentStart;\n this._segmentStart = null;\n }\n }\n\n private _currentElapsed(): number {\n return this._accumulatedElapsed +\n (this._segmentStart !== null ? Date.now() - this._segmentStart : 0);\n }\n}\n","import { config } from \"./config.js\";\nimport type { Timer } from \"./components/Timer.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const timerId = triggerElement.getAttribute(config.triggerAttribute);\n if (!timerId) return;\n\n // Resolve the registered constructor at call time instead of importing Timer\n // as a value. The value import created a components/Timer.ts ⇄ autoTrigger.ts\n // cycle (Timer.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-timer> class matches — without the import cycle.\n const TimerCtor = customElements.get(config.tagNames.timer);\n const timerElement = document.getElementById(timerId);\n if (!TimerCtor || !(timerElement instanceof TimerCtor)) return;\n\n // Suppress the element's default action so a timer can start without\n // navigating. Intentional: do not attach data-timertarget to an element whose\n // default action you also want (real <a href> link, form-submit button) — it\n // will be cancelled. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (timerElement as Timer).start();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\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// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\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 const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { TimerCore } from \"../core/TimerCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class Timer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...TimerCore.wcBindable,\n properties: [\n ...TimerCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-timer:trigger-changed\", semantics: \"state\" },\n ],\n // Shell-level settable surface. `attribute` is a purely descriptive hint\n // (per SPEC-extensions.md the binding core does not act on it) naming the\n // mirrored HTML attribute, matching <wcs-geo> / <wcs-debounce>. `trigger` is a\n // momentary command-property with no backing attribute, so it carries no hint\n // (same as those packages). `start` / `stop` / `reset` / `pause` / `resume`\n // commands are inherited from the Core above.\n inputs: [\n { name: \"interval\", attribute: \"interval\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"repeat\", attribute: \"repeat\" },\n { name: \"immediate\", attribute: \"immediate\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"interval\"]; }\n\n private _core: TimerCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new TimerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-timer:running-changed\": (d) => ({ running: d === true }),\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 // SSR (§4.1/§4.4): the Shell exposes the Core's readiness so a server-side\n // renderer can await the connect-time probe before snapshotting. The timer has\n // no async probe (observe() resolves immediately), but the contract is uniform\n // across IO nodes.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined: `null`\n // removes the attribute (the documented default), `undefined` restores the\n // attribute the element started with (wc-bindable producer guidance P1;\n // React 19 and a direct assignment deliver it, @wcstack/state does not).\n // An `interval` write still goes through attributeChangedCallback, so a\n // running timer swaps to the restored / default period in place.\n\n get interval(): number {\n const attr = this.getAttribute(\"interval\");\n if (attr === null || attr.trim() === \"\") return 1000;\n // Strict parse via Number() (unlike parseInt, \"100px\" -> NaN, not 100),\n // matching <wcs-geo> / <wcs-debounce>. Fall back to the 1000ms default for any\n // invalid period — not only NaN but also 0 / negative values, which would\n // otherwise reach setInterval as a hot loop and break resume()'s modulo\n // arithmetic in the Core.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 1000;\n }\n\n set interval(value: number | null | undefined) {\n reflectAttribute(this, \"interval\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"once\", value);\n }\n\n get repeat(): number {\n const attr = this.getAttribute(\"repeat\");\n if (attr === null || attr.trim() === \"\") return 0;\n // Strict parse via Number() (\"3px\" -> NaN, not 3), matching <wcs-geo> /\n // <wcs-debounce>. Normalise any non-positive / non-numeric value to 0\n // (= unlimited), mirroring the `interval` getter. Without this a negative\n // `repeat=\"-3\"` would leak through to start(); harmless today (Core treats\n // `_repeat <= 0` as unlimited) but the asymmetry is a trap.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 0;\n }\n\n set repeat(value: number | null | undefined) {\n reflectAttribute(this, \"repeat\", value);\n }\n\n get immediate(): boolean {\n return this.hasAttribute(\"immediate\");\n }\n\n set immediate(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"immediate\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get tick(): number {\n return this._core.tick;\n }\n\n get elapsed(): number {\n return this._core.elapsed;\n }\n\n get running(): boolean {\n return this._core.running;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write starts the timer. Mirrors\n // the trigger flag on <wcs-fetch> / <wcs-ws>. Prefer the command-token\n // protocol (`command.start: $command.tick`) for state-driven starts; this\n // exists mainly for the DOM click trigger and simple boolean bindings.\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.start();\n this._trigger = false;\n // The `trigger-changed` event reports the momentary flag returning to\n // false, i.e. that the trigger property *changed* — it is deliberately not\n // gated on whether start() actually began a new run. This keeps the\n // wcBindable `trigger` property's change-notification semantics consistent\n // (every false→true write produces exactly one change-back event), even\n // when start() was a no-op because the timer was already running.\n this.dispatchEvent(new CustomEvent(\"wcs-timer:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // --- Commands ---\n\n start(): void {\n // `once` is sugar for \"fire exactly one tick\": map it to repeat=1, but let an\n // explicit repeat attribute win when both are present.\n const repeat = this.repeat > 0 ? this.repeat : (this.once ? 1 : 0);\n this._core.start({\n interval: this.interval,\n repeat,\n immediate: this.immediate,\n });\n }\n\n stop(): void {\n this._core.stop();\n }\n\n reset(): void {\n this._core.reset();\n }\n\n pause(): void {\n this._core.pause();\n }\n\n resume(): void {\n this._core.resume();\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // Live interval changes swap the underlying setInterval period in place.\n // `tick` / `elapsed` and the per-run `repeat` progress are preserved — we\n // deliberately do NOT stop()+start(), which would re-run start() and\n // re-evaluate per-run options (re-firing `immediate` and re-baselining\n // `repeat`). `running` alone gates this: swapping the period is orthogonal to\n // *how* the timer was started, so a `manual` timer the user has explicitly\n // started gets live period changes too. A non-running timer needs no swap —\n // its next start() picks up the new attribute as plain config.\n if (name === \"interval\" && oldValue !== newValue && this.isConnected && this.running) {\n this._core.changeInterval(this.interval);\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // Establish monitoring (§3.5). observe() is a no-op that resolves once ready;\n // expose it as connectedCallbackPromise for SSR.\n this._connectedCallbackPromise = this._core.observe();\n if (!this.manual) {\n this.start();\n }\n }\n\n disconnectedCallback(): void {\n // dispose() stops the timer and bumps the generation so a callback already\n // queued cannot fire onto a disconnected element (§3.5 / §4.4).\n this._core.dispose();\n }\n}\n","import { Timer } from \"./components/Timer.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.timer)) {\n registry.define(config.tagNames.timer, Timer);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapTimer(userConfig?: IWritableConfig, registry?: CustomElementRegistry): void {\n if (userConfig) {\n setConfig(userConfig);\n }\n registerComponents(registry);\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/config.ts","../src/core/TimerCore.ts","../src/autoTrigger.ts","../src/protocol/upgradeProperties.ts","../src/protocol/inputAttribute.ts","../src/components/Timer.ts","../src/registerComponents.ts","../src/bootstrapTimer.ts"],"sourcesContent":["import { IConfig, IWritableConfig } from \"./types.js\";\n\ninterface IInternalConfig extends IConfig {\n autoTrigger: boolean;\n triggerAttribute: string;\n tagNames: {\n timer: string;\n };\n}\n\nconst _config: IInternalConfig = {\n autoTrigger: true,\n triggerAttribute: \"data-timertarget\",\n tagNames: {\n timer: \"wcs-timer\",\n },\n};\n\nfunction deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n Object.freeze(obj);\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key]);\n }\n return obj;\n}\n\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const clone: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n clone[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return clone as T;\n}\n\nlet frozenConfig: IConfig | null = null;\n\n// Internal-only live handle to the mutable config. NOT part of the public API\n// (deliberately absent from exports.ts) — it is exported solely so sibling\n// modules in this package can read current settings cheaply. External consumers\n// must use getConfig() (returns a deep-frozen snapshot) / setConfig(). Mutating\n// this object directly bypasses the frozenConfig cache and is unsupported.\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\n/** A misspelt option would otherwise do nothing: `bootstrapTimer` refuses it. */\nfunction invalid(key: string): never {\n throw new Error(`[@wcstack/timer] bootstrapTimer: \"${key}\" is not one of its options, or not of the option's type.`);\n}\n\n/**\n * Applies the options given; an undefined value is left out. An option this package does not\n * have, a value of another type than its default (null, or an array for an object, included) or\n * a tag name it does not define throws, and then nothing is applied.\n */\nexport function setConfig(partialConfig: IWritableConfig): void {\n const options = _config as unknown as Record<string, unknown>;\n const tags = _config.tagNames as Record<string, string>;\n const given = Object.entries(partialConfig).filter(([, value]) => value !== undefined);\n const givenTags = Object.entries(partialConfig.tagNames ?? {}).filter(([, tag]) => tag !== undefined);\n for (const [key, value] of given) {\n const current = options[key];\n if (!Object.hasOwn(options, key) || value === null || typeof value !== typeof current || Array.isArray(value) !== Array.isArray(current)) {\n invalid(key);\n }\n }\n for (const [name, tag] of givenTags) {\n if (!Object.hasOwn(tags, name) || typeof tag !== \"string\") invalid(`tagNames.${name}`);\n }\n for (const [key, value] of given) {\n if (key !== \"tagNames\") {\n options[key] = value;\n }\n }\n for (const [name, tag] of givenTags) tags[name] = tag as string;\n frozenConfig = null;\n}\n","import { IWcBindable } from \"../types.js\";\n\nexport interface TimerStartOptions {\n interval?: number;\n repeat?: number;\n immediate?: boolean;\n}\n\n/**\n * Headless timer primitive. A thin, framework-agnostic wrapper around\n * `setInterval` exposed through the wc-bindable protocol: it streams `tick`\n * (a monotonically increasing counter), `elapsed` (running time in ms) and a\n * `running` flag, and is driven by the `start` / `stop` / `reset` / `pause` /\n * `resume` commands.\n *\n * `tick` and `elapsed` are both surfaced via the single `wcs-timer:tick` event\n * (read through getters, mirroring how FetchCore exposes value/status from one\n * `wcs-fetch:response` event), so an observer that binds either property is\n * notified on every fire.\n */\nexport class TimerCore extends EventTarget {\n static wcBindable: IWcBindable = {\n protocol: \"wc-bindable\",\n version: 1,\n properties: [\n { name: \"tick\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.count },\n { name: \"elapsed\", event: \"wcs-timer:tick\", semantics: \"state\", getter: (e: Event) => (e as CustomEvent).detail.elapsed },\n { name: \"running\", event: \"wcs-timer:running-changed\", semantics: \"state\" },\n ],\n commands: [\n { name: \"start\" },\n { name: \"stop\" },\n { name: \"reset\" },\n { name: \"pause\" },\n { name: \"resume\" },\n ],\n };\n\n private _target: EventTarget;\n private _timerId: ReturnType<typeof setInterval> | null = null;\n\n // Generation guard (§3.4): bumped on dispose() and at every async start\n // (start()/resume()). A scheduled callback (setInterval/setTimeout) captures the\n // generation live via `_gen`; a fire that was already queued when the timer was\n // torn down — or superseded by a new run — has a stale gen and MUST NOT mutate\n // state or dispatch on a disposed element. _clearTimer() removes the handle, but\n // the guard is the belt-and-braces defense for a callback already in the queue.\n private _gen = 0;\n // Generation captured for the currently scheduled run, set at each async start\n // (start()/resume()). A scheduled callback compares it against the live `_gen`;\n // a stale callback (dispose() bumped `_gen` after this run was armed) bails.\n private _runGen = 0;\n // SSR (§3.8): the timer does no asynchronous probe, so readiness is immediate.\n private _ready: Promise<void> = Promise.resolve();\n\n private _tick: number = 0;\n private _running: boolean = false;\n private _paused: boolean = false;\n\n // `_tick` value captured at the start of the current run. `repeat` counts ticks\n // *per run*, so the stop condition compares against this baseline rather than the\n // cumulative `_tick` (which only resets on reset()). Without it, re-starting a\n // completed bounded timer would stop after a single tick.\n private _runStartTick: number = 0;\n\n // Timer configuration (captured on start, reused by pause/resume).\n // `_immediate` is intentionally NOT a field: it is per-run intent consumed\n // entirely within start() (fire once, then schedule), so it lives as a local\n // there rather than lingering as instance state no other method reads.\n private _interval: number = 1000;\n private _repeat: number = 0; // 0 = unlimited\n\n // Elapsed-time bookkeeping. `_accumulatedElapsed` holds the time folded from\n // already-finished running segments; `_segmentStart` is the timestamp the\n // current running segment began (null when not running). The live elapsed is\n // the sum of the two — see _currentElapsed().\n private _accumulatedElapsed: number = 0;\n private _segmentStart: number | null = null;\n\n constructor(target?: EventTarget) {\n super();\n this._target = target ?? this;\n }\n\n get tick(): number {\n return this._tick;\n }\n\n get elapsed(): number {\n return this._currentElapsed();\n }\n\n get running(): boolean {\n return this._running;\n }\n\n // SSR readiness (§3.8): resolves after the first probe. The timer is\n // command-driven with nothing to probe, so this is an already-resolved promise.\n get ready(): Promise<void> {\n return this._ready;\n }\n\n // Lifecycle (§3.5). The timer is command-driven (start/stop/...) with no\n // ambient subscription to establish, so observe() is an idempotent no-op that\n // resolves once ready (mirroring UploadCore). dispose() tears the timer down —\n // it stops any running interval and bumps the generation so a callback already\n // queued cannot fire onto a torn-down element.\n observe(): Promise<void> {\n return this._ready;\n }\n\n dispose(): void {\n this._gen++;\n this.stop();\n }\n\n // --- State setters with event dispatch ---\n\n private _dispatchTick(): void {\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:tick\", {\n detail: { count: this._tick, elapsed: this._currentElapsed() },\n bubbles: true,\n }));\n }\n\n private _setRunning(running: boolean): void {\n if (this._running === running) return;\n this._running = running;\n this._target.dispatchEvent(new CustomEvent(\"wcs-timer:running-changed\", {\n detail: running,\n bubbles: true,\n }));\n }\n\n // --- Public API ---\n\n start(options: TimerStartOptions = {}): void {\n // Idempotent while running: a redundant start() must not stack a second\n // setInterval (which would leak and double the tick rate). Reconfiguring an\n // active timer is done via stop() + start().\n if (this._running) return;\n\n // start() begins a fresh running segment, so clear any lingering pause from a\n // prior pause()-without-resume(). Without this, the timer would run while\n // _paused stayed true, leaving pause() a no-op and letting resume() overwrite\n // the live timer handle (leak + double fire).\n this._paused = false;\n\n // `interval` is persistent configuration: a non-positive / non-finite value\n // (or an omitted option) keeps the previous interval (default 1000ms). The\n // guard rejects values that would turn setInterval into a hot loop and make\n // resume()'s `accumulated % interval` arithmetic produce NaN. The Shell already\n // falls back to 1000 for invalid attributes; this is the backstop for direct\n // Core API callers.\n if (typeof options.interval === \"number\" && Number.isFinite(options.interval) && options.interval > 0) {\n this._interval = options.interval;\n }\n\n // `repeat` / `immediate` are per-run intent, NOT persistent configuration:\n // every start() re-establishes them from the options, defaulting to\n // \"unlimited\" / \"no immediate fire\" when omitted. This keeps a bare start()\n // after a bounded or one-shot run from silently inheriting the old bounds.\n // `repeat` is a field (pause/resume/_fire read it across the run); `immediate`\n // is consumed here and now, so it stays a local.\n this._repeat = (typeof options.repeat === \"number\" && options.repeat > 0) ? options.repeat : 0;\n const immediate = options.immediate === true;\n\n this._setRunning(true);\n this._segmentStart = Date.now();\n // Baseline this run's per-run repeat counting (set after _setRunning so a\n // re-start of a completed bounded timer fires the full N ticks again).\n this._runStartTick = this._tick;\n // Capture this run's generation (§3.4): a scheduled fire that outlives a\n // dispose() (which bumps `_gen`) is then recognised as stale and ignored.\n this._runGen = ++this._gen;\n\n // Fire immediately on start when requested. _fire() may stop the timer (when\n // repeat is reached), so re-check _running before scheduling the interval.\n if (immediate) {\n this._fire();\n }\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n }\n\n // Swap the tick period of a live timer in place, WITHOUT re-running start().\n // Unlike stop() + start(), this leaves the per-run repeat progress in flight\n // (`_repeat` and its `_runStartTick` baseline) untouched, so a bounded\n // `repeat=\"N\"` run is not re-baselined to fire N more times. It also never goes\n // through start()'s `immediate` path, so an `immediate` timer does not fire an\n // extra tick. Only re-arms the steady interval; pause()/resume() and reset() are\n // unaffected. No-op when not running (interval is then plain config, captured on\n // the next start) or when the new period is non-positive / non-finite (which\n // would turn setInterval into a hot loop and break resume()'s modulo arithmetic).\n changeInterval(interval: number): void {\n if (!this._running) return;\n if (!(typeof interval === \"number\" && Number.isFinite(interval) && interval > 0)) return;\n if (interval === this._interval) return;\n this._interval = interval;\n // Re-arm the steady ticking at the new period. The current period's progress\n // is intentionally discarded (the next tick is a full new interval away),\n // matching the boundary reset of the previous stop()+start() behaviour.\n this._clearTimer();\n this._timerId = setInterval(this._fire, this._interval);\n }\n\n stop(): void {\n this._clearTimer();\n this._foldElapsed();\n this._paused = false;\n this._setRunning(false);\n }\n\n reset(): void {\n this._clearTimer();\n this._paused = false;\n this._tick = 0;\n this._accumulatedElapsed = 0;\n this._segmentStart = null;\n this._setRunning(false);\n // Notify observers that the counter/elapsed have returned to zero.\n this._dispatchTick();\n }\n\n pause(): void {\n // Pause only a live timer; a no-op otherwise so it composes safely with the\n // declarative lifecycle. Unlike stop(), it records `_paused` so resume() can\n // tell an intentional pause from a full stop.\n if (!this._running || this._paused) return;\n this._clearTimer();\n this._foldElapsed();\n this._paused = true;\n this._setRunning(false);\n }\n\n resume(): void {\n if (!this._paused) return;\n this._paused = false;\n this._setRunning(true);\n this._segmentStart = Date.now();\n // New scheduled run after a pause: capture its generation (§3.4) so a\n // post-dispose() boundary/interval callback is recognised as stale.\n this._runGen = ++this._gen;\n // Invariant: `_interval` is fixed at start() and stays constant for the whole\n // pause/resume cycle — changeInterval() only mutates it while *running* (never\n // while paused), so the remainder arithmetic below can safely assume the same\n // period was in effect across the paused segment. Consequence for the Shell:\n // because the live interval-attribute path (attributeChangedCallback ->\n // changeInterval) is gated on `running`, an `interval` change made *while\n // paused* is silently not applied here; it is picked up only on the next\n // start() as plain config. This is by design — see README \"Commands\".\n // Resume seamlessly: a tick fires every `interval` ms of *running* time, so\n // honour the partial period consumed before the pause. Wait only the\n // remainder to the next boundary, then fall back to the steady interval.\n // (`accumulated % interval === 0` — paused exactly on a boundary — yields a\n // full interval, which is correct: the next tick is a whole period away.)\n const remainder = this._interval - (this._accumulatedElapsed % this._interval);\n this._timerId = setTimeout(this._onResumeBoundary, remainder);\n }\n\n // --- Internal ---\n\n private _onResumeBoundary = (): void => {\n // Stale-run guard (§3.4): a resume-boundary timeout that fires after dispose()\n // belongs to a torn-down run — drop it without re-arming the interval.\n if (this._runGen !== this._gen) return;\n this._timerId = null;\n this._fire();\n // _fire() may have auto-stopped the timer (repeat reached); only re-arm the\n // steady interval while still running.\n if (this._running) {\n this._timerId = setInterval(this._fire, this._interval);\n }\n };\n\n private _fire = (): void => {\n // Stale-run guard (§3.4): an interval callback queued before dispose() (which\n // bumps `_gen`) must not tick or dispatch onto a torn-down element.\n if (this._runGen !== this._gen) return;\n this._tick++;\n this._dispatchTick();\n\n // Auto-stop once this run has fired the requested number of ticks (repeat=0\n // runs forever). Counted per-run via `_runStartTick`, so a re-start after a\n // completed bounded run fires N ticks again. `once` is expressed by the Shell\n // as repeat=1.\n if (this._repeat > 0 && (this._tick - this._runStartTick) >= this._repeat) {\n this._clearTimer();\n this._foldElapsed();\n this._setRunning(false);\n }\n };\n\n private _clearTimer(): void {\n if (this._timerId !== null) {\n // `_timerId` may hold a setInterval handle (steady ticking) or a setTimeout\n // handle (the resume remainder). Clear both — per the HTML spec timers\n // share one list and clearTimeout/clearInterval each remove the entry\n // regardless of which call created it.\n clearTimeout(this._timerId);\n clearInterval(this._timerId);\n this._timerId = null;\n }\n }\n\n private _foldElapsed(): void {\n if (this._segmentStart !== null) {\n this._accumulatedElapsed += Date.now() - this._segmentStart;\n this._segmentStart = null;\n }\n }\n\n private _currentElapsed(): number {\n return this._accumulatedElapsed +\n (this._segmentStart !== null ? Date.now() - this._segmentStart : 0);\n }\n}\n","import { config } from \"./config.js\";\nimport type { Timer } from \"./components/Timer.js\";\n\nlet registered = false;\n\nfunction handleClick(event: Event): void {\n const target = event.target;\n if (!(target instanceof Element)) return;\n\n const triggerElement = target.closest<Element>(`[${config.triggerAttribute}]`);\n if (!triggerElement) return;\n\n const timerId = triggerElement.getAttribute(config.triggerAttribute);\n if (!timerId) return;\n\n // Resolve the registered constructor at call time instead of importing Timer\n // as a value. The value import created a components/Timer.ts ⇄ autoTrigger.ts\n // cycle (Timer.connectedCallback() calls registerAutoTrigger()). instanceof\n // against the customElements registry keeps the exact same identity guarantee\n // — only the registered <wcs-timer> class matches — without the import cycle.\n const TimerCtor = customElements.get(config.tagNames.timer);\n const timerElement = document.getElementById(timerId);\n if (!TimerCtor || !(timerElement instanceof TimerCtor)) return;\n\n // Suppress the element's default action so a timer can start without\n // navigating. Intentional: do not attach data-timertarget to an element whose\n // default action you also want (real <a href> link, form-submit button) — it\n // will be cancelled. See README \"Optional DOM Triggering\".\n event.preventDefault();\n (timerElement as Timer).start();\n}\n\nexport function registerAutoTrigger(): void {\n if (registered) return;\n registered = true;\n document.addEventListener(\"click\", handleClick);\n}\n\nexport function unregisterAutoTrigger(): void {\n if (!registered) return;\n registered = false;\n document.removeEventListener(\"click\", handleClick);\n}\n","// ===========================================================================\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// 属性になってしまったオブジェクトの入力(`files=\"[object File]\"`)を、要素ごとに 1 回だけ言う。\n// React 19 は定義前の要素にプロパティが無いのでオブジェクトを属性に書き、Vue の `.attr` も\n// 書く。要素はその入力をプロパティでしか読まないので、何も受け取らず、何も言わなかった\n// (docs/seam-apps.md、fw-inventory)。\nconst toldObjectAttribute = new WeakSet<object>();\n\nfunction warnObjectAttribute(element: object, name: string, value: string): void {\n if (toldObjectAttribute.has(element)) return;\n toldObjectAttribute.add(element);\n const tag = (element as { localName?: string }).localName ?? \"element\";\n console.warn(\n `[wcs/input-as-attribute] <${tag}> has the attribute ${name}=\"${value}\": an object was written as an ` +\n `attribute, so the element did not receive it. A framework does that when the property is set before the ` +\n `element's definition loads (React 19), or when told to (Vue's .attr). Load the definition before rendering, ` +\n `or assign the property through a ref (Vue: .prop). (Said once per element.)`,\n element,\n );\n}\n\n/**\n * `connectedCallback` の先頭で呼ぶ。宣言済み input のうち upgrade 前の代入で\n * accessor をシャドウしている own プロパティを、delete → 再代入で setter に通し直す。\n *\n * - 冪等: 再代入は accessor を通るので own プロパティは残らず、2 回目以降は no-op。\n * - 宣言に `inputs` が無い要素、`wcBindable` を持たない要素では何もしない。\n * - 値の意味は変えない。今まで捨てられていた代入が届くようになる一方向の変化。\n * - 値が `[object …]` の属性(属性に書かれてしまったオブジェクトの入力)は、要素ごとに 1 回警告する。\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 const getAttribute = (element as { getAttribute?: (name: string) => string | null }).getAttribute;\n for (const input of inputs) {\n const name = input.name;\n const attribute = typeof getAttribute === \"function\" ? getAttribute.call(element, name.toLowerCase()) : null;\n if (attribute !== null && attribute.startsWith(\"[object \")) warnObjectAttribute(element, name, attribute);\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","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/input-attribute.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// 属性へ反映する wc-bindable 入力の producer 側(SPEC-extensions § Producer guidance for inputs の P1〜P3)。\n// 入力の setter は属性をこの 2 関数で書く。それで次が揃う:\n// - `undefined` は「値が無い」(P1): 属性を、この関数で最初に書く前の状態 — マークアップに書かれた値、\n// 無ければ属性なし(= その入力の文書化した既定値)— へ戻す。applier プロファイルを宣言する binder は\n// 値の後の `undefined` を書き(A2)、React 19 も書き、直接の代入でも届く。\n// - `null` はクリア(P2): 属性なし、つまり文書化した既定値。\n// - どちらも文字列 \"undefined\" / \"null\" として属性に入らない。\n//\n// 「最初に書く前」は、その最初の書き込みのときに読む(遅延)。upgrade 前に代入されたプロパティは\n// connectedCallback の upgradeProperties() が通し直すので、そのときにはパーサが書いた属性が揃っている。\n// 要素自身が setter を通さずに書いた属性は、最初の書き込みより前なら「最初の状態」に含まれる。\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/input-attribute.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/inputAttribute.ts). Those copies are generated — do not edit them.\n\nconst initialAttributes = new WeakMap<Element, Map<string, string | null>>();\n\n/** The attribute as it stood before the first write through these helpers. */\nfunction initialAttribute(el: Element, name: string): string | null {\n let byName = initialAttributes.get(el);\n if (byName === undefined) {\n byName = new Map();\n initialAttributes.set(el, byName);\n }\n if (!byName.has(name)) byName.set(name, el.getAttribute(name));\n return byName.get(name) as string | null;\n}\n\nfunction writeAttribute(el: Element, name: string, value: string | null): void {\n if (value === null) el.removeAttribute(name);\n else el.setAttribute(name, value);\n}\n\n/**\n * A value attribute. `value` is written as `String(value)`; `null` removes the attribute;\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value === null ? null : String(value));\n}\n\n/**\n * A boolean attribute, present while `value` is truthy (`null` and `false` remove it);\n * `undefined` restores the attribute the element started with.\n */\nexport function reflectBooleanAttribute(el: Element, name: string, value: unknown): void {\n const initial = initialAttribute(el, name);\n writeAttribute(el, name, value === undefined ? initial : value ? \"\" : null);\n}\n","import { config } from \"../config.js\";\nimport { IWcBindable } from \"../types.js\";\nimport { TimerCore } from \"../core/TimerCore.js\";\nimport { registerAutoTrigger } from \"../autoTrigger.js\";\nimport { upgradeProperties } from \"../protocol/upgradeProperties.js\";\nimport { reflectAttribute, reflectBooleanAttribute } from \"../protocol/inputAttribute.js\";\n\nexport class Timer extends HTMLElement {\n static hasConnectedCallbackPromise = true;\n static wcBindable: IWcBindable = {\n ...TimerCore.wcBindable,\n properties: [\n ...TimerCore.wcBindable.properties,\n { name: \"trigger\", event: \"wcs-timer:trigger-changed\", semantics: \"state\" },\n ],\n // Shell-level settable surface. `attribute` is a purely descriptive hint\n // (per SPEC-extensions.md the binding core does not act on it) naming the\n // mirrored HTML attribute, matching <wcs-geo> / <wcs-debounce>. `trigger` is a\n // momentary command-property with no backing attribute, so it carries no hint\n // (same as those packages). `start` / `stop` / `reset` / `pause` / `resume`\n // commands are inherited from the Core above.\n inputs: [\n { name: \"interval\", attribute: \"interval\" },\n { name: \"once\", attribute: \"once\" },\n { name: \"repeat\", attribute: \"repeat\" },\n { name: \"immediate\", attribute: \"immediate\" },\n { name: \"manual\", attribute: \"manual\" },\n { name: \"trigger\" },\n ],\n };\n static get observedAttributes(): string[] { return [\"interval\"]; }\n\n private _core: TimerCore;\n private _trigger: boolean = false;\n private _connectedCallbackPromise: Promise<void> = Promise.resolve();\n // _scheduleStart のマイクロタスクが待っている間 true\n private _startPending = false;\n private _internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this._core = new TimerCore(this);\n this._internals = this._initInternals();\n this._wireStates({\n \"wcs-timer:running-changed\": (d) => ({ running: d === true }),\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 // SSR (§4.1/§4.4): the Shell exposes the Core's readiness so a server-side\n // renderer can await the connect-time probe before snapshotting. The timer has\n // no async probe (observe() resolves immediately), but the contract is uniform\n // across IO nodes.\n get connectedCallbackPromise(): Promise<void> {\n return this._connectedCallbackPromise;\n }\n\n // --- Attribute accessors ---\n //\n // Input setters never let setAttribute stringify null / undefined: `null`\n // removes the attribute (the documented default), `undefined` restores the\n // attribute the element started with (wc-bindable producer guidance P1;\n // React 19 and a direct assignment deliver it, @wcstack/state does not).\n // An `interval` write still goes through attributeChangedCallback, so a\n // running timer swaps to the restored / default period in place.\n\n get interval(): number {\n const attr = this.getAttribute(\"interval\");\n if (attr === null || attr.trim() === \"\") return 1000;\n // Strict parse via Number() (unlike parseInt, \"100px\" -> NaN, not 100),\n // matching <wcs-geo> / <wcs-debounce>. Fall back to the 1000ms default for any\n // invalid period — not only NaN but also 0 / negative values, which would\n // otherwise reach setInterval as a hot loop and break resume()'s modulo\n // arithmetic in the Core.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 1000;\n }\n\n set interval(value: number | null | undefined) {\n reflectAttribute(this, \"interval\", value);\n }\n\n get once(): boolean {\n return this.hasAttribute(\"once\");\n }\n\n set once(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"once\", value);\n }\n\n get repeat(): number {\n const attr = this.getAttribute(\"repeat\");\n if (attr === null || attr.trim() === \"\") return 0;\n // Strict parse via Number() (\"3px\" -> NaN, not 3), matching <wcs-geo> /\n // <wcs-debounce>. Normalise any non-positive / non-numeric value to 0\n // (= unlimited), mirroring the `interval` getter. Without this a negative\n // `repeat=\"-3\"` would leak through to start(); harmless today (Core treats\n // `_repeat <= 0` as unlimited) but the asymmetry is a trap.\n const parsed = Number(attr);\n return (Number.isFinite(parsed) && parsed > 0) ? parsed : 0;\n }\n\n set repeat(value: number | null | undefined) {\n reflectAttribute(this, \"repeat\", value);\n }\n\n get immediate(): boolean {\n return this.hasAttribute(\"immediate\");\n }\n\n set immediate(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"immediate\", value);\n }\n\n get manual(): boolean {\n return this.hasAttribute(\"manual\");\n }\n\n set manual(value: boolean | null | undefined) {\n reflectBooleanAttribute(this, \"manual\", value);\n }\n\n // --- Core delegated getters ---\n\n get tick(): number {\n return this._core.tick;\n }\n\n get elapsed(): number {\n return this._core.elapsed;\n }\n\n get running(): boolean {\n return this._core.running;\n }\n\n // --- Command property ---\n\n get trigger(): boolean {\n return this._trigger;\n }\n\n set trigger(value: boolean) {\n // Momentary command-property: a false→true write starts the timer. Mirrors\n // the trigger flag on <wcs-fetch> / <wcs-ws>. Prefer the command-token\n // protocol (`command.start: $command.tick`) for state-driven starts; this\n // exists mainly for the DOM click trigger and simple boolean bindings.\n const v = !!value;\n if (v) {\n this._trigger = true;\n this.start();\n this._trigger = false;\n // The `trigger-changed` event reports the momentary flag returning to\n // false, i.e. that the trigger property *changed* — it is deliberately not\n // gated on whether start() actually began a new run. This keeps the\n // wcBindable `trigger` property's change-notification semantics consistent\n // (every false→true write produces exactly one change-back event), even\n // when start() was a no-op because the timer was already running.\n this.dispatchEvent(new CustomEvent(\"wcs-timer:trigger-changed\", {\n detail: false,\n bubbles: true,\n }));\n }\n }\n\n // --- Commands ---\n\n start(): void {\n // `once` is sugar for \"fire exactly one tick\": map it to repeat=1, but let an\n // explicit repeat attribute win when both are present.\n const repeat = this.repeat > 0 ? this.repeat : (this.once ? 1 : 0);\n this._core.start({\n interval: this.interval,\n repeat,\n immediate: this.immediate,\n });\n }\n\n stop(): void {\n // 同じタスクで接続の後に止められたら、待っている自動開始も取り消す\n // (同期で start していた頃は、start → stop で止まったままだった)\n this._startPending = false;\n this._core.stop();\n }\n\n reset(): void {\n // reset も止める命令: 待っている自動開始を取り消す(stop と同じ)\n this._startPending = false;\n this._core.reset();\n }\n\n pause(): void {\n // 接続時の自動開始が待っているなら、ここでそのときの入力で判断してから止める。\n // 同期で start していた頃と同じく、append → pause() は resume() できる一時停止になる\n if (this._startPending) {\n this._startPending = false;\n if (this.isConnected && !this.manual) {\n this.start();\n }\n }\n this._core.pause();\n }\n\n resume(): void {\n this._core.resume();\n }\n\n // --- Lifecycle ---\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n // Live interval changes swap the underlying setInterval period in place.\n // `tick` / `elapsed` and the per-run `repeat` progress are preserved — we\n // deliberately do NOT stop()+start(), which would re-run start() and\n // re-evaluate per-run options (re-firing `immediate` and re-baselining\n // `repeat`). `running` alone gates this: swapping the period is orthogonal to\n // *how* the timer was started, so a `manual` timer the user has explicitly\n // started gets live period changes too. A non-running timer needs no swap —\n // its next start() picks up the new attribute as plain config.\n if (name === \"interval\" && oldValue !== newValue && this.isConnected && this.running) {\n this._core.changeInterval(this.interval);\n }\n }\n\n connectedCallback(): void {\n // upgrade 前に代入された input を取り込み直す(doc 13 §1.2 / Phase A1)\n upgradeProperties(this);\n this.style.display = \"none\";\n if (config.autoTrigger) {\n registerAutoTrigger();\n }\n // Establish monitoring (§3.5). observe() is a no-op that resolves once ready;\n // expose it as connectedCallbackPromise for SSR. (The auto-start below runs in a\n // microtask queued before any caller can await this promise, so it still\n // precedes the awaiter.)\n this._connectedCallbackPromise = this._core.observe();\n this._scheduleStart();\n }\n\n // 自動開始の判断はマイクロタスクで、そのときの manual / interval / repeat / once /\n // immediate で 1 回だけ行う(timing-and-firing-contract §23)。router は遷移で同じノードを\n // 入れ直し、新しいルートの params から state が入力を書くのはマイクロタスク — その場で\n // start すると、前の入力で動き出し(immediate なら前の入力で 1 tick 発火し)、manual も\n // 前のままで判断していた(docs/seam-apps.md、shift-desk)。その時点で外れていれば何もしない。\n private _scheduleStart(): void {\n if (this._startPending) return;\n this._startPending = true;\n queueMicrotask(() => {\n // stop() / reset() が取り消した(そのあと同じタスクで積み直されたら、それが判断する)\n if (!this._startPending) return;\n this._startPending = false;\n if (this.isConnected && !this.manual) {\n this.start();\n }\n });\n }\n\n disconnectedCallback(): void {\n // dispose() stops the timer and bumps the generation so a callback already\n // queued cannot fire onto a disconnected element (§3.5 / §4.4).\n this._core.dispose();\n }\n}\n","import { Timer } from \"./components/Timer.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.timer)) {\n registry.define(config.tagNames.timer, Timer);\n }\n}\n","import { setConfig } from \"./config.js\";\nimport { registerComponents } from \"./registerComponents.js\";\nimport { IWritableConfig } from \"./types.js\";\n\nexport function bootstrapTimer(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