mancha 0.20.2 → 0.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/expressions/eval.js +8 -2
- package/dist/expressions/eval.js.map +1 -1
- package/dist/expressions/eval.test.js +48 -0
- package/dist/expressions/eval.test.js.map +1 -1
- package/dist/{interfaces-BnxInboi.d.ts → interfaces-BR8ZL61m.d.ts} +59 -5
- package/dist/mancha.js +24 -24
- package/dist/plugins.js +5 -4
- package/dist/plugins.js.map +1 -1
- package/dist/renderer-Dk63KOGx.js +30 -0
- package/dist/renderer.d.ts +23 -3
- package/dist/renderer.js +24 -4
- package/dist/renderer.js.map +1 -1
- package/dist/safe_browser.d.ts +1 -1
- package/dist/safe_browser.js +1 -1
- package/dist/store.d.ts +36 -2
- package/dist/store.js +69 -7
- package/dist/store.js.map +1 -1
- package/docs/01_syntax.md +2 -1
- package/docs/03_reactivity.md +98 -0
- package/docs/09_performance.md +30 -8
- package/package.json +1 -1
- package/dist/renderer-gpXY5UCp.js +0 -30
package/docs/09_performance.md
CHANGED
|
@@ -33,7 +33,7 @@ $.debug('off');
|
|
|
33
33
|
| `effects` | Same as lifecycle | Above + individual effect timings |
|
|
34
34
|
| `verbose` | Same as lifecycle | Above + all internal logging |
|
|
35
35
|
|
|
36
|
-
The `lifecycle` level is the recommended default for performance analysis. It tracks all the data needed for `
|
|
36
|
+
The `lifecycle` level is the recommended default for performance analysis. It tracks all the data needed for `getPerformanceReport()` while keeping console output minimal.
|
|
37
37
|
|
|
38
38
|
## Performance Reports
|
|
39
39
|
|
|
@@ -44,7 +44,7 @@ const { $ } = Mancha;
|
|
|
44
44
|
$.debug('lifecycle');
|
|
45
45
|
await $.mount(document.body);
|
|
46
46
|
|
|
47
|
-
const report = $.
|
|
47
|
+
const report = $.getPerformanceReport();
|
|
48
48
|
console.log(report);
|
|
49
49
|
```
|
|
50
50
|
|
|
@@ -85,6 +85,28 @@ console.log(report);
|
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
## Measuring Specific User Flows
|
|
89
|
+
|
|
90
|
+
By default, performance data resets on each `mount()` call. To measure a specific user flow (like a button click or data update) after the initial mount, use `clearPerformanceReport()`:
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
const { $ } = Mancha;
|
|
94
|
+
$.debug('lifecycle');
|
|
95
|
+
await $.mount(document.body);
|
|
96
|
+
|
|
97
|
+
// Setup is complete. Now measure a specific user flow.
|
|
98
|
+
$.clearPerformanceReport();
|
|
99
|
+
|
|
100
|
+
// Perform the user flow you want to measure.
|
|
101
|
+
$.items = await fetchLargeDataset();
|
|
102
|
+
|
|
103
|
+
// Get the report for just this flow.
|
|
104
|
+
const report = $.getPerformanceReport();
|
|
105
|
+
console.log('User flow effects:', report.effects.slowest);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This is useful for optimizing specific interactions without the noise of initial mount timing.
|
|
109
|
+
|
|
88
110
|
## Effect Identification
|
|
89
111
|
|
|
90
112
|
Each effect is identified by a unique ID composed of the directive name, element identifier, and expression. The element identifier is determined by the following priority:
|
|
@@ -127,7 +149,7 @@ This helps identify render bottlenecks without needing to analyze the full perfo
|
|
|
127
149
|
|
|
128
150
|
### 1. Profile Before Optimizing
|
|
129
151
|
|
|
130
|
-
Always measure before making changes. Enable debugging, interact with your application, then check `
|
|
152
|
+
Always measure before making changes. Enable debugging, interact with your application, then check `getPerformanceReport()`:
|
|
131
153
|
|
|
132
154
|
```js
|
|
133
155
|
$.debug('lifecycle');
|
|
@@ -135,7 +157,7 @@ await $.mount(document.body);
|
|
|
135
157
|
|
|
136
158
|
// Interact with your application...
|
|
137
159
|
|
|
138
|
-
console.table($.
|
|
160
|
+
console.table($.getPerformanceReport().effects.slowest);
|
|
139
161
|
```
|
|
140
162
|
|
|
141
163
|
### 2. Add data-perfid to Critical Elements
|
|
@@ -155,7 +177,7 @@ For elements in loops or those with complex expressions, add `data-perfid` for c
|
|
|
155
177
|
High observer counts on a single key can indicate performance issues:
|
|
156
178
|
|
|
157
179
|
```js
|
|
158
|
-
const report = $.
|
|
180
|
+
const report = $.getPerformanceReport();
|
|
159
181
|
for (const [key, count] of Object.entries(report.observers.byKey)) {
|
|
160
182
|
if (count > 50) {
|
|
161
183
|
console.warn(`Key "${key}" has ${count} observers - consider restructuring`);
|
|
@@ -171,10 +193,10 @@ Performance data automatically resets when `mount()` is called. This means each
|
|
|
171
193
|
$.debug('lifecycle');
|
|
172
194
|
|
|
173
195
|
await $.mount(element1);
|
|
174
|
-
console.log($.
|
|
196
|
+
console.log($.getPerformanceReport()); // Data for element1
|
|
175
197
|
|
|
176
198
|
await $.mount(element2);
|
|
177
|
-
console.log($.
|
|
199
|
+
console.log($.getPerformanceReport()); // Fresh data for element2 only
|
|
178
200
|
```
|
|
179
201
|
|
|
180
202
|
### 5. Disable in Production
|
|
@@ -201,7 +223,7 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
201
223
|
Mancha.debug('lifecycle');
|
|
202
224
|
await Mancha.mount(document.body);
|
|
203
225
|
|
|
204
|
-
const report = Mancha.
|
|
226
|
+
const report = Mancha.getPerformanceReport();
|
|
205
227
|
|
|
206
228
|
// Check which directives are slowest
|
|
207
229
|
console.log('By directive:', report.effects.byDirective);
|
package/package.json
CHANGED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import{safeAnchorEl as e,safeAreaEl as t,safeElement as n}from"safevalues/dom";import{safeAttrPrefix as r}from"safevalues";const i=[r`:`,r`style`,r`class`];function*a(e,t=new Set){let n=new Set,r=Array.from(e.childNodes).filter(e=>!t.has(e));for(yield e;r.length;){let e=r.shift();n.has(e)||(n.add(e),yield e),e.childNodes&&Array.from(e.childNodes).filter(e=>!t.has(e)).forEach(e=>{r.push(e)})}}function o(e,t){return e?.[t]!==void 0}function s(e,t){return typeof e?.[t]==`function`}function c(e){return e.replace(/-./g,e=>e[1].toUpperCase())}function l(e,t){return e.attribs?e.attribs[t]??null:e.getAttribute?.(t)??null}function u(e,t){return e.attribs?t in e.attribs:e.hasAttribute?.(t)??!1}function d(e,t,n=``){return l(e,n+t)||l(e,`data-${t}`)||(e.dataset?.[c(t)]??null)}function f(e,t,n){e.attribs?e.attribs[t]=n:e.setAttribute?.(t,n)}function p(e,t,r){e.attribs?e.attribs[t]=r:n.setPrefixedAttribute(i,e,t,r)}function m(e,t,n){switch(t){case`disabled`:e.disabled=n;return;case`selected`:e.selected=n;return;case`checked`:e.checked=n;return;default:e[t]=n}}function h(e,t){e.attribs?delete e.attribs[t]:e.removeAttribute?.(t)}function g(e,t,n,r=``){u(e,`${r}${t}`)?f(e,`${r}${t}`,n):u(e,`data-${t}`)?f(e,`data-${t}`,n):f(e,`${r}${t}`,n)}function _(e,t,n=``){h(e,`${n}${t}`),h(e,`data-${t}`)}function v(e,t,n){if(e.attribs&&t.attribs)t.attribs[n]=e.attribs[n];else if(n.startsWith(`data-`)){let r=c(n.slice(5));t.dataset&&e.dataset&&(t.dataset[r]=e.dataset[r])}else{let r=e?.getAttribute?.(n);p(t,n,r||``)}}function y(e){return o(e,`firstElementChild`)?e.firstElementChild:Array.from(e.children).find(e=>e.nodeType===1)}function b(e,...t){if(s(e,`replaceWith`)){e.replaceWith(...t);return}else{let n=e,r=n.parentNode;if(!r)return;let i=Array.from(r.childNodes).indexOf(n);n.parentNode=null,t.forEach(e=>{e.parentNode=r}),r.childNodes=[].concat(Array.from(r.childNodes).slice(0,i),t,Array.from(r.childNodes).slice(i+1))}}function x(e,...t){s(e,`replaceChildren`)?e.replaceChildren(...t):(e.childNodes=t,t.forEach(t=>{t.parentNode=e}))}function S(e,t){return s(t,`appendChild`)?e.appendChild(t):(e.childNodes.push(t),t.parentNode=e,t)}function C(e,t){return s(t,`removeChild`)?e.removeChild(t):(x(e,...Array.from(e.childNodes).filter(e=>e!==t)),t)}function w(e,t,n){return n?s(e,`insertBefore`)?e.insertBefore(t,n):(b(n,t,n),t):S(e,t)}function T(e,t=0){return e?e.length<=t?e:`${e.slice(0,t-1)}…`:``}function E(e,t=0){return globalThis.DocumentFragment&&e instanceof DocumentFragment?Array.from(e.childNodes).map(e=>E(e,t)).join(``):T(e.outerHTML||e.nodeValue||String(e),t)}function D(e){return e.includes(`/`)?e.split(`/`).slice(0,-1).join(`/`):``}function O(e){return!e.includes(`://`)&&!e.startsWith(`/`)&&!e.startsWith(`#`)&&!e.startsWith(`data:`)}var k=class e{iterable;constructor(e){this.iterable=e}filter(t){return new e(e.filterGenerator(t,this.iterable))}map(t){return new e(e.mapGenerator(t,this.iterable))}find(e){for(let t of this.iterable)if(e(t))return t}array(){return Array.from(this.iterable)}*generator(){for(let e of this.iterable)yield e}static*filterGenerator(e,t){for(let n of t)e(n)&&(yield n)}static*mapGenerator(e,t){for(let n of t)yield e(n)}static equals(e,t){let n=e[Symbol.iterator](),r=t[Symbol.iterator](),i=n.next(),a=r.next();for(;!i.done&&!a.done;){if(i.value!==a.value)return!1;i=n.next(),a=r.next()}return i.done===a.done}};let A;(function(n){n.resolveIncludes=async function(e,t){let n=e,r=n.tagName?.toLowerCase();if(![`include`,`link`].includes(r)||r===`link`&&l(n,`rel`)!==`subresource`)return;this.log(`include directive found in:
|
|
2
|
-
`,E(e,128)),this.log(`include params:`,t);let i=n.tagName.toLocaleLowerCase()===`link`?`href`:`src`,a=l(n,i);if(!a)throw Error(`"${i}" attribute missing from ${E(e,128)}.`);let o=[];r===`include`&&o.push(`src`),r===`link`&&o.push(`rel`,`href`);let s=t=>{let r=y(t);for(let e of Array.from(n.attributes))r&&!o.includes(e.name)&&v(n,r,e.name);b(e,...t.childNodes)},c={...t,rootDocument:!1,maxdepth:(t?.maxdepth??100)-1};if(c.maxdepth===0)throw Error(`Maximum recursion depth reached.`);if(a.includes(`://`)||a.startsWith(`//`))this.log(`Including remote file from absolute path:`,a),await this.preprocessRemote(a,c).then(s);else if(t?.dirpath?.includes(`://`)||t?.dirpath?.startsWith(`//`)){let e=a.startsWith(`/`)?a:`${t.dirpath}/${a}`;this.log(`Including remote file from relative path:`,e),await this.preprocessRemote(e,c).then(s)}else if(a.charAt(0)===`/`)this.log(`Including local file from absolute path:`,a),await this.preprocessLocal(a,c).then(s);else{let e=t?.dirpath&&t?.dirpath!==`.`?`${t?.dirpath}/${a}`:a;this.log(`Including local file from relative path:`,e),await this.preprocessLocal(e,c).then(s)}},n.rebaseRelativePaths=function(n,r){let i=n,a=i.tagName?.toLowerCase();if(!r?.dirpath)return;let s=l(i,`src`),c=l(i,`href`),u=d(i,`render`,`:`),f=s||c||u;if(!f||!O(f))return;let m=`${r.dirpath}/${f}`;this.log(`Rebasing relative path as:`,m),u?g(i,`render`,m,`:`):o(i,`attribs`)?p(i,s?`src`:`href`,m):a===`img`?i.src=m:a===`a`?e.setHref(i,m):a===`source`||a===`audio`||a===`video`||a===`track`||a===`input`?i.src=m:a===`area`?t.setHref(i,m):this.log(`Unable to rebase relative path for element:`,a)},n.registerCustomElements=function(e,t){let n=e,r=n.tagName?.toLowerCase(),i=(l(n,`is`)||l(n,`alt`))?.toLowerCase();if([`template`,`div`].includes(r)&&i){if(r===`div`&&l(n,`role`)!==`template`)return;if(!this._customElements.has(i)){this.log(`Registering custom element: ${i}\n`,E(n,128));let e=n.content||n,r=Array.from(a(e));for(let e=1;e<r.length;e++)A.rebaseRelativePaths.call(this,r[e],t);this._customElements.set(i,n),n?.parentNode&&C(n.parentNode,n)}}},n.resolveCustomElements=function(e,t){let n=e,r=n.tagName?.toLowerCase(),i=r;if(i===`div`&&(i=l(n,`role`)?.toLowerCase()||i),i&&this._customElements.has(i)){this.log(`Processing custom element: ${i}\n`,E(n,128));let t=this._customElements.get(i),o=(t.content||t).cloneNode(!0),s=y(o);if(s)for(let e of Array.from(n.attributes))(r!==`div`||e.name!==`role`)&&v(n,s,e.name);let c=new k(a(o)).find(e=>e.tagName?.toLowerCase()===`slot`);c&&b(c,...n.childNodes),b(e,...o.childNodes)}},n.resolveTextNodeExpressions=function(e,t){let n=e.nodeValue||``;if(e.nodeType!==3||!n?.trim())return;this.log(`Processing node content value:
|
|
3
|
-
`,T(n,128));let r=new RegExp(/{{ ([^}]+) }}/gm),i=Array.from(n.matchAll(r)).map(e=>e[1]);return this.effect(function(){let t=n;for(let n of i){let r=this.eval(n,{$elem:e});t=t.replace(`{{ ${n} }}`,String(r))}e.nodeValue=t},{directive:`text`,element:e.parentElement??void 0,expression:i.join(`, `)})},n.resolveDataAttribute=async function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`data`,`:`);if(r){this.log(`:data attribute found in:
|
|
4
|
-
`,E(e,128)),_(n,`data`,`:`);let i;o(e,`renderer`)?(i=e.renderer,this.log(`Reusing existing subrenderer for node:`,E(e,64))):(i=this.subrenderer(),m(e,`renderer`,i),this.log(`Created and attached new subrenderer for node:`,E(e,64)));let s=i.eval(r,{$elem:e});if(await Promise.all(Object.entries(s).map(([e,t])=>e.startsWith(`$$`)?(i._store.get(`$rootRenderer`)||i).set(e,t):i._store.set(e,t))),i===this)return;for(let t of a(e,this._skipNodes))this._skipNodes.add(t);await i.mount(e,t)}},n.resolveClassAttribute=function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`class`,`:`);if(r){this.log(`:class attribute found in:
|
|
5
|
-
`,E(e,128)),_(n,`class`,`:`);let t=l(n,`class`)||``;return this.effect(function(){let i=this.eval(r,{$elem:e});p(n,`class`,(i?`${t} ${i}`:t).trim())},{directive:`class`,element:n,expression:r})}},n.resolveTextAttributes=function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`text`,`:`);if(r){this.log(`:text attribute found in:
|
|
6
|
-
`,E(e,128)),_(n,`text`,`:`);let t=t=>this.textContent(e,t);return this.effect(function(){t(this.eval(r,{$elem:e}))},{directive:`:text`,element:n,expression:r})}},n.resolveHtmlAttribute=async function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`html`,`:`);if(r)return this.log(`:html attribute found in:
|
|
7
|
-
`,E(e,128)),_(n,`html`,`:`),this.effect(function(){let i=this.eval(r,{$elem:e});return new Promise(e=>{(async()=>{let r=await this.preprocessString(i,t);await this.renderNode(r),x(n,r),e()})()})},{directive:`:html`,element:n,expression:r})},n.resolveEventAttributes=function(e,t){if(this._skipNodes.has(e))return;let n=e;for(let t of Array.from(n.attributes||[]))if(t.name.startsWith(`:on:`)||t.name.startsWith(`data-on-`)){let r=``,i=[];if(t.name.startsWith(`:on:`)?[r,...i]=t.name.substring(4).split(`.`):t.name.startsWith(`data-on-`)&&([r,...i]=t.name.substring(8).split(`.`)),!r)throw Error(`Invalid event attribute: ${t.name}`);this.log(t.name,`attribute found in:
|
|
8
|
-
`,E(e,128)),_(n,t.name);let a=r===`submit`&&n.tagName.toUpperCase()===`FORM`;e.addEventListener?.(r,n=>((i.includes(`prevent`)||a)&&n.preventDefault(),this.eval(t.value,{$elem:e,$event:n})))}},n.resolveForAttribute=async function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`for`,`:`)?.trim();if(r){this.log(`:for attribute found in:
|
|
9
|
-
`,E(e,128)),_(n,`for`,`:`);for(let t of a(e,this._skipNodes))this._skipNodes.add(t);let i=l(n,`style`)||``;f(n,`style`,`display: none;`);let o=e.parentNode;if(!o)return;let s=this.createElement(`template`,e.ownerDocument);w(o,s,e),C(o,e),`content`in s?S(s.content,e):S(s,e),this.log(`:for template:
|
|
10
|
-
`,E(s,128));let c=r.split(` in `,2);if(c.length!==2)throw Error(`Invalid :for format: \`${r}\`. Expected "{key} in {expression}".`);let u=[],[d,p]=c;await this.effect(function(){let n=this.eval(p,{$elem:e});if(this.log(`:for list items:`,n),u.splice(0,u.length).forEach(e=>{e.parentNode===o&&C(o,e),this._skipNodes.delete(e)}),!Array.isArray(n))return console.error(`Expression did not yield a list: \`${p}\` => \`${n}\``),Promise.resolve();let r=[];for(let a of n){let n=this.subrenderer();n._store.set(d,a);let o=e.cloneNode(!0);f(o,`style`,i),u.push(o),this._skipNodes.add(o),r.push(n.mount(o,t)),this.log(`Rendered list child:
|
|
11
|
-
`,E(o,128))}let a=s.nextSibling;for(let e of u)w(o,e,a);return Promise.all(r)},{directive:`:for`,element:n,expression:r})}},n.resolveBindAttribute=function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`bind`,`:`);if(r){this.log(`:bind attribute found in:
|
|
12
|
-
`,E(e,128));let t=l(n,`:bind:on`)?.split(`,`)||n.dataset?.bindOn?.split(`,`)||[`change`,`input`];_(n,`bind`,`:`),h(n,`:bind:on`),h(n,`data-bind-on`);let i=l(n,`type`)===`checkbox`?`checked`:`value`;!r.includes(`.`)&&!this.has(r)&&this.set(r,``);let a=this;this.effect(function(){let t=this.eval(r,{$elem:e});i===`checked`?n.checked=!!t:(n.value=t,n.value!==t&&t!=null&&a._pendingValueRetries.push(()=>{n.value=t}))},{directive:`:bind`,element:n,expression:r});let o=`${r} = $elem.${i}`;for(let n of t)e.addEventListener(n,()=>this.eval(o,{$elem:e}))}},n.resolveIfAttribute=function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`if`,`:`);if(r){this.log(`:if attribute found in:
|
|
13
|
-
`,E(e,128)),_(n,`if`,`:`);let t=this.createComment(` :if placeholder `,e.ownerDocument);this.effect(function(){this.eval(r,{$elem:e})?!n.parentNode&&t.parentNode&&b(t,n):n.parentNode&&b(n,t)},{directive:`:if`,element:n,expression:r})}},n.resolveShowAttribute=function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`show`,`:`);if(r){this.log(`:show attribute found in:
|
|
14
|
-
`,E(e,128)),_(n,`show`,`:`);let t=n.style?.display===`none`?``:n.style?.display??l(n,`style`)?.split(`;`)?.find(e=>e.split(`:`)[0]===`display`)?.split(`:`)?.at(1)?.trim();this.effect(function(){let i=this.eval(r,{$elem:e});n.style?n.style.display=i?t:`none`:p(n,`style`,`display: ${i?t:`none`};`)},{directive:`:show`,element:n,expression:r})}},n.resolveCustomAttribute=function(e,t){if(this._skipNodes.has(e))return;let n=e;for(let t of Array.from(n.attributes||[])){let r=`:attr:`,i=`data-attr-`;if(t.name.startsWith(r)||t.name.startsWith(i)){this.log(t.name,`attribute found in:
|
|
15
|
-
`,E(e,128)),h(n,t.name);let a=(t.name.split(r,2).at(-1)||``).split(i,2).at(-1)??``;this.effect(function(){f(n,a,this.eval(t.value,{$elem:e}))},{directive:`:attr:${a}`,element:n,expression:t.value})}}},n.resolveCustomProperty=function(e,t){if(this._skipNodes.has(e))return;let n=e;for(let t of Array.from(n.attributes||[])){let r=`:prop:`,i=`data-prop-`;if(t.name.startsWith(r)||t.name.startsWith(i)){this.log(t.name,`property found in:
|
|
16
|
-
`,E(e,128)),h(n,t.name);let a=c((t.name.split(r,2).at(-1)||``).split(i,2).at(-1)??``);this.effect(function(){m(n,a,this.eval(t.value,{$elem:e}))},{directive:`:prop:${a}`,element:n,expression:t.value})}}},n.stripTypes=(e,t)=>{let n=e;l(n,`:types`)&&h(n,`:types`),l(n,`data-types`)&&h(n,`data-types`)},n.resolveRenderAttribute=async function(e,t){if(this._skipNodes.has(e))return;let n=e,r=d(n,`render`,`:`);if(!r)return;this.log(`:render attribute found: ${r}`),_(n,`render`,`:`);let i;o(e,`renderer`)?(i=e.renderer,this.log(`Reusing existing subrenderer for :render:`,E(e,64))):(i=this.subrenderer(),m(n,`renderer`,i)),await i.mount(e,t);for(let t of a(e,this._skipNodes))this._skipNodes.add(t);try{let e=await import(r);typeof e.default==`function`?await e.default(n,i):e.default!==void 0&&console.warn(`Module ${r} default export is not a function`)}catch(e){console.error(`Failed to execute render init from ${r}:`,e)}}})(A||={});function j(){return new URL(globalThis.window?.location?.href||`http://localhost/`)}function M(e){return e.substring(2)}function N(e){return`\$\$${e}`}function P(e){return e.keys().filter(e=>e.startsWith(`$$`))}async function ee(e,t){for(let[n,r]of t.searchParams.entries()){let t=N(n);e.get(t)!==r&&await e.set(t,r)}}function F(e,t,n){let r=M(t),i=!1;if(!n)e.searchParams.has(r)&&(e.searchParams.delete(r),i=!0);else{let t=String(n);e.searchParams.get(r)!==t&&(e.searchParams.set(r,t),i=!0)}return i}function I(e,t){let n=!1;for(let r of P(t))F(e,r,t.get(r))&&(n=!0);n&&globalThis.window?.history?.replaceState({},``,e.toString())}function L(e){return async()=>{let t=j(),n=new Set;for(let[r,i]of t.searchParams.entries()){let t=N(r);n.add(t),e.get(t)!==i&&e.set(t,i)}let r=P(e);for(let t of r)n.has(t)||e.del(t)}}async function te(e){let t=j();await ee(e,t),I(t,e),e.addKeyHandler(/^\$\$/,(e,t)=>{let n=j();F(n,e,t)&&globalThis.window?.history?.replaceState({},``,n.toString())}),globalThis.window?.addEventListener(`popstate`,L(e))}
|
|
17
|
-
/*
|
|
18
|
-
* @license
|
|
19
|
-
* Portions Copyright (c) 2013, the Dart project authors.
|
|
20
|
-
*/
|
|
21
|
-
const R=new Set([`this`,`typeof`]),ne=new Set([`in`]),re=new Set([`+`,`-`,`!`,`typeof`]),ie=new Set([`=`,`+`,`-`,`*`,`/`,`%`,`^`,`==`,`!=`,`>`,`<`,`>=`,`<=`,`||`,`&&`,`??`,`&`,`===`,`!==`,`|`,`in`]),z={"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":2,"??":3,"||":4,"&&":5,"|":6,"^":7,"&":8,"!=":9,"==":9,"!==":9,"===":9,">=":10,">":10,"<=":10,"<":10,in:10,"+":11,"-":11,"%":12,"/":12,"*":12,"(":13,"[":13,".":13,"?.":13,"{":13},B={"+":(e,t)=>e+t,"-":(e,t)=>e-t,"*":(e,t)=>e*t,"/":(e,t)=>e/t,"%":(e,t)=>e%t,"==":(e,t)=>e==t,"!=":(e,t)=>e!=t,"===":(e,t)=>e===t,"!==":(e,t)=>e!==t,">":(e,t)=>e>t,">=":(e,t)=>e>=t,"<":(e,t)=>e<t,"<=":(e,t)=>e<=t,"||":(e,t)=>e||t,"&&":(e,t)=>e&&t,"??":(e,t)=>e??t,"|":(e,t)=>t(e),in:(e,t)=>e in t},V={"+":e=>e,"-":e=>-e,"!":e=>!e,typeof:e=>typeof e};var H=class{empty(){return{type:`Empty`,evaluate(e){return e},getIds(e){return e}}}literal(e){return{type:`Literal`,value:e,evaluate(e){return this.value},getIds(e){return e}}}id(e){return{type:`ID`,value:e,evaluate(e){return this.value===`this`?e:e?.[this.value]},getIds(e){return e.push(this.value),e}}}unary(e,t){let n=V[e];return{type:`Unary`,operator:e,child:t,evaluate(e){return n(this.child.evaluate(e))},getIds(e){return this.child.getIds(e)}}}binary(e,t,n){let r=B[t];return{type:`Binary`,operator:t,left:e,right:n,evaluate(e){if(this.operator===`=`){if(this.left.type!==`ID`&&this.left.type!==`Getter`&&this.left.type!==`Index`)throw Error(`Invalid assignment target: ${this.left}`);let t=this.right.evaluate(e),n,r;return this.left.type===`Getter`?(n=this.left.receiver.evaluate(e),r=this.left.name):this.left.type===`Index`?(n=this.left.receiver.evaluate(e),r=String(this.left.argument.evaluate(e))):this.left.type===`ID`&&(n=e,r=this.left.value),n===void 0?void 0:(n[r]=t,t)}return r(this.left.evaluate(e),this.right.evaluate(e))},getIds(e){return this.left.getIds(e),this.right.getIds(e),e}}}getter(e,t,n){return{type:`Getter`,receiver:e,name:t,optional:n,evaluate(e){let t=this.receiver.evaluate(e);if(!(this.optional&&t==null))return t?.[this.name]},getIds(e){return this.receiver.getIds(e),e}}}invoke(e,t,n,r){if(t!=null&&typeof t!=`string`)throw Error(`method not a string`);return{type:`Invoke`,receiver:e,method:t,arguments:n,optional:r,evaluate(e){let t=this.receiver.evaluate(e);if(this.optional&&t==null)return;let n=this.method?t:e?.this??e,r=this.method?t?.[this.method]:t,i=this.arguments??[],a=[];for(let t of i)if(t?.type===`SpreadElement`){let n=t.evaluate(e);n&&typeof n[Symbol.iterator]==`function`&&a.push(...n)}else a.push(t?.evaluate(e));return r?.apply?.(n,a)},getIds(e){return this.receiver.getIds(e),this.arguments?.forEach(t=>{t?.getIds(e)}),e}}}paren(e){return e}index(e,t,n){return{type:`Index`,receiver:e,argument:t,optional:n,evaluate(e){let t=this.receiver.evaluate(e);if(this.optional&&t==null)return;let n=this.argument.evaluate(e);return t?.[n]},getIds(e){return this.receiver.getIds(e),e}}}ternary(e,t,n){return{type:`Ternary`,condition:e,trueExpr:t,falseExpr:n,evaluate(e){return this.condition.evaluate(e)?this.trueExpr.evaluate(e):this.falseExpr.evaluate(e)},getIds(e){return this.condition.getIds(e),this.trueExpr.getIds(e),this.falseExpr.getIds(e),e}}}map(e){return{type:`Map`,properties:e,evaluate(t){let n={};if(e&&this.properties)for(let e of this.properties)e.type===`SpreadProperty`?Object.assign(n,e.evaluate(t)):n[e.key]=e.value.evaluate(t);return n},getIds(t){if(e&&this.properties)for(let e of this.properties)e.type===`SpreadProperty`?e.expression.getIds(t):e.value.getIds(t);return t}}}property(e,t){return{type:`Property`,key:e,value:t,evaluate(e){return this.value.evaluate(e)},getIds(e){return this.value.getIds(e)}}}list(e){return{type:`List`,items:e,evaluate(e){if(!this.items)return[];let t=[];for(let n of this.items)if(n?.type===`SpreadElement`){let r=n.evaluate(e);r&&typeof r[Symbol.iterator]==`function`&&t.push(...r)}else t.push(n?.evaluate(e));return t},getIds(e){return this.items?.forEach(t=>{t?.getIds(e)}),e}}}arrowFunction(e,t){return{type:`ArrowFunction`,params:e,body:t,evaluate(e){let t=this.params,n=this.body;return(...r)=>{let i=Object.fromEntries(t.map((e,t)=>[e,r[t]])),a=new Proxy(e??{},{set(e,t,n){return Object.hasOwn(i,t)&&(i[t]=n),e[t]=n,n},get(e,t){return Object.hasOwn(i,t)?i[t]:e[t]}});return n.evaluate(a)}},getIds(e){return this.body.getIds(e).filter(e=>!this.params.includes(e))}}}spreadProperty(e){return{type:`SpreadProperty`,expression:e,evaluate(e){return this.expression.evaluate(e)},getIds(e){return this.expression.getIds(e)}}}spreadElement(e){return{type:`SpreadElement`,expression:e,evaluate(e){return this.expression.evaluate(e)},getIds(e){return this.expression.getIds(e)}}}};
|
|
22
|
-
/*
|
|
23
|
-
* @license
|
|
24
|
-
* Portions Copyright (c) 2013, the Dart project authors.
|
|
25
|
-
*/
|
|
26
|
-
const U=new Set([`==`,`!=`,`<=`,`>=`,`||`,`&&`,`??`,`?.`]),W=new Set([`===`,`!==`]);let G=function(e){return e[e.STRING=1]=`STRING`,e[e.IDENTIFIER=2]=`IDENTIFIER`,e[e.DOT=3]=`DOT`,e[e.COMMA=4]=`COMMA`,e[e.COLON=5]=`COLON`,e[e.INTEGER=6]=`INTEGER`,e[e.DECIMAL=7]=`DECIMAL`,e[e.OPERATOR=8]=`OPERATOR`,e[e.GROUPER=9]=`GROUPER`,e[e.KEYWORD=10]=`KEYWORD`,e[e.ARROW=11]=`ARROW`,e[e.OPTIONAL_DOT=12]=`OPTIONAL_DOT`,e[e.SPREAD=13]=`SPREAD`,e}({});const K=(e,t,n=0)=>({kind:e,value:t,precedence:n}),q=e=>e===9||e===10||e===13||e===32,J=e=>{if(e===95||e===36)return!0;let t=e&-33;return 65<=t&&t<=90},ae=e=>J(e)||Y(e),oe=e=>R.has(e),se=e=>e===34||e===39,Y=e=>48<=e&&e<=57,ce=e=>e===43||e===45||e===42||e===47||e===33||e===38||e===37||e===60||e===61||e===62||e===63||e===94||e===124,le=e=>e===40||e===41||e===91||e===93||e===123||e===125,ue=e=>e.replace(/\\(.)/g,(e,t)=>{switch(t){case`n`:return`
|
|
27
|
-
`;case`r`:return`\r`;case`t`:return` `;case`b`:return`\b`;case`f`:return`\f`;default:return t}});var de=class{_input;_index=-1;_tokenStart=0;_next;constructor(e){this._input=e,this._advance()}nextToken(){for(;q(this._next??-1);)this._advance(!0);if(se(this._next??-1))return this._tokenizeString();if(J(this._next??-1))return this._tokenizeIdentOrKeyword();if(Y(this._next??-1))return this._tokenizeNumber();if(this._next===46)return this._tokenizeDot();if(this._next===44)return this._tokenizeComma();if(this._next===58)return this._tokenizeColon();if(ce(this._next??-1))return this._tokenizeOperator();if(le(this._next??-1))return this._tokenizeGrouper();if(this._advance(),this._next!==void 0)throw Error(`Expected end of input, got ${this._next}`)}_advance(e){this._index++,this._index<this._input.length?(this._next=this._input.charCodeAt(this._index),e===!0&&(this._tokenStart=this._index)):this._next=void 0}_getValue(e=0){let t=this._input.substring(this._tokenStart,this._index+e);return e===0&&this._clearValue(),t}_clearValue(){this._tokenStart=this._index}_tokenizeString(){let e=this._next;for(this._advance(!0);this._next!==e;){if(this._next===void 0||this._next===92&&(this._advance(),this._next===void 0))throw Error(`unterminated string`);this._advance()}let t=K(G.STRING,ue(this._getValue()));return this._advance(),t}_tokenizeIdentOrKeyword(){do this._advance();while(ae(this._next??-1));let e=this._getValue();return K(oe(e)?G.KEYWORD:ne.has(e)?G.OPERATOR:G.IDENTIFIER,e,z[e]??0)}_tokenizeNumber(){do this._advance();while(Y(this._next??-1));return this._next===46?this._tokenizeDot():K(G.INTEGER,this._getValue())}_tokenizeDot(){if(this._advance(),Y(this._next??-1))return this._tokenizeFraction();if(this._next===46){if(this._advance(),this._next===46)return this._advance(),this._clearValue(),K(G.SPREAD,`...`);throw Error(`Unexpected token ..`)}return this._clearValue(),K(G.DOT,`.`,13)}_tokenizeComma(){return this._advance(!0),K(G.COMMA,`,`)}_tokenizeColon(){return this._advance(!0),K(G.COLON,`:`)}_tokenizeFraction(){do this._advance();while(Y(this._next??-1));return K(G.DECIMAL,this._getValue())}_tokenizeOperator(){this._advance();let e=this._getValue(2);if(W.has(e))this._advance(),this._advance();else{if(e=this._getValue(1),e===`=>`)return this._advance(),K(G.ARROW,e);U.has(e)&&this._advance()}return e=this._getValue(),e===`?.`?K(G.OPTIONAL_DOT,e,13):K(G.OPERATOR,e,z[e])}_tokenizeGrouper(){let e=String.fromCharCode(this._next??0),t=K(G.GROUPER,e,z[e]);return this._advance(!0),t}};const fe=(e,t)=>new pe(e,t).parse();var pe=class{_kind;_tokenizer;_ast;_token;_value;constructor(e,t){this._tokenizer=new de(e),this._ast=t}parse(){this._advance();let e=this._parseExpression();if(this._token)throw Error(`Unexpected token: ${this._token.value}`);return e}_advance(e,t){if(!this._matches(e,t))throw Error(`Expected kind ${e} (${t}), was ${this._token?.kind} (${this._token?.value})`);let n=this._tokenizer.nextToken();this._token=n,this._kind=n?.kind,this._value=n?.value}_matches(e,t){return!(e&&this._kind!==e||t&&this._value!==t)}_parseExpression(){if(!this._token)return this._ast.empty();let e=this._parseUnary();return e===void 0?void 0:this._parsePrecedence(e,0)}_parsePrecedence(e,t){if(e===void 0)throw Error(`Expected left to be defined.`);for(;this._token;)if(this._matches(G.GROUPER,`(`)){let t=this._parseArguments();e=this._ast.invoke(e,void 0,t)}else if(this._matches(G.GROUPER,`[`)){let t=this._parseIndex();e=this._ast.index(e,t)}else if(this._matches(G.DOT)||this._matches(G.OPTIONAL_DOT)){let t=this._kind===G.OPTIONAL_DOT;if(this._advance(),t&&this._matches(G.GROUPER,`[`)){let t=this._parseIndex();e=this._ast.index(e,t,!0)}else if(t&&this._matches(G.GROUPER,`(`)){let t=this._parseArguments();e=this._ast.invoke(e,void 0,t,!0)}else{let n=this._parseUnary();e=this._makeInvokeOrGetter(e,n,t)}}else if(this._matches(G.KEYWORD))break;else if(this._matches(G.OPERATOR)&&this._token.precedence>=t)e=this._value===`?`?this._parseTernary(e):this._parseBinary(e,this._token);else break;return e}_makeInvokeOrGetter(e,t,n){if(t===void 0)throw Error(`expected identifier`);if(t.type===`ID`)return this._ast.getter(e,t.value,n);if(t.type===`Invoke`&&t.receiver.type===`ID`){let r=t.receiver;return this._ast.invoke(e,r.value,t.arguments,n)}else throw Error(`expected identifier: ${t}`)}_parseBinary(e,t){if(!ie.has(t.value))throw Error(`unknown operator: ${t.value}`);this._advance();let n=this._parseUnary();for(;(this._kind===G.OPERATOR||this._kind===G.DOT||this._kind===G.GROUPER)&&this._token&&(this._token.precedence??0)>t.precedence;)n=this._parsePrecedence(n,this._token?.precedence??0);if(n===void 0)throw Error(`Expected expression after ${t.value}`);return this._ast.binary(e,t.value,n)}_parseUnary(){if(this._matches(G.KEYWORD,`typeof`)){this._advance();let e=this._parsePrecedence(this._parsePrimary(),13);return this._ast.unary(`typeof`,e)}if(this._matches(G.OPERATOR)){let e=this._value;if(this._advance(),e===`+`||e===`-`){if(this._matches(G.INTEGER))return this._parseInteger(e);if(this._matches(G.DECIMAL))return this._parseDecimal(e)}if(!e||!re.has(e))throw Error(`unexpected token: ${e}`);let t=this._parsePrecedence(this._parsePrimary(),13);return this._ast.unary(e,t)}return this._parsePrimary()}_parseTernary(e){this._advance(G.OPERATOR,`?`);let t=this._parseExpression();this._advance(G.COLON);let n=this._parseExpression();return this._ast.ternary(e,t,n)}_parsePrimary(){switch(this._kind){case G.KEYWORD:{let e=this._value??``;if(e===`this`)return this._advance(),this._ast.id(e);throw R.has(e)?Error(`unexpected keyword: ${e}`):Error(`unrecognized keyword: ${e}`)}case G.IDENTIFIER:return this._parseInvokeOrIdentifier();case G.STRING:return this._parseString();case G.INTEGER:return this._parseInteger();case G.DECIMAL:return this._parseDecimal();case G.GROUPER:return this._value===`(`?this._parseParenOrFunction():this._value===`{`?this._parseMap():this._value===`[`?this._parseList():void 0;case G.COLON:throw Error(`unexpected token ":"`);default:return}}_parseList(){let e=[];do{if(this._advance(),this._matches(G.GROUPER,`]`))break;if(this._matches(G.SPREAD)){this._advance();let t=this._parseExpression();t&&e.push(this._ast.spreadElement(t))}else e.push(this._parseExpression())}while(this._matches(G.COMMA));return this._advance(G.GROUPER,`]`),this._ast.list(e)}_parseMap(){let e=[];do{if(this._advance(),this._matches(G.GROUPER,`}`))break;if(this._matches(G.SPREAD)){this._advance();let t=this._parseExpression();t&&e.push(this._ast.spreadProperty(t))}else{let t=this._value??``;if((this._matches(G.STRING)||this._matches(G.IDENTIFIER))&&this._advance(),this._matches(G.COLON)){this._advance(G.COLON);let n=this._parseExpression();n&&e.push(this._ast.property(t,n))}else e.push(this._ast.property(t,this._ast.id(t)))}}while(this._matches(G.COMMA));return this._advance(G.GROUPER,`}`),this._ast.map(e)}_parseInvokeOrIdentifier(){let e=this._value;if(e===`true`)return this._advance(),this._ast.literal(!0);if(e===`false`)return this._advance(),this._ast.literal(!1);if(e===`null`)return this._advance(),this._ast.literal(null);if(e===`undefined`)return this._advance(),this._ast.literal(void 0);let t=this._parseIdentifier(),n=this._parseArguments();return n?this._ast.invoke(t,void 0,n):t}_parseIdentifier(){if(!this._matches(G.IDENTIFIER))throw Error(`expected identifier: ${this._value}`);let e=this._value;return this._advance(),this._ast.id(e??``)}_parseArguments(){if(!this._matches(G.GROUPER,`(`))return;let e=[];do{if(this._advance(),this._matches(G.GROUPER,`)`))break;if(this._matches(G.SPREAD)){this._advance();let t=this._parseExpression();t&&e.push(this._ast.spreadElement(t))}else{let t=this._parseExpression();e.push(t)}}while(this._matches(G.COMMA));return this._advance(G.GROUPER,`)`),e}_parseIndex(){this._advance();let e=this._parseExpression();return this._advance(G.GROUPER,`]`),e}_parseParenOrFunction(){let e=this._parseArguments();if(this._matches(G.ARROW)){this._advance();let t=this._parseExpression(),n=e?.map(e=>e.value)??[];return this._ast.arrowFunction(n,t)}else return this._ast.paren(e?.[0])}_parseString(){let e=this._ast.literal(this._value??``);return this._advance(),e}_parseInteger(e=``){let t=this._ast.literal(parseInt(`${e}${this._value}`,10));return this._advance(),t}_parseDecimal(e=``){let t=this._ast.literal(parseFloat(`${e}${this._value}`));return this._advance(),t}},me=class{timeouts=new Map;debounce(e,t){return new Promise((n,r)=>{let i=this.timeouts.get(t);i&&clearTimeout(i),this.timeouts.set(t,setTimeout(()=>{try{n(t()),this.timeouts.delete(t)}catch(e){r(e)}},e))})}};const he=new H,X=`__is_proxy__`;function ge(e){return e instanceof $||e[X]===!0}function Z(e,t){let n=e?._store;if(n?.has(t))return n.get(t);if(n?.has(`$parent`))return Z(n.get(`$parent`),t)}function Q(e,t){let n=e?._store;return n?.has(t)?e:n?.has(`$parent`)?Q(n.get(`$parent`),t):null}function _e(e,t,n){let r=Q(e,t);r?r._store.set(t,n):e._store.set(t,n)}var $=class e extends me{evalkeys=[`$elem`,`$event`];expressionCache=new Map;observers=new Map;keyHandlers=new Map;_store=new Map;_lock=Promise.resolve();constructor(e){super();for(let[t,n]of Object.entries(e||{}))this.set(t,n)}wrapObject(e,t){return e==null||ge(e)||e.constructor!==Object&&!Array.isArray(e)?e:new Proxy(e,{deleteProperty:(e,n)=>typeof n==`string`&&n in e?(delete e[n],t(),!0):!1,set:(e,n,r,i)=>{if(Reflect.get(e,n,i)===r)return!0;typeof r==`object`&&r&&(r=this.wrapObject(r,t));let a=Reflect.set(e,n,r,i);return t(),a},get:(e,t,n)=>t===X?!0:Reflect.get(e,t,n)})}watch(e,t){let n=Q(this,e);if(!n)throw Error(`Cannot watch key "${e}" as it does not exist in the store.`);n.observers.has(e)||n.observers.set(e,new Set),Array.from(n.observers.get(e)||[]).some(e=>e.observer===t)||n.observers.get(e)?.add({observer:t,store:this})}addKeyHandler(e,t){this.keyHandlers.has(e)||this.keyHandlers.set(e,new Set),this.keyHandlers.get(e)?.add(t)}async notify(e,t=10){let n=Q(this,e),r=Array.from(n?.observers.get(e)||[]);await this.debounce(t,()=>Promise.all(r.map(e=>e.observer.call(e.store.proxify(e.observer)))))}get(e,t){return t&&this.watch(e,t),Z(this,e)}async set(e,t){if(this._store.has(e)&&t===this._store.get(e))return;let n=()=>this.notify(e);t&&typeof t==`object`&&(t=this.wrapObject(t,n)),_e(this,e,t);for(let[n,r]of this.keyHandlers.entries())if(n.test(e))for(let n of r)await Promise.resolve(n.call(this.$,e,t));await n()}async del(e){await this.set(e,null),this._store.delete(e),this.observers.delete(e)}keys(){return Array.from(this._store.keys())}has(e){return this._store.has(e)}getObserverStats(){let e={},t=0;for(let[n,r]of this.observers)e[n]=r.size,t+=r.size;return{totalKeys:this.observers.size,totalObservers:t,byKey:e}}effect(e,t){return e.call(this.proxify(e))}proxify(t){let n=Array.from(this._store.entries()).map(([e])=>e),r=Object.fromEntries(n.map(e=>[e,null])),i=(e,t,n)=>typeof e==`function`&&t!==`constructor`?(...t)=>e.call(n,...t):e;return new Proxy(r,{has:(e,t)=>typeof t==`string`&&(Q(this,t)||Reflect.has(this,t))?!0:Reflect.has(r,t),get:(n,r,a)=>{if(typeof r==`string`){if(Q(this,r)){let n=this.get(r,t);return t&&n instanceof e?n.proxify(t):i(n,r,a)}if(t&&r!==X&&!Reflect.has(this,r))return this.set(r,void 0),this.get(r,t)}return r===`$`?this.proxify(t):i(Reflect.get(this,r,a),r,a)},set:(e,t,n,r)=>(typeof t!=`string`||t in this?Reflect.set(this,t,n,r):this.set(t,n),!0)})}get $(){return this.proxify()}makeEvalFunction(e){return(t,n)=>{let r=fe(e,he),i=new Proxy(n,{has(e,n){return n in e||n in t||n in globalThis},get(e,n){if(typeof n==`string`)return n in e?e[n]:n in t?t[n]:n in globalThis?globalThis[n]:t[n]},set(e,n,r){return typeof n==`string`?n in e?(e[n]=r,!0):(t[n]=r,!0):!1}});return r?.evaluate(i)}}cachedExpressionFunction(e){e=e.trim(),this.expressionCache.has(e)||this.expressionCache.set(e,this.makeEvalFunction(e));let t=this.expressionCache.get(e);if(!t)throw Error(`Failed to retrieve cached expression: ${e}`);return t}eval(e,t={}){let n=this.$;if(this._store.has(e))return n[e];{let r=this.cachedExpressionFunction(e);try{return r(n,t)}catch(t){return console.error(`Failed to evaluate expression: ${e}`),console.error(t),null}}}$resolve(e,t){let n={$pending:!0,$result:null,$error:null};return Promise.resolve().then(()=>e(t)).then(e=>{n.$result=e}).catch(e=>{n.$error=e instanceof Error?e:Error(String(e))}).finally(()=>{n.$pending=!1}),n}},ve=class e extends ${_debugLevel=`off`;dirpath=``;_perfData={lifecycle:{},effects:new Map};static DEBUG_LEVELS=[`off`,`lifecycle`,`effects`,`verbose`];_skipNodes=new Set;_customElements=new Map;_pendingValueRetries=[];debug(e){return typeof e==`boolean`?this._debugLevel=e?`lifecycle`:`off`:this._debugLevel=e,this}get debugging(){return this._debugLevel!==`off`}shouldLog(t){return e.DEBUG_LEVELS.indexOf(this._debugLevel)>=e.DEBUG_LEVELS.indexOf(t)}resetPerfData(){this._perfData={lifecycle:{},effects:new Map}}getNodePath(e){let t=[],n=e;for(;n?.tagName;){let e=n.tagName.toLowerCase(),r=n.parentElement;if(r){let i=Array.from(r.children).filter(t=>t.tagName.toLowerCase()===e);if(i.length>1){let r=i.indexOf(n)+1;t.unshift(`${e}:nth-child(${r})`)}else t.unshift(e)}else t.unshift(e);n=r}return t.join(`>`)}buildEffectId(e){let t=e?.directive??`unknown`,n=T(e?.expression??``,32),r=e?.element;return`${t}:${r?r.dataset?.perfid??r.id??r.dataset?.testid??this.getNodePath(r):`unknown`}:${n}`}recordEffectExecution(e,t){let n=this.buildEffectId(e),r=this._perfData.effects.get(n)??{count:0,totalTime:0};r.count++,r.totalTime+=t,this._perfData.effects.set(n,r)}performanceReport(){let e=Array.from(this._perfData.effects.entries()),t={};for(let[n,r]of e){let e=n.split(`:`)[0];t[e]||(t[e]={count:0,totalTime:0}),t[e].count+=r.count,t[e].totalTime+=r.totalTime}let n=e.map(([e,t])=>({id:e,executionCount:t.count,totalTime:t.totalTime,avgTime:t.count>0?t.totalTime/t.count:0})).sort((e,t)=>t.totalTime-e.totalTime).slice(0,10);return{lifecycle:this._perfData.lifecycle,effects:{total:e.length,byDirective:t,slowest:n},observers:this.getObserverStats()}}effect(e,t){if(!this.shouldLog(`lifecycle`))return super.effect(e,t);let n=performance.now(),r=super.effect(e,t),i=performance.now()-n;return t&&this.recordEffectExecution(t,i),i>16&&console.warn(`Slow effect (${i.toFixed(1)}ms):`,this.buildEffectId(t)),this.shouldLog(`effects`)&&console.debug(`Effect (${i.toFixed(2)}ms):`,this.buildEffectId(t)),r}async fetchRemote(e,t){return fetch(e,{cache:t?.cache??`default`}).then(e=>e.text())}async fetchLocal(e,t){return this.fetchRemote(e,t)}async preprocessString(e,t){this.log(`Preprocessing string content with params:
|
|
28
|
-
`,t);let n=this.parseHTML(e,t);return await this.preprocessNode(n,t),n}async preprocessRemote(e,t){let n={};t?.cache&&(n.cache=t.cache);let r=await fetch(e,n).then(e=>e.text());return this.preprocessString(r,{...t,dirpath:D(e),rootDocument:t?.rootDocument??!e.endsWith(`.tpl.html`)})}async preprocessLocal(e,t){let n=await this.fetchLocal(e,t);return this.preprocessString(n,{...t,dirpath:D(e),rootDocument:t?.rootDocument??!e.endsWith(`.tpl.html`)})}subrenderer(){let e=new this.constructor().debug(this.debugging);return e._store.set(`$parent`,this),e._store.set(`$rootRenderer`,this.get(`$rootRenderer`)??this),e._customElements=this._customElements,e}log(...e){this.shouldLog(`verbose`)&&console.debug(...e)}async preprocessNode(e,t){let n=this.shouldLog(`lifecycle`)?performance.now():0;t={dirpath:this.dirpath,maxdepth:10,...t};let r=new k(a(e,this._skipNodes)).map(async e=>{this.log(`Preprocessing node:
|
|
29
|
-
`,E(e,128)),await A.resolveIncludes.call(this,e,t),await A.rebaseRelativePaths.call(this,e,t),await A.registerCustomElements.call(this,e,t),await A.resolveCustomElements.call(this,e,t)});return await Promise.all(r.generator()),n&&(this._perfData.lifecycle.preprocessTime=(this._perfData.lifecycle.preprocessTime??0)+(performance.now()-n)),e}async renderNode(e,t){let n=this.shouldLog(`lifecycle`)?performance.now():0;for(let n of a(e,this._skipNodes))this.log(`Rendering node:
|
|
30
|
-
`,E(n,128)),await A.resolveForAttribute.call(this,n,t),await A.resolveRenderAttribute.call(this,n,t),await A.resolveDataAttribute.call(this,n,t),await A.resolveTextAttributes.call(this,n,t),await A.resolveHtmlAttribute.call(this,n,t),await A.resolveIfAttribute.call(this,n,t),await A.resolveShowAttribute.call(this,n,t),await A.resolveClassAttribute.call(this,n,t),await A.resolveBindAttribute.call(this,n,t),await A.resolveEventAttributes.call(this,n,t),await A.resolveTextNodeExpressions.call(this,n,t),await A.resolveCustomAttribute.call(this,n,t),await A.resolveCustomProperty.call(this,n,t),await A.stripTypes.call(this,n,t);for(let e of this._pendingValueRetries.splice(0))e();return n&&(this._perfData.lifecycle.renderTime=(this._perfData.lifecycle.renderTime??0)+(performance.now()-n)),e}async mount(e,t){let n=this.shouldLog(`lifecycle`)?performance.now():0;n&&this.resetPerfData(),t={...t,rootNode:e},m(e,`renderer`,this),this._store.set(`$rootNode`,e),this.has(`$rootRenderer`)||this._store.set(`$rootRenderer`,this),this.get(`$rootRenderer`)===this&&await te(this),await this.preprocessNode(e,t),await this.renderNode(e,t),n&&(this._perfData.lifecycle.mountTime=performance.now()-n)}};export{D as n,ve as t};
|