@liforma/client 0.2.1
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/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +103 -0
- package/dist/next/index.js +5186 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/next/createLiformaSessionRouteHandler.d.ts +45 -0
- package/dist/next/next/createLiformaSessionRouteHandler.d.ts.map +1 -0
- package/dist/next/next/index.d.ts +8 -0
- package/dist/next/next/index.d.ts.map +1 -0
- package/dist/next/react/ExperienceThumbnail.d.ts +22 -0
- package/dist/next/react/ExperienceThumbnail.d.ts.map +1 -0
- package/dist/next/react/ExperienceWidget.d.ts +35 -0
- package/dist/next/react/ExperienceWidget.d.ts.map +1 -0
- package/dist/next/shims/apiBaseUrl.d.ts +14 -0
- package/dist/next/shims/apiBaseUrl.d.ts.map +1 -0
- package/dist/next/shims/localStack.d.ts +6 -0
- package/dist/next/shims/localStack.d.ts.map +1 -0
- package/dist/next/thumbnail/attachThumbnailParallax.d.ts +7 -0
- package/dist/next/thumbnail/attachThumbnailParallax.d.ts.map +1 -0
- package/dist/next/thumbnail/ensureStyles.d.ts +3 -0
- package/dist/next/thumbnail/ensureStyles.d.ts.map +1 -0
- package/dist/next/thumbnail/hostedLaunchUrl.d.ts +23 -0
- package/dist/next/thumbnail/hostedLaunchUrl.d.ts.map +1 -0
- package/dist/next/thumbnail/index.d.ts +9 -0
- package/dist/next/thumbnail/index.d.ts.map +1 -0
- package/dist/next/thumbnail/lazyLoad.d.ts +8 -0
- package/dist/next/thumbnail/lazyLoad.d.ts.map +1 -0
- package/dist/next/thumbnail/scrollParallax.d.ts +13 -0
- package/dist/next/thumbnail/scrollParallax.d.ts.map +1 -0
- package/dist/next/thumbnail/styles.d.ts +3 -0
- package/dist/next/thumbnail/styles.d.ts.map +1 -0
- package/dist/next/thumbnail/toGalleryThumbUrl.d.ts +23 -0
- package/dist/next/thumbnail/toGalleryThumbUrl.d.ts.map +1 -0
- package/dist/next/thumbnail/toGalleryThumbUrl.test.d.ts +2 -0
- package/dist/next/thumbnail/toGalleryThumbUrl.test.d.ts.map +1 -0
- package/dist/next/thumbnail/types.d.ts +37 -0
- package/dist/next/thumbnail/types.d.ts.map +1 -0
- package/dist/next/v2/api/fetchExperiencePreview.d.ts +15 -0
- package/dist/next/v2/api/fetchExperiencePreview.d.ts.map +1 -0
- package/dist/next/v2/api/mintPublicSession.d.ts +25 -0
- package/dist/next/v2/api/mintPublicSession.d.ts.map +1 -0
- package/dist/next/v2/api/sessionEndpointRequest.d.ts +16 -0
- package/dist/next/v2/api/sessionEndpointRequest.d.ts.map +1 -0
- package/dist/next/v2/conversationProcessor.d.ts +6 -0
- package/dist/next/v2/conversationProcessor.d.ts.map +1 -0
- package/dist/next/v2/embed/iframeHost.d.ts +70 -0
- package/dist/next/v2/embed/iframeHost.d.ts.map +1 -0
- package/dist/next/v2/embed/playerReachability.d.ts +4 -0
- package/dist/next/v2/embed/playerReachability.d.ts.map +1 -0
- package/dist/next/v2/embed/protocol.d.ts +181 -0
- package/dist/next/v2/embed/protocol.d.ts.map +1 -0
- package/dist/next/v2/embed/readyGate.d.ts +7 -0
- package/dist/next/v2/embed/readyGate.d.ts.map +1 -0
- package/dist/next/v2/experience.d.ts +133 -0
- package/dist/next/v2/experience.d.ts.map +1 -0
- package/dist/next/v2/experienceEvents.d.ts +27 -0
- package/dist/next/v2/experienceEvents.d.ts.map +1 -0
- package/dist/next/v2/shims/embedBaseUrl.d.ts +19 -0
- package/dist/next/v2/shims/embedBaseUrl.d.ts.map +1 -0
- package/dist/next/v2/speechOnlyManifest.d.ts +7 -0
- package/dist/next/v2/speechOnlyManifest.d.ts.map +1 -0
- package/dist/next/v2/types/sessionInteraction.d.ts +120 -0
- package/dist/next/v2/types/sessionInteraction.d.ts.map +1 -0
- package/dist/next/v2/types/sessionManifest.d.ts +93 -0
- package/dist/next/v2/types/sessionManifest.d.ts.map +1 -0
- package/dist/next/v2/types/sessionManifestSchema.d.ts +183 -0
- package/dist/next/v2/types/sessionManifestSchema.d.ts.map +1 -0
- package/dist/next/v2/types/sessionPipeline.d.ts +23 -0
- package/dist/next/v2/types/sessionPipeline.d.ts.map +1 -0
- package/dist/next/widget/dockGeometry.d.ts +26 -0
- package/dist/next/widget/dockGeometry.d.ts.map +1 -0
- package/dist/next/widget/index.d.ts +5 -0
- package/dist/next/widget/index.d.ts.map +1 -0
- package/dist/next/widget/mountExperienceWidget.d.ts +13 -0
- package/dist/next/widget/mountExperienceWidget.d.ts.map +1 -0
- package/dist/next/widget/styles.d.ts +4 -0
- package/dist/next/widget/styles.d.ts.map +1 -0
- package/dist/next/widget/types.d.ts +62 -0
- package/dist/next/widget/types.d.ts.map +1 -0
- package/dist/npm/index.js +4859 -0
- package/dist/npm/index.js.map +1 -0
- package/dist/npm/shims/apiBaseUrl.d.ts +14 -0
- package/dist/npm/shims/apiBaseUrl.d.ts.map +1 -0
- package/dist/npm/shims/localStack.d.ts +6 -0
- package/dist/npm/shims/localStack.d.ts.map +1 -0
- package/dist/npm/svelte/experienceLoadError.d.ts +16 -0
- package/dist/npm/svelte/experienceLoadError.d.ts.map +1 -0
- package/dist/npm/svelte/experienceLoadErrorOverlay.d.ts +8 -0
- package/dist/npm/svelte/experienceLoadErrorOverlay.d.ts.map +1 -0
- package/dist/npm/svelte/experienceLoadErrorStyles.d.ts +5 -0
- package/dist/npm/svelte/experienceLoadErrorStyles.d.ts.map +1 -0
- package/dist/npm/thumbnail/attachThumbnailParallax.d.ts +7 -0
- package/dist/npm/thumbnail/attachThumbnailParallax.d.ts.map +1 -0
- package/dist/npm/thumbnail/ensureStyles.d.ts +3 -0
- package/dist/npm/thumbnail/ensureStyles.d.ts.map +1 -0
- package/dist/npm/thumbnail/hostedLaunchUrl.d.ts +23 -0
- package/dist/npm/thumbnail/hostedLaunchUrl.d.ts.map +1 -0
- package/dist/npm/thumbnail/index.d.ts +9 -0
- package/dist/npm/thumbnail/index.d.ts.map +1 -0
- package/dist/npm/thumbnail/lazyLoad.d.ts +8 -0
- package/dist/npm/thumbnail/lazyLoad.d.ts.map +1 -0
- package/dist/npm/thumbnail/scrollParallax.d.ts +13 -0
- package/dist/npm/thumbnail/scrollParallax.d.ts.map +1 -0
- package/dist/npm/thumbnail/styles.d.ts +3 -0
- package/dist/npm/thumbnail/styles.d.ts.map +1 -0
- package/dist/npm/thumbnail/toGalleryThumbUrl.d.ts +23 -0
- package/dist/npm/thumbnail/toGalleryThumbUrl.d.ts.map +1 -0
- package/dist/npm/thumbnail/types.d.ts +37 -0
- package/dist/npm/thumbnail/types.d.ts.map +1 -0
- package/dist/npm/v2/api/fetchExperiencePreview.d.ts +15 -0
- package/dist/npm/v2/api/fetchExperiencePreview.d.ts.map +1 -0
- package/dist/npm/v2/api/mintPublicSession.d.ts +25 -0
- package/dist/npm/v2/api/mintPublicSession.d.ts.map +1 -0
- package/dist/npm/v2/api/sessionEndpointRequest.d.ts +16 -0
- package/dist/npm/v2/api/sessionEndpointRequest.d.ts.map +1 -0
- package/dist/npm/v2/conversationProcessor.d.ts +6 -0
- package/dist/npm/v2/conversationProcessor.d.ts.map +1 -0
- package/dist/npm/v2/embed/iframeHost.d.ts +70 -0
- package/dist/npm/v2/embed/iframeHost.d.ts.map +1 -0
- package/dist/npm/v2/embed/playerReachability.d.ts +4 -0
- package/dist/npm/v2/embed/playerReachability.d.ts.map +1 -0
- package/dist/npm/v2/embed/protocol.d.ts +181 -0
- package/dist/npm/v2/embed/protocol.d.ts.map +1 -0
- package/dist/npm/v2/embed/readyGate.d.ts +7 -0
- package/dist/npm/v2/embed/readyGate.d.ts.map +1 -0
- package/dist/npm/v2/embed/returnNavigation.d.ts +4 -0
- package/dist/npm/v2/embed/returnNavigation.d.ts.map +1 -0
- package/dist/npm/v2/experience.d.ts +133 -0
- package/dist/npm/v2/experience.d.ts.map +1 -0
- package/dist/npm/v2/experienceEvents.d.ts +27 -0
- package/dist/npm/v2/experienceEvents.d.ts.map +1 -0
- package/dist/npm/v2/index.d.ts +21 -0
- package/dist/npm/v2/index.d.ts.map +1 -0
- package/dist/npm/v2/liforma-experience-thumbnail.d.ts +9 -0
- package/dist/npm/v2/liforma-experience-thumbnail.d.ts.map +1 -0
- package/dist/npm/v2/liforma-experience-widget.d.ts +8 -0
- package/dist/npm/v2/liforma-experience-widget.d.ts.map +1 -0
- package/dist/npm/v2/liforma-experience.d.ts +15 -0
- package/dist/npm/v2/liforma-experience.d.ts.map +1 -0
- package/dist/npm/v2/npm.d.ts +10 -0
- package/dist/npm/v2/npm.d.ts.map +1 -0
- package/dist/npm/v2/shims/embedBaseUrl.d.ts +19 -0
- package/dist/npm/v2/shims/embedBaseUrl.d.ts.map +1 -0
- package/dist/npm/v2/speechOnlyManifest.d.ts +7 -0
- package/dist/npm/v2/speechOnlyManifest.d.ts.map +1 -0
- package/dist/npm/v2/types/index.d.ts +3 -0
- package/dist/npm/v2/types/index.d.ts.map +1 -0
- package/dist/npm/v2/types/sessionInteraction.d.ts +120 -0
- package/dist/npm/v2/types/sessionInteraction.d.ts.map +1 -0
- package/dist/npm/v2/types/sessionManifest.d.ts +93 -0
- package/dist/npm/v2/types/sessionManifest.d.ts.map +1 -0
- package/dist/npm/v2/types/sessionManifestSchema.d.ts +183 -0
- package/dist/npm/v2/types/sessionManifestSchema.d.ts.map +1 -0
- package/dist/npm/v2/types/sessionPipeline.d.ts +23 -0
- package/dist/npm/v2/types/sessionPipeline.d.ts.map +1 -0
- package/dist/npm/widget/dockGeometry.d.ts +26 -0
- package/dist/npm/widget/dockGeometry.d.ts.map +1 -0
- package/dist/npm/widget/index.d.ts +5 -0
- package/dist/npm/widget/index.d.ts.map +1 -0
- package/dist/npm/widget/mountExperienceWidget.d.ts +13 -0
- package/dist/npm/widget/mountExperienceWidget.d.ts.map +1 -0
- package/dist/npm/widget/styles.d.ts +4 -0
- package/dist/npm/widget/styles.d.ts.map +1 -0
- package/dist/npm/widget/types.d.ts +62 -0
- package/dist/npm/widget/types.d.ts.map +1 -0
- package/dist/react/component/experienceComponentLaunch.d.ts +7 -0
- package/dist/react/component/experienceComponentLaunch.d.ts.map +1 -0
- package/dist/react/component/experienceComponentRuntime.d.ts +55 -0
- package/dist/react/component/experienceComponentRuntime.d.ts.map +1 -0
- package/dist/react/component/experienceComponentTypes.d.ts +60 -0
- package/dist/react/component/experienceComponentTypes.d.ts.map +1 -0
- package/dist/react/index.js +5499 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/react/Experience.d.ts +4 -0
- package/dist/react/react/Experience.d.ts.map +1 -0
- package/dist/react/react/ExperienceThumbnail.d.ts +22 -0
- package/dist/react/react/ExperienceThumbnail.d.ts.map +1 -0
- package/dist/react/react/ExperienceWidget.d.ts +35 -0
- package/dist/react/react/ExperienceWidget.d.ts.map +1 -0
- package/dist/react/react/index.d.ts +8 -0
- package/dist/react/react/index.d.ts.map +1 -0
- package/dist/react/shims/apiBaseUrl.d.ts +14 -0
- package/dist/react/shims/apiBaseUrl.d.ts.map +1 -0
- package/dist/react/shims/localStack.d.ts +6 -0
- package/dist/react/shims/localStack.d.ts.map +1 -0
- package/dist/react/svelte/experienceLoadError.d.ts +16 -0
- package/dist/react/svelte/experienceLoadError.d.ts.map +1 -0
- package/dist/react/svelte/experienceLoadErrorOverlay.d.ts +8 -0
- package/dist/react/svelte/experienceLoadErrorOverlay.d.ts.map +1 -0
- package/dist/react/svelte/experienceLoadErrorStyles.d.ts +5 -0
- package/dist/react/svelte/experienceLoadErrorStyles.d.ts.map +1 -0
- package/dist/react/thumbnail/attachThumbnailParallax.d.ts +7 -0
- package/dist/react/thumbnail/attachThumbnailParallax.d.ts.map +1 -0
- package/dist/react/thumbnail/ensureStyles.d.ts +3 -0
- package/dist/react/thumbnail/ensureStyles.d.ts.map +1 -0
- package/dist/react/thumbnail/hostedLaunchUrl.d.ts +23 -0
- package/dist/react/thumbnail/hostedLaunchUrl.d.ts.map +1 -0
- package/dist/react/thumbnail/index.d.ts +9 -0
- package/dist/react/thumbnail/index.d.ts.map +1 -0
- package/dist/react/thumbnail/lazyLoad.d.ts +8 -0
- package/dist/react/thumbnail/lazyLoad.d.ts.map +1 -0
- package/dist/react/thumbnail/scrollParallax.d.ts +13 -0
- package/dist/react/thumbnail/scrollParallax.d.ts.map +1 -0
- package/dist/react/thumbnail/styles.d.ts +3 -0
- package/dist/react/thumbnail/styles.d.ts.map +1 -0
- package/dist/react/thumbnail/toGalleryThumbUrl.d.ts +23 -0
- package/dist/react/thumbnail/toGalleryThumbUrl.d.ts.map +1 -0
- package/dist/react/thumbnail/toGalleryThumbUrl.test.d.ts +2 -0
- package/dist/react/thumbnail/toGalleryThumbUrl.test.d.ts.map +1 -0
- package/dist/react/thumbnail/types.d.ts +37 -0
- package/dist/react/thumbnail/types.d.ts.map +1 -0
- package/dist/react/v2/api/fetchExperiencePreview.d.ts +15 -0
- package/dist/react/v2/api/fetchExperiencePreview.d.ts.map +1 -0
- package/dist/react/v2/api/mintPublicSession.d.ts +25 -0
- package/dist/react/v2/api/mintPublicSession.d.ts.map +1 -0
- package/dist/react/v2/api/sessionEndpointRequest.d.ts +16 -0
- package/dist/react/v2/api/sessionEndpointRequest.d.ts.map +1 -0
- package/dist/react/v2/conversationProcessor.d.ts +6 -0
- package/dist/react/v2/conversationProcessor.d.ts.map +1 -0
- package/dist/react/v2/embed/iframeHost.d.ts +70 -0
- package/dist/react/v2/embed/iframeHost.d.ts.map +1 -0
- package/dist/react/v2/embed/playerReachability.d.ts +4 -0
- package/dist/react/v2/embed/playerReachability.d.ts.map +1 -0
- package/dist/react/v2/embed/protocol.d.ts +181 -0
- package/dist/react/v2/embed/protocol.d.ts.map +1 -0
- package/dist/react/v2/embed/readyGate.d.ts +7 -0
- package/dist/react/v2/embed/readyGate.d.ts.map +1 -0
- package/dist/react/v2/experience.d.ts +133 -0
- package/dist/react/v2/experience.d.ts.map +1 -0
- package/dist/react/v2/experienceEvents.d.ts +27 -0
- package/dist/react/v2/experienceEvents.d.ts.map +1 -0
- package/dist/react/v2/shims/embedBaseUrl.d.ts +19 -0
- package/dist/react/v2/shims/embedBaseUrl.d.ts.map +1 -0
- package/dist/react/v2/speechOnlyManifest.d.ts +7 -0
- package/dist/react/v2/speechOnlyManifest.d.ts.map +1 -0
- package/dist/react/v2/types/sessionInteraction.d.ts +120 -0
- package/dist/react/v2/types/sessionInteraction.d.ts.map +1 -0
- package/dist/react/v2/types/sessionManifest.d.ts +93 -0
- package/dist/react/v2/types/sessionManifest.d.ts.map +1 -0
- package/dist/react/v2/types/sessionManifestSchema.d.ts +183 -0
- package/dist/react/v2/types/sessionManifestSchema.d.ts.map +1 -0
- package/dist/react/v2/types/sessionPipeline.d.ts +23 -0
- package/dist/react/v2/types/sessionPipeline.d.ts.map +1 -0
- package/dist/react/widget/dockGeometry.d.ts +26 -0
- package/dist/react/widget/dockGeometry.d.ts.map +1 -0
- package/dist/react/widget/index.d.ts +5 -0
- package/dist/react/widget/index.d.ts.map +1 -0
- package/dist/react/widget/mountExperienceWidget.d.ts +13 -0
- package/dist/react/widget/mountExperienceWidget.d.ts.map +1 -0
- package/dist/react/widget/styles.d.ts +4 -0
- package/dist/react/widget/styles.d.ts.map +1 -0
- package/dist/react/widget/types.d.ts +62 -0
- package/dist/react/widget/types.d.ts.map +1 -0
- package/dist/sdk/v2/client.js +806 -0
- package/dist/sdk/v2/client.js.map +1 -0
- package/dist/svelte/Experience.svelte +522 -0
- package/dist/svelte/Experience.svelte.d.ts +15 -0
- package/dist/svelte/ExperienceThumbnail.svelte +376 -0
- package/dist/svelte/ExperienceThumbnail.svelte.d.ts +22 -0
- package/dist/svelte/ExperienceWidget.svelte +146 -0
- package/dist/svelte/ExperienceWidget.svelte.d.ts +35 -0
- package/dist/svelte/experienceLoadError.d.ts +15 -0
- package/dist/svelte/experienceLoadError.js +82 -0
- package/dist/svelte/experienceLoadError.test.d.ts +1 -0
- package/dist/svelte/experienceLoadError.test.js +18 -0
- package/dist/svelte/experienceLoadErrorOverlay.d.ts +7 -0
- package/dist/svelte/experienceLoadErrorOverlay.js +48 -0
- package/dist/svelte/experienceLoadErrorStyles.d.ts +4 -0
- package/dist/svelte/experienceLoadErrorStyles.js +112 -0
- package/dist/svelte/index.d.ts +7 -0
- package/dist/svelte/index.js +5 -0
- package/dist/svelte/types.d.ts +1 -0
- package/dist/svelte/types.js +1 -0
- package/package.json +154 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
3
|
+
import type { Attachment } from 'svelte/attachments';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Experience as ExperienceClient,
|
|
7
|
+
navigateOnExperienceClose,
|
|
8
|
+
type CloseEvent,
|
|
9
|
+
type EmbedState,
|
|
10
|
+
type ExperienceEvents,
|
|
11
|
+
type ExperienceEventName,
|
|
12
|
+
type ExperienceSession,
|
|
13
|
+
type ListenOnceOptions,
|
|
14
|
+
type SessionManifest,
|
|
15
|
+
type SpeakOptions,
|
|
16
|
+
type SpeechResult,
|
|
17
|
+
type StartSessionOptions,
|
|
18
|
+
type UtteranceResult
|
|
19
|
+
} from '@liforma/client';
|
|
20
|
+
import type { ExperienceProps } from './types';
|
|
21
|
+
import {
|
|
22
|
+
presentExperienceLoadError,
|
|
23
|
+
type ExperienceLoadErrorPresentation
|
|
24
|
+
} from './experienceLoadError';
|
|
25
|
+
import { createExperienceLoadErrorOverlay } from './experienceLoadErrorOverlay';
|
|
26
|
+
|
|
27
|
+
type Deferred<T> = {
|
|
28
|
+
readonly promise: Promise<T>;
|
|
29
|
+
resolve(value: T): void;
|
|
30
|
+
reject(reason: unknown): void;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type LaunchSnapshot =
|
|
34
|
+
| { readonly options: StartSessionOptions; readonly error?: never }
|
|
35
|
+
| { readonly options?: never; readonly error: Error };
|
|
36
|
+
|
|
37
|
+
type Generation = {
|
|
38
|
+
readonly id: number;
|
|
39
|
+
readonly session: Deferred<ExperienceSession>;
|
|
40
|
+
readonly ready: Deferred<ExperienceEvents['ready']>;
|
|
41
|
+
readonly started: Deferred<ExperienceEvents['started']>;
|
|
42
|
+
readonly unsubscribers: (() => void)[];
|
|
43
|
+
readonly reportedErrors: Set<Error>;
|
|
44
|
+
instance: ExperienceSession | null;
|
|
45
|
+
destroyed: boolean;
|
|
46
|
+
instanceDestroyed: boolean;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
let {
|
|
50
|
+
experienceId,
|
|
51
|
+
sessionEndpoint,
|
|
52
|
+
manifest,
|
|
53
|
+
acceptCredentialExposure = false,
|
|
54
|
+
language,
|
|
55
|
+
mode,
|
|
56
|
+
responseMode,
|
|
57
|
+
speechInputMode,
|
|
58
|
+
startButton,
|
|
59
|
+
conversationProcessor,
|
|
60
|
+
speechOnly = false,
|
|
61
|
+
fit,
|
|
62
|
+
avatarId,
|
|
63
|
+
locationId,
|
|
64
|
+
embedBaseUrl,
|
|
65
|
+
debug = false,
|
|
66
|
+
returnUrl,
|
|
67
|
+
onReady,
|
|
68
|
+
onStarted,
|
|
69
|
+
onUserTranscript,
|
|
70
|
+
onUserSpeechStarted,
|
|
71
|
+
onUserSpeechEnded,
|
|
72
|
+
onCharacterSpeechStarted,
|
|
73
|
+
onCharacterSpeechEnded,
|
|
74
|
+
onConversationUpdate,
|
|
75
|
+
onMessage,
|
|
76
|
+
onListeningState,
|
|
77
|
+
onModeChange,
|
|
78
|
+
onConversationProcessorError,
|
|
79
|
+
onStateUpdate,
|
|
80
|
+
onClose,
|
|
81
|
+
onError
|
|
82
|
+
}: ExperienceProps = $props();
|
|
83
|
+
|
|
84
|
+
let host = $state<HTMLDivElement>();
|
|
85
|
+
let errorHost = $state<HTMLDivElement>();
|
|
86
|
+
let loadError = $state<ExperienceLoadErrorPresentation | null>(null);
|
|
87
|
+
let generationId = 0;
|
|
88
|
+
let launchIdentityId = 0;
|
|
89
|
+
let activeGeneration: Generation | null = null;
|
|
90
|
+
const launchIdentities = new WeakMap<object, number>();
|
|
91
|
+
|
|
92
|
+
const startButtonKey = $derived(stableSerialize(startButton));
|
|
93
|
+
const launchKey = $derived(
|
|
94
|
+
stableSerialize([
|
|
95
|
+
experienceId,
|
|
96
|
+
sessionEndpoint,
|
|
97
|
+
manifest ? identityKey(manifest) : 0,
|
|
98
|
+
acceptCredentialExposure,
|
|
99
|
+
language,
|
|
100
|
+
mode,
|
|
101
|
+
responseMode,
|
|
102
|
+
speechInputMode,
|
|
103
|
+
startButtonKey,
|
|
104
|
+
conversationProcessor ? identityKey(conversationProcessor) : 0,
|
|
105
|
+
speechOnly,
|
|
106
|
+
fit,
|
|
107
|
+
avatarId,
|
|
108
|
+
locationId,
|
|
109
|
+
embedBaseUrl,
|
|
110
|
+
debug
|
|
111
|
+
])
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
function createDeferred<T>(): Deferred<T> {
|
|
115
|
+
let resolve!: (value: T) => void;
|
|
116
|
+
let reject!: (reason: unknown) => void;
|
|
117
|
+
const promise = new Promise<T>((promiseResolve, promiseReject) => {
|
|
118
|
+
resolve = promiseResolve;
|
|
119
|
+
reject = promiseReject;
|
|
120
|
+
});
|
|
121
|
+
void promise.catch(() => undefined);
|
|
122
|
+
return { promise, resolve, reject };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function createGeneration(): Generation {
|
|
126
|
+
return {
|
|
127
|
+
id: ++generationId,
|
|
128
|
+
session: createDeferred<ExperienceSession>(),
|
|
129
|
+
ready: createDeferred<ExperienceEvents['ready']>(),
|
|
130
|
+
started: createDeferred<ExperienceEvents['started']>(),
|
|
131
|
+
unsubscribers: [],
|
|
132
|
+
reportedErrors: new Set(),
|
|
133
|
+
instance: null,
|
|
134
|
+
destroyed: false,
|
|
135
|
+
instanceDestroyed: false
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function abortError(): DOMException {
|
|
140
|
+
return new DOMException('Aborted', 'AbortError');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function toError(error: unknown): Error {
|
|
144
|
+
if (error instanceof DOMException) return error as Error;
|
|
145
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isAbortError(error: unknown): boolean {
|
|
149
|
+
return error instanceof DOMException && error.name === 'AbortError';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function stableSerialize(value: unknown): string {
|
|
153
|
+
if (value === undefined) return 'undefined';
|
|
154
|
+
if (value === null || typeof value !== 'object') return JSON.stringify(value);
|
|
155
|
+
if (Array.isArray(value)) return `[${value.map(stableSerialize).join(',')}]`;
|
|
156
|
+
const record = value as Record<string, unknown>;
|
|
157
|
+
return `{${Object.keys(record)
|
|
158
|
+
.sort()
|
|
159
|
+
.map((key) => `${JSON.stringify(key)}:${stableSerialize(record[key])}`)
|
|
160
|
+
.join(',')}}`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function identityKey(value: object): number {
|
|
164
|
+
const existing = launchIdentities.get(value);
|
|
165
|
+
if (existing !== undefined) return existing;
|
|
166
|
+
const id = ++launchIdentityId;
|
|
167
|
+
launchIdentities.set(value, id);
|
|
168
|
+
return id;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function destroyInstance(generation: Generation): void {
|
|
172
|
+
if (!generation.instance || generation.instanceDestroyed) return;
|
|
173
|
+
generation.instanceDestroyed = true;
|
|
174
|
+
generation.instance.destroy();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function cancelGeneration(generation: Generation): void {
|
|
178
|
+
if (generation.destroyed) return;
|
|
179
|
+
generation.destroyed = true;
|
|
180
|
+
const error = abortError();
|
|
181
|
+
generation.session.reject(error);
|
|
182
|
+
generation.ready.reject(error);
|
|
183
|
+
generation.started.reject(error);
|
|
184
|
+
for (const unsubscribe of generation.unsubscribers.splice(0)) unsubscribe();
|
|
185
|
+
destroyInstance(generation);
|
|
186
|
+
if (activeGeneration === generation) activeGeneration = null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function resolveExperienceId(options?: StartSessionOptions): string | undefined {
|
|
190
|
+
if (!options) return experienceId?.trim() || undefined;
|
|
191
|
+
if ('experienceId' in options) {
|
|
192
|
+
const id = (options as { readonly experienceId?: string }).experienceId;
|
|
193
|
+
if (typeof id === 'string' && id.trim()) return id;
|
|
194
|
+
}
|
|
195
|
+
if ('manifest' in options) {
|
|
196
|
+
const manifest = (options as { readonly manifest?: unknown }).manifest;
|
|
197
|
+
if (manifest && typeof manifest === 'object' && 'experienceId' in manifest) {
|
|
198
|
+
const id = (manifest as { readonly experienceId?: unknown }).experienceId;
|
|
199
|
+
if (typeof id === 'string' && id.trim()) return id;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return experienceId?.trim() || undefined;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function showLoadError(error: unknown, options?: StartSessionOptions): void {
|
|
206
|
+
loadError = presentExperienceLoadError(error, {
|
|
207
|
+
experienceId: resolveExperienceId(options)
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function reportError(
|
|
212
|
+
error: unknown,
|
|
213
|
+
generation: Generation,
|
|
214
|
+
showFallback = false,
|
|
215
|
+
options?: StartSessionOptions
|
|
216
|
+
): Error {
|
|
217
|
+
const normalized = toError(error);
|
|
218
|
+
if (!isAbortError(normalized) && activeGeneration === generation && !generation.destroyed) {
|
|
219
|
+
if (showFallback) showLoadError(normalized, options);
|
|
220
|
+
if (!generation.reportedErrors.has(normalized)) {
|
|
221
|
+
generation.reportedErrors.add(normalized);
|
|
222
|
+
console.error('[Experience]', normalized);
|
|
223
|
+
onError?.(normalized);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return normalized;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function requireGeneration(): Generation {
|
|
230
|
+
const generation = activeGeneration;
|
|
231
|
+
if (!generation || generation.destroyed) throw abortError();
|
|
232
|
+
return generation;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function assertCurrent(generation: Generation): void {
|
|
236
|
+
if (generation.destroyed || activeGeneration !== generation) throw abortError();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function subscribe<K extends ExperienceEventName>(
|
|
240
|
+
generation: Generation,
|
|
241
|
+
session: ExperienceSession,
|
|
242
|
+
event: K,
|
|
243
|
+
handler: (payload: ExperienceEvents[K]) => void
|
|
244
|
+
): void {
|
|
245
|
+
generation.unsubscribers.push(session.on(event, handler));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function subscribeToEvents(generation: Generation, session: ExperienceSession): void {
|
|
249
|
+
subscribe(generation, session, 'ready', (event) => {
|
|
250
|
+
if (generation.destroyed) return;
|
|
251
|
+
generation.ready.resolve(event);
|
|
252
|
+
onReady?.(event);
|
|
253
|
+
});
|
|
254
|
+
subscribe(generation, session, 'started', (event) => {
|
|
255
|
+
if (generation.destroyed) return;
|
|
256
|
+
generation.started.resolve(event);
|
|
257
|
+
onStarted?.(event);
|
|
258
|
+
});
|
|
259
|
+
subscribe(generation, session, 'userTranscript', (event) => onUserTranscript?.(event));
|
|
260
|
+
subscribe(generation, session, 'userSpeechStarted', (event) => onUserSpeechStarted?.(event));
|
|
261
|
+
subscribe(generation, session, 'userSpeechEnded', (event) => onUserSpeechEnded?.(event));
|
|
262
|
+
subscribe(generation, session, 'characterSpeechStarted', (event) =>
|
|
263
|
+
onCharacterSpeechStarted?.(event)
|
|
264
|
+
);
|
|
265
|
+
subscribe(generation, session, 'characterSpeechEnded', (event) =>
|
|
266
|
+
onCharacterSpeechEnded?.(event)
|
|
267
|
+
);
|
|
268
|
+
subscribe(generation, session, 'conversationUpdate', (event) =>
|
|
269
|
+
onConversationUpdate?.(event)
|
|
270
|
+
);
|
|
271
|
+
subscribe(generation, session, 'message', (event) => onMessage?.(event));
|
|
272
|
+
subscribe(generation, session, 'listeningState', (event) => onListeningState?.(event));
|
|
273
|
+
subscribe(generation, session, 'modeChange', (event) => onModeChange?.(event));
|
|
274
|
+
subscribe(generation, session, 'conversationProcessorError', (event) =>
|
|
275
|
+
onConversationProcessorError?.(event)
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function buildStartOptions(): StartSessionOptions {
|
|
280
|
+
const hasSessionEndpoint = Boolean(sessionEndpoint?.trim());
|
|
281
|
+
if (hasSessionEndpoint && !experienceId?.trim()) {
|
|
282
|
+
throw new Error('sessionEndpoint requires experienceId.');
|
|
283
|
+
}
|
|
284
|
+
if (!hasSessionEndpoint && !experienceId && !manifest) {
|
|
285
|
+
throw new Error('Experience requires experienceId or manifest.');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (hasSessionEndpoint && experienceId && sessionEndpoint) {
|
|
289
|
+
return {
|
|
290
|
+
experienceId,
|
|
291
|
+
sessionEndpoint,
|
|
292
|
+
language,
|
|
293
|
+
locationId,
|
|
294
|
+
avatarId,
|
|
295
|
+
embedBaseUrl,
|
|
296
|
+
debug,
|
|
297
|
+
mode,
|
|
298
|
+
responseMode,
|
|
299
|
+
speechInputMode,
|
|
300
|
+
speechOnly,
|
|
301
|
+
fit,
|
|
302
|
+
startButton: untrack(() => startButton),
|
|
303
|
+
conversationProcessor
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
if (manifest) {
|
|
307
|
+
return {
|
|
308
|
+
manifest,
|
|
309
|
+
acceptCredentialExposure,
|
|
310
|
+
embedBaseUrl,
|
|
311
|
+
debug,
|
|
312
|
+
speechOnly,
|
|
313
|
+
fit,
|
|
314
|
+
startButton: untrack(() => startButton),
|
|
315
|
+
conversationProcessor
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
if (experienceId) {
|
|
319
|
+
return {
|
|
320
|
+
experienceId,
|
|
321
|
+
language,
|
|
322
|
+
locationId,
|
|
323
|
+
avatarId,
|
|
324
|
+
embedBaseUrl,
|
|
325
|
+
debug,
|
|
326
|
+
mode,
|
|
327
|
+
responseMode,
|
|
328
|
+
speechInputMode,
|
|
329
|
+
speechOnly,
|
|
330
|
+
fit,
|
|
331
|
+
startButton: untrack(() => startButton),
|
|
332
|
+
conversationProcessor
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
throw new Error('Experience requires experienceId or manifest.');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function snapshotLaunch(): LaunchSnapshot {
|
|
339
|
+
try {
|
|
340
|
+
return { options: buildStartOptions() };
|
|
341
|
+
} catch (error) {
|
|
342
|
+
return { error: toError(error) };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async function launch(
|
|
347
|
+
generation: Generation,
|
|
348
|
+
container: HTMLDivElement,
|
|
349
|
+
options: StartSessionOptions
|
|
350
|
+
): Promise<void> {
|
|
351
|
+
try {
|
|
352
|
+
const session = await ExperienceClient.startSession(options);
|
|
353
|
+
generation.instance = session;
|
|
354
|
+
if (generation.destroyed || activeGeneration !== generation) {
|
|
355
|
+
destroyInstance(generation);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
subscribeToEvents(generation, session);
|
|
360
|
+
const player = await session.attach({
|
|
361
|
+
container,
|
|
362
|
+
showClose: Boolean(onClose || returnUrl?.trim()),
|
|
363
|
+
onStateUpdate: (state: EmbedState) => {
|
|
364
|
+
if (!generation.destroyed) onStateUpdate?.(state);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
assertCurrent(generation);
|
|
368
|
+
generation.session.resolve(session);
|
|
369
|
+
player.on('close', (event: CloseEvent) => {
|
|
370
|
+
if (generation.destroyed) return;
|
|
371
|
+
if (onClose) {
|
|
372
|
+
onClose(event);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const fallback = returnUrl?.trim();
|
|
376
|
+
if (fallback) {
|
|
377
|
+
navigateOnExperienceClose(event, fallback);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
} catch (error) {
|
|
381
|
+
const normalized = reportError(error, generation, true, options);
|
|
382
|
+
generation.session.reject(normalized);
|
|
383
|
+
generation.ready.reject(normalized);
|
|
384
|
+
generation.started.reject(normalized);
|
|
385
|
+
destroyInstance(generation);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function withSession<T>(
|
|
390
|
+
operation: (session: ExperienceSession) => Promise<T>
|
|
391
|
+
): Promise<T> {
|
|
392
|
+
const generation = requireGeneration();
|
|
393
|
+
try {
|
|
394
|
+
const session = await generation.session.promise;
|
|
395
|
+
assertCurrent(generation);
|
|
396
|
+
return await operation(session);
|
|
397
|
+
} catch (error) {
|
|
398
|
+
const normalized = reportError(error, generation);
|
|
399
|
+
throw normalized;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export function ready(): Promise<ExperienceEvents['ready']> {
|
|
404
|
+
return requireGeneration().ready.promise;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export function started(): Promise<ExperienceEvents['started']> {
|
|
408
|
+
return requireGeneration().started.promise;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export function speak(options: SpeakOptions): Promise<SpeechResult> {
|
|
412
|
+
return withSession((session) => session.speak(options));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export function startListening(): Promise<void> {
|
|
416
|
+
return withSession((session) => session.startListening());
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function stopListening(): Promise<UtteranceResult> {
|
|
420
|
+
return withSession((session) => session.stopListening());
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export function listenOnce(options?: ListenOnceOptions): Promise<UtteranceResult> {
|
|
424
|
+
return withSession((session) => session.listenOnce(options));
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export function getManifest(): SessionManifest | null {
|
|
428
|
+
return activeGeneration?.instance?.getManifest() ?? null;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export function getConversation(): ReturnType<ExperienceSession['getConversation']> {
|
|
432
|
+
return activeGeneration?.instance?.getConversation() ?? [];
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
export function end(): Promise<void> {
|
|
436
|
+
return withSession((session) => session.end());
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function activateGeneration(
|
|
440
|
+
container: HTMLDivElement,
|
|
441
|
+
snapshot: LaunchSnapshot
|
|
442
|
+
): () => void {
|
|
443
|
+
const generation = createGeneration();
|
|
444
|
+
activeGeneration = generation;
|
|
445
|
+
loadError = null;
|
|
446
|
+
if (snapshot.error) {
|
|
447
|
+
const error = reportError(snapshot.error, generation, true);
|
|
448
|
+
generation.session.reject(error);
|
|
449
|
+
generation.ready.reject(error);
|
|
450
|
+
generation.started.reject(error);
|
|
451
|
+
} else {
|
|
452
|
+
void launch(generation, container, snapshot.options);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return () => cancelGeneration(generation);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const attachHost: Attachment<HTMLDivElement> = (container) => {
|
|
459
|
+
host = container;
|
|
460
|
+
return () => {
|
|
461
|
+
if (host === container) host = undefined;
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
const attachErrorHost: Attachment<HTMLDivElement> = (container) => {
|
|
466
|
+
errorHost = container;
|
|
467
|
+
return () => {
|
|
468
|
+
if (errorHost === container) errorHost = undefined;
|
|
469
|
+
};
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
function restartSession(): (() => void) | undefined {
|
|
473
|
+
const container = host;
|
|
474
|
+
if (!container) return;
|
|
475
|
+
void launchKey;
|
|
476
|
+
const snapshot = untrack(snapshotLaunch);
|
|
477
|
+
return untrack(() => activateGeneration(container, snapshot));
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
$effect(restartSession);
|
|
481
|
+
|
|
482
|
+
$effect(() => {
|
|
483
|
+
const container = errorHost;
|
|
484
|
+
const presentation = loadError;
|
|
485
|
+
if (!container) return;
|
|
486
|
+
container.replaceChildren();
|
|
487
|
+
if (!presentation) return;
|
|
488
|
+
const overlay = createExperienceLoadErrorOverlay(container, presentation);
|
|
489
|
+
return () => overlay.remove();
|
|
490
|
+
});
|
|
491
|
+
</script>
|
|
492
|
+
|
|
493
|
+
<div class="liforma-experience-shell">
|
|
494
|
+
<div class="error-host" {@attach attachErrorHost} aria-hidden={loadError ? undefined : 'true'}></div>
|
|
495
|
+
<div class="host" {@attach attachHost}></div>
|
|
496
|
+
</div>
|
|
497
|
+
|
|
498
|
+
<style>
|
|
499
|
+
.liforma-experience-shell {
|
|
500
|
+
position: relative;
|
|
501
|
+
width: 100%;
|
|
502
|
+
height: 100%;
|
|
503
|
+
min-height: inherit;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.host {
|
|
507
|
+
position: absolute;
|
|
508
|
+
inset: 0;
|
|
509
|
+
overflow: hidden;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.error-host {
|
|
513
|
+
position: absolute;
|
|
514
|
+
inset: 0;
|
|
515
|
+
z-index: 20;
|
|
516
|
+
pointer-events: none;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.error-host:not(:empty) {
|
|
520
|
+
pointer-events: auto;
|
|
521
|
+
}
|
|
522
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ExperienceEvents, type ExperienceSession, type ListenOnceOptions, type SessionManifest, type SpeakOptions, type SpeechResult, type UtteranceResult } from '@liforma/client';
|
|
2
|
+
import type { ExperienceProps } from './types';
|
|
3
|
+
declare const Experience: import("svelte").Component<ExperienceProps, {
|
|
4
|
+
ready: () => Promise<ExperienceEvents["ready"]>;
|
|
5
|
+
started: () => Promise<ExperienceEvents["started"]>;
|
|
6
|
+
speak: (options: SpeakOptions) => Promise<SpeechResult>;
|
|
7
|
+
startListening: () => Promise<void>;
|
|
8
|
+
stopListening: () => Promise<UtteranceResult>;
|
|
9
|
+
listenOnce: (options?: ListenOnceOptions) => Promise<UtteranceResult>;
|
|
10
|
+
getManifest: () => SessionManifest | null;
|
|
11
|
+
getConversation: () => ReturnType<ExperienceSession["getConversation"]>;
|
|
12
|
+
end: () => Promise<void>;
|
|
13
|
+
}, "">;
|
|
14
|
+
type Experience = ReturnType<typeof Experience>;
|
|
15
|
+
export default Experience;
|