refactorings
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Chat } from "./chat"
|
||||
import { WerkChatSession } from "@kontextwerk/web-sdk"
|
||||
import InputRow from "./InputRow.svelte"
|
||||
import Messages from "./Messages.svelte"
|
||||
function generateUniqueId() {
|
||||
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
|
||||
}
|
||||
let chat = $derived(
|
||||
new Chat(generateUniqueId(), {
|
||||
new WerkChatSession(generateUniqueId(), {
|
||||
url: "https://2schat-server.robins-spielwiese.de/api/v1/chatbot/stream",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { mdiSendVariantOutline } from "@mdi/js"
|
||||
import Icon from "../widgets/Icon.svelte"
|
||||
import type { Chat } from "./chat"
|
||||
let { chat }: { chat: Chat } = $props()
|
||||
import type { WerkChatSession } from "@kontextwerk/web-sdk"
|
||||
let { chat }: { chat: WerkChatSession } = $props()
|
||||
let value = $state("")
|
||||
let textareaEl: HTMLTextAreaElement = $state(null)
|
||||
function autoResize() {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type { Chat } from "./chat"
|
||||
import type { WerkChatSession } from "@kontextwerk/web-sdk"
|
||||
let {
|
||||
chat,
|
||||
}: {
|
||||
chat: Chat
|
||||
chat: WerkChatSession
|
||||
} = $props()
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,175 +1,2 @@
|
||||
import { fetchEventSource } from "@microsoft/fetch-event-source"
|
||||
|
||||
export type Role = "user" | "assistant" | "system"
|
||||
|
||||
export interface ChatMessage {
|
||||
role: Role
|
||||
content: string
|
||||
}
|
||||
|
||||
export interface ChatRequestPayload {
|
||||
user_id: string
|
||||
message: string
|
||||
session_id: string
|
||||
}
|
||||
|
||||
type ServerEvent =
|
||||
| { type: "token"; delta: string }
|
||||
| { type: "heartbeat" }
|
||||
| { type: "error"; message: string }
|
||||
| { type: "final"; state: unknown }
|
||||
|
||||
// Optionale Konfiguration für Headers, URL usw.
|
||||
export interface ChatOptions {
|
||||
/** Vollständige URL, z. B. "https://api.example.com/stream" */
|
||||
url: string
|
||||
/** Zusätzliche Request-Header (z. B. Auth) */
|
||||
headers?: Record<string, string>
|
||||
/** Fallback-Assistant-Fehlermeldung für die UI */
|
||||
fallbackErrorText?: string
|
||||
/** Offen lassen, wenn Tab im Hintergrund – sinnvoll für Safari */
|
||||
openWhenHidden?: boolean
|
||||
/** User-ID, wenn du sie nicht pro Aufruf übergibst */
|
||||
userId?: string
|
||||
}
|
||||
|
||||
export class Chat {
|
||||
public messages: ChatMessage[] = []
|
||||
public isStreaming = false
|
||||
public lastFinalState: unknown = null
|
||||
|
||||
private sessionId: string
|
||||
private opts: ChatOptions
|
||||
private controller: AbortController | null = null
|
||||
|
||||
constructor(sessionId: string, opts: ChatOptions) {
|
||||
if (!sessionId) throw new Error("session_id ist erforderlich")
|
||||
if (!opts?.url) throw new Error("ChatOptions.url ist erforderlich")
|
||||
this.sessionId = sessionId
|
||||
this.opts = {
|
||||
fallbackErrorText: "Es ist ein Fehler aufgetreten.",
|
||||
openWhenHidden: true,
|
||||
...opts,
|
||||
}
|
||||
}
|
||||
|
||||
public abortActiveStream() {
|
||||
this.controller?.abort()
|
||||
this.controller = null
|
||||
this.isStreaming = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Sendet eine Benutzer-Nachricht und streamt die Assistent-Antwort in `messages`.
|
||||
* @param message Text der Benutzer-Nachricht
|
||||
* @param userId optionaler Override der User-ID (falls nicht in opts.userId)
|
||||
*/
|
||||
public async generateResponse(message: string, userId?: string): Promise<void> {
|
||||
const text = (message ?? "").trim()
|
||||
if (!text) return
|
||||
if (this.isStreaming) this.abortActiveStream()
|
||||
this.messages = [...this.messages, { role: "user", content: text }]
|
||||
const assistantIndex = this.messages.length
|
||||
this.messages = [...this.messages, { role: "assistant", content: "" }]
|
||||
|
||||
const payload: ChatRequestPayload = {
|
||||
user_id: userId ?? this.opts.userId ?? "anonymous",
|
||||
message: text,
|
||||
session_id: this.sessionId,
|
||||
}
|
||||
|
||||
this.controller = new AbortController()
|
||||
this.isStreaming = true
|
||||
this.lastFinalState = null
|
||||
|
||||
try {
|
||||
await fetchEventSource(this.opts.url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(this.opts.headers ?? {}),
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
signal: this.controller.signal,
|
||||
openWhenHidden: this.opts.openWhenHidden,
|
||||
|
||||
onopen: async (res) => {
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
||||
},
|
||||
|
||||
onmessage: (ev) => {
|
||||
if (!ev.data) return
|
||||
let parsed: ServerEvent | null = null
|
||||
try {
|
||||
parsed = JSON.parse(ev.data) as ServerEvent
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
switch (parsed.type) {
|
||||
case "token": {
|
||||
const delta = parsed.delta ?? ""
|
||||
const updated = {
|
||||
...this.messages[assistantIndex],
|
||||
content: (this.messages[assistantIndex]?.content ?? "") + delta,
|
||||
}
|
||||
this.messages = [
|
||||
...this.messages.slice(0, assistantIndex),
|
||||
updated,
|
||||
...this.messages.slice(assistantIndex + 1),
|
||||
]
|
||||
break
|
||||
}
|
||||
|
||||
case "heartbeat": {
|
||||
break
|
||||
}
|
||||
|
||||
case "error": {
|
||||
const msg = parsed.message || this.opts.fallbackErrorText!
|
||||
const updated = {
|
||||
...this.messages[assistantIndex],
|
||||
content: (this.messages[assistantIndex]?.content || "") + `\n\n⚠️ ${msg}`,
|
||||
}
|
||||
this.messages = [
|
||||
...this.messages.slice(0, assistantIndex),
|
||||
updated,
|
||||
...this.messages.slice(assistantIndex + 1),
|
||||
]
|
||||
this.abortActiveStream()
|
||||
break
|
||||
}
|
||||
|
||||
case "final": {
|
||||
this.lastFinalState = parsed.state
|
||||
this.abortActiveStream()
|
||||
break
|
||||
}
|
||||
|
||||
default: {
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onerror: (err) => {
|
||||
const updated = {
|
||||
...this.messages[assistantIndex],
|
||||
content:
|
||||
(this.messages[assistantIndex]?.content || "") +
|
||||
`\n\n⚠️ ${this.opts.fallbackErrorText} (${String(err)})`,
|
||||
}
|
||||
this.messages = [
|
||||
...this.messages.slice(0, assistantIndex),
|
||||
updated,
|
||||
...this.messages.slice(assistantIndex + 1),
|
||||
]
|
||||
throw err
|
||||
},
|
||||
})
|
||||
} finally {
|
||||
this.isStreaming = false
|
||||
this.controller = null
|
||||
}
|
||||
}
|
||||
}
|
||||
export { WerkChatSession as Chat } from "@kontextwerk/web-sdk"
|
||||
export type { ChatMessage, ChatOptions } from "@kontextwerk/web-sdk"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { mdiBookAccountOutline, mdiCreation, mdiFaceAgent, mdiHours24 } from "@mdi/js"
|
||||
import ProductCategoryFrame from "../widgets/ProductCategoryFrame.svelte"
|
||||
import CrinkledSection from "../CrinkledSection.svelte"
|
||||
import { createVoicebotPreviewController } from "./voicebotPreviewController"
|
||||
import { createVoicebotPreviewController } from "../voicebotDemo/voicebotPreviewController"
|
||||
|
||||
const voiceProperties: Array<{ title: string; icon: string; color: string }> = [
|
||||
{
|
||||
@@ -149,12 +149,6 @@
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
&.connected {
|
||||
}
|
||||
|
||||
&.errored {
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--primary-200);
|
||||
outline-offset: 4px;
|
||||
|
||||
@@ -1,207 +1,2 @@
|
||||
import { derived, get, writable, type Readable } from "svelte/store"
|
||||
import {
|
||||
ConnectorLifecycleEvents,
|
||||
createVoiceConnector,
|
||||
WS_URL,
|
||||
} from "../voicebotDemo/helper"
|
||||
import type { WerkRealtimeConnector } from "../voicebotDemo/helper"
|
||||
|
||||
export type VoiceStatus = "idle" | "connecting" | "connected" | "error"
|
||||
|
||||
interface VoicebotPreviewController {
|
||||
status: Readable<VoiceStatus>
|
||||
errorMessage: Readable<string>
|
||||
statusHint: Readable<string>
|
||||
setup: () => void
|
||||
teardown: () => void
|
||||
start: () => Promise<void>
|
||||
stop: (silent?: boolean) => Promise<void>
|
||||
toggle: () => Promise<void>
|
||||
}
|
||||
|
||||
const isBrowser = typeof window !== "undefined"
|
||||
|
||||
const extractErrorMessage = (err: unknown, fallback: string) => {
|
||||
if (err instanceof DOMException) {
|
||||
if (err.name === "NotAllowedError") return "Zugriff auf das Mikrofon wurde verweigert."
|
||||
if (err.name === "NotFoundError") return "Kein Mikrofon gefunden oder verfügbar."
|
||||
if (err.name === "NotReadableError") return "Auf das Mikrofon konnte nicht zugegriffen werden."
|
||||
if (err.name === "SecurityError") return "Der Browser blockiert den Zugriff – bitte die Seite über HTTPS öffnen."
|
||||
}
|
||||
if (err instanceof Error && err.message) return err.message
|
||||
return fallback
|
||||
}
|
||||
|
||||
export const createVoicebotPreviewController = (): VoicebotPreviewController => {
|
||||
const statusStore = writable<VoiceStatus>("idle")
|
||||
const errorStore = writable("")
|
||||
|
||||
const statusHint = derived([statusStore, errorStore], ([$status, $error]) => {
|
||||
switch ($status) {
|
||||
case "idle":
|
||||
return "Tippen, um die Voice-Demo zu starten"
|
||||
case "connecting":
|
||||
return "Verbindung wird aufgebaut …"
|
||||
case "connected":
|
||||
return "Live – sprechen Sie jetzt"
|
||||
case "error":
|
||||
return $error || "Verbindung fehlgeschlagen"
|
||||
default:
|
||||
return "Voice-Demo"
|
||||
}
|
||||
})
|
||||
|
||||
let connector: WerkRealtimeConnector | null = null
|
||||
let detachHandlers: Array<() => void> = []
|
||||
let startPromise: Promise<void> | null = null
|
||||
let stopPromise: Promise<void> | null = null
|
||||
let closing = false
|
||||
const handleRealtimeEvent = (rawType: string, msg: any) => {
|
||||
const type = rawType
|
||||
if (!type) return
|
||||
|
||||
const now = new Date()
|
||||
|
||||
}
|
||||
const ensureConnector = () => {
|
||||
if (!isBrowser || connector) return
|
||||
|
||||
const instance = createVoiceConnector()
|
||||
|
||||
const detachConnecting = instance.onLifecycle(ConnectorLifecycleEvents.CONNECTING, () => {
|
||||
statusStore.set("connecting")
|
||||
errorStore.set("")
|
||||
})
|
||||
const detachConnected = instance.onLifecycle(ConnectorLifecycleEvents.CONNECTED, () => {
|
||||
statusStore.set("connected")
|
||||
closing = false
|
||||
})
|
||||
const detachDisconnected = instance.onLifecycle(ConnectorLifecycleEvents.DISCONNECTED, () => {
|
||||
if (closing) {
|
||||
closing = false
|
||||
return
|
||||
}
|
||||
if (get(statusStore) !== "error") {
|
||||
statusStore.set("idle")
|
||||
errorStore.set("")
|
||||
}
|
||||
})
|
||||
const detachError = instance.onLifecycle(ConnectorLifecycleEvents.ERROR, (evt) => {
|
||||
const message =
|
||||
typeof evt?.message === "string" && evt.message.trim().length
|
||||
? evt.message
|
||||
: "Verbindung fehlgeschlagen"
|
||||
errorStore.set(`${message} (${WS_URL})`)
|
||||
statusStore.set("error")
|
||||
closing = false
|
||||
})
|
||||
|
||||
detachHandlers = [detachConnecting, detachConnected, detachDisconnected, detachError]
|
||||
connector = instance
|
||||
}
|
||||
|
||||
const cleanupConnector = () => {
|
||||
detachHandlers.forEach((fn) => fn())
|
||||
detachHandlers = []
|
||||
const instance = connector
|
||||
connector = null
|
||||
if (instance) {
|
||||
void instance.stop()
|
||||
}
|
||||
startPromise = null
|
||||
stopPromise = null
|
||||
closing = false
|
||||
}
|
||||
|
||||
const stop = async (silent = false) => {
|
||||
if (!connector) return
|
||||
if (stopPromise) {
|
||||
await stopPromise
|
||||
return
|
||||
}
|
||||
|
||||
closing = true
|
||||
if (!silent && get(statusStore) !== "error") {
|
||||
statusStore.set("idle")
|
||||
errorStore.set("")
|
||||
}
|
||||
|
||||
stopPromise = connector.stop()
|
||||
|
||||
try {
|
||||
await stopPromise
|
||||
} catch (err) {
|
||||
console.error("VoicebotPreview stop error", err)
|
||||
if (!silent) {
|
||||
errorStore.set(extractErrorMessage(err, "Verbindung konnte nicht beendet werden."))
|
||||
statusStore.set("error")
|
||||
}
|
||||
} finally {
|
||||
stopPromise = null
|
||||
closing = false
|
||||
}
|
||||
}
|
||||
|
||||
const start = async () => {
|
||||
if (!isBrowser) {
|
||||
statusStore.set("error")
|
||||
errorStore.set("Die Sprach-Demo steht nur im Browser zur Verfügung.")
|
||||
return
|
||||
}
|
||||
|
||||
ensureConnector()
|
||||
if (!connector || startPromise) return
|
||||
|
||||
await stop(true)
|
||||
|
||||
statusStore.set("connecting")
|
||||
errorStore.set("")
|
||||
|
||||
startPromise = (async () => {
|
||||
await connector!.start()
|
||||
connector!.setInputMuted(false)
|
||||
connector!.setOutputMuted(false)
|
||||
})()
|
||||
|
||||
try {
|
||||
await startPromise
|
||||
} catch (err) {
|
||||
console.error("VoicebotPreview start error", err)
|
||||
errorStore.set(extractErrorMessage(err, "Verbindung konnte nicht aufgebaut werden."))
|
||||
statusStore.set("error")
|
||||
closing = false
|
||||
} finally {
|
||||
startPromise = null
|
||||
}
|
||||
}
|
||||
|
||||
const toggle = async () => {
|
||||
const current = get(statusStore)
|
||||
if (current === "connecting") return
|
||||
if (current === "connected") {
|
||||
await stop()
|
||||
return
|
||||
}
|
||||
await start()
|
||||
}
|
||||
|
||||
const setup = () => {
|
||||
ensureConnector()
|
||||
}
|
||||
|
||||
const teardown = () => {
|
||||
void stop(true)
|
||||
cleanupConnector()
|
||||
}
|
||||
|
||||
return {
|
||||
status: { subscribe: statusStore.subscribe },
|
||||
errorMessage: { subscribe: errorStore.subscribe },
|
||||
statusHint,
|
||||
setup,
|
||||
teardown,
|
||||
start,
|
||||
stop,
|
||||
toggle,
|
||||
}
|
||||
}
|
||||
export { createVoicebotPreviewController } from "../voicebotDemo/voicebotPreviewController"
|
||||
export type { VoiceStatus } from "../voicebotDemo/voicebotPreviewController"
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
import { derived, get, writable, type Readable } from "svelte/store"
|
||||
import { ConnectorLifecycleEvents, createVoiceConnector, WS_URL } from "./helper"
|
||||
import type { WerkRealtimeConnector } from "./helper"
|
||||
|
||||
export type VoiceStatus = "idle" | "connecting" | "connected" | "error"
|
||||
|
||||
interface VoicebotPreviewController {
|
||||
status: Readable<VoiceStatus>
|
||||
errorMessage: Readable<string>
|
||||
statusHint: Readable<string>
|
||||
setup: () => void
|
||||
teardown: () => void
|
||||
start: () => Promise<void>
|
||||
stop: (silent?: boolean) => Promise<void>
|
||||
toggle: () => Promise<void>
|
||||
}
|
||||
|
||||
const isBrowser = typeof window !== "undefined"
|
||||
|
||||
const extractErrorMessage = (err: unknown, fallback: string) => {
|
||||
if (err instanceof DOMException) {
|
||||
if (err.name === "NotAllowedError") return "Zugriff auf das Mikrofon wurde verweigert."
|
||||
if (err.name === "NotFoundError") return "Kein Mikrofon gefunden oder verfügbar."
|
||||
if (err.name === "NotReadableError") return "Auf das Mikrofon konnte nicht zugegriffen werden."
|
||||
if (err.name === "SecurityError") {
|
||||
return "Der Browser blockiert den Zugriff – bitte die Seite über HTTPS öffnen."
|
||||
}
|
||||
}
|
||||
if (err instanceof Error && err.message) return err.message
|
||||
return fallback
|
||||
}
|
||||
|
||||
export const createVoicebotPreviewController = (): VoicebotPreviewController => {
|
||||
const statusStore = writable<VoiceStatus>("idle")
|
||||
const errorStore = writable("")
|
||||
|
||||
const statusHint = derived([statusStore, errorStore], ([$status, $error]) => {
|
||||
switch ($status) {
|
||||
case "idle":
|
||||
return "Tippen, um die Voice-Demo zu starten"
|
||||
case "connecting":
|
||||
return "Verbindung wird aufgebaut …"
|
||||
case "connected":
|
||||
return "Live – sprechen Sie jetzt"
|
||||
case "error":
|
||||
return $error || "Verbindung fehlgeschlagen"
|
||||
default:
|
||||
return "Voice-Demo"
|
||||
}
|
||||
})
|
||||
|
||||
let connector: WerkRealtimeConnector | null = null
|
||||
let detachHandlers: Array<() => void> = []
|
||||
let startPromise: Promise<void> | null = null
|
||||
let stopPromise: Promise<void> | null = null
|
||||
let closing = false
|
||||
|
||||
const ensureConnector = () => {
|
||||
if (!isBrowser || connector) return
|
||||
|
||||
const instance = createVoiceConnector()
|
||||
|
||||
const detachConnecting = instance.onLifecycle(ConnectorLifecycleEvents.CONNECTING, () => {
|
||||
statusStore.set("connecting")
|
||||
errorStore.set("")
|
||||
})
|
||||
const detachConnected = instance.onLifecycle(ConnectorLifecycleEvents.CONNECTED, () => {
|
||||
statusStore.set("connected")
|
||||
closing = false
|
||||
})
|
||||
const detachDisconnected = instance.onLifecycle(ConnectorLifecycleEvents.DISCONNECTED, () => {
|
||||
if (closing) {
|
||||
closing = false
|
||||
return
|
||||
}
|
||||
if (get(statusStore) !== "error") {
|
||||
statusStore.set("idle")
|
||||
errorStore.set("")
|
||||
}
|
||||
})
|
||||
const detachError = instance.onLifecycle(ConnectorLifecycleEvents.ERROR, (evt) => {
|
||||
const message =
|
||||
typeof evt?.message === "string" && evt.message.trim().length
|
||||
? evt.message
|
||||
: "Verbindung fehlgeschlagen"
|
||||
errorStore.set(`${message} (${WS_URL})`)
|
||||
statusStore.set("error")
|
||||
closing = false
|
||||
})
|
||||
|
||||
detachHandlers = [detachConnecting, detachConnected, detachDisconnected, detachError]
|
||||
connector = instance
|
||||
}
|
||||
|
||||
const cleanupConnector = () => {
|
||||
detachHandlers.forEach((fn) => fn())
|
||||
detachHandlers = []
|
||||
const instance = connector
|
||||
connector = null
|
||||
if (instance) {
|
||||
void instance.stop()
|
||||
}
|
||||
startPromise = null
|
||||
stopPromise = null
|
||||
closing = false
|
||||
}
|
||||
|
||||
const stop = async (silent = false) => {
|
||||
if (!connector) return
|
||||
if (stopPromise) {
|
||||
await stopPromise
|
||||
return
|
||||
}
|
||||
|
||||
closing = true
|
||||
if (!silent && get(statusStore) !== "error") {
|
||||
statusStore.set("idle")
|
||||
errorStore.set("")
|
||||
}
|
||||
|
||||
stopPromise = connector.stop()
|
||||
|
||||
try {
|
||||
await stopPromise
|
||||
} catch (err) {
|
||||
console.error("VoicebotPreview stop error", err)
|
||||
if (!silent) {
|
||||
errorStore.set(extractErrorMessage(err, "Verbindung konnte nicht beendet werden."))
|
||||
statusStore.set("error")
|
||||
}
|
||||
} finally {
|
||||
stopPromise = null
|
||||
closing = false
|
||||
}
|
||||
}
|
||||
|
||||
const start = async () => {
|
||||
if (!isBrowser) {
|
||||
statusStore.set("error")
|
||||
errorStore.set("Die Sprach-Demo steht nur im Browser zur Verfügung.")
|
||||
return
|
||||
}
|
||||
|
||||
ensureConnector()
|
||||
if (!connector || startPromise) return
|
||||
|
||||
await stop(true)
|
||||
|
||||
statusStore.set("connecting")
|
||||
errorStore.set("")
|
||||
|
||||
startPromise = (async () => {
|
||||
await connector!.start()
|
||||
connector!.setInputMuted(false)
|
||||
connector!.setOutputMuted(false)
|
||||
})()
|
||||
|
||||
try {
|
||||
await startPromise
|
||||
} catch (err) {
|
||||
console.error("VoicebotPreview start error", err)
|
||||
errorStore.set(extractErrorMessage(err, "Verbindung konnte nicht aufgebaut werden."))
|
||||
statusStore.set("error")
|
||||
closing = false
|
||||
} finally {
|
||||
startPromise = null
|
||||
}
|
||||
}
|
||||
|
||||
const toggle = async () => {
|
||||
const current = get(statusStore)
|
||||
if (current === "connecting") return
|
||||
if (current === "connected") {
|
||||
await stop()
|
||||
return
|
||||
}
|
||||
await start()
|
||||
}
|
||||
|
||||
const setup = () => {
|
||||
ensureConnector()
|
||||
}
|
||||
|
||||
const teardown = () => {
|
||||
void stop(true)
|
||||
cleanupConnector()
|
||||
}
|
||||
|
||||
return {
|
||||
status: { subscribe: statusStore.subscribe },
|
||||
errorMessage: { subscribe: errorStore.subscribe },
|
||||
statusHint,
|
||||
setup,
|
||||
teardown,
|
||||
start,
|
||||
stop,
|
||||
toggle,
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
"upload:sourcemaps": "scripts/upload-sourcemaps.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.27.2",
|
||||
"@babel/cli": "^7.28.3",
|
||||
"@babel/core": "^7.27.1",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.27.1",
|
||||
"@babel/preset-env": "^7.27.2",
|
||||
@@ -55,7 +55,7 @@
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kontextwerk/web-sdk": "0.1.0",
|
||||
"@kontextwerk/web-sdk": "0.1.1",
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@okrad/svelte-progressbar": "^2.2.0",
|
||||
|
||||
14
yarn.lock
14
yarn.lock
@@ -5,7 +5,7 @@ __metadata:
|
||||
version: 6
|
||||
cacheKey: 8
|
||||
|
||||
"@babel/cli@npm:^7.27.2":
|
||||
"@babel/cli@npm:^7.28.3":
|
||||
version: 7.28.3
|
||||
resolution: "@babel/cli@npm:7.28.3"
|
||||
dependencies:
|
||||
@@ -1779,12 +1779,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@kontextwerk/web-sdk@npm:0.1.0":
|
||||
version: 0.1.0
|
||||
resolution: "@kontextwerk/web-sdk@npm:0.1.0"
|
||||
"@kontextwerk/web-sdk@npm:0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "@kontextwerk/web-sdk@npm:0.1.1"
|
||||
dependencies:
|
||||
zod: ^3.23.8
|
||||
checksum: b99d6a71584c1db40ab2eb83f5b269bca6a70c4eec4c644eed0873e909c08fbae9600556599b7012ff13fb6150086687612c59c98c2f03699ad8559302090f83
|
||||
checksum: 8b7aa7608f2f71efc6c299088eb4f9f89fcd18b49edad194cd8e19e9ac6617c762f092ad286d3974f781acfc5137a7154f350e673c030f6cfe92f54fb2a9898b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6092,11 +6092,11 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "renz-shop-2020@workspace:."
|
||||
dependencies:
|
||||
"@babel/cli": ^7.27.2
|
||||
"@babel/cli": ^7.28.3
|
||||
"@babel/core": ^7.27.1
|
||||
"@babel/plugin-transform-async-to-generator": ^7.27.1
|
||||
"@babel/preset-env": ^7.27.2
|
||||
"@kontextwerk/web-sdk": 0.1.0
|
||||
"@kontextwerk/web-sdk": 0.1.1
|
||||
"@mdi/js": ^7.4.47
|
||||
"@microsoft/fetch-event-source": ^2.0.1
|
||||
"@okrad/svelte-progressbar": ^2.2.0
|
||||
|
||||
Reference in New Issue
Block a user