@wcstack/state 4.10.0 → 4.11.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.
Files changed (54) hide show
  1. package/README.ja.md +27 -7
  2. package/README.md +28 -7
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/index.d.ts +5 -1
  6. package/dist/index.esm.js +1 -1
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/split/auto.js +1 -1
  9. package/dist/split/chunks/{chunk-JCQTA35B.js → chunk-AKTGQ6TC.js} +2 -2
  10. package/dist/split/chunks/chunk-CYMUD7KV.js +2 -0
  11. package/dist/split/chunks/chunk-CYMUD7KV.js.map +1 -0
  12. package/dist/split/chunks/chunk-E3XSBW55.js +2 -0
  13. package/dist/split/chunks/chunk-IYPAK7PO.js +2 -0
  14. package/dist/split/chunks/chunk-IYPAK7PO.js.map +1 -0
  15. package/dist/split/chunks/{chunk-FFXJVUTT.js → chunk-JJYM4JVZ.js} +2 -2
  16. package/dist/split/chunks/chunk-KBQKAD3I.js +2 -0
  17. package/dist/split/chunks/{chunk-PTFWXISY.js.map → chunk-KBQKAD3I.js.map} +1 -1
  18. package/dist/split/chunks/{chunk-SJRJALR4.js → chunk-LPJFTEVT.js} +2 -2
  19. package/dist/split/chunks/chunk-NAV7FBTI.js +2 -0
  20. package/dist/split/chunks/{chunk-MZVF2WEY.js.map → chunk-NAV7FBTI.js.map} +1 -1
  21. package/dist/split/chunks/{chunk-FT7OW7CG.js → chunk-R6RHIIR4.js} +2 -2
  22. package/dist/split/chunks/chunk-REB4RMZ3.js +2 -0
  23. package/dist/split/chunks/{chunk-65B2K2XD.js.map → chunk-REB4RMZ3.js.map} +1 -1
  24. package/dist/split/chunks/chunk-SJ552B3B.js +2 -0
  25. package/dist/split/chunks/{chunk-TB52U4QV.js.map → chunk-SJ552B3B.js.map} +1 -1
  26. package/dist/split/core.js +1 -1
  27. package/dist/split/features/devtools.js +1 -1
  28. package/dist/split/features/devtools.js.map +1 -1
  29. package/dist/split/features/diagnostics.js +1 -1
  30. package/dist/split/features/diagnostics.js.map +1 -1
  31. package/dist/split/features/formats.js +1 -1
  32. package/dist/split/features/list-keys.js +1 -1
  33. package/dist/split/features/native-commands.js +1 -1
  34. package/dist/split/features/recursion.js +1 -1
  35. package/dist/split/features/scopes.js +1 -1
  36. package/dist/split/features/scopes.js.map +1 -1
  37. package/dist/split/features/ssr.js +1 -1
  38. package/dist/split/features/ssr.js.map +1 -1
  39. package/dist/split/features/temporal.js +1 -1
  40. package/package.json +1 -1
  41. package/dist/split/chunks/chunk-65B2K2XD.js +0 -2
  42. package/dist/split/chunks/chunk-GU7IAIWW.js +0 -2
  43. package/dist/split/chunks/chunk-GU7IAIWW.js.map +0 -1
  44. package/dist/split/chunks/chunk-IWY3I2DG.js +0 -2
  45. package/dist/split/chunks/chunk-IWY3I2DG.js.map +0 -1
  46. package/dist/split/chunks/chunk-MZVF2WEY.js +0 -2
  47. package/dist/split/chunks/chunk-PTFWXISY.js +0 -2
  48. package/dist/split/chunks/chunk-TB52U4QV.js +0 -2
  49. package/dist/split/chunks/chunk-UE6JK2ZA.js +0 -2
  50. /package/dist/split/chunks/{chunk-JCQTA35B.js.map → chunk-AKTGQ6TC.js.map} +0 -0
  51. /package/dist/split/chunks/{chunk-UE6JK2ZA.js.map → chunk-E3XSBW55.js.map} +0 -0
  52. /package/dist/split/chunks/{chunk-FFXJVUTT.js.map → chunk-JJYM4JVZ.js.map} +0 -0
  53. /package/dist/split/chunks/{chunk-SJRJALR4.js.map → chunk-LPJFTEVT.js.map} +0 -0
  54. /package/dist/split/chunks/{chunk-FT7OW7CG.js.map → chunk-R6RHIIR4.js.map} +0 -0
@@ -1,2 +1,2 @@
1
- import{b as t,c as e,d as s}from"./chunk-65B2K2XD.js";import{p as i,q as n}from"./chunk-IWY3I2DG.js";import{f as o}from"./chunk-GU7IAIWW.js";import{a,b as r}from"./chunk-JCQTA35B.js";import{a as l,b as c}from"./chunk-UE6JK2ZA.js";import{a as h,h as u,i as d,k as m}from"./chunk-SJRJALR4.js";var f=0,p=new WeakMap;function b(t,e=t.getRootNode()){p.set(e,[...p.get(e)??[],t].filter((t,e,s)=>t.isConnected&&s.lastIndexOf(t)===e))}function g(t){let e=p.get(t)??[],s=e.filter(e=>e.getRootNode()===t);return Promise.any(s.map(t=>t.initializePromise.then(()=>t.V||t.connectedCallbackPromise))).then(()=>{},i=>s.length?p.get(t)!==e?g(t):Promise.reject(i.errors[0]):void 0)}var w=typeof HTMLElement>"u"?class{}:HTMLElement,y=class extends w{constructor(){super(),this.engine=null,this.Wn=!1,this.Ge=!1,this.K=null,this.Je=null,this.loaded=!1,this.un=null,this.connectedCallbackPromise=new Promise((t,e)=>{this.cn=t,this.Ro=e}),this.connectedCallbackPromise.catch(()=>{}),this.initializePromise=new Promise(t=>{this.an=t})}static{this.getBindingsReady=g}static{this.hasConnectedCallbackPromise=!0}connectedCallback(){if(this.Wn){if(null!==this.Je)return void this.Je.Qe();b(this);let e=this.engine;if(null!==e){let s=e.root;s===this.getRootNode()&&!i.has(s)&&i.set(s,e),t(),h.element?.(e,"back"),this.To("$connectedCallback",50,()=>{this.isConnected&&h.element?.(e,"connected")})}return}this.Wn=!0;let e=this.getRootNode(),s=h.dt?.(this,e);if(s)return this.Je=s,!s.Ao&&this.parentNode instanceof ShadowRoot&&b(this),void(void 0===s.St?this.Fo():s.St()).then(t=>(this.loaded=!0,s.start(t,()=>this.Oo()))).then(()=>{this.an(),this.cn()},t=>this.Rt(t,s.Ao));this.start(e),b(this)}disconnectedCallback(){if(null!==this.Je)return void this.Je.Mn();let t=this.engine;if(null===t)return;let e=t.root;i.get(e)===t&&i.delete(e),b(this,e),this.To("$disconnectedCallback",51),h.element?.(t,"disconnected")}setInitialState(t){if(this.Ge&&c(14),this.loaded)this.Je.reset(t);else if(null===this.engine)if(null!==this.un){let e=this.un;this.un=null,e(t)}else this.K=t;else this.engine.reset(t)}createState(t,e){let s=this.engine;null===s&&c(15),"readonly"===t&&s.Be++;try{e(s.proxy)}finally{"readonly"===t&&s.Be--}}async createStateAsync(t,e){let s=this.engine;null===s&&c(15),await e("writable"===t?s.proxy:new Proxy(s.proxy,{get(t,e,s){let i=Reflect.get(t,e,s);return"$setAll"===e||"$resolve"===e?(...t)=>(t.length>2&&c(8),i(...t)):i},set(){c(8)}}))}async Fo(){await 0;let t=this.getAttribute("state");if(null!==t){let e=e=>[...e.querySelectorAll('script[type="application/json"]')].find(e=>e.id===t),s=e(this.getRootNode())??e(document);return void 0===s?Promise.reject(new Error(`[@wcstack/state] ${l(16,[t])}`)):Promise.resolve(JSON.parse(s.textContent||"{}"))}let e=this.getAttribute("src");if(null!==e)return async function(t){let e=new URL(t,document.baseURI).href;if(/\.json(?:[?#]|$)/.test(e)){let s=await fetch(e);return s.ok||c(13,[t,s.status]),await s.json()}return(await(import(globalThis[Symbol.for("wcstack.ssr.resolveModule")]?.(e)??e))).default??{}}(e);let s=this.getAttribute("json");if(null!==s)return Promise.resolve(JSON.parse(s));let i=this.querySelector('script[type="module"]');return null!==i?async function(t){let e=!1,s=t=>{t.effectiveDirective.startsWith("script-src")&&(e=!0)};document.addEventListener("securitypolicyviolation",s);let i="function"==typeof URL.createObjectURL,n=i?URL.createObjectURL(new Blob([t.text],{type:"application/javascript"})):"data:text/javascript;charset=utf-8,"+encodeURIComponent(`${t.text}\n//${++f}`);try{return(await(import(n))).default??{}}catch(t){throw await new Promise(t=>setTimeout(t)),new Error(`[@wcstack/state] ${e?l(42):l(43,[t instanceof Error?t.message:String(t)])}`,{cause:t})}finally{document.removeEventListener("securitypolicyviolation",s),i&&URL.revokeObjectURL(n)}}(i):null!==this.K?Promise.resolve(this.K):new Promise(t=>{this.un=t})}async start(e){try{let a=e.host;(this.hasAttribute("mount")||this.hasAttribute("bind-component")||a?.hasAttribute("data-wc-definition"))&&d("scopes","<wcs-state>");let r=await this.Fo(),l=u(r);if(l&&await l,this.getRootNode()!==e)return this.K=r,this.Wn=!1,void(this.isConnected&&this.connectedCallback());this.hasAttribute("enable-ssr")&&d("ssr","enable-ssr");let m=i.get(e)?.element;m?.isConnected&&(m.V||m.Je)&&c(47);let f=new o(r,new s);f.element=this,this.engine=f,h.element?.(f,"mounting"),n(f,e),t(),f.Pn(),this.Oo(),await f.$e("$connectedCallback"),this.isConnected&&h.element?.(f,"connected"),this.cn()}catch(t){this.Ge=!this.V,this.Rt(t)}}Oo(){this.V=!0,this.an()}Rt(t,e){this.Ye(this.V?50:49,t),this.an(),e?this.cn():this.Ro(t)}Ye(t,e){let s=["mount","bind-component","state","src"].flatMap(t=>this.hasAttribute(t)?[t,this.getAttribute(t)]:[]);m(e,`[@wcstack/state] ${l(t,[this.localName,...s])}`)}To(t,e,s){(async()=>this.engine.$e(t))().then(s,t=>this.Ye(e,t))}},k=[];function v(){return(k=k.filter(t=>t.deref())).map(t=>t.deref())}function R(t,s){t&&r(t),function(t=customElements){e(),v().includes(t)||k.push(new WeakRef(t));let s=a.tagNames.state;void 0===t.get(s)&&t.define(s,class extends y{}),h.Co?.(t)}(s)}var C=t=>g(t);export{g as a,w as b,v as c,R as d,C as e};
2
- //# sourceMappingURL=chunk-FT7OW7CG.js.map
1
+ import{b as t,c as e,d as s}from"./chunk-REB4RMZ3.js";import{o as i,p as n}from"./chunk-CYMUD7KV.js";import{f as o}from"./chunk-IYPAK7PO.js";import{a,b as r}from"./chunk-AKTGQ6TC.js";import{a as l,b as c}from"./chunk-E3XSBW55.js";import{a as h,h as u,i as d,k as m}from"./chunk-LPJFTEVT.js";var f=0,p=new WeakMap;function b(t,e=t.getRootNode()){p.set(e,[...p.get(e)??[],t].filter((t,e,s)=>t.isConnected&&s.lastIndexOf(t)===e))}function g(t){let e=p.get(t)??[],s=e.filter(e=>e.getRootNode()===t);return Promise.any(s.map(t=>t.initializePromise.then(()=>t.U||t.connectedCallbackPromise))).then(()=>{},i=>s.length?p.get(t)!==e?g(t):Promise.reject(i.errors[0]):void 0)}var w=typeof HTMLElement>"u"?class{}:HTMLElement,y=class extends w{constructor(){super(),this.engine=null,this.Wn=!1,this.Ge=!1,this.z=null,this.Je=null,this.loaded=!1,this.dn=null,this.connectedCallbackPromise=new Promise((t,e)=>{this.un=t,this.To=e}),this.connectedCallbackPromise.catch(()=>{}),this.initializePromise=new Promise(t=>{this.cn=t})}static{this.getBindingsReady=g}static{this.hasConnectedCallbackPromise=!0}connectedCallback(){if(this.Wn){if(null!==this.Je)return void this.Je.Qe();b(this);let e=this.engine;if(null!==e){let s=e.root;s===this.getRootNode()&&!i.has(s)&&i.set(s,e),t(),h.element?.(e,"back"),this.Ao("$connectedCallback",50,()=>{this.isConnected&&h.element?.(e,"connected")})}return}this.Wn=!0;let e=this.getRootNode(),s=h.ft?.(this,e);if(s)return this.Je=s,!s.Fo&&this.parentNode instanceof ShadowRoot&&b(this),void(void 0===s.$t?this.Oo():s.$t()).then(t=>(this.loaded=!0,s.start(t,()=>this.Co()))).then(()=>{this.cn(),this.un()},t=>this.Tt(t,s.Fo));this.start(e),b(this)}disconnectedCallback(){if(null!==this.Je)return void this.Je.Mn();let t=this.engine;if(null===t)return;let e=t.root;i.get(e)===t&&i.delete(e),b(this,e),this.Ao("$disconnectedCallback",51),h.element?.(t,"disconnected")}setInitialState(t){if(this.Ge&&c(14),this.loaded)this.Je.reset(t);else if(null===this.engine)if(null!==this.dn){let e=this.dn;this.dn=null,e(t)}else this.z=t;else this.engine.reset(t)}createState(t,e){let s=this.engine;null===s&&c(15),"readonly"===t&&s.Be++;try{e(s.proxy)}finally{"readonly"===t&&s.Be--}}async createStateAsync(t,e){let s=this.engine;null===s&&c(15),await e("writable"===t?s.proxy:new Proxy(s.proxy,{get(t,e,s){let i=Reflect.get(t,e,s);return"$setAll"===e||"$resolve"===e?(...t)=>(t.length>2&&c(8),i(...t)):i},set(){c(8)}}))}async Oo(){await 0;let t=this.getAttribute("state");if(null!==t){let e=e=>[...e.querySelectorAll('script[type="application/json"]')].find(e=>e.id===t),s=e(this.getRootNode())??e(document);return void 0===s?Promise.reject(new Error(`[@wcstack/state] ${l(16,[t])}`)):Promise.resolve(JSON.parse(s.textContent||"{}"))}let e=this.getAttribute("src");if(null!==e)return async function(t){let e=new URL(t,document.baseURI).href;if(/\.json(?:[?#]|$)/.test(e)){let s=await fetch(e);return s.ok||c(13,[t,s.status]),await s.json()}return(await(import(globalThis[Symbol.for("wcstack.ssr.resolveModule")]?.(e)??e))).default??{}}(e);let s=this.getAttribute("json");if(null!==s)return Promise.resolve(JSON.parse(s));let i=this.querySelector('script[type="module"]');return null!==i?async function(t){let e=!1,s=t=>{t.effectiveDirective.startsWith("script-src")&&(e=!0)};document.addEventListener("securitypolicyviolation",s);let i="function"==typeof URL.createObjectURL,n=i?URL.createObjectURL(new Blob([t.text],{type:"application/javascript"})):"data:text/javascript;charset=utf-8,"+encodeURIComponent(`${t.text}\n//${++f}`);try{return(await(import(n))).default??{}}catch(t){throw await new Promise(t=>setTimeout(t)),new Error(`[@wcstack/state] ${e?l(42):l(43,[t instanceof Error?t.message:String(t)])}`,{cause:t})}finally{document.removeEventListener("securitypolicyviolation",s),i&&URL.revokeObjectURL(n)}}(i):null!==this.z?Promise.resolve(this.z):new Promise(t=>{this.dn=t})}async start(e){try{let a=e.host;(this.hasAttribute("mount")||this.hasAttribute("bind-component")||a?.hasAttribute("data-wc-definition"))&&d("scopes","<wcs-state>");let r=await this.Oo(),l=u(r);if(l&&await l,this.getRootNode()!==e)return this.z=r,this.Wn=!1,void(this.isConnected&&this.connectedCallback());this.hasAttribute("enable-ssr")&&d("ssr","enable-ssr");let m=i.get(e)?.element;m?.isConnected&&(m.U||m.Je)&&c(47);let f=new o(r,new s);f.element=this,this.engine=f,h.element?.(f,"mounting"),n(f,e),t(),f.Pn(),this.Co(),await f.xe("$connectedCallback"),this.isConnected&&h.element?.(f,"connected"),this.un()}catch(t){this.Ge=!this.U,this.Tt(t)}}Co(){this.U=!0,this.cn()}Tt(t,e){this.Ye(this.U?50:49,t),this.cn(),e?this.un():this.To(t)}Ye(t,e){let s=["mount","bind-component","state","src"].flatMap(t=>this.hasAttribute(t)?[t,this.getAttribute(t)]:[]);m(e,`[@wcstack/state] ${l(t,[this.localName,...s])}`)}Ao(t,e,s){(async()=>this.engine.xe(t))().then(s,t=>this.Ye(e,t))}},k=[];function v(){return(k=k.filter(t=>t.deref())).map(t=>t.deref())}function C(t,s){t&&r(t),function(t=customElements){e(),v().includes(t)||k.push(new WeakRef(t));let s=a.tagNames.state;void 0===t.get(s)&&t.define(s,class extends y{}),h.Io?.(t)}(s)}var P=t=>g(t);export{g as a,w as b,v as c,C as d,P as e};
2
+ //# sourceMappingURL=chunk-R6RHIIR4.js.map
@@ -0,0 +1,2 @@
1
+ import{o as e,q as n}from"./chunk-CYMUD7KV.js";import{a as t,b as l,c as r}from"./chunk-NAV7FBTI.js";import{a as o}from"./chunk-LPJFTEVT.js";var i=Symbol.for("wcstack.binder"),u=Symbol.for("wcstack.binder.pending"),s=Symbol.for("wcstack.binder.taken");var a=new Map;function f(t,l){if(1!==t.nodeType||!t.isConnected)return;let r=e.get(t.getRootNode());void 0===r||!1===r.element?.isConnected?a.set(t,l):n(r,t,l?.range)}function c(){let e=[...a];a.clear();for(let[n,t]of e)f(n,t);!function(){let e=function(){let e=globalThis[i];return null==e||"wcs-binder"!==e.protocol||"number"!=typeof e.version||e.version<1||"function"!=typeof e.bind?null:e}();if(null===e)return;let n=function(){let e=globalThis,n=e[u];return void 0===n&&(n=[],e[u]=n),n}();if(0===n.length)return;let t=n.splice(0,n.length),l=function(){let e=globalThis,n=e[s];return void 0===n&&(n=new WeakSet,e[s]=n),n}();for(let n of t)l.add(n),e.bind(n)}()}function d(){let e=globalThis;void 0===e[i]&&(e[i]={protocol:"wcs-binder",version:1,bind:f})}var b=class{constructor(){this.name="dirty",this.ee=(e,n)=>{if(0===e.n){let n=e.G;return n!==t&&n!==l&&(e.G=l,!0)}let r=null===n?null:n.kt;if(null===r)return!1;let o=r[e.O];return o!==t&&o!==l&&(r[e.O]=l,!0)}}tr(e,n,t){null!==n.getter&&this.ee(n,t),e.Rt(n,t),e.Tn(n,t,this.ee)}zo(e,n){let t=n.l.o.Wt;if(null!==t)for(let l of t)l.n===n.l.n?e.ct(l,n,this.ee):e.tn(n,l,n=>e.ct(l,n,this.ee))}Ee(e,n,t){this.ee(n,t),o.Ne?.(e,n,t),e.Rt(n,t),e.Tn(n,t,this.ee)}Yo(e,n,o){let i=0===n.n;if(!i&&null===o)return;let u=i?null:o.kt??=new Array(e.Le).fill(t),s=null===u?n.G:u[n.O];if(s!==t&&s!==l&&s!==r&&(null===u||n.O in u))return s;s=r;try{return s=e.Go(n,null===u?null:o)}finally{null===u?n.G=s:u[n.O]=s}}Jt(e){e.kt=null}nt(e){for(let n of e.C.all())null!==n.getter&&(0===n.n?n.G===l&&(n.G=r):e.on(n.h[n.n],e=>{let t=e.kt;null!==t&&t[n.O]===l&&(t[n.O]=r)}))}};export{f as a,c as b,d as c,b as d};
2
+ //# sourceMappingURL=chunk-REB4RMZ3.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["BINDER_KEY","Symbol","for","PENDING_KEY","TAKEN_KEY","early","Map","bind","subtree","options","nodeType","isConnected","engine","engines","get","getRootNode","element","set","mountSubtree","range","drainBinds","waiting","clear","binder","candidate","globalThis","protocol","version","getBinder","queue","globals","pendingQueue","length","pending","splice","taken","WeakSet","takenSet","add","flushPendingBinds","installBinder","slot","DirtyStrategy","constructor","this","name","mark","g","row","depth","v","rootValue","UNSET","DIRTY","c","cache","onWrite","p","getter","enqueueBound","walkDependents","onIndexChange","watchers","list","pattern","indexWatchers","visitGetter","forRowsUnder","r","invalidate","hooks","getterReached","readGetter","root","Array","slotCount","fill","FAILED","evalGetter","resetRow","dropped","patterns","all","forAllRows","lists","E","W","h"],"sources":["../../../src/protocol/binder.ts","../../../src/dom/binder.ts","../../../src/strategy/dirty.ts"],"sourcesContent":["// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/binder.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// binder protocol — how a package that inserts DOM hands those nodes to whoever\n// owns data bindings on the page.\n//\n// The dual of transition-runner: that one hands a *mutation* to whoever animates\n// it, this one hands *new nodes* to whoever binds them.\n//\n// A `data-wcs` binding exists only for nodes @wcstack/state walked when it built\n// its bindings. Nodes that arrive later — the content of a route that was not\n// active at that moment, a <wcs-head> child reflected into <head> — were never\n// walked, so their bindings silently do nothing, however often they are inserted.\n// @wcstack/router must not depend on @wcstack/state (zero runtime dependencies,\n// independently publishable), so state installs a binder on a well-known global\n// symbol and inserters look it up lazily.\n//\n// No binder installed means nothing happens — byte-for-byte the behavior these\n// packages had before the protocol existed.\n//\n// docs/binder-protocol-design.md is the normative description.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/binder.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/binder.ts). Those copies are generated — do not edit them.\n\n/**\n * Global key the binder installs itself under. `Symbol.for` so independently\n * loaded copies of this file (two CDN bundles on one page) still agree.\n */\nexport const BINDER_KEY = Symbol.for(\"wcstack.binder\");\n\n/**\n * What the caller declares about a subtree it hands over (the second argument of `bind`; additive\n * since version 1 — a binder that predates it ignores it, and leaving it out keeps the old contract).\n */\nexport interface IWcsBindOptions {\n /**\n * The caller carries the range the subtree sits in: on removal it takes everything from its own\n * start mark up to its end mark along — what the binder rendered beside the subtree included, as\n * the rows a structural template handed over at the top of the content renders before its anchor —\n * and puts it all back on reinsertion. Only with this may a binder render such a template: without\n * it, what the binder rendered beside the subtree would be left behind, so @wcstack/state 4.0\n * refuses one (#204). @wcstack/state 3.x ignores the option and renders no structural template\n * handed over itself, with or without it (docs/binder-protocol-design.md §2, §9-5, §9-6).\n */\n readonly range?: boolean;\n}\n\nexport interface IWcsBinder {\n readonly protocol: \"wcs-binder\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /**\n * Take a subtree that has just entered the document and bind whatever\n * declarations it carries.\n *\n * Contract (docs/binder-protocol-design.md §2):\n * - Synchronous. Initial values are applied before this returns, so the\n * caller never shows one frame of unbound markup.\n * - Idempotent. A subtree that is already bound is left alone, so a caller\n * may hand over the same nodes on every insertion without tracking which\n * ones are new.\n * - Binding survives later relocation, so this need not be called again when\n * the same nodes are moved (measured: design doc §8-3).\n * - Never throws for markup reasons; a subtree with no declarations is a\n * no-op.\n * - `options` (optional) is what the caller declares about the subtree\n * ({@link IWcsBindOptions}).\n */\n bind(subtree: Node, options?: IWcsBindOptions): void;\n}\n\n/**\n * The installed binder, or null when there is none or it speaks a version this\n * reader does not.\n *\n * Looked up on every call rather than cached, for the same reason\n * transition-runner does: the page's composition can change at any point, and a\n * stale cache would keep calling into a binder that is no longer there.\n */\nexport function getBinder(): IWcsBinder | null {\n const candidate = (globalThis as Record<symbol, unknown>)[BINDER_KEY] as IWcsBinder | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-binder\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.bind !== \"function\") return null;\n return candidate;\n}\n\n/**\n * Subtrees offered before a binder existed, and the set of everything a binder\n * has taken. Both live on global symbols so that independently loaded copies of\n * this file — the router's and state's — share one queue.\n *\n * The queue is needed because of load order: the router's auto bundle runs\n * before state's, so `<wcs-head>` reflects its children into `<head>` while\n * there is still nothing to bind them. Offering them to a binder that arrives\n * later is the difference between working and silently blank.\n */\nconst PENDING_KEY = Symbol.for(\"wcstack.binder.pending\");\nconst TAKEN_KEY = Symbol.for(\"wcstack.binder.taken\");\n\nfunction pendingQueue(): Node[] {\n const globals = globalThis as Record<symbol, unknown>;\n let queue = globals[PENDING_KEY] as Node[] | undefined;\n if (queue === undefined) {\n queue = [];\n globals[PENDING_KEY] = queue;\n }\n return queue;\n}\n\nfunction takenSet(): WeakSet<Node> {\n const globals = globalThis as Record<symbol, unknown>;\n let taken = globals[TAKEN_KEY] as WeakSet<Node> | undefined;\n if (taken === undefined) {\n taken = new WeakSet<Node>();\n globals[TAKEN_KEY] = taken;\n }\n return taken;\n}\n\n/**\n * Hand `subtree` to the installed binder, or hold it for one that arrives later.\n *\n * Returns whether a binder took it *now*. A `false` does not yet mean the markup\n * is doomed — check {@link wasBoundBy} once module scripts have run.\n *\n * `options` goes to the binder with the subtree. A subtree held for a later binder\n * is handed over without it: that binder's first walk of the page binds what is\n * still in place there.\n */\nexport function bindSubtree(subtree: Node, options?: IWcsBindOptions): boolean {\n const binder = getBinder();\n if (binder === null) {\n pendingQueue().push(subtree);\n return false;\n }\n takenSet().add(subtree);\n binder.bind(subtree, options);\n return true;\n}\n\n/** Whether any binder has taken this subtree. */\nexport function wasBoundBy(subtree: Node): boolean {\n return takenSet().has(subtree);\n}\n\n/**\n * Bind everything offered before this binder existed. Called by the binder right\n * after it installs itself.\n */\nexport function flushPendingBinds(): void {\n const binder = getBinder();\n if (binder === null) return;\n const queue = pendingQueue();\n if (queue.length === 0) return;\n const pending = queue.splice(0, queue.length);\n const taken = takenSet();\n for (const subtree of pending) {\n taken.add(subtree);\n binder.bind(subtree);\n }\n}\n","import { BINDER_KEY, flushPendingBinds, type IWcsBinder, type IWcsBindOptions } from \"../protocol/binder\";\nimport { engines, mountSubtree } from \"./mount\";\n\n/**\n * The binder protocol's provider (docs/binder-protocol-design.md): a package that inserts\n * DOM after the mount — the router's route content, `<wcs-head>`'s clones in <head> —\n * hands the subtree over, and it is bound to the engine of its root, synchronously.\n * Only what is handed over is bound (no scan of every insertion), and binding twice is a\n * no-op, so the router may hand the same nodes over on every insertion.\n */\n\n/**\n * Subtrees handed over before their root's engine finished its first mount, or while it was out of the\n * page, with what the caller declared (a range: a route's top-level template is rendered then).\n */\nconst early = new Map<Element, IWcsBindOptions | undefined>();\n\nexport function bind(subtree: Node, options?: IWcsBindOptions): void {\n // not in a document (it left, or was replaced, as a chain's `else:` template by its anchor): nothing to bind\n if (subtree.nodeType !== 1 || !subtree.isConnected) return;\n // (a root taken out of the page lets go of its root node: it binds what waited here when it is back.\n // A component's, whose <wcs-state> alone left, is still registered: not one to bind to either)\n const engine = engines.get(subtree.getRootNode());\n // (once each: the router hands the same nodes over on every insertion. One handed over early is\n // walked by the first mount where it is: the declaration is not needed then)\n if (engine === undefined || (engine.element as Node | null)?.isConnected === false) early.set(subtree as Element, options);\n else mountSubtree(engine, subtree as Element, options?.range);\n}\n\n/**\n * After an engine's first mount, and when a root is back in the page: binds what was handed over\n * too early — to this binder before the mount or while the root was out, or (queued by the\n * protocol) before any binder existed.\n */\nexport function drainBinds(): void {\n // (one that left the document meanwhile is dropped: handed over again if it comes back)\n const waiting = [...early];\n early.clear();\n for (const [subtree, options] of waiting) bind(subtree, options);\n flushPendingBinds();\n}\n\n/** Installs the binder on the protocol's global slot, unless another copy already has it. */\nexport function installBinder(): void {\n const slot = globalThis as Record<symbol, unknown>;\n if (slot[BINDER_KEY] === undefined) slot[BINDER_KEY] = { protocol: \"wcs-binder\", version: 1, bind } satisfies IWcsBinder;\n}\n","import type { Engine } from \"../engine\";\nimport { DIRTY, FAILED, UNSET, type Pattern } from \"../pattern\";\nimport type { StateRow } from \"../list\";\nimport type { Strategy } from \"./types\";\nimport { hooks } from \"../hooks\";\n\n/**\n * Push invalidation: a write walks its dependents immediately, marks their caches\n * DIRTY and queues their bindings. A cache already DIRTY (or never computed) stops the\n * walk — whatever depends on it was reached when it was marked.\n */\nexport class DirtyStrategy implements Strategy {\n readonly name = \"dirty\";\n\n private readonly mark = (g: Pattern, row: StateRow | null): boolean => {\n // UNSET: nobody read it; DIRTY: already reached. FAILED was read (and threw): reach it.\n if (g.depth === 0) {\n const v = g.rootValue;\n if (v === UNSET || v === DIRTY) return false;\n g.rootValue = DIRTY;\n return true;\n }\n const c = row === null ? null : row.cache;\n if (c === null) return false;\n const v = c[g.slot];\n if (v === UNSET || v === DIRTY) return false;\n c[g.slot] = DIRTY;\n return true;\n };\n\n onWrite(engine: Engine, p: Pattern, row: StateRow | null): void {\n // a write through a getter's setter: the written occurrence itself is stale\n if (p.getter !== null) this.mark(p, row);\n engine.enqueueBound(p, row);\n engine.walkDependents(p, row, this.mark);\n }\n\n onIndexChange(engine: Engine, row: StateRow): void {\n const watchers = row.list.pattern.indexWatchers;\n if (watchers === null) return;\n for (const g of watchers) {\n // the row itself (a row getter reading its own index): no closure per moved row\n if (g.depth === row.list.depth) engine.visitGetter(g, row, this.mark);\n else engine.forRowsUnder(row, g, (r) => engine.visitGetter(g, r, this.mark));\n }\n }\n\n invalidate(engine: Engine, g: Pattern, row: StateRow | null): void {\n this.mark(g, row);\n hooks.getterReached?.(engine, g, row);\n engine.enqueueBound(g, row);\n engine.walkDependents(g, row, this.mark);\n }\n\n readGetter(engine: Engine, g: Pattern, row: StateRow | null): unknown {\n const root = g.depth === 0;\n if (!root && row === null) return undefined;\n const c = root ? null : (row!.cache ??= new Array(engine.slotCount).fill(UNSET));\n let v = c === null ? g.rootValue : c[g.slot];\n // a getter made after the row's cache (a recursive family, a mounted key, a binder's subtree) has\n // no entry yet — nor one whose slot lies before a later getter's written past the end (a hole)\n if (v !== UNSET && v !== DIRTY && v !== FAILED && (c === null || g.slot in c)) return v;\n v = FAILED;\n try {\n return (v = engine.evalGetter(g, c === null ? null : row));\n } finally {\n if (c === null) g.rootValue = v;\n else c[g.slot] = v;\n }\n }\n\n resetRow(row: StateRow): void {\n row.cache = null;\n }\n\n dropped(engine: Engine): void {\n // DIRTY says \"its readers were reached\", and they were dropped: FAILED is reached again\n for (const g of engine.patterns.all()) {\n if (g.getter === null) continue;\n if (g.depth === 0) {\n if (g.rootValue === DIRTY) g.rootValue = FAILED;\n } else {\n engine.forAllRows(g.lists[g.depth]!, (r) => {\n const c = r.cache;\n if (c !== null && c[g.slot] === DIRTY) c[g.slot] = FAILED;\n });\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["BINDER_KEY","Symbol","for","PENDING_KEY","TAKEN_KEY","early","Map","bind","subtree","options","nodeType","isConnected","engine","engines","get","getRootNode","element","set","mountSubtree","range","drainBinds","waiting","clear","binder","candidate","globalThis","protocol","version","getBinder","queue","globals","pendingQueue","length","pending","splice","taken","WeakSet","takenSet","add","flushPendingBinds","installBinder","slot","DirtyStrategy","constructor","this","name","mark","g","row","depth","v","rootValue","UNSET","DIRTY","c","cache","onWrite","p","getter","enqueueBound","walkDependents","onIndexChange","watchers","list","pattern","indexWatchers","visitGetter","forRowsUnder","r","invalidate","hooks","getterReached","readGetter","root","Array","slotCount","fill","FAILED","evalGetter","resetRow","dropped","patterns","all","forAllRows","lists","E","W","h"],"sources":["../../../src/protocol/binder.ts","../../../src/dom/binder.ts","../../../src/strategy/dirty.ts"],"sourcesContent":["// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/binder.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// binder protocol — how a package that inserts DOM hands those nodes to whoever\n// owns data bindings on the page.\n//\n// The dual of transition-runner: that one hands a *mutation* to whoever animates\n// it, this one hands *new nodes* to whoever binds them.\n//\n// A `data-wcs` binding exists only for nodes @wcstack/state walked when it built\n// its bindings. Nodes that arrive later — the content of a route that was not\n// active at that moment, a <wcs-head> child reflected into <head> — were never\n// walked, so their bindings silently do nothing, however often they are inserted.\n// @wcstack/router must not depend on @wcstack/state (zero runtime dependencies,\n// independently publishable), so state installs a binder on a well-known global\n// symbol and inserters look it up lazily.\n//\n// No binder installed means nothing happens — byte-for-byte the behavior these\n// packages had before the protocol existed.\n//\n// docs/binder-protocol-design.md is the normative description.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/binder.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/binder.ts). Those copies are generated — do not edit them.\n\n/**\n * Global key the binder installs itself under. `Symbol.for` so independently\n * loaded copies of this file (two CDN bundles on one page) still agree.\n */\nexport const BINDER_KEY = Symbol.for(\"wcstack.binder\");\n\n/**\n * What the caller declares about a subtree it hands over (the second argument of `bind`; additive\n * since version 1 — a binder that predates it ignores it, and leaving it out keeps the old contract).\n */\nexport interface IWcsBindOptions {\n /**\n * The caller carries the range the subtree sits in: on removal it takes everything from its own\n * start mark up to its end mark along — what the binder rendered beside the subtree included, as\n * the rows a structural template handed over at the top of the content renders before its anchor —\n * and puts it all back on reinsertion. Only with this may a binder render such a template: without\n * it, what the binder rendered beside the subtree would be left behind, so @wcstack/state 4.0\n * refuses one (#204). @wcstack/state 3.x ignores the option and renders no structural template\n * handed over itself, with or without it (docs/binder-protocol-design.md §2, §9-5, §9-6).\n */\n readonly range?: boolean;\n}\n\nexport interface IWcsBinder {\n readonly protocol: \"wcs-binder\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /**\n * Take a subtree that has just entered the document and bind whatever\n * declarations it carries.\n *\n * Contract (docs/binder-protocol-design.md §2):\n * - Synchronous. Initial values are applied before this returns, so the\n * caller never shows one frame of unbound markup.\n * - Idempotent. A subtree that is already bound is left alone, so a caller\n * may hand over the same nodes on every insertion without tracking which\n * ones are new.\n * - Binding survives later relocation, so this need not be called again when\n * the same nodes are moved (measured: design doc §8-3).\n * - Never throws for markup reasons; a subtree with no declarations is a\n * no-op.\n * - `options` (optional) is what the caller declares about the subtree\n * ({@link IWcsBindOptions}).\n */\n bind(subtree: Node, options?: IWcsBindOptions): void;\n}\n\n/**\n * The installed binder, or null when there is none or it speaks a version this\n * reader does not.\n *\n * Looked up on every call rather than cached, for the same reason\n * transition-runner does: the page's composition can change at any point, and a\n * stale cache would keep calling into a binder that is no longer there.\n */\nexport function getBinder(): IWcsBinder | null {\n const candidate = (globalThis as Record<symbol, unknown>)[BINDER_KEY] as IWcsBinder | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-binder\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.bind !== \"function\") return null;\n return candidate;\n}\n\n/**\n * Subtrees offered before a binder existed, and the set of everything a binder\n * has taken. Both live on global symbols so that independently loaded copies of\n * this file — the router's and state's — share one queue.\n *\n * The queue is needed because of load order: the router's auto bundle runs\n * before state's, so `<wcs-head>` reflects its children into `<head>` while\n * there is still nothing to bind them. Offering them to a binder that arrives\n * later is the difference between working and silently blank.\n */\nconst PENDING_KEY = Symbol.for(\"wcstack.binder.pending\");\nconst TAKEN_KEY = Symbol.for(\"wcstack.binder.taken\");\n\nfunction pendingQueue(): Node[] {\n const globals = globalThis as Record<symbol, unknown>;\n let queue = globals[PENDING_KEY] as Node[] | undefined;\n if (queue === undefined) {\n queue = [];\n globals[PENDING_KEY] = queue;\n }\n return queue;\n}\n\nfunction takenSet(): WeakSet<Node> {\n const globals = globalThis as Record<symbol, unknown>;\n let taken = globals[TAKEN_KEY] as WeakSet<Node> | undefined;\n if (taken === undefined) {\n taken = new WeakSet<Node>();\n globals[TAKEN_KEY] = taken;\n }\n return taken;\n}\n\n/**\n * Hand `subtree` to the installed binder, or hold it for one that arrives later.\n *\n * Returns whether a binder took it *now*. A `false` does not yet mean the markup\n * is doomed — check {@link wasBoundBy} once module scripts have run.\n *\n * `options` goes to the binder with the subtree. A subtree held for a later binder\n * is handed over without it: that binder's first walk of the page binds what is\n * still in place there.\n */\nexport function bindSubtree(subtree: Node, options?: IWcsBindOptions): boolean {\n const binder = getBinder();\n if (binder === null) {\n pendingQueue().push(subtree);\n return false;\n }\n takenSet().add(subtree);\n binder.bind(subtree, options);\n return true;\n}\n\n/** Whether any binder has taken this subtree. */\nexport function wasBoundBy(subtree: Node): boolean {\n return takenSet().has(subtree);\n}\n\n/**\n * Bind everything offered before this binder existed. Called by the binder right\n * after it installs itself.\n */\nexport function flushPendingBinds(): void {\n const binder = getBinder();\n if (binder === null) return;\n const queue = pendingQueue();\n if (queue.length === 0) return;\n const pending = queue.splice(0, queue.length);\n const taken = takenSet();\n for (const subtree of pending) {\n taken.add(subtree);\n binder.bind(subtree);\n }\n}\n","import { BINDER_KEY, flushPendingBinds, type IWcsBinder, type IWcsBindOptions } from \"../protocol/binder\";\nimport { engines, mountSubtree } from \"./mount\";\n\n/**\n * The binder protocol's provider (docs/binder-protocol-design.md): a package that inserts\n * DOM after the mount — the router's route content, `<wcs-head>`'s clones in <head> —\n * hands the subtree over, and it is bound to the engine of its root, synchronously.\n * Only what is handed over is bound (no scan of every insertion), and binding twice is a\n * no-op, so the router may hand the same nodes over on every insertion.\n */\n\n/**\n * Subtrees handed over before their root's engine finished its first mount, or while it was out of the\n * page, with what the caller declared (a range: a route's top-level template is rendered then).\n */\nconst early = new Map<Element, IWcsBindOptions | undefined>();\n\nexport function bind(subtree: Node, options?: IWcsBindOptions): void {\n // not in a document (it left, or was replaced, as a chain's `else:` template by its anchor): nothing to bind\n if (subtree.nodeType !== 1 || !subtree.isConnected) return;\n // (a root taken out of the page lets go of its root node: it binds what waited here when it is back.\n // A component's, whose <wcs-state> alone left, is still registered: not one to bind to either)\n const engine = engines.get(subtree.getRootNode());\n // (once each: the router hands the same nodes over on every insertion. One handed over early is\n // walked by the first mount where it is: the declaration is not needed then)\n if (engine === undefined || (engine.element as Node | null)?.isConnected === false) early.set(subtree as Element, options);\n else mountSubtree(engine, subtree as Element, options?.range);\n}\n\n/**\n * After an engine's first mount, and when a root is back in the page: binds what was handed over\n * too early — to this binder before the mount or while the root was out, or (queued by the\n * protocol) before any binder existed.\n */\nexport function drainBinds(): void {\n // (one that left the document meanwhile is dropped: handed over again if it comes back)\n const waiting = [...early];\n early.clear();\n for (const [subtree, options] of waiting) bind(subtree, options);\n flushPendingBinds();\n}\n\n/** Installs the binder on the protocol's global slot, unless another copy already has it. */\nexport function installBinder(): void {\n const slot = globalThis as Record<symbol, unknown>;\n if (slot[BINDER_KEY] === undefined) slot[BINDER_KEY] = { protocol: \"wcs-binder\", version: 1, bind } satisfies IWcsBinder;\n}\n","import type { Engine } from \"../engine\";\nimport { DIRTY, FAILED, UNSET, type Pattern } from \"../pattern\";\nimport type { StateRow } from \"../list\";\nimport type { Strategy } from \"./types\";\nimport { hooks } from \"../hooks\";\n\n/**\n * Push invalidation: a write walks its dependents immediately, marks their caches\n * DIRTY and queues their bindings. A cache already DIRTY (or never computed) stops the\n * walk — whatever depends on it was reached when it was marked.\n */\nexport class DirtyStrategy implements Strategy {\n readonly name = \"dirty\";\n\n private readonly mark = (g: Pattern, row: StateRow | null): boolean => {\n // UNSET: nobody read it; DIRTY: already reached. FAILED was read (and threw): reach it.\n if (g.depth === 0) {\n const v = g.rootValue;\n if (v === UNSET || v === DIRTY) return false;\n g.rootValue = DIRTY;\n return true;\n }\n const c = row === null ? null : row.cache;\n if (c === null) return false;\n const v = c[g.slot];\n if (v === UNSET || v === DIRTY) return false;\n c[g.slot] = DIRTY;\n return true;\n };\n\n onWrite(engine: Engine, p: Pattern, row: StateRow | null): void {\n // a write through a getter's setter: the written occurrence itself is stale\n if (p.getter !== null) this.mark(p, row);\n engine.enqueueBound(p, row);\n engine.walkDependents(p, row, this.mark);\n }\n\n onIndexChange(engine: Engine, row: StateRow): void {\n const watchers = row.list.pattern.indexWatchers;\n if (watchers === null) return;\n for (const g of watchers) {\n // the row itself (a row getter reading its own index): no closure per moved row\n if (g.depth === row.list.depth) engine.visitGetter(g, row, this.mark);\n else engine.forRowsUnder(row, g, (r) => engine.visitGetter(g, r, this.mark));\n }\n }\n\n invalidate(engine: Engine, g: Pattern, row: StateRow | null): void {\n this.mark(g, row);\n hooks.getterReached?.(engine, g, row);\n engine.enqueueBound(g, row);\n engine.walkDependents(g, row, this.mark);\n }\n\n readGetter(engine: Engine, g: Pattern, row: StateRow | null): unknown {\n const root = g.depth === 0;\n if (!root && row === null) return undefined;\n const c = root ? null : (row!.cache ??= new Array(engine.slotCount).fill(UNSET));\n let v = c === null ? g.rootValue : c[g.slot];\n // a getter made after the row's cache (a recursive family, a mounted key, a binder's subtree) has\n // no entry yet — nor one whose slot lies before a later getter's written past the end (a hole)\n if (v !== UNSET && v !== DIRTY && v !== FAILED && (c === null || g.slot in c)) return v;\n v = FAILED;\n try {\n return (v = engine.evalGetter(g, c === null ? null : row));\n } finally {\n if (c === null) g.rootValue = v;\n else c[g.slot] = v;\n }\n }\n\n resetRow(row: StateRow): void {\n row.cache = null;\n }\n\n dropped(engine: Engine): void {\n // DIRTY says \"its readers were reached\", and they were dropped: FAILED is reached again\n for (const g of engine.patterns.all()) {\n if (g.getter === null) continue;\n if (g.depth === 0) {\n if (g.rootValue === DIRTY) g.rootValue = FAILED;\n } else {\n engine.forAllRows(g.lists[g.depth]!, (r) => {\n const c = r.cache;\n if (c !== null && c[g.slot] === DIRTY) c[g.slot] = FAILED;\n });\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ var a="4.11.0";export{a};
2
+ //# sourceMappingURL=chunk-SJ552B3B.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION","r"],"sources":["../../../package.json","../../../src/version.ts"],"sourcesContent":["{\n \"name\": \"@wcstack/state\",\n \"version\": \"4.10.0\",\n \"description\": \"Reactive state management with declarative data binding for Web Components. Zero dependencies, buildless.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.esm.js\",\n \"module\": \"./dist/index.esm.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.esm.js\"\n },\n \"./auto\": {\n \"types\": \"./dist/auto.d.ts\",\n \"import\": \"./dist/auto.min.js\"\n },\n \"./core\": {\n \"types\": \"./dist/split/core.d.ts\",\n \"import\": \"./dist/split/core.js\"\n },\n \"./features/*\": {\n \"types\": \"./dist/split/features/*.d.ts\",\n \"import\": \"./dist/split/features/*.js\"\n },\n \"./define\": {\n \"types\": \"./dist/define.d.ts\",\n \"import\": \"./dist/define.js\"\n },\n \"./manifest\": {\n \"types\": \"./dist/manifest.d.ts\",\n \"import\": \"./dist/manifest.esm.js\"\n },\n \"./parser\": {\n \"types\": \"./dist/parser.d.ts\",\n \"import\": \"./dist/parser.esm.js\"\n },\n \"./wcs-manifest.json\": \"./dist/wcs-manifest.json\"\n },\n \"files\": [\n \"dist\",\n \"!dist/core.min.js\"\n ],\n \"scripts\": {\n \"clean\": \"node -e \\\"require('node:fs').rmSync('dist', { recursive: true, force: true })\\\"\",\n \"build\": \"node build.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\",\n \"golden\": \"node scripts/golden.mjs\",\n \"version:patch\": \"npm version patch\",\n \"version:minor\": \"npm version minor\",\n \"version:major\": \"npm version major\",\n \"prepublishOnly\": \"npm run build && npm run test:coverage\"\n },\n \"keywords\": [\n \"web-components\",\n \"state-management\",\n \"reactive\",\n \"data-binding\",\n \"proxy\",\n \"custom-elements\",\n \"shadow-dom\",\n \"buildless\",\n \"zero-dependencies\",\n \"declarative\"\n ],\n \"author\": \"mogera551\",\n \"homepage\": \"https://wcstack.github.io\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/wcstack/wcstack.git\",\n \"directory\": \"packages/state\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/wcstack/wcstack/issues\"\n },\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.5\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"esbuild\": \"0.27.2\",\n \"eslint\": \"^9.39.5\",\n \"globals\": \"^16.5.0\",\n \"happy-dom\": \"^20.0.11\",\n \"rollup\": \"^4.63.5\",\n \"rollup-plugin-dts\": \"^6.5.1\",\n \"terser\": \"^5.51.2\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.70.1\",\n \"vitest\": \"^4.0.15\"\n }\n}\n","import pkg from \"../package.json\" with { type: \"json\" };\n\n/** The package version: stamped into `<wcs-ssr>`, compared on hydration (major.minor), shown by DevTools. */\nexport const VERSION: string = pkg.version;\n"],"mappings":"AAAA,ICGaA,EDDA,gBCCsBC","ignoreList":[]}
1
+ {"version":3,"names":["VERSION","r"],"sources":["../../../package.json","../../../src/version.ts"],"sourcesContent":["{\n \"name\": \"@wcstack/state\",\n \"version\": \"4.11.0\",\n \"description\": \"Reactive state management with declarative data binding for Web Components. Zero dependencies, buildless.\",\n \"type\": \"module\",\n \"main\": \"./dist/index.esm.js\",\n \"module\": \"./dist/index.esm.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.esm.js\"\n },\n \"./auto\": {\n \"types\": \"./dist/auto.d.ts\",\n \"import\": \"./dist/auto.min.js\"\n },\n \"./core\": {\n \"types\": \"./dist/split/core.d.ts\",\n \"import\": \"./dist/split/core.js\"\n },\n \"./features/*\": {\n \"types\": \"./dist/split/features/*.d.ts\",\n \"import\": \"./dist/split/features/*.js\"\n },\n \"./define\": {\n \"types\": \"./dist/define.d.ts\",\n \"import\": \"./dist/define.js\"\n },\n \"./manifest\": {\n \"types\": \"./dist/manifest.d.ts\",\n \"import\": \"./dist/manifest.esm.js\"\n },\n \"./parser\": {\n \"types\": \"./dist/parser.d.ts\",\n \"import\": \"./dist/parser.esm.js\"\n },\n \"./wcs-manifest.json\": \"./dist/wcs-manifest.json\"\n },\n \"files\": [\n \"dist\",\n \"!dist/core.min.js\"\n ],\n \"scripts\": {\n \"clean\": \"node -e \\\"require('node:fs').rmSync('dist', { recursive: true, force: true })\\\"\",\n \"build\": \"node build.mjs\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"lint\": \"eslint src\",\n \"typecheck\": \"tsc --noEmit\",\n \"golden\": \"node scripts/golden.mjs\",\n \"version:patch\": \"npm version patch\",\n \"version:minor\": \"npm version minor\",\n \"version:major\": \"npm version major\",\n \"prepublishOnly\": \"npm run build && npm run test:coverage\"\n },\n \"keywords\": [\n \"web-components\",\n \"state-management\",\n \"reactive\",\n \"data-binding\",\n \"proxy\",\n \"custom-elements\",\n \"shadow-dom\",\n \"buildless\",\n \"zero-dependencies\",\n \"declarative\"\n ],\n \"author\": \"mogera551\",\n \"homepage\": \"https://wcstack.github.io\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/wcstack/wcstack.git\",\n \"directory\": \"packages/state\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/wcstack/wcstack/issues\"\n },\n \"license\": \"MIT\",\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.5\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"esbuild\": \"0.27.2\",\n \"eslint\": \"^9.39.5\",\n \"globals\": \"^16.5.0\",\n \"happy-dom\": \"^20.0.11\",\n \"rollup\": \"^4.63.5\",\n \"rollup-plugin-dts\": \"^6.5.1\",\n \"terser\": \"^5.51.2\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.70.1\",\n \"vitest\": \"^4.0.15\"\n }\n}\n","import pkg from \"../package.json\" with { type: \"json\" };\n\n/** The package version: stamped into `<wcs-ssr>`, compared on hydration (major.minor), shown by DevTools. */\nexport const VERSION: string = pkg.version;\n"],"mappings":"AAAA,ICGaA,EDDA,gBCCsBC","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import{a as s}from"./chunks/chunk-TB52U4QV.js";import{a as n,d as t,e as u}from"./chunks/chunk-FT7OW7CG.js";import"./chunks/chunk-65B2K2XD.js";import"./chunks/chunk-IWY3I2DG.js";import"./chunks/chunk-FFXJVUTT.js";import{g as a,h as c,i as h}from"./chunks/chunk-GU7IAIWW.js";import{c as i}from"./chunks/chunk-JCQTA35B.js";import"./chunks/chunk-MZVF2WEY.js";import"./chunks/chunk-PTFWXISY.js";import"./chunks/chunk-UE6JK2ZA.js";import{g as o}from"./chunks/chunk-SJRJALR4.js";function r(s){return s}export{a as TRUSTED_TYPES_POLICY_SLOT,s as VERSION,t as bootstrapState,u as buildBindings,r as defineState,n as getBindingsReady,i as getConfig,c as getTrustedTypesPolicy,o as installFeatures,h as setTrustedTypesPolicy};
1
+ import{a as s}from"./chunks/chunk-SJ552B3B.js";import{a as n,d as t,e as u}from"./chunks/chunk-R6RHIIR4.js";import"./chunks/chunk-REB4RMZ3.js";import"./chunks/chunk-CYMUD7KV.js";import"./chunks/chunk-JJYM4JVZ.js";import{h as a,i as c,j as h}from"./chunks/chunk-IYPAK7PO.js";import{c as i}from"./chunks/chunk-AKTGQ6TC.js";import"./chunks/chunk-NAV7FBTI.js";import"./chunks/chunk-KBQKAD3I.js";import"./chunks/chunk-E3XSBW55.js";import{g as o}from"./chunks/chunk-LPJFTEVT.js";function r(s){return s}export{a as TRUSTED_TYPES_POLICY_SLOT,s as VERSION,t as bootstrapState,u as buildBindings,r as defineState,n as getBindingsReady,i as getConfig,c as getTrustedTypesPolicy,o as installFeatures,h as setTrustedTypesPolicy};
2
2
  //# sourceMappingURL=core.js.map
@@ -1,2 +1,2 @@
1
- import{a as e}from"../chunks/chunk-TB52U4QV.js";import{c as t,d as n,e as l,f as o,g as s,h as r,i as a,p as i}from"../chunks/chunk-IWY3I2DG.js";import"../chunks/chunk-FFXJVUTT.js";import"../chunks/chunk-GU7IAIWW.js";import"../chunks/chunk-JCQTA35B.js";import"../chunks/chunk-MZVF2WEY.js";import"../chunks/chunk-PTFWXISY.js";import"../chunks/chunk-UE6JK2ZA.js";import{a as u,b as d}from"../chunks/chunk-SJRJALR4.js";var f="__WCSTACK_DEVTOOLS_HOOK__",c=null,m=new Set,p=(e,t,n)=>({absolutePathInfo:{pathInfo:{path:t.t},stateElement:e.element},listIndex:null===n?null:{indexes:e.H(n)}}),h=new WeakMap,k=0;var v=new WeakMap;function g(e){if(null===c)return;let i=v.get(e),u=m.has(e)?function(e,i){let u=new Map,d=new Set,f=(r,a,d,f,c,m)=>{if(r===s)return;let v=function(e,s){return e===t?"textContent":e===n?`class.${s}`:e===l?`attr.${s}`:e===o?`style.${s}`:s}(r,a),g=0===f.n?null:c,w=`${(e=>{let t=h.get(e);return void 0===t&&h.set(e,t=++k),t})(d)}|${v}|${f.t}|${null===g?"":e.H(g).join(",")}`;if(u.has(w))return;let y=i?.get(w);u.set(w,y??{binding:{propName:v,statePathName:f.t,bindingType:m,node:d,replaceNode:d},absoluteAddress:p(e,f,g)})},c=e=>f(e.i,e.name,e.c,e.o,e.r,e.on()),m=e=>{if(!d.has(e)){if(d.add(e),null!==e.we)for(let t of e.we)c(t);if(e instanceof r&&null!==e.pe){let n=e.C.Xe;for(let l=0;l<n.length;l++){let o=e.V?.[l];void 0!==o?c(o):f(n[l].i,n[l].name,e.pe[2*l],n[l].o,e.r,n[l].i===t?"text":"prop")}}if(null!==e.u)for(let t of e.u)v(t)}},v=e=>{if(!d.has(e))if(d.add(e),e instanceof a){f(-1,"for",e.S,e.l.o,e.l.ce,"for");for(let t of e.Ae)m(t)}else null!==e.I&&m(e.I)};for(let t of e.ue.values())for(let e of t)c(e),null!==e.D&&v(e.D);for(let t of e.oe.values())if(null!==t.N&&v(t.N),null!==t.W)for(let e of t.W)v(e);return u}(e,i):new Map;if(void 0!==i)for(let[e,t]of i)u.has(e)||c({type:"state:binding-removed",...t});for(let[e,t]of u)(void 0===i||!i.has(e))&&c({type:"state:binding-added",...t});v.set(e,u)}function w(e){let t=i.get(e);if(void 0===t)throw new Error("[@wcstack/state] devtools: no state tree on this root");return t}function y(e){let t=new Set,n=new Set,l=new Set,o=new Set;for(let s of e.O.all()){for(let e=1;e<=s.n;e++)t.add(s.h[e].t);"*"===s.s&&n.add(s.t),null!==s.getter&&l.add(s.t),null!==s.se&&o.add(s.t)}let s=e.target;return{rootNode:e.root,element:e.element,paths:{list:t,element:n,getter:l,setter:o},commandTokenNames:new Set(Object.keys(e.commands)),eventTokenNames:new Set(e.Oe.keys()),staticDependency:new Map,dynamicDependency:new Map,watchPaths:null!==s.$watch&&"object"==typeof s.$watch?new Set(Object.keys(s.$watch)):null,keyedListPaths:null!==s.$listKeys&&"object"==typeof s.$listKeys?new Set(Object.keys(s.$listKeys)):null}}var S=new WeakSet,b=new WeakMap;function j(e,t){if(("mounting"===t||"reset"===t)&&function(e){let t=(t,n)=>{if(S.has(t))return;S.add(t);let l=t.emit;t.emit=(...o)=>(null!==c&&c({type:"state:token-emit",kind:n,tokenName:t.name,args:o,subscriberCount:t.size,stateElement:e.element}),l.apply(t,o))};for(let n of Object.values(e.commands))t(n,"command");for(let n of e.Oe.values())t(n,"event")}(e),"connected"===t){if(m.has(e))return;m.add(e),c?.({type:"state:element-registered",rootNode:e.root,element:e.element}),g(e)}else"disconnected"===t&&(m.delete(e),g(e),c?.({type:"state:element-unregistered",rootNode:e.root,element:e.element}))}function $(e,t,n,l,o,s){if(null===c)return;let r=p(e,t,0===t.n?null:n),a=b.get(e);void 0===a&&b.set(e,a=new Set),a.add(r),s&&c({type:"state:write",absoluteAddress:r,value:o,oldValue:l,hasOldValue:!0})}function O(e){if(null===c)return;let t=b.get(e);b.delete(e),void 0!==t&&c({type:"state:update-batch",addresses:t}),g(e)}function W(e,t,n){c?.({type:"state:binding-apply-error",path:n.o.t,bindingType:n.on(),error:t})}var M={name:"devtools",hooks:u,install(){u.element=d(u.element,j),u.re=d(u.re,$),u.me=d(u.me,O),u.Ge=d(u.Ge,W),function(){if(typeof document>"u"||document.documentElement?.hasAttribute("data-wcs-server"))return;let t=globalThis,n=t[f]??(t[f]=function(){let e=new Map,t=new Set,n=e=>{0===t.size?e._setSink(null):e._setSink(n=>{for(let l of t)l.onEvent?.(e.id,n)})};return{version:2,sources:e,register(l){if(!e.has(l.id)){e.set(l.id,l),n(l);for(let e of t)e.onSourceRegistered?.(l)}},unregister(n){let l=e.get(n);if(void 0!==l){l._setSink(null),e.delete(n);for(let e of t)e.onSourceUnregistered?.(n)}},addListener(l){t.add(l);for(let t of e.values())n(t),l.onSourceRegistered?.(t);return()=>{if(t.delete(l))for(let t of e.values())n(t)}}}}());2!==n.version&&console.warn(`[@wcstack/state] devtools hook registry version ${n.version}, expected 2: keeping the existing one.`),n.register({id:`state:${Math.random().toString(36).slice(2,10)}`,kind:"state",packageVersion:e,getStateElements:()=>[...m].map(y),overlays:()=>[],keyedSubscriptions:e=>function(e){let t=[];for(let n of e.O.all()){let l=n._,o=n.je?.length??0;if((null===l||0===l.size)&&0===o)continue;let s,r=0;if(null!==l)for(let e of l.values())r+=e.size;try{s=0===n.n?e.v(n,null):void 0}catch{s=void 0}t.push({path:n.t,tracked:!1,rows:r,keys:null===l?0:l.size,lists:o,lastValue:s})}return t}(w(e)),keys(e){let t=w(e).target;return Object.keys(t).filter(e=>{if(e.includes("*")||"$"===e[0])return!1;let n=Object.getOwnPropertyDescriptor(t,e);return void 0!==n.get||"function"!=typeof n.value})},read(e,t,n){let l;return w(e).element.createState("readonly",e=>{l=e.$resolve(t,n??[])}),l},write(e,t,n,l){w(e).element.createState("writable",e=>{e.$resolve(t,l??[],n)})},_setSink(e){let t=null===c&&null!==e;c=e,null===e&&(v=new WeakMap),u.ct=e&&((e,t)=>c?.({...t,stateElement:e.element})),t&&queueMicrotask(()=>{for(let e of m)g(e)})}})}()}},T=M;export{T as default,M as devtools};
1
+ import{a as e}from"../chunks/chunk-SJ552B3B.js";import{b as t,c as n,d as l,e as o,f as s,g as r,h as a,o as i}from"../chunks/chunk-CYMUD7KV.js";import"../chunks/chunk-JJYM4JVZ.js";import"../chunks/chunk-IYPAK7PO.js";import"../chunks/chunk-AKTGQ6TC.js";import"../chunks/chunk-NAV7FBTI.js";import"../chunks/chunk-KBQKAD3I.js";import"../chunks/chunk-E3XSBW55.js";import{a as u,b as d}from"../chunks/chunk-LPJFTEVT.js";var f="__WCSTACK_DEVTOOLS_HOOK__",c=null,m=new Set,p=(e,t,n)=>({absolutePathInfo:{pathInfo:{path:t.t},stateElement:e.element},listIndex:null===n?null:{indexes:e.K(n)}}),h=new WeakMap,k=0;var v=new WeakMap;function g(e){if(null===c)return;let i=v.get(e),u=m.has(e)?function(e,i){let u=new Map,d=new Set,f=(r,a,d,f,c,m)=>{if(r===s)return;let v=function(e,s){return e===t?"textContent":e===n?`class.${s}`:e===l?`attr.${s}`:e===o?`style.${s}`:s}(r,a),g=0===f.n?null:c,w=`${(e=>{let t=h.get(e);return void 0===t&&h.set(e,t=++k),t})(d)}|${v}|${f.t}|${null===g?"":e.K(g).join(",")}`;if(u.has(w))return;let y=i?.get(w);u.set(w,y??{binding:{propName:v,statePathName:f.t,bindingType:m,node:d,replaceNode:d},absoluteAddress:p(e,f,g)})},c=e=>f(e.i,e.name,e.a,e.o,e.r,e.rn()),m=e=>{if(!d.has(e)){if(d.add(e),null!==e.ke)for(let t of e.ke)c(t);if(e instanceof r&&null!==e.pe){let n=e.E.Xe;for(let l=0;l<n.length;l++){let o=e.U?.[l];void 0!==o?c(o):f(n[l].i,n[l].name,e.pe[2*l],n[l].o,e.r,n[l].i===t?"text":"prop")}}if(null!==e.u)for(let t of e.u)v(t)}},v=e=>{if(!d.has(e))if(d.add(e),e instanceof a){f(-1,"for",e.$,e.l.o,e.l.oe,"for");for(let t of e.Ae)m(t)}else null!==e.D&&m(e.D)};for(let t of e.ie.values())for(let e of t)c(e),null!==e.I&&v(e.I);for(let t of e.H.values())if(null!==t.S&&v(t.S),null!==t.j)for(let e of t.j)v(e);return u}(e,i):new Map;if(void 0!==i)for(let[e,t]of i)u.has(e)||c({type:"state:binding-removed",...t});for(let[e,t]of u)(void 0===i||!i.has(e))&&c({type:"state:binding-added",...t});v.set(e,u)}function w(e){let t=i.get(e);if(void 0===t)throw new Error("[@wcstack/state] devtools: no state tree on this root");return t}function y(e){let t=new Set,n=new Set,l=new Set,o=new Set;for(let s of e.C.all()){for(let e=1;e<=s.n;e++)t.add(s.h[e].t);"*"===s.s&&n.add(s.t),null!==s.getter&&l.add(s.t),null!==s.ce&&o.add(s.t)}let s=e.target;return{rootNode:e.root,element:e.element,paths:{list:t,element:n,getter:l,setter:o},commandTokenNames:new Set(Object.keys(e.commands)),eventTokenNames:new Set(e.Oe.keys()),staticDependency:new Map,dynamicDependency:new Map,watchPaths:null!==s.$watch&&"object"==typeof s.$watch?new Set(Object.keys(s.$watch)):null,keyedListPaths:null!==s.$listKeys&&"object"==typeof s.$listKeys?new Set(Object.keys(s.$listKeys)):null}}var S=new WeakSet,b=new WeakMap;function j(e,t){if(("mounting"===t||"reset"===t)&&function(e){let t=(t,n)=>{if(S.has(t))return;S.add(t);let l=t.emit;t.emit=(...o)=>(null!==c&&c({type:"state:token-emit",kind:n,tokenName:t.name,args:o,subscriberCount:t.size,stateElement:e.element}),l.apply(t,o))};for(let n of Object.values(e.commands))t(n,"command");for(let n of e.Oe.values())t(n,"event")}(e),"connected"===t){if(m.has(e))return;m.add(e),c?.({type:"state:element-registered",rootNode:e.root,element:e.element}),g(e)}else"disconnected"===t&&(m.delete(e),g(e),c?.({type:"state:element-unregistered",rootNode:e.root,element:e.element}))}function $(e,t,n,l,o,s){if(null===c)return;let r=p(e,t,0===t.n?null:n),a=b.get(e);void 0===a&&b.set(e,a=new Set),a.add(r),s&&c({type:"state:write",absoluteAddress:r,value:o,oldValue:l,hasOldValue:!0})}function O(e){if(null===c)return;let t=b.get(e);b.delete(e),void 0!==t&&c({type:"state:update-batch",addresses:t}),g(e)}function M(e,t,n){c?.({type:"state:binding-apply-error",path:n.o.t,bindingType:n.rn(),error:t})}var K={name:"devtools",hooks:u,install(){u.element=d(u.element,j),u.se=d(u.se,$),u.me=d(u.me,O),u.Ge=d(u.Ge,M),function(){if(typeof document>"u"||document.documentElement?.hasAttribute("data-wcs-server"))return;let t=globalThis,n=t[f]??(t[f]=function(){let e=new Map,t=new Set,n=e=>{0===t.size?e._setSink(null):e._setSink(n=>{for(let l of t)l.onEvent?.(e.id,n)})};return{version:2,sources:e,register(l){if(!e.has(l.id)){e.set(l.id,l),n(l);for(let e of t)e.onSourceRegistered?.(l)}},unregister(n){let l=e.get(n);if(void 0!==l){l._setSink(null),e.delete(n);for(let e of t)e.onSourceUnregistered?.(n)}},addListener(l){t.add(l);for(let t of e.values())n(t),l.onSourceRegistered?.(t);return()=>{if(t.delete(l))for(let t of e.values())n(t)}}}}());2!==n.version&&console.warn(`[@wcstack/state] devtools hook registry version ${n.version}, expected 2: keeping the existing one.`),n.register({id:`state:${Math.random().toString(36).slice(2,10)}`,kind:"state",packageVersion:e,getStateElements:()=>[...m].map(y),overlays:()=>[],keyedSubscriptions:e=>function(e){let t=[];for(let n of e.C.all()){let l=n.V,o=n.je?.length??0;if((null===l||0===l.size)&&0===o)continue;let s,r=0;if(null!==l)for(let e of l.values())r+=e.size;try{s=0===n.n?e.v(n,null):void 0}catch{s=void 0}t.push({path:n.t,tracked:!1,rows:r,keys:null===l?0:l.size,lists:o,lastValue:s})}return t}(w(e)),keys(e){let t=w(e).target;return Object.keys(t).filter(e=>{if(e.includes("*")||"$"===e[0])return!1;let n=Object.getOwnPropertyDescriptor(t,e);return void 0!==n.get||"function"!=typeof n.value})},read(e,t,n){let l;return w(e).element.createState("readonly",e=>{l=e.$resolve(t,n??[])}),l},write(e,t,n,l){w(e).element.createState("writable",e=>{e.$resolve(t,l??[],n)})},_setSink(e){let t=null===c&&null!==e;c=e,null===e&&(v=new WeakMap),u.ut=e&&((e,t)=>c?.({...t,stateElement:e.element})),t&&queueMicrotask(()=>{for(let e of m)g(e)})}})}()}},T=K;export{T as default,K as devtools};
2
2
  //# sourceMappingURL=devtools.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["HOOK","sink","live","Set","address","engine","p","row","absolutePathInfo","pathInfo","path","stateElement","element","listIndex","indexes","indexesOf","nodeIds","WeakMap","nodeSeq","ledgers","sync","old","get","now","has","out","Map","seen","add","kind","name","node","type","K_EVENT","prop","K_TEXT","K_CLASS","K_ATTR","K_STYLE","propName","r","depth","key","n","id","set","idOf","join","kept","binding","statePathName","bindingType","replaceNode","absoluteAddress","b","pattern","typeName","block","bindings","x","RowView","slots","lazy","plan","k","length","made","bound","children","v","view","ForView","anchor","list","parentRow","rv","rowViews","current","bs","rootBindings","values","chain","l","rootLists","extra","snapshot","e","engineOf","root","engines","Error","summary","getter","setter","patterns","all","lists","last","t","target","rootNode","paths","commandTokenNames","Object","keys","commands","eventTokenNames","events","staticDependency","dynamicDependency","watchPaths","$watch","keyedListPaths","$listKeys","wrapped","WeakSet","batches","devtoolsElement","phase","wrap","emit","args","tokenName","subscriberCount","size","apply","wrapTokens","delete","devtoolsWritten","value","direct","a","batch","oldValue","hasOldValue","devtoolsDrained","addresses","devtoolsFailed","_engine","error","devtools","hooks","install","written","drained","failed","document","documentElement","hasAttribute","g","globalThis","registry","sources","listeners","s","_setSink","event","onEvent","version","register","onSourceRegistered","unregister","onSourceUnregistered","addListener","createRegistry","console","warn","Math","random","toString","slice","packageVersion","VERSION","getStateElements","map","overlays","keyedSubscriptions","subs","eqSubs","eqIndexWatchers","lastValue","rows","readUntracked","push","tracked","filter","includes","d","getOwnPropertyDescriptor","read","createState","$resolve","write","next","attached","noticed","queueMicrotask","registerSource","devtools_default"],"sources":["../../../src/devtools/devtools.ts","../../../src/features/devtools.ts"],"sourcesContent":["/**\n * DevTools (`@wcstack/devtools`) — the DevTools Hook Protocol v2 (docs/devtools-hook-protocol.ja.md),\n * spoken by an add-on so the engine pays nothing while no DevTools is attached.\n *\n * The protocol's pulls (the roster, keys, read, write, keyed subscriptions) read the engines; its\n * events come from the add-on hooks (written, drained, failed, the element lifecycle) and from\n * the tokens, wrapped per engine. Addresses and bindings are small plain objects of the shape\n * DevTools reads (`absolutePathInfo.pathInfo.path`, `listIndex.indexes`, `propName`,\n * `statePathName`, `bindingType`, `node`), built only while a sink is set. Every key that\n * crosses to DevTools is quoted: the build shortens internal names, some of which (`kind`,\n * `path`, `node`, `propName`, …) are also the protocol's.\n *\n * The one part v2 builds from the engine's own bookkeeping — \"binding added / removed\" — the new\n * engine does not have (row bindings are lazy slots, made on their first change). While DevTools\n * is attached, the add-on takes the list of bindings after every drain (materialized ones and\n * slots alike) and reports the difference: DevTools sees the same live ledger, at a cost paid\n * only then.\n */\nimport type { Engine } from \"../engine\";\nimport type { Pattern } from \"../pattern\";\nimport type { StateRow } from \"../list\";\nimport type { Token } from \"../token\";\nimport { ForView, IfView, K_ATTR, K_CLASS, K_EVENT, K_STYLE, K_TEXT, type Binding, type Block, RowView, type Spec } from \"../dom/view\";\nimport { engines as byRoot } from \"../dom/mount\";\nimport { VERSION } from \"../version\";\nimport { hooks } from \"../hooks\";\n\nconst HOOK = \"__WCSTACK_DEVTOOLS_HOOK__\";\nconst PROTOCOL = 2;\n\ntype Sink = (event: Record<string, unknown>) => void;\ntype Source = Record<string, any>;\n\nlet sink: Sink | null = null;\n/** The attached DevTools' sink (analyzeContract forwards its events there). */\nexport const devtoolsSink = (): Sink | null => sink;\nconst live = new Set<Engine>();\n\n// ---------------------------------------------------------------- registry (first one wins)\n\nfunction createRegistry(): Record<string, unknown> {\n const sources = new Map<string, Source>();\n const listeners = new Set<Record<string, (...a: any[]) => void>>();\n const apply = (s: Source): void => {\n if (listeners.size === 0) s[\"_setSink\"](null);\n else s[\"_setSink\"]((event: unknown) => { for (const l of listeners) l[\"onEvent\"]?.(s[\"id\"], event); });\n };\n return {\n \"version\": PROTOCOL,\n \"sources\": sources,\n \"register\"(s: Source): void {\n if (sources.has(s[\"id\"])) return;\n sources.set(s[\"id\"], s);\n apply(s);\n for (const l of listeners) l[\"onSourceRegistered\"]?.(s);\n },\n \"unregister\"(id: string): void {\n const s = sources.get(id);\n if (s === undefined) return;\n s[\"_setSink\"](null);\n sources.delete(id);\n for (const l of listeners) l[\"onSourceUnregistered\"]?.(id);\n },\n \"addListener\"(l: Record<string, (...a: any[]) => void>): () => void {\n listeners.add(l);\n for (const s of sources.values()) {\n apply(s);\n l[\"onSourceRegistered\"]?.(s);\n }\n return () => {\n if (listeners.delete(l)) for (const s of sources.values()) apply(s);\n };\n },\n };\n}\n\n// ---------------------------------------------------------------- shapes DevTools reads\n\nconst address = (engine: Engine, p: Pattern, row: StateRow | null): Record<string, unknown> => ({\n \"absolutePathInfo\": { \"pathInfo\": { \"path\": p.path }, \"stateElement\": engine.element },\n \"listIndex\": row === null ? null : { \"indexes\": engine.indexesOf(row) },\n});\n\nfunction propName(kind: number, name: string): string {\n if (kind === K_TEXT) return \"textContent\";\n if (kind === K_CLASS) return `class.${name}`;\n if (kind === K_ATTR) return `attr.${name}`;\n if (kind === K_STYLE) return `style.${name}`;\n return name;\n}\n\n/** A binding as DevTools reads it: `{ binding, absoluteAddress }`. */\ntype Entry = Record<string, unknown>;\n\nconst nodeIds = new WeakMap<Node, number>();\nlet nodeSeq = 0;\nconst idOf = (n: Node): number => {\n let id = nodeIds.get(n);\n if (id === undefined) nodeIds.set(n, (id = ++nodeSeq));\n return id;\n};\n\n/** Every binding of the engine now — materialized ones and row slots alike — by identity. */\nfunction snapshot(engine: Engine, old: Map<string, Entry> | undefined): Map<string, Entry> {\n const out = new Map<string, Entry>();\n const seen = new Set<object>();\n const add = (kind: number, name: string, node: Node, p: Pattern, row: StateRow | null, type: string): void => {\n if (kind === K_EVENT) return;\n const prop = propName(kind, name);\n const r = p.depth === 0 ? null : row;\n const key = `${idOf(node)}|${prop}|${p.path}|${r === null ? \"\" : engine.indexesOf(r).join(\",\")}`;\n if (out.has(key)) return;\n const kept = old?.get(key);\n out.set(key, kept ?? {\n \"binding\": { \"propName\": prop, \"statePathName\": p.path, \"bindingType\": type, \"node\": node, \"replaceNode\": node },\n \"absoluteAddress\": address(engine, p, r),\n });\n };\n const binding = (b: Binding): void => add(b.kind, b.name, b.node, b.pattern, b.row, b.typeName());\n const block = (b: Block): void => {\n if (seen.has(b)) return;\n seen.add(b);\n if (b.bindings !== null) for (const x of b.bindings) binding(x);\n if (b instanceof RowView && b.slots !== null) {\n const lazy: Spec[] = b.plan.lazy;\n for (let k = 0; k < lazy.length; k++) {\n const made = b.bound?.[k];\n if (made !== undefined) binding(made);\n else add(lazy[k].kind, lazy[k].name, b.slots[2 * k] as Node, lazy[k].pattern!, b.row, lazy[k].kind === K_TEXT ? \"text\" : \"prop\");\n }\n }\n if (b.children !== null) for (const v of b.children) view(v);\n };\n const view = (v: ForView | IfView): void => {\n if (seen.has(v)) return;\n seen.add(v);\n if (v instanceof ForView) {\n // the list binding itself: v2 has one per `for`, on the anchor that replaced the template\n add(-1, \"for\", v.anchor, v.list.pattern, v.list.parentRow, \"for\");\n for (const rv of v.rowViews) block(rv);\n } else if (v.current !== null) block(v.current);\n };\n for (const bs of engine.rootBindings.values()) {\n for (const b of bs) {\n binding(b);\n if (b.chain !== null) view(b.chain);\n }\n }\n for (const l of engine.rootLists.values()) {\n if (l.view !== null) view(l.view);\n if (l.extra !== null) for (const v of l.extra) view(v);\n }\n return out;\n}\n\nlet ledgers = new WeakMap<Engine, Map<string, Entry>>();\n\n/** Reports the bindings added and removed since the last look. */\nfunction sync(engine: Engine): void {\n if (sink === null) return;\n const old = ledgers.get(engine);\n const now = live.has(engine) ? snapshot(engine, old) : new Map<string, Entry>();\n if (old !== undefined) for (const [k, e] of old) if (!now.has(k)) sink({ \"type\": \"state:binding-removed\", ...e });\n for (const [k, e] of now) if (old === undefined || !old.has(k)) sink({ \"type\": \"state:binding-added\", ...e });\n ledgers.set(engine, now);\n}\n\n// ---------------------------------------------------------------- the pulls\n\nfunction engineOf(root: Node): Engine {\n const e = byRoot.get(root);\n if (e === undefined) throw new Error(\"[@wcstack/state] devtools: no state tree on this root\");\n return e;\n}\n\nfunction summary(engine: Engine): Record<string, unknown> {\n const list = new Set<string>();\n const element = new Set<string>();\n const getter = new Set<string>();\n const setter = new Set<string>();\n for (const p of engine.patterns.all()) {\n for (let k = 1; k <= p.depth; k++) list.add(p.lists[k]!.path);\n if (p.last === \"*\") element.add(p.path);\n if (p.getter !== null) getter.add(p.path);\n if (p.setter !== null) setter.add(p.path);\n }\n const t = engine.target;\n return {\n \"rootNode\": engine.root,\n \"element\": engine.element,\n \"paths\": { \"list\": list, \"element\": element, \"getter\": getter, \"setter\": setter },\n \"commandTokenNames\": new Set(Object.keys(engine.commands)),\n \"eventTokenNames\": new Set(engine.events.keys()),\n \"staticDependency\": new Map(),\n \"dynamicDependency\": new Map(),\n \"watchPaths\": t.$watch !== null && typeof t.$watch === \"object\" ? new Set(Object.keys(t.$watch)) : null,\n \"keyedListPaths\": t.$listKeys !== null && typeof t.$listKeys === \"object\" ? new Set(Object.keys(t.$listKeys)) : null,\n };\n}\n\nfunction keyedSubscriptions(engine: Engine): Record<string, unknown>[] {\n const out: Record<string, unknown>[] = [];\n for (const p of engine.patterns.all()) {\n const subs = p.eqSubs;\n const lists = p.eqIndexWatchers?.length ?? 0;\n if ((subs === null || subs.size === 0) && lists === 0) continue;\n let rows = 0;\n if (subs !== null) for (const s of subs.values()) rows += s.size;\n let lastValue: unknown;\n try { lastValue = p.depth === 0 ? engine.readUntracked(p, null) : undefined; } catch { lastValue = undefined; }\n out.push({ \"path\": p.path, \"tracked\": false, \"rows\": rows, \"keys\": subs === null ? 0 : subs.size, \"lists\": lists, \"lastValue\": lastValue });\n }\n return out;\n}\n\nfunction createSource(): Source {\n return {\n \"id\": `state:${Math.random().toString(36).slice(2, 10)}`,\n \"kind\": \"state\",\n \"packageVersion\": VERSION,\n \"getStateElements\": () => [...live].map(summary),\n \"overlays\": () => [],\n \"keyedSubscriptions\": (root: Node) => keyedSubscriptions(engineOf(root)),\n \"keys\"(root: Node): string[] {\n const t = engineOf(root).target;\n return Object.keys(t).filter((k) => {\n if (k.includes(\"*\") || k[0] === \"$\") return false;\n const d = Object.getOwnPropertyDescriptor(t, k)!;\n return d.get !== undefined || typeof d.value !== \"function\";\n });\n },\n \"read\"(root: Node, path: string, indexes?: number[]): unknown {\n const el = engineOf(root).element as any;\n let v: unknown;\n el.createState(\"readonly\", (s: any) => { v = s.$resolve(path, indexes ?? []); });\n return v;\n },\n \"write\"(root: Node, path: string, value: unknown, indexes?: number[]): void {\n const el = engineOf(root).element as any;\n el.createState(\"writable\", (s: any) => { s.$resolve(path, indexes ?? [], value); });\n },\n \"_setSink\"(next: Sink | null): void {\n const attached = sink === null && next !== null;\n sink = next;\n // detached: the ledgers go — an attach after it is told every binding there, and none of\n // their nodes is held meanwhile\n if (next === null) ledgers = new WeakMap();\n // what the add-ons notice ($watch fired / threw / cut, a path that does not resolve), with the\n // tree it came from (`stateElement`): built only while a DevTools is attached\n hooks.noticed = next && ((engine, event) => sink?.({ ...event, \"stateElement\": engine.element }));\n // a DevTools that attaches late sees the bindings there already\n if (attached) queueMicrotask(() => { for (const e of live) sync(e); });\n },\n };\n}\n\n// ---------------------------------------------------------------- the hooks\n\nconst wrapped = new WeakSet<Token>();\n\nfunction wrapTokens(engine: Engine): void {\n const wrap = (t: Token, kind: \"command\" | \"event\"): void => {\n if (wrapped.has(t)) return;\n wrapped.add(t);\n const emit = t.emit;\n t.emit = (...args: unknown[]) => {\n if (sink !== null) sink({ \"type\": \"state:token-emit\", \"kind\": kind, \"tokenName\": t.name, \"args\": args, \"subscriberCount\": t.size, \"stateElement\": engine.element });\n return emit.apply(t, args);\n };\n };\n for (const t of Object.values(engine.commands)) wrap(t, \"command\");\n for (const t of engine.events.values()) wrap(t, \"event\");\n}\n\nconst batches = new WeakMap<Engine, Set<unknown>>();\n\nexport function devtoolsElement(engine: Engine, phase: string): void {\n if (phase === \"mounting\" || phase === \"reset\") wrapTokens(engine);\n if (phase === \"connected\") {\n if (live.has(engine)) return;\n live.add(engine);\n sink?.({ \"type\": \"state:element-registered\", \"rootNode\": engine.root, \"element\": engine.element });\n sync(engine);\n } else if (phase === \"disconnected\") {\n live.delete(engine);\n sync(engine);\n sink?.({ \"type\": \"state:element-unregistered\", \"rootNode\": engine.root, \"element\": engine.element });\n }\n}\n\nexport function devtoolsWritten(engine: Engine, p: Pattern, row: StateRow | null, old: unknown, value: unknown, direct: boolean): void {\n if (sink === null) return;\n const a = address(engine, p, p.depth === 0 ? null : row);\n let batch = batches.get(engine);\n if (batch === undefined) batches.set(engine, (batch = new Set()));\n batch.add(a);\n if (direct) sink({ \"type\": \"state:write\", \"absoluteAddress\": a, \"value\": value, \"oldValue\": old, \"hasOldValue\": true });\n}\n\nexport function devtoolsDrained(engine: Engine): void {\n if (sink === null) return;\n const batch = batches.get(engine);\n batches.delete(engine);\n if (batch !== undefined) sink({ \"type\": \"state:update-batch\", \"addresses\": batch });\n sync(engine);\n}\n\nexport function devtoolsFailed(_engine: Engine, error: unknown, b: Binding): void {\n sink?.({ \"type\": \"state:binding-apply-error\", \"path\": b.pattern.path, \"bindingType\": b.typeName(), \"error\": error });\n}\n\nexport function registerSource(): void {\n if (typeof document === \"undefined\" || document.documentElement?.hasAttribute(\"data-wcs-server\")) return;\n const g = globalThis as any;\n const registry = g[HOOK] ?? (g[HOOK] = createRegistry());\n if (registry[\"version\"] !== PROTOCOL) console.warn(`[@wcstack/state] devtools hook registry version ${registry[\"version\"]}, expected ${PROTOCOL}: keeping the existing one.`);\n registry[\"register\"](createSource());\n}\n","/**\n * The DevTools add-on (@wcstack/state/features/devtools): `@wcstack/devtools` over the hook\n * protocol v2 — see src/devtools/devtools.ts.\n */\nimport { chain, hooks, type Feature } from \"../hooks\";\nimport { devtoolsDrained, devtoolsElement, devtoolsFailed, devtoolsWritten, registerSource } from \"../devtools/devtools\";\n\nexport const devtools: Feature = {\n name: \"devtools\",\n hooks,\n install(): void {\n hooks.element = chain(hooks.element, devtoolsElement);\n hooks.written = chain(hooks.written, devtoolsWritten);\n hooks.drained = chain(hooks.drained, devtoolsDrained);\n hooks.failed = chain(hooks.failed, devtoolsFailed);\n registerSource();\n },\n};\nexport default devtools;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["HOOK","sink","live","Set","address","engine","p","row","absolutePathInfo","pathInfo","path","stateElement","element","listIndex","indexes","indexesOf","nodeIds","WeakMap","nodeSeq","ledgers","sync","old","get","now","has","out","Map","seen","add","kind","name","node","type","K_EVENT","prop","K_TEXT","K_CLASS","K_ATTR","K_STYLE","propName","r","depth","key","n","id","set","idOf","join","kept","binding","statePathName","bindingType","replaceNode","absoluteAddress","b","pattern","typeName","block","bindings","x","RowView","slots","lazy","plan","k","length","made","bound","children","v","view","ForView","anchor","list","parentRow","rv","rowViews","current","bs","rootBindings","values","chain","l","rootLists","extra","snapshot","e","engineOf","root","engines","Error","summary","getter","setter","patterns","all","lists","last","t","target","rootNode","paths","commandTokenNames","Object","keys","commands","eventTokenNames","events","staticDependency","dynamicDependency","watchPaths","$watch","keyedListPaths","$listKeys","wrapped","WeakSet","batches","devtoolsElement","phase","wrap","emit","args","tokenName","subscriberCount","size","apply","wrapTokens","delete","devtoolsWritten","value","direct","a","batch","oldValue","hasOldValue","devtoolsDrained","addresses","devtoolsFailed","_engine","error","devtools","hooks","install","written","drained","failed","document","documentElement","hasAttribute","g","globalThis","registry","sources","listeners","s","_setSink","event","onEvent","version","register","onSourceRegistered","unregister","onSourceUnregistered","addListener","createRegistry","console","warn","Math","random","toString","slice","packageVersion","VERSION","getStateElements","map","overlays","keyedSubscriptions","subs","eqSubs","eqIndexWatchers","lastValue","rows","readUntracked","push","tracked","filter","includes","d","getOwnPropertyDescriptor","read","createState","$resolve","write","next","attached","noticed","queueMicrotask","registerSource","devtools_default"],"sources":["../../../src/devtools/devtools.ts","../../../src/features/devtools.ts"],"sourcesContent":["/**\n * DevTools (`@wcstack/devtools`) — the DevTools Hook Protocol v2 (docs/devtools-hook-protocol.ja.md),\n * spoken by an add-on so the engine pays nothing while no DevTools is attached.\n *\n * The protocol's pulls (the roster, keys, read, write, keyed subscriptions) read the engines; its\n * events come from the add-on hooks (written, drained, failed, the element lifecycle) and from\n * the tokens, wrapped per engine. Addresses and bindings are small plain objects of the shape\n * DevTools reads (`absolutePathInfo.pathInfo.path`, `listIndex.indexes`, `propName`,\n * `statePathName`, `bindingType`, `node`), built only while a sink is set. Every key that\n * crosses to DevTools is quoted: the build shortens internal names, some of which (`kind`,\n * `path`, `node`, `propName`, …) are also the protocol's.\n *\n * The one part v2 builds from the engine's own bookkeeping — \"binding added / removed\" — the new\n * engine does not have (row bindings are lazy slots, made on their first change). While DevTools\n * is attached, the add-on takes the list of bindings after every drain (materialized ones and\n * slots alike) and reports the difference: DevTools sees the same live ledger, at a cost paid\n * only then.\n */\nimport type { Engine } from \"../engine\";\nimport type { Pattern } from \"../pattern\";\nimport type { StateRow } from \"../list\";\nimport type { Token } from \"../token\";\nimport { ForView, IfView, K_ATTR, K_CLASS, K_EVENT, K_STYLE, K_TEXT, type Binding, type Block, RowView, type Spec } from \"../dom/view\";\nimport { engines as byRoot } from \"../dom/mount\";\nimport { VERSION } from \"../version\";\nimport { hooks } from \"../hooks\";\n\nconst HOOK = \"__WCSTACK_DEVTOOLS_HOOK__\";\nconst PROTOCOL = 2;\n\ntype Sink = (event: Record<string, unknown>) => void;\ntype Source = Record<string, any>;\n\nlet sink: Sink | null = null;\n/** The attached DevTools' sink (analyzeContract forwards its events there). */\nexport const devtoolsSink = (): Sink | null => sink;\nconst live = new Set<Engine>();\n\n// ---------------------------------------------------------------- registry (first one wins)\n\nfunction createRegistry(): Record<string, unknown> {\n const sources = new Map<string, Source>();\n const listeners = new Set<Record<string, (...a: any[]) => void>>();\n const apply = (s: Source): void => {\n if (listeners.size === 0) s[\"_setSink\"](null);\n else s[\"_setSink\"]((event: unknown) => { for (const l of listeners) l[\"onEvent\"]?.(s[\"id\"], event); });\n };\n return {\n \"version\": PROTOCOL,\n \"sources\": sources,\n \"register\"(s: Source): void {\n if (sources.has(s[\"id\"])) return;\n sources.set(s[\"id\"], s);\n apply(s);\n for (const l of listeners) l[\"onSourceRegistered\"]?.(s);\n },\n \"unregister\"(id: string): void {\n const s = sources.get(id);\n if (s === undefined) return;\n s[\"_setSink\"](null);\n sources.delete(id);\n for (const l of listeners) l[\"onSourceUnregistered\"]?.(id);\n },\n \"addListener\"(l: Record<string, (...a: any[]) => void>): () => void {\n listeners.add(l);\n for (const s of sources.values()) {\n apply(s);\n l[\"onSourceRegistered\"]?.(s);\n }\n return () => {\n if (listeners.delete(l)) for (const s of sources.values()) apply(s);\n };\n },\n };\n}\n\n// ---------------------------------------------------------------- shapes DevTools reads\n\nconst address = (engine: Engine, p: Pattern, row: StateRow | null): Record<string, unknown> => ({\n \"absolutePathInfo\": { \"pathInfo\": { \"path\": p.path }, \"stateElement\": engine.element },\n \"listIndex\": row === null ? null : { \"indexes\": engine.indexesOf(row) },\n});\n\nfunction propName(kind: number, name: string): string {\n if (kind === K_TEXT) return \"textContent\";\n if (kind === K_CLASS) return `class.${name}`;\n if (kind === K_ATTR) return `attr.${name}`;\n if (kind === K_STYLE) return `style.${name}`;\n return name;\n}\n\n/** A binding as DevTools reads it: `{ binding, absoluteAddress }`. */\ntype Entry = Record<string, unknown>;\n\nconst nodeIds = new WeakMap<Node, number>();\nlet nodeSeq = 0;\nconst idOf = (n: Node): number => {\n let id = nodeIds.get(n);\n if (id === undefined) nodeIds.set(n, (id = ++nodeSeq));\n return id;\n};\n\n/** Every binding of the engine now — materialized ones and row slots alike — by identity. */\nfunction snapshot(engine: Engine, old: Map<string, Entry> | undefined): Map<string, Entry> {\n const out = new Map<string, Entry>();\n const seen = new Set<object>();\n const add = (kind: number, name: string, node: Node, p: Pattern, row: StateRow | null, type: string): void => {\n if (kind === K_EVENT) return;\n const prop = propName(kind, name);\n const r = p.depth === 0 ? null : row;\n const key = `${idOf(node)}|${prop}|${p.path}|${r === null ? \"\" : engine.indexesOf(r).join(\",\")}`;\n if (out.has(key)) return;\n const kept = old?.get(key);\n out.set(key, kept ?? {\n \"binding\": { \"propName\": prop, \"statePathName\": p.path, \"bindingType\": type, \"node\": node, \"replaceNode\": node },\n \"absoluteAddress\": address(engine, p, r),\n });\n };\n const binding = (b: Binding): void => add(b.kind, b.name, b.node, b.pattern, b.row, b.typeName());\n const block = (b: Block): void => {\n if (seen.has(b)) return;\n seen.add(b);\n if (b.bindings !== null) for (const x of b.bindings) binding(x);\n if (b instanceof RowView && b.slots !== null) {\n const lazy: Spec[] = b.plan.lazy;\n for (let k = 0; k < lazy.length; k++) {\n const made = b.bound?.[k];\n if (made !== undefined) binding(made);\n else add(lazy[k].kind, lazy[k].name, b.slots[2 * k] as Node, lazy[k].pattern!, b.row, lazy[k].kind === K_TEXT ? \"text\" : \"prop\");\n }\n }\n if (b.children !== null) for (const v of b.children) view(v);\n };\n const view = (v: ForView | IfView): void => {\n if (seen.has(v)) return;\n seen.add(v);\n if (v instanceof ForView) {\n // the list binding itself: v2 has one per `for`, on the anchor that replaced the template\n add(-1, \"for\", v.anchor, v.list.pattern, v.list.parentRow, \"for\");\n for (const rv of v.rowViews) block(rv);\n } else if (v.current !== null) block(v.current);\n };\n for (const bs of engine.rootBindings.values()) {\n for (const b of bs) {\n binding(b);\n if (b.chain !== null) view(b.chain);\n }\n }\n for (const l of engine.rootLists.values()) {\n if (l.view !== null) view(l.view);\n if (l.extra !== null) for (const v of l.extra) view(v);\n }\n return out;\n}\n\nlet ledgers = new WeakMap<Engine, Map<string, Entry>>();\n\n/** Reports the bindings added and removed since the last look. */\nfunction sync(engine: Engine): void {\n if (sink === null) return;\n const old = ledgers.get(engine);\n const now = live.has(engine) ? snapshot(engine, old) : new Map<string, Entry>();\n if (old !== undefined) for (const [k, e] of old) if (!now.has(k)) sink({ \"type\": \"state:binding-removed\", ...e });\n for (const [k, e] of now) if (old === undefined || !old.has(k)) sink({ \"type\": \"state:binding-added\", ...e });\n ledgers.set(engine, now);\n}\n\n// ---------------------------------------------------------------- the pulls\n\nfunction engineOf(root: Node): Engine {\n const e = byRoot.get(root);\n if (e === undefined) throw new Error(\"[@wcstack/state] devtools: no state tree on this root\");\n return e;\n}\n\nfunction summary(engine: Engine): Record<string, unknown> {\n const list = new Set<string>();\n const element = new Set<string>();\n const getter = new Set<string>();\n const setter = new Set<string>();\n for (const p of engine.patterns.all()) {\n for (let k = 1; k <= p.depth; k++) list.add(p.lists[k]!.path);\n if (p.last === \"*\") element.add(p.path);\n if (p.getter !== null) getter.add(p.path);\n if (p.setter !== null) setter.add(p.path);\n }\n const t = engine.target;\n return {\n \"rootNode\": engine.root,\n \"element\": engine.element,\n \"paths\": { \"list\": list, \"element\": element, \"getter\": getter, \"setter\": setter },\n \"commandTokenNames\": new Set(Object.keys(engine.commands)),\n \"eventTokenNames\": new Set(engine.events.keys()),\n \"staticDependency\": new Map(),\n \"dynamicDependency\": new Map(),\n \"watchPaths\": t.$watch !== null && typeof t.$watch === \"object\" ? new Set(Object.keys(t.$watch)) : null,\n \"keyedListPaths\": t.$listKeys !== null && typeof t.$listKeys === \"object\" ? new Set(Object.keys(t.$listKeys)) : null,\n };\n}\n\nfunction keyedSubscriptions(engine: Engine): Record<string, unknown>[] {\n const out: Record<string, unknown>[] = [];\n for (const p of engine.patterns.all()) {\n const subs = p.eqSubs;\n const lists = p.eqIndexWatchers?.length ?? 0;\n if ((subs === null || subs.size === 0) && lists === 0) continue;\n let rows = 0;\n if (subs !== null) for (const s of subs.values()) rows += s.size;\n let lastValue: unknown;\n try { lastValue = p.depth === 0 ? engine.readUntracked(p, null) : undefined; } catch { lastValue = undefined; }\n out.push({ \"path\": p.path, \"tracked\": false, \"rows\": rows, \"keys\": subs === null ? 0 : subs.size, \"lists\": lists, \"lastValue\": lastValue });\n }\n return out;\n}\n\nfunction createSource(): Source {\n return {\n \"id\": `state:${Math.random().toString(36).slice(2, 10)}`,\n \"kind\": \"state\",\n \"packageVersion\": VERSION,\n \"getStateElements\": () => [...live].map(summary),\n \"overlays\": () => [],\n \"keyedSubscriptions\": (root: Node) => keyedSubscriptions(engineOf(root)),\n \"keys\"(root: Node): string[] {\n const t = engineOf(root).target;\n return Object.keys(t).filter((k) => {\n if (k.includes(\"*\") || k[0] === \"$\") return false;\n const d = Object.getOwnPropertyDescriptor(t, k)!;\n return d.get !== undefined || typeof d.value !== \"function\";\n });\n },\n \"read\"(root: Node, path: string, indexes?: number[]): unknown {\n const el = engineOf(root).element as any;\n let v: unknown;\n el.createState(\"readonly\", (s: any) => { v = s.$resolve(path, indexes ?? []); });\n return v;\n },\n \"write\"(root: Node, path: string, value: unknown, indexes?: number[]): void {\n const el = engineOf(root).element as any;\n el.createState(\"writable\", (s: any) => { s.$resolve(path, indexes ?? [], value); });\n },\n \"_setSink\"(next: Sink | null): void {\n const attached = sink === null && next !== null;\n sink = next;\n // detached: the ledgers go — an attach after it is told every binding there, and none of\n // their nodes is held meanwhile\n if (next === null) ledgers = new WeakMap();\n // what the add-ons notice ($watch fired / threw / cut, a path that does not resolve), with the\n // tree it came from (`stateElement`): built only while a DevTools is attached\n hooks.noticed = next && ((engine, event) => sink?.({ ...event, \"stateElement\": engine.element }));\n // a DevTools that attaches late sees the bindings there already\n if (attached) queueMicrotask(() => { for (const e of live) sync(e); });\n },\n };\n}\n\n// ---------------------------------------------------------------- the hooks\n\nconst wrapped = new WeakSet<Token>();\n\nfunction wrapTokens(engine: Engine): void {\n const wrap = (t: Token, kind: \"command\" | \"event\"): void => {\n if (wrapped.has(t)) return;\n wrapped.add(t);\n const emit = t.emit;\n t.emit = (...args: unknown[]) => {\n if (sink !== null) sink({ \"type\": \"state:token-emit\", \"kind\": kind, \"tokenName\": t.name, \"args\": args, \"subscriberCount\": t.size, \"stateElement\": engine.element });\n return emit.apply(t, args);\n };\n };\n for (const t of Object.values(engine.commands)) wrap(t, \"command\");\n for (const t of engine.events.values()) wrap(t, \"event\");\n}\n\nconst batches = new WeakMap<Engine, Set<unknown>>();\n\nexport function devtoolsElement(engine: Engine, phase: string): void {\n if (phase === \"mounting\" || phase === \"reset\") wrapTokens(engine);\n if (phase === \"connected\") {\n if (live.has(engine)) return;\n live.add(engine);\n sink?.({ \"type\": \"state:element-registered\", \"rootNode\": engine.root, \"element\": engine.element });\n sync(engine);\n } else if (phase === \"disconnected\") {\n live.delete(engine);\n sync(engine);\n sink?.({ \"type\": \"state:element-unregistered\", \"rootNode\": engine.root, \"element\": engine.element });\n }\n}\n\nexport function devtoolsWritten(engine: Engine, p: Pattern, row: StateRow | null, old: unknown, value: unknown, direct: boolean): void {\n if (sink === null) return;\n const a = address(engine, p, p.depth === 0 ? null : row);\n let batch = batches.get(engine);\n if (batch === undefined) batches.set(engine, (batch = new Set()));\n batch.add(a);\n if (direct) sink({ \"type\": \"state:write\", \"absoluteAddress\": a, \"value\": value, \"oldValue\": old, \"hasOldValue\": true });\n}\n\nexport function devtoolsDrained(engine: Engine): void {\n if (sink === null) return;\n const batch = batches.get(engine);\n batches.delete(engine);\n if (batch !== undefined) sink({ \"type\": \"state:update-batch\", \"addresses\": batch });\n sync(engine);\n}\n\nexport function devtoolsFailed(_engine: Engine, error: unknown, b: Binding): void {\n sink?.({ \"type\": \"state:binding-apply-error\", \"path\": b.pattern.path, \"bindingType\": b.typeName(), \"error\": error });\n}\n\nexport function registerSource(): void {\n if (typeof document === \"undefined\" || document.documentElement?.hasAttribute(\"data-wcs-server\")) return;\n const g = globalThis as any;\n const registry = g[HOOK] ?? (g[HOOK] = createRegistry());\n if (registry[\"version\"] !== PROTOCOL) console.warn(`[@wcstack/state] devtools hook registry version ${registry[\"version\"]}, expected ${PROTOCOL}: keeping the existing one.`);\n registry[\"register\"](createSource());\n}\n","/**\n * The DevTools add-on (@wcstack/state/features/devtools): `@wcstack/devtools` over the hook\n * protocol v2 — see src/devtools/devtools.ts.\n */\nimport { chain, hooks, type Feature } from \"../hooks\";\nimport { devtoolsDrained, devtoolsElement, devtoolsFailed, devtoolsWritten, registerSource } from \"../devtools/devtools\";\n\nexport const devtools: Feature = {\n name: \"devtools\",\n hooks,\n install(): void {\n hooks.element = chain(hooks.element, devtoolsElement);\n hooks.written = chain(hooks.written, devtoolsWritten);\n hooks.drained = chain(hooks.drained, devtoolsDrained);\n hooks.failed = chain(hooks.failed, devtoolsFailed);\n registerSource();\n },\n};\nexport default devtools;\n"],"mappings":"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","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import{b as e,c as t,h as n,j as a}from"../chunks/chunk-GU7IAIWW.js";import{a as s,d as i,f as r}from"../chunks/chunk-JCQTA35B.js";import{e as o}from"../chunks/chunk-MZVF2WEY.js";import"../chunks/chunk-PTFWXISY.js";import{b as l}from"../chunks/chunk-UE6JK2ZA.js";import{a as d,b as c,c as u,e as f,j as h}from"../chunks/chunk-SJRJALR4.js";function $(e,t,n){if(Math.abs(e.length-t.length)>n)return n+1;let a=new Array(t.length+1),s=new Array(t.length+1);for(let e=0;e<=t.length;e++)a[e]=e;for(let n=1;n<=e.length;n++){s[0]=n;for(let i=1;i<=t.length;i++){let r=e[n-1]===t[i-1]?0:1;s[i]=Math.min(a[i]+1,s[i-1]+1,a[i-1]+r)}for(let e=0;e<=t.length;e++)a[e]=s[e]}return a[t.length]}function p(e,t){if(0===e.length)return"";let n=e.toLowerCase(),a=null,s=3;for(let e of t){let t=$(n,e.toLowerCase(),2);t<s&&(a=e,s=t)}return null!==a?` Did you mean "${a}"?`:""}var m=" Validate statically: npx @wcstack/lint <file>.",g=["","binding-syntax","template-syntax","binding-path-missing","binding-type-expectation","filter-unknown","filter-arity","getter-cycle","getter-depth-exceeded","index-arity","index-param-range","recursion-unsupported","token-misconfigured","token-undeclared","wildcard-rank","spread-no-bindable","declaration-alias","name-alias"],w=e=>{let t=g[e/100|0];return t?`[wcs/${t}] `:""},b=["enableMustache","sameValueGuard","enableDirectionalInitialSync"],y=e=>null==e?String(e):e instanceof Date?"a Date":Array.isArray(e)?"an array":"string"==typeof e?`a string (${JSON.stringify(e.length>32?e.slice(0,32)+"…":e)})`:"object"==typeof e?"an object":`a ${typeof e} (${String(e)})`,v=["","","class.","attr.","style."],k=(e,t)=>`<${e}${t.map((e,t)=>t%2?`="${e}"`:` ${e}`).join("")}>`,x="https://github.com/wcstack/wcstack/blob/main/docs/csp.md",j={1:()=>"$scan was removed (use $watch or $on)",2:e=>`"${e}" is a getter without a setter`,3:e=>`no row for "${e}"`,4:(e,t)=>`cannot write "${e}": its parent is ${t}`,5:e=>`"${e}" is not a method`,6:e=>`$getAll("${e}"): no loop level in common with the context`,7:e=>`$eqIndex("${e}") needs a list row scope.`,8:()=>"This state is readonly.",9:e=>`$setAll("${e}") needs indexes ([] for every match)`,10:(e,t)=>`$setAll("${e}", …, { spread: true }) needs an array of ${t} values`,11:()=>`updates did not settle after ${e} passes`,41:()=>`render chain depth limit exceeded (${t} drains that rendering itself started); bindings for this batch were not applied.`,12:(e,t,n,a)=>`binding "${n?(v[a]??"")+n:e}: ${t}" failed to apply.`,13:(e,t)=>`failed to load "${e}": ${t}`,14:()=>"this <wcs-state> failed to initialize; create a new one",15:()=>"state is not initialized",16:e=>`no <script> with id "${e}"`,42:()=>`The inline <script> of <wcs-state> was blocked by Content-Security-Policy. Inline state is evaluated through a blob: URL: give the page's nonce to the <script> that loads @wcstack/state, or allow blob: in script-src. Moving the state into an external file (src="./state.js") needs neither. See ${x}`,43:e=>`Failed to evaluate the inline <script> of <wcs-state>: ${e}. If this page sets a Content-Security-Policy, see ${x}`,17:e=>`a subscriber of token "${e}" threw.`,18:e=>`${e} must be an array of strings.`,19:e=>`${e} entries must be non-empty strings.`,20:(e,t,n)=>`${e} entry "${t}" conflicts with the reserved namespace name "${n}".`,21:(e,t)=>`${e} entry "${t}" is duplicated.`,22:()=>"$on must be an object of handlers.",23:e=>`$on entry "${e}" is not declared in $eventTokens.`,24:e=>`$on entry "${e}" must be a function.`,25:e=>`view-transition naming-limit (${e}) reached.`,26:e=>`filter ${e} requires at least one option`,27:e=>`filter ${e} requires a number as option`,28:(e,t)=>`filter ${e} requires a number value, not ${y(t)}${"string"==typeof t?` — put |number before |${e}, or convert it where it is read`:""}`,29:(e,t)=>`filter ${e} requires a date value (a Date), not ${y(t)}${"string"==typeof t||"number"==typeof t?" — make the Date where it is read: a getter returning new Date(…)":""}${"string"==typeof t&&/^\d{4}-\d\d-\d\d$/.test(t)?`. A date-only string is a day, not a moment: new Date(${JSON.stringify(t)}) is midnight UTC, the day before west of Greenwich — new Date(y, m - 1, d) is that day where the page is`:""}`,52:(e,t)=>`filter ${e} takes a style of full, long, medium or short, not "${t}"${/\/|^UTC$/.test(t)?` — a time zone is the third argument, after the locale and the style, and an empty argument keeps its default: ${e}(,,${t}), ${e}(en-US,long,${t})`:""}`,53:e=>`filter currency takes an ISO 4217 currency code (JPY, USD, EUR), not "${e}"`,54:(e,t)=>`filter ${e} takes an IANA time zone (Asia/Tokyo, America/New_York, UTC), not "${t}"`,30:e=>`filter ${e} requires an array value`,31:()=>"init=/sync= modifiers require enableDirectionalInitialSync.",33:(e,t)=>`Unknown binding modifier "${e}" in "${t}".`,34:e=>`Binding modifier "${e}" may only be specified once.`,35:(e,t)=>`Invalid ${e} modifier value "${t}".`,36:()=>"Event bindings only allow init=none.",37:(e,t)=>`Binding type "${e}" does not support init=${t}.`,38:e=>`Property "${e}" is not declared by wcBindable.`,39:(e,t)=>`init=${e} is incompatible with wcBindable member "${t}".`,40:e=>`sync=connect requires observable property "${e}".`,44:(e,t)=>`${e}: "${t}" is not one of its options, or not of the option's type.${"bootstrapState"===e&&b.includes(t)?" 4.0 moved it to the state's $behavior.":""}`,45:()=>"a re-set state may not change $behavior: create the element again.",47:()=>'a second <wcs-state> on the same root: there is one state tree per root — graft a subtree with <wcs-state mount="path"> (v1\'s name="…" is gone: read the mounted state by its path).',48:e=>`the locale "${e}" (<html lang> or bootstrapState's locale) is not a language tag Intl takes (en-US, not en_US): the locale filters use "en".`,46:()=>'$features must be an array of add-on names (["temporal", "formats"]).',49:(e,...t)=>`${k(e,t)} failed to initialize.`,50:(e,...t)=>`${k(e,t)} $connectedCallback failed.`,51:(e,...t)=>`${k(e,t)} $disconnectedCallback failed.`,101:e=>`Invalid bindText: "${e}". Missing ':' separator between propPart and statePart.`,102:(e,t)=>`"${e}": "${t}" takes no modifiers or filters on its left side — write "${t}:".`,103:e=>`"${e}": "else" takes no value — write "else:".`,104:e=>`Invalid spread binding "${e}": spread target path is required.`,105:e=>`Invalid spread binding "${e}": filters are not allowed on spread targets.`,106:e=>`"${e}": a leading "." binds an element property by name — write a non-empty property that is not a namespace (class, attr, style, command, eventToken, state).`,107:(e,t)=>`unterminated ${e} quote in the filter arguments "(${t})". Close the quote.`,108:e=>`Invalid filter format: missing closing parenthesis in "${e}".`,109:e=>`Invalid filter format: missing opening parenthesis in "${e}".`,110:e=>`Invalid filter format: ")" comes before "(" in "${e}".`,111:(e,t)=>`"${e}": unexpected "${t}" after the filter's closing ")" — separate filters with "|" (write "${e.slice(0,e.lastIndexOf(")")+1)}|${t}").`,112:e=>`an empty filter in "${e}" — remove the extra "|" or name the filter.`,113:(e,t)=>`"${e}" is not a filter name: a modifier list "#${t}" comes before the input filters, not inside one`,114:e=>`"${e}" is not a filter name: "#" cannot appear in one.`,115:e=>`"${e}": a binding takes one modifier list after a single "#"`,116:e=>`"${e}": the left side of a binding must name a property — write "<property>: <path>" (modifiers and input filters come after the name).`,117:(e,t)=>`"${e}" has ${t} path segments — the limit is 512.`,32:e=>`"${e}": the "@name" selector was removed in v2 — there is a single state tree. Mount the named state onto the tree (<wcs-state mount="...">) and read it by its path prefix instead.`,120:e=>`"${e}": a state path cannot go through "__proto__" or "prototype" (it would reach every object's prototype).`,121:e=>`"${e}": "for:" takes no filters — a row is "<path>.<index>", so the rows of a filtered list would name other elements. Declare a getter that returns the filtered list and loop over it ("for: <getter>").`,122:(e,t)=>"class"===t?`"${e}": "class:" needs a class name — "class.NAME:" toggles one class (a bare "class:" would set an element property named "class", which does nothing). To set the whole class attribute, bind "className:".`:`"${e}": "attr:" needs an attribute name — "attr.NAME:" sets one attribute (a bare "attr:" would set an element property named "attr", which does nothing).`,119:e=>`"${e}": the right side of a binding must name a state path — write "<property>: <path>" (a path segment cannot be empty; "." alone and a leading "." are the loop-relative shorthand).`,201:e=>`Invalid bindText: "${e}". 'if', 'elseif', 'else', and 'for' bindings must be single binding.`,202:e=>`"${e}:" must follow an "if:" template`,204:e=>`a "${e}:" template at the top of inserted content was not rendered, as it would render beside itself out of the inserter's reach: wrap it in an element.`,203:e=>`"${e}:" replaces its element, so it cannot be used inside a "for" / "if" template (a row or branch keeps its nodes by position): bind innerHTML: on a wrapper element instead.`,301:e=>`Path "${e}" does not exist on the state tree.`,401:(e,t)=>`class.${e} needs a boolean, got ${t}.`,501:e=>`filter not found: ${e}.`,601:(e,t,n)=>`filter "${e}" requires at least ${t} argument(s) (${n} given).`,602:(e,t,n)=>`filter "${e}" accepts at most ${t} argument(s) (${n} given).`,701:e=>`"${e}" depends on itself`,801:e=>`"${e}"`,901:(e,t,n,a)=>`${e}("${t}") takes ${n} index(es), got ${a}.`,902:(e,t,n,a)=>`${e}("${t}") takes at most ${n} index(es), got ${a}.`,1001:e=>`"${e}": list index parameters run from $1 to $128.`,1101:e=>`"${e}" uses "**", which is not accepted here.`,1201:(e,t)=>`"${e}: ${t}": the right-hand side must be $command.<name>`,1202:(e,t)=>`<${e}> declares no static wcBindable (${t}).${!e.includes("-")&&t.startsWith("command.")?" A native element's command needs the add-on @wcstack/state/features/native-commands.":""}`,1203:(e,t)=>`<${e}> declares no command "${t}".`,1204:(e,t)=>`<${e}> declares no property "${t}".`,1205:(e,t,n)=>`<${e}> has no command "${t}" (a native <${e}>'s commands: ${n}).`,1301:e=>`eventToken "${e}" is not declared in $eventTokens.`,1302:e=>`"$command.${e}" is not declared in $commandTokens.`,1401:(e,t,n=0)=>`"${e}" needs ${t} enclosing loop level(s); the scope provides ${n}.`,1402:e=>`"${e}" is relative: it needs an enclosing "for" template`,1403:(e,t,n)=>`"${e}" ranges over the rows of "${t}", but the enclosing "for" template at that level renders "${n}".`,1501:(e,t)=>`<${e}> declares no static wcBindable (${t}).`,1601:(e,t)=>`${e} was removed: write ${t}.`,1701:(e,t)=>`${e} was removed: write ${t}.`};function S(e,t){let n=j[e];return void 0===n?`${w(e)}#${e} ${t.join(" ")}`:w(e)+n(...t)}var T=new Set(["binding-syntax","template-syntax","filter-unknown","filter-arity","index-arity","wildcard-rank","token-undeclared","binding-path-missing","index-param-range"]),A=[[/no loop level in common with the context/,"; pass indexes ([] for all)."],[/"([^"#]+)#([^"]*)" is not a filter name: a modifier list .* comes before the input filters/,' — write "<property>#$2|$1".'],[/\[wcs\/recursion-unsupported\]/," It is only meaningful in a $recursion declaration, in a recursive getter key, and in the path argument of $getAll / $setAll — and only when the state declares a $recursion anchor."],[/must be single binding/,' Put the structural binding alone in its own data-wcs (e.g. <template data-wcs="for: items">).'],[/\[wcs\/wildcard-rank\] .* needs \d+ enclosing/,' Wrap it in that many "for" templates, or use $resolve(path, indexes) to name the row explicitly.'],[/\[wcs\/wildcard-rank\] .* ranges over the rows of/,' A "*" in a binding is the row of the loop around it: read a row of another list in a getter, with $resolve(path, indexes).'],[/\[wcs\/binding-type-expectation\] class\.([^ ]+)/,' Write "class.$1: path|truthy" to toggle on truthiness.'],[/path segments — the limit/," Every prefix of a path is interned, so the cost grows with the square of the depth."],[/\[wcs\/index-arity\] \$resolve/,' $resolve takes one index per "*"; $getAll / $setAll take at most that many (fewer expands the rest).'],[/"([^"#]+)#[^"]*" is not a filter name: "#" cannot appear in one/,' Modifiers belong on the left side of the binding, before the ":" — write "$1" here.']],O={inc:"add",dec:"sub",fix:"toFixed",uc:"upper",lc:"lower",cap:"capitalize",rep:"repeat",rev:"reverse",pad:"padStart",null:"nullIfEmpty"};function W(e,t,n){let a=(void 0!==t&&e.includes("[wcs/filter-unknown]")?function(e){if("substr"===e)return' "substr" was removed in 4.0 — write slice(start, start + length): slice takes the end index, not a length.';let t=Object.hasOwn(O,e)?O[e]:null;return null===t?null:` "${e}" was renamed "${t}" in 3.2 and removed in 4.0 — write "${t}".`}(t):null)??(void 0!==t&&void 0!==n?p(t,n):"");for(let[t,n]of A){let s=t.exec(e);null!==s&&(a+=n.replace(/\$(\d)/g,(e,t)=>s[Number(t)]))}let s=/"([^"#]+)#([^"]+)": a binding takes one modifier list/.exec(e);null!==s&&(a+=` — write "${s[1]}#${s[2].split("#").join(",")}".`),e.includes("[wcs/filter-unknown]")&&(e.includes("formats add-on")?a+=' On a split auto page: features="formats" on the root, or "$features": ["formats"].':i.some(r)||(a+=' No formatting filters are installed — add the formats add-on: installFeatures([formats]) from "@wcstack/state/features/formats" (a split auto page: features="formats", or "$features").'));let o=/\[wcs\/([\w-]+)\]/.exec(e);return null!==o&&T.has(o[1])&&!/ path segments — the limit is |inserted content was not rendered|formats add-on/.test(e)&&(a+=m),a}var M=new WeakMap,I=new WeakMap,P=new WeakSet,N=new WeakSet;function D(e,t){for(let n=e;null!==n&&n!==Object.prototype;n=Object.getPrototypeOf(n)){let e=Object.getOwnPropertyDescriptor(n,t);if(void 0!==e)return e}}function U(e){let t=new Set;for(let n=e;null!==n&&n!==Object.prototype;n=Object.getPrototypeOf(n))for(let e of Object.getOwnPropertyNames(n))"$"!==e[0]&&"constructor"!==e&&t.add(e);return[...t]}function q(e,t){let n=[];for(let e=t;null!==e;e=e.a)n.unshift(e);let a=t=>null===t?null:function(e,t){let n=t.t.split("."),a=n.findIndex((e,t)=>t>0&&/^\d/.test(e));return a<0||n.indexOf("*",a)>=0||void 0!==D(e.target,t.t)?.get?t:e.O.bt(o(t.t).o)}(e,t);return n.some(e=>null!=a(e)?.getter)?null:C(e,n,0,e.target,a)}function C(e,t,n,a,s){for(;n<t.length;n++){let i=t[n];if(null===a||"object"!=typeof a)return null;if("*"===i.s){if(!Array.isArray(a)||0===a.length)return null;let i=null;for(let r of a){let a=C(e,t,n+1,r,s);if(null===a)return null;if(null===i)i=a;else if(a.seg===i.seg)for(let e of a.names)i.names.includes(e)||i.names.push(e)}return i}if(Array.isArray(a)&&/^\d+$/.test(i.s)){if(Number(i.s)>=a.length)return null;a=a[Number(i.s)];continue}let r=D(a,i.s);if(void 0===r&&null===i.a&&e.nt.has(i.s))return null;if(void 0===r){let r=U(a),o=s(i.a);for(let t of e.O.all())t.a===o&&null!==t.getter&&r.push(t.s);return n>0&&0===r.length?null:{seg:i.s,names:r,r:t.slice(0,n).some(e=>"*"===e.s)}}if(void 0!==r.get||void 0!==r.set)return null;a=r.value}return null}function z(e){P.has(e)||(P.add(e),setTimeout(()=>function(e){P.delete(e);let t=M.get(e);if(void 0===t)return;let n=I.get(e);void 0===n&&I.set(e,n=new Set);let a=new Map(t),i=new Map;for(let s of e.O.all()){let e=null===s.a||n.has(s)||t.has(s)?void 0:s.B.find(e=>!e.hn);void 0!==e&&(i.set(s,e),a.set(s,3))}for(let[t,r]of a){if(n.has(t))continue;n.add(t);let a=q(e,t);if(null===a)continue;let l=H.get(e),c=t.a;for(;null!==c&&!l?.has(c);)c=c.a;if(null!==c)continue;let u=[...e.root?.querySelectorAll(`${s.tagNames.state}[mount]`)??[]].find(e=>!N.has(e)&&(t.t+".").startsWith(e.getAttribute("mount")+"."));if(void 0!==u){n.delete(t),u.initializePromise.then(()=>{N.add(u),z(e)});continue}let f=e.O.bt(o(t.t).o),h="";if(void 0!==f&&f!==t&&null!==f.getter){let e=f.h.slice(1).map((e,t)=>`for: ${0===t?e.t:e.t.slice(f.h[t].t.length+2)}`);h=` The getter "${f.t}" is declared for the rows of ${e.join(" → ")}; a list named by an index has rows of its own.`}let $=p(a.seg,a.names);if((a.r||3===r)&&""===$&&""===h)continue;let[g,w,b]=1===r?["watch-path-missing","$watch path","watch"]:2===r?["post-update-path-missing","$postUpdate path","postUpdate"]:3===r?["read-path-missing","Path","getter"]:["binding-path-missing","Bound path","binding"];d.ct?.(e,{type:"state:path-unresolved",source:b,path:t.t,missingSegment:a.seg}),console.warn(`[@wcstack/state] [wcs/${g}] ${w} "${t.t}"${3===r?` read by the getter "${i.get(t).t}"`:""} does not resolve on the state tree: "${a.seg}" is not declared.${$}${h} ${2===r?"The call updates nothing.":3===r?"The getter reads undefined.":"Updates to this path will be silently dropped."}${m}`)}}(e),0))}function E(e,t,n=!1){L(e,t,n?1:0)}function L(e,t,n){if("$"===t.t[0]||t.t.includes("#")||0===n&&null===t.a)return;let a=M.get(e);void 0===a&&M.set(e,a=new Map),a.has(t)||a.set(t,n),z(e)}var B=new WeakSet,J=!1,R=new WeakMap,H=new WeakMap;function _(e,t,n,a,s,i,r){if(!r)return;let o=H.get(e);void 0===o&&H.set(e,o=new Set),o.add(t)}function F(e,t){let n=R.get(e),a=t.s;if(null!==t.a||J||void 0===n||n.has(a)||"$"===a[0]||e.nt.has(a))return;let i=p(a,[...n]);n.add(a),""!==i&&![...e.root?.querySelectorAll(`${s.tagNames.state}[mount]`)??[]].some(e=>`${e.getAttribute("mount")}.`.startsWith(`${a}.`))&&console.warn(`[@wcstack/state] [wcs/write-path-missing] "${a}" is not declared: writing it creates a new key.${i}${m}`)}var G=new WeakSet;function V(e){if(G.has(e))return;G.add(e);let t=e.emit,n=!1;e.emit=(...a)=>(0===e.size&&!n&&(n=!0,console.warn(`[@wcstack/state] [wcs/command-token-unbound] "$command.${e.name}" was emitted with no subscriber and is lost: its element is not defined or rendered yet (emit from $renderedCallback), or no command. binding takes it.${m}`)),t.apply(e,a))}var Y=new WeakMap;function K(e,t,n){let a=e.target;for(let e of t.split("."))a=null==a?void 0:D(a,e)?.value;if("function"!=typeof a||!String(a).includes("currentTarget"))return;let s=Y.get(e);void 0===s&&Y.set(e,s=new Set),!s.has(t)&&(s.add(t),console.warn(`[@wcstack/state] [wcs/delegated-current-target] "${t}" reads event.currentTarget, the root for a delegated on${n}:. Write on${n}#direct:, or use event.target.closest(…).${m}`))}var Z=new WeakSet,Q=/\bthis\s*[.[]|=\s*this\b/,X=new WeakSet,ee=e=>{for(let t of["src","state","json"])if(e.hasAttribute(t))return`<${e.localName} ${t}${"json"===t?"":`="${e.getAttribute(t)}"`}>`;return`<${e.localName}>`};function te(e,t){let n=e.element;if("mounting"!==t||!n)return;let a=n.getRootNode();if(X.has(a))return;let i=[...a.querySelectorAll(s.tagNames.state)].filter(e=>e!==n&&!e.hasAttribute("mount")&&!e.hasAttribute("bind-component"));0!==i.length&&(X.add(a),console.warn(`[@wcstack/state] [wcs/second-root] ${i.length+1} root <wcs-state> elements share one root, and there is one state tree per root: ${ee(n)} takes it — its state was ready first, whatever the order in the document — and ${i.map(ee).join(", ")} is refused (#47). Keep one, and graft the others with <wcs-state mount="path">.${m}`))}function ne(e){M.has(e)&&e.Ue.length>0&&z(e)}var ae=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),se=!1;function ie(e,t,s){let i="html"===s.name?"innerHTML":s.name;if(se||!(t instanceof TypeError)||!a(i)||!("trustedTypes"in globalThis))return;se=!0;let r="function"==typeof n()?.createHTML?"The injected policy's createHTML() did not return a TrustedHTML.":"No sanitizing policy is installed, and @wcstack/state deliberately does not pass state values through an identity policy — that would defeat the CSP.";console.error(`[@wcstack/state] Writing to "${i}" was blocked by Trusted Types (require-trusted-types-for 'script'). ${r}\nInstall a sanitizing policy before the first binding is applied:\n globalThis[Symbol.for("wcstack.trustedTypes.policy")] =\n trustedTypes.createPolicy("my-app", { createHTML: (s) => DOMPurify.sanitize(s) });\nOr bind the value as text instead of HTML. See docs/csp.md section 7.`,{element:s.c,property:i})}var re=new WeakMap;function oe(e,t,n){let a=e[t],s=void 0===n?void 0===a?null:`the event carried no detail (undefined) while element.${t} is ${typeof a}`:null===n||"object"!=typeof n||!Object.prototype.hasOwnProperty.call(n,t)||null!==a&&"object"==typeof a?null:`the event's detail is an object with a "${t}" key while element.${t} is ${typeof a}`;if(null===s)return;let i=re.get(e);void 0===i&&re.set(e,i=new Set),!i.has(t)&&(i.add(t),console.warn(`[@wcstack/state] [wcs/default-getter-mismatch] <${e.localName}> "${t}": ${s}. With no getter, state receives e.detail as-is. Dispatch the value itself as detail, or declare getter (e.g. (e) => e.detail.${t}, or (e) => e.target.${t}) on that wcBindable property.`))}var le=[["$streams","$stream"],["$updatedCallback","$renderedCallback"]],de={$trackDependency:"$dependOn",$untrackDependency:"$untracked"},ce={name:"diagnostics",hooks:d,install(){d._o=W,d.Vo=S,d.xo=E,d.detail=oe,d.Ge=c(d.Ge,ie);let e=d.fe;d.fe=(t,n)=>{(function(e){void 0!==e.$scan&&l(1);for(let[t,n]of le)void 0!==e[t]&&l(1601,[t,n])})(n),e?.(t,n),function(e){let t=e.$recursion;if(null===t||"object"!=typeof t)return;let n=Object.entries(t);if(1!==n.length||"string"!=typeof n[0][1])return;let[a,s]=n[0];if(!a.endsWith(".*")||!s.endsWith(".*"))return;let i=a.slice(0,-2),r=s.slice(0,-2),o=`.${s}`,l=`${i}.**`,d=U(e),c=d.filter(e=>e.startsWith(l)).map(e=>e.slice(l.length)),u=e=>h(`[wcs/recursion-declaration-invalid] ${e}`);for(let e of c){(e===`.${r}`||e.startsWith(`.${r}.`))&&u(`"${l}${e}" names the recursion structure itself (the "${r}" lists): recursive getters compute values over the nodes.`);for(let t of c)t.length>e.length&&t.endsWith(e)&&new RegExp(`^(?:${ae(o)})+$`).test(t.slice(0,t.length-e.length))&&u(`"${l}${e}" and "${l}${t}" expand to the same concrete path at different depths (they differ by whole repetitions of "${s}"). Rename one of them.`);let t=new RegExp(`^${ae(a)}(?:${ae(o)})*${ae(e)}$`);for(let n of d)!n.includes("**")&&t.test(n)&&u(`"${n}" is already defined on the state, so the recursive getter "${l}${e}" cannot expand to it.`)}}(n),function(e){let t=D(e,"$on")?.value;if(null!==t&&"object"==typeof t)for(let e of Object.keys(t)){let n=t[e];"function"!=typeof n||Z.has(n)||!Q.test(String(n))||(Z.add(n),console.warn(`[@wcstack/state] [wcs/on-handler-this] The $on handler "${e}" uses this. A $on handler is called as ${e}(state, event): this is undefined there, so it throws when the event arrives — write ${e}(state, event) { state.x = … }.${m}`))}}(n),function(e){I.delete(e),M.has(e)&&z(e)}(t),function(e){if(B.has(e))return;B.add(e);let t=e.Jn,n=t.$postUpdate;t.$postUpdate=t=>{J=!0;try{n(t)}finally{J=!1}let a=e.O.bt(o(t).o);void 0!==a&&L(e,a,2)}}(t),function(e){if(void 0!==Object.getOwnPropertyDescriptor(e,"commands")?.set)return;let t=e.commands;Object.defineProperty(e,"commands",{configurable:!0,get:()=>t,set:e=>{t=e;for(let t of Object.values(e))V(t)}})}(t),R.set(t,new Set(U(n)))},d.handlerThrew=K,d.element=c(d.element,te),d.re=c(c(d.re,F),_),d.me=c(d.me,ne),d.it=u(f,d.it,(e,t)=>Object.hasOwn(de,t)?l(1701,[t,de[t]]):void 0)}},ue=ce;export{ue as default,ce as diagnostics};
1
+ import{b as e,c as t,g as n,i as a,k as s}from"../chunks/chunk-IYPAK7PO.js";import{a as i,d as r,f as o}from"../chunks/chunk-AKTGQ6TC.js";import{e as l}from"../chunks/chunk-NAV7FBTI.js";import"../chunks/chunk-KBQKAD3I.js";import{b as d}from"../chunks/chunk-E3XSBW55.js";import{a as c,b as u,c as f,e as h,j as $}from"../chunks/chunk-LPJFTEVT.js";function p(e,t,n){if(Math.abs(e.length-t.length)>n)return n+1;let a=new Array(t.length+1),s=new Array(t.length+1);for(let e=0;e<=t.length;e++)a[e]=e;for(let n=1;n<=e.length;n++){s[0]=n;for(let i=1;i<=t.length;i++){let r=e[n-1]===t[i-1]?0:1;s[i]=Math.min(a[i]+1,s[i-1]+1,a[i-1]+r)}for(let e=0;e<=t.length;e++)a[e]=s[e]}return a[t.length]}function m(e,t){if(0===e.length)return"";let n=e.toLowerCase(),a=null,s=3;for(let e of t){let t=p(n,e.toLowerCase(),2);t<s&&(a=e,s=t)}return null!==a?` Did you mean "${a}"?`:""}var g=" Validate statically: npx @wcstack/lint <file>.",w=["","binding-syntax","template-syntax","binding-path-missing","binding-type-expectation","filter-unknown","filter-arity","getter-cycle","getter-depth-exceeded","index-arity","index-param-range","recursion-unsupported","token-misconfigured","token-undeclared","wildcard-rank","spread-no-bindable","declaration-alias","name-alias"],y=e=>{let t=w[e/100|0];return t?`[wcs/${t}] `:""},b=["enableMustache","sameValueGuard","enableDirectionalInitialSync"],v=e=>null==e?String(e):e instanceof Date?"a Date":Array.isArray(e)?"an array":"string"==typeof e?`a string (${JSON.stringify(e.length>32?e.slice(0,32)+"…":e)})`:"object"==typeof e?"an object":`a ${typeof e} (${String(e)})`,k=["","","class.","attr.","style."],x=(e,t)=>`<${e}${t.map((e,t)=>t%2?`="${e}"`:` ${e}`).join("")}>`,S="https://github.com/wcstack/wcstack/blob/main/docs/csp.md",T={1:()=>"$scan was removed (use $watch or $on)",2:e=>`"${e}" is a getter without a setter`,3:e=>`no row for "${e}"`,4:(e,t)=>`cannot write "${e}": its parent is ${t}`,5:e=>`"${e}" is not a method`,6:e=>`$getAll("${e}"): no loop level in common with the context`,7:e=>`$eqIndex("${e}") needs a list row scope.`,8:()=>"This state is readonly.",9:e=>`$setAll("${e}") needs indexes ([] for every match)`,10:(e,t)=>`$setAll("${e}", …, { spread: true }) needs an array of ${t} values`,11:()=>`updates did not settle after ${e} passes`,41:()=>`render chain depth limit exceeded (${t} drains that rendering itself started); bindings for this batch were not applied.`,12:(e,t,n,a)=>`binding "${n?(k[a]??"")+n:e}: ${t}" failed to apply.`,13:(e,t)=>`failed to load "${e}": ${t}`,14:()=>"this <wcs-state> failed to initialize; create a new one",15:()=>"state is not initialized",16:e=>`no <script> with id "${e}"`,42:()=>`The inline <script> of <wcs-state> was blocked by Content-Security-Policy. Inline state is evaluated through a blob: URL: give the page's nonce to the <script> that loads @wcstack/state, or allow blob: in script-src. Moving the state into an external file (src="./state.js") needs neither. See ${S}`,43:e=>`Failed to evaluate the inline <script> of <wcs-state>: ${e}. If this page sets a Content-Security-Policy, see ${S}`,17:e=>`a subscriber of token "${e}" threw.`,18:e=>`${e} must be an array of strings.`,19:e=>`${e} entries must be non-empty strings.`,20:(e,t,n)=>`${e} entry "${t}" conflicts with the reserved namespace name "${n}".`,21:(e,t)=>`${e} entry "${t}" is duplicated.`,22:()=>"$on must be an object of handlers.",23:e=>`$on entry "${e}" is not declared in $eventTokens.`,24:e=>`$on entry "${e}" must be a function.`,25:e=>`view-transition naming-limit (${e}) reached.`,26:e=>`filter ${e} requires at least one option`,27:e=>`filter ${e} requires a number as option`,28:(e,t)=>`filter ${e} requires a number value, not ${v(t)}${"string"==typeof t?` — put |number before |${e}, or convert it where it is read`:""}`,29:(e,t)=>`filter ${e} requires a date value (a Date), not ${v(t)}${"string"==typeof t||"number"==typeof t?" — make the Date where it is read: a getter returning new Date(…)":""}${"string"==typeof t&&/^\d{4}-\d\d-\d\d$/.test(t)?`. A date-only string is a day, not a moment: new Date(${JSON.stringify(t)}) is midnight UTC, the day before west of Greenwich — new Date(y, m - 1, d) is that day where the page is`:""}`,52:(e,t)=>`filter ${e} takes a style of full, long, medium or short, not "${t}"${/\/|^UTC$/.test(t)?` — a time zone is the third argument, after the locale and the style, and an empty argument keeps its default: ${e}(,,${t}), ${e}(en-US,long,${t})`:""}`,53:e=>`filter currency takes an ISO 4217 currency code (JPY, USD, EUR), not "${e}"`,54:(e,t)=>`filter ${e} takes an IANA time zone (Asia/Tokyo, America/New_York, UTC), not "${t}"`,30:e=>`filter ${e} requires an array value`,31:()=>"init=/sync= modifiers require enableDirectionalInitialSync.",33:(e,t)=>`Unknown binding modifier "${e}" in "${t}".`,34:e=>`Binding modifier "${e}" may only be specified once.`,35:(e,t)=>`Invalid ${e} modifier value "${t}".`,36:()=>"Event bindings only allow init=none.",37:(e,t)=>`Binding type "${e}" does not support init=${t}.`,38:e=>`Property "${e}" is not declared by wcBindable.`,39:(e,t)=>`init=${e} is incompatible with wcBindable member "${t}".`,40:e=>`sync=connect requires observable property "${e}".`,44:(e,t)=>`${e}: "${t}" is not one of its options, or not of the option's type.${"bootstrapState"===e&&b.includes(t)?" 4.0 moved it to the state's $behavior.":""}`,45:()=>"a re-set state may not change $behavior: create the element again.",47:()=>'a second <wcs-state> on the same root: there is one state tree per root — graft a subtree with <wcs-state mount="path"> (v1\'s name="…" is gone: read the mounted state by its path).',48:e=>`the locale "${e}" (<html lang> or bootstrapState's locale) is not a language tag Intl takes (en-US, not en_US): the locale filters use "en".`,46:()=>'$features must be an array of add-on names (["temporal", "formats"]).',49:(e,...t)=>`${x(e,t)} failed to initialize.`,50:(e,...t)=>`${x(e,t)} $connectedCallback failed.`,51:(e,...t)=>`${x(e,t)} $disconnectedCallback failed.`,101:e=>`Invalid bindText: "${e}". Missing ':' separator between propPart and statePart.`,102:(e,t)=>`"${e}": "${t}" takes no modifiers or filters on its left side — write "${t}:".`,103:e=>`"${e}": "else" takes no value — write "else:".`,104:e=>`Invalid spread binding "${e}": spread target path is required.`,105:e=>`Invalid spread binding "${e}": filters are not allowed on spread targets.`,106:e=>`"${e}": a leading "." binds an element property by name — write a non-empty property that is not a namespace (class, attr, style, command, eventToken, state).`,107:(e,t)=>`unterminated ${e} quote in the filter arguments "(${t})". Close the quote.`,108:e=>`Invalid filter format: missing closing parenthesis in "${e}".`,109:e=>`Invalid filter format: missing opening parenthesis in "${e}".`,110:e=>`Invalid filter format: ")" comes before "(" in "${e}".`,111:(e,t)=>`"${e}": unexpected "${t}" after the filter's closing ")" — separate filters with "|" (write "${e.slice(0,e.lastIndexOf(")")+1)}|${t}").`,112:e=>`an empty filter in "${e}" — remove the extra "|" or name the filter.`,113:(e,t)=>`"${e}" is not a filter name: a modifier list "#${t}" comes before the input filters, not inside one`,114:e=>`"${e}" is not a filter name: "#" cannot appear in one.`,115:e=>`"${e}": a binding takes one modifier list after a single "#"`,116:e=>`"${e}": the left side of a binding must name a property — write "<property>: <path>" (modifiers and input filters come after the name).`,117:(e,t)=>`"${e}" has ${t} path segments — the limit is 512.`,32:e=>`"${e}": the "@name" selector was removed in v2 — there is a single state tree. Mount the named state onto the tree (<wcs-state mount="...">) and read it by its path prefix instead.`,120:e=>`"${e}": a state path cannot go through "__proto__" or "prototype" (it would reach every object's prototype).`,121:e=>`"${e}": "for:" takes no filters — a row is "<path>.<index>", so the rows of a filtered list would name other elements. Declare a getter that returns the filtered list and loop over it ("for: <getter>").`,122:(e,t)=>"class"===t?`"${e}": "class:" needs a class name — "class.NAME:" toggles one class (a bare "class:" would set an element property named "class", which does nothing). To set the whole class attribute, bind "className:".`:`"${e}": "attr:" needs an attribute name — "attr.NAME:" sets one attribute (a bare "attr:" would set an element property named "attr", which does nothing).`,119:e=>`"${e}": the right side of a binding must name a state path — write "<property>: <path>" (a path segment cannot be empty; "." alone and a leading "." are the loop-relative shorthand).`,201:e=>`Invalid bindText: "${e}". 'if', 'elseif', 'else', and 'for' bindings must be single binding.`,202:e=>`"${e}:" must follow an "if:" template`,204:e=>`a "${e}:" template at the top of inserted content was not rendered, as it would render beside itself out of the inserter's reach: wrap it in an element.`,203:e=>`"${e}:" replaces its element, so it cannot be used inside a "for" / "if" template (a row or branch keeps its nodes by position): bind innerHTML: on a wrapper element instead.`,301:e=>`Path "${e}" does not exist on the state tree.`,401:(e,t)=>`class.${e} needs a boolean, got ${t}.`,501:e=>`filter not found: ${e}.`,601:(e,t,n)=>`filter "${e}" requires at least ${t} argument(s) (${n} given).`,602:(e,t,n)=>`filter "${e}" accepts at most ${t} argument(s) (${n} given).`,701:e=>`"${e}" depends on itself`,801:e=>`"${e}"`,901:(e,t,n,a)=>`${e}("${t}") takes ${n} index(es), got ${a}.`,902:(e,t,n,a)=>`${e}("${t}") takes at most ${n} index(es), got ${a}.`,1001:e=>`"${e}": list index parameters run from $1 to $128.`,1101:e=>`"${e}" uses "**", which is not accepted here.`,1201:(e,t)=>`"${e}: ${t}": the right-hand side must be $command.<name>`,1202:(e,t)=>`<${e}> declares no static wcBindable (${t}).${!e.includes("-")&&t.startsWith("command.")?" A native element's command needs the add-on @wcstack/state/features/native-commands.":""}`,1203:(e,t)=>`<${e}> declares no command "${t}".`,1204:(e,t)=>`<${e}> declares no property "${t}".`,1205:(e,t,n)=>`<${e}> has no command "${t}" (a native <${e}>'s commands: ${n}).`,1301:e=>`eventToken "${e}" is not declared in $eventTokens.`,1302:e=>`"$command.${e}" is not declared in $commandTokens.`,1401:(e,t,n=0)=>`"${e}" needs ${t} enclosing loop level(s); the scope provides ${n}.`,1402:e=>`"${e}" is relative: it needs an enclosing "for" template`,1403:(e,t,n)=>`"${e}" ranges over the rows of "${t}", but the enclosing "for" template at that level renders "${n}".`,1501:(e,t)=>`<${e}> declares no static wcBindable (${t}).`,1601:(e,t)=>`${e} was removed: write ${t}.`,1701:(e,t)=>`${e} was removed: write ${t}.`};function A(e,t){let n=T[e];return void 0===n?`${y(e)}#${e} ${t.join(" ")}`:y(e)+n(...t)}var j=new Set(["binding-syntax","template-syntax","filter-unknown","filter-arity","index-arity","wildcard-rank","token-undeclared","binding-path-missing","index-param-range"]),O=[[/no loop level in common with the context/,"; pass indexes ([] for all)."],[/"([^"#]+)#([^"]*)" is not a filter name: a modifier list .* comes before the input filters/,' — write "<property>#$2|$1".'],[/\[wcs\/recursion-unsupported\]/," It is only meaningful in a $recursion declaration, in a recursive getter key, and in the path argument of $getAll / $setAll — and only when the state declares a $recursion anchor."],[/must be single binding/,' Put the structural binding alone in its own data-wcs (e.g. <template data-wcs="for: items">).'],[/\[wcs\/wildcard-rank\] .* needs \d+ enclosing/,' Wrap it in that many "for" templates, or use $resolve(path, indexes) to name the row explicitly.'],[/\[wcs\/wildcard-rank\] .* ranges over the rows of/,' A "*" in a binding is the row of the loop around it: read a row of another list in a getter, with $resolve(path, indexes).'],[/\[wcs\/binding-type-expectation\] class\.([^ ]+)/,' Write "class.$1: path|truthy" to toggle on truthiness.'],[/path segments — the limit/," Every prefix of a path is interned, so the cost grows with the square of the depth."],[/\[wcs\/index-arity\] \$resolve/,' $resolve takes one index per "*"; $getAll / $setAll take at most that many (fewer expands the rest).'],[/"([^"#]+)#[^"]*" is not a filter name: "#" cannot appear in one/,' Modifiers belong on the left side of the binding, before the ":" — write "$1" here.']],W={inc:"add",dec:"sub",fix:"toFixed",uc:"upper",lc:"lower",cap:"capitalize",rep:"repeat",rev:"reverse",pad:"padStart",null:"nullIfEmpty"};function M(e,t,n){let a=(void 0!==t&&e.includes("[wcs/filter-unknown]")?function(e){if("substr"===e)return' "substr" was removed in 4.0 — write slice(start, start + length): slice takes the end index, not a length.';let t=Object.hasOwn(W,e)?W[e]:null;return null===t?null:` "${e}" was renamed "${t}" in 3.2 and removed in 4.0 — write "${t}".`}(t):null)??(void 0!==t&&void 0!==n?m(t,n):"");for(let[t,n]of O){let s=t.exec(e);null!==s&&(a+=n.replace(/\$(\d)/g,(e,t)=>s[Number(t)]))}let s=/"([^"#]+)#([^"]+)": a binding takes one modifier list/.exec(e);null!==s&&(a+=` — write "${s[1]}#${s[2].split("#").join(",")}".`),e.includes("[wcs/filter-unknown]")&&(e.includes("formats add-on")?a+=' On a split auto page: features="formats" on the root, or "$features": ["formats"].':r.some(o)||(a+=' No formatting filters are installed — add the formats add-on: installFeatures([formats]) from "@wcstack/state/features/formats" (a split auto page: features="formats", or "$features").'));let i=/\[wcs\/([\w-]+)\]/.exec(e);return null!==i&&j.has(i[1])&&!/ path segments — the limit is |inserted content was not rendered|formats add-on/.test(e)&&(a+=g),a}var I=new WeakMap,N=new WeakMap,P=new WeakSet,C=new WeakSet;function E(e,t){for(let n=e;null!==n&&n!==Object.prototype;n=Object.getPrototypeOf(n)){let e=Object.getOwnPropertyDescriptor(n,t);if(void 0!==e)return e}}function q(e){let t=new Set;for(let n=e;null!==n&&n!==Object.prototype;n=Object.getPrototypeOf(n))for(let e of Object.getOwnPropertyNames(n))"$"!==e[0]&&"constructor"!==e&&t.add(e);return[...t]}function D(e,t){let n=[];for(let e=t;null!==e;e=e.c)n.unshift(e);let a=t=>null===t?null:function(e,t){let n=t.t.split("."),a=n.findIndex((e,t)=>t>0&&/^\d/.test(e));return a<0||n.indexOf("*",a)>=0||void 0!==E(e.target,t.t)?.get?t:e.C.vt(l(t.t).o)}(e,t);return n.some(e=>null!=a(e)?.getter)?null:U(e,n,0,e.target,a)}function U(e,t,n,a,s){for(;n<t.length;n++){let i=t[n];if(null===a||"object"!=typeof a)return null;if("*"===i.s){if(!Array.isArray(a)||0===a.length)return null;let i=null;for(let r of a){let a=U(e,t,n+1,r,s);if(null===a)return null;if(null===i)i=a;else if(a.seg===i.seg)for(let e of a.names)i.names.includes(e)||i.names.push(e)}return i}if(Array.isArray(a)&&/^\d+$/.test(i.s)){if(Number(i.s)>=a.length)return null;a=a[Number(i.s)];continue}let r=E(a,i.s);if(void 0===r&&null===i.c&&e.nt.has(i.s))return null;if(void 0===r){let r=q(a),o=s(i.c);for(let t of e.C.all())t.c===o&&null!==t.getter&&r.push(t.s);return n>0&&0===r.length?null:{seg:i.s,names:r,r:t.slice(0,n).some(e=>"*"===e.s)}}if(void 0!==r.get||void 0!==r.set)return null;a=r.value}return null}function L(e){P.has(e)||(P.add(e),setTimeout(()=>function(e){P.delete(e);let t=I.get(e);if(void 0===t)return;let n=N.get(e);void 0===n&&N.set(e,n=new Set);let a=new Map(t),s=new Map;for(let i of e.C.all()){let e=null===i.c||n.has(i)||t.has(i)?void 0:i.M.find(e=>!e.gn);void 0!==e&&(s.set(i,e),a.set(i,3))}for(let[t,r]of a){if(n.has(t))continue;n.add(t);let a=D(e,t);if(null===a)continue;let o=F.get(e),d=t.c;for(;null!==d&&!o?.has(d);)d=d.c;if(null!==d)continue;let u=[...e.root?.querySelectorAll(`${i.tagNames.state}[mount]`)??[]].find(e=>!C.has(e)&&(t.t+".").startsWith(e.getAttribute("mount")+"."));if(void 0!==u){n.delete(t),u.initializePromise.then(()=>{C.add(u),L(e)});continue}let f=e.C.vt(l(t.t).o),h="";if(void 0!==f&&f!==t&&null!==f.getter){let e=f.h.slice(1).map((e,t)=>`for: ${0===t?e.t:e.t.slice(f.h[t].t.length+2)}`);h=` The getter "${f.t}" is declared for the rows of ${e.join(" → ")}; a list named by an index has rows of its own.`}let $=m(a.seg,a.names);if((a.r||3===r)&&""===$&&""===h)continue;let[p,w,y]=1===r?["watch-path-missing","$watch path","watch"]:2===r?["post-update-path-missing","$postUpdate path","postUpdate"]:3===r?["read-path-missing","Path","getter"]:["binding-path-missing","Bound path","binding"];c.ut?.(e,{type:"state:path-unresolved",source:y,path:t.t,missingSegment:a.seg}),console.warn(`[@wcstack/state] [wcs/${p}] ${w} "${t.t}"${3===r?` read by the getter "${s.get(t).t}"`:""} does not resolve on the state tree: "${a.seg}" is not declared.${$}${h} ${2===r?"The call updates nothing.":3===r?"The getter reads undefined.":"Updates to this path will be silently dropped."}${g}`)}}(e),0))}function H(e,t,n=!1){z(e,t,n?1:0)}function z(e,t,n){if("$"===t.t[0]||t.t.includes("#")||0===n&&null===t.c)return;let a=I.get(e);void 0===a&&I.set(e,a=new Map),a.has(t)||a.set(t,n),L(e)}var B=new WeakSet,R=!1,_=new WeakMap,F=new WeakMap;function G(e,t,n,a,s,i,r){if(!r)return;let o=F.get(e);void 0===o&&F.set(e,o=new Set),o.add(t)}function J(e,t){let n=_.get(e),a=t.s;if(null!==t.c||R||void 0===n||n.has(a)||"$"===a[0]||e.nt.has(a))return;let s=m(a,[...n]);n.add(a),""!==s&&![...e.root?.querySelectorAll(`${i.tagNames.state}[mount]`)??[]].some(e=>`${e.getAttribute("mount")}.`.startsWith(`${a}.`))&&console.warn(`[@wcstack/state] [wcs/write-path-missing] "${a}" is not declared: writing it creates a new key.${s}${g}`)}var K=new WeakSet;function V(e){if(K.has(e))return;K.add(e);let t=e.emit,n=!1;e.emit=(...a)=>(0===e.size&&!n&&(n=!0,console.warn(`[@wcstack/state] [wcs/command-token-unbound] "$command.${e.name}" was emitted with no subscriber and is lost: its element is not defined or rendered yet (emit from $renderedCallback), or no command. binding takes it.${g}`)),t.apply(e,a))}var Y=new WeakMap;function Q(e,t,n){let a=e.target;for(let e of t.split("."))a=null==a?void 0:E(a,e)?.value;if("function"!=typeof a||!String(a).includes("currentTarget"))return;let s=Y.get(e);void 0===s&&Y.set(e,s=new Set),!s.has(t)&&(s.add(t),console.warn(`[@wcstack/state] [wcs/delegated-current-target] "${t}" reads event.currentTarget, the root for a delegated on${n}:. Write on${n}#direct:, or use event.target.closest(…).${g}`))}var X=new WeakSet,Z=/\bthis\s*[.[]|=\s*this\b/,ee=new WeakSet,te=e=>{for(let t of["src","state","json"])if(e.hasAttribute(t))return`<${e.localName} ${t}${"json"===t?"":`="${e.getAttribute(t)}"`}>`;return`<${e.localName}>`};function ne(e,t){let n=e.element;if("mounting"!==t||!n)return;let a=n.getRootNode();if(ee.has(a))return;let s=[...a.querySelectorAll(i.tagNames.state)].filter(e=>e!==n&&!e.hasAttribute("mount")&&!e.hasAttribute("bind-component"));0!==s.length&&(ee.add(a),console.warn(`[@wcstack/state] [wcs/second-root] ${s.length+1} root <wcs-state> elements share one root, and there is one state tree per root: ${te(n)} takes it — its state was ready first, whatever the order in the document — and ${s.map(te).join(", ")} is refused (#47). Keep one, and graft the others with <wcs-state mount="path">.${g}`))}var ae=new Set,se=new WeakSet,ie=/^(?:(?:attr|class|style)\.|(?:html|innerHTML|outerHTML|srcdoc)$)/;function re(e){try{return null!==e&&n(e).some(e=>"spread"===e.b||"eventToken"===e.ye[0]||"prop"===e.b&&!ie.test(e.he))}catch{return!1}}function oe(e,t){for(let n of e.xo){null!==n.E&&oe(n.E,t);for(let e of n.W??[])oe(e.E,t);if(n.we&&5!==n.i){let a=e.It;for(let t of e.an[n.a])a=a.childNodes[t];t.add(a.localName)}}}function le(e,t){if("connected"!==t||se.has(e)||document.documentElement.hasAttribute("data-wcs-server"))return;se.add(e);let n=new WeakRef(e),a=()=>{setTimeout(()=>{let e=n.deref();e?.element?.isConnected&&function(e){let t=new Set;for(let n of e.H.values())for(let e of[n.S,...n.j??[]])null!==e&&oe(e.E,t);for(let n of e.ie.values())for(let e of n)for(let n of e.I?.W??[])oe(n.E,t);let n=i.bindAttributeName;for(let a of e.root.querySelectorAll("*")){let e=a.localName;!e.includes("-")||ae.has(e)||void 0!==(a.customElementRegistry??customElements).get(e)||!t.has(e)&&!re(a.getAttribute(n))||null!==a.closest(`[${n}-ignore]`)||(ae.add(e),console.warn(`[@wcstack/state] [wcs/element-undefined] <${e}> is not defined 5 s after the page was ready; its bindings wait for it (property bindings, textContent: included, spreads, commands, event tokens — attr.*, class.*, style.* and on*: apply at once). Load the ${e.startsWith("wcs-")?"wcstack package that defines it (its /auto)":"script that defines it"}.`))}}(e)},5e3)};"complete"===document.readyState?a():addEventListener("load",a,{once:!0})}var de=new WeakSet;function ce(e,t){let n,a=t.o;if(!(de.has(a)||t.d.length>0)){try{n=e.v(a,t.oe)}catch{return}null==n||Array.isArray(n)||queueMicrotask(()=>{null===t.S||de.has(a)||(de.add(a),console.warn(`[@wcstack/state] [wcs/binding-type-expectation] "for: ${a.t}" needs an array, not ${v(n)}: it renders no rows (null and undefined render none on purpose).${g}`))})}}function ue(e){I.has(e)&&e.Ue.length>0&&L(e);for(let t of e.H.values())null!==t.S&&null!==t.R&&ce(e,t)}var fe=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),he=!1;function $e(e,t,n){let i="html"===n.name?"innerHTML":n.name;if(he||!(t instanceof TypeError)||!s(i)||!("trustedTypes"in globalThis))return;he=!0;let r="function"==typeof a()?.createHTML?"The injected policy's createHTML() did not return a TrustedHTML.":"No sanitizing policy is installed, and @wcstack/state deliberately does not pass state values through an identity policy — that would defeat the CSP.";console.error(`[@wcstack/state] Writing to "${i}" was blocked by Trusted Types (require-trusted-types-for 'script'). ${r}\nInstall a sanitizing policy before the first binding is applied:\n globalThis[Symbol.for("wcstack.trustedTypes.policy")] =\n trustedTypes.createPolicy("my-app", { createHTML: (s) => DOMPurify.sanitize(s) });\nOr bind the value as text instead of HTML. See docs/csp.md section 7.`,{element:n.a,property:i})}var pe=new WeakMap;function me(e,t,n){let a=e[t],s=void 0===n?void 0===a?null:`the event carried no detail (undefined) while element.${t} is ${typeof a}`:null===n||"object"!=typeof n||!Object.prototype.hasOwnProperty.call(n,t)||null!==a&&"object"==typeof a?null:`the event's detail is an object with a "${t}" key while element.${t} is ${typeof a}`;if(null===s)return;let i=pe.get(e);void 0===i&&pe.set(e,i=new Set),!i.has(t)&&(i.add(t),console.warn(`[@wcstack/state] [wcs/default-getter-mismatch] <${e.localName}> "${t}": ${s}. With no getter, state receives e.detail as-is. Dispatch the value itself as detail, or declare getter (e.g. (e) => e.detail.${t}, or (e) => e.target.${t}) on that wcBindable property.`))}var ge=[["$streams","$stream"],["$updatedCallback","$renderedCallback"]],we={$trackDependency:"$dependOn",$untrackDependency:"$untracked"},ye={name:"diagnostics",hooks:c,install(){c.Vo=M,c.Ho=A,c.Ro=H,c.detail=me,c.Ge=u(c.Ge,$e);let e=c.fe;c.fe=(t,n)=>{(function(e){void 0!==e.$scan&&d(1);for(let[t,n]of ge)void 0!==e[t]&&d(1601,[t,n])})(n),e?.(t,n),function(e){let t=e.$recursion;if(null===t||"object"!=typeof t)return;let n=Object.entries(t);if(1!==n.length||"string"!=typeof n[0][1])return;let[a,s]=n[0];if(!a.endsWith(".*")||!s.endsWith(".*"))return;let i=a.slice(0,-2),r=s.slice(0,-2),o=`.${s}`,l=`${i}.**`,d=q(e),c=d.filter(e=>e.startsWith(l)).map(e=>e.slice(l.length)),u=e=>$(`[wcs/recursion-declaration-invalid] ${e}`);for(let e of c){(e===`.${r}`||e.startsWith(`.${r}.`))&&u(`"${l}${e}" names the recursion structure itself (the "${r}" lists): recursive getters compute values over the nodes.`);for(let t of c)t.length>e.length&&t.endsWith(e)&&new RegExp(`^(?:${fe(o)})+$`).test(t.slice(0,t.length-e.length))&&u(`"${l}${e}" and "${l}${t}" expand to the same concrete path at different depths (they differ by whole repetitions of "${s}"). Rename one of them.`);let t=new RegExp(`^${fe(a)}(?:${fe(o)})*${fe(e)}$`);for(let n of d)!n.includes("**")&&t.test(n)&&u(`"${n}" is already defined on the state, so the recursive getter "${l}${e}" cannot expand to it.`)}}(n),function(e){let t=E(e,"$on")?.value;if(null!==t&&"object"==typeof t)for(let e of Object.keys(t)){let n=t[e];"function"!=typeof n||X.has(n)||!Z.test(String(n))||(X.add(n),console.warn(`[@wcstack/state] [wcs/on-handler-this] The $on handler "${e}" uses this. A $on handler is called as ${e}(state, event): this is undefined there, so it throws when the event arrives — write ${e}(state, event) { state.x = … }.${g}`))}}(n),function(e){N.delete(e),I.has(e)&&L(e)}(t),function(e){if(B.has(e))return;B.add(e);let t=e.Jn,n=t.$postUpdate;t.$postUpdate=t=>{R=!0;try{n(t)}finally{R=!1}let a=e.C.vt(l(t).o);void 0!==a&&z(e,a,2)}}(t),function(e){if(void 0!==Object.getOwnPropertyDescriptor(e,"commands")?.set)return;let t=e.commands;Object.defineProperty(e,"commands",{configurable:!0,get:()=>t,set:e=>{t=e;for(let t of Object.values(e))V(t)}})}(t),_.set(t,new Set(q(n)))},c.handlerThrew=Q,c.element=u(u(c.element,ne),le),c.se=u(u(c.se,J),G),c.me=u(c.me,ue),c.st=u(c.st,ce),c.it=f(h,c.it,(e,t)=>Object.hasOwn(we,t)?d(1701,[t,we[t]]):void 0)}},be=ye;export{be as default,ye as diagnostics};
2
2
  //# sourceMappingURL=diagnostics.js.map