@athenaintel/react 0.30.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/README.md +160 -9
  2. package/dist/agent-runtime/src/athena-asset-drag.cjs +44 -0
  3. package/dist/agent-runtime/src/athena-asset-drag.cjs.map +1 -0
  4. package/dist/agent-runtime/src/athena-asset-drag.js +44 -0
  5. package/dist/agent-runtime/src/athena-asset-drag.js.map +1 -0
  6. package/dist/agent-runtime/src/composer-markdown.cjs.map +1 -1
  7. package/dist/agent-runtime/src/composer-markdown.js.map +1 -1
  8. package/dist/agent-runtime/src/config-mutations.cjs +59 -0
  9. package/dist/agent-runtime/src/config-mutations.cjs.map +1 -0
  10. package/dist/agent-runtime/src/config-mutations.js +59 -0
  11. package/dist/agent-runtime/src/config-mutations.js.map +1 -0
  12. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs +2 -3
  13. package/dist/agent-runtime/src/deep-agent-transport-recipe.cjs.map +1 -1
  14. package/dist/agent-runtime/src/deep-agent-transport-recipe.js +3 -4
  15. package/dist/agent-runtime/src/deep-agent-transport-recipe.js.map +1 -1
  16. package/dist/agent-runtime/src/edit-command.cjs.map +1 -1
  17. package/dist/agent-runtime/src/edit-command.js.map +1 -1
  18. package/dist/agent-runtime/src/generated/runconfig-contract.cjs +6 -0
  19. package/dist/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
  20. package/dist/agent-runtime/src/generated/runconfig-contract.js +6 -0
  21. package/dist/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
  22. package/dist/agent-runtime/src/messages.cjs +57 -2
  23. package/dist/agent-runtime/src/messages.cjs.map +1 -1
  24. package/dist/agent-runtime/src/messages.js +57 -2
  25. package/dist/agent-runtime/src/messages.js.map +1 -1
  26. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +72 -3
  27. package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
  28. package/dist/agent-runtime/src/quota-safe-local-storage-session.js +73 -4
  29. package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
  30. package/dist/agent-runtime/src/statewire-transport.cjs +4 -13
  31. package/dist/agent-runtime/src/statewire-transport.cjs.map +1 -1
  32. package/dist/agent-runtime/src/statewire-transport.js +5 -14
  33. package/dist/agent-runtime/src/statewire-transport.js.map +1 -1
  34. package/dist/agent-runtime/src/tool-metadata.cjs +26 -7
  35. package/dist/agent-runtime/src/tool-metadata.cjs.map +1 -1
  36. package/dist/agent-runtime/src/tool-metadata.js +26 -7
  37. package/dist/agent-runtime/src/tool-metadata.js.map +1 -1
  38. package/dist/agent-runtime/src/use-deep-agent-config.cjs +117 -1
  39. package/dist/agent-runtime/src/use-deep-agent-config.cjs.map +1 -1
  40. package/dist/agent-runtime/src/use-deep-agent-config.js +118 -2
  41. package/dist/agent-runtime/src/use-deep-agent-config.js.map +1 -1
  42. package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
  43. package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
  44. package/dist/assets/AthenaAssetEmbed.cjs +9 -2
  45. package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
  46. package/dist/assets/AthenaAssetEmbed.d.ts +9 -0
  47. package/dist/assets/AthenaAssetEmbed.js +11 -4
  48. package/dist/assets/AthenaAssetEmbed.js.map +1 -1
  49. package/dist/assets/asset-embed-messages.cjs +6 -0
  50. package/dist/assets/asset-embed-messages.cjs.map +1 -1
  51. package/dist/assets/asset-embed-messages.d.ts +7 -0
  52. package/dist/assets/asset-embed-messages.js +6 -0
  53. package/dist/assets/asset-embed-messages.js.map +1 -1
  54. package/dist/assets/use-asset-embed.cjs +71 -71
  55. package/dist/assets/use-asset-embed.cjs.map +1 -1
  56. package/dist/assets/use-asset-embed.d.ts +20 -7
  57. package/dist/assets/use-asset-embed.js +72 -72
  58. package/dist/assets/use-asset-embed.js.map +1 -1
  59. package/dist/catalog/agent-model-options.cjs +122 -0
  60. package/dist/catalog/agent-model-options.cjs.map +1 -0
  61. package/dist/catalog/agent-model-options.d.ts +115 -0
  62. package/dist/catalog/agent-model-options.js +122 -0
  63. package/dist/catalog/agent-model-options.js.map +1 -0
  64. package/dist/catalog/chat-pickers.cjs +184 -4
  65. package/dist/catalog/chat-pickers.cjs.map +1 -1
  66. package/dist/catalog/chat-pickers.d.ts +27 -3
  67. package/dist/catalog/chat-pickers.js +187 -7
  68. package/dist/catalog/chat-pickers.js.map +1 -1
  69. package/dist/catalog/runtime-catalog.cjs +117 -3
  70. package/dist/catalog/runtime-catalog.cjs.map +1 -1
  71. package/dist/catalog/runtime-catalog.d.ts +104 -0
  72. package/dist/catalog/runtime-catalog.js +119 -5
  73. package/dist/catalog/runtime-catalog.js.map +1 -1
  74. package/dist/chat/AthenaChat.cjs +41 -26
  75. package/dist/chat/AthenaChat.cjs.map +1 -1
  76. package/dist/chat/AthenaChat.d.ts +8 -7
  77. package/dist/chat/AthenaChat.js +41 -26
  78. package/dist/chat/AthenaChat.js.map +1 -1
  79. package/dist/chat/super-grouping/SuperGroupingCard.cjs +61 -14
  80. package/dist/chat/super-grouping/SuperGroupingCard.cjs.map +1 -1
  81. package/dist/chat/super-grouping/SuperGroupingCard.d.ts +26 -12
  82. package/dist/chat/super-grouping/SuperGroupingCard.js +63 -16
  83. package/dist/chat/super-grouping/SuperGroupingCard.js.map +1 -1
  84. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs +80 -53
  85. package/dist/chat/super-grouping/SuperGroupingTranscript.cjs.map +1 -1
  86. package/dist/chat/super-grouping/SuperGroupingTranscript.d.ts +10 -10
  87. package/dist/chat/super-grouping/SuperGroupingTranscript.js +81 -54
  88. package/dist/chat/super-grouping/SuperGroupingTranscript.js.map +1 -1
  89. package/dist/chat/super-grouping/activity-timeline.cjs +19 -4
  90. package/dist/chat/super-grouping/activity-timeline.cjs.map +1 -1
  91. package/dist/chat/super-grouping/activity-timeline.d.ts +24 -5
  92. package/dist/chat/super-grouping/activity-timeline.js +19 -4
  93. package/dist/chat/super-grouping/activity-timeline.js.map +1 -1
  94. package/dist/chat/super-grouping/index.cjs +2 -0
  95. package/dist/chat/super-grouping/index.cjs.map +1 -1
  96. package/dist/chat/super-grouping/index.d.ts +7 -6
  97. package/dist/chat/super-grouping/index.js +3 -1
  98. package/dist/chat/super-grouping/toolkit-map.cjs +4 -1
  99. package/dist/chat/super-grouping/toolkit-map.cjs.map +1 -1
  100. package/dist/chat/super-grouping/toolkit-map.js +4 -1
  101. package/dist/chat/super-grouping/toolkit-map.js.map +1 -1
  102. package/dist/chat-ui/composer/tiptap-composer.cjs +40 -4
  103. package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
  104. package/dist/chat-ui/composer/tiptap-composer.js +40 -4
  105. package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
  106. package/dist/chat-ui/index.cjs +1 -0
  107. package/dist/chat-ui/index.cjs.map +1 -1
  108. package/dist/chat-ui/index.d.ts +1 -1
  109. package/dist/chat-ui/index.js +2 -1
  110. package/dist/chat-ui/mentions/mention-chip.cjs +29 -2
  111. package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
  112. package/dist/chat-ui/mentions/mention-chip.d.ts +2 -5
  113. package/dist/chat-ui/mentions/mention-chip.js +30 -3
  114. package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
  115. package/dist/chat-ui/mentions/mention-extension.cjs +1 -1
  116. package/dist/chat-ui/mentions/mention-extension.cjs.map +1 -1
  117. package/dist/chat-ui/mentions/mention-extension.js +1 -1
  118. package/dist/chat-ui/mentions/mention-extension.js.map +1 -1
  119. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +33 -2
  120. package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
  121. package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +14 -0
  122. package/dist/chat-ui/mentions/suggestions/data/api-client.js +33 -2
  123. package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
  124. package/dist/chat-ui/mentions/use-account-workspace-id.cjs +61 -0
  125. package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -0
  126. package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +3 -0
  127. package/dist/chat-ui/mentions/use-account-workspace-id.js +61 -0
  128. package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -0
  129. package/dist/chat-ui/mentions/use-member-avatar.cjs +75 -0
  130. package/dist/chat-ui/mentions/use-member-avatar.cjs.map +1 -0
  131. package/dist/chat-ui/mentions/use-member-avatar.d.ts +2 -0
  132. package/dist/chat-ui/mentions/use-member-avatar.js +75 -0
  133. package/dist/chat-ui/mentions/use-member-avatar.js.map +1 -0
  134. package/dist/collab/client.cjs +80 -19
  135. package/dist/collab/client.cjs.map +1 -1
  136. package/dist/collab/client.d.ts +22 -0
  137. package/dist/collab/client.js +80 -19
  138. package/dist/collab/client.js.map +1 -1
  139. package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
  140. package/dist/diagnostics/athena-diagnostics.d.ts +3 -1
  141. package/dist/diagnostics/athena-diagnostics.js.map +1 -1
  142. package/dist/index.cjs +5 -0
  143. package/dist/index.cjs.map +1 -1
  144. package/dist/index.d.ts +6 -3
  145. package/dist/index.js +7 -2
  146. package/dist/index.js.map +1 -1
  147. package/dist/lib/use-athena-rest-query.cjs +4 -0
  148. package/dist/lib/use-athena-rest-query.cjs.map +1 -1
  149. package/dist/lib/use-athena-rest-query.d.ts +6 -0
  150. package/dist/lib/use-athena-rest-query.js +4 -0
  151. package/dist/lib/use-athena-rest-query.js.map +1 -1
  152. package/dist/provider/AthenaProvider.cjs +57 -6
  153. package/dist/provider/AthenaProvider.cjs.map +1 -1
  154. package/dist/provider/AthenaProvider.d.ts +21 -5
  155. package/dist/provider/AthenaProvider.js +59 -8
  156. package/dist/provider/AthenaProvider.js.map +1 -1
  157. package/dist/provider/agent-selection-context.cjs +6 -0
  158. package/dist/provider/agent-selection-context.cjs.map +1 -0
  159. package/dist/provider/agent-selection-context.d.ts +14 -0
  160. package/dist/provider/agent-selection-context.js +6 -0
  161. package/dist/provider/agent-selection-context.js.map +1 -0
  162. package/dist/react/package.json.cjs +1 -1
  163. package/dist/react/package.json.js +1 -1
  164. package/dist/runtime/StatewireThreadConfigLaneSync.cjs +125 -0
  165. package/dist/runtime/StatewireThreadConfigLaneSync.cjs.map +1 -0
  166. package/dist/runtime/StatewireThreadConfigLaneSync.d.ts +54 -0
  167. package/dist/runtime/StatewireThreadConfigLaneSync.js +125 -0
  168. package/dist/runtime/StatewireThreadConfigLaneSync.js.map +1 -0
  169. package/dist/runtime/statewire-lifecycle.cjs +5 -2
  170. package/dist/runtime/statewire-lifecycle.cjs.map +1 -1
  171. package/dist/runtime/statewire-lifecycle.d.ts +5 -0
  172. package/dist/runtime/statewire-lifecycle.js +5 -2
  173. package/dist/runtime/statewire-lifecycle.js.map +1 -1
  174. package/dist/runtime/statewire-model-lane.cjs +16 -0
  175. package/dist/runtime/statewire-model-lane.cjs.map +1 -0
  176. package/dist/runtime/statewire-model-lane.d.ts +66 -0
  177. package/dist/runtime/statewire-model-lane.js +16 -0
  178. package/dist/runtime/statewire-model-lane.js.map +1 -0
  179. package/dist/runtime/statewire-run-config.cjs +16 -2
  180. package/dist/runtime/statewire-run-config.cjs.map +1 -1
  181. package/dist/runtime/statewire-run-config.d.ts +10 -0
  182. package/dist/runtime/statewire-run-config.js +16 -2
  183. package/dist/runtime/statewire-run-config.js.map +1 -1
  184. package/dist/runtime/statewire-server-lane-context.cjs +24 -0
  185. package/dist/runtime/statewire-server-lane-context.cjs.map +1 -0
  186. package/dist/runtime/statewire-server-lane-context.d.ts +30 -0
  187. package/dist/runtime/statewire-server-lane-context.js +24 -0
  188. package/dist/runtime/statewire-server-lane-context.js.map +1 -0
  189. package/dist/runtime/statewire-thread-config-lane.cjs +84 -0
  190. package/dist/runtime/statewire-thread-config-lane.cjs.map +1 -0
  191. package/dist/runtime/statewire-thread-config-lane.d.ts +94 -0
  192. package/dist/runtime/statewire-thread-config-lane.js +84 -0
  193. package/dist/runtime/statewire-thread-config-lane.js.map +1 -0
  194. package/dist/runtime/useAthenaStatewireRuntime.cjs +38 -18
  195. package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
  196. package/dist/runtime/useAthenaStatewireRuntime.d.ts +8 -1
  197. package/dist/runtime/useAthenaStatewireRuntime.js +39 -19
  198. package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
  199. package/dist/styles.css +1 -1
  200. package/dist/threads/api.cjs +2 -1
  201. package/dist/threads/api.cjs.map +1 -1
  202. package/dist/threads/api.d.ts +1 -0
  203. package/dist/threads/api.js +2 -1
  204. package/dist/threads/api.js.map +1 -1
  205. package/dist/threads/use-athena-thread-model.cjs +22 -0
  206. package/dist/threads/use-athena-thread-model.cjs.map +1 -0
  207. package/dist/threads/use-athena-thread-model.d.ts +27 -0
  208. package/dist/threads/use-athena-thread-model.js +22 -0
  209. package/dist/threads/use-athena-thread-model.js.map +1 -0
  210. package/package.json +4 -4
@@ -18,6 +18,7 @@ const AthenaAssetEmbed = ({
18
18
  reference,
19
19
  displayMode = useAssetEmbed.DEFAULT_ASSET_EMBED_DISPLAY_MODE,
20
20
  readOnly = useAssetEmbed.DEFAULT_ASSET_EMBED_READ_ONLY,
21
+ allowQuickEdit = useAssetEmbed.DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
21
22
  expiresInSeconds,
22
23
  citationBehavior,
23
24
  onCitationClick,
@@ -25,6 +26,7 @@ const AthenaAssetEmbed = ({
25
26
  onCitationAction,
26
27
  embedUrl: hostEmbedUrl,
27
28
  onReady,
29
+ onContentReady,
28
30
  onLoad,
29
31
  onError,
30
32
  loadingFallback,
@@ -46,7 +48,8 @@ const AthenaAssetEmbed = ({
46
48
  getToken: athenaConfig.getToken,
47
49
  readOnly,
48
50
  expiresInSeconds,
49
- displayMode
51
+ displayMode,
52
+ allowQuickEdit
50
53
  });
51
54
  const embedUrl = hostEmbedUrl ?? minted.embedUrl;
52
55
  const isLoading = hostEmbedUrl ? false : minted.isLoading;
@@ -95,6 +98,10 @@ const AthenaAssetEmbed = ({
95
98
  onReady == null ? void 0 : onReady();
96
99
  return;
97
100
  }
101
+ if (assetEmbedMessages.isAthenaAssetEmbedContentReadyEvent(event.data)) {
102
+ if (event.data.assetId === assetId) onContentReady == null ? void 0 : onContentReady();
103
+ return;
104
+ }
98
105
  if (assetEmbedMessages.isAthenaAssetCitationClickEvent(event.data)) {
99
106
  onCitationClick == null ? void 0 : onCitationClick(event.data);
100
107
  return;
@@ -105,7 +112,7 @@ const AthenaAssetEmbed = ({
105
112
  };
106
113
  window.addEventListener("message", handleMessage);
107
114
  return () => window.removeEventListener("message", handleMessage);
108
- }, [embedUrl, onCitationAction, onCitationClick, onReady, sendConfig, targetOrigin]);
115
+ }, [assetId, embedUrl, onCitationAction, onCitationClick, onReady, onContentReady, sendConfig, targetOrigin]);
109
116
  react.useEffect(() => {
110
117
  if (!embedUrl) return;
111
118
  sendConfig();
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaAssetEmbed.cjs","sources":["../../src/assets/AthenaAssetEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport { AlertCircle, Loader2 } from \"lucide-react\";\nimport { type CSSProperties, type FC, type IframeHTMLAttributes, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useAthenaConfig } from \"../provider/AthenaContext\";\nimport {\n ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n type AthenaAssetCitationActionEvent,\n type AthenaAssetCitationBehavior,\n type AthenaAssetCitationClickEvent,\n type AthenaAssetCitationReference,\n isAthenaAssetCitationActionEvent,\n isAthenaAssetCitationClickEvent,\n isAthenaAssetEmbedReadyEvent,\n resolveAthenaAssetCitationActionBehavior,\n resolveAthenaAssetCitationBehavior,\n} from \"./asset-embed-messages\";\nimport {\n buildSdkAssetEmbedUrl,\n DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n DEFAULT_ASSET_EMBED_READ_ONLY,\n useAssetEmbed,\n} from \"./use-asset-embed\";\n\nexport interface AthenaAssetEmbedProps extends Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n \"src\" | \"onError\" | \"onLoad\"\n> {\n assetId: string;\n /** Optional citation target to open inside the embedded asset, such as a PDF page. */\n reference?: AthenaAssetCitationReference;\n /** Defaults to the native full asset experience. */\n displayMode?: \"minimal\" | \"full\";\n /** Defaults to false so authorized users can edit the embedded asset. */\n readOnly?: boolean;\n expiresInSeconds?: number;\n citationBehavior?: AthenaAssetCitationBehavior;\n onCitationClick?: (event: AthenaAssetCitationClickEvent) => void;\n /** Controls the citation popover's actions, including the (+) Open in Spaces button. */\n citationActionBehavior?: AthenaAssetCitationBehavior;\n onCitationAction?: (event: AthenaAssetCitationActionEvent) => void;\n /**\n * An embed link the host minted itself (`POST /api/embed/generate-token`, its `/embed/<token>/`\n * page): the component shows it and mints none. Without it the component mints one with the\n * provider's credentials, as before.\n */\n embedUrl?: string;\n /** The embedded page said it is ready (its bridge's first message): Athena runs in the frame. */\n onReady?: () => void;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n loadingFallback?: React.ReactNode;\n errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);\n}\n\nconst DEFAULT_STYLE: CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n border: 0,\n};\nconst AUTH_SYNC_INTERVAL_MS = 60_000;\n\nexport const AthenaAssetEmbed: FC<AthenaAssetEmbedProps> = ({\n assetId,\n reference,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n expiresInSeconds,\n citationBehavior,\n onCitationClick,\n citationActionBehavior,\n onCitationAction,\n embedUrl: hostEmbedUrl,\n onReady,\n onLoad,\n onError,\n loadingFallback,\n errorFallback,\n className,\n style,\n title,\n allow = \"clipboard-read; clipboard-write; fullscreen\",\n ...iframeProps\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const athenaConfig = useAthenaConfig();\n const { backendUrl, appUrl, apiKey } = athenaConfig;\n // A link the host minted is shown as given; the hook then mints nothing (no asset to mint for).\n const minted = useAssetEmbed(hostEmbedUrl ? null : assetId, {\n backendUrl,\n appUrl,\n apiKey,\n token: athenaConfig.token,\n getToken: athenaConfig.getToken,\n readOnly,\n expiresInSeconds,\n displayMode,\n });\n const embedUrl = hostEmbedUrl ?? minted.embedUrl;\n const isLoading = hostEmbedUrl ? false : minted.isLoading;\n const error = hostEmbedUrl ? null : minted.error;\n const targetOrigin = useMemo(() => {\n if (!embedUrl) return null;\n try {\n return new URL(embedUrl, window.location.href).origin;\n } catch {\n return null;\n }\n }, [embedUrl]);\n const iframeSrc = useMemo(\n () => (embedUrl ? buildSdkAssetEmbedUrl(embedUrl, reference) : null),\n [embedUrl, reference],\n );\n const effectiveCitationBehavior = resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler: !!onCitationClick,\n });\n const effectiveCitationActionBehavior = resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler: !!onCitationAction,\n });\n\n const sendConfig = useCallback(() => {\n if (!targetOrigin) return;\n iframeRef.current?.contentWindow?.postMessage(\n {\n type: ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n version: 1,\n ...(athenaConfig.token ? { token: athenaConfig.token } : {}),\n citationBehavior: effectiveCitationBehavior,\n citationActionBehavior: effectiveCitationActionBehavior,\n },\n targetOrigin,\n );\n }, [athenaConfig, effectiveCitationActionBehavior, effectiveCitationBehavior, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl || !targetOrigin) return;\n const handleMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== targetOrigin || event.source !== iframeRef.current?.contentWindow) return;\n if (isAthenaAssetEmbedReadyEvent(event.data)) {\n sendConfig();\n onReady?.();\n return;\n }\n if (isAthenaAssetCitationClickEvent(event.data)) {\n onCitationClick?.(event.data);\n return;\n }\n if (isAthenaAssetCitationActionEvent(event.data)) {\n onCitationAction?.(event.data);\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [embedUrl, onCitationAction, onCitationClick, onReady, sendConfig, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl) return;\n sendConfig();\n const interval = window.setInterval(sendConfig, AUTH_SYNC_INTERVAL_MS);\n return () => window.clearInterval(interval);\n }, [embedUrl, sendConfig]);\n\n useEffect(() => {\n if (error) onError?.(new Error(error));\n }, [error, onError]);\n\n if (isLoading) {\n return (\n loadingFallback ?? (\n <output className=\"athena-sdk-chrome flex h-full w-full items-center justify-center\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n <span className=\"sr-only\">Loading asset</span>\n </output>\n )\n );\n }\n\n if (error) {\n const embedError = new Error(error);\n if (typeof errorFallback === \"function\") return errorFallback(embedError);\n return (\n errorFallback ?? (\n <div\n className=\"athena-sdk-chrome flex h-full w-full items-center justify-center gap-2 p-4 text-sm text-muted-foreground\"\n role=\"alert\"\n >\n <AlertCircle className=\"size-4 text-destructive\" />\n <span>{error}</span>\n </div>\n )\n );\n }\n\n if (!embedUrl) return null;\n\n return (\n <iframe\n {...iframeProps}\n ref={iframeRef}\n src={iframeSrc ?? undefined}\n title={title ?? `Athena asset ${assetId}`}\n allow={allow}\n className={cn(\"block h-full w-full\", className)}\n style={{ ...DEFAULT_STYLE, ...style }}\n onLoad={() => {\n sendConfig();\n onLoad?.();\n }}\n />\n );\n};\n"],"names":["DEFAULT_ASSET_EMBED_DISPLAY_MODE","DEFAULT_ASSET_EMBED_READ_ONLY","useRef","useAthenaConfig","useAssetEmbed","useMemo","buildSdkAssetEmbedUrl","resolveAthenaAssetCitationBehavior","resolveAthenaAssetCitationActionBehavior","useCallback","ATHENA_ASSET_EMBED_CONFIG_MESSAGE","useEffect","isAthenaAssetEmbedReadyEvent","isAthenaAssetCitationClickEvent","isAthenaAssetCitationActionEvent","jsxs","jsx","Loader2","AlertCircle","cn"],"mappings":"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"}
1
+ {"version":3,"file":"AthenaAssetEmbed.cjs","sources":["../../src/assets/AthenaAssetEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport { AlertCircle, Loader2 } from \"lucide-react\";\nimport { type CSSProperties, type FC, type IframeHTMLAttributes, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useAthenaConfig } from \"../provider/AthenaContext\";\nimport {\n ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n type AthenaAssetCitationActionEvent,\n type AthenaAssetCitationBehavior,\n type AthenaAssetCitationClickEvent,\n type AthenaAssetCitationReference,\n isAthenaAssetCitationActionEvent,\n isAthenaAssetCitationClickEvent,\n isAthenaAssetEmbedReadyEvent,\n isAthenaAssetEmbedContentReadyEvent,\n resolveAthenaAssetCitationActionBehavior,\n resolveAthenaAssetCitationBehavior,\n} from \"./asset-embed-messages\";\nimport {\n buildSdkAssetEmbedUrl,\n DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n DEFAULT_ASSET_EMBED_READ_ONLY,\n useAssetEmbed,\n} from \"./use-asset-embed\";\n\nexport interface AthenaAssetEmbedProps extends Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n \"src\" | \"onError\" | \"onLoad\"\n> {\n assetId: string;\n /** Optional citation target to open inside the embedded asset, such as a PDF page. */\n reference?: AthenaAssetCitationReference;\n /** Defaults to the native full asset experience. */\n displayMode?: \"minimal\" | \"full\";\n /** Defaults to false so authorized users can edit the embedded asset. */\n readOnly?: boolean;\n /**\n * Offer Quick Edit (⌘J) in a minimal embed (`displayMode=\"minimal\"`): spreadsheets and Word\n * documents, on an editable link (`readOnly: false`) only. Billed to the asset's workspace, with\n * an hourly cap per link; the full mode's editors offer it to the signed-in person already.\n * Defaults to false. Ignored with `embedUrl`: a link the host minted says itself.\n */\n allowQuickEdit?: boolean;\n expiresInSeconds?: number;\n citationBehavior?: AthenaAssetCitationBehavior;\n onCitationClick?: (event: AthenaAssetCitationClickEvent) => void;\n /** Controls the citation popover's actions, including the (+) Open in Spaces button. */\n citationActionBehavior?: AthenaAssetCitationBehavior;\n onCitationAction?: (event: AthenaAssetCitationActionEvent) => void;\n /**\n * An embed link the host minted itself (`POST /api/embed/generate-token`, its `/embed/<token>/`\n * page): the component shows it and mints none. Without it the component mints one with the\n * provider's credentials, as before.\n */\n embedUrl?: string;\n /** The embedded page said it is ready (its bridge's first message): Athena runs in the frame. */\n onReady?: () => void;\n /** The matching asset viewer has committed usable content in this frame. */\n onContentReady?: () => void;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n loadingFallback?: React.ReactNode;\n errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);\n}\n\nconst DEFAULT_STYLE: CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n border: 0,\n};\nconst AUTH_SYNC_INTERVAL_MS = 60_000;\n\nexport const AthenaAssetEmbed: FC<AthenaAssetEmbedProps> = ({\n assetId,\n reference,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n expiresInSeconds,\n citationBehavior,\n onCitationClick,\n citationActionBehavior,\n onCitationAction,\n embedUrl: hostEmbedUrl,\n onReady,\n onContentReady,\n onLoad,\n onError,\n loadingFallback,\n errorFallback,\n className,\n style,\n title,\n allow = \"clipboard-read; clipboard-write; fullscreen\",\n ...iframeProps\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const athenaConfig = useAthenaConfig();\n const { backendUrl, appUrl, apiKey } = athenaConfig;\n // A link the host minted is shown as given; the hook then mints nothing (no asset to mint for).\n const minted = useAssetEmbed(hostEmbedUrl ? null : assetId, {\n backendUrl,\n appUrl,\n apiKey,\n token: athenaConfig.token,\n getToken: athenaConfig.getToken,\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit,\n });\n const embedUrl = hostEmbedUrl ?? minted.embedUrl;\n const isLoading = hostEmbedUrl ? false : minted.isLoading;\n const error = hostEmbedUrl ? null : minted.error;\n const targetOrigin = useMemo(() => {\n if (!embedUrl) return null;\n try {\n return new URL(embedUrl, window.location.href).origin;\n } catch {\n return null;\n }\n }, [embedUrl]);\n const iframeSrc = useMemo(\n () => (embedUrl ? buildSdkAssetEmbedUrl(embedUrl, reference) : null),\n [embedUrl, reference],\n );\n const effectiveCitationBehavior = resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler: !!onCitationClick,\n });\n const effectiveCitationActionBehavior = resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler: !!onCitationAction,\n });\n\n const sendConfig = useCallback(() => {\n if (!targetOrigin) return;\n iframeRef.current?.contentWindow?.postMessage(\n {\n type: ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n version: 1,\n ...(athenaConfig.token ? { token: athenaConfig.token } : {}),\n citationBehavior: effectiveCitationBehavior,\n citationActionBehavior: effectiveCitationActionBehavior,\n },\n targetOrigin,\n );\n }, [athenaConfig, effectiveCitationActionBehavior, effectiveCitationBehavior, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl || !targetOrigin) return;\n const handleMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== targetOrigin || event.source !== iframeRef.current?.contentWindow) return;\n if (isAthenaAssetEmbedReadyEvent(event.data)) {\n sendConfig();\n onReady?.();\n return;\n }\n if (isAthenaAssetEmbedContentReadyEvent(event.data)) {\n if (event.data.assetId === assetId) onContentReady?.();\n return;\n }\n if (isAthenaAssetCitationClickEvent(event.data)) {\n onCitationClick?.(event.data);\n return;\n }\n if (isAthenaAssetCitationActionEvent(event.data)) {\n onCitationAction?.(event.data);\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [assetId, embedUrl, onCitationAction, onCitationClick, onReady, onContentReady, sendConfig, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl) return;\n sendConfig();\n const interval = window.setInterval(sendConfig, AUTH_SYNC_INTERVAL_MS);\n return () => window.clearInterval(interval);\n }, [embedUrl, sendConfig]);\n\n useEffect(() => {\n if (error) onError?.(new Error(error));\n }, [error, onError]);\n\n if (isLoading) {\n return (\n loadingFallback ?? (\n <output className=\"athena-sdk-chrome flex h-full w-full items-center justify-center\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n <span className=\"sr-only\">Loading asset</span>\n </output>\n )\n );\n }\n\n if (error) {\n const embedError = new Error(error);\n if (typeof errorFallback === \"function\") return errorFallback(embedError);\n return (\n errorFallback ?? (\n <div\n className=\"athena-sdk-chrome flex h-full w-full items-center justify-center gap-2 p-4 text-sm text-muted-foreground\"\n role=\"alert\"\n >\n <AlertCircle className=\"size-4 text-destructive\" />\n <span>{error}</span>\n </div>\n )\n );\n }\n\n if (!embedUrl) return null;\n\n return (\n <iframe\n {...iframeProps}\n ref={iframeRef}\n src={iframeSrc ?? undefined}\n title={title ?? `Athena asset ${assetId}`}\n allow={allow}\n className={cn(\"block h-full w-full\", className)}\n style={{ ...DEFAULT_STYLE, ...style }}\n onLoad={() => {\n sendConfig();\n onLoad?.();\n }}\n />\n );\n};\n"],"names":["DEFAULT_ASSET_EMBED_DISPLAY_MODE","DEFAULT_ASSET_EMBED_READ_ONLY","DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT","useRef","useAthenaConfig","useAssetEmbed","useMemo","buildSdkAssetEmbedUrl","resolveAthenaAssetCitationBehavior","resolveAthenaAssetCitationActionBehavior","useCallback","ATHENA_ASSET_EMBED_CONFIG_MESSAGE","useEffect","isAthenaAssetEmbedReadyEvent","isAthenaAssetEmbedContentReadyEvent","isAthenaAssetCitationClickEvent","isAthenaAssetCitationActionEvent","jsxs","jsx","Loader2","AlertCircle","cn"],"mappings":"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"}
@@ -8,6 +8,13 @@ export interface AthenaAssetEmbedProps extends Omit<IframeHTMLAttributes<HTMLIFr
8
8
  displayMode?: "minimal" | "full";
9
9
  /** Defaults to false so authorized users can edit the embedded asset. */
10
10
  readOnly?: boolean;
11
+ /**
12
+ * Offer Quick Edit (⌘J) in a minimal embed (`displayMode="minimal"`): spreadsheets and Word
13
+ * documents, on an editable link (`readOnly: false`) only. Billed to the asset's workspace, with
14
+ * an hourly cap per link; the full mode's editors offer it to the signed-in person already.
15
+ * Defaults to false. Ignored with `embedUrl`: a link the host minted says itself.
16
+ */
17
+ allowQuickEdit?: boolean;
11
18
  expiresInSeconds?: number;
12
19
  citationBehavior?: AthenaAssetCitationBehavior;
13
20
  onCitationClick?: (event: AthenaAssetCitationClickEvent) => void;
@@ -22,6 +29,8 @@ export interface AthenaAssetEmbedProps extends Omit<IframeHTMLAttributes<HTMLIFr
22
29
  embedUrl?: string;
23
30
  /** The embedded page said it is ready (its bridge's first message): Athena runs in the frame. */
24
31
  onReady?: () => void;
32
+ /** The matching asset viewer has committed usable content in this frame. */
33
+ onContentReady?: () => void;
25
34
  onLoad?: () => void;
26
35
  onError?: (error: Error) => void;
27
36
  loadingFallback?: React.ReactNode;
@@ -2,8 +2,8 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { Loader2, AlertCircle } from "lucide-react";
3
3
  import { useRef, useMemo, useCallback, useEffect } from "react";
4
4
  import { useAthenaConfig } from "../provider/AthenaContext.js";
5
- import { ATHENA_ASSET_EMBED_CONFIG_MESSAGE, resolveAthenaAssetCitationActionBehavior, resolveAthenaAssetCitationBehavior, isAthenaAssetEmbedReadyEvent, isAthenaAssetCitationClickEvent, isAthenaAssetCitationActionEvent } from "./asset-embed-messages.js";
6
- import { useAssetEmbed, buildSdkAssetEmbedUrl, DEFAULT_ASSET_EMBED_DISPLAY_MODE, DEFAULT_ASSET_EMBED_READ_ONLY } from "./use-asset-embed.js";
5
+ import { ATHENA_ASSET_EMBED_CONFIG_MESSAGE, resolveAthenaAssetCitationActionBehavior, resolveAthenaAssetCitationBehavior, isAthenaAssetEmbedReadyEvent, isAthenaAssetEmbedContentReadyEvent, isAthenaAssetCitationClickEvent, isAthenaAssetCitationActionEvent } from "./asset-embed-messages.js";
6
+ import { useAssetEmbed, buildSdkAssetEmbedUrl, DEFAULT_ASSET_EMBED_DISPLAY_MODE, DEFAULT_ASSET_EMBED_READ_ONLY, DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT } from "./use-asset-embed.js";
7
7
  import { cn } from "cnfast";
8
8
  const DEFAULT_STYLE = {
9
9
  width: "100%",
@@ -16,6 +16,7 @@ const AthenaAssetEmbed = ({
16
16
  reference,
17
17
  displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
18
18
  readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,
19
+ allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
19
20
  expiresInSeconds,
20
21
  citationBehavior,
21
22
  onCitationClick,
@@ -23,6 +24,7 @@ const AthenaAssetEmbed = ({
23
24
  onCitationAction,
24
25
  embedUrl: hostEmbedUrl,
25
26
  onReady,
27
+ onContentReady,
26
28
  onLoad,
27
29
  onError,
28
30
  loadingFallback,
@@ -44,7 +46,8 @@ const AthenaAssetEmbed = ({
44
46
  getToken: athenaConfig.getToken,
45
47
  readOnly,
46
48
  expiresInSeconds,
47
- displayMode
49
+ displayMode,
50
+ allowQuickEdit
48
51
  });
49
52
  const embedUrl = hostEmbedUrl ?? minted.embedUrl;
50
53
  const isLoading = hostEmbedUrl ? false : minted.isLoading;
@@ -93,6 +96,10 @@ const AthenaAssetEmbed = ({
93
96
  onReady == null ? void 0 : onReady();
94
97
  return;
95
98
  }
99
+ if (isAthenaAssetEmbedContentReadyEvent(event.data)) {
100
+ if (event.data.assetId === assetId) onContentReady == null ? void 0 : onContentReady();
101
+ return;
102
+ }
96
103
  if (isAthenaAssetCitationClickEvent(event.data)) {
97
104
  onCitationClick == null ? void 0 : onCitationClick(event.data);
98
105
  return;
@@ -103,7 +110,7 @@ const AthenaAssetEmbed = ({
103
110
  };
104
111
  window.addEventListener("message", handleMessage);
105
112
  return () => window.removeEventListener("message", handleMessage);
106
- }, [embedUrl, onCitationAction, onCitationClick, onReady, sendConfig, targetOrigin]);
113
+ }, [assetId, embedUrl, onCitationAction, onCitationClick, onReady, onContentReady, sendConfig, targetOrigin]);
107
114
  useEffect(() => {
108
115
  if (!embedUrl) return;
109
116
  sendConfig();
@@ -1 +1 @@
1
- {"version":3,"file":"AthenaAssetEmbed.js","sources":["../../src/assets/AthenaAssetEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport { AlertCircle, Loader2 } from \"lucide-react\";\nimport { type CSSProperties, type FC, type IframeHTMLAttributes, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useAthenaConfig } from \"../provider/AthenaContext\";\nimport {\n ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n type AthenaAssetCitationActionEvent,\n type AthenaAssetCitationBehavior,\n type AthenaAssetCitationClickEvent,\n type AthenaAssetCitationReference,\n isAthenaAssetCitationActionEvent,\n isAthenaAssetCitationClickEvent,\n isAthenaAssetEmbedReadyEvent,\n resolveAthenaAssetCitationActionBehavior,\n resolveAthenaAssetCitationBehavior,\n} from \"./asset-embed-messages\";\nimport {\n buildSdkAssetEmbedUrl,\n DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n DEFAULT_ASSET_EMBED_READ_ONLY,\n useAssetEmbed,\n} from \"./use-asset-embed\";\n\nexport interface AthenaAssetEmbedProps extends Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n \"src\" | \"onError\" | \"onLoad\"\n> {\n assetId: string;\n /** Optional citation target to open inside the embedded asset, such as a PDF page. */\n reference?: AthenaAssetCitationReference;\n /** Defaults to the native full asset experience. */\n displayMode?: \"minimal\" | \"full\";\n /** Defaults to false so authorized users can edit the embedded asset. */\n readOnly?: boolean;\n expiresInSeconds?: number;\n citationBehavior?: AthenaAssetCitationBehavior;\n onCitationClick?: (event: AthenaAssetCitationClickEvent) => void;\n /** Controls the citation popover's actions, including the (+) Open in Spaces button. */\n citationActionBehavior?: AthenaAssetCitationBehavior;\n onCitationAction?: (event: AthenaAssetCitationActionEvent) => void;\n /**\n * An embed link the host minted itself (`POST /api/embed/generate-token`, its `/embed/<token>/`\n * page): the component shows it and mints none. Without it the component mints one with the\n * provider's credentials, as before.\n */\n embedUrl?: string;\n /** The embedded page said it is ready (its bridge's first message): Athena runs in the frame. */\n onReady?: () => void;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n loadingFallback?: React.ReactNode;\n errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);\n}\n\nconst DEFAULT_STYLE: CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n border: 0,\n};\nconst AUTH_SYNC_INTERVAL_MS = 60_000;\n\nexport const AthenaAssetEmbed: FC<AthenaAssetEmbedProps> = ({\n assetId,\n reference,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n expiresInSeconds,\n citationBehavior,\n onCitationClick,\n citationActionBehavior,\n onCitationAction,\n embedUrl: hostEmbedUrl,\n onReady,\n onLoad,\n onError,\n loadingFallback,\n errorFallback,\n className,\n style,\n title,\n allow = \"clipboard-read; clipboard-write; fullscreen\",\n ...iframeProps\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const athenaConfig = useAthenaConfig();\n const { backendUrl, appUrl, apiKey } = athenaConfig;\n // A link the host minted is shown as given; the hook then mints nothing (no asset to mint for).\n const minted = useAssetEmbed(hostEmbedUrl ? null : assetId, {\n backendUrl,\n appUrl,\n apiKey,\n token: athenaConfig.token,\n getToken: athenaConfig.getToken,\n readOnly,\n expiresInSeconds,\n displayMode,\n });\n const embedUrl = hostEmbedUrl ?? minted.embedUrl;\n const isLoading = hostEmbedUrl ? false : minted.isLoading;\n const error = hostEmbedUrl ? null : minted.error;\n const targetOrigin = useMemo(() => {\n if (!embedUrl) return null;\n try {\n return new URL(embedUrl, window.location.href).origin;\n } catch {\n return null;\n }\n }, [embedUrl]);\n const iframeSrc = useMemo(\n () => (embedUrl ? buildSdkAssetEmbedUrl(embedUrl, reference) : null),\n [embedUrl, reference],\n );\n const effectiveCitationBehavior = resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler: !!onCitationClick,\n });\n const effectiveCitationActionBehavior = resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler: !!onCitationAction,\n });\n\n const sendConfig = useCallback(() => {\n if (!targetOrigin) return;\n iframeRef.current?.contentWindow?.postMessage(\n {\n type: ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n version: 1,\n ...(athenaConfig.token ? { token: athenaConfig.token } : {}),\n citationBehavior: effectiveCitationBehavior,\n citationActionBehavior: effectiveCitationActionBehavior,\n },\n targetOrigin,\n );\n }, [athenaConfig, effectiveCitationActionBehavior, effectiveCitationBehavior, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl || !targetOrigin) return;\n const handleMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== targetOrigin || event.source !== iframeRef.current?.contentWindow) return;\n if (isAthenaAssetEmbedReadyEvent(event.data)) {\n sendConfig();\n onReady?.();\n return;\n }\n if (isAthenaAssetCitationClickEvent(event.data)) {\n onCitationClick?.(event.data);\n return;\n }\n if (isAthenaAssetCitationActionEvent(event.data)) {\n onCitationAction?.(event.data);\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [embedUrl, onCitationAction, onCitationClick, onReady, sendConfig, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl) return;\n sendConfig();\n const interval = window.setInterval(sendConfig, AUTH_SYNC_INTERVAL_MS);\n return () => window.clearInterval(interval);\n }, [embedUrl, sendConfig]);\n\n useEffect(() => {\n if (error) onError?.(new Error(error));\n }, [error, onError]);\n\n if (isLoading) {\n return (\n loadingFallback ?? (\n <output className=\"athena-sdk-chrome flex h-full w-full items-center justify-center\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n <span className=\"sr-only\">Loading asset</span>\n </output>\n )\n );\n }\n\n if (error) {\n const embedError = new Error(error);\n if (typeof errorFallback === \"function\") return errorFallback(embedError);\n return (\n errorFallback ?? (\n <div\n className=\"athena-sdk-chrome flex h-full w-full items-center justify-center gap-2 p-4 text-sm text-muted-foreground\"\n role=\"alert\"\n >\n <AlertCircle className=\"size-4 text-destructive\" />\n <span>{error}</span>\n </div>\n )\n );\n }\n\n if (!embedUrl) return null;\n\n return (\n <iframe\n {...iframeProps}\n ref={iframeRef}\n src={iframeSrc ?? undefined}\n title={title ?? `Athena asset ${assetId}`}\n allow={allow}\n className={cn(\"block h-full w-full\", className)}\n style={{ ...DEFAULT_STYLE, ...style }}\n onLoad={() => {\n sendConfig();\n onLoad?.();\n }}\n />\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AthenaAssetEmbed.js","sources":["../../src/assets/AthenaAssetEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport { AlertCircle, Loader2 } from \"lucide-react\";\nimport { type CSSProperties, type FC, type IframeHTMLAttributes, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useAthenaConfig } from \"../provider/AthenaContext\";\nimport {\n ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n type AthenaAssetCitationActionEvent,\n type AthenaAssetCitationBehavior,\n type AthenaAssetCitationClickEvent,\n type AthenaAssetCitationReference,\n isAthenaAssetCitationActionEvent,\n isAthenaAssetCitationClickEvent,\n isAthenaAssetEmbedReadyEvent,\n isAthenaAssetEmbedContentReadyEvent,\n resolveAthenaAssetCitationActionBehavior,\n resolveAthenaAssetCitationBehavior,\n} from \"./asset-embed-messages\";\nimport {\n buildSdkAssetEmbedUrl,\n DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n DEFAULT_ASSET_EMBED_READ_ONLY,\n useAssetEmbed,\n} from \"./use-asset-embed\";\n\nexport interface AthenaAssetEmbedProps extends Omit<\n IframeHTMLAttributes<HTMLIFrameElement>,\n \"src\" | \"onError\" | \"onLoad\"\n> {\n assetId: string;\n /** Optional citation target to open inside the embedded asset, such as a PDF page. */\n reference?: AthenaAssetCitationReference;\n /** Defaults to the native full asset experience. */\n displayMode?: \"minimal\" | \"full\";\n /** Defaults to false so authorized users can edit the embedded asset. */\n readOnly?: boolean;\n /**\n * Offer Quick Edit (⌘J) in a minimal embed (`displayMode=\"minimal\"`): spreadsheets and Word\n * documents, on an editable link (`readOnly: false`) only. Billed to the asset's workspace, with\n * an hourly cap per link; the full mode's editors offer it to the signed-in person already.\n * Defaults to false. Ignored with `embedUrl`: a link the host minted says itself.\n */\n allowQuickEdit?: boolean;\n expiresInSeconds?: number;\n citationBehavior?: AthenaAssetCitationBehavior;\n onCitationClick?: (event: AthenaAssetCitationClickEvent) => void;\n /** Controls the citation popover's actions, including the (+) Open in Spaces button. */\n citationActionBehavior?: AthenaAssetCitationBehavior;\n onCitationAction?: (event: AthenaAssetCitationActionEvent) => void;\n /**\n * An embed link the host minted itself (`POST /api/embed/generate-token`, its `/embed/<token>/`\n * page): the component shows it and mints none. Without it the component mints one with the\n * provider's credentials, as before.\n */\n embedUrl?: string;\n /** The embedded page said it is ready (its bridge's first message): Athena runs in the frame. */\n onReady?: () => void;\n /** The matching asset viewer has committed usable content in this frame. */\n onContentReady?: () => void;\n onLoad?: () => void;\n onError?: (error: Error) => void;\n loadingFallback?: React.ReactNode;\n errorFallback?: React.ReactNode | ((error: Error) => React.ReactNode);\n}\n\nconst DEFAULT_STYLE: CSSProperties = {\n width: \"100%\",\n height: \"100%\",\n border: 0,\n};\nconst AUTH_SYNC_INTERVAL_MS = 60_000;\n\nexport const AthenaAssetEmbed: FC<AthenaAssetEmbedProps> = ({\n assetId,\n reference,\n displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,\n readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,\n allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,\n expiresInSeconds,\n citationBehavior,\n onCitationClick,\n citationActionBehavior,\n onCitationAction,\n embedUrl: hostEmbedUrl,\n onReady,\n onContentReady,\n onLoad,\n onError,\n loadingFallback,\n errorFallback,\n className,\n style,\n title,\n allow = \"clipboard-read; clipboard-write; fullscreen\",\n ...iframeProps\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const athenaConfig = useAthenaConfig();\n const { backendUrl, appUrl, apiKey } = athenaConfig;\n // A link the host minted is shown as given; the hook then mints nothing (no asset to mint for).\n const minted = useAssetEmbed(hostEmbedUrl ? null : assetId, {\n backendUrl,\n appUrl,\n apiKey,\n token: athenaConfig.token,\n getToken: athenaConfig.getToken,\n readOnly,\n expiresInSeconds,\n displayMode,\n allowQuickEdit,\n });\n const embedUrl = hostEmbedUrl ?? minted.embedUrl;\n const isLoading = hostEmbedUrl ? false : minted.isLoading;\n const error = hostEmbedUrl ? null : minted.error;\n const targetOrigin = useMemo(() => {\n if (!embedUrl) return null;\n try {\n return new URL(embedUrl, window.location.href).origin;\n } catch {\n return null;\n }\n }, [embedUrl]);\n const iframeSrc = useMemo(\n () => (embedUrl ? buildSdkAssetEmbedUrl(embedUrl, reference) : null),\n [embedUrl, reference],\n );\n const effectiveCitationBehavior = resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler: !!onCitationClick,\n });\n const effectiveCitationActionBehavior = resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler: !!onCitationAction,\n });\n\n const sendConfig = useCallback(() => {\n if (!targetOrigin) return;\n iframeRef.current?.contentWindow?.postMessage(\n {\n type: ATHENA_ASSET_EMBED_CONFIG_MESSAGE,\n version: 1,\n ...(athenaConfig.token ? { token: athenaConfig.token } : {}),\n citationBehavior: effectiveCitationBehavior,\n citationActionBehavior: effectiveCitationActionBehavior,\n },\n targetOrigin,\n );\n }, [athenaConfig, effectiveCitationActionBehavior, effectiveCitationBehavior, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl || !targetOrigin) return;\n const handleMessage = (event: MessageEvent<unknown>) => {\n if (event.origin !== targetOrigin || event.source !== iframeRef.current?.contentWindow) return;\n if (isAthenaAssetEmbedReadyEvent(event.data)) {\n sendConfig();\n onReady?.();\n return;\n }\n if (isAthenaAssetEmbedContentReadyEvent(event.data)) {\n if (event.data.assetId === assetId) onContentReady?.();\n return;\n }\n if (isAthenaAssetCitationClickEvent(event.data)) {\n onCitationClick?.(event.data);\n return;\n }\n if (isAthenaAssetCitationActionEvent(event.data)) {\n onCitationAction?.(event.data);\n }\n };\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [assetId, embedUrl, onCitationAction, onCitationClick, onReady, onContentReady, sendConfig, targetOrigin]);\n\n useEffect(() => {\n if (!embedUrl) return;\n sendConfig();\n const interval = window.setInterval(sendConfig, AUTH_SYNC_INTERVAL_MS);\n return () => window.clearInterval(interval);\n }, [embedUrl, sendConfig]);\n\n useEffect(() => {\n if (error) onError?.(new Error(error));\n }, [error, onError]);\n\n if (isLoading) {\n return (\n loadingFallback ?? (\n <output className=\"athena-sdk-chrome flex h-full w-full items-center justify-center\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n <span className=\"sr-only\">Loading asset</span>\n </output>\n )\n );\n }\n\n if (error) {\n const embedError = new Error(error);\n if (typeof errorFallback === \"function\") return errorFallback(embedError);\n return (\n errorFallback ?? (\n <div\n className=\"athena-sdk-chrome flex h-full w-full items-center justify-center gap-2 p-4 text-sm text-muted-foreground\"\n role=\"alert\"\n >\n <AlertCircle className=\"size-4 text-destructive\" />\n <span>{error}</span>\n </div>\n )\n );\n }\n\n if (!embedUrl) return null;\n\n return (\n <iframe\n {...iframeProps}\n ref={iframeRef}\n src={iframeSrc ?? undefined}\n title={title ?? `Athena asset ${assetId}`}\n allow={allow}\n className={cn(\"block h-full w-full\", className)}\n style={{ ...DEFAULT_STYLE, ...style }}\n onLoad={() => {\n sendConfig();\n onLoad?.();\n }}\n />\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const ATHENA_ASSET_EMBED_READY_MESSAGE = "athena:asset-embed-ready";
4
+ const ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE = "athena:asset-embed-content-ready";
4
5
  const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = "athena:asset-embed-config";
5
6
  const ATHENA_ASSET_CITATION_CLICK_MESSAGE = "athena:asset-citation-click";
6
7
  const ATHENA_ASSET_CITATION_ACTION_MESSAGE = "athena:asset-citation-action";
@@ -27,12 +28,17 @@ function isAthenaAssetCitationClickEvent(value) {
27
28
  function isAthenaAssetCitationActionEvent(value) {
28
29
  return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE && "version" in value && value.version === 1 && "action" in value && value.action === "open-in-spaces" && "reference" in value && typeof value.reference === "object" && value.reference !== null && "id" in value.reference && typeof value.reference.id === "string";
29
30
  }
31
+ function isAthenaAssetEmbedContentReadyEvent(value) {
32
+ return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE && "version" in value && value.version === 1 && "assetId" in value && typeof value.assetId === "string" && value.assetId.length > 0;
33
+ }
30
34
  exports.ATHENA_ASSET_CITATION_ACTION_MESSAGE = ATHENA_ASSET_CITATION_ACTION_MESSAGE;
31
35
  exports.ATHENA_ASSET_CITATION_CLICK_MESSAGE = ATHENA_ASSET_CITATION_CLICK_MESSAGE;
32
36
  exports.ATHENA_ASSET_EMBED_CONFIG_MESSAGE = ATHENA_ASSET_EMBED_CONFIG_MESSAGE;
37
+ exports.ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE = ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE;
33
38
  exports.ATHENA_ASSET_EMBED_READY_MESSAGE = ATHENA_ASSET_EMBED_READY_MESSAGE;
34
39
  exports.isAthenaAssetCitationActionEvent = isAthenaAssetCitationActionEvent;
35
40
  exports.isAthenaAssetCitationClickEvent = isAthenaAssetCitationClickEvent;
41
+ exports.isAthenaAssetEmbedContentReadyEvent = isAthenaAssetEmbedContentReadyEvent;
36
42
  exports.isAthenaAssetEmbedReadyEvent = isAthenaAssetEmbedReadyEvent;
37
43
  exports.resolveAthenaAssetCitationActionBehavior = resolveAthenaAssetCitationActionBehavior;
38
44
  exports.resolveAthenaAssetCitationBehavior = resolveAthenaAssetCitationBehavior;
@@ -1 +1 @@
1
- {"version":3,"file":"asset-embed-messages.cjs","sources":["../../src/assets/asset-embed-messages.ts"],"sourcesContent":["export const ATHENA_ASSET_EMBED_READY_MESSAGE = \"athena:asset-embed-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = \"athena:asset-embed-config\" as const;\nexport const ATHENA_ASSET_CITATION_CLICK_MESSAGE = \"athena:asset-citation-click\" as const;\nexport const ATHENA_ASSET_CITATION_ACTION_MESSAGE = \"athena:asset-citation-action\" as const;\n\nexport type AthenaAssetCitationBehavior = \"browser\" | \"host\";\nexport type AthenaAssetCitationAction = \"open-in-spaces\";\n\nexport interface AthenaAssetCitationReference {\n id: string;\n /**\n * Where in the asset the citation points. Either the anchor's raw query string as Athena links,\n * citations and search results carry it (`anchor=slide&slide_index=3`, `anchor=time&time=0:42`,\n * `asset_x?anchor=pm_node&node_id=…`), which an embed receives as written whatever kind of\n * place it names, or a typed page or sheet anchor (`{ type: 'page', page: 34 }`).\n */\n anchor?: unknown;\n meta?: Record<string, unknown>;\n}\n\nexport interface AthenaAssetCitationClickEvent {\n type: typeof ATHENA_ASSET_CITATION_CLICK_MESSAGE;\n version: 1;\n sourceAssetId?: string;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetCitationActionEvent {\n type: typeof ATHENA_ASSET_CITATION_ACTION_MESSAGE;\n version: 1;\n action: AthenaAssetCitationAction;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetEmbedReadyEvent {\n type: typeof ATHENA_ASSET_EMBED_READY_MESSAGE;\n version: 1;\n}\n\nexport interface AthenaAssetEmbedConfigEvent {\n type: typeof ATHENA_ASSET_EMBED_CONFIG_MESSAGE;\n version: 1;\n token?: string;\n citationBehavior: AthenaAssetCitationBehavior;\n citationActionBehavior?: AthenaAssetCitationBehavior;\n}\n\nexport function resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler,\n}: {\n citationBehavior?: AthenaAssetCitationBehavior;\n hasCitationClickHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationBehavior === \"host\" && !hasCitationClickHandler) return \"browser\";\n return citationBehavior ?? (hasCitationClickHandler ? \"host\" : \"browser\");\n}\n\nexport function resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler,\n}: {\n citationActionBehavior?: AthenaAssetCitationBehavior;\n hasCitationActionHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationActionBehavior === \"host\" && !hasCitationActionHandler) return \"browser\";\n return citationActionBehavior ?? (hasCitationActionHandler ? \"host\" : \"browser\");\n}\n\nexport function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1\n );\n}\n\nexport function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_CLICK_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\nexport function isAthenaAssetCitationActionEvent(value: unknown): value is AthenaAssetCitationActionEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"action\" in value &&\n value.action === \"open-in-spaces\" &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n"],"names":[],"mappings":";;AAAO,MAAM,mCAAmC;AACzC,MAAM,oCAAoC;AAC1C,MAAM,sCAAsC;AAC5C,MAAM,uCAAuC;AA4C7C,SAAS,mCAAmC;AAAA,EACjD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,qBAAqB,UAAU,CAAC,wBAAyB,QAAO;AACpE,SAAO,qBAAqB,0BAA0B,SAAS;AACjE;AAEO,SAAS,yCAAyC;AAAA,EACvD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,2BAA2B,UAAU,CAAC,yBAA0B,QAAO;AAC3E,SAAO,2BAA2B,2BAA2B,SAAS;AACxE;AAEO,SAAS,6BAA6B,OAAqD;AAChG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,oCACf,aAAa,SACb,MAAM,YAAY;AAEtB;AAEO,SAAS,gCAAgC,OAAwD;AACtG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,uCACf,aAAa,SACb,MAAM,YAAY,KAClB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAEO,SAAS,iCAAiC,OAAyD;AACxG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,wCACf,aAAa,SACb,MAAM,YAAY,KAClB,YAAY,SACZ,MAAM,WAAW,oBACjB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;;;;;;;;;;"}
1
+ {"version":3,"file":"asset-embed-messages.cjs","sources":["../../src/assets/asset-embed-messages.ts"],"sourcesContent":["export const ATHENA_ASSET_EMBED_READY_MESSAGE = \"athena:asset-embed-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE = \"athena:asset-embed-content-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = \"athena:asset-embed-config\" as const;\nexport const ATHENA_ASSET_CITATION_CLICK_MESSAGE = \"athena:asset-citation-click\" as const;\nexport const ATHENA_ASSET_CITATION_ACTION_MESSAGE = \"athena:asset-citation-action\" as const;\n\nexport type AthenaAssetCitationBehavior = \"browser\" | \"host\";\nexport type AthenaAssetCitationAction = \"open-in-spaces\";\n\nexport interface AthenaAssetCitationReference {\n id: string;\n /**\n * Where in the asset the citation points. Either the anchor's raw query string as Athena links,\n * citations and search results carry it (`anchor=slide&slide_index=3`, `anchor=time&time=0:42`,\n * `asset_x?anchor=pm_node&node_id=…`), which an embed receives as written whatever kind of\n * place it names, or a typed page or sheet anchor (`{ type: 'page', page: 34 }`).\n */\n anchor?: unknown;\n meta?: Record<string, unknown>;\n}\n\nexport interface AthenaAssetCitationClickEvent {\n type: typeof ATHENA_ASSET_CITATION_CLICK_MESSAGE;\n version: 1;\n sourceAssetId?: string;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetCitationActionEvent {\n type: typeof ATHENA_ASSET_CITATION_ACTION_MESSAGE;\n version: 1;\n action: AthenaAssetCitationAction;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetEmbedReadyEvent {\n type: typeof ATHENA_ASSET_EMBED_READY_MESSAGE;\n version: 1;\n}\n\nexport interface AthenaAssetEmbedConfigEvent {\n type: typeof ATHENA_ASSET_EMBED_CONFIG_MESSAGE;\n version: 1;\n token?: string;\n citationBehavior: AthenaAssetCitationBehavior;\n citationActionBehavior?: AthenaAssetCitationBehavior;\n}\n\nexport function resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler,\n}: {\n citationBehavior?: AthenaAssetCitationBehavior;\n hasCitationClickHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationBehavior === \"host\" && !hasCitationClickHandler) return \"browser\";\n return citationBehavior ?? (hasCitationClickHandler ? \"host\" : \"browser\");\n}\n\nexport function resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler,\n}: {\n citationActionBehavior?: AthenaAssetCitationBehavior;\n hasCitationActionHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationActionBehavior === \"host\" && !hasCitationActionHandler) return \"browser\";\n return citationActionBehavior ?? (hasCitationActionHandler ? \"host\" : \"browser\");\n}\n\nexport function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1\n );\n}\n\nexport function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_CLICK_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\nexport function isAthenaAssetCitationActionEvent(value: unknown): value is AthenaAssetCitationActionEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"action\" in value &&\n value.action === \"open-in-spaces\" &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\n/** Content has rendered; bootstrap and iframe load events do not prove an asset opened. */\nexport function isAthenaAssetEmbedContentReadyEvent(value: unknown): value is {\n type: typeof ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE;\n version: 1;\n assetId: string;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"assetId\" in value &&\n typeof value.assetId === \"string\" &&\n value.assetId.length > 0\n );\n}\n"],"names":[],"mappings":";;AAAO,MAAM,mCAAmC;AACzC,MAAM,2CAA2C;AACjD,MAAM,oCAAoC;AAC1C,MAAM,sCAAsC;AAC5C,MAAM,uCAAuC;AA4C7C,SAAS,mCAAmC;AAAA,EACjD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,qBAAqB,UAAU,CAAC,wBAAyB,QAAO;AACpE,SAAO,qBAAqB,0BAA0B,SAAS;AACjE;AAEO,SAAS,yCAAyC;AAAA,EACvD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,2BAA2B,UAAU,CAAC,yBAA0B,QAAO;AAC3E,SAAO,2BAA2B,2BAA2B,SAAS;AACxE;AAEO,SAAS,6BAA6B,OAAqD;AAChG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,oCACf,aAAa,SACb,MAAM,YAAY;AAEtB;AAEO,SAAS,gCAAgC,OAAwD;AACtG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,uCACf,aAAa,SACb,MAAM,YAAY,KAClB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAEO,SAAS,iCAAiC,OAAyD;AACxG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,wCACf,aAAa,SACb,MAAM,YAAY,KAClB,YAAY,SACZ,MAAM,WAAW,oBACjB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAGO,SAAS,oCAAoC,OAIlD;AACA,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,4CACf,aAAa,SACb,MAAM,YAAY,KAClB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,MAAM,QAAQ,SAAS;AAE3B;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  export declare const ATHENA_ASSET_EMBED_READY_MESSAGE: "athena:asset-embed-ready";
2
+ export declare const ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE: "athena:asset-embed-content-ready";
2
3
  export declare const ATHENA_ASSET_EMBED_CONFIG_MESSAGE: "athena:asset-embed-config";
3
4
  export declare const ATHENA_ASSET_CITATION_CLICK_MESSAGE: "athena:asset-citation-click";
4
5
  export declare const ATHENA_ASSET_CITATION_ACTION_MESSAGE: "athena:asset-citation-action";
@@ -49,3 +50,9 @@ export declare function resolveAthenaAssetCitationActionBehavior({ citationActio
49
50
  export declare function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent;
50
51
  export declare function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent;
51
52
  export declare function isAthenaAssetCitationActionEvent(value: unknown): value is AthenaAssetCitationActionEvent;
53
+ /** Content has rendered; bootstrap and iframe load events do not prove an asset opened. */
54
+ export declare function isAthenaAssetEmbedContentReadyEvent(value: unknown): value is {
55
+ type: typeof ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE;
56
+ version: 1;
57
+ assetId: string;
58
+ };
@@ -1,4 +1,5 @@
1
1
  const ATHENA_ASSET_EMBED_READY_MESSAGE = "athena:asset-embed-ready";
2
+ const ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE = "athena:asset-embed-content-ready";
2
3
  const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = "athena:asset-embed-config";
3
4
  const ATHENA_ASSET_CITATION_CLICK_MESSAGE = "athena:asset-citation-click";
4
5
  const ATHENA_ASSET_CITATION_ACTION_MESSAGE = "athena:asset-citation-action";
@@ -25,13 +26,18 @@ function isAthenaAssetCitationClickEvent(value) {
25
26
  function isAthenaAssetCitationActionEvent(value) {
26
27
  return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE && "version" in value && value.version === 1 && "action" in value && value.action === "open-in-spaces" && "reference" in value && typeof value.reference === "object" && value.reference !== null && "id" in value.reference && typeof value.reference.id === "string";
27
28
  }
29
+ function isAthenaAssetEmbedContentReadyEvent(value) {
30
+ return typeof value === "object" && value !== null && "type" in value && value.type === ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE && "version" in value && value.version === 1 && "assetId" in value && typeof value.assetId === "string" && value.assetId.length > 0;
31
+ }
28
32
  export {
29
33
  ATHENA_ASSET_CITATION_ACTION_MESSAGE,
30
34
  ATHENA_ASSET_CITATION_CLICK_MESSAGE,
31
35
  ATHENA_ASSET_EMBED_CONFIG_MESSAGE,
36
+ ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE,
32
37
  ATHENA_ASSET_EMBED_READY_MESSAGE,
33
38
  isAthenaAssetCitationActionEvent,
34
39
  isAthenaAssetCitationClickEvent,
40
+ isAthenaAssetEmbedContentReadyEvent,
35
41
  isAthenaAssetEmbedReadyEvent,
36
42
  resolveAthenaAssetCitationActionBehavior,
37
43
  resolveAthenaAssetCitationBehavior
@@ -1 +1 @@
1
- {"version":3,"file":"asset-embed-messages.js","sources":["../../src/assets/asset-embed-messages.ts"],"sourcesContent":["export const ATHENA_ASSET_EMBED_READY_MESSAGE = \"athena:asset-embed-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = \"athena:asset-embed-config\" as const;\nexport const ATHENA_ASSET_CITATION_CLICK_MESSAGE = \"athena:asset-citation-click\" as const;\nexport const ATHENA_ASSET_CITATION_ACTION_MESSAGE = \"athena:asset-citation-action\" as const;\n\nexport type AthenaAssetCitationBehavior = \"browser\" | \"host\";\nexport type AthenaAssetCitationAction = \"open-in-spaces\";\n\nexport interface AthenaAssetCitationReference {\n id: string;\n /**\n * Where in the asset the citation points. Either the anchor's raw query string as Athena links,\n * citations and search results carry it (`anchor=slide&slide_index=3`, `anchor=time&time=0:42`,\n * `asset_x?anchor=pm_node&node_id=…`), which an embed receives as written whatever kind of\n * place it names, or a typed page or sheet anchor (`{ type: 'page', page: 34 }`).\n */\n anchor?: unknown;\n meta?: Record<string, unknown>;\n}\n\nexport interface AthenaAssetCitationClickEvent {\n type: typeof ATHENA_ASSET_CITATION_CLICK_MESSAGE;\n version: 1;\n sourceAssetId?: string;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetCitationActionEvent {\n type: typeof ATHENA_ASSET_CITATION_ACTION_MESSAGE;\n version: 1;\n action: AthenaAssetCitationAction;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetEmbedReadyEvent {\n type: typeof ATHENA_ASSET_EMBED_READY_MESSAGE;\n version: 1;\n}\n\nexport interface AthenaAssetEmbedConfigEvent {\n type: typeof ATHENA_ASSET_EMBED_CONFIG_MESSAGE;\n version: 1;\n token?: string;\n citationBehavior: AthenaAssetCitationBehavior;\n citationActionBehavior?: AthenaAssetCitationBehavior;\n}\n\nexport function resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler,\n}: {\n citationBehavior?: AthenaAssetCitationBehavior;\n hasCitationClickHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationBehavior === \"host\" && !hasCitationClickHandler) return \"browser\";\n return citationBehavior ?? (hasCitationClickHandler ? \"host\" : \"browser\");\n}\n\nexport function resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler,\n}: {\n citationActionBehavior?: AthenaAssetCitationBehavior;\n hasCitationActionHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationActionBehavior === \"host\" && !hasCitationActionHandler) return \"browser\";\n return citationActionBehavior ?? (hasCitationActionHandler ? \"host\" : \"browser\");\n}\n\nexport function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1\n );\n}\n\nexport function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_CLICK_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\nexport function isAthenaAssetCitationActionEvent(value: unknown): value is AthenaAssetCitationActionEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"action\" in value &&\n value.action === \"open-in-spaces\" &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n"],"names":[],"mappings":"AAAO,MAAM,mCAAmC;AACzC,MAAM,oCAAoC;AAC1C,MAAM,sCAAsC;AAC5C,MAAM,uCAAuC;AA4C7C,SAAS,mCAAmC;AAAA,EACjD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,qBAAqB,UAAU,CAAC,wBAAyB,QAAO;AACpE,SAAO,qBAAqB,0BAA0B,SAAS;AACjE;AAEO,SAAS,yCAAyC;AAAA,EACvD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,2BAA2B,UAAU,CAAC,yBAA0B,QAAO;AAC3E,SAAO,2BAA2B,2BAA2B,SAAS;AACxE;AAEO,SAAS,6BAA6B,OAAqD;AAChG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,oCACf,aAAa,SACb,MAAM,YAAY;AAEtB;AAEO,SAAS,gCAAgC,OAAwD;AACtG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,uCACf,aAAa,SACb,MAAM,YAAY,KAClB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAEO,SAAS,iCAAiC,OAAyD;AACxG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,wCACf,aAAa,SACb,MAAM,YAAY,KAClB,YAAY,SACZ,MAAM,WAAW,oBACjB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;"}
1
+ {"version":3,"file":"asset-embed-messages.js","sources":["../../src/assets/asset-embed-messages.ts"],"sourcesContent":["export const ATHENA_ASSET_EMBED_READY_MESSAGE = \"athena:asset-embed-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE = \"athena:asset-embed-content-ready\" as const;\nexport const ATHENA_ASSET_EMBED_CONFIG_MESSAGE = \"athena:asset-embed-config\" as const;\nexport const ATHENA_ASSET_CITATION_CLICK_MESSAGE = \"athena:asset-citation-click\" as const;\nexport const ATHENA_ASSET_CITATION_ACTION_MESSAGE = \"athena:asset-citation-action\" as const;\n\nexport type AthenaAssetCitationBehavior = \"browser\" | \"host\";\nexport type AthenaAssetCitationAction = \"open-in-spaces\";\n\nexport interface AthenaAssetCitationReference {\n id: string;\n /**\n * Where in the asset the citation points. Either the anchor's raw query string as Athena links,\n * citations and search results carry it (`anchor=slide&slide_index=3`, `anchor=time&time=0:42`,\n * `asset_x?anchor=pm_node&node_id=…`), which an embed receives as written whatever kind of\n * place it names, or a typed page or sheet anchor (`{ type: 'page', page: 34 }`).\n */\n anchor?: unknown;\n meta?: Record<string, unknown>;\n}\n\nexport interface AthenaAssetCitationClickEvent {\n type: typeof ATHENA_ASSET_CITATION_CLICK_MESSAGE;\n version: 1;\n sourceAssetId?: string;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetCitationActionEvent {\n type: typeof ATHENA_ASSET_CITATION_ACTION_MESSAGE;\n version: 1;\n action: AthenaAssetCitationAction;\n reference: AthenaAssetCitationReference;\n}\n\nexport interface AthenaAssetEmbedReadyEvent {\n type: typeof ATHENA_ASSET_EMBED_READY_MESSAGE;\n version: 1;\n}\n\nexport interface AthenaAssetEmbedConfigEvent {\n type: typeof ATHENA_ASSET_EMBED_CONFIG_MESSAGE;\n version: 1;\n token?: string;\n citationBehavior: AthenaAssetCitationBehavior;\n citationActionBehavior?: AthenaAssetCitationBehavior;\n}\n\nexport function resolveAthenaAssetCitationBehavior({\n citationBehavior,\n hasCitationClickHandler,\n}: {\n citationBehavior?: AthenaAssetCitationBehavior;\n hasCitationClickHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationBehavior === \"host\" && !hasCitationClickHandler) return \"browser\";\n return citationBehavior ?? (hasCitationClickHandler ? \"host\" : \"browser\");\n}\n\nexport function resolveAthenaAssetCitationActionBehavior({\n citationActionBehavior,\n hasCitationActionHandler,\n}: {\n citationActionBehavior?: AthenaAssetCitationBehavior;\n hasCitationActionHandler: boolean;\n}): AthenaAssetCitationBehavior {\n if (citationActionBehavior === \"host\" && !hasCitationActionHandler) return \"browser\";\n return citationActionBehavior ?? (hasCitationActionHandler ? \"host\" : \"browser\");\n}\n\nexport function isAthenaAssetEmbedReadyEvent(value: unknown): value is AthenaAssetEmbedReadyEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1\n );\n}\n\nexport function isAthenaAssetCitationClickEvent(value: unknown): value is AthenaAssetCitationClickEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_CLICK_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\nexport function isAthenaAssetCitationActionEvent(value: unknown): value is AthenaAssetCitationActionEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_CITATION_ACTION_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"action\" in value &&\n value.action === \"open-in-spaces\" &&\n \"reference\" in value &&\n typeof value.reference === \"object\" &&\n value.reference !== null &&\n \"id\" in value.reference &&\n typeof value.reference.id === \"string\"\n );\n}\n\n/** Content has rendered; bootstrap and iframe load events do not prove an asset opened. */\nexport function isAthenaAssetEmbedContentReadyEvent(value: unknown): value is {\n type: typeof ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE;\n version: 1;\n assetId: string;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n value.type === ATHENA_ASSET_EMBED_CONTENT_READY_MESSAGE &&\n \"version\" in value &&\n value.version === 1 &&\n \"assetId\" in value &&\n typeof value.assetId === \"string\" &&\n value.assetId.length > 0\n );\n}\n"],"names":[],"mappings":"AAAO,MAAM,mCAAmC;AACzC,MAAM,2CAA2C;AACjD,MAAM,oCAAoC;AAC1C,MAAM,sCAAsC;AAC5C,MAAM,uCAAuC;AA4C7C,SAAS,mCAAmC;AAAA,EACjD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,qBAAqB,UAAU,CAAC,wBAAyB,QAAO;AACpE,SAAO,qBAAqB,0BAA0B,SAAS;AACjE;AAEO,SAAS,yCAAyC;AAAA,EACvD;AAAA,EACA;AACF,GAGgC;AAC9B,MAAI,2BAA2B,UAAU,CAAC,yBAA0B,QAAO;AAC3E,SAAO,2BAA2B,2BAA2B,SAAS;AACxE;AAEO,SAAS,6BAA6B,OAAqD;AAChG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,oCACf,aAAa,SACb,MAAM,YAAY;AAEtB;AAEO,SAAS,gCAAgC,OAAwD;AACtG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,uCACf,aAAa,SACb,MAAM,YAAY,KAClB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAEO,SAAS,iCAAiC,OAAyD;AACxG,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,wCACf,aAAa,SACb,MAAM,YAAY,KAClB,YAAY,SACZ,MAAM,WAAW,oBACjB,eAAe,SACf,OAAO,MAAM,cAAc,YAC3B,MAAM,cAAc,QACpB,QAAQ,MAAM,aACd,OAAO,MAAM,UAAU,OAAO;AAElC;AAGO,SAAS,oCAAoC,OAIlD;AACA,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,4CACf,aAAa,SACb,MAAM,YAAY,KAClB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,MAAM,QAAQ,SAAS;AAE3B;"}
@@ -1,24 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const reactQuery = require("@tanstack/react-query");
3
4
  const react = require("react");
4
5
  const athenaUrls = require("../lib/athena-urls.cjs");
6
+ const useAthenaRestQuery = require("../lib/use-athena-rest-query.cjs");
5
7
  const credentialRenewal = require("../runtime/credential-renewal.cjs");
6
8
  const DEFAULT_ASSET_EMBED_READ_ONLY = false;
9
+ const DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = false;
7
10
  const DEFAULT_ASSET_EMBED_DISPLAY_MODE = "full";
8
11
  function buildAssetEmbedRequestBody({
9
12
  assetId,
10
13
  readOnly,
11
14
  expiresInSeconds,
12
- displayMode
15
+ displayMode,
16
+ allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT
13
17
  }) {
14
18
  return {
15
19
  asset_id: assetId,
16
20
  read_only: readOnly,
17
21
  expires_in_seconds: expiresInSeconds,
18
- display_mode: displayMode
22
+ display_mode: displayMode,
23
+ // Sent only when asked: an agora that predates it is never handed an unknown field.
24
+ ...allowQuickEdit && { allow_quick_edit: true }
19
25
  };
20
26
  }
21
- const embedCache = /* @__PURE__ */ new Map();
27
+ const embedQueryClient = new reactQuery.QueryClient();
22
28
  const ATHENA_APP_HOSTNAMES = /* @__PURE__ */ new Set(["app.athenaintel.com", "staging-app.athenaintel.com"]);
23
29
  const ATHENA_PREVIEW_HOSTNAME_SUFFIX = ".previews.athenaintel.com";
24
30
  const ATHENA_WORKSPACE_HOSTNAME_PATTERN = /^.+--(\d+)\.(?:app\.athenaintel\.com|staging-app\.athenaintel\.com)$/;
@@ -294,91 +300,85 @@ function getAssetEmbedAuthContext({ token, apiKey }) {
294
300
  function useAssetEmbed(assetId, options = {
295
301
  backendUrl: ""
296
302
  }) {
303
+ var _a;
297
304
  const {
298
305
  readOnly = DEFAULT_ASSET_EMBED_READ_ONLY,
299
306
  expiresInSeconds = 60 * 60 * 24 * 30,
300
307
  displayMode = DEFAULT_ASSET_EMBED_DISPLAY_MODE,
308
+ allowQuickEdit = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT,
301
309
  backendUrl,
302
310
  appUrl,
303
311
  apiKey,
304
312
  token,
305
313
  getToken
306
314
  } = options;
307
- const [embedUrl, setEmbedUrl] = react.useState(null);
308
- const [isLoading, setIsLoading] = react.useState(false);
309
- const [error, setError] = react.useState(null);
310
- const abortRef = react.useRef(null);
311
315
  const tokenRef = react.useRef(token);
312
316
  tokenRef.current = token;
313
317
  const getTokenRef = react.useRef(getToken);
314
318
  getTokenRef.current = getToken;
315
319
  const authContext = getAssetEmbedAuthContext({ token, apiKey });
316
- react.useEffect(() => {
317
- var _a;
318
- if (!assetId || !backendUrl) {
319
- setEmbedUrl(null);
320
- setIsLoading(false);
321
- setError(null);
322
- return;
323
- }
324
- const cacheKey = `${assetId}:${readOnly}:${displayMode}:${authContext}:${backendUrl}:${appUrl ?? ""}`;
325
- const cached = embedCache.get(cacheKey);
326
- if (cached && cached.expiresAt > Date.now() / 1e3) {
327
- setEmbedUrl(cached.url);
328
- setIsLoading(false);
329
- setError(null);
330
- return;
331
- }
332
- const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
333
- const endpoint = `${apiBaseUrl}/api/embed/generate-token`;
334
- (_a = abortRef.current) == null ? void 0 : _a.abort();
335
- const controller = new AbortController();
336
- abortRef.current = controller;
337
- setIsLoading(true);
338
- setError(null);
339
- const heldToken = tokenRef.current;
340
- credentialRenewal.sendWithCredentialRenewal(
341
- { apiKey, token: heldToken, getToken: heldToken ? getTokenRef.current : void 0 },
342
- (headers) => fetch(endpoint, {
343
- method: "POST",
344
- headers: { "Content-Type": "application/json", ...headers },
345
- body: JSON.stringify(
346
- buildAssetEmbedRequestBody({
347
- assetId,
348
- readOnly,
349
- expiresInSeconds,
350
- displayMode
320
+ const enabled = Boolean(assetId && backendUrl);
321
+ const query = reactQuery.useQuery(
322
+ {
323
+ queryKey: [
324
+ "athena-sdk",
325
+ "asset-embed",
326
+ assetId,
327
+ readOnly,
328
+ displayMode,
329
+ allowQuickEdit,
330
+ // The identity, never the credential: an opaque token or a key is part of `authContext`.
331
+ useAthenaRestQuery.keyPartFingerprint(authContext),
332
+ backendUrl,
333
+ appUrl ?? ""
334
+ ],
335
+ queryFn: async ({ signal }) => {
336
+ const apiBaseUrl = backendUrl.replace(/\/api\/assistant-ui\/?$/, "");
337
+ const heldToken = tokenRef.current;
338
+ const res = await credentialRenewal.sendWithCredentialRenewal(
339
+ { apiKey, token: heldToken, getToken: heldToken ? getTokenRef.current : void 0 },
340
+ (headers) => fetch(`${apiBaseUrl}/api/embed/generate-token`, {
341
+ method: "POST",
342
+ headers: { "Content-Type": "application/json", ...headers },
343
+ body: JSON.stringify(
344
+ buildAssetEmbedRequestBody({
345
+ assetId: assetId ?? "",
346
+ readOnly,
347
+ expiresInSeconds,
348
+ displayMode,
349
+ allowQuickEdit
350
+ })
351
+ ),
352
+ signal
351
353
  })
352
- ),
353
- signal: controller.signal
354
- })
355
- ).then(async (res) => {
356
- if (!res.ok) {
357
- const text = await res.text().catch(() => "");
358
- throw new Error(`Failed to generate embed token (${res.status}): ${text}`);
359
- }
360
- return res.json();
361
- }).then((data) => {
362
- const resolvedEmbedUrl = resolveAssetEmbedUrl({
363
- embedUrl: data.embed_url,
364
- appUrl,
365
- backendUrl
366
- });
367
- embedCache.set(cacheKey, {
368
- url: resolvedEmbedUrl,
369
- expiresAt: data.expires_at
370
- });
371
- setEmbedUrl(resolvedEmbedUrl);
372
- setIsLoading(false);
373
- }).catch((err) => {
374
- if (err.name === "AbortError") return;
375
- setError(err.message);
376
- setIsLoading(false);
377
- });
378
- return () => controller.abort();
379
- }, [assetId, readOnly, expiresInSeconds, displayMode, backendUrl, appUrl, authContext, apiKey]);
380
- return { embedUrl, isLoading, error };
354
+ );
355
+ if (!res.ok) {
356
+ const text = await res.text().catch(() => "");
357
+ throw new Error(`Failed to generate embed token (${res.status}): ${text}`);
358
+ }
359
+ const data = await res.json();
360
+ return {
361
+ url: resolveAssetEmbedUrl({ embedUrl: data.embed_url, appUrl, backendUrl }),
362
+ expiresAt: data.expires_at
363
+ };
364
+ },
365
+ enabled,
366
+ // A minted link is good until it expires; a new one would reload the frame, so it is never
367
+ // minted again while the embed shows (no refetch on focus or reconnect) and never retried.
368
+ staleTime: (cached) => cached.state.data ? Math.max(0, cached.state.data.expiresAt * 1e3 - Date.now()) : 0,
369
+ refetchOnWindowFocus: false,
370
+ refetchOnReconnect: false,
371
+ retry: false
372
+ },
373
+ react.useContext(reactQuery.QueryClientContext) ?? embedQueryClient
374
+ );
375
+ return {
376
+ embedUrl: enabled ? ((_a = query.data) == null ? void 0 : _a.url) ?? null : null,
377
+ isLoading: enabled && query.isLoading,
378
+ error: enabled && query.error ? query.error.message : null
379
+ };
381
380
  }
381
+ exports.DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT = DEFAULT_ASSET_EMBED_ALLOW_QUICK_EDIT;
382
382
  exports.DEFAULT_ASSET_EMBED_DISPLAY_MODE = DEFAULT_ASSET_EMBED_DISPLAY_MODE;
383
383
  exports.DEFAULT_ASSET_EMBED_READ_ONLY = DEFAULT_ASSET_EMBED_READ_ONLY;
384
384
  exports.appendCitationReferenceParams = appendCitationReferenceParams;