@flamingo-stack/openframe-frontend-core 0.0.569 → 0.0.570

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/{chunk-PLJAOZYZ.js → chunk-3H6NH2AD.js} +5 -5
  2. package/dist/{chunk-VNE2EHCD.cjs → chunk-3YO2ZIZL.cjs} +14 -14
  3. package/dist/{chunk-VNE2EHCD.cjs.map → chunk-3YO2ZIZL.cjs.map} +1 -1
  4. package/dist/{chunk-QY3VTOB6.cjs → chunk-4BJ4FQPG.cjs} +18 -18
  5. package/dist/{chunk-QY3VTOB6.cjs.map → chunk-4BJ4FQPG.cjs.map} +1 -1
  6. package/dist/{chunk-FE5QR7PT.js → chunk-5NVVVIHJ.js} +48 -28
  7. package/dist/{chunk-FE5QR7PT.js.map → chunk-5NVVVIHJ.js.map} +1 -1
  8. package/dist/{chunk-2DSDGWWU.cjs → chunk-6WXL6CIL.cjs} +97 -97
  9. package/dist/{chunk-2DSDGWWU.cjs.map → chunk-6WXL6CIL.cjs.map} +1 -1
  10. package/dist/{chunk-Z3SRMLMK.cjs → chunk-AQ6MIFNX.cjs} +41 -14
  11. package/dist/chunk-AQ6MIFNX.cjs.map +1 -0
  12. package/dist/{chunk-FMWIA5IH.cjs → chunk-CSCAOET4.cjs} +42 -42
  13. package/dist/{chunk-FMWIA5IH.cjs.map → chunk-CSCAOET4.cjs.map} +1 -1
  14. package/dist/{chunk-XMECOGLY.cjs → chunk-CYY2PEYQ.cjs} +3 -3
  15. package/dist/{chunk-XMECOGLY.cjs.map → chunk-CYY2PEYQ.cjs.map} +1 -1
  16. package/dist/{chunk-SMW5Z4NW.cjs → chunk-D463PBIY.cjs} +23 -23
  17. package/dist/{chunk-SMW5Z4NW.cjs.map → chunk-D463PBIY.cjs.map} +1 -1
  18. package/dist/{chunk-TDYTAED2.cjs → chunk-DP2L7US5.cjs} +3 -3
  19. package/dist/{chunk-TDYTAED2.cjs.map → chunk-DP2L7US5.cjs.map} +1 -1
  20. package/dist/{chunk-ME346OJF.cjs → chunk-GDPPFPLD.cjs} +40 -40
  21. package/dist/{chunk-ME346OJF.cjs.map → chunk-GDPPFPLD.cjs.map} +1 -1
  22. package/dist/{chunk-EBE22KOQ.cjs → chunk-HJCXSI7R.cjs} +4 -4
  23. package/dist/{chunk-EBE22KOQ.cjs.map → chunk-HJCXSI7R.cjs.map} +1 -1
  24. package/dist/{chunk-D6SBYELJ.cjs → chunk-I7CFA5DO.cjs} +32 -32
  25. package/dist/{chunk-D6SBYELJ.cjs.map → chunk-I7CFA5DO.cjs.map} +1 -1
  26. package/dist/{chunk-SW3K3JSP.cjs → chunk-IJA26YDA.cjs} +8 -8
  27. package/dist/{chunk-SW3K3JSP.cjs.map → chunk-IJA26YDA.cjs.map} +1 -1
  28. package/dist/{chunk-HOMYI5RR.js → chunk-KYDVOX5J.js} +2 -2
  29. package/dist/{chunk-OS5RFMW5.js → chunk-MT7IDGCM.js} +3 -3
  30. package/dist/{chunk-6STF67EF.js → chunk-MTORQ4LY.js} +4 -4
  31. package/dist/{chunk-AAROYQ4O.cjs → chunk-PS2TV7WG.cjs} +12 -12
  32. package/dist/{chunk-AAROYQ4O.cjs.map → chunk-PS2TV7WG.cjs.map} +1 -1
  33. package/dist/{chunk-P7ZENKIA.js → chunk-PTDRJCPW.js} +2 -2
  34. package/dist/{chunk-KO333Q2B.js → chunk-QIU5B2ZD.js} +2 -2
  35. package/dist/{chunk-74DB5H5T.cjs → chunk-RVCCJB6M.cjs} +165 -145
  36. package/dist/chunk-RVCCJB6M.cjs.map +1 -0
  37. package/dist/{chunk-PCL6WYYT.cjs → chunk-T4MB5TX6.cjs} +5 -5
  38. package/dist/{chunk-PCL6WYYT.cjs.map → chunk-T4MB5TX6.cjs.map} +1 -1
  39. package/dist/{chunk-3UPQAOES.js → chunk-TQER4FVN.js} +3 -3
  40. package/dist/{chunk-KCAGMTJ6.js → chunk-U6NPZMNT.js} +8 -8
  41. package/dist/{chunk-LJBNHO6B.js → chunk-VZQKENQU.js} +3 -3
  42. package/dist/{chunk-OWCN3BM6.js → chunk-XWMEHLDK.js} +6 -6
  43. package/dist/{chunk-TXEI4PES.js → chunk-YFLKONLB.js} +33 -6
  44. package/dist/{chunk-TXEI4PES.js.map → chunk-YFLKONLB.js.map} +1 -1
  45. package/dist/{chunk-C5GKBUT7.js → chunk-YYESWAAQ.js} +3 -3
  46. package/dist/{chunk-A2T266F3.js → chunk-Z3MSD6ZE.js} +6 -6
  47. package/dist/{chunk-GY22CIEF.cjs → chunk-Z7DXVKVT.cjs} +76 -76
  48. package/dist/{chunk-GY22CIEF.cjs.map → chunk-Z7DXVKVT.cjs.map} +1 -1
  49. package/dist/{chunk-4NN7V443.js → chunk-ZAYZ7JHF.js} +2 -2
  50. package/dist/{chunk-MZG3QQUR.js → chunk-ZTGWMXJK.js} +2 -2
  51. package/dist/components/case-studies/index.cjs +9 -9
  52. package/dist/components/case-studies/index.js +3 -3
  53. package/dist/components/chat/index.cjs +3 -3
  54. package/dist/components/chat/index.js +2 -2
  55. package/dist/components/contact/index.cjs +4 -4
  56. package/dist/components/contact/index.js +3 -3
  57. package/dist/components/docs/index.cjs +6 -6
  58. package/dist/components/docs/index.js +5 -5
  59. package/dist/components/embeds/claude-embed.d.ts.map +1 -1
  60. package/dist/components/embeds/embed-viewer-frame.d.ts +10 -2
  61. package/dist/components/embeds/embed-viewer-frame.d.ts.map +1 -1
  62. package/dist/components/embeds/index.cjs +4 -4
  63. package/dist/components/embeds/index.js +3 -3
  64. package/dist/components/faq/index.cjs +5 -5
  65. package/dist/components/faq/index.js +4 -4
  66. package/dist/components/features/index.cjs +3 -3
  67. package/dist/components/features/index.js +2 -2
  68. package/dist/components/help-center-pages/index.cjs +24 -24
  69. package/dist/components/help-center-pages/index.js +15 -15
  70. package/dist/components/index.cjs +138 -138
  71. package/dist/components/index.js +13 -13
  72. package/dist/components/meeting-scheduler/index.cjs +35 -35
  73. package/dist/components/meeting-scheduler/index.js +4 -4
  74. package/dist/components/navigation/index.cjs +3 -3
  75. package/dist/components/navigation/index.js +2 -2
  76. package/dist/components/onboarding-guides/index.cjs +7 -7
  77. package/dist/components/onboarding-guides/index.js +6 -6
  78. package/dist/components/related-content/index.cjs +5 -5
  79. package/dist/components/related-content/index.js +4 -4
  80. package/dist/components/tickets/index.cjs +7 -7
  81. package/dist/components/tickets/index.js +6 -6
  82. package/dist/components/ui/index.cjs +3 -3
  83. package/dist/components/ui/index.js +2 -2
  84. package/dist/hooks/index.cjs +2 -2
  85. package/dist/hooks/index.js +1 -1
  86. package/dist/hooks/use-claude-mirror-src.d.ts +34 -13
  87. package/dist/hooks/use-claude-mirror-src.d.ts.map +1 -1
  88. package/dist/index.cjs +3 -3
  89. package/dist/index.js +2 -2
  90. package/package.json +1 -1
  91. package/src/components/embeds/claude-embed.tsx +13 -4
  92. package/src/components/embeds/embed-viewer-frame.tsx +27 -2
  93. package/src/hooks/use-claude-mirror-src.ts +79 -19
  94. package/dist/chunk-74DB5H5T.cjs.map +0 -1
  95. package/dist/chunk-Z3SRMLMK.cjs.map +0 -1
  96. /package/dist/{chunk-PLJAOZYZ.js.map → chunk-3H6NH2AD.js.map} +0 -0
  97. /package/dist/{chunk-HOMYI5RR.js.map → chunk-KYDVOX5J.js.map} +0 -0
  98. /package/dist/{chunk-OS5RFMW5.js.map → chunk-MT7IDGCM.js.map} +0 -0
  99. /package/dist/{chunk-6STF67EF.js.map → chunk-MTORQ4LY.js.map} +0 -0
  100. /package/dist/{chunk-P7ZENKIA.js.map → chunk-PTDRJCPW.js.map} +0 -0
  101. /package/dist/{chunk-KO333Q2B.js.map → chunk-QIU5B2ZD.js.map} +0 -0
  102. /package/dist/{chunk-3UPQAOES.js.map → chunk-TQER4FVN.js.map} +0 -0
  103. /package/dist/{chunk-KCAGMTJ6.js.map → chunk-U6NPZMNT.js.map} +0 -0
  104. /package/dist/{chunk-LJBNHO6B.js.map → chunk-VZQKENQU.js.map} +0 -0
  105. /package/dist/{chunk-OWCN3BM6.js.map → chunk-XWMEHLDK.js.map} +0 -0
  106. /package/dist/{chunk-C5GKBUT7.js.map → chunk-YYESWAAQ.js.map} +0 -0
  107. /package/dist/{chunk-A2T266F3.js.map → chunk-Z3MSD6ZE.js.map} +0 -0
  108. /package/dist/{chunk-4NN7V443.js.map → chunk-ZAYZ7JHF.js.map} +0 -0
  109. /package/dist/{chunk-MZG3QQUR.js.map → chunk-ZTGWMXJK.js.map} +0 -0
@@ -4,40 +4,100 @@ import { useEffect, useState } from 'react'
4
4
  import { useEndpointsRuntime } from '../contexts/endpoints-runtime-context'
5
5
  import { toClaudeMirrorPath } from '../utils/embed-url-converters'
6
6
 
7
+ export type ClaudeMirrorStatus =
8
+ /** No mirror candidate at all (no proxy configured, or a non-mirrorable url). */
9
+ | 'absent'
10
+ /** Probing the host for a self-hosted mirror (or minting one on first view). */
11
+ | 'probing'
12
+ /** A mirror exists and `src` points at it. */
13
+ | 'found'
14
+
15
+ export interface ClaudeMirrorState {
16
+ /** The mirror src when found (with a cache-bust once a re-publish is
17
+ * detected), else `null`. */
18
+ src: string | null
19
+ status: ClaudeMirrorStatus
20
+ }
21
+
7
22
  /**
8
- * The host's SELF-HOSTED MIRROR src for a claude artifact url, or `null`
9
- * while none is known THE hook behind `ClaudeEmbed`'s transparent
10
- * mirror leg, extracted so the component stays presentational.
23
+ * Ask the host's storage-view proxy whether the cached mirror is still the
24
+ * artifact's CURRENT version, re-minting it silently if a re-publish moved
25
+ * it. Returns a cache-bust token (the new version) when the mirror changed,
26
+ * else null. Best-effort: any failure just leaves the shown mirror in place.
27
+ */
28
+ async function revalidateMirror(mirrorPath: string): Promise<string | null> {
29
+ try {
30
+ const res = await fetch(`${mirrorPath}?revalidate=1`)
31
+ if (!res.ok) return null
32
+ const body = (await res.json()) as { updated?: boolean; version?: string | null }
33
+ return body?.updated ? String(body.version ?? Date.now()) : null
34
+ } catch {
35
+ return null
36
+ }
37
+ }
38
+
39
+ /**
40
+ * The host's SELF-HOSTED MIRROR src for a claude artifact url, plus a
41
+ * `status` so the viewer can show a loading state while it resolves — THE
42
+ * hook behind `ClaudeEmbed`'s transparent mirror leg, extracted so the
43
+ * component stays presentational.
44
+ *
45
+ * Fully under the hood, three moves:
46
+ * 1. Derive the candidate mirror path from the url's artifact id under the
47
+ * host's configured storage-view proxy base
48
+ * (`EndpointsRuntime.storageViewBaseUrl`) and probe it with a 1-byte
49
+ * ranged GET. On a cold first view that probe IS the server-side
50
+ * self-heal (~1-2s), which is exactly why `status: 'probing'` exists —
51
+ * the viewer shows a spinner instead of the empty "no embeddable view"
52
+ * flash. Exists → `found`; missing / no proxy / blip → `absent`, and the
53
+ * caller's claude.ai fallback stands (the pre-mirror behavior).
54
+ * 2. Once found, fire ONE background revalidation. If the artifact was
55
+ * re-published since the mirror was cached, the server re-mints it and
56
+ * reports the new version; the hook bumps a cache-bust on `src` so the
57
+ * iframe silently reloads the fresh bytes. Unchanged → nothing happens.
11
58
  *
12
- * Fully under the hood: derives the candidate mirror path from the url's
13
- * artifact id under the host's configured storage-view proxy base
14
- * (`EndpointsRuntime.storageViewBaseUrl` — the SAME proxy-path mechanism
15
- * as every other lib→API call) and probes it with a 1-byte ranged GET
16
- * (the proxy forwards Range, so the probe costs nothing). Exists → the
17
- * mirror path; missing / no proxy / network blip → `null`, and the
18
- * caller's claude.ai fallback is exactly the pre-mirror behavior. A host
19
- * that mounts no EndpointsRuntime provider (or omits the entry) skips
20
- * the mirror leg entirely.
59
+ * A host that mounts no EndpointsRuntime provider (or omits the entry) skips
60
+ * the mirror leg entirely (`absent`).
21
61
  */
22
- export function useClaudeMirrorSrc(url: string): string | null {
62
+ export function useClaudeMirrorSrc(url: string): ClaudeMirrorState {
23
63
  const endpoints = useEndpointsRuntime()
24
64
  const mirrorPath = toClaudeMirrorPath(url, endpoints?.storageViewBaseUrl)
25
- const [mirrorSrc, setMirrorSrc] = useState<string | null>(null)
65
+ const [state, setState] = useState<ClaudeMirrorState>(() => ({
66
+ src: null,
67
+ status: mirrorPath ? 'probing' : 'absent',
68
+ }))
69
+
26
70
  useEffect(() => {
27
- setMirrorSrc(null)
28
- if (!mirrorPath) return
71
+ if (!mirrorPath) {
72
+ setState({ src: null, status: 'absent' })
73
+ return
74
+ }
75
+ setState({ src: null, status: 'probing' })
29
76
  let cancelled = false
30
77
  fetch(mirrorPath, { headers: { Range: 'bytes=0-0' } })
31
- .then(res => {
32
- if (!cancelled && (res.ok || res.status === 206)) setMirrorSrc(mirrorPath)
78
+ .then((res) => {
79
+ if (cancelled) return
80
+ if (!(res.ok || res.status === 206)) {
81
+ setState({ src: null, status: 'absent' })
82
+ return
83
+ }
84
+ setState({ src: mirrorPath, status: 'found' })
85
+ // Background freshness check — reload in place only if it changed.
86
+ revalidateMirror(mirrorPath).then((bust) => {
87
+ if (!cancelled && bust) {
88
+ setState({ src: `${mirrorPath}?v=${encodeURIComponent(bust)}`, status: 'found' })
89
+ }
90
+ })
33
91
  })
34
92
  .catch(() => {
35
93
  // No proxy on this host / network blip — the caller's claude.ai
36
94
  // fallback stands, same as before mirrors existed.
95
+ if (!cancelled) setState({ src: null, status: 'absent' })
37
96
  })
38
97
  return () => {
39
98
  cancelled = true
40
99
  }
41
100
  }, [mirrorPath])
42
- return mirrorSrc
101
+
102
+ return state
43
103
  }