@symbo.ls/utils 3.14.782 → 3.14.784

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/CHANGELOG.md CHANGED
@@ -1,5 +1,61 @@
1
1
  # @symbo.ls/utils
2
2
 
3
+ ## 3.14.784
4
+
5
+ ### Patch Changes
6
+
7
+ - 13c4922: extends: one precedence law — `LAST wins` on the frank/utils path too
8
+
9
+ The framework shipped two `extends` resolvers implementing OPPOSITE laws for an
10
+ authored `extends: [A, B]` array. `packages/element/src/extends.js` (the browser
11
+ and SSR runtime) merged each top-level entry in order, so LAST wins.
12
+ `packages/utils/extends.js` — the standalone resolver published in this package
13
+ and used on the frank/JSON path — resolved the other way, so FIRST won.
14
+
15
+ `@symbo.ls/utils` now follows the same law as the runtime: for
16
+ `extends: [A, B]`, B wins. A shared fixture pins both resolvers so they cannot
17
+ diverge again.
18
+
19
+ This is a behaviour change to a published API, not an internal refactor. It is
20
+ released as a patch because it aligns the minority path with the law the runtime
21
+ already enforced, and a census across authored projects measured ZERO on-screen
22
+ differences — every observed array either had no conflicting keys or already
23
+ relied on the runtime ordering. If a consumer deliberately depended on FIRST
24
+ winning through the frank/JSON path, that expectation no longer holds and the
25
+ array order must be reversed.
26
+
27
+ Reference: FW-EXTENDS-ARRAY-TWO-RESOLVERS-OPPOSITE-PRECEDENCE-1.
28
+
29
+ - Fixes for the 42 issues reported while building xma.info (FW-XMA-EXCEPTIONS-UPSTREAM-1).
30
+
31
+ Behaviour changes (check these first):
32
+
33
+ - CSS precedence across `extends`: a later layer's shorthand that states a longhand now beats a longhand an earlier layer declared (`borderWidth: '0'` no longer loses to a base `borderBottomWidth`; a derived `border: 'hairline solid …'` now paints over a base `borderWidth: '0'`). Positional shorthands (`background`, `transition`, `font`, `flex`, `grid`…) never remove a base longhand. A `:focus-visible` longhand (`outlineColor`) now paints over Link/Focusable's ring.
34
+ - Built-in `Img` no longer copies `alt` into `title`. `Link` leaves Ctrl/Cmd/Shift/Alt, middle, `target` and `download` clicks to the browser.
35
+ - `X<` breakpoints start at N.02px, so no width matches both `X` and `X<`.
36
+ - Helmet renders the head as the merge of mounted layers: keys a page leaves out fall back instead of staying from the previous page.
37
+ - `smbls build` with `"brender": true` pre-renders again (it rendered nothing since 3.14.6): every static route is written, `/*` becomes `404.html`, `:param` routes are skipped and listed, and the build exits 1 when no route renders.
38
+ - `onStateInit`, `onStateCreated` and `onBeforeStateUpdate` run again (`onBeforeStateUpdate` returning `false` cancels the update).
39
+ - `onWindowLoad` runs once right after creation when the page had already loaded.
40
+ - The first render no longer forces a style+layout pass per microtask.
41
+ - socket.io-client loads only when a sync transport is configured; the ESM build ships it as `dist/smbls.socket-io-client.esm.js` (keep it beside `smbls.esm.js`).
42
+
43
+ New, opt-in:
44
+
45
+ - `designSystem.focusableRing`; `vars` and top-level `'--x'` keys set reactive custom properties; `fill`/`stroke` are CSS outside `<svg>`; attributes inside `.isX` / `'!isX'` blocks apply.
46
+ - Design-system tokens resolve inside `style: {}` blocks; `sizes` tokens negate (`-hairline2`) and publish `--size-<name>`.
47
+ - `fetchpriority` and every multi-word attribute work flat in both spellings.
48
+ - `inertOutside`, the `Bridge` host for DOM-owning libraries, element events with `{ capture, passive, once, selector, handler }`, `TooltipLayer` for `[data-tooltip]` nodes.
49
+ - Router `scrollRestoration: 'restore'`; guards that refuse Back/Forward put the address back; lazy route groups (`context.lazy`, `el.call('loadLazy')`).
50
+ - Fetch: `el.call('invalidateQueries')` and friends, `invalidates` on rpc, `fetch.early` pre-boot requests, `fetch.reads` anonymous GET reads without a CORS preflight.
51
+ - Polyglot `setLang` switches text, `<html lang>` and fonts in one frame; `getPendingLang`.
52
+ - `s.$settled()` / `settled()` await the DOM a state write produces; `onMediaQueryChange` takes design-system media keys; the `animation` shorthand resolves tokens.
53
+ - `smbls/ssr` entry for server rendering; `smbls push` publishes `new URL('<path>', import.meta.url)` assets.
54
+ - frank-audit: FA105 per-tag, FA410 (history writes), wider FA701; opt-in FA211, FA810, FA811, FA812; unknown `--rule` ids are reported.
55
+
56
+ - Updated dependencies
57
+ - @symbo.ls/fetch@3.14.662
58
+
3
59
  ## 3.14.770
4
60
 
5
61
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- "use strict";var j=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var D=(e,s)=>{for(var t in s)j(e,t,{get:s[t],enumerable:!0})},P=(e,s,t,n)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of T(s))!F.call(e,r)&&r!==t&&j(e,r,{get:()=>s[r],enumerable:!(n=x(s,r))||n.enumerable});return e};var R=e=>P(j({},"__esModule",{value:!0}),e);var Y={};D(Y,{fileEntryUrl:()=>E,generateHeadArrayTags:()=>L,generateMetaTags:()=>q,getPageMetadata:()=>N,hashContent:()=>b,resolveFileReferences:()=>W});module.exports=R(Y);var w=require("./types.js"),M=require("./function.js");const g=e=>{if(e==null)return"";const s={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return e.toString().replace(/[&<>"']/g,t=>s[t])},U=e=>Object.entries(e||{}).filter(([s,t])=>t!==void 0).map(([s,t])=>`${s}="${g(t)}"`).join(" "),b=e=>{let s=5381;const t=String(e);for(let n=0;n<t.length;n++)s=(s*33^t.charCodeAt(n))>>>0;return s.toString(36)},_=new Set(["jsonLd","styles","scripts"]),L=e=>{const s=[];if(Array.isArray(e.jsonLd))for(const t of e.jsonLd){if(t==null)continue;const n=typeof t=="string"?t:JSON.stringify(t),r=String(n).replace(/<\/script/gi,"<\\/script");s.push(`<script type="application/ld+json" data-smbls-jsonld="${b(n)}">${r}<\/script>`)}if(Array.isArray(e.styles))for(const t of e.styles){if(t==null||!String(t).trim())continue;const n=String(t).replace(/<\/style/gi,"<\\/style");s.push(`<style data-smbls-style="${b(n)}">${n}</style>`)}if(Array.isArray(e.scripts))for(const t of e.scripts){if(!t)continue;const n=typeof t=="string",r=n?t:t.src;if(!r&&!t.body)continue;const o=[];r&&o.push(`src="${g(r)}"`),n||(t.type&&o.push(`type="${g(t.type)}"`),t.async&&o.push("async"),t.defer&&o.push("defer"),t.integrity&&o.push(`integrity="${g(t.integrity)}"`),t.crossorigin&&o.push(`crossorigin="${g(t.crossorigin)}"`),t.referrerpolicy&&o.push(`referrerpolicy="${g(t.referrerpolicy)}"`),t.nomodule&&o.push("nomodule"));const l=` data-smbls-script="${g(r||b(t.body||""))}"`;if(!n&&t.body){const h=String(t.body).replace(/<\/script/gi,"<\\/script");s.push(`<script ${o.join(" ")}${l}>${h}<\/script>`)}else s.push(`<script ${o.join(" ")}${l}><\/script>`)}return s},q=(e,s)=>{s||(e={...e,robots:"noindex"});const t=Object.entries(e).reduce((n,[r,o])=>{if(!o&&o!==0&&o!==!1||_.has(r))return n;if(r==="title")return n.push(`<title>${g(o)}</title>`),n;if(r==="canonical")return n.push(`<link rel="canonical" href="${g(o)}">`),n;if(r==="manifest")return n.push(`<link rel="manifest" href="${g(o)}">`),n;if(r==="favicon"||r==="favicons"||r==="icon"||r==="icons")return(Array.isArray(o)?o:[o]).forEach(c=>{if(typeof c=="string")n.push(`<link rel="icon" href="${g(c)}">`);else if(typeof c=="object"){const u=U(c);/rel=/.test(u)?n.push(`<link ${u}>`):n.push(`<link rel="icon" ${u}>`)}}),n;if(r==="alternate")return(Array.isArray(o)?o:[o]).forEach(c=>{if(typeof c=="object"){const u=Object.entries(c).filter(([i,p])=>p!==void 0).map(([i,p])=>`${i}="${g(p)}"`).join(" ");n.push(`<link rel="alternate" ${u}>`)}}),n;const l=(f,c,u="name")=>{if(typeof c=="string"||typeof c=="number"||typeof c=="boolean")n.push(`<meta ${u}="${g(f)}" content="${g(c)}">`);else if(Array.isArray(c))c.forEach(i=>{if(typeof i=="string"||typeof i=="number"||typeof i=="boolean")n.push(`<meta ${u}="${g(f)}" content="${g(i)}">`);else if(typeof i=="object"){const p=Object.entries(i).filter(([m,a])=>a!==void 0).map(([m,a])=>`${m}="${g(a)}"`).join(" ");n.push(`<meta ${p}>`)}});else if(typeof c=="object"){const i=Object.entries(c).filter(([p,m])=>m!==void 0).map(([p,m])=>`${p}="${g(m)}"`).join(" ");n.push(`<meta ${i}>`)}};if(r.startsWith("http-equiv:")){const f=r.replace("http-equiv:","");return l(f,o,"http-equiv"),n}if(r.startsWith("itemprop:")){const f=r.replace("itemprop:","");return l(f,o,"itemprop"),n}const y=["og:","twitter:","fb:","article:","profile:","book:","business:","music:","product:","video:","DC:","DCTERMS:"].find(f=>r.startsWith(f));if(y){const f=r.replace(y,"");return l(`${y.replace(":","")}:${f}`,o,y==="twitter:"||y==="DC:"||y==="DCTERMS:"?"name":"property"),n}if(r.startsWith("apple:")||r.startsWith("msapplication:")){const f=r.startsWith("apple:")?"apple-":"msapplication-",c=r.replace(/^apple:|^msapplication:/,"");return l(`${f}${c}`,o,"name"),n}return l(r,o),n},['<meta charset="UTF-8">','<meta name="viewport" content="width=device-width, initial-scale=1">']);return t.push(...L(e)),t.join(`
2
- `)},K=e=>typeof e=="string"&&e.length>0&&!e.startsWith("/")&&!e.startsWith("http"),S=e=>typeof e=="string"&&e.length>0,E=e=>{if(!e||typeof e!="object")return null;if(S(e.src))return e.src;const s=e.content;return!s||typeof s!="object"?null:S(s.src)?s.src:S(s.storageUrl)?s.storageUrl:null};function W(e,s){if(!s||typeof s!="object")return e;const t=r=>!K(r)||!Object.prototype.hasOwnProperty.call(s,r)?r:E(s[r])||r,n={...e};for(const[r,o]of Object.entries(n))typeof o=="string"?n[r]=t(o):Array.isArray(o)&&(n[r]=o.map(l=>typeof l=="string"?t(l):l));return n}function A(e,s){if(!e||!s)return;const t=s.split(".");let n=e;for(const r of t){if(n==null||typeof n!="object")return;n=n[r]}return n}function C(e,s){const t=A(e,s);if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(typeof t=="string"&&!(0,M.isStringFunction)(t))return t}function H(e,s,t){const r=(s.config||s.settings||{}).polyglot||s.polyglot,o=t?.lang||r?.defaultLang||"en",h=(r?.translations||{})[o]||{},y=[t?.state,s.state].filter(u=>u&&typeof u=="object"),f=u=>{for(const i of y){const p=C(i,u);if(p!==void 0)return p}},c={...e};for(const[u,i]of Object.entries(c))typeof i!="string"||!i.includes("{{")||(c[u]=i.replace(/\{\{\s*([^|{}]+?)\s*(?:\|\s*(\w+)\s*)?\}\}/g,(p,m,a)=>{const d=m.trim();if(a==="polyglot")return h[d]??A(h,d)??p;if(a==="getLocalStateLang")return f(d+o)??p;const $=f(d);return $!==void 0?$:h[d]??A(h,d)??p}));return c}function O(e){if(!(0,w.isObject)(e))return{};const s={...e};for(const[t,n]of Object.entries(s))if(typeof n=="function"){const r=n.toString(),o=r.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){s[t]=`{{ ${o[1]} | getLocalStateLang }}`;continue}const l=r.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(l){s[t]=`{{ ${l[1]} | polyglot }}`;continue}const h=r.match(/s\.(\w+(?:\.\w+)+)/);if(h){s[t]=`{{ ${h[1]} }}`;continue}delete s[t]}else if(typeof n=="string"){const r=n.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(r){s[t]=`{{ ${r[1]} | getLocalStateLang }}`;continue}const o=n.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){s[t]=`{{ ${o[1]} | polyglot }}`;continue}if(n.includes("=>")&&n.includes("s.")){const l=n.match(/s\.(\w+(?:\.\w+)+)/);if(l){s[t]=`{{ ${l[1]} }}`;continue}}(0,M.isStringFunction)(n)&&delete s[t]}return s}function N(e,s,t,{isProduction:n=!1,channel:r="production"}={}){const o=e.pages?.[s],l=(0,w.isObject)(o?.state)&&o?.state,h=o?.metadata||o?.helmet||l||{},y=O(h),f=new Set(Object.keys(y)),c=e.app?.metadata||{},u=O(c);let i={};if(e.integrations?.seo?i={...e.integrations.seo,...u,...y}:Object.keys(u).length?i={...u,...y}:i={...y},!i.title){const a=e.name||e.key;a?n?i.title=a:r==="development"?i.title=`${a} / dev:symbo.ls`:r==="staging"?i.title=`${a} / staging:symbo.ls`:i.title=`${a} / symbo.ls`:i.title="Symbols demo"}i=H(i,e,t),i.title&&(f.has("title")||!i["og:title"])&&(f.has("og:title")||(i["og:title"]=i.title)),i.description&&(f.has("description")||!i["og:description"])&&(f.has("og:description")||(i["og:description"]=i.description)),i.title&&!i["twitter:title"]&&(i["twitter:title"]=i.title),i.description&&!i["twitter:description"]&&(i["twitter:description"]=i.description);const p=t?.actualPathname||s;if(i["og:url"]||i.url){const a=(i["og:url"]||i.url||"").replace(/\/$/,"");if(a&&p&&p!=="/"){const d=p.startsWith("/")?p:"/"+p;i["og:url"]=a+d}}i=W(i,e.files);const m=e.name||e.app?.metadata?.title||e.app?.name||"";for(const[a,d]of Object.entries(i))if(typeof d=="string"&&d.includes("{{")){const $=d.replace(/\{\{[^}]*\}\}/g,"").trim();$?i[a]=$:a==="title"?i[a]=m:delete i[a]}return i}
1
+ "use strict";var A=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var U=(e,n)=>{for(var t in n)A(e,t,{get:n[t],enumerable:!0})},D=(e,n,t,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of F(n))!K.call(e,i)&&i!==t&&A(e,i,{get:()=>n[i],enumerable:!(s=T(n,i))||s.enumerable});return e};var P=e=>D(A({},"__esModule",{value:!0}),e);var z={};U(z,{fileEntryUrl:()=>W,generateHeadArrayTags:()=>E,generateMetaTags:()=>N,getPageMetadata:()=>B,hashContent:()=>j,resolveFileReferences:()=>x});module.exports=P(z);var b=require("./types.js"),M=require("./function.js");const p=e=>{if(e==null)return"";const n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return e.toString().replace(/[&<>"']/g,t=>n[t])},R=e=>Object.entries(e||{}).filter(([n,t])=>t!==void 0).map(([n,t])=>`${n}="${p(t)}"`).join(" "),j=e=>{let n=5381;const t=String(e);for(let s=0;s<t.length;s++)n=(n*33^t.charCodeAt(s))>>>0;return n.toString(36)},_=new Set(["jsonLd","styles","scripts"]),E=e=>{const n=[];if(Array.isArray(e.jsonLd))for(const t of e.jsonLd){if(t==null)continue;const s=typeof t=="string"?t:JSON.stringify(t),i=String(s).replace(/<\/script/gi,"<\\/script");n.push(`<script type="application/ld+json" data-smbls-jsonld="${j(s)}">${i}<\/script>`)}if(Array.isArray(e.styles))for(const t of e.styles){if(t==null||!String(t).trim())continue;const s=String(t).replace(/<\/style/gi,"<\\/style");n.push(`<style data-smbls-style="${j(s)}">${s}</style>`)}if(Array.isArray(e.scripts))for(const t of e.scripts){if(!t)continue;const s=typeof t=="string",i=s?t:t.src;if(!i&&!t.body)continue;const o=[];i&&o.push(`src="${p(i)}"`),s||(t.type&&o.push(`type="${p(t.type)}"`),t.async&&o.push("async"),t.defer&&o.push("defer"),t.integrity&&o.push(`integrity="${p(t.integrity)}"`),t.crossorigin&&o.push(`crossorigin="${p(t.crossorigin)}"`),t.referrerpolicy&&o.push(`referrerpolicy="${p(t.referrerpolicy)}"`),t.nomodule&&o.push("nomodule"));const l=` data-smbls-script="${p(i||j(t.body||""))}"`;if(!s&&t.body){const d=String(t.body).replace(/<\/script/gi,"<\\/script");n.push(`<script ${o.join(" ")}${l}>${d}<\/script>`)}else n.push(`<script ${o.join(" ")}${l}><\/script>`)}return n},q=(e,n,t)=>e==="favicons"?Array.isArray(n)?typeof t=="string"?` data-smbls-favicon="${p(t)}"`:(0,b.isObject)(t)?` data-smbls-favicon="${j(JSON.stringify(t))}"`:"":"":(e==="icon"||e==="favicon")&&typeof n=="string"?` data-smbls-single-icon="${p(n)}"`:"",C=e=>(0,b.isObject)(e)?` data-smbls-alternate="${p(`${e.hreflang||""}|${e.href||""}`)}"`:"",N=(e,n)=>{n||(e={...e,robots:"noindex"});const t=Object.entries(e).reduce((s,[i,o])=>{if(!o&&o!==0&&o!==!1||_.has(i))return s;if(i==="title")return s.push(`<title>${p(o)}</title>`),s;if(i==="canonical")return s.push(`<link rel="canonical" href="${p(o)}">`),s;if(i==="manifest")return s.push(`<link rel="manifest" href="${p(o)}">`),s;if(i==="favicon"||i==="favicons"||i==="icon"||i==="icons")return(Array.isArray(o)?o:[o]).forEach(c=>{const u=q(i,o,c);if(typeof c=="string")s.push(`<link rel="icon" href="${p(c)}"${u}>`);else if(typeof c=="object"){const r=R(c);/rel=/.test(r)?s.push(`<link ${r}${u}>`):s.push(`<link rel="icon" ${r}${u}>`)}}),s;if(i==="alternate")return(Array.isArray(o)?o:[o]).forEach(c=>{if(c&&typeof c=="object"){const u=Object.entries(c).filter(([r,g])=>g!==void 0).map(([r,g])=>`${r}="${p(g)}"`).join(" ");s.push(`<link rel="alternate" ${u}${C(c)}>`)}}),s;const l=(f,c,u="name")=>{if(typeof c=="string"||typeof c=="number"||typeof c=="boolean")s.push(`<meta ${u}="${p(f)}" content="${p(c)}">`);else if(Array.isArray(c))c.forEach(r=>{if(typeof r=="string"||typeof r=="number"||typeof r=="boolean")s.push(`<meta ${u}="${p(f)}" content="${p(r)}">`);else if(typeof r=="object"){const g=Object.entries(r).filter(([y,$])=>$!==void 0).map(([y,$])=>`${y}="${p($)}"`).join(" ");s.push(`<meta ${g}>`)}});else if(typeof c=="object"){const r=Object.entries(c).filter(([g,y])=>y!==void 0).map(([g,y])=>`${g}="${p(y)}"`).join(" ");s.push(`<meta ${r}>`)}};if(i.startsWith("http-equiv:")){const f=i.replace("http-equiv:","");return l(f,o,"http-equiv"),s}if(i.startsWith("itemprop:")){const f=i.replace("itemprop:","");return l(f,o,"itemprop"),s}const h=["og:","twitter:","fb:","article:","profile:","book:","business:","music:","product:","video:","DC:","DCTERMS:"].find(f=>i.startsWith(f));if(h){const f=i.replace(h,"");return l(`${h.replace(":","")}:${f}`,o,h==="twitter:"||h==="DC:"||h==="DCTERMS:"?"name":"property"),s}if(i.startsWith("apple:")||i.startsWith("msapplication:")){const f=i.startsWith("apple:")?"apple-":"msapplication-",c=i.replace(/^apple:|^msapplication:/,"");return l(`${f}${c}`,o,"name"),s}return l(i,o),s},['<meta charset="UTF-8">','<meta name="viewport" content="width=device-width, initial-scale=1">']);return t.push(...E(e)),t.join(`
2
+ `)},H=e=>typeof e=="string"&&e.length>0&&!e.startsWith("/")&&!e.startsWith("http"),S=e=>typeof e=="string"&&e.length>0,W=e=>{if(!e||typeof e!="object")return null;if(S(e.src))return e.src;const n=e.content;return!n||typeof n!="object"?null:S(n.src)?n.src:S(n.storageUrl)?n.storageUrl:null};function x(e,n){if(!n||typeof n!="object")return e;const t=i=>!H(i)||!Object.prototype.hasOwnProperty.call(n,i)?i:W(n[i])||i,s={...e};for(const[i,o]of Object.entries(s))typeof o=="string"?s[i]=t(o):Array.isArray(o)&&(s[i]=o.map(l=>typeof l=="string"?t(l):l));return s}function w(e,n){if(!e||!n)return;const t=n.split(".");let s=e;for(const i of t){if(s==null||typeof s!="object")return;s=s[i]}return s}function J(e,n){const t=w(e,n);if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(typeof t=="string"&&!(0,M.isStringFunction)(t))return t}function Y(e,n,t){const i=(n.config||n.settings||{}).polyglot||n.polyglot,o=t?.lang||i?.defaultLang||"en",d=(i?.translations||{})[o]||{},h=[t?.state,n.state].filter(u=>u&&typeof u=="object"),f=u=>{for(const r of h){const g=J(r,u);if(g!==void 0)return g}},c={...e};for(const[u,r]of Object.entries(c))typeof r!="string"||!r.includes("{{")||(c[u]=r.replace(/\{\{\s*([^|{}]+?)\s*(?:\|\s*(\w+)\s*)?\}\}/g,(g,y,$)=>{const a=y.trim();if($==="polyglot")return d[a]??w(d,a)??g;if($==="getLocalStateLang")return f(a+o)??g;const m=f(a);return m!==void 0?m:d[a]??w(d,a)??g}));return c}function L(e){if(!(0,b.isObject)(e))return{};const n={...e};for(const[t,s]of Object.entries(n))if(typeof s=="function"){const i=s.toString(),o=i.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){n[t]=`{{ ${o[1]} | getLocalStateLang }}`;continue}const l=i.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(l){n[t]=`{{ ${l[1]} | polyglot }}`;continue}const d=i.match(/s\.(\w+(?:\.\w+)+)/);if(d){n[t]=`{{ ${d[1]} }}`;continue}delete n[t]}else if(typeof s=="string"){const i=s.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(i){n[t]=`{{ ${i[1]} | getLocalStateLang }}`;continue}const o=s.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){n[t]=`{{ ${o[1]} | polyglot }}`;continue}if(s.includes("=>")&&s.includes("s.")){const l=s.match(/s\.(\w+(?:\.\w+)+)/);if(l){n[t]=`{{ ${l[1]} }}`;continue}}(0,M.isStringFunction)(s)&&delete n[t]}return n}function B(e,n,t,{isProduction:s=!1,channel:i="production"}={}){const o=e.pages?.[n],l=(0,b.isObject)(o?.state)&&o?.state,d=o?.metadata||o?.helmet||l||{},h=L(d),f=new Set(Object.keys(h)),c=e.app?.metadata||{},u=L(c);let r={};if(e.integrations?.seo?r={...e.integrations.seo,...u,...h}:Object.keys(u).length?r={...u,...h}:r={...h},!r.title){const a=e.name||e.key;a?s?r.title=a:i==="development"?r.title=`${a} / dev:symbo.ls`:i==="staging"?r.title=`${a} / staging:symbo.ls`:r.title=`${a} / symbo.ls`:r.title="Symbols demo"}r=Y(r,e,t),r.title&&(f.has("title")||!r["og:title"])&&(f.has("og:title")||(r["og:title"]=r.title)),r.description&&(f.has("description")||!r["og:description"])&&(f.has("og:description")||(r["og:description"]=r.description)),r.title&&!r["twitter:title"]&&(r["twitter:title"]=r.title),r.description&&!r["twitter:description"]&&(r["twitter:description"]=r.description);const g=f.has("og:url")?r["og:url"]:f.has("url")?r.url:void 0,y=t?.actualPathname||n;if(g)r["og:url"]=g;else if(r["og:url"]||r.url){const a=(r["og:url"]||r.url||"").replace(/\/$/,"");if(a&&y&&y!=="/"){const m=y.startsWith("/")?y:"/"+y;r["og:url"]=a+m}}r=x(r,e.files);const $=e.name||e.app?.metadata?.title||e.app?.name||"";for(const[a,m]of Object.entries(r))if(typeof m=="string"&&m.includes("{{")){const O=m.replace(/\{\{[^}]*\}\}/g,"").trim();O?r[a]=O:a==="title"?r[a]=$:delete r[a]}return r}
@@ -1 +1,4 @@
1
- "use strict";var d=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var D=Object.prototype.hasOwnProperty;var T=(n,e)=>{for(var s in e)d(n,s,{get:e[s],enumerable:!0})},z=(n,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of C(e))!D.call(n,o)&&o!==s&&d(n,o,{get:()=>e[o],enumerable:!(t=M(e,o))||t.enumerable});return n};var N=n=>z(d({},"__esModule",{value:!0}),n);var cn={};T(cn,{__resetBuiltinMethodWarnings:()=>q,deepDefaults:()=>m,fetchLibraryData:()=>O,isWrappedLibrary:()=>k,mergeSharedLibraries:()=>sn,mergeSharedLibraryDesignSystems:()=>rn,normalizeIgnoreList:()=>y,normalizeLibraryKey:()=>f,resolveSharedLibraries:()=>an,sharedLibrary:()=>V});module.exports=N(cn);var c=require("./types.js"),u=require("./keys.js"),B=require("./env.js");const h="system",G="https://smbls-kv.nika-980.workers.dev",K="https://api.symbols.app";function f(n){const e=String(n||"").trim();if(!e)return{owner:h,key:"",full:""};let s=null,t=e;if(e.includes("/")){const i=e.indexOf("/");s=e.slice(0,i),t=e.slice(i+1)}t=t.replace(/\.symbo\.ls$/iu,""),s||(s=h);const o=t?`${s}/${t}`:"";return{owner:s,key:t,full:o}}const m=(n,e,s,t)=>{for(const o in e){const i=t?`${t}/${o}`:o;s&&s.has(i)||(o in n?(0,c.isObject)(n[o])&&(0,c.isObject)(e[o])&&m(n[o],e[o],s,i):n[o]=e[o])}},g=(n,e,s)=>{if(!(0,c.isObject)(n)||!e.size)return n;const t=`${s}/`;let o=!1;for(const r of e)if(r.startsWith(t)){o=!0;break}if(!o)return n;const i={};for(const r in n){if(!Object.prototype.hasOwnProperty.call(n,r))continue;const a=`${s}/${r}`;e.has(a)||(i[r]=g(n[r],e,a))}return i},W=new Set,Y=new Set(["components","pages","functions","snippets","methods"]),L=(n,e)=>e===""&&Y.has(n),$=["fontFamily","fontfamily","font_family","FONT_FAMILY"],S=n=>{const e=new Map;if(!(0,c.isObject)(n))return e;for(const s of $){const t=n[s];if((0,c.isObject)(t))for(const o in t)!(0,c.isObject)(t[o])||!t[o].isDefault||(e.has(s)||e.set(s,new Set),e.get(s).add(o))}return e},A=(n,e)=>{for(const s of $){const t=n[s];if(!(0,c.isObject)(t))continue;const o=e.get(s);let i=null;for(const r in t){const a=t[r];if(!(0,c.isObject)(a)||!a.isDefault||o&&o.has(r))continue;const l={...a};delete l.isDefault,i||(i={...t}),i[r]=l}i&&(n[s]=i)}},J=n=>n.replace(/\.js$/iu,""),y=n=>{const e=new Set;if(!Array.isArray(n))return e;for(const s of n){if(!(0,c.isString)(s))continue;const t=s.split("/").map(o=>J(o.trim())).filter(Boolean).join("/");t&&e.add(t)}return e},V=(n,e={})=>({library:n,ignoreList:Array.isArray(e.ignoreList)?e.ignoreList:[]}),k=n=>(0,c.isObject)(n)&&Array.isArray(n.ignoreList)&&("library"in n||"key"in n||"name"in n),I=n=>n.library!==void 0?n.library:n.key??n.name,p=new Set,q=()=>{p.clear()},H=(n,e)=>{const s=e.filter(t=>!p.has(t));if(s.length){for(const t of s)p.add(t);(0,B.isLoudDevRuntime)()&&console.warn(`[smbls] shared library "${n}" ships ${s.map(t=>`methods.${t}`).join(", ")} \u2014 named like a built-in element method. Refused: the built-in wins; a library cannot replace an element method on the consuming app. If the app wants this version, declare it in the app's OWN methods.`)}},Q=(n,e,s)=>{let t=null;for(const o in n)if((0,u.isProtectedElementMethod)(o)&&(e.has(`methods/${o}`)||s.push(o),!t)){t={};for(const i in n)(0,u.isProtectedElementMethod)(i)||(t[i]=n[i])}return t||n},_=(n,e)=>{const s=y(n.sharedLibIgnore);return n.sharePages===!1&&s.add("pages"),s.size?new Set([...e,...s]):e},X=(n,e,s,t="library")=>{const o=_(e,s),i=[];for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)&&!(r==="sharePages"||r==="sharedLibIgnore")&&r!=="app"&&!o.has(r)){if((0,c.isObject)(e[r])&&(0,c.isObject)(n[r])){if(r==="designSystem")m(n[r],e[r],o,r);else for(const a in e[r])if(!o.has(`${r}/${a}`)){if(r==="methods"&&(0,u.isProtectedElementMethod)(a)){a in n[r]||i.push(a);continue}a in n[r]?L(r,n[r][a])&&!L(r,e[r][a])&&(n[r][a]=e[r][a]):n[r][a]=e[r][a]}}else if(!(r in n)){const a=e[r],l=r==="methods"&&a&&typeof a=="object"?Q(a,o,i):a;n[r]=g(l,o,r)}}i.length&&H(t,i)},Z=(n,e,s)=>{if(n!==e){const t=I(n);if((0,c.isString)(t)&&t)return t;if(n.key||n.name)return n.key||n.name}return e&&(e.key||e.name)||`sharedLibraries[${s}]`},x=`${h}/default`,nn=n=>(0,c.isString)(n)&&n!==""&&f(n).full===x,en=(n,e)=>{if((0,c.isString)(e.key)&&e.key)return e.key;if(n!==e){if((0,c.isString)(n.key)&&n.key)return n.key;if((0,c.isString)(n.name)&&n.name)return n.name}return null},tn=n=>{const e=[],s=[];for(let t=0;t<n.length;t++){const o=n[t];let i=o,r=W;if(k(i)&&(r=y(i.ignoreList),i=i.library),!(0,c.isObject)(i))continue;const a={entry:o,lib:i,ignore:r,index:t};nn(en(o,i))?s.push(a):e.push(a)}return{linked:e,bases:s}},R=(n,e,s)=>{const t=S(e()),{linked:o,bases:i}=tn(n);for(const a of o)s(a);const r=!t.size&&i.length?S(e()):null;for(const a of i)s(a);return t.size?t:r&&r.size?r:null},sn=(n,e)=>{if(!e||!e.length)return;const s=n.designSystem,t=R(e,()=>n.designSystem,({entry:o,lib:i,ignore:r,index:a})=>X(n,i,r,Z(o,i,a)));t&&(n.designSystem!==s&&(n.designSystem={...n.designSystem}),A(n.designSystem,t))},rn=(n,e,s=m)=>{if(!(0,c.isObject)(n)||!Array.isArray(e)||!e.length)return n;const t=R(e,()=>n,({lib:o,ignore:i})=>{const r=o.designSystem;if(!r||typeof r!="object")return;const a=_(o,i);a.has("designSystem")||s(n,r,a,"designSystem")});return t&&A(n,t),n};async function O(n,e={}){if((e.provider||"kv")==="api")return j(n,e);const t=await on(n,e);return t||j(n,e)}async function on(n,e={}){const s=e.kvBaseUrl||G,t=e.env||"production",o=`${s}/kv/${encodeURIComponent(n)}?env=${t}`;try{const i=await fetch(o,{method:"GET"});return i.ok&&(await i.json())?.value||null}catch{return null}}async function j(n,e={}){const s=e.apiBaseUrl||K,{key:t}=f(n);try{const o=`${s}/core/projects/libraries/available?search=${encodeURIComponent(t)}&limit=10`,i=await fetch(o,{method:"GET"});if(!i.ok)return null;const r=await i.json(),l=(r?.items||r?.data||(Array.isArray(r)?r:[])).find(U=>{const{key:F}=f(U?.key);return F.toLowerCase()===t.toLowerCase()});if(!l?.id&&!l?._id)return null;const E=l.id||l._id,P=`${s}/core/projects/${encodeURIComponent(E)}/data?branch=main`,w=await fetch(P,{method:"GET"});if(!w.ok)return null;const b=await w.json();return b?.data||b||null}catch{return null}}async function v(n,e={}){if((0,c.isObject)(n))return n;if((0,c.isString)(n)){const{full:s}=f(n);if(!s)return null;try{const t=await O(s,e);return t||console.warn(`[smbls] Shared library "${s}" not found`),t}catch(t){return console.warn(`[smbls] Failed to fetch shared library "${s}":`,t.message),null}}return null}async function an(n,e={}){return!n||!n.length?[]:(await Promise.all(n.map(async t=>{if(k(t)){const o=await v(I(t),e);return o?{library:o,ignoreList:t.ignoreList}:null}return v(t,e)}))).filter(Boolean)}
1
+ "use strict";var $=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var ye=Object.prototype.hasOwnProperty;var be=(e,n)=>{for(var o in n)$(e,o,{get:n[o],enumerable:!0})},de=(e,n,o,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of pe(n))!ye.call(e,s)&&s!==o&&$(e,s,{get:()=>n[s],enumerable:!(t=ue(n,s))||t.enumerable});return e};var he=e=>de($({},"__esModule",{value:!0}),e);var nt={};be(nt,{LIBRARY_PACKAGES:()=>le,LIBRARY_SCOPES_KEY:()=>k,__resetBuiltinMethodWarnings:()=>Oe,bindLibraryGlobalScopes:()=>Ue,deepDefaults:()=>A,exposeBagGlobalScopes:()=>ze,fetchLibraryData:()=>fe,isWrappedLibrary:()=>_,libraryPackageSpecs:()=>ce,mergeSharedLibraries:()=>ve,mergeSharedLibraryDesignSystems:()=>xe,normalizeIgnoreList:()=>B,normalizeLibraryKey:()=>S,resolveSharedLibraries:()=>tt,sharedLibrary:()=>we,warnLibraryAliasCollision:()=>ae});module.exports=he(nt);var f=require("./types.js"),L=require("./keys.js"),ie=require("./env.js"),b=require("./object.js");const R="system",me="https://smbls-kv.nika-980.workers.dev",ge="https://api.symbols.app";function S(e){const n=String(e||"").trim();if(!n)return{owner:R,key:"",full:""};let o=null,t=n;if(n.includes("/")){const i=n.indexOf("/");o=n.slice(0,i),t=n.slice(i+1)}t=t.replace(/\.symbo\.ls$/iu,""),o||(o=R);const s=t?`${o}/${t}`:"";return{owner:o,key:t,full:s}}const A=(e,n,o,t)=>{for(const s in n){const i=t?`${t}/${s}`:s;o&&o.has(i)||(s in e?(0,f.isObject)(e[s])&&(0,f.isObject)(n[s])&&A(e[s],n[s],o,i):e[s]=n[s])}},N=(e,n,o)=>{if(!(0,f.isObject)(e)||!n.size)return e;const t=`${o}/`;let s=!1;for(const c of n)if(c.startsWith(t)){s=!0;break}if(!s)return e;const i={};for(const c in e){if(!Object.prototype.hasOwnProperty.call(e,c))continue;const r=`${o}/${c}`;n.has(r)||(i[c]=N(e[c],n,r))}return i},Se=new Set,_e=new Set(["components","pages","functions","snippets","methods"]),F=(e,n)=>n===""&&_e.has(e),V=["fontFamily","fontfamily","font_family","FONT_FAMILY"],D=e=>{const n=new Map;if(!(0,f.isObject)(e))return n;for(const o of V){const t=e[o];if((0,f.isObject)(t))for(const s in t)!(0,f.isObject)(t[s])||!t[s].isDefault||(n.has(o)||n.set(o,new Set),n.get(o).add(s))}return n},G=(e,n)=>{for(const o of V){const t=e[o];if(!(0,f.isObject)(t))continue;const s=n.get(o);let i=null;for(const c in t){const r=t[c];if(!(0,f.isObject)(r)||!r.isDefault||s&&s.has(c))continue;const l={...r};delete l.isDefault,i||(i={...t}),i[c]=l}i&&(e[o]=i)}},ke=e=>e.replace(/\.js$/iu,""),B=e=>{const n=new Set;if(!Array.isArray(e))return n;for(const o of e){if(!(0,f.isString)(o))continue;const t=o.split("/").map(s=>ke(s.trim())).filter(Boolean).join("/");t&&n.add(t)}return n},we=(e,n={})=>({library:e,ignoreList:Array.isArray(n.ignoreList)?n.ignoreList:[]}),_=e=>(0,f.isObject)(e)&&Array.isArray(e.ignoreList)&&("library"in e||"key"in e||"name"in e),U=e=>e.library!==void 0?e.library:e.key??e.name,j=new Set,Oe=()=>{j.clear()},Le=(e,n)=>{const o=n.filter(t=>!j.has(t));if(o.length){for(const t of o)j.add(t);(0,ie.isLoudDevRuntime)()&&console.warn(`[smbls] shared library "${e}" ships ${o.map(t=>`methods.${t}`).join(", ")} \u2014 named like a built-in element method. Refused: the built-in wins; a library cannot replace an element method on the consuming app. If the app wants this version, declare it in the app's OWN methods.`)}},Ae=(e,n,o)=>{let t=null;for(const s in e)if((0,L.isProtectedElementMethod)(s)&&(n.has(`methods/${s}`)||o.push(s),!t)){t={};for(const i in e)(0,L.isProtectedElementMethod)(i)||(t[i]=e[i])}return t||e},Y=(e,n)=>{const o=B(e.sharedLibIgnore);return e.sharePages===!1&&o.add("pages"),o.size?new Set([...n,...o]):n},E=["functions","methods","snippets"],W=["components","pages"],K=Symbol.for("smbls.libraryScope"),k="__libraryScopes",I=new Map,$e=()=>Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4),h=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),Re=/const __scope = |const __peers_* = |const _s = el\?\.scope|\?\.context\?\.globalScope\?\./,z=e=>{try{return(0,b.getFunctionSource)(e)}catch{return null}},J=e=>{if(typeof e!="function")return null;const n=z(e);return(0,f.isString)(n)&&Re.test(n)&&(0,b.hasFunction)(n)?n:null},H=e=>(0,f.isString)(e)&&(0,b.hasFunction)(e)||J(e)!==null,je=e=>{const n=e.globalScope;return(0,f.isObject)(n)&&Object.keys(n).some(o=>H(n[o]))?!0:E.some(o=>{const t=e[o];return!!t&&typeof t=="object"&&Object.keys(t).some(s=>H(t[s]))})},Ee=(e,n,o)=>{const t=e.globalScope,s=n.globalScope;if(o.has("globalScope")||!(0,f.isObject)(t)||!(0,f.isObject)(s)||!je(n))return 0;let i=0;for(const c of Object.keys(s))o.has(`globalScope/${c}`)||h(t,c)&&i++;return i},Ie=[[/const __scope = (\(\(\) => \{ const r = [\s\S]*?\}\)\(\));/g,"const __scope = $RESOLVE($1);"],[/const __scope = this \?\? \{\};/g,"const __scope = $RESOLVE(this ?? {});"],[/const (__peers_*) = (this && this !== globalThis && this\.context && this\.context\.globalScope \? this\.scope \?\? this\.context\.globalScope : this);/g,"const $1 = $RESOLVE($2);"],[/const _s = (el\?\.scope \?\? el\?\.context\?\.globalScope \?\? \{\});/g,"const _s = $RESOLVE($1);"],[/(?<![\w$.])(this|[A-Za-z_$][\w$]*)\?\.context\?\.globalScope\?\./g,"$RESOLVE($1?.context?.globalScope)?."]],Pe=e=>{const n=e.split(""),o=[];let t=0,s=0;const i=(r,l)=>{for(let p=r;p<l;p++)n[p]!==`
2
+ `&&(n[p]="~")},c=()=>{const r=t;for(;t<e.length;){const l=e[t];if(l==="\\"){t+=2;continue}if(l==="`"){i(r,t),t++;return}if(l==="$"&&e[t+1]==="{"){i(r,t),t+=2,o.push(s),s++;return}t++}i(r,t)};for(;t<e.length;){const r=e[t];if(r==="/"&&e[t+1]==="/"){const l=e.indexOf(`
3
+ `,t),p=l===-1?e.length:l;i(t,p),t=p;continue}if(r==="/"&&e[t+1]==="*"){const l=e.indexOf("*/",t+2),p=l===-1?e.length:l+2;i(t,p),t=p;continue}if(r==='"'||r==="'"){const l=r,p=++t;for(;t<e.length&&e[t]!==l&&e[t]!==`
4
+ `;)e[t]==="\\"&&t++,t++;i(p,t),t++;continue}if(r==="`"){t++,c();continue}if(r==="{"){s++,t++;continue}if(r==="}"){if(s--,o.length&&s===o[o.length-1]){o.pop(),t++,c();continue}t++;continue}t++}return n.join("")},q=(e,n)=>{if(!(0,f.isString)(e)||!e.includes("__scope = ")&&!e.includes("__peers")&&!e.includes("const _s = ")&&!e.includes("?.context?.globalScope?.")||!(0,b.hasFunction)(e))return e;const o=`(globalThis[Symbol.for('smbls.libraryScope')] || ((_, v) => v))(${JSON.stringify(n)}, `;let t=e;for(const[s,i]of Ie){const c=Pe(t);t=t.replace(s,(...r)=>{const l=r[r.length-2];return c[l]==="~"||c[l]!==t[l]?r[0]:i.replace(/\$RESOLVE\(/g,o).replace(/\$(\d)/g,(p,a)=>r[Number(a)])})}return t},w=(e,n)=>{if((0,f.isString)(e))return q(e,n);const o=J(e);return o===null?e:q(o,n)},Te={lazy:!0,window:globalThis},Z=(e,n)=>{const o=w(e,n);if(o===e||!(0,f.isString)(o))return o;try{const t=(0,b.deepDestringifyFunctions)({v:o},{},Te).v;return typeof t!="function"?o:(Object.defineProperty(t,"toJSON",{value:()=>o,configurable:!0}),t)}catch{return o}},P=e=>{if(!e||typeof e!="object")return!1;if(Array.isArray(e))return!0;const n=Object.getPrototypeOf(e);return n===Object.prototype||n===null},Q=(e,n,o=new WeakMap)=>{if((0,f.isString)(e)||typeof e=="function")return Z(e,n);if((0,b.isStringTag)(e)||!P(e))return e;if(o.has(e))return o.get(e);const t=Array.isArray(e)?[]:Object.getPrototypeOf(e)===null?Object.create(null):{};o.set(e,t);for(const s of Object.keys(e))t[s]=Q(e[s],n,o);return t},Be=(e,n)=>{const o={...e},t={};for(const s of Object.keys(e.globalScope))t[s]=w(e.globalScope[s],n);o.globalScope=t;for(const s of E){const i=e[s];if(!P(i))continue;const c={};for(const r of Object.keys(i))c[r]=Z(i[r],n);o[s]=c}for(const s of W)P(e[s])&&(o[s]=Q(e[s],n));return o},X=new WeakMap,Ce=(e,n,o)=>{let t=X.get(e);t||X.set(e,t=new Map);let s=t.get(n);if(s)return s;const i=(c,r)=>h(o,c)&&o[c]===r;return s=new Proxy(e,{get(c,r){if(typeof r=="symbol"||h(c,r))return Reflect.get(c,r);const l=Reflect.get(c,r);return h(n,r)&&(l===void 0||i(r,l))||l===void 0?n[r]:l},set(c,r,l){return typeof r!="symbol"&&!h(c,r)&&h(n,r)?(n[r]=l,!0):Reflect.set(c,r,l)},has:(c,r)=>Reflect.has(c,r)||r in n}),t.set(n,s),s},Me=e=>!!e&&typeof e=="object"&&!!e.__raw&&typeof e.__raw=="object",Ne=(e,n)=>{const o=I.get(e);return o?n===o.consumerGs?o.libGs:Me(n)?Ce(n,o.libGs,o.consumerGs):n:n},Fe=()=>{typeof globalThis[K]!="function"&&Object.defineProperty(globalThis,K,{value:Ne,configurable:!0})},O=e=>{const n=e[k];return Array.isArray(n)?n:null},T=e=>_(e)?e.library:e,Ve=(e,n,o)=>{const t=O(e);return!!t&&t.some(s=>s&&s.index===n&&(!s.key||s.key===o.key)&&(0,f.isString)(s.id)&&De(e,s.id))},De=(e,n)=>{const o=JSON.stringify(n),t=new Set,s=i=>{if((0,f.isString)(i))return i.includes(o);if(!i||typeof i!="object"||t.has(i))return!1;t.add(i);for(const c in i)if(s(i[c]))return!0;return!1};for(const i of["globalScope",...E,...W])if(s(e[i]))return!0;return!1},Ge=(e,n)=>{const o={};for(const t of Object.keys(e))o[t]=w(e[t],n);return o},v=new WeakMap,Ue=(e,n=null)=>{const o=e&&O(e);if(!o||!o.length)return 0;const t=e.globalScope;if(!(0,f.isObject)(t))return 0;const s=Array.isArray(e.sharedLibraries)?e.sharedLibraries:[];let i=v.get(t);i||v.set(t,i=new Set),Fe();let c=0;for(const r of o){if(!r||!(0,f.isString)(r.id)||i.has(r.id))continue;const l=T(s[r.index]);if(!l||!(0,f.isObject)(l.globalScope)||r.key&&l.key!==r.key)continue;const p=y=>typeof y=="function"?z(y):y,a=(y,m)=>{if(y===m)return!0;const C=p(y),M=p(m);return(0,f.isString)(C)||(0,f.isString)(M)?C===M:JSON.stringify(y)===JSON.stringify(m)},u=(0,f.isObject)(n)?(Array.isArray(r.landed)?r.landed:[]).filter(y=>(0,f.isString)(y)&&h(l.globalScope,y)&&h(n,y)&&a(n[y],w(l.globalScope[y],r.id))):[],d=(0,b.destringifyGlobalScope)(Ge(l.globalScope,r.id));Object.setPrototypeOf(d,t),I.set(r.id,{libGs:d,consumerGs:t});for(const y of u)t[y]=d[y];i.add(r.id),c++}return c},Ye=/^@symbo[-.]ls\//,x=e=>e.includes("/")?e.slice(e.indexOf("/")+1):e,ce=(e,n)=>{const o=[];if(!Array.isArray(e))return o;const t=new Map,s=(c,r,l)=>{for(const p of[`@symbo-ls/${c}`,`@symbo.ls/${c}`]){const a=t.get(p);if(a===void 0){t.set(p,r),o.push([p,r]);continue}a!==r&&l&&typeof n=="function"&&n({spec:p,kept:a,refused:r})}},i=[];for(const c of e){const r=T(c);if(!r||typeof r!="object"||r.__isStub)continue;const l=r.key||r.name||r.__libraryKey,p=[];for(const a of[r.key,r.name,r.__libraryKey,r.__libraryName]){if(typeof a!="string"||!a||a!==l&&!Ye.test(a))continue;const u=x(a);u&&!p.includes(u)&&p.push(u)}p.forEach((a,u)=>{u===0&&l&&x(l)===a?s(a,r,!1):i.push([a,r])})}for(const[c,r]of i)s(c,r,!0);return o},ae=({spec:e,kept:n,refused:o})=>{typeof console>"u"||console.warn(`[smbls] shared library "${o&&o.key}" also claims ${e}, which "${n&&n.key}" already owns; ${e} stays with "${n&&n.key}".`)},ee=["functions","methods","snippets"],le=Symbol.for("smbls.libraryPackages"),g=new WeakMap,We=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Ke=e=>({get globalScope(){return e()}}),te=(e,n,o)=>{const t={};for(const s of Object.keys(e))t[s]=e[s];return Object.defineProperty(t,"context",{configurable:!0,enumerable:!1,writable:!0,value:Ke(n)}),g.set(t,o),t},ne=e=>!We(e)||!g.has(e)&&Object.prototype.hasOwnProperty.call(e,"context"),ze=e=>{if(!e||typeof e!="object")return;const n=()=>e.globalScope;for(const t of ee){const s=e[t];ne(s)||g.get(s)===e||(e[t]=te(s,n,e))}if(Array.isArray(e.sharedLibraries)){const t=O(e)||[];e.sharedLibraries=e.sharedLibraries.map((s,i)=>{const c=_(s)&&s&&"library"in s,r=T(s);if(!r||typeof r!="object"||r.__isStub||g.get(r)===e)return s;const l=t.find(u=>u&&u.index===i&&(!u.key||u.key===r.key)),p=()=>{const u=l&&I.get(l.id);return u&&u.consumerGs===e.globalScope?u.libGs:e.globalScope},a={...r};for(const u of ee)ne(r[u])||(a[u]=te(r[u],p,e));return g.set(a,e),c?{...s,library:a}:a})}const o=e.globalScope;if(o&&typeof o=="object"){const t={};for(const[s,i]of ce(e.sharedLibraries,ae))t[s]=i;try{Object.defineProperty(o,le,{configurable:!0,enumerable:!1,writable:!0,value:t})}catch{}}},Je=(e,n,o,t="library",s=-1)=>{const i=Y(n,o),c=!Ve(e,s,n)&&Ee(e,n,i)>0?`${t}#${$e()}`:null,r=c?Be(n,c):n,l=c?new Set(Object.keys(e.globalScope)):null,p=[];for(const a in r)if(Object.prototype.hasOwnProperty.call(r,a)&&!(a==="sharePages"||a==="sharedLibIgnore")&&a!==k&&!a.startsWith("__")&&a!=="app"&&!i.has(a)){if((0,f.isObject)(r[a])&&(0,f.isObject)(e[a])){if(a==="designSystem")A(e[a],r[a],i,a);else for(const u in r[a])if(!i.has(`${a}/${u}`)){if(a==="methods"&&(0,L.isProtectedElementMethod)(u)){u in e[a]||p.push(u);continue}u in e[a]?F(a,e[a][u])&&!F(a,r[a][u])&&(e[a][u]=r[a][u]):e[a][u]=r[a][u]}}else if(!(a in e)){const u=r[a],d=a==="methods"&&u&&typeof u=="object"?Ae(u,i,p):u;e[a]=N(d,i,a)}}c&&(O(e)||(e[k]=[]),e[k].push({id:c,index:s,key:(0,f.isString)(n.key)?n.key:null,landed:Object.keys(r.globalScope).filter(a=>!l.has(a))})),p.length&&Le(t,p)},He=(e,n,o)=>{if(e!==n){const t=U(e);if((0,f.isString)(t)&&t)return t;if(e.key||e.name)return e.key||e.name}return n&&(n.key||n.name)||`sharedLibraries[${o}]`},qe=`${R}/default`,Ze=e=>(0,f.isString)(e)&&e!==""&&S(e).full===qe,Qe=(e,n)=>{if((0,f.isString)(n.key)&&n.key)return n.key;if(e!==n){if((0,f.isString)(e.key)&&e.key)return e.key;if((0,f.isString)(e.name)&&e.name)return e.name}return null},Xe=e=>{const n=[],o=[];for(let t=0;t<e.length;t++){const s=e[t];let i=s,c=Se;if(_(i)&&(c=B(i.ignoreList),i=i.library),!(0,f.isObject)(i))continue;const r={entry:s,lib:i,ignore:c,index:t};Ze(Qe(s,i))?o.push(r):n.push(r)}return{linked:n,bases:o}},oe=(e,n,o)=>{const t=D(n()),{linked:s,bases:i}=Xe(e);for(const r of s)o(r);const c=!t.size&&i.length?D(n()):null;for(const r of i)o(r);return t.size?t:c&&c.size?c:null},ve=(e,n)=>{if(!n||!n.length)return;const o=e.designSystem,t=oe(n,()=>e.designSystem,({entry:s,lib:i,ignore:c,index:r})=>Je(e,i,c,He(s,i,r),r));t&&(e.designSystem!==o&&(e.designSystem={...e.designSystem}),G(e.designSystem,t))},xe=(e,n,o=A)=>{if(!(0,f.isObject)(e)||!Array.isArray(n)||!n.length)return e;const t=oe(n,()=>e,({lib:s,ignore:i})=>{const c=s.designSystem;if(!c||typeof c!="object")return;const r=Y(s,i);r.has("designSystem")||o(e,c,r,"designSystem")});return t&&G(e,t),e};async function fe(e,n={}){if((n.provider||"kv")==="api")return se(e,n);const t=await et(e,n);return t||se(e,n)}async function et(e,n={}){const o=n.kvBaseUrl||me,t=n.env||"production",s=`${o}/kv/${encodeURIComponent(e)}?env=${t}`;try{const i=await fetch(s,{method:"GET"});return i.ok&&(await i.json())?.value||null}catch{return null}}async function se(e,n={}){const o=n.apiBaseUrl||ge,{key:t}=S(e);try{const s=`${o}/core/projects/libraries/available?search=${encodeURIComponent(t)}&limit=10`,i=await fetch(s,{method:"GET"});if(!i.ok)return null;const c=await i.json(),l=(c?.items||c?.data||(Array.isArray(c)?c:[])).find(y=>{const{key:m}=S(y?.key);return m.toLowerCase()===t.toLowerCase()});if(!l?.id&&!l?._id)return null;const p=l.id||l._id,a=`${o}/core/projects/${encodeURIComponent(p)}/data?branch=main`,u=await fetch(a,{method:"GET"});if(!u.ok)return null;const d=await u.json();return d?.data||d||null}catch{return null}}async function re(e,n={}){if((0,f.isObject)(e))return e;if((0,f.isString)(e)){const{full:o}=S(e);if(!o)return null;try{const t=await fe(o,n);return t||console.warn(`[smbls] Shared library "${o}" not found`),t}catch(t){return console.warn(`[smbls] Failed to fetch shared library "${o}":`,t.message),null}}return null}async function tt(e,n={}){return!e||!e.length?[]:(await Promise.all(e.map(async t=>{if(_(t)){const s=await re(U(t),n);return s?{library:s,ignoreList:t.ignoreList}:null}return re(t,n)}))).filter(Boolean)}
@@ -1,2 +1,2 @@
1
- import{isObject as A}from"./types.js";import{isStringFunction as w}from"./function.js";const g=n=>{if(n==null)return"";const r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return n.toString().replace(/[&<>"']/g,t=>r[t])},O=n=>Object.entries(n||{}).filter(([r,t])=>t!==void 0).map(([r,t])=>`${r}="${g(t)}"`).join(" "),b=n=>{let r=5381;const t=String(n);for(let e=0;e<t.length;e++)r=(r*33^t.charCodeAt(e))>>>0;return r.toString(36)},L=new Set(["jsonLd","styles","scripts"]),E=n=>{const r=[];if(Array.isArray(n.jsonLd))for(const t of n.jsonLd){if(t==null)continue;const e=typeof t=="string"?t:JSON.stringify(t),i=String(e).replace(/<\/script/gi,"<\\/script");r.push(`<script type="application/ld+json" data-smbls-jsonld="${b(e)}">${i}<\/script>`)}if(Array.isArray(n.styles))for(const t of n.styles){if(t==null||!String(t).trim())continue;const e=String(t).replace(/<\/style/gi,"<\\/style");r.push(`<style data-smbls-style="${b(e)}">${e}</style>`)}if(Array.isArray(n.scripts))for(const t of n.scripts){if(!t)continue;const e=typeof t=="string",i=e?t:t.src;if(!i&&!t.body)continue;const o=[];i&&o.push(`src="${g(i)}"`),e||(t.type&&o.push(`type="${g(t.type)}"`),t.async&&o.push("async"),t.defer&&o.push("defer"),t.integrity&&o.push(`integrity="${g(t.integrity)}"`),t.crossorigin&&o.push(`crossorigin="${g(t.crossorigin)}"`),t.referrerpolicy&&o.push(`referrerpolicy="${g(t.referrerpolicy)}"`),t.nomodule&&o.push("nomodule"));const l=` data-smbls-script="${g(i||b(t.body||""))}"`;if(!e&&t.body){const h=String(t.body).replace(/<\/script/gi,"<\\/script");r.push(`<script ${o.join(" ")}${l}>${h}<\/script>`)}else r.push(`<script ${o.join(" ")}${l}><\/script>`)}return r},U=(n,r)=>{r||(n={...n,robots:"noindex"});const t=Object.entries(n).reduce((e,[i,o])=>{if(!o&&o!==0&&o!==!1||L.has(i))return e;if(i==="title")return e.push(`<title>${g(o)}</title>`),e;if(i==="canonical")return e.push(`<link rel="canonical" href="${g(o)}">`),e;if(i==="manifest")return e.push(`<link rel="manifest" href="${g(o)}">`),e;if(i==="favicon"||i==="favicons"||i==="icon"||i==="icons")return(Array.isArray(o)?o:[o]).forEach(c=>{if(typeof c=="string")e.push(`<link rel="icon" href="${g(c)}">`);else if(typeof c=="object"){const u=O(c);/rel=/.test(u)?e.push(`<link ${u}>`):e.push(`<link rel="icon" ${u}>`)}}),e;if(i==="alternate")return(Array.isArray(o)?o:[o]).forEach(c=>{if(typeof c=="object"){const u=Object.entries(c).filter(([s,p])=>p!==void 0).map(([s,p])=>`${s}="${g(p)}"`).join(" ");e.push(`<link rel="alternate" ${u}>`)}}),e;const l=(f,c,u="name")=>{if(typeof c=="string"||typeof c=="number"||typeof c=="boolean")e.push(`<meta ${u}="${g(f)}" content="${g(c)}">`);else if(Array.isArray(c))c.forEach(s=>{if(typeof s=="string"||typeof s=="number"||typeof s=="boolean")e.push(`<meta ${u}="${g(f)}" content="${g(s)}">`);else if(typeof s=="object"){const p=Object.entries(s).filter(([m,a])=>a!==void 0).map(([m,a])=>`${m}="${g(a)}"`).join(" ");e.push(`<meta ${p}>`)}});else if(typeof c=="object"){const s=Object.entries(c).filter(([p,m])=>m!==void 0).map(([p,m])=>`${p}="${g(m)}"`).join(" ");e.push(`<meta ${s}>`)}};if(i.startsWith("http-equiv:")){const f=i.replace("http-equiv:","");return l(f,o,"http-equiv"),e}if(i.startsWith("itemprop:")){const f=i.replace("itemprop:","");return l(f,o,"itemprop"),e}const y=["og:","twitter:","fb:","article:","profile:","book:","business:","music:","product:","video:","DC:","DCTERMS:"].find(f=>i.startsWith(f));if(y){const f=i.replace(y,"");return l(`${y.replace(":","")}:${f}`,o,y==="twitter:"||y==="DC:"||y==="DCTERMS:"?"name":"property"),e}if(i.startsWith("apple:")||i.startsWith("msapplication:")){const f=i.startsWith("apple:")?"apple-":"msapplication-",c=i.replace(/^apple:|^msapplication:/,"");return l(`${f}${c}`,o,"name"),e}return l(i,o),e},['<meta charset="UTF-8">','<meta name="viewport" content="width=device-width, initial-scale=1">']);return t.push(...E(n)),t.join(`
2
- `)},W=n=>typeof n=="string"&&n.length>0&&!n.startsWith("/")&&!n.startsWith("http"),j=n=>typeof n=="string"&&n.length>0,x=n=>{if(!n||typeof n!="object")return null;if(j(n.src))return n.src;const r=n.content;return!r||typeof r!="object"?null:j(r.src)?r.src:j(r.storageUrl)?r.storageUrl:null};function T(n,r){if(!r||typeof r!="object")return n;const t=i=>!W(i)||!Object.prototype.hasOwnProperty.call(r,i)?i:x(r[i])||i,e={...n};for(const[i,o]of Object.entries(e))typeof o=="string"?e[i]=t(o):Array.isArray(o)&&(e[i]=o.map(l=>typeof l=="string"?t(l):l));return e}function S(n,r){if(!n||!r)return;const t=r.split(".");let e=n;for(const i of t){if(e==null||typeof e!="object")return;e=e[i]}return e}function F(n,r){const t=S(n,r);if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(typeof t=="string"&&!w(t))return t}function D(n,r,t){const i=(r.config||r.settings||{}).polyglot||r.polyglot,o=t?.lang||i?.defaultLang||"en",h=(i?.translations||{})[o]||{},y=[t?.state,r.state].filter(u=>u&&typeof u=="object"),f=u=>{for(const s of y){const p=F(s,u);if(p!==void 0)return p}},c={...n};for(const[u,s]of Object.entries(c))typeof s!="string"||!s.includes("{{")||(c[u]=s.replace(/\{\{\s*([^|{}]+?)\s*(?:\|\s*(\w+)\s*)?\}\}/g,(p,m,a)=>{const d=m.trim();if(a==="polyglot")return h[d]??S(h,d)??p;if(a==="getLocalStateLang")return f(d+o)??p;const $=f(d);return $!==void 0?$:h[d]??S(h,d)??p}));return c}function M(n){if(!A(n))return{};const r={...n};for(const[t,e]of Object.entries(r))if(typeof e=="function"){const i=e.toString(),o=i.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){r[t]=`{{ ${o[1]} | getLocalStateLang }}`;continue}const l=i.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(l){r[t]=`{{ ${l[1]} | polyglot }}`;continue}const h=i.match(/s\.(\w+(?:\.\w+)+)/);if(h){r[t]=`{{ ${h[1]} }}`;continue}delete r[t]}else if(typeof e=="string"){const i=e.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(i){r[t]=`{{ ${i[1]} | getLocalStateLang }}`;continue}const o=e.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){r[t]=`{{ ${o[1]} | polyglot }}`;continue}if(e.includes("=>")&&e.includes("s.")){const l=e.match(/s\.(\w+(?:\.\w+)+)/);if(l){r[t]=`{{ ${l[1]} }}`;continue}}w(e)&&delete r[t]}return r}function _(n,r,t,{isProduction:e=!1,channel:i="production"}={}){const o=n.pages?.[r],l=A(o?.state)&&o?.state,h=o?.metadata||o?.helmet||l||{},y=M(h),f=new Set(Object.keys(y)),c=n.app?.metadata||{},u=M(c);let s={};if(n.integrations?.seo?s={...n.integrations.seo,...u,...y}:Object.keys(u).length?s={...u,...y}:s={...y},!s.title){const a=n.name||n.key;a?e?s.title=a:i==="development"?s.title=`${a} / dev:symbo.ls`:i==="staging"?s.title=`${a} / staging:symbo.ls`:s.title=`${a} / symbo.ls`:s.title="Symbols demo"}s=D(s,n,t),s.title&&(f.has("title")||!s["og:title"])&&(f.has("og:title")||(s["og:title"]=s.title)),s.description&&(f.has("description")||!s["og:description"])&&(f.has("og:description")||(s["og:description"]=s.description)),s.title&&!s["twitter:title"]&&(s["twitter:title"]=s.title),s.description&&!s["twitter:description"]&&(s["twitter:description"]=s.description);const p=t?.actualPathname||r;if(s["og:url"]||s.url){const a=(s["og:url"]||s.url||"").replace(/\/$/,"");if(a&&p&&p!=="/"){const d=p.startsWith("/")?p:"/"+p;s["og:url"]=a+d}}s=T(s,n.files);const m=n.name||n.app?.metadata?.title||n.app?.name||"";for(const[a,d]of Object.entries(s))if(typeof d=="string"&&d.includes("{{")){const $=d.replace(/\{\{[^}]*\}\}/g,"").trim();$?s[a]=$:a==="title"?s[a]=m:delete s[a]}return s}export{x as fileEntryUrl,E as generateHeadArrayTags,U as generateMetaTags,_ as getPageMetadata,b as hashContent,T as resolveFileReferences};
1
+ import{isObject as b}from"./types.js";import{isStringFunction as M}from"./function.js";const p=e=>{if(e==null)return"";const r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#039;"};return e.toString().replace(/[&<>"']/g,t=>r[t])},L=e=>Object.entries(e||{}).filter(([r,t])=>t!==void 0).map(([r,t])=>`${r}="${p(t)}"`).join(" "),j=e=>{let r=5381;const t=String(e);for(let s=0;s<t.length;s++)r=(r*33^t.charCodeAt(s))>>>0;return r.toString(36)},E=new Set(["jsonLd","styles","scripts"]),W=e=>{const r=[];if(Array.isArray(e.jsonLd))for(const t of e.jsonLd){if(t==null)continue;const s=typeof t=="string"?t:JSON.stringify(t),i=String(s).replace(/<\/script/gi,"<\\/script");r.push(`<script type="application/ld+json" data-smbls-jsonld="${j(s)}">${i}<\/script>`)}if(Array.isArray(e.styles))for(const t of e.styles){if(t==null||!String(t).trim())continue;const s=String(t).replace(/<\/style/gi,"<\\/style");r.push(`<style data-smbls-style="${j(s)}">${s}</style>`)}if(Array.isArray(e.scripts))for(const t of e.scripts){if(!t)continue;const s=typeof t=="string",i=s?t:t.src;if(!i&&!t.body)continue;const o=[];i&&o.push(`src="${p(i)}"`),s||(t.type&&o.push(`type="${p(t.type)}"`),t.async&&o.push("async"),t.defer&&o.push("defer"),t.integrity&&o.push(`integrity="${p(t.integrity)}"`),t.crossorigin&&o.push(`crossorigin="${p(t.crossorigin)}"`),t.referrerpolicy&&o.push(`referrerpolicy="${p(t.referrerpolicy)}"`),t.nomodule&&o.push("nomodule"));const l=` data-smbls-script="${p(i||j(t.body||""))}"`;if(!s&&t.body){const d=String(t.body).replace(/<\/script/gi,"<\\/script");r.push(`<script ${o.join(" ")}${l}>${d}<\/script>`)}else r.push(`<script ${o.join(" ")}${l}><\/script>`)}return r},x=(e,r,t)=>e==="favicons"?Array.isArray(r)?typeof t=="string"?` data-smbls-favicon="${p(t)}"`:b(t)?` data-smbls-favicon="${j(JSON.stringify(t))}"`:"":"":(e==="icon"||e==="favicon")&&typeof r=="string"?` data-smbls-single-icon="${p(r)}"`:"",T=e=>b(e)?` data-smbls-alternate="${p(`${e.hreflang||""}|${e.href||""}`)}"`:"",q=(e,r)=>{r||(e={...e,robots:"noindex"});const t=Object.entries(e).reduce((s,[i,o])=>{if(!o&&o!==0&&o!==!1||E.has(i))return s;if(i==="title")return s.push(`<title>${p(o)}</title>`),s;if(i==="canonical")return s.push(`<link rel="canonical" href="${p(o)}">`),s;if(i==="manifest")return s.push(`<link rel="manifest" href="${p(o)}">`),s;if(i==="favicon"||i==="favicons"||i==="icon"||i==="icons")return(Array.isArray(o)?o:[o]).forEach(c=>{const u=x(i,o,c);if(typeof c=="string")s.push(`<link rel="icon" href="${p(c)}"${u}>`);else if(typeof c=="object"){const n=L(c);/rel=/.test(n)?s.push(`<link ${n}${u}>`):s.push(`<link rel="icon" ${n}${u}>`)}}),s;if(i==="alternate")return(Array.isArray(o)?o:[o]).forEach(c=>{if(c&&typeof c=="object"){const u=Object.entries(c).filter(([n,g])=>g!==void 0).map(([n,g])=>`${n}="${p(g)}"`).join(" ");s.push(`<link rel="alternate" ${u}${T(c)}>`)}}),s;const l=(f,c,u="name")=>{if(typeof c=="string"||typeof c=="number"||typeof c=="boolean")s.push(`<meta ${u}="${p(f)}" content="${p(c)}">`);else if(Array.isArray(c))c.forEach(n=>{if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")s.push(`<meta ${u}="${p(f)}" content="${p(n)}">`);else if(typeof n=="object"){const g=Object.entries(n).filter(([y,$])=>$!==void 0).map(([y,$])=>`${y}="${p($)}"`).join(" ");s.push(`<meta ${g}>`)}});else if(typeof c=="object"){const n=Object.entries(c).filter(([g,y])=>y!==void 0).map(([g,y])=>`${g}="${p(y)}"`).join(" ");s.push(`<meta ${n}>`)}};if(i.startsWith("http-equiv:")){const f=i.replace("http-equiv:","");return l(f,o,"http-equiv"),s}if(i.startsWith("itemprop:")){const f=i.replace("itemprop:","");return l(f,o,"itemprop"),s}const h=["og:","twitter:","fb:","article:","profile:","book:","business:","music:","product:","video:","DC:","DCTERMS:"].find(f=>i.startsWith(f));if(h){const f=i.replace(h,"");return l(`${h.replace(":","")}:${f}`,o,h==="twitter:"||h==="DC:"||h==="DCTERMS:"?"name":"property"),s}if(i.startsWith("apple:")||i.startsWith("msapplication:")){const f=i.startsWith("apple:")?"apple-":"msapplication-",c=i.replace(/^apple:|^msapplication:/,"");return l(`${f}${c}`,o,"name"),s}return l(i,o),s},['<meta charset="UTF-8">','<meta name="viewport" content="width=device-width, initial-scale=1">']);return t.push(...W(e)),t.join(`
2
+ `)},F=e=>typeof e=="string"&&e.length>0&&!e.startsWith("/")&&!e.startsWith("http"),A=e=>typeof e=="string"&&e.length>0,K=e=>{if(!e||typeof e!="object")return null;if(A(e.src))return e.src;const r=e.content;return!r||typeof r!="object"?null:A(r.src)?r.src:A(r.storageUrl)?r.storageUrl:null};function U(e,r){if(!r||typeof r!="object")return e;const t=i=>!F(i)||!Object.prototype.hasOwnProperty.call(r,i)?i:K(r[i])||i,s={...e};for(const[i,o]of Object.entries(s))typeof o=="string"?s[i]=t(o):Array.isArray(o)&&(s[i]=o.map(l=>typeof l=="string"?t(l):l));return s}function S(e,r){if(!e||!r)return;const t=r.split(".");let s=e;for(const i of t){if(s==null||typeof s!="object")return;s=s[i]}return s}function D(e,r){const t=S(e,r);if(typeof t=="number")return Number.isFinite(t)?t:void 0;if(typeof t=="string"&&!M(t))return t}function P(e,r,t){const i=(r.config||r.settings||{}).polyglot||r.polyglot,o=t?.lang||i?.defaultLang||"en",d=(i?.translations||{})[o]||{},h=[t?.state,r.state].filter(u=>u&&typeof u=="object"),f=u=>{for(const n of h){const g=D(n,u);if(g!==void 0)return g}},c={...e};for(const[u,n]of Object.entries(c))typeof n!="string"||!n.includes("{{")||(c[u]=n.replace(/\{\{\s*([^|{}]+?)\s*(?:\|\s*(\w+)\s*)?\}\}/g,(g,y,$)=>{const a=y.trim();if($==="polyglot")return d[a]??S(d,a)??g;if($==="getLocalStateLang")return f(a+o)??g;const m=f(a);return m!==void 0?m:d[a]??S(d,a)??g}));return c}function O(e){if(!b(e))return{};const r={...e};for(const[t,s]of Object.entries(r))if(typeof s=="function"){const i=s.toString(),o=i.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){r[t]=`{{ ${o[1]} | getLocalStateLang }}`;continue}const l=i.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(l){r[t]=`{{ ${l[1]} | polyglot }}`;continue}const d=i.match(/s\.(\w+(?:\.\w+)+)/);if(d){r[t]=`{{ ${d[1]} }}`;continue}delete r[t]}else if(typeof s=="string"){const i=s.match(/el\.call\(\s*["']getLocalStateLang["']\s*,\s*["']([^"']+)["']\s*\)/);if(i){r[t]=`{{ ${i[1]} | getLocalStateLang }}`;continue}const o=s.match(/el\.call\(\s*["']polyglot["']\s*,\s*["']([^"']+)["']\s*\)/);if(o){r[t]=`{{ ${o[1]} | polyglot }}`;continue}if(s.includes("=>")&&s.includes("s.")){const l=s.match(/s\.(\w+(?:\.\w+)+)/);if(l){r[t]=`{{ ${l[1]} }}`;continue}}M(s)&&delete r[t]}return r}function C(e,r,t,{isProduction:s=!1,channel:i="production"}={}){const o=e.pages?.[r],l=b(o?.state)&&o?.state,d=o?.metadata||o?.helmet||l||{},h=O(d),f=new Set(Object.keys(h)),c=e.app?.metadata||{},u=O(c);let n={};if(e.integrations?.seo?n={...e.integrations.seo,...u,...h}:Object.keys(u).length?n={...u,...h}:n={...h},!n.title){const a=e.name||e.key;a?s?n.title=a:i==="development"?n.title=`${a} / dev:symbo.ls`:i==="staging"?n.title=`${a} / staging:symbo.ls`:n.title=`${a} / symbo.ls`:n.title="Symbols demo"}n=P(n,e,t),n.title&&(f.has("title")||!n["og:title"])&&(f.has("og:title")||(n["og:title"]=n.title)),n.description&&(f.has("description")||!n["og:description"])&&(f.has("og:description")||(n["og:description"]=n.description)),n.title&&!n["twitter:title"]&&(n["twitter:title"]=n.title),n.description&&!n["twitter:description"]&&(n["twitter:description"]=n.description);const g=f.has("og:url")?n["og:url"]:f.has("url")?n.url:void 0,y=t?.actualPathname||r;if(g)n["og:url"]=g;else if(n["og:url"]||n.url){const a=(n["og:url"]||n.url||"").replace(/\/$/,"");if(a&&y&&y!=="/"){const m=y.startsWith("/")?y:"/"+y;n["og:url"]=a+m}}n=U(n,e.files);const $=e.name||e.app?.metadata?.title||e.app?.name||"";for(const[a,m]of Object.entries(n))if(typeof m=="string"&&m.includes("{{")){const w=m.replace(/\{\{[^}]*\}\}/g,"").trim();w?n[a]=w:a==="title"?n[a]=$:delete n[a]}return n}export{K as fileEntryUrl,W as generateHeadArrayTags,q as generateMetaTags,C as getPageMetadata,j as hashContent,U as resolveFileReferences};
@@ -1 +1,4 @@
1
- import{isObject as c,isString as f}from"./types.js";import{isProtectedElementMethod as m}from"./keys.js";import{isLoudDevRuntime as U}from"./env.js";const d="system",F="https://smbls-kv.nika-980.workers.dev",M="https://api.symbols.app";function u(n){const e=String(n||"").trim();if(!e)return{owner:d,key:"",full:""};let s=null,t=e;if(e.includes("/")){const i=e.indexOf("/");s=e.slice(0,i),t=e.slice(i+1)}t=t.replace(/\.symbo\.ls$/iu,""),s||(s=d);const o=t?`${s}/${t}`:"";return{owner:s,key:t,full:o}}const h=(n,e,s,t)=>{for(const o in e){const i=t?`${t}/${o}`:o;s&&s.has(i)||(o in n?c(n[o])&&c(e[o])&&h(n[o],e[o],s,i):n[o]=e[o])}},w=(n,e,s)=>{if(!c(n)||!e.size)return n;const t=`${s}/`;let o=!1;for(const r of e)if(r.startsWith(t)){o=!0;break}if(!o)return n;const i={};for(const r in n){if(!Object.prototype.hasOwnProperty.call(n,r))continue;const a=`${s}/${r}`;e.has(a)||(i[r]=w(n[r],e,a))}return i},C=new Set,D=new Set(["components","pages","functions","snippets","methods"]),b=(n,e)=>e===""&&D.has(n),g=["fontFamily","fontfamily","font_family","FONT_FAMILY"],L=n=>{const e=new Map;if(!c(n))return e;for(const s of g){const t=n[s];if(c(t))for(const o in t)!c(t[o])||!t[o].isDefault||(e.has(s)||e.set(s,new Set),e.get(s).add(o))}return e},$=(n,e)=>{for(const s of g){const t=n[s];if(!c(t))continue;const o=e.get(s);let i=null;for(const r in t){const a=t[r];if(!c(a)||!a.isDefault||o&&o.has(r))continue;const l={...a};delete l.isDefault,i||(i={...t}),i[r]=l}i&&(n[s]=i)}},T=n=>n.replace(/\.js$/iu,""),S=n=>{const e=new Set;if(!Array.isArray(n))return e;for(const s of n){if(!f(s))continue;const t=s.split("/").map(o=>T(o.trim())).filter(Boolean).join("/");t&&e.add(t)}return e},x=(n,e={})=>({library:n,ignoreList:Array.isArray(e.ignoreList)?e.ignoreList:[]}),A=n=>c(n)&&Array.isArray(n.ignoreList)&&("library"in n||"key"in n||"name"in n),I=n=>n.library!==void 0?n.library:n.key??n.name,p=new Set,nn=()=>{p.clear()},z=(n,e)=>{const s=e.filter(t=>!p.has(t));if(s.length){for(const t of s)p.add(t);U()&&console.warn(`[smbls] shared library "${n}" ships ${s.map(t=>`methods.${t}`).join(", ")} \u2014 named like a built-in element method. Refused: the built-in wins; a library cannot replace an element method on the consuming app. If the app wants this version, declare it in the app's OWN methods.`)}},N=(n,e,s)=>{let t=null;for(const o in n)if(m(o)&&(e.has(`methods/${o}`)||s.push(o),!t)){t={};for(const i in n)m(i)||(t[i]=n[i])}return t||n},_=(n,e)=>{const s=S(n.sharedLibIgnore);return n.sharePages===!1&&s.add("pages"),s.size?new Set([...e,...s]):e},G=(n,e,s,t="library")=>{const o=_(e,s),i=[];for(const r in e)if(Object.prototype.hasOwnProperty.call(e,r)&&!(r==="sharePages"||r==="sharedLibIgnore")&&r!=="app"&&!o.has(r)){if(c(e[r])&&c(n[r])){if(r==="designSystem")h(n[r],e[r],o,r);else for(const a in e[r])if(!o.has(`${r}/${a}`)){if(r==="methods"&&m(a)){a in n[r]||i.push(a);continue}a in n[r]?b(r,n[r][a])&&!b(r,e[r][a])&&(n[r][a]=e[r][a]):n[r][a]=e[r][a]}}else if(!(r in n)){const a=e[r],l=r==="methods"&&a&&typeof a=="object"?N(a,o,i):a;n[r]=w(l,o,r)}}i.length&&z(t,i)},K=(n,e,s)=>{if(n!==e){const t=I(n);if(f(t)&&t)return t;if(n.key||n.name)return n.key||n.name}return e&&(e.key||e.name)||`sharedLibraries[${s}]`},W=`${d}/default`,Y=n=>f(n)&&n!==""&&u(n).full===W,J=(n,e)=>{if(f(e.key)&&e.key)return e.key;if(n!==e){if(f(n.key)&&n.key)return n.key;if(f(n.name)&&n.name)return n.name}return null},V=n=>{const e=[],s=[];for(let t=0;t<n.length;t++){const o=n[t];let i=o,r=C;if(A(i)&&(r=S(i.ignoreList),i=i.library),!c(i))continue;const a={entry:o,lib:i,ignore:r,index:t};Y(J(o,i))?s.push(a):e.push(a)}return{linked:e,bases:s}},R=(n,e,s)=>{const t=L(e()),{linked:o,bases:i}=V(n);for(const a of o)s(a);const r=!t.size&&i.length?L(e()):null;for(const a of i)s(a);return t.size?t:r&&r.size?r:null},en=(n,e)=>{if(!e||!e.length)return;const s=n.designSystem,t=R(e,()=>n.designSystem,({entry:o,lib:i,ignore:r,index:a})=>G(n,i,r,K(o,i,a)));t&&(n.designSystem!==s&&(n.designSystem={...n.designSystem}),$(n.designSystem,t))},tn=(n,e,s=h)=>{if(!c(n)||!Array.isArray(e)||!e.length)return n;const t=R(e,()=>n,({lib:o,ignore:i})=>{const r=o.designSystem;if(!r||typeof r!="object")return;const a=_(o,i);a.has("designSystem")||s(n,r,a,"designSystem")});return t&&$(n,t),n};async function q(n,e={}){if((e.provider||"kv")==="api")return j(n,e);const t=await H(n,e);return t||j(n,e)}async function H(n,e={}){const s=e.kvBaseUrl||F,t=e.env||"production",o=`${s}/kv/${encodeURIComponent(n)}?env=${t}`;try{const i=await fetch(o,{method:"GET"});return i.ok&&(await i.json())?.value||null}catch{return null}}async function j(n,e={}){const s=e.apiBaseUrl||M,{key:t}=u(n);try{const o=`${s}/core/projects/libraries/available?search=${encodeURIComponent(t)}&limit=10`,i=await fetch(o,{method:"GET"});if(!i.ok)return null;const r=await i.json(),l=(r?.items||r?.data||(Array.isArray(r)?r:[])).find(E=>{const{key:P}=u(E?.key);return P.toLowerCase()===t.toLowerCase()});if(!l?.id&&!l?._id)return null;const B=l.id||l._id,O=`${s}/core/projects/${encodeURIComponent(B)}/data?branch=main`,y=await fetch(O,{method:"GET"});if(!y.ok)return null;const k=await y.json();return k?.data||k||null}catch{return null}}async function v(n,e={}){if(c(n))return n;if(f(n)){const{full:s}=u(n);if(!s)return null;try{const t=await q(s,e);return t||console.warn(`[smbls] Shared library "${s}" not found`),t}catch(t){return console.warn(`[smbls] Failed to fetch shared library "${s}":`,t.message),null}}return null}async function sn(n,e={}){return!n||!n.length?[]:(await Promise.all(n.map(async t=>{if(A(t)){const o=await v(I(t),e);return o?{library:o,ignoreList:t.ignoreList}:null}return v(t,e)}))).filter(Boolean)}export{nn as __resetBuiltinMethodWarnings,h as deepDefaults,q as fetchLibraryData,A as isWrappedLibrary,en as mergeSharedLibraries,tn as mergeSharedLibraryDesignSystems,S as normalizeIgnoreList,u as normalizeLibraryKey,sn as resolveSharedLibraries,x as sharedLibrary};
1
+ import{isObject as p,isString as y}from"./types.js";import{isProtectedElementMethod as L}from"./keys.js";import{isLoudDevRuntime as ie}from"./env.js";import{destringifyGlobalScope as ce,hasFunction as A,getFunctionSource as ae,deepDestringifyFunctions as le,isStringTag as fe}from"./object.js";const $="system",ue="https://smbls-kv.nika-980.workers.dev",pe="https://api.symbols.app";function S(e){const n=String(e||"").trim();if(!n)return{owner:$,key:"",full:""};let o=null,t=n;if(n.includes("/")){const i=n.indexOf("/");o=n.slice(0,i),t=n.slice(i+1)}t=t.replace(/\.symbo\.ls$/iu,""),o||(o=$);const r=t?`${o}/${t}`:"";return{owner:o,key:t,full:r}}const R=(e,n,o,t)=>{for(const r in n){const i=t?`${t}/${r}`:r;o&&o.has(i)||(r in e?p(e[r])&&p(n[r])&&R(e[r],n[r],o,i):e[r]=n[r])}},M=(e,n,o)=>{if(!p(e)||!n.size)return e;const t=`${o}/`;let r=!1;for(const c of n)if(c.startsWith(t)){r=!0;break}if(!r)return e;const i={};for(const c in e){if(!Object.prototype.hasOwnProperty.call(e,c))continue;const s=`${o}/${c}`;n.has(s)||(i[c]=M(e[c],n,s))}return i},ye=new Set,be=new Set(["components","pages","functions","snippets","methods"]),N=(e,n)=>n===""&&be.has(e),F=["fontFamily","fontfamily","font_family","FONT_FAMILY"],V=e=>{const n=new Map;if(!p(e))return n;for(const o of F){const t=e[o];if(p(t))for(const r in t)!p(t[r])||!t[r].isDefault||(n.has(o)||n.set(o,new Set),n.get(o).add(r))}return n},D=(e,n)=>{for(const o of F){const t=e[o];if(!p(t))continue;const r=n.get(o);let i=null;for(const c in t){const s=t[c];if(!p(s)||!s.isDefault||r&&r.has(c))continue;const l={...s};delete l.isDefault,i||(i={...t}),i[c]=l}i&&(e[o]=i)}},de=e=>e.replace(/\.js$/iu,""),G=e=>{const n=new Set;if(!Array.isArray(e))return n;for(const o of e){if(!y(o))continue;const t=o.split("/").map(r=>de(r.trim())).filter(Boolean).join("/");t&&n.add(t)}return n},Xe=(e,n={})=>({library:e,ignoreList:Array.isArray(n.ignoreList)?n.ignoreList:[]}),_=e=>p(e)&&Array.isArray(e.ignoreList)&&("library"in e||"key"in e||"name"in e),U=e=>e.library!==void 0?e.library:e.key??e.name,j=new Set,ve=()=>{j.clear()},he=(e,n)=>{const o=n.filter(t=>!j.has(t));if(o.length){for(const t of o)j.add(t);ie()&&console.warn(`[smbls] shared library "${e}" ships ${o.map(t=>`methods.${t}`).join(", ")} \u2014 named like a built-in element method. Refused: the built-in wins; a library cannot replace an element method on the consuming app. If the app wants this version, declare it in the app's OWN methods.`)}},me=(e,n,o)=>{let t=null;for(const r in e)if(L(r)&&(n.has(`methods/${r}`)||o.push(r),!t)){t={};for(const i in e)L(i)||(t[i]=e[i])}return t||e},Y=(e,n)=>{const o=G(e.sharedLibIgnore);return e.sharePages===!1&&o.add("pages"),o.size?new Set([...n,...o]):n},E=["functions","methods","snippets"],W=["components","pages"],K=Symbol.for("smbls.libraryScope"),k="__libraryScopes",I=new Map,ge=()=>Math.random().toString(36).slice(2,10)+Date.now().toString(36).slice(-4),h=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),Se=/const __scope = |const __peers_* = |const _s = el\?\.scope|\?\.context\?\.globalScope\?\./,z=e=>{try{return ae(e)}catch{return null}},J=e=>{if(typeof e!="function")return null;const n=z(e);return y(n)&&Se.test(n)&&A(n)?n:null},H=e=>y(e)&&A(e)||J(e)!==null,_e=e=>{const n=e.globalScope;return p(n)&&Object.keys(n).some(o=>H(n[o]))?!0:E.some(o=>{const t=e[o];return!!t&&typeof t=="object"&&Object.keys(t).some(r=>H(t[r]))})},ke=(e,n,o)=>{const t=e.globalScope,r=n.globalScope;if(o.has("globalScope")||!p(t)||!p(r)||!_e(n))return 0;let i=0;for(const c of Object.keys(r))o.has(`globalScope/${c}`)||h(t,c)&&i++;return i},we=[[/const __scope = (\(\(\) => \{ const r = [\s\S]*?\}\)\(\));/g,"const __scope = $RESOLVE($1);"],[/const __scope = this \?\? \{\};/g,"const __scope = $RESOLVE(this ?? {});"],[/const (__peers_*) = (this && this !== globalThis && this\.context && this\.context\.globalScope \? this\.scope \?\? this\.context\.globalScope : this);/g,"const $1 = $RESOLVE($2);"],[/const _s = (el\?\.scope \?\? el\?\.context\?\.globalScope \?\? \{\});/g,"const _s = $RESOLVE($1);"],[/(?<![\w$.])(this|[A-Za-z_$][\w$]*)\?\.context\?\.globalScope\?\./g,"$RESOLVE($1?.context?.globalScope)?."]],Oe=e=>{const n=e.split(""),o=[];let t=0,r=0;const i=(s,l)=>{for(let u=s;u<l;u++)n[u]!==`
2
+ `&&(n[u]="~")},c=()=>{const s=t;for(;t<e.length;){const l=e[t];if(l==="\\"){t+=2;continue}if(l==="`"){i(s,t),t++;return}if(l==="$"&&e[t+1]==="{"){i(s,t),t+=2,o.push(r),r++;return}t++}i(s,t)};for(;t<e.length;){const s=e[t];if(s==="/"&&e[t+1]==="/"){const l=e.indexOf(`
3
+ `,t),u=l===-1?e.length:l;i(t,u),t=u;continue}if(s==="/"&&e[t+1]==="*"){const l=e.indexOf("*/",t+2),u=l===-1?e.length:l+2;i(t,u),t=u;continue}if(s==='"'||s==="'"){const l=s,u=++t;for(;t<e.length&&e[t]!==l&&e[t]!==`
4
+ `;)e[t]==="\\"&&t++,t++;i(u,t),t++;continue}if(s==="`"){t++,c();continue}if(s==="{"){r++,t++;continue}if(s==="}"){if(r--,o.length&&r===o[o.length-1]){o.pop(),t++,c();continue}t++;continue}t++}return n.join("")},q=(e,n)=>{if(!y(e)||!e.includes("__scope = ")&&!e.includes("__peers")&&!e.includes("const _s = ")&&!e.includes("?.context?.globalScope?.")||!A(e))return e;const o=`(globalThis[Symbol.for('smbls.libraryScope')] || ((_, v) => v))(${JSON.stringify(n)}, `;let t=e;for(const[r,i]of we){const c=Oe(t);t=t.replace(r,(...s)=>{const l=s[s.length-2];return c[l]==="~"||c[l]!==t[l]?s[0]:i.replace(/\$RESOLVE\(/g,o).replace(/\$(\d)/g,(u,a)=>s[Number(a)])})}return t},w=(e,n)=>{if(y(e))return q(e,n);const o=J(e);return o===null?e:q(o,n)},Le={lazy:!0,window:globalThis},Z=(e,n)=>{const o=w(e,n);if(o===e||!y(o))return o;try{const t=le({v:o},{},Le).v;return typeof t!="function"?o:(Object.defineProperty(t,"toJSON",{value:()=>o,configurable:!0}),t)}catch{return o}},P=e=>{if(!e||typeof e!="object")return!1;if(Array.isArray(e))return!0;const n=Object.getPrototypeOf(e);return n===Object.prototype||n===null},Q=(e,n,o=new WeakMap)=>{if(y(e)||typeof e=="function")return Z(e,n);if(fe(e)||!P(e))return e;if(o.has(e))return o.get(e);const t=Array.isArray(e)?[]:Object.getPrototypeOf(e)===null?Object.create(null):{};o.set(e,t);for(const r of Object.keys(e))t[r]=Q(e[r],n,o);return t},Ae=(e,n)=>{const o={...e},t={};for(const r of Object.keys(e.globalScope))t[r]=w(e.globalScope[r],n);o.globalScope=t;for(const r of E){const i=e[r];if(!P(i))continue;const c={};for(const s of Object.keys(i))c[s]=Z(i[s],n);o[r]=c}for(const r of W)P(e[r])&&(o[r]=Q(e[r],n));return o},X=new WeakMap,$e=(e,n,o)=>{let t=X.get(e);t||X.set(e,t=new Map);let r=t.get(n);if(r)return r;const i=(c,s)=>h(o,c)&&o[c]===s;return r=new Proxy(e,{get(c,s){if(typeof s=="symbol"||h(c,s))return Reflect.get(c,s);const l=Reflect.get(c,s);return h(n,s)&&(l===void 0||i(s,l))||l===void 0?n[s]:l},set(c,s,l){return typeof s!="symbol"&&!h(c,s)&&h(n,s)?(n[s]=l,!0):Reflect.set(c,s,l)},has:(c,s)=>Reflect.has(c,s)||s in n}),t.set(n,r),r},Re=e=>!!e&&typeof e=="object"&&!!e.__raw&&typeof e.__raw=="object",je=(e,n)=>{const o=I.get(e);return o?n===o.consumerGs?o.libGs:Re(n)?$e(n,o.libGs,o.consumerGs):n:n},Ee=()=>{typeof globalThis[K]!="function"&&Object.defineProperty(globalThis,K,{value:je,configurable:!0})},O=e=>{const n=e[k];return Array.isArray(n)?n:null},T=e=>_(e)?e.library:e,Ie=(e,n,o)=>{const t=O(e);return!!t&&t.some(r=>r&&r.index===n&&(!r.key||r.key===o.key)&&y(r.id)&&Pe(e,r.id))},Pe=(e,n)=>{const o=JSON.stringify(n),t=new Set,r=i=>{if(y(i))return i.includes(o);if(!i||typeof i!="object"||t.has(i))return!1;t.add(i);for(const c in i)if(r(i[c]))return!0;return!1};for(const i of["globalScope",...E,...W])if(r(e[i]))return!0;return!1},Te=(e,n)=>{const o={};for(const t of Object.keys(e))o[t]=w(e[t],n);return o},v=new WeakMap,xe=(e,n=null)=>{const o=e&&O(e);if(!o||!o.length)return 0;const t=e.globalScope;if(!p(t))return 0;const r=Array.isArray(e.sharedLibraries)?e.sharedLibraries:[];let i=v.get(t);i||v.set(t,i=new Set),Ee();let c=0;for(const s of o){if(!s||!y(s.id)||i.has(s.id))continue;const l=T(r[s.index]);if(!l||!p(l.globalScope)||s.key&&l.key!==s.key)continue;const u=b=>typeof b=="function"?z(b):b,a=(b,m)=>{if(b===m)return!0;const B=u(b),C=u(m);return y(B)||y(C)?B===C:JSON.stringify(b)===JSON.stringify(m)},f=p(n)?(Array.isArray(s.landed)?s.landed:[]).filter(b=>y(b)&&h(l.globalScope,b)&&h(n,b)&&a(n[b],w(l.globalScope[b],s.id))):[],d=ce(Te(l.globalScope,s.id));Object.setPrototypeOf(d,t),I.set(s.id,{libGs:d,consumerGs:t});for(const b of f)t[b]=d[b];i.add(s.id),c++}return c},Be=/^@symbo[-.]ls\//,x=e=>e.includes("/")?e.slice(e.indexOf("/")+1):e,Ce=(e,n)=>{const o=[];if(!Array.isArray(e))return o;const t=new Map,r=(c,s,l)=>{for(const u of[`@symbo-ls/${c}`,`@symbo.ls/${c}`]){const a=t.get(u);if(a===void 0){t.set(u,s),o.push([u,s]);continue}a!==s&&l&&typeof n=="function"&&n({spec:u,kept:a,refused:s})}},i=[];for(const c of e){const s=T(c);if(!s||typeof s!="object"||s.__isStub)continue;const l=s.key||s.name||s.__libraryKey,u=[];for(const a of[s.key,s.name,s.__libraryKey,s.__libraryName]){if(typeof a!="string"||!a||a!==l&&!Be.test(a))continue;const f=x(a);f&&!u.includes(f)&&u.push(f)}u.forEach((a,f)=>{f===0&&l&&x(l)===a?r(a,s,!1):i.push([a,s])})}for(const[c,s]of i)r(c,s,!0);return o},Me=({spec:e,kept:n,refused:o})=>{typeof console>"u"||console.warn(`[smbls] shared library "${o&&o.key}" also claims ${e}, which "${n&&n.key}" already owns; ${e} stays with "${n&&n.key}".`)},ee=["functions","methods","snippets"],Ne=Symbol.for("smbls.libraryPackages"),g=new WeakMap,Fe=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Ve=e=>({get globalScope(){return e()}}),te=(e,n,o)=>{const t={};for(const r of Object.keys(e))t[r]=e[r];return Object.defineProperty(t,"context",{configurable:!0,enumerable:!1,writable:!0,value:Ve(n)}),g.set(t,o),t},ne=e=>!Fe(e)||!g.has(e)&&Object.prototype.hasOwnProperty.call(e,"context"),et=e=>{if(!e||typeof e!="object")return;const n=()=>e.globalScope;for(const t of ee){const r=e[t];ne(r)||g.get(r)===e||(e[t]=te(r,n,e))}if(Array.isArray(e.sharedLibraries)){const t=O(e)||[];e.sharedLibraries=e.sharedLibraries.map((r,i)=>{const c=_(r)&&r&&"library"in r,s=T(r);if(!s||typeof s!="object"||s.__isStub||g.get(s)===e)return r;const l=t.find(f=>f&&f.index===i&&(!f.key||f.key===s.key)),u=()=>{const f=l&&I.get(l.id);return f&&f.consumerGs===e.globalScope?f.libGs:e.globalScope},a={...s};for(const f of ee)ne(s[f])||(a[f]=te(s[f],u,e));return g.set(a,e),c?{...r,library:a}:a})}const o=e.globalScope;if(o&&typeof o=="object"){const t={};for(const[r,i]of Ce(e.sharedLibraries,Me))t[r]=i;try{Object.defineProperty(o,Ne,{configurable:!0,enumerable:!1,writable:!0,value:t})}catch{}}},De=(e,n,o,t="library",r=-1)=>{const i=Y(n,o),c=!Ie(e,r,n)&&ke(e,n,i)>0?`${t}#${ge()}`:null,s=c?Ae(n,c):n,l=c?new Set(Object.keys(e.globalScope)):null,u=[];for(const a in s)if(Object.prototype.hasOwnProperty.call(s,a)&&!(a==="sharePages"||a==="sharedLibIgnore")&&a!==k&&!a.startsWith("__")&&a!=="app"&&!i.has(a)){if(p(s[a])&&p(e[a])){if(a==="designSystem")R(e[a],s[a],i,a);else for(const f in s[a])if(!i.has(`${a}/${f}`)){if(a==="methods"&&L(f)){f in e[a]||u.push(f);continue}f in e[a]?N(a,e[a][f])&&!N(a,s[a][f])&&(e[a][f]=s[a][f]):e[a][f]=s[a][f]}}else if(!(a in e)){const f=s[a],d=a==="methods"&&f&&typeof f=="object"?me(f,i,u):f;e[a]=M(d,i,a)}}c&&(O(e)||(e[k]=[]),e[k].push({id:c,index:r,key:y(n.key)?n.key:null,landed:Object.keys(s.globalScope).filter(a=>!l.has(a))})),u.length&&he(t,u)},Ge=(e,n,o)=>{if(e!==n){const t=U(e);if(y(t)&&t)return t;if(e.key||e.name)return e.key||e.name}return n&&(n.key||n.name)||`sharedLibraries[${o}]`},Ue=`${$}/default`,Ye=e=>y(e)&&e!==""&&S(e).full===Ue,We=(e,n)=>{if(y(n.key)&&n.key)return n.key;if(e!==n){if(y(e.key)&&e.key)return e.key;if(y(e.name)&&e.name)return e.name}return null},Ke=e=>{const n=[],o=[];for(let t=0;t<e.length;t++){const r=e[t];let i=r,c=ye;if(_(i)&&(c=G(i.ignoreList),i=i.library),!p(i))continue;const s={entry:r,lib:i,ignore:c,index:t};Ye(We(r,i))?o.push(s):n.push(s)}return{linked:n,bases:o}},oe=(e,n,o)=>{const t=V(n()),{linked:r,bases:i}=Ke(e);for(const s of r)o(s);const c=!t.size&&i.length?V(n()):null;for(const s of i)o(s);return t.size?t:c&&c.size?c:null},tt=(e,n)=>{if(!n||!n.length)return;const o=e.designSystem,t=oe(n,()=>e.designSystem,({entry:r,lib:i,ignore:c,index:s})=>De(e,i,c,Ge(r,i,s),s));t&&(e.designSystem!==o&&(e.designSystem={...e.designSystem}),D(e.designSystem,t))},nt=(e,n,o=R)=>{if(!p(e)||!Array.isArray(n)||!n.length)return e;const t=oe(n,()=>e,({lib:r,ignore:i})=>{const c=r.designSystem;if(!c||typeof c!="object")return;const s=Y(r,i);s.has("designSystem")||o(e,c,s,"designSystem")});return t&&D(e,t),e};async function ze(e,n={}){if((n.provider||"kv")==="api")return se(e,n);const t=await Je(e,n);return t||se(e,n)}async function Je(e,n={}){const o=n.kvBaseUrl||ue,t=n.env||"production",r=`${o}/kv/${encodeURIComponent(e)}?env=${t}`;try{const i=await fetch(r,{method:"GET"});return i.ok&&(await i.json())?.value||null}catch{return null}}async function se(e,n={}){const o=n.apiBaseUrl||pe,{key:t}=S(e);try{const r=`${o}/core/projects/libraries/available?search=${encodeURIComponent(t)}&limit=10`,i=await fetch(r,{method:"GET"});if(!i.ok)return null;const c=await i.json(),l=(c?.items||c?.data||(Array.isArray(c)?c:[])).find(b=>{const{key:m}=S(b?.key);return m.toLowerCase()===t.toLowerCase()});if(!l?.id&&!l?._id)return null;const u=l.id||l._id,a=`${o}/core/projects/${encodeURIComponent(u)}/data?branch=main`,f=await fetch(a,{method:"GET"});if(!f.ok)return null;const d=await f.json();return d?.data||d||null}catch{return null}}async function re(e,n={}){if(p(e))return e;if(y(e)){const{full:o}=S(e);if(!o)return null;try{const t=await ze(o,n);return t||console.warn(`[smbls] Shared library "${o}" not found`),t}catch(t){return console.warn(`[smbls] Failed to fetch shared library "${o}":`,t.message),null}}return null}async function ot(e,n={}){return!e||!e.length?[]:(await Promise.all(e.map(async t=>{if(_(t)){const r=await re(U(t),n);return r?{library:r,ignoreList:t.ignoreList}:null}return re(t,n)}))).filter(Boolean)}export{Ne as LIBRARY_PACKAGES,k as LIBRARY_SCOPES_KEY,ve as __resetBuiltinMethodWarnings,xe as bindLibraryGlobalScopes,R as deepDefaults,et as exposeBagGlobalScopes,ze as fetchLibraryData,_ as isWrappedLibrary,Ce as libraryPackageSpecs,tt as mergeSharedLibraries,nt as mergeSharedLibraryDesignSystems,G as normalizeIgnoreList,S as normalizeLibraryKey,ot as resolveSharedLibraries,Xe as sharedLibrary,Me as warnLibraryAliasCollision};
package/metadata.js CHANGED
@@ -115,6 +115,33 @@ export const generateHeadArrayTags = (metadata) => {
115
115
  return tags
116
116
  }
117
117
 
118
+ /**
119
+ * The `data-smbls-*` key the client runtime reconciles a link tag by —
120
+ * `@symbo.ls/helmet` renderIcon (`icon` / `favicon`: one href string),
121
+ * renderFavicons (each `favicons` entry: a string's own value, a plain object's
122
+ * content hash) and renderAlternate (each `alternate` entry: `hreflang|href`).
123
+ * Unkeyed, a hydrating client could not take a served tag over: it added a
124
+ * keyed copy of every icon and hreflang link, and a page's served alternates
125
+ * stayed on every page after it. helmet's SSR builder (`generateHeadHtml`)
126
+ * emits the same keys. A shape the client never renders (`icons`, an icon
127
+ * array, a lone `favicons` value) stays unkeyed, so the client never owns it.
128
+ */
129
+ const iconKeyAttr = (key, value, item) => {
130
+ if (key === 'favicons') {
131
+ if (!Array.isArray(value)) return ''
132
+ if (typeof item === 'string') return ` data-smbls-favicon="${escapeHtml(item)}"`
133
+ if (isObject(item)) return ` data-smbls-favicon="${hashContent(JSON.stringify(item))}"`
134
+ return ''
135
+ }
136
+ if ((key === 'icon' || key === 'favicon') && typeof value === 'string') {
137
+ return ` data-smbls-single-icon="${escapeHtml(value)}"`
138
+ }
139
+ return ''
140
+ }
141
+
142
+ const alternateKeyAttr = (alt) =>
143
+ isObject(alt) ? ` data-smbls-alternate="${escapeHtml(`${alt.hreflang || ''}|${alt.href || ''}`)}"` : ''
144
+
118
145
  /**
119
146
  * Generates HTML meta tags from a flat metadata object.
120
147
  * Works on both server (SSR head injection) and client (dynamic meta updates).
@@ -152,14 +179,15 @@ export const generateMetaTags = (metadata, isProduction) => {
152
179
  if (key === 'favicon' || key === 'favicons' || key === 'icon' || key === 'icons') {
153
180
  const items = Array.isArray(value) ? value : [value]
154
181
  items.forEach((item) => {
182
+ const keyAttr = iconKeyAttr(key, value, item)
155
183
  if (typeof item === 'string') {
156
- acc.push(`<link rel="icon" href="${escapeHtml(item)}">`)
184
+ acc.push(`<link rel="icon" href="${escapeHtml(item)}"${keyAttr}>`)
157
185
  } else if (typeof item === 'object') {
158
186
  const attrs = buildAttrs(item)
159
187
  if (!/rel=/.test(attrs)) {
160
- acc.push(`<link rel="icon" ${attrs}>`)
188
+ acc.push(`<link rel="icon" ${attrs}${keyAttr}>`)
161
189
  } else {
162
- acc.push(`<link ${attrs}>`)
190
+ acc.push(`<link ${attrs}${keyAttr}>`)
163
191
  }
164
192
  }
165
193
  })
@@ -169,12 +197,13 @@ export const generateMetaTags = (metadata, isProduction) => {
169
197
  if (key === 'alternate') {
170
198
  const alternates = Array.isArray(value) ? value : [value]
171
199
  alternates.forEach((alt) => {
172
- if (typeof alt === 'object') {
200
+ // A null entry threw (Object.entries(null)); the client skips it.
201
+ if (alt && typeof alt === 'object') {
173
202
  const attrs = Object.entries(alt)
174
203
  .filter(([_, attrValue]) => attrValue !== undefined)
175
204
  .map(([attrKey, attrValue]) => `${attrKey}="${escapeHtml(attrValue)}"`)
176
205
  .join(' ')
177
- acc.push(`<link rel="alternate" ${attrs}>`)
206
+ acc.push(`<link rel="alternate" ${attrs}${alternateKeyAttr(alt)}>`)
178
207
  }
179
208
  })
180
209
  return acc
@@ -556,9 +585,18 @@ export function getPageMetadata (data, pathname, ssrContext, { isProduction = fa
556
585
  merged['twitter:description'] = merged.description
557
586
  }
558
587
 
559
- // Make og:url route-aware — use actual pathname if available
588
+ // og:url is route-aware only as a BASE — helmet extractMetadata's rule. An
589
+ // app-level or integrations.seo og:url (or `url`) gets the actual path; a
590
+ // page's own og:url (or `url` alias) names that page already and stays as
591
+ // written. Appending the path to it doubled it: a detail page's
592
+ // `{{ item.url }}` served `…/blog/abc/blog/abc`.
593
+ const pageUrl = pageExplicitKeys.has('og:url')
594
+ ? merged['og:url']
595
+ : (pageExplicitKeys.has('url') ? merged.url : undefined)
560
596
  const routeForUrl = ssrContext?.actualPathname || pathname
561
- if (merged['og:url'] || merged.url) {
597
+ if (pageUrl) {
598
+ merged['og:url'] = pageUrl
599
+ } else if (merged['og:url'] || merged.url) {
562
600
  const baseUrl = (merged['og:url'] || merged.url || '').replace(/\/$/, '')
563
601
  if (baseUrl && routeForUrl && routeForUrl !== '/') {
564
602
  const cleanRoute = routeForUrl.startsWith('/') ? routeForUrl : '/' + routeForUrl
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/utils",
3
- "version": "3.14.782",
3
+ "version": "3.14.784",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
6
  "module": "./dist/esm/index.js",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
49
49
  "peerDependencies": {
50
- "@symbo.ls/fetch": "^3.14.656"
50
+ "@symbo.ls/fetch": "^3.14.662"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "@symbo.ls/fetch": {
@@ -3,6 +3,7 @@
3
3
  import { isObject, isString } from './types.js'
4
4
  import { isProtectedElementMethod } from './keys.js'
5
5
  import { isLoudDevRuntime } from './env.js'
6
+ import { destringifyGlobalScope, hasFunction, getFunctionSource, deepDestringifyFunctions, isStringTag } from './object.js'
6
7
 
7
8
  const DEFAULT_LIBRARY_OWNER = 'system'
8
9
 
@@ -354,13 +355,556 @@ const librarySkip = (sharedLib, ignore) => {
354
355
  : ignore
355
356
  }
356
357
 
357
- const mergeOneLibrary = (context, sharedLib, ignore, label = 'library') => {
358
- const skip = librarySkip(sharedLib, ignore)
358
+ // ── one globalScope per library ───────────────────────────────────────────
359
+ //
360
+ // frank emits each project's free variables into ONE flat globalScope: every
361
+ // library carries its own mutable-let holder `Smut`, and a minified helper
362
+ // (symbolize-core's `s2`) lands under the same short name in each library that
363
+ // inlines it, meaning something different in each. The add-missing merge
364
+ // below is first-wins, so such a name in a library resolved to the consumer's
365
+ // (or an earlier library's) — and the library's own code, which finds its
366
+ // peers through `this.scope ?? this.context.globalScope` (the CONSUMER's
367
+ // element), read the consumer's `Smut` and called the consumer's `s2`.
368
+ //
369
+ // A library whose EMITTED globalScope shares ANY name with what the context
370
+ // already holds — even byte-identical text: two `Smut` IIFEs are two
371
+ // containers — keeps its own globalScope. Its emitted code is not wrapped and
372
+ // its `this` is never replaced: the only change is to the statement frank
373
+ // emits to FIND the peers (the four shapes below — scopeRewriter
374
+ // buildScopeDecl and the toJSON peer rewrite). That statement's value passes
375
+ // through the library's scope resolver, which answers the consumer's
376
+ // globalScope (or a scope store chained to it) with the library's own. The
377
+ // element, `this`, and anything handed to consumer code stay the real ones.
378
+ // Libraries without a shared name, names a library does not define, and
379
+ // libraries bundled from source (real values, no emitted text) are merged
380
+ // exactly as before.
381
+ const LIBRARY_FUNCTION_BAGS = ['functions', 'methods', 'snippets']
382
+ const LIBRARY_DEFINITION_BAGS = ['components', 'pages']
383
+ const LIBRARY_SCOPE = Symbol.for('smbls.libraryScope')
384
+ // The merge's record travels WITH the context data (`__libraryScopes`), so a
385
+ // merge done before the browser (smbls start / the runner, brender, any host
386
+ // that pre-merges with this function and serializes the result) is bound by
387
+ // the browser runtime exactly like a merge done in it: [{ id, index, key,
388
+ // landed }] — `index` into `context.sharedLibraries`, whose library payload
389
+ // the browser re-scopes with the same `id` (the payload is not copied).
390
+ export const LIBRARY_SCOPES_KEY = '__libraryScopes'
391
+ const libraryScopes = new Map() // id -> { libGs, consumerGs }
392
+ const scopeToken = () => Math.random().toString(36).slice(2, 10) + Date.now().toString(36).slice(-4)
393
+
394
+ const hasOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k)
395
+
396
+ // A library's EMITTED code — frank's output: a string, or a function revived
397
+ // from one (mermaid SSR deep-destringifies the payload; `smbls fetch` writes a
398
+ // library's payload to files that the runner / brender bundle). Emitted code
399
+ // carries one of frank's peer statements; a library bundled from its own
400
+ // SOURCE never does, keeps its real closures and never reads globalScope for
401
+ // its own names.
402
+ const PEER_STATEMENT_HINT = /const __scope = |const __peers_* = |const _s = el\?\.scope|\?\.context\?\.globalScope\?\./
403
+ // The SOURCE text of a function (a lazily revived one answers its stored
404
+ // source — Function.prototype.toString would read the wrapper).
405
+ const functionText = (v) => {
406
+ try {
407
+ return getFunctionSource(v)
408
+ } catch (_) {
409
+ return null
410
+ }
411
+ }
412
+ // Frank's emission revived to a function: its text holds a peer statement.
413
+ // A function without one (a library bundled from SOURCE, or a helper that
414
+ // needs no peers) keeps its closures and is never converted.
415
+ const emittedFunctionText = (v) => {
416
+ if (typeof v !== 'function') return null
417
+ const text = functionText(v)
418
+ return isString(text) && PEER_STATEMENT_HINT.test(text) && hasFunction(text) ? text : null
419
+ }
420
+ // Emitted CODE: function text as a string, or a function revived from it.
421
+ // A data string (a constant, copy) does not count.
422
+ const isEmittedValue = (v) => (isString(v) && hasFunction(v)) || emittedFunctionText(v) !== null
423
+
424
+ const libraryCarriesEmittedCode = (sharedLib) => {
425
+ const gs = sharedLib.globalScope
426
+ if (isObject(gs) && Object.keys(gs).some((k) => isEmittedValue(gs[k]))) return true
427
+ return LIBRARY_FUNCTION_BAGS.some((bag) => {
428
+ const b = sharedLib[bag]
429
+ return !!b && typeof b === 'object' && Object.keys(b).some((k) => isEmittedValue(b[k]))
430
+ })
431
+ }
432
+
433
+ const sharedGlobalScopeNames = (context, sharedLib, skip) => {
434
+ const own = context.globalScope
435
+ const lib = sharedLib.globalScope
436
+ if (skip.has('globalScope') || !isObject(own) || !isObject(lib)) return 0
437
+ if (!libraryCarriesEmittedCode(sharedLib)) return 0
438
+ let n = 0
439
+ for (const k of Object.keys(lib)) {
440
+ if (skip.has(`globalScope/${k}`)) continue
441
+ if (hasOwn(own, k)) n++
442
+ }
443
+ return n
444
+ }
445
+
446
+ // The peer-finding statements frank emits, exactly. Only their VALUE is
447
+ // routed through the resolver; nothing else in the text changes.
448
+ const PEER_STATEMENTS = [
449
+ // scopeRewriter buildScopeDecl, receiver form (`r = this` / `r = el`)
450
+ [/const __scope = (\(\(\) => \{ const r = [\s\S]*?\}\)\(\));/g, 'const __scope = $RESOLVE($1);'],
451
+ // scopeRewriter buildScopeDecl, globalScope-helper form
452
+ [/const __scope = this \?\? \{\};/g, 'const __scope = $RESOLVE(this ?? {});'],
453
+ // toJSON peer rewrite, receiver-callable form
454
+ [/const (__peers_*) = (this && this !== globalThis && this\.context && this\.context\.globalScope \? this\.scope \?\? this\.context\.globalScope : this);/g, 'const $1 = $RESOLVE($2);'],
455
+ // toJSON peer rewrite, `el`-parameter form
456
+ [/const _s = (el\?\.scope \?\? el\?\.context\?\.globalScope \?\? \{\});/g, 'const _s = $RESOLVE($1);'],
457
+ // scopeRewriter replaceVarWithScopeAwareOfParamDefaults: a free var read
458
+ // inside a PARAMETER DEFAULT (the body's peer statement cannot reach it)
459
+ [/(?<![\w$.])(this|[A-Za-z_$][\w$]*)\?\.context\?\.globalScope\?\./g, '$RESOLVE($1?.context?.globalScope)?.']
460
+ ]
461
+
462
+ // A copy of `code` with string / template-text / comment interiors blanked
463
+ // ('~', same offsets) and `${ … }` substitutions kept as code — so a peer form
464
+ // written INSIDE a literal (docs text, a code sample) is never rewritten.
465
+ // Regex literals are not modelled: a peer form inside one is not a realistic
466
+ // shape, and the statement forms are exact multi-token statements.
467
+ const codeMask = (code) => {
468
+ const out = code.split('')
469
+ const stack = [] // template nesting: brace depth when a `${` opened
470
+ let i = 0
471
+ let depth = 0
472
+ const blank = (from, to) => { for (let k = from; k < to; k++) if (out[k] !== '\n') out[k] = '~' }
473
+ const scanTemplate = () => { // at the char after an opening ` (or after a closing } of ${)
474
+ const start = i
475
+ while (i < code.length) {
476
+ const c = code[i]
477
+ if (c === '\\') { i += 2; continue }
478
+ if (c === '`') { blank(start, i); i++; return }
479
+ if (c === '$' && code[i + 1] === '{') { blank(start, i); i += 2; stack.push(depth); depth++; return }
480
+ i++
481
+ }
482
+ blank(start, i)
483
+ }
484
+ while (i < code.length) {
485
+ const c = code[i]
486
+ if (c === '/' && code[i + 1] === '/') { const e = code.indexOf('\n', i); const end = e === -1 ? code.length : e; blank(i, end); i = end; continue }
487
+ if (c === '/' && code[i + 1] === '*') { const e = code.indexOf('*/', i + 2); const end = e === -1 ? code.length : e + 2; blank(i, end); i = end; continue }
488
+ if (c === '"' || c === "'") {
489
+ const q = c; const start = ++i
490
+ while (i < code.length && code[i] !== q && code[i] !== '\n') { if (code[i] === '\\') i++; i++ }
491
+ blank(start, i); i++; continue
492
+ }
493
+ if (c === '`') { i++; scanTemplate(); continue }
494
+ if (c === '{') { depth++; i++; continue }
495
+ if (c === '}') {
496
+ depth--
497
+ if (stack.length && depth === stack[stack.length - 1]) { stack.pop(); i++; scanTemplate(); continue }
498
+ i++; continue
499
+ }
500
+ i++
501
+ }
502
+ return out.join('')
503
+ }
504
+
505
+ // Scope the peer statements of ONE emitted function string. Only strings the
506
+ // runtime itself revives as functions (`hasFunction`, destringify's own test)
507
+ // are touched — a component's text, a page's copy, any data string stays as
508
+ // authored — and a match counts only where it starts in code, never inside a
509
+ // string / template text / comment.
510
+ const scopeLibraryText = (text, id) => {
511
+ if (!isString(text) || (!text.includes('__scope = ') && !text.includes('__peers') && !text.includes('const _s = ') && !text.includes('?.context?.globalScope?.'))) return text
512
+ if (!hasFunction(text)) return text
513
+ const resolve = `(globalThis[Symbol.for('smbls.libraryScope')] || ((_, v) => v))(${JSON.stringify(id)}, `
514
+ let out = text
515
+ for (const [re, tpl] of PEER_STATEMENTS) {
516
+ // every replacement keeps the earlier offsets valid only per pass: rescan
517
+ // the mask of the CURRENT text for each form
518
+ const m = codeMask(out)
519
+ out = out.replace(re, (...args) => {
520
+ const offset = args[args.length - 2]
521
+ if (m[offset] === '~' || m[offset] !== out[offset]) return args[0]
522
+ return tpl.replace(/\$RESOLVE\(/g, resolve).replace(/\$(\d)/g, (_, k) => args[Number(k)])
523
+ })
524
+ }
525
+ return out
526
+ }
527
+
528
+ // One library value as merged: emitted text scoped to `id`; a function of
529
+ // emitted text becomes its scoped TEXT (the runtime revives it like any
530
+ // emitted string — frank's emission is closure-free by construction); any
531
+ // other value as is.
532
+ const scopedValue = (v, id) => {
533
+ if (isString(v)) return scopeLibraryText(v, id)
534
+ const text = emittedFunctionText(v)
535
+ return text === null ? v : scopeLibraryText(text, id)
536
+ }
537
+
538
+ // A bag / definition value as merged: if the merge scoped it (emitted text,
539
+ // or a revived emitted function turned back into text), the merge revives that
540
+ // text ITSELF — lazily, the runtime's own revival — because nothing later
541
+ // does for every payload kind: createDomql revives the bags only for raw-JSON
542
+ // payloads (a boot-revived or local-source payload is left as it is).
543
+ const LIBRARY_REVIVAL = { lazy: true, window: globalThis }
544
+ // The revived function serializes as its scoped TEXT (`toJSON`): a merge done
545
+ // in Node and written out as JSON (the runner's project.json, brender) keeps
546
+ // the code instead of dropping it, and the browser's boot pass revives it.
547
+ const scopedCodeValue = (v, id) => {
548
+ const out = scopedValue(v, id)
549
+ if (out === v || !isString(out)) return out
550
+ try {
551
+ const fn = deepDestringifyFunctions({ v: out }, {}, LIBRARY_REVIVAL).v
552
+ if (typeof fn !== 'function') return out
553
+ Object.defineProperty(fn, 'toJSON', { value: () => out, configurable: true })
554
+ return fn
555
+ } catch (_) {
556
+ return out
557
+ }
558
+ }
559
+
560
+ const isPlainContainer = (v) => {
561
+ if (!v || typeof v !== 'object') return false
562
+ if (Array.isArray(v)) return true
563
+ const proto = Object.getPrototypeOf(v)
564
+ return proto === Object.prototype || proto === null
565
+ }
566
+
567
+ // A copy of a definition tree (component / page and its children) with every
568
+ // emitted text scoped; the library's own object is never written.
569
+ const scopeLibraryTree = (v, id, seen = new WeakMap()) => {
570
+ if (isString(v) || typeof v === 'function') return scopedCodeValue(v, id)
571
+ if (isStringTag(v)) return v // a source STRING that looks like code stays a string
572
+ if (!isPlainContainer(v)) return v
573
+ if (seen.has(v)) return seen.get(v)
574
+ const out = Array.isArray(v) ? [] : (Object.getPrototypeOf(v) === null ? Object.create(null) : {})
575
+ seen.set(v, out)
576
+ for (const k of Object.keys(v)) out[k] = scopeLibraryTree(v[k], id, seen)
577
+ return out
578
+ }
579
+
580
+ // The library as merged: its emitted globalScope, function bags and
581
+ // definitions with the peer statements scoped to `id`.
582
+ const scopedLibrary = (sharedLib, id) => {
583
+ const out = { ...sharedLib }
584
+ const gs = {}
585
+ for (const k of Object.keys(sharedLib.globalScope)) gs[k] = scopedValue(sharedLib.globalScope[k], id)
586
+ out.globalScope = gs
587
+ for (const bag of LIBRARY_FUNCTION_BAGS) {
588
+ const from = sharedLib[bag]
589
+ if (!isPlainContainer(from)) continue
590
+ const copy = {}
591
+ for (const k of Object.keys(from)) copy[k] = scopedCodeValue(from[k], id)
592
+ out[bag] = copy
593
+ }
594
+ for (const bag of LIBRARY_DEFINITION_BAGS) {
595
+ if (isPlainContainer(sharedLib[bag])) out[bag] = scopeLibraryTree(sharedLib[bag], id)
596
+ }
597
+ return out
598
+ }
599
+
600
+ // The scope a library reads through an element's scope store: the element's
601
+ // own locals and its ancestors first, then the LIBRARY's globalScope where
602
+ // the consumer's would answer, then the consumer's. A view of the store —
603
+ // never the element, never `this`.
604
+ const scopeViews = new WeakMap() // store -> Map<libGs, view>
605
+ const libraryStoreView = (store, libGs, consumerGs) => {
606
+ let byLib = scopeViews.get(store)
607
+ if (!byLib) scopeViews.set(store, (byLib = new Map()))
608
+ let view = byLib.get(libGs)
609
+ if (view) return view
610
+ const fromConsumer = (p, v) => hasOwn(consumerGs, p) && consumerGs[p] === v
611
+ view = new Proxy(store, {
612
+ get (t, p) {
613
+ if (typeof p === 'symbol' || hasOwn(t, p)) return Reflect.get(t, p)
614
+ const v = Reflect.get(t, p)
615
+ if (hasOwn(libGs, p) && (v === undefined || fromConsumer(p, v))) return libGs[p]
616
+ return v === undefined ? libGs[p] : v
617
+ },
618
+ set (t, p, v) {
619
+ if (typeof p !== 'symbol' && !hasOwn(t, p) && hasOwn(libGs, p)) {
620
+ libGs[p] = v
621
+ return true
622
+ }
623
+ return Reflect.set(t, p, v)
624
+ },
625
+ has: (t, p) => Reflect.has(t, p) || p in libGs
626
+ })
627
+ byLib.set(libGs, view)
628
+ return view
629
+ }
630
+
631
+ const isScopeStore = (v) => !!v && typeof v === 'object' && !!v.__raw && typeof v.__raw === 'object'
632
+
633
+ // globalThis[Symbol.for('smbls.libraryScope')](id, value): what a scoped
634
+ // peer statement evaluates to. Before the library is bound, or for a value
635
+ // that is not the consumer's globalScope / a store, the value as is.
636
+ const resolveLibraryScope = (id, value) => {
637
+ const rec = libraryScopes.get(id)
638
+ if (!rec) return value
639
+ if (value === rec.consumerGs) return rec.libGs
640
+ if (isScopeStore(value)) return libraryStoreView(value, rec.libGs, rec.consumerGs)
641
+ return value
642
+ }
643
+
644
+ const installLibraryScopeResolver = () => {
645
+ if (typeof globalThis[LIBRARY_SCOPE] !== 'function') {
646
+ Object.defineProperty(globalThis, LIBRARY_SCOPE, { value: resolveLibraryScope, configurable: true })
647
+ }
648
+ }
649
+
650
+ const libraryScopeRecordsOf = (context) => {
651
+ const list = context[LIBRARY_SCOPES_KEY]
652
+ return Array.isArray(list) ? list : null
653
+ }
654
+
655
+ const unwrapLibrary = (entry) => (isWrappedLibrary(entry) ? entry.library : entry)
656
+
657
+ // A library this context's data already carries a record for (merged before
658
+ // this runtime — the runner, brender): its scoped entries are in place under
659
+ // that record's id, so this merge must not isolate it a second time.
660
+ const priorLibraryScope = (context, index, library) => {
661
+ const list = libraryScopeRecordsOf(context)
662
+ return !!list && list.some((rec) => rec && rec.index === index && (!rec.key || rec.key === library.key) &&
663
+ isString(rec.id) && carriesScopeId(context, rec.id))
664
+ }
665
+
666
+ // A record is the trace of a real merge only if that merge's scoped text is
667
+ // in the context: some code string carries its id. A record without one (made
668
+ // up, or stale) must not switch this merge's isolation off.
669
+ const carriesScopeId = (context, id) => {
670
+ const needle = JSON.stringify(id)
671
+ const seen = new Set()
672
+ const walk = (v) => {
673
+ if (isString(v)) return v.includes(needle)
674
+ if (!v || typeof v !== 'object' || seen.has(v)) return false
675
+ seen.add(v)
676
+ for (const k in v) if (walk(v[k])) return true
677
+ return false
678
+ }
679
+ for (const bag of ['globalScope', ...LIBRARY_FUNCTION_BAGS, ...LIBRARY_DEFINITION_BAGS]) {
680
+ if (walk(context[bag])) return true
681
+ }
682
+ return false
683
+ }
684
+
685
+ const scopedGlobalScopeOf = (gs, id) => {
686
+ const out = {}
687
+ for (const k of Object.keys(gs)) out[k] = scopedValue(gs[k], id)
688
+ return out
689
+ }
690
+
691
+ const boundScopes = new WeakMap() // consumer globalScope -> Set<id>
692
+
693
+ /**
694
+ * After the runtime revived `context.globalScope` and the bags (createDomql),
695
+ * give every library recorded in `context.__libraryScopes` — by this merge or
696
+ * by one done before this runtime — its own revived globalScope (falling back
697
+ * to the consumer's for names it does not define) and register it for the
698
+ * resolver its scoped peer statements call. The library's names the consumer
699
+ * did NOT hold (`landed`) become the library's own values in the consumer's
700
+ * globalScope — one value, shared by both. Returns the number bound.
701
+ */
702
+ export const bindLibraryGlobalScopes = (context, mergedGlobalScope = null) => {
703
+ const records = context && libraryScopeRecordsOf(context)
704
+ if (!records || !records.length) return 0
705
+ const consumerGs = context.globalScope
706
+ if (!isObject(consumerGs)) return 0
707
+ const libraries = Array.isArray(context.sharedLibraries) ? context.sharedLibraries : []
708
+ let done = boundScopes.get(consumerGs)
709
+ if (!done) boundScopes.set(consumerGs, (done = new Set()))
710
+ installLibraryScopeResolver()
711
+ let n = 0
712
+ for (const rec of records) {
713
+ if (!rec || !isString(rec.id) || done.has(rec.id)) continue
714
+ const lib = unwrapLibrary(libraries[rec.index])
715
+ if (!lib || !isObject(lib.globalScope) || (rec.key && lib.key !== rec.key)) continue
716
+ // A landed name is one the CONSUMER did not have: the library defines it
717
+ // and the merged (pre-revival) consumer globalScope holds exactly the
718
+ // library's own scoped value under it — so neither a library nor a record
719
+ // can re-point a name the consumer owns. (A consumer whose own value is
720
+ // byte-identical to the library's is indistinguishable here: it can only
721
+ // re-point its own name to an identical value, through its own data.)
722
+ const asText = (v) => (typeof v === 'function' ? functionText(v) : v)
723
+ const sameValue = (a, b) => {
724
+ if (a === b) return true
725
+ const ta = asText(a)
726
+ const tb = asText(b)
727
+ if (isString(ta) || isString(tb)) return ta === tb // functions compare by source text
728
+ return JSON.stringify(a) === JSON.stringify(b)
729
+ }
730
+ const landed = !isObject(mergedGlobalScope)
731
+ ? []
732
+ : (Array.isArray(rec.landed) ? rec.landed : []).filter((k) =>
733
+ isString(k) && hasOwn(lib.globalScope, k) && hasOwn(mergedGlobalScope, k) &&
734
+ sameValue(mergedGlobalScope[k], scopedValue(lib.globalScope[k], rec.id)))
735
+ const libGs = destringifyGlobalScope(scopedGlobalScopeOf(lib.globalScope, rec.id))
736
+ Object.setPrototypeOf(libGs, consumerGs)
737
+ libraryScopes.set(rec.id, { libGs, consumerGs })
738
+ for (const k of landed) consumerGs[k] = libGs[k]
739
+ done.add(rec.id)
740
+ n++
741
+ }
742
+ return n
743
+ }
744
+
745
+ // ── a library's package names ─────────────────────────────────────────────
746
+ //
747
+ // frank emits a declared-library import as a registry read under the
748
+ // specifier the source used: `@symbo-ls/<record key>` or the npm name
749
+ // (`@symbo-ls/workspace-shared`). A library is known by its PRIMARY name
750
+ // (`key || name || __libraryKey`, any form) and by every npm-scoped
751
+ // identifier it carries (`__libraryName`, stamped by frank at the library's
752
+ // push; `__libraryKey`/`name` when scoped). Every primary registers before any
753
+ // alias, so a library cannot take a slot another library owns by record key;
754
+ // an alias two libraries claim stays with the first and is reported.
755
+ const NPM_SCOPED_LIBRARY_ID_RE = /^@symbo[-.]ls\//
756
+ const bareLibraryKey = (raw) => (raw.includes('/') ? raw.slice(raw.indexOf('/') + 1) : raw)
757
+
758
+ /**
759
+ * Ordered [spec, library] pairs for `libraries` (entries or wrappers), stubs
760
+ * skipped. `onCollision({ spec, kept, refused })` is called for an alias a
761
+ * later library could not take.
762
+ */
763
+ export const libraryPackageSpecs = (libraries, onCollision) => {
764
+ const out = []
765
+ if (!Array.isArray(libraries)) return out
766
+ const owner = new Map()
767
+ const take = (key, lib, isAlias) => {
768
+ for (const spec of [`@symbo-ls/${key}`, `@symbo.ls/${key}`]) {
769
+ const have = owner.get(spec)
770
+ if (have === undefined) { owner.set(spec, lib); out.push([spec, lib]); continue }
771
+ if (have !== lib && isAlias && typeof onCollision === 'function') onCollision({ spec, kept: have, refused: lib })
772
+ }
773
+ }
774
+ const aliases = []
775
+ for (const entry of libraries) {
776
+ const lib = unwrapLibrary(entry)
777
+ if (!lib || typeof lib !== 'object' || lib.__isStub) continue
778
+ const primary = lib.key || lib.name || lib.__libraryKey
779
+ const keys = []
780
+ for (const raw of [lib.key, lib.name, lib.__libraryKey, lib.__libraryName]) {
781
+ if (typeof raw !== 'string' || !raw) continue
782
+ if (raw !== primary && !NPM_SCOPED_LIBRARY_ID_RE.test(raw)) continue
783
+ const key = bareLibraryKey(raw)
784
+ if (key && !keys.includes(key)) keys.push(key)
785
+ }
786
+ keys.forEach((key, i) => {
787
+ if (i === 0 && primary && bareLibraryKey(primary) === key) take(key, lib, false)
788
+ else aliases.push([key, lib])
789
+ })
790
+ }
791
+ for (const [key, lib] of aliases) take(key, lib, true)
792
+ return out
793
+ }
794
+
795
+ export const warnLibraryAliasCollision = ({ spec, kept, refused }) => {
796
+ if (typeof console === 'undefined') return
797
+ console.warn(`[smbls] shared library "${refused && refused.key}" also claims ${spec}, which "${kept && kept.key}" already owns; ${spec} stays with "${kept && kept.key}".`)
798
+ }
799
+
800
+ // ── a code bag as receiver ────────────────────────────────────────────────
801
+ //
802
+ // frank's peer statements derive the globalScope from the receiver
803
+ // (`r.scope ?? r.context.globalScope ?? r`). A function reached THROUGH a bag —
804
+ // a declared-library facade (`_wsShared.functions.applyA11yPrefs(...)`, emitted
805
+ // as `__scope.___wsShared.functions.applyA11yPrefs(...)`), or project code
806
+ // calling `el.context.functions.x(...)` — runs with the bag as `this`, which has
807
+ // neither, so every peer read was undefined (`__scope.wsA11yWindow is not a
808
+ // function` in applyA11yPrefs on the served dev shell, 2026-10-07).
809
+ //
810
+ // Everything is PER CONTEXT and nothing is global:
811
+ // - the context's own bags are always COPIES bound to this context (never a
812
+ // library's bag the merge may have reused, never one another context owns);
813
+ // - each `sharedLibraries` entry becomes a per-context VIEW (shallow copy)
814
+ // whose bags are copies answering the library's isolated globalScope in this
815
+ // context (else this context's globalScope); the library object is never
816
+ // mutated;
817
+ // - the views are published on THIS context's globalScope under the
818
+ // non-enumerable `Symbol.for('smbls.libraryPackages')` map (spec -> view).
819
+ // frank's facades read it first (`this` is the globalScope, an element scope
820
+ // chained to it, or an element whose `context.globalScope` carries it), then
821
+ // the process-global `__SMBLS_PKGS__` registry, which keeps RAW library
822
+ // objects only — no context is ever reachable from a global (SSR: one
823
+ // process, many requests).
824
+ const CODE_BAGS_WITH_RECEIVER = ['functions', 'methods', 'snippets']
825
+ export const LIBRARY_PACKAGES = Symbol.for('smbls.libraryPackages')
826
+ const bagOwners = new WeakMap()
827
+
828
+ const isBag = (bag) => !!bag && typeof bag === 'object' && !Array.isArray(bag)
829
+
830
+ const receiverContextFor = (readGlobalScope) => ({
831
+ get globalScope () { return readGlobalScope() }
832
+ })
833
+
834
+ const boundCopy = (bag, readGlobalScope, owner) => {
835
+ const copy = {}
836
+ for (const key of Object.keys(bag)) copy[key] = bag[key]
837
+ Object.defineProperty(copy, 'context', {
838
+ configurable: true,
839
+ enumerable: false,
840
+ writable: true,
841
+ value: receiverContextFor(readGlobalScope)
842
+ })
843
+ bagOwners.set(copy, owner)
844
+ return copy
845
+ }
846
+
847
+ // A bag we did not bind that has its own `context` KEY is the project's data.
848
+ const keepAsIs = (bag) => !isBag(bag) || (!bagOwners.has(bag) && Object.prototype.hasOwnProperty.call(bag, 'context'))
849
+
850
+ export const exposeBagGlobalScopes = (context) => {
851
+ if (!context || typeof context !== 'object') return
852
+ const ownGs = () => context.globalScope
853
+ for (const bag of CODE_BAGS_WITH_RECEIVER) {
854
+ const cur = context[bag]
855
+ if (keepAsIs(cur) || bagOwners.get(cur) === context) continue
856
+ context[bag] = boundCopy(cur, ownGs, context)
857
+ }
858
+ if (Array.isArray(context.sharedLibraries)) {
859
+ const records = libraryScopeRecordsOf(context) || []
860
+ context.sharedLibraries = context.sharedLibraries.map((entry, index) => {
861
+ const wrapped = isWrappedLibrary(entry) && entry && 'library' in entry
862
+ const lib = unwrapLibrary(entry)
863
+ if (!lib || typeof lib !== 'object' || lib.__isStub) return entry
864
+ if (bagOwners.get(lib) === context) return entry // already this context's view
865
+ const rec = records.find((r) => r && r.index === index && (!r.key || r.key === lib.key))
866
+ const readGlobalScope = () => {
867
+ const bound = rec && libraryScopes.get(rec.id)
868
+ return bound && bound.consumerGs === context.globalScope ? bound.libGs : context.globalScope
869
+ }
870
+ const view = { ...lib }
871
+ for (const bag of CODE_BAGS_WITH_RECEIVER) {
872
+ if (!keepAsIs(lib[bag])) view[bag] = boundCopy(lib[bag], readGlobalScope, context)
873
+ }
874
+ bagOwners.set(view, context)
875
+ return wrapped ? { ...entry, library: view } : view
876
+ })
877
+ }
878
+ const gs = context.globalScope
879
+ if (gs && typeof gs === 'object') {
880
+ const map = {}
881
+ for (const [spec, view] of libraryPackageSpecs(context.sharedLibraries, warnLibraryAliasCollision)) map[spec] = view
882
+ try {
883
+ Object.defineProperty(gs, LIBRARY_PACKAGES, { configurable: true, enumerable: false, writable: true, value: map })
884
+ } catch (_) {} // frozen globalScope: facades fall back to the global registry
885
+ }
886
+ }
887
+
888
+ const mergeOneLibrary = (context, library, ignore, label = 'library', index = -1) => {
889
+ const skip = librarySkip(library, ignore)
890
+ // a library sharing a globalScope name keeps its own (see above)
891
+ const scopeId = !priorLibraryScope(context, index, library) && sharedGlobalScopeNames(context, library, skip) > 0
892
+ ? `${label}#${scopeToken()}`
893
+ : null
894
+ const sharedLib = scopeId ? scopedLibrary(library, scopeId) : library
895
+ const landedBefore = scopeId ? new Set(Object.keys(context.globalScope)) : null
359
896
  const refusedMethods = []
360
897
  for (const key in sharedLib) {
361
898
  if (!Object.prototype.hasOwnProperty.call(sharedLib, key)) continue
362
899
  // merge directives, not library content
363
900
  if (key === 'sharePages' || key === 'sharedLibIgnore') continue
901
+ // the merge's own record (see LIBRARY_SCOPES_KEY): written only by the
902
+ // merge, never taken from a library payload — a library carrying one
903
+ // could re-point another library's (or the consumer's) globalScope names
904
+ if (key === LIBRARY_SCOPES_KEY) continue
905
+ // no `__` key of a library payload is consumer content (the server merge
906
+ // skips them too): merge bookkeeping and markers are the merge's own
907
+ if (key.startsWith('__')) continue
364
908
  // A library's `app` is its own standalone deployment root — chrome, boot
365
909
  // hooks, watchers — never consumer content, so it is excluded
366
910
  // UNCONDITIONALLY, on both merge branches, declaration or not. Six of the
@@ -408,6 +952,15 @@ const mergeOneLibrary = (context, sharedLib, ignore, label = 'library') => {
408
952
  context[key] = copyWithNestedIgnores(value, skip, key)
409
953
  }
410
954
  }
955
+ if (scopeId) {
956
+ if (!libraryScopeRecordsOf(context)) context[LIBRARY_SCOPES_KEY] = []
957
+ context[LIBRARY_SCOPES_KEY].push({
958
+ id: scopeId,
959
+ index,
960
+ key: isString(library.key) ? library.key : null,
961
+ landed: Object.keys(sharedLib.globalScope).filter((k) => !landedBefore.has(k))
962
+ })
963
+ }
411
964
  if (refusedMethods.length) warnRefusedBuiltinMethods(label, refusedMethods)
412
965
  }
413
966
 
@@ -549,7 +1102,7 @@ export const mergeSharedLibraries = (context, libraries) => {
549
1102
  libraries,
550
1103
  () => context.designSystem,
551
1104
  ({ entry, lib, ignore, index }) =>
552
- mergeOneLibrary(context, lib, ignore, libraryLabel(entry, lib, index))
1105
+ mergeOneLibrary(context, lib, ignore, libraryLabel(entry, lib, index), index)
553
1106
  )
554
1107
  if (!claims) return
555
1108
  // A consumer with no design system of its own holds the first library's