@mariozechner/pi-web-ui 0.5.44 → 0.5.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -99
- package/dist/ChatPanel.d.ts +15 -10
- package/dist/ChatPanel.d.ts.map +1 -1
- package/dist/ChatPanel.js +68 -100
- package/dist/ChatPanel.js.map +1 -1
- package/dist/{state/agent-session.d.ts → agent/agent.d.ts} +23 -19
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/{state/agent-session.js → agent/agent.js} +50 -32
- package/dist/agent/agent.js.map +1 -0
- package/dist/{state → agent}/transports/AppTransport.d.ts +1 -3
- package/dist/agent/transports/AppTransport.d.ts.map +1 -0
- package/dist/{state → agent}/transports/AppTransport.js +5 -4
- package/dist/{state → agent}/transports/AppTransport.js.map +1 -1
- package/dist/{state → agent}/transports/ProviderTransport.d.ts +1 -3
- package/dist/agent/transports/ProviderTransport.d.ts.map +1 -0
- package/dist/{state → agent}/transports/ProviderTransport.js +6 -7
- package/dist/agent/transports/ProviderTransport.js.map +1 -0
- package/dist/{state → agent}/transports/index.d.ts.map +1 -1
- package/dist/agent/transports/index.js.map +1 -0
- package/dist/{state → agent}/transports/proxy-types.d.ts.map +1 -1
- package/dist/agent/transports/proxy-types.js.map +1 -0
- package/dist/agent/transports/types.d.ts +12 -0
- package/dist/agent/transports/types.d.ts.map +1 -0
- package/dist/{state → agent}/transports/types.js.map +1 -1
- package/dist/{state → agent}/types.d.ts.map +1 -1
- package/dist/{state → agent}/types.js.map +1 -1
- package/dist/app.css +1 -1
- package/dist/components/AgentInterface.d.ts +7 -4
- package/dist/components/AgentInterface.d.ts.map +1 -1
- package/dist/components/AgentInterface.js +29 -17
- package/dist/components/AgentInterface.js.map +1 -1
- package/dist/components/ConsoleBlock.d.ts +1 -0
- package/dist/components/ConsoleBlock.d.ts.map +1 -1
- package/dist/components/ConsoleBlock.js +7 -1
- package/dist/components/ConsoleBlock.js.map +1 -1
- package/dist/components/ExpandableSection.d.ts +15 -0
- package/dist/components/ExpandableSection.d.ts.map +1 -0
- package/dist/components/ExpandableSection.js +63 -0
- package/dist/components/ExpandableSection.js.map +1 -0
- package/dist/components/MessageEditor.d.ts +8 -1
- package/dist/components/MessageEditor.d.ts.map +1 -1
- package/dist/components/MessageEditor.js +149 -6
- package/dist/components/MessageEditor.js.map +1 -1
- package/dist/components/MessageList.d.ts +3 -2
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +14 -1
- package/dist/components/MessageList.js.map +1 -1
- package/dist/components/Messages.d.ts +15 -6
- package/dist/components/Messages.d.ts.map +1 -1
- package/dist/components/Messages.js +17 -83
- package/dist/components/Messages.js.map +1 -1
- package/dist/components/ProviderKeyInput.d.ts.map +1 -1
- package/dist/components/ProviderKeyInput.js +6 -5
- package/dist/components/ProviderKeyInput.js.map +1 -1
- package/dist/components/SandboxedIframe.d.ts +29 -7
- package/dist/components/SandboxedIframe.d.ts.map +1 -1
- package/dist/components/SandboxedIframe.js +350 -282
- package/dist/components/SandboxedIframe.js.map +1 -1
- package/dist/components/message-renderer-registry.d.ts +12 -0
- package/dist/components/message-renderer-registry.d.ts.map +1 -0
- package/dist/components/message-renderer-registry.js +12 -0
- package/dist/components/message-renderer-registry.js.map +1 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +35 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js +189 -0
- package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +17 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js +64 -0
- package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +42 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.js +161 -0
- package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +30 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js +97 -0
- package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -0
- package/dist/components/sandbox/RuntimeMessageBridge.d.ts +19 -0
- package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -0
- package/dist/components/sandbox/RuntimeMessageBridge.js +74 -0
- package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -0
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts +65 -0
- package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -0
- package/dist/components/sandbox/RuntimeMessageRouter.js +168 -0
- package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +33 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.js +2 -0
- package/dist/components/sandbox/SandboxRuntimeProvider.js.map +1 -0
- package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -1
- package/dist/dialogs/ApiKeyPromptDialog.js +2 -5
- package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -1
- package/dist/dialogs/ModelSelector.js.map +1 -1
- package/dist/dialogs/PersistentStorageDialog.d.ts +17 -0
- package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -0
- package/dist/dialogs/PersistentStorageDialog.js +144 -0
- package/dist/dialogs/PersistentStorageDialog.js.map +1 -0
- package/dist/dialogs/SessionListDialog.d.ts +19 -0
- package/dist/dialogs/SessionListDialog.d.ts.map +1 -0
- package/dist/dialogs/SessionListDialog.js +152 -0
- package/dist/dialogs/SessionListDialog.js.map +1 -0
- package/dist/dialogs/SettingsDialog.d.ts.map +1 -1
- package/dist/dialogs/SettingsDialog.js +1 -0
- package/dist/dialogs/SettingsDialog.js.map +1 -1
- package/dist/index.d.ts +34 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -14
- package/dist/index.js.map +1 -1
- package/dist/prompts/prompts.d.ts +11 -0
- package/dist/prompts/prompts.d.ts.map +1 -0
- package/dist/prompts/prompts.js +272 -0
- package/dist/prompts/prompts.js.map +1 -0
- package/dist/storage/app-storage.d.ts +17 -12
- package/dist/storage/app-storage.d.ts.map +1 -1
- package/dist/storage/app-storage.js +13 -20
- package/dist/storage/app-storage.js.map +1 -1
- package/dist/storage/backends/indexeddb-storage-backend.d.ts +27 -0
- package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -0
- package/dist/storage/backends/indexeddb-storage-backend.js +166 -0
- package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -0
- package/dist/storage/store.d.ts +23 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +26 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/stores/provider-keys-store.d.ts +14 -0
- package/dist/storage/stores/provider-keys-store.d.ts.map +1 -0
- package/dist/storage/stores/provider-keys-store.js +27 -0
- package/dist/storage/stores/provider-keys-store.js.map +1 -0
- package/dist/storage/stores/sessions-store.d.ts +31 -0
- package/dist/storage/stores/sessions-store.d.ts.map +1 -0
- package/dist/storage/stores/sessions-store.js +113 -0
- package/dist/storage/stores/sessions-store.js.map +1 -0
- package/dist/storage/stores/settings-store.d.ts +14 -0
- package/dist/storage/stores/settings-store.d.ts.map +1 -0
- package/dist/storage/stores/settings-store.js +28 -0
- package/dist/storage/stores/settings-store.js.map +1 -0
- package/dist/storage/types.d.ts +156 -22
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.d.ts +0 -1
- package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -1
- package/dist/tools/artifacts/ArtifactElement.js +0 -1
- package/dist/tools/artifacts/ArtifactElement.js.map +1 -1
- package/dist/tools/artifacts/ArtifactPill.d.ts +4 -0
- package/dist/tools/artifacts/ArtifactPill.d.ts.map +1 -0
- package/dist/tools/artifacts/ArtifactPill.js +22 -0
- package/dist/tools/artifacts/ArtifactPill.js.map +1 -0
- package/dist/tools/artifacts/Console.d.ts +18 -0
- package/dist/tools/artifacts/Console.d.ts.map +1 -0
- package/dist/tools/artifacts/Console.js +95 -0
- package/dist/tools/artifacts/Console.js.map +1 -0
- package/dist/tools/artifacts/DocxArtifact.d.ts +22 -0
- package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/DocxArtifact.js +208 -0
- package/dist/tools/artifacts/DocxArtifact.js.map +1 -0
- package/dist/tools/artifacts/ExcelArtifact.d.ts +24 -0
- package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/ExcelArtifact.js +216 -0
- package/dist/tools/artifacts/ExcelArtifact.js.map +1 -0
- package/dist/tools/artifacts/GenericArtifact.d.ts +19 -0
- package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/GenericArtifact.js +117 -0
- package/dist/tools/artifacts/GenericArtifact.js.map +1 -0
- package/dist/tools/artifacts/HtmlArtifact.d.ts +8 -11
- package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/HtmlArtifact.js +56 -88
- package/dist/tools/artifacts/HtmlArtifact.js.map +1 -1
- package/dist/tools/artifacts/ImageArtifact.d.ts +20 -0
- package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/ImageArtifact.js +120 -0
- package/dist/tools/artifacts/ImageArtifact.js.map +1 -0
- package/dist/tools/artifacts/MarkdownArtifact.d.ts +0 -1
- package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/MarkdownArtifact.js +0 -4
- package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -1
- package/dist/tools/artifacts/PdfArtifact.d.ts +25 -0
- package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -0
- package/dist/tools/artifacts/PdfArtifact.js +184 -0
- package/dist/tools/artifacts/PdfArtifact.js.map +1 -0
- package/dist/tools/artifacts/SvgArtifact.d.ts +0 -1
- package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/SvgArtifact.js +0 -4
- package/dist/tools/artifacts/SvgArtifact.js.map +1 -1
- package/dist/tools/artifacts/TextArtifact.d.ts +0 -1
- package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -1
- package/dist/tools/artifacts/TextArtifact.js +0 -4
- package/dist/tools/artifacts/TextArtifact.js.map +1 -1
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts +11 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.js +262 -0
- package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -0
- package/dist/tools/artifacts/artifacts.d.ts +10 -13
- package/dist/tools/artifacts/artifacts.d.ts.map +1 -1
- package/dist/tools/artifacts/artifacts.js +166 -344
- package/dist/tools/artifacts/artifacts.js.map +1 -1
- package/dist/tools/artifacts/index.d.ts +1 -0
- package/dist/tools/artifacts/index.d.ts.map +1 -1
- package/dist/tools/artifacts/index.js +1 -0
- package/dist/tools/artifacts/index.js.map +1 -1
- package/dist/tools/extract-document.d.ts +24 -0
- package/dist/tools/extract-document.d.ts.map +1 -0
- package/dist/tools/extract-document.js +193 -0
- package/dist/tools/extract-document.js.map +1 -0
- package/dist/tools/index.d.ts +9 -7
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +17 -13
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/javascript-repl.d.ts +16 -15
- package/dist/tools/javascript-repl.d.ts.map +1 -1
- package/dist/tools/javascript-repl.js +101 -133
- package/dist/tools/javascript-repl.js.map +1 -1
- package/dist/tools/renderer-registry.d.ts +12 -0
- package/dist/tools/renderer-registry.d.ts.map +1 -1
- package/dist/tools/renderer-registry.js +78 -0
- package/dist/tools/renderer-registry.js.map +1 -1
- package/dist/tools/renderers/BashRenderer.d.ts +2 -4
- package/dist/tools/renderers/BashRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/BashRenderer.js +30 -26
- package/dist/tools/renderers/BashRenderer.js.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.d.ts +2 -4
- package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/CalculateRenderer.js +32 -28
- package/dist/tools/renderers/CalculateRenderer.js.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.d.ts +2 -4
- package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/DefaultRenderer.js +78 -18
- package/dist/tools/renderers/DefaultRenderer.js.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts +2 -4
- package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -1
- package/dist/tools/renderers/GetCurrentTimeRenderer.js +57 -21
- package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -1
- package/dist/tools/types.d.ts +5 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/i18n.d.ts +424 -1
- package/dist/utils/i18n.d.ts.map +1 -1
- package/dist/utils/i18n.js +131 -7
- package/dist/utils/i18n.js.map +1 -1
- package/example/package.json +2 -1
- package/example/src/custom-messages.ts +112 -0
- package/example/src/main.ts +391 -38
- package/package.json +48 -43
- package/scripts/count-prompt-tokens.ts +88 -0
- package/src/ChatPanel.ts +93 -101
- package/src/{state/agent-session.ts → agent/agent.ts} +80 -55
- package/src/{state → agent}/transports/AppTransport.ts +6 -6
- package/src/{state → agent}/transports/ProviderTransport.ts +13 -7
- package/src/{state → agent}/transports/types.ts +8 -2
- package/src/components/AgentInterface.ts +32 -16
- package/src/components/ConsoleBlock.ts +5 -1
- package/src/components/ExpandableSection.ts +46 -0
- package/src/components/MessageEditor.ts +159 -5
- package/src/components/MessageList.ts +18 -3
- package/src/components/Messages.ts +48 -89
- package/src/components/ProviderKeyInput.ts +6 -5
- package/src/components/SandboxedIframe.ts +412 -321
- package/src/components/message-renderer-registry.ts +28 -0
- package/src/components/sandbox/ArtifactsRuntimeProvider.ts +219 -0
- package/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
- package/src/components/sandbox/ConsoleRuntimeProvider.ts +187 -0
- package/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
- package/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
- package/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
- package/src/components/sandbox/SandboxRuntimeProvider.ts +35 -0
- package/src/dialogs/ApiKeyPromptDialog.ts +2 -5
- package/src/dialogs/ModelSelector.ts +2 -2
- package/src/dialogs/PersistentStorageDialog.ts +141 -0
- package/src/dialogs/SessionListDialog.ts +148 -0
- package/src/dialogs/SettingsDialog.ts +1 -0
- package/src/index.ts +61 -20
- package/src/prompts/prompts.ts +282 -0
- package/src/storage/app-storage.ts +27 -24
- package/src/storage/backends/indexeddb-storage-backend.ts +193 -0
- package/src/storage/store.ts +33 -0
- package/src/storage/stores/provider-keys-store.ts +33 -0
- package/src/storage/stores/sessions-store.ts +130 -0
- package/src/storage/stores/settings-store.ts +34 -0
- package/src/storage/types.ts +182 -22
- package/src/tools/artifacts/ArtifactElement.ts +0 -1
- package/src/tools/artifacts/ArtifactPill.ts +25 -0
- package/src/tools/artifacts/Console.ts +93 -0
- package/src/tools/artifacts/DocxArtifact.ts +213 -0
- package/src/tools/artifacts/ExcelArtifact.ts +231 -0
- package/src/tools/artifacts/GenericArtifact.ts +117 -0
- package/src/tools/artifacts/HtmlArtifact.ts +64 -94
- package/src/tools/artifacts/ImageArtifact.ts +116 -0
- package/src/tools/artifacts/MarkdownArtifact.ts +0 -1
- package/src/tools/artifacts/PdfArtifact.ts +201 -0
- package/src/tools/artifacts/SvgArtifact.ts +0 -1
- package/src/tools/artifacts/TextArtifact.ts +0 -1
- package/src/tools/artifacts/artifacts-tool-renderer.ts +298 -0
- package/src/tools/artifacts/artifacts.ts +190 -366
- package/src/tools/artifacts/index.ts +1 -0
- package/src/tools/extract-document.ts +250 -0
- package/src/tools/index.ts +25 -14
- package/src/tools/javascript-repl.ts +138 -160
- package/src/tools/renderer-registry.ts +98 -0
- package/src/tools/renderers/BashRenderer.ts +33 -30
- package/src/tools/renderers/CalculateRenderer.ts +36 -31
- package/src/tools/renderers/DefaultRenderer.ts +84 -21
- package/src/tools/renderers/GetCurrentTimeRenderer.ts +68 -23
- package/src/tools/types.ts +10 -2
- package/src/utils/i18n.ts +203 -8
- package/dist/state/agent-session.d.ts.map +0 -1
- package/dist/state/agent-session.js.map +0 -1
- package/dist/state/transports/AppTransport.d.ts.map +0 -1
- package/dist/state/transports/ProviderTransport.d.ts.map +0 -1
- package/dist/state/transports/ProviderTransport.js.map +0 -1
- package/dist/state/transports/index.js.map +0 -1
- package/dist/state/transports/proxy-types.js.map +0 -1
- package/dist/state/transports/types.d.ts +0 -11
- package/dist/state/transports/types.d.ts.map +0 -1
- package/dist/storage/backends/chrome-storage-backend.d.ts +0 -18
- package/dist/storage/backends/chrome-storage-backend.d.ts.map +0 -1
- package/dist/storage/backends/chrome-storage-backend.js +0 -67
- package/dist/storage/backends/chrome-storage-backend.js.map +0 -1
- package/dist/storage/backends/indexeddb-backend.d.ts +0 -20
- package/dist/storage/backends/indexeddb-backend.d.ts.map +0 -1
- package/dist/storage/backends/indexeddb-backend.js +0 -89
- package/dist/storage/backends/indexeddb-backend.js.map +0 -1
- package/dist/storage/backends/local-storage-backend.d.ts +0 -18
- package/dist/storage/backends/local-storage-backend.d.ts.map +0 -1
- package/dist/storage/backends/local-storage-backend.js +0 -69
- package/dist/storage/backends/local-storage-backend.js.map +0 -1
- package/dist/storage/repositories/provider-keys-repository.d.ts +0 -34
- package/dist/storage/repositories/provider-keys-repository.d.ts.map +0 -1
- package/dist/storage/repositories/provider-keys-repository.js +0 -50
- package/dist/storage/repositories/provider-keys-repository.js.map +0 -1
- package/dist/storage/repositories/settings-repository.d.ts +0 -34
- package/dist/storage/repositories/settings-repository.d.ts.map +0 -1
- package/dist/storage/repositories/settings-repository.js +0 -46
- package/dist/storage/repositories/settings-repository.js.map +0 -1
- package/src/storage/backends/chrome-storage-backend.ts +0 -82
- package/src/storage/backends/indexeddb-backend.ts +0 -107
- package/src/storage/backends/local-storage-backend.ts +0 -74
- package/src/storage/repositories/provider-keys-repository.ts +0 -55
- package/src/storage/repositories/settings-repository.ts +0 -51
- /package/dist/{state → agent}/transports/index.d.ts +0 -0
- /package/dist/{state → agent}/transports/index.js +0 -0
- /package/dist/{state → agent}/transports/proxy-types.d.ts +0 -0
- /package/dist/{state → agent}/transports/proxy-types.js +0 -0
- /package/dist/{state → agent}/transports/types.js +0 -0
- /package/dist/{state → agent}/types.d.ts +0 -0
- /package/dist/{state → agent}/types.js +0 -0
- /package/src/{state → agent}/transports/index.ts +0 -0
- /package/src/{state → agent}/transports/proxy-types.ts +0 -0
- /package/src/{state → agent}/types.ts +0 -0
|
@@ -1,35 +1,33 @@
|
|
|
1
|
-
import { CopyButton, DownloadButton, PreviewCodeToggle } from "@mariozechner/mini-lit";
|
|
1
|
+
import { Button, CopyButton, DownloadButton, icon, PreviewCodeToggle } from "@mariozechner/mini-lit";
|
|
2
2
|
import hljs from "highlight.js";
|
|
3
3
|
import { html } from "lit";
|
|
4
4
|
import { customElement, property, state } from "lit/decorators.js";
|
|
5
5
|
import { createRef, type Ref, ref } from "lit/directives/ref.js";
|
|
6
6
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
7
|
+
import { RefreshCw } from "lucide";
|
|
7
8
|
import type { SandboxIframe } from "../../components/SandboxedIframe.js";
|
|
8
|
-
import type
|
|
9
|
+
import { type MessageConsumer, RUNTIME_MESSAGE_ROUTER } from "../../components/sandbox/RuntimeMessageRouter.js";
|
|
10
|
+
import type { SandboxRuntimeProvider } from "../../components/sandbox/SandboxRuntimeProvider.js";
|
|
9
11
|
import { i18n } from "../../utils/i18n.js";
|
|
10
12
|
import "../../components/SandboxedIframe.js";
|
|
11
13
|
import { ArtifactElement } from "./ArtifactElement.js";
|
|
14
|
+
import type { Console } from "./Console.js";
|
|
15
|
+
import "./Console.js";
|
|
12
16
|
|
|
13
17
|
@customElement("html-artifact")
|
|
14
18
|
export class HtmlArtifact extends ArtifactElement {
|
|
15
19
|
@property() override filename = "";
|
|
16
|
-
@property({ attribute: false })
|
|
17
|
-
@property({ attribute: false }) attachments: Attachment[] = [];
|
|
20
|
+
@property({ attribute: false }) runtimeProviders: SandboxRuntimeProvider[] = [];
|
|
18
21
|
@property({ attribute: false }) sandboxUrlProvider?: () => string;
|
|
19
22
|
|
|
20
23
|
private _content = "";
|
|
21
24
|
private logs: Array<{ type: "log" | "error"; text: string }> = [];
|
|
22
25
|
|
|
23
26
|
// Refs for DOM elements
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
private consoleButtonRef: Ref<HTMLButtonElement> = createRef();
|
|
27
|
-
|
|
28
|
-
// Store message handler so we can remove it
|
|
29
|
-
private messageHandler?: (e: MessageEvent) => void;
|
|
27
|
+
public sandboxIframeRef: Ref<SandboxIframe> = createRef();
|
|
28
|
+
private consoleRef: Ref<Console> = createRef();
|
|
30
29
|
|
|
31
30
|
@state() private viewMode: "preview" | "code" = "preview";
|
|
32
|
-
@state() private consoleOpen = false;
|
|
33
31
|
|
|
34
32
|
private setViewMode(mode: "preview" | "code") {
|
|
35
33
|
this.viewMode = mode;
|
|
@@ -47,11 +45,30 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
47
45
|
copyButton.title = i18n("Copy HTML");
|
|
48
46
|
copyButton.showText = false;
|
|
49
47
|
|
|
48
|
+
// Generate standalone HTML with all runtime code injected for download
|
|
49
|
+
const sandbox = this.sandboxIframeRef.value;
|
|
50
|
+
const sandboxId = `artifact-${this.filename}`;
|
|
51
|
+
const downloadContent =
|
|
52
|
+
sandbox?.prepareHtmlDocument(sandboxId, this._content, this.runtimeProviders || [], {
|
|
53
|
+
isHtmlArtifact: true,
|
|
54
|
+
isStandalone: true, // Skip runtime bridge and navigation interceptor for standalone downloads
|
|
55
|
+
}) || this._content;
|
|
56
|
+
|
|
50
57
|
return html`
|
|
51
58
|
<div class="flex items-center gap-2">
|
|
52
59
|
${toggle}
|
|
60
|
+
${Button({
|
|
61
|
+
variant: "ghost",
|
|
62
|
+
size: "sm",
|
|
63
|
+
onClick: () => {
|
|
64
|
+
this.logs = [];
|
|
65
|
+
this.executeContent(this._content);
|
|
66
|
+
},
|
|
67
|
+
title: i18n("Reload HTML"),
|
|
68
|
+
children: icon(RefreshCw, "sm"),
|
|
69
|
+
})}
|
|
53
70
|
${copyButton}
|
|
54
|
-
${DownloadButton({ content:
|
|
71
|
+
${DownloadButton({ content: downloadContent, filename: this.filename, mimeType: "text/html", title: i18n("Download HTML") })}
|
|
55
72
|
</div>
|
|
56
73
|
`;
|
|
57
74
|
}
|
|
@@ -62,19 +79,15 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
62
79
|
if (oldValue !== value) {
|
|
63
80
|
// Reset logs when content changes
|
|
64
81
|
this.logs = [];
|
|
65
|
-
if (this.consoleLogsRef.value) {
|
|
66
|
-
this.consoleLogsRef.value.innerHTML = "";
|
|
67
|
-
}
|
|
68
82
|
this.requestUpdate();
|
|
69
83
|
// Execute content in sandbox if it exists
|
|
70
84
|
if (this.sandboxIframeRef.value && value) {
|
|
71
|
-
this.updateConsoleButton();
|
|
72
85
|
this.executeContent(value);
|
|
73
86
|
}
|
|
74
87
|
}
|
|
75
88
|
}
|
|
76
89
|
|
|
77
|
-
|
|
90
|
+
public executeContent(html: string) {
|
|
78
91
|
const sandbox = this.sandboxIframeRef.value;
|
|
79
92
|
if (!sandbox) return;
|
|
80
93
|
|
|
@@ -83,29 +96,40 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
83
96
|
sandbox.sandboxUrlProvider = this.sandboxUrlProvider;
|
|
84
97
|
}
|
|
85
98
|
|
|
86
|
-
// Remove previous message handler if it exists
|
|
87
|
-
if (this.messageHandler) {
|
|
88
|
-
window.removeEventListener("message", this.messageHandler);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
99
|
const sandboxId = `artifact-${this.filename}`;
|
|
92
100
|
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
// Create consumer for console messages
|
|
102
|
+
const consumer: MessageConsumer = {
|
|
103
|
+
handleMessage: async (message: any): Promise<void> => {
|
|
104
|
+
if (message.type === "console") {
|
|
105
|
+
// Create new array reference for Lit reactivity
|
|
106
|
+
this.logs = [
|
|
107
|
+
...this.logs,
|
|
108
|
+
{
|
|
109
|
+
type: message.method === "error" ? "error" : "log",
|
|
110
|
+
text: message.text,
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
this.requestUpdate(); // Re-render to show console
|
|
114
|
+
}
|
|
115
|
+
},
|
|
104
116
|
};
|
|
105
|
-
window.addEventListener("message", this.messageHandler);
|
|
106
117
|
|
|
107
|
-
//
|
|
108
|
-
|
|
118
|
+
// Inject window.complete() call at the end of the HTML to signal when page is loaded
|
|
119
|
+
// HTML artifacts don't time out - they call complete() when ready
|
|
120
|
+
let modifiedHtml = html;
|
|
121
|
+
if (modifiedHtml.includes("</html>")) {
|
|
122
|
+
modifiedHtml = modifiedHtml.replace(
|
|
123
|
+
"</html>",
|
|
124
|
+
"<script>if (window.complete) window.complete();</script></html>",
|
|
125
|
+
);
|
|
126
|
+
} else {
|
|
127
|
+
// If no closing </html> tag, append the script
|
|
128
|
+
modifiedHtml += "<script>if (window.complete) window.complete();</script>";
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Load content - this handles sandbox registration, consumer registration, and iframe creation
|
|
132
|
+
sandbox.loadContent(sandboxId, modifiedHtml, this.runtimeProviders, [consumer]);
|
|
109
133
|
}
|
|
110
134
|
|
|
111
135
|
override get content(): string {
|
|
@@ -114,11 +138,9 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
114
138
|
|
|
115
139
|
override disconnectedCallback() {
|
|
116
140
|
super.disconnectedCallback();
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.messageHandler = undefined;
|
|
121
|
-
}
|
|
141
|
+
// Unregister sandbox when element is removed from DOM
|
|
142
|
+
const sandboxId = `artifact-${this.filename}`;
|
|
143
|
+
RUNTIME_MESSAGE_ROUTER.unregisterSandbox(sandboxId);
|
|
122
144
|
}
|
|
123
145
|
|
|
124
146
|
override firstUpdated() {
|
|
@@ -137,39 +159,6 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
137
159
|
}
|
|
138
160
|
}
|
|
139
161
|
|
|
140
|
-
private updateConsoleButton() {
|
|
141
|
-
const button = this.consoleButtonRef.value;
|
|
142
|
-
if (!button) return;
|
|
143
|
-
|
|
144
|
-
const errorCount = this.logs.filter((l) => l.type === "error").length;
|
|
145
|
-
const text =
|
|
146
|
-
errorCount > 0
|
|
147
|
-
? `${i18n("console")} <span class="text-destructive">${errorCount} errors</span>`
|
|
148
|
-
: `${i18n("console")} (${this.logs.length})`;
|
|
149
|
-
button.innerHTML = `<span>${text}</span><span>${this.consoleOpen ? "▼" : "▶"}</span>`;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
private toggleConsole() {
|
|
153
|
-
this.consoleOpen = !this.consoleOpen;
|
|
154
|
-
this.requestUpdate();
|
|
155
|
-
|
|
156
|
-
// Populate console logs if opening
|
|
157
|
-
if (this.consoleOpen) {
|
|
158
|
-
requestAnimationFrame(() => {
|
|
159
|
-
if (this.consoleLogsRef.value) {
|
|
160
|
-
// Populate with existing logs
|
|
161
|
-
this.consoleLogsRef.value.innerHTML = "";
|
|
162
|
-
this.logs.forEach((log) => {
|
|
163
|
-
const logEl = document.createElement("div");
|
|
164
|
-
logEl.className = `text-xs font-mono ${log.type === "error" ? "text-destructive" : "text-muted-foreground"}`;
|
|
165
|
-
logEl.textContent = `[${log.type}] ${log.text}`;
|
|
166
|
-
this.consoleLogsRef.value!.appendChild(logEl);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
162
|
public getLogs(): string {
|
|
174
163
|
if (this.logs.length === 0) return i18n("No logs for {filename}").replace("{filename}", this.filename);
|
|
175
164
|
return this.logs.map((l) => `[${l.type}] ${l.text}`).join("\n");
|
|
@@ -184,26 +173,7 @@ export class HtmlArtifact extends ArtifactElement {
|
|
|
184
173
|
<sandbox-iframe class="flex-1" ${ref(this.sandboxIframeRef)}></sandbox-iframe>
|
|
185
174
|
${
|
|
186
175
|
this.logs.length > 0
|
|
187
|
-
? html
|
|
188
|
-
<div class="border-t border-border">
|
|
189
|
-
<button
|
|
190
|
-
@click=${() => this.toggleConsole()}
|
|
191
|
-
class="w-full px-3 py-1 text-xs text-left hover:bg-muted flex items-center justify-between"
|
|
192
|
-
${ref(this.consoleButtonRef)}
|
|
193
|
-
>
|
|
194
|
-
<span
|
|
195
|
-
>${i18n("console")}
|
|
196
|
-
${
|
|
197
|
-
this.logs.filter((l) => l.type === "error").length > 0
|
|
198
|
-
? html`<span class="text-destructive">${this.logs.filter((l) => l.type === "error").length} errors</span>`
|
|
199
|
-
: `(${this.logs.length})`
|
|
200
|
-
}</span
|
|
201
|
-
>
|
|
202
|
-
<span>${this.consoleOpen ? "▼" : "▶"}</span>
|
|
203
|
-
</button>
|
|
204
|
-
${this.consoleOpen ? html` <div class="max-h-48 overflow-y-auto bg-muted/50 p-2" ${ref(this.consoleLogsRef)}></div> ` : ""}
|
|
205
|
-
</div>
|
|
206
|
-
`
|
|
176
|
+
? html`<artifact-console .logs=${this.logs} ${ref(this.consoleRef)}></artifact-console>`
|
|
207
177
|
: ""
|
|
208
178
|
}
|
|
209
179
|
</div>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { DownloadButton } from "@mariozechner/mini-lit";
|
|
2
|
+
import { html, type TemplateResult } from "lit";
|
|
3
|
+
import { customElement, property } from "lit/decorators.js";
|
|
4
|
+
import { i18n } from "../../utils/i18n.js";
|
|
5
|
+
import { ArtifactElement } from "./ArtifactElement.js";
|
|
6
|
+
|
|
7
|
+
@customElement("image-artifact")
|
|
8
|
+
export class ImageArtifact extends ArtifactElement {
|
|
9
|
+
@property({ type: String }) private _content = "";
|
|
10
|
+
|
|
11
|
+
get content(): string {
|
|
12
|
+
return this._content;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
set content(value: string) {
|
|
16
|
+
this._content = value;
|
|
17
|
+
this.requestUpdate();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected override createRenderRoot(): HTMLElement | DocumentFragment {
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override connectedCallback(): void {
|
|
25
|
+
super.connectedCallback();
|
|
26
|
+
this.style.display = "block";
|
|
27
|
+
this.style.height = "100%";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private getMimeType(): string {
|
|
31
|
+
const ext = this.filename.split(".").pop()?.toLowerCase();
|
|
32
|
+
if (ext === "jpg" || ext === "jpeg") return "image/jpeg";
|
|
33
|
+
if (ext === "gif") return "image/gif";
|
|
34
|
+
if (ext === "webp") return "image/webp";
|
|
35
|
+
if (ext === "svg") return "image/svg+xml";
|
|
36
|
+
if (ext === "bmp") return "image/bmp";
|
|
37
|
+
if (ext === "ico") return "image/x-icon";
|
|
38
|
+
return "image/png";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private getImageUrl(): string {
|
|
42
|
+
// If content is already a data URL, use it directly
|
|
43
|
+
if (this._content.startsWith("data:")) {
|
|
44
|
+
return this._content;
|
|
45
|
+
}
|
|
46
|
+
// Otherwise assume it's base64 and construct data URL
|
|
47
|
+
return `data:${this.getMimeType()};base64,${this._content}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private decodeBase64(): Uint8Array {
|
|
51
|
+
let base64Data: string;
|
|
52
|
+
|
|
53
|
+
// If content is a data URL, extract the base64 part
|
|
54
|
+
if (this._content.startsWith("data:")) {
|
|
55
|
+
const base64Match = this._content.match(/base64,(.+)/);
|
|
56
|
+
if (base64Match) {
|
|
57
|
+
base64Data = base64Match[1];
|
|
58
|
+
} else {
|
|
59
|
+
// Not a base64 data URL, return empty
|
|
60
|
+
return new Uint8Array(0);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
// Otherwise use content as-is
|
|
64
|
+
base64Data = this._content;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Decode base64 to binary string
|
|
68
|
+
const binaryString = atob(base64Data);
|
|
69
|
+
|
|
70
|
+
// Convert binary string to Uint8Array
|
|
71
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
72
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
73
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return bytes;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public getHeaderButtons() {
|
|
80
|
+
return html`
|
|
81
|
+
<div class="flex items-center gap-1">
|
|
82
|
+
${DownloadButton({
|
|
83
|
+
content: this.decodeBase64(),
|
|
84
|
+
filename: this.filename,
|
|
85
|
+
mimeType: this.getMimeType(),
|
|
86
|
+
title: i18n("Download"),
|
|
87
|
+
})}
|
|
88
|
+
</div>
|
|
89
|
+
`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
override render(): TemplateResult {
|
|
93
|
+
return html`
|
|
94
|
+
<div class="h-full flex flex-col bg-background overflow-auto">
|
|
95
|
+
<div class="flex-1 flex items-center justify-center p-4">
|
|
96
|
+
<img
|
|
97
|
+
src="${this.getImageUrl()}"
|
|
98
|
+
alt="${this.filename}"
|
|
99
|
+
class="max-w-full max-h-full object-contain"
|
|
100
|
+
@error=${(e: Event) => {
|
|
101
|
+
const target = e.target as HTMLImageElement;
|
|
102
|
+
target.src =
|
|
103
|
+
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext x='50' y='50' text-anchor='middle' dominant-baseline='middle' fill='%23999'%3EImage Error%3C/text%3E%3C/svg%3E";
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
declare global {
|
|
113
|
+
interface HTMLElementTagNameMap {
|
|
114
|
+
"image-artifact": ImageArtifact;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -10,7 +10,6 @@ import { ArtifactElement } from "./ArtifactElement.js";
|
|
|
10
10
|
@customElement("markdown-artifact")
|
|
11
11
|
export class MarkdownArtifact extends ArtifactElement {
|
|
12
12
|
@property() override filename = "";
|
|
13
|
-
@property({ attribute: false }) override displayTitle = "";
|
|
14
13
|
|
|
15
14
|
private _content = "";
|
|
16
15
|
override get content(): string {
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { DownloadButton } from "@mariozechner/mini-lit";
|
|
2
|
+
import { html, type TemplateResult } from "lit";
|
|
3
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
4
|
+
import * as pdfjsLib from "pdfjs-dist";
|
|
5
|
+
import { i18n } from "../../utils/i18n.js";
|
|
6
|
+
import { ArtifactElement } from "./ArtifactElement.js";
|
|
7
|
+
|
|
8
|
+
// Configure PDF.js worker
|
|
9
|
+
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url).toString();
|
|
10
|
+
|
|
11
|
+
@customElement("pdf-artifact")
|
|
12
|
+
export class PdfArtifact extends ArtifactElement {
|
|
13
|
+
@property({ type: String }) private _content = "";
|
|
14
|
+
@state() private error: string | null = null;
|
|
15
|
+
private currentLoadingTask: any = null;
|
|
16
|
+
|
|
17
|
+
get content(): string {
|
|
18
|
+
return this._content;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
set content(value: string) {
|
|
22
|
+
this._content = value;
|
|
23
|
+
this.error = null;
|
|
24
|
+
this.requestUpdate();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected override createRenderRoot(): HTMLElement | DocumentFragment {
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override connectedCallback(): void {
|
|
32
|
+
super.connectedCallback();
|
|
33
|
+
this.style.display = "block";
|
|
34
|
+
this.style.height = "100%";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
override disconnectedCallback(): void {
|
|
38
|
+
super.disconnectedCallback();
|
|
39
|
+
this.cleanup();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private cleanup() {
|
|
43
|
+
if (this.currentLoadingTask) {
|
|
44
|
+
this.currentLoadingTask.destroy();
|
|
45
|
+
this.currentLoadingTask = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private base64ToArrayBuffer(base64: string): ArrayBuffer {
|
|
50
|
+
// Remove data URL prefix if present
|
|
51
|
+
let base64Data = base64;
|
|
52
|
+
if (base64.startsWith("data:")) {
|
|
53
|
+
const base64Match = base64.match(/base64,(.+)/);
|
|
54
|
+
if (base64Match) {
|
|
55
|
+
base64Data = base64Match[1];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const binaryString = atob(base64Data);
|
|
60
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
61
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
62
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
63
|
+
}
|
|
64
|
+
return bytes.buffer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private decodeBase64(): Uint8Array {
|
|
68
|
+
let base64Data = this._content;
|
|
69
|
+
if (this._content.startsWith("data:")) {
|
|
70
|
+
const base64Match = this._content.match(/base64,(.+)/);
|
|
71
|
+
if (base64Match) {
|
|
72
|
+
base64Data = base64Match[1];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const binaryString = atob(base64Data);
|
|
77
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
78
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
79
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
80
|
+
}
|
|
81
|
+
return bytes;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public getHeaderButtons() {
|
|
85
|
+
return html`
|
|
86
|
+
<div class="flex items-center gap-1">
|
|
87
|
+
${DownloadButton({
|
|
88
|
+
content: this.decodeBase64(),
|
|
89
|
+
filename: this.filename,
|
|
90
|
+
mimeType: "application/pdf",
|
|
91
|
+
title: i18n("Download"),
|
|
92
|
+
})}
|
|
93
|
+
</div>
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
override async updated(changedProperties: Map<string, any>) {
|
|
98
|
+
super.updated(changedProperties);
|
|
99
|
+
|
|
100
|
+
if (changedProperties.has("_content") && this._content && !this.error) {
|
|
101
|
+
await this.renderPdf();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private async renderPdf() {
|
|
106
|
+
const container = this.querySelector("#pdf-container");
|
|
107
|
+
if (!container || !this._content) return;
|
|
108
|
+
|
|
109
|
+
let pdf: any = null;
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const arrayBuffer = this.base64ToArrayBuffer(this._content);
|
|
113
|
+
|
|
114
|
+
// Cancel any existing loading task
|
|
115
|
+
if (this.currentLoadingTask) {
|
|
116
|
+
this.currentLoadingTask.destroy();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Load the PDF
|
|
120
|
+
this.currentLoadingTask = pdfjsLib.getDocument({ data: arrayBuffer });
|
|
121
|
+
pdf = await this.currentLoadingTask.promise;
|
|
122
|
+
this.currentLoadingTask = null;
|
|
123
|
+
|
|
124
|
+
// Clear container
|
|
125
|
+
container.innerHTML = "";
|
|
126
|
+
const wrapper = document.createElement("div");
|
|
127
|
+
wrapper.className = "p-4";
|
|
128
|
+
container.appendChild(wrapper);
|
|
129
|
+
|
|
130
|
+
// Render all pages
|
|
131
|
+
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
|
132
|
+
const page = await pdf.getPage(pageNum);
|
|
133
|
+
|
|
134
|
+
const pageContainer = document.createElement("div");
|
|
135
|
+
pageContainer.className = "mb-4 last:mb-0";
|
|
136
|
+
|
|
137
|
+
const canvas = document.createElement("canvas");
|
|
138
|
+
const context = canvas.getContext("2d");
|
|
139
|
+
|
|
140
|
+
const viewport = page.getViewport({ scale: 1.5 });
|
|
141
|
+
canvas.height = viewport.height;
|
|
142
|
+
canvas.width = viewport.width;
|
|
143
|
+
|
|
144
|
+
canvas.className = "w-full max-w-full h-auto block mx-auto bg-white rounded shadow-sm border border-border";
|
|
145
|
+
|
|
146
|
+
if (context) {
|
|
147
|
+
context.fillStyle = "white";
|
|
148
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
await page.render({
|
|
152
|
+
canvasContext: context!,
|
|
153
|
+
viewport: viewport,
|
|
154
|
+
canvas: canvas,
|
|
155
|
+
}).promise;
|
|
156
|
+
|
|
157
|
+
pageContainer.appendChild(canvas);
|
|
158
|
+
|
|
159
|
+
if (pageNum < pdf.numPages) {
|
|
160
|
+
const separator = document.createElement("div");
|
|
161
|
+
separator.className = "h-px bg-border my-4";
|
|
162
|
+
pageContainer.appendChild(separator);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
wrapper.appendChild(pageContainer);
|
|
166
|
+
}
|
|
167
|
+
} catch (error: any) {
|
|
168
|
+
console.error("Error rendering PDF:", error);
|
|
169
|
+
this.error = error?.message || i18n("Failed to load PDF");
|
|
170
|
+
} finally {
|
|
171
|
+
if (pdf) {
|
|
172
|
+
pdf.destroy();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
override render(): TemplateResult {
|
|
178
|
+
if (this.error) {
|
|
179
|
+
return html`
|
|
180
|
+
<div class="h-full flex items-center justify-center bg-background p-4">
|
|
181
|
+
<div class="bg-destructive/10 border border-destructive text-destructive p-4 rounded-lg max-w-2xl">
|
|
182
|
+
<div class="font-medium mb-1">${i18n("Error loading PDF")}</div>
|
|
183
|
+
<div class="text-sm opacity-90">${this.error}</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return html`
|
|
190
|
+
<div class="h-full flex flex-col bg-background overflow-auto">
|
|
191
|
+
<div id="pdf-container" class="flex-1 overflow-auto"></div>
|
|
192
|
+
</div>
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
declare global {
|
|
198
|
+
interface HTMLElementTagNameMap {
|
|
199
|
+
"pdf-artifact": PdfArtifact;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -9,7 +9,6 @@ import { ArtifactElement } from "./ArtifactElement.js";
|
|
|
9
9
|
@customElement("svg-artifact")
|
|
10
10
|
export class SvgArtifact extends ArtifactElement {
|
|
11
11
|
@property() override filename = "";
|
|
12
|
-
@property({ attribute: false }) override displayTitle = "";
|
|
13
12
|
|
|
14
13
|
private _content = "";
|
|
15
14
|
override get content(): string {
|
|
@@ -56,7 +56,6 @@ const CODE_EXTENSIONS = [
|
|
|
56
56
|
@customElement("text-artifact")
|
|
57
57
|
export class TextArtifact extends ArtifactElement {
|
|
58
58
|
@property() override filename = "";
|
|
59
|
-
@property({ attribute: false }) override displayTitle = "";
|
|
60
59
|
|
|
61
60
|
private _content = "";
|
|
62
61
|
override get content(): string {
|