@invisibleloop/pulse 0.1.30 → 0.1.32

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.
@@ -32,4 +32,5 @@ jobs:
32
32
  VERSION=$(node -e "const [a,b,c]='$VERSION'.split('.').map(Number);console.log(a+'.'+b+'.'+(c+1))")
33
33
  done
34
34
  npm version $VERSION --no-git-tag-version
35
+ echo "$VERSION" > public/.pulse-ui-version
35
36
  npm publish --provenance --access public
@@ -1 +1 @@
1
- 0.1.28
1
+ 0.1.29
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
2
+ <rect width="32" height="32" rx="6" fill="#0d0d10"/>
3
+ <path d="M18 4L8 17H15L14 28L24 15H17L18 4Z" fill="#f5c842" stroke="#f5c842" stroke-width="0.5" stroke-linejoin="round"/>
4
+ </svg>
@@ -810,8 +810,8 @@ hr.ui-divider {
810
810
  }
811
811
 
812
812
  .ui-testimonial-avatar--initials {
813
- background: var(--ui-accent-dim, rgba(155,141,255,.12));
814
- color: var(--ui-accent, var(--accent, #9b8dff));
813
+ background: var(--ui-muted-bg, rgba(128,128,128,.2));
814
+ color: var(--ui-text, var(--text, #e2e2ea));
815
815
  font-size: .8rem;
816
816
  font-weight: 700;
817
817
  display: flex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invisibleloop/pulse",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "type": "module",
5
5
  "description": "AI-first frontend framework. The spec is the source of truth.",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- 0.1.17
1
+ 0.1.32
@@ -160,7 +160,7 @@ export function renderToStream(spec, ctx = {}, nonce = '') {
160
160
  * @param {Object} [options.timing] - Server-Timing values
161
161
  * @returns {string}
162
162
  */
163
- export function wrapDocument({ content, spec = {}, serverState = {}, storeState = null, storeDef = null, timing = {}, extraBody = '', extraHead = '', nonce = '', runtimeBundle = '' }) {
163
+ export function wrapDocument({ content, spec = {}, serverState = {}, storeState = null, storeDef = null, timing = {}, extraBody = '', extraHead = '', nonce = '', runtimeBundle = '', faviconHref = '' }) {
164
164
  const meta = spec.meta || {}
165
165
  const title = meta.title || 'Pulse'
166
166
 
@@ -250,7 +250,7 @@ export function wrapDocument({ content, spec = {}, serverState = {}, storeState
250
250
  <head>
251
251
  <meta charset="UTF-8">
252
252
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
253
- <link rel="icon" href="data:,">
253
+ <link rel="icon" href="${faviconHref || 'data:,'}">
254
254
  <title>${esc(title)}</title>
255
255
  ${stylePreloads}
256
256
  ${runtimePreload}
@@ -400,6 +400,11 @@ export function createServer(specs, options = {}) {
400
400
  const hydrateMap = loadManifest(manifest, staticDir)
401
401
  const runtimeBundle = hydrateMap['_runtime'] || ''
402
402
 
403
+ // Auto-detect favicon in staticDir
404
+ const faviconPath = staticDir
405
+ ? ['/favicon.svg', '/favicon.ico', '/favicon.png'].find(f => fs.existsSync(path.join(staticDir, f))) || null
406
+ : null
407
+
403
408
  // Validate all specs upfront — fail at startup, not at request time
404
409
  for (const spec of specs) {
405
410
  const { valid, errors } = validateSpec(spec)
@@ -704,7 +709,7 @@ async function handleStringResponse(spec, ctx, req, res, extraBody = '', dev = f
704
709
  const canonicalTag = canonicalUrl ? `<link rel="canonical" href="${escHtml(canonicalUrl)}">` : ''
705
710
  const resolvedSpec = { ...spec, meta: resolveMeta(spec.meta, ctx) }
706
711
  const resolvedExtraBody = typeof extraBody === 'function' ? extraBody(nonce) : extraBody
707
- const wrapped = wrapDocument({ content, spec: resolvedSpec, serverState, storeState: ctx.store || null, storeDef: store || null, timing, extraBody: resolvedExtraBody, extraHead: (dev ? devImportMap(nonce) + '\n ' : '') + canonicalTag, nonce, runtimeBundle })
712
+ const wrapped = wrapDocument({ content, spec: resolvedSpec, serverState, storeState: ctx.store || null, storeDef: store || null, timing, extraBody: resolvedExtraBody, extraHead: (dev ? devImportMap(nonce) + '\n ' : '') + canonicalTag, nonce, runtimeBundle, faviconHref: faviconPath || '' })
708
713
  html = wrapped.html
709
714
  serverTimingValue = wrapped.serverTimingValue
710
715
  if (ttl > 0) pageHtmlCache.set(cacheKey, { html }, ttl)
@@ -799,7 +804,7 @@ async function handleStreamResponse(spec, ctx, req, res, extraBody = '', dev = f
799
804
  <head>
800
805
  <meta charset="UTF-8">
801
806
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
802
- <link rel="icon" href="data:,">
807
+ <link rel="icon" href="${faviconPath || 'data:,'}">
803
808
  <title>${escHtml(title)}</title>
804
809
  ${stylePreloads ? stylePreloads + '\n' : ''}${runtimePreload ? runtimePreload + '\n' : ''}${dev ? devImportMap(nonce) + '\n' : ''}${metaTags}
805
810
  </head>