@urun-sh/react 0.2.4 → 0.2.5
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 +18 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +168 -8
- package/dist/index.d.ts +168 -8
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/styles.css +148 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.5
|
|
4
|
+
|
|
5
|
+
- Session workbench building blocks: generic, composable debug/steer components
|
|
6
|
+
over the public `Session` primitives — `UrunStreamTail` (named data-lane tail
|
|
7
|
+
over `stream.messages()`), `UrunDocPanel` + `UrunControlSender` (view/patch a
|
|
8
|
+
session doc), `UrunEventSpine` (SDK-native activity log from `onPhase` /
|
|
9
|
+
track / doc events), `UrunSessionStatus` + `UrunSessionGate`, plus the hooks
|
|
10
|
+
`useSessionTrack` / `useSessionDoc` / `useStreamMessages`. Media panes reuse
|
|
11
|
+
the existing `UrunVideo` / `UrunAudio` / `UrunVoice`. See
|
|
12
|
+
`docs/session-workbench-building-blocks.md`.
|
|
13
|
+
- `useStreamMessages` now cancels the stream's async iterator (calls
|
|
14
|
+
`.return()`) on unmount / name change, instead of only flipping a local
|
|
15
|
+
flag — on a quiet stream the old subscription used to linger until the next
|
|
16
|
+
message ever arrived.
|
|
17
|
+
- `UrunControlSender`'s doc-change log line is labeled `change` instead of
|
|
18
|
+
`recv`: the core doc has no origin marker, so the line also fires for this
|
|
19
|
+
component's own writes and `recv` overclaimed it came from the runtime.
|
|
20
|
+
|
|
3
21
|
## 0.2.1
|
|
4
22
|
|
|
5
23
|
- Republish of the 0.2.0 line (`@urun-sh/core` / `@urun-sh/react` 0.2.0 published but never persisted in the npm packument; bumped to 0.2.1 for a clean, resolvable release). No source changes vs 0.2.0.
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--urun-bg: #ffffff;--urun-text: #1a1a2e;--urun-border: #e2e8f0;--urun-radius: 8px;--urun-font: system-ui, -apple-system, sans-serif;--urun-progress-bg: #e2e8f0;--urun-progress-fill: #3b82f6;--urun-progress-success: #22c55e;--urun-progress-error: #ef4444;--urun-progress-height: 8px;--urun-status-thinking: #f59e0b;--urun-status-generating: #3b82f6;--urun-status-idle: #94a3b8;--urun-status-error: #ef4444;--urun-status-indicator-size: 8px;--urun-cursor-color: #3b82f6;--urun-cursor-width: 2px;--urun-metric-bg: #f8fafc;--urun-metric-label-color: #64748b;--urun-metric-value-color: #1a1a2e}.urun-progress-card{font-family:var(--urun-font);color:var(--urun-text);border:1px solid var(--urun-border);border-radius:var(--urun-radius);padding:12px 16px;background:var(--urun-bg)}.urun-progress-label{font-size:.875rem;font-weight:500;margin-bottom:8px}.urun-progress-bar{height:var(--urun-progress-height);background:var(--urun-progress-bg);border-radius:calc(var(--urun-progress-height) / 2);overflow:hidden}.urun-progress-fill{height:100%;background:var(--urun-progress-fill);border-radius:inherit;transition:width .3s ease}.urun-progress-card[data-variant=success] .urun-progress-fill{background:var(--urun-progress-success)}.urun-progress-card[data-variant=error] .urun-progress-fill{background:var(--urun-progress-error)}.urun-progress-text{font-size:.75rem;color:var(--urun-metric-label-color);margin-top:4px;text-align:right}.urun-status-badge{display:inline-flex;align-items:center;gap:6px;font-family:var(--urun-font);font-size:.875rem;color:var(--urun-text)}.urun-status-indicator{display:inline-block;width:var(--urun-status-indicator-size);height:var(--urun-status-indicator-size);border-radius:50%;background:var(--urun-status-idle);flex-shrink:0}.urun-status-badge[data-state=thinking] .urun-status-indicator{background:var(--urun-status-thinking)}.urun-status-badge[data-state=generating] .urun-status-indicator{background:var(--urun-status-generating)}.urun-status-badge[data-state=error] .urun-status-indicator{background:var(--urun-status-error)}.urun-status-pulse{animation:urun-pulse 1.5s ease-in-out infinite}.urun-text-stream{font-family:var(--urun-font);color:var(--urun-text);white-space:pre-wrap;word-break:break-word}.urun-text-cursor{display:inline-block;width:var(--urun-cursor-width);height:1em;background:var(--urun-cursor-color);vertical-align:text-bottom;animation:urun-blink 1s step-end infinite}.urun-image-frame{margin:0;border:1px solid var(--urun-border);border-radius:var(--urun-radius);overflow:hidden;background:var(--urun-bg)}.urun-image{display:block;width:100%;height:auto}.urun-image-caption{padding:8px 12px;font-family:var(--urun-font);font-size:.875rem;color:var(--urun-metric-label-color);text-align:center}.urun-metrics-panel{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;font-family:var(--urun-font)}.urun-metric-card{background:var(--urun-metric-bg);border:1px solid var(--urun-border);border-radius:var(--urun-radius);padding:12px;text-align:center}.urun-metric-label{font-size:.75rem;color:var(--urun-metric-label-color);margin-bottom:4px}.urun-metric-value{font-size:1.25rem;font-weight:600;color:var(--urun-metric-value-color)}.urun-component-error{font-family:var(--urun-font);padding:8px 12px;border:1px solid var(--urun-status-error);border-radius:var(--urun-radius);background:#fef2f2;color:var(--urun-status-error);font-size:.875rem}@keyframes urun-pulse{0%,to{opacity:1}50%{opacity:.4}}@keyframes urun-blink{0%,to{opacity:1}50%{opacity:0}}[data-urun-video],[data-urun-video] .video-js,[data-urun-video] .vjs-tech{width:100%;height:100%}[data-urun-video] .vjs-tech{object-fit:contain}.urun-video-live.vjs-has-started .vjs-poster,.urun-video-live.vjs-has-started .vjs-loading-spinner,.urun-video-live.vjs-has-started .vjs-big-play-button{display:none!important}.urun-video-live .vjs-poster{background-color:transparent}
|
|
1
|
+
:root{--urun-bg: #ffffff;--urun-text: #1a1a2e;--urun-border: #e2e8f0;--urun-radius: 8px;--urun-font: system-ui, -apple-system, sans-serif;--urun-progress-bg: #e2e8f0;--urun-progress-fill: #3b82f6;--urun-progress-success: #22c55e;--urun-progress-error: #ef4444;--urun-progress-height: 8px;--urun-status-thinking: #f59e0b;--urun-status-generating: #3b82f6;--urun-status-idle: #94a3b8;--urun-status-error: #ef4444;--urun-status-indicator-size: 8px;--urun-cursor-color: #3b82f6;--urun-cursor-width: 2px;--urun-metric-bg: #f8fafc;--urun-metric-label-color: #64748b;--urun-metric-value-color: #1a1a2e}.urun-progress-card{font-family:var(--urun-font);color:var(--urun-text);border:1px solid var(--urun-border);border-radius:var(--urun-radius);padding:12px 16px;background:var(--urun-bg)}.urun-progress-label{font-size:.875rem;font-weight:500;margin-bottom:8px}.urun-progress-bar{height:var(--urun-progress-height);background:var(--urun-progress-bg);border-radius:calc(var(--urun-progress-height) / 2);overflow:hidden}.urun-progress-fill{height:100%;background:var(--urun-progress-fill);border-radius:inherit;transition:width .3s ease}.urun-progress-card[data-variant=success] .urun-progress-fill{background:var(--urun-progress-success)}.urun-progress-card[data-variant=error] .urun-progress-fill{background:var(--urun-progress-error)}.urun-progress-text{font-size:.75rem;color:var(--urun-metric-label-color);margin-top:4px;text-align:right}.urun-status-badge{display:inline-flex;align-items:center;gap:6px;font-family:var(--urun-font);font-size:.875rem;color:var(--urun-text)}.urun-status-indicator{display:inline-block;width:var(--urun-status-indicator-size);height:var(--urun-status-indicator-size);border-radius:50%;background:var(--urun-status-idle);flex-shrink:0}.urun-status-badge[data-state=thinking] .urun-status-indicator{background:var(--urun-status-thinking)}.urun-status-badge[data-state=generating] .urun-status-indicator{background:var(--urun-status-generating)}.urun-status-badge[data-state=error] .urun-status-indicator{background:var(--urun-status-error)}.urun-status-pulse{animation:urun-pulse 1.5s ease-in-out infinite}.urun-text-stream{font-family:var(--urun-font);color:var(--urun-text);white-space:pre-wrap;word-break:break-word}.urun-text-cursor{display:inline-block;width:var(--urun-cursor-width);height:1em;background:var(--urun-cursor-color);vertical-align:text-bottom;animation:urun-blink 1s step-end infinite}.urun-image-frame{margin:0;border:1px solid var(--urun-border);border-radius:var(--urun-radius);overflow:hidden;background:var(--urun-bg)}.urun-image{display:block;width:100%;height:auto}.urun-image-caption{padding:8px 12px;font-family:var(--urun-font);font-size:.875rem;color:var(--urun-metric-label-color);text-align:center}.urun-metrics-panel{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;font-family:var(--urun-font)}.urun-metric-card{background:var(--urun-metric-bg);border:1px solid var(--urun-border);border-radius:var(--urun-radius);padding:12px;text-align:center}.urun-metric-label{font-size:.75rem;color:var(--urun-metric-label-color);margin-bottom:4px}.urun-metric-value{font-size:1.25rem;font-weight:600;color:var(--urun-metric-value-color)}.urun-component-error{font-family:var(--urun-font);padding:8px 12px;border:1px solid var(--urun-status-error);border-radius:var(--urun-radius);background:#fef2f2;color:var(--urun-status-error);font-size:.875rem}@keyframes urun-pulse{0%,to{opacity:1}50%{opacity:.4}}@keyframes urun-blink{0%,to{opacity:1}50%{opacity:0}}[data-urun-video],[data-urun-video] .video-js,[data-urun-video] .vjs-tech{width:100%;height:100%}[data-urun-video] .vjs-tech{object-fit:contain}.urun-video-live.vjs-has-started .vjs-poster,.urun-video-live.vjs-has-started .vjs-loading-spinner,.urun-video-live.vjs-has-started .vjs-big-play-button{display:none!important}.urun-video-live .vjs-poster{background-color:transparent}.urun-stream-tail,.urun-doc-panel,.urun-control-sender,.urun-event-spine{display:flex;flex-direction:column;gap:6px;font-size:12px}.urun-stream-tail-meta,.urun-doc-panel-meta{display:flex;align-items:center;gap:8px;color:var(--urun-wb-muted, #8a8a8a)}.urun-stream-tail-log,.urun-control-sender-log{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow:auto;padding:6px;border-radius:6px;background:var(--urun-wb-log-bg, rgba(0, 0, 0, .25));font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.urun-stream-tail-time,.urun-control-sender-time,.urun-event-spine-time{color:var(--urun-wb-muted, #8a8a8a)}.urun-doc-panel-snapshot{margin:0;padding:8px;max-height:220px;overflow:auto;border-radius:6px;background:var(--urun-wb-log-bg, rgba(0, 0, 0, .25));font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.urun-doc-patch,.urun-control-sender{display:flex;flex-direction:column;gap:6px}.urun-doc-patch-input{width:100%;resize:vertical;border-radius:6px;border:1px solid var(--urun-wb-border, rgba(128, 128, 128, .4));background:var(--urun-wb-input-bg, transparent);color:inherit;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.urun-doc-patch-actions{display:flex;align-items:center;gap:8px}.urun-doc-patch-button,.urun-mic-button{cursor:pointer;border-radius:6px;border:1px solid var(--urun-wb-border, rgba(128, 128, 128, .4));background:var(--urun-wb-accent, #24db49);color:var(--urun-wb-accent-fg, #04120a);padding:4px 12px;font-size:12px;font-weight:600}.urun-doc-patch-button:disabled{cursor:default;opacity:.5}.urun-doc-patch-error,.urun-mic-error{color:var(--urun-wb-danger, #e5484d)}.urun-event-spine{max-height:260px;overflow:auto}.urun-event-spine-line,.urun-control-sender-line{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.urun-event-spine-kind,.urun-control-sender-dir{display:inline-block;min-width:3.5em;color:var(--urun-wb-muted, #8a8a8a)}.urun-session-status{display:inline-flex;align-items:center;gap:6px;font-size:12px}.urun-session-status-dot{width:8px;height:8px;border-radius:50%;background:var(--urun-wb-muted, #8a8a8a)}.urun-session-status-dot[data-phase=live]{background:var(--urun-wb-accent, #24db49)}.urun-session-status-dot[data-phase=connecting],.urun-session-status-dot[data-phase=provisioning],.urun-session-status-dot[data-phase=queued]{background:var(--urun-wb-warn, #ffb224)}.urun-session-status-dot[data-phase=error]{background:var(--urun-wb-danger, #e5484d)}.urun-session-status-detail{color:var(--urun-wb-muted, #8a8a8a)}
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { RefObject, ReactNode, Component, ErrorInfo, ComponentType } from 'react';
|
|
4
4
|
export { UrunAuthMode, authMode, urunPublicEnv, usesWorkOSAuth } from './auth.mjs';
|
|
5
|
-
import { SessionInterface, SessionDocument, SessionStream, SessionPhase } from '@urun-sh/core';
|
|
5
|
+
import { SessionInterface, SessionDocument, SessionStream, SessionPhase, SessionStatus } from '@urun-sh/core';
|
|
6
6
|
export { App as AppInterface, AppOptions, SessionDocument, Session as SessionInterface, SessionPhase, SessionPhaseName, SessionStream } from '@urun-sh/core';
|
|
7
7
|
import { ZodSchema, z } from 'zod';
|
|
8
8
|
import Player from 'video.js/dist/types/player';
|
|
@@ -74,6 +74,8 @@ interface ReactSession extends Omit<SessionInterface, 'doc' | 'stream'> {
|
|
|
74
74
|
stream(name: string): ReactSessionStream;
|
|
75
75
|
|
|
76
76
|
readonly phase: SessionPhase;
|
|
77
|
+
|
|
78
|
+
readonly status: SessionStatus;
|
|
77
79
|
}
|
|
78
80
|
type ReactApp = Record<string, (args?: Record<string, unknown>) => ReactSession>;
|
|
79
81
|
|
|
@@ -275,12 +277,12 @@ declare const ImageFrameSchema: z.ZodObject<{
|
|
|
275
277
|
caption: z.ZodOptional<z.ZodString>;
|
|
276
278
|
}, "strip", z.ZodTypeAny, {
|
|
277
279
|
src: string;
|
|
278
|
-
alt?: string | undefined;
|
|
279
280
|
caption?: string | undefined;
|
|
281
|
+
alt?: string | undefined;
|
|
280
282
|
}, {
|
|
281
283
|
src: string;
|
|
282
|
-
alt?: string | undefined;
|
|
283
284
|
caption?: string | undefined;
|
|
285
|
+
alt?: string | undefined;
|
|
284
286
|
}>;
|
|
285
287
|
type ImageFrameProps = z.infer<typeof ImageFrameSchema>;
|
|
286
288
|
declare function useImageFrame(props: ImageFrameProps): {
|
|
@@ -296,24 +298,24 @@ declare const MetricsPanelSchema: z.ZodObject<{
|
|
|
296
298
|
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
297
299
|
unit: z.ZodOptional<z.ZodString>;
|
|
298
300
|
}, "strip", z.ZodTypeAny, {
|
|
299
|
-
value: string | number;
|
|
300
301
|
label: string;
|
|
302
|
+
value: string | number;
|
|
301
303
|
unit?: string | undefined;
|
|
302
304
|
}, {
|
|
303
|
-
value: string | number;
|
|
304
305
|
label: string;
|
|
306
|
+
value: string | number;
|
|
305
307
|
unit?: string | undefined;
|
|
306
308
|
}>, "many">;
|
|
307
309
|
}, "strip", z.ZodTypeAny, {
|
|
308
310
|
metrics: {
|
|
309
|
-
value: string | number;
|
|
310
311
|
label: string;
|
|
312
|
+
value: string | number;
|
|
311
313
|
unit?: string | undefined;
|
|
312
314
|
}[];
|
|
313
315
|
}, {
|
|
314
316
|
metrics: {
|
|
315
|
-
value: string | number;
|
|
316
317
|
label: string;
|
|
318
|
+
value: string | number;
|
|
317
319
|
unit?: string | undefined;
|
|
318
320
|
}[];
|
|
319
321
|
}>;
|
|
@@ -415,6 +417,8 @@ interface UrunVoiceSessionSource {
|
|
|
415
417
|
timeout?: number;
|
|
416
418
|
signal?: AbortSignal;
|
|
417
419
|
}): Promise<void>;
|
|
420
|
+
|
|
421
|
+
readonly status?: SessionStatus;
|
|
418
422
|
}
|
|
419
423
|
|
|
420
424
|
interface UrunVoiceHandle {
|
|
@@ -473,6 +477,8 @@ interface UrunCameraSessionSource {
|
|
|
473
477
|
timeout?: number;
|
|
474
478
|
signal?: AbortSignal;
|
|
475
479
|
}): Promise<void>;
|
|
480
|
+
|
|
481
|
+
readonly status?: SessionStatus;
|
|
476
482
|
}
|
|
477
483
|
|
|
478
484
|
type UrunCameraFacing = 'user' | 'environment';
|
|
@@ -555,4 +561,158 @@ declare function getUrunAudioContext(): AudioContext | null;
|
|
|
555
561
|
|
|
556
562
|
declare function resumeUrunAudioContext(): void;
|
|
557
563
|
|
|
558
|
-
|
|
564
|
+
interface WorkbenchStreamSource {
|
|
565
|
+
|
|
566
|
+
readonly track: MediaStreamTrack | null;
|
|
567
|
+
|
|
568
|
+
on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
|
|
569
|
+
|
|
570
|
+
messages(): AsyncIterable<unknown>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
interface WorkbenchDocSource {
|
|
574
|
+
|
|
575
|
+
get(path?: string, defaultValue?: unknown): unknown;
|
|
576
|
+
|
|
577
|
+
set(patch: Record<string, unknown>): void;
|
|
578
|
+
|
|
579
|
+
on(event: 'change', handler: (snapshot: unknown) => void): () => void;
|
|
580
|
+
|
|
581
|
+
readonly synced: boolean;
|
|
582
|
+
|
|
583
|
+
onSynced(handler: () => void): () => void;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
interface WorkbenchSession {
|
|
587
|
+
|
|
588
|
+
readonly id: string;
|
|
589
|
+
|
|
590
|
+
readonly phase: SessionPhase;
|
|
591
|
+
|
|
592
|
+
onPhase(handler: (phase: SessionPhase) => void): () => void;
|
|
593
|
+
|
|
594
|
+
stream(name: string): WorkbenchStreamSource;
|
|
595
|
+
|
|
596
|
+
doc(key: string): WorkbenchDocSource;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
declare function useSessionTrack(session: WorkbenchSession | null, name: string): MediaStreamTrack | null;
|
|
600
|
+
|
|
601
|
+
interface UseSessionDocResult<T> {
|
|
602
|
+
|
|
603
|
+
snapshot: T | null;
|
|
604
|
+
|
|
605
|
+
synced: boolean;
|
|
606
|
+
|
|
607
|
+
set: (patch: Partial<T> & Record<string, unknown>) => void;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
declare function useSessionDoc<T = Record<string, unknown>>(session: WorkbenchSession | null, key: string): UseSessionDocResult<T>;
|
|
611
|
+
|
|
612
|
+
declare const DEFAULT_LOG_CAP = 200;
|
|
613
|
+
|
|
614
|
+
declare function pushCapped<T>(list: readonly T[], entry: T, cap?: number): T[];
|
|
615
|
+
|
|
616
|
+
interface StreamMessageEntry {
|
|
617
|
+
at: number;
|
|
618
|
+
payload: unknown;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
interface SpineEntry {
|
|
622
|
+
at: number;
|
|
623
|
+
kind: 'phase' | 'track' | 'doc';
|
|
624
|
+
text: string;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
declare function formatPayload(payload: unknown): string;
|
|
628
|
+
type JsonObjectParse = {
|
|
629
|
+
ok: true;
|
|
630
|
+
value: Record<string, unknown>;
|
|
631
|
+
} | {
|
|
632
|
+
ok: false;
|
|
633
|
+
error: string;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
declare function parseJsonObject(text: string): JsonObjectParse;
|
|
637
|
+
|
|
638
|
+
interface UseStreamMessagesOptions {
|
|
639
|
+
|
|
640
|
+
cap?: number;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
declare function useStreamMessages(session: WorkbenchSession | null, name: string, options?: UseStreamMessagesOptions): StreamMessageEntry[];
|
|
644
|
+
|
|
645
|
+
interface UrunStreamTailProps {
|
|
646
|
+
|
|
647
|
+
session: WorkbenchSession | null;
|
|
648
|
+
|
|
649
|
+
name: string;
|
|
650
|
+
|
|
651
|
+
cap?: number;
|
|
652
|
+
className?: string;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
declare function UrunStreamTail({ session, name, cap, className }: UrunStreamTailProps): react_jsx_runtime.JSX.Element;
|
|
656
|
+
|
|
657
|
+
declare function DocPatchForm({ placeholder, buttonLabel, disabled, onApply, }: {
|
|
658
|
+
placeholder?: string;
|
|
659
|
+
buttonLabel: string;
|
|
660
|
+
disabled?: boolean;
|
|
661
|
+
onApply: (patch: Record<string, unknown>, raw: string) => void;
|
|
662
|
+
}): react_jsx_runtime.JSX.Element;
|
|
663
|
+
interface UrunDocPanelProps {
|
|
664
|
+
session: WorkbenchSession | null;
|
|
665
|
+
|
|
666
|
+
docKey: string;
|
|
667
|
+
|
|
668
|
+
editable?: boolean;
|
|
669
|
+
|
|
670
|
+
patchPlaceholder?: string;
|
|
671
|
+
className?: string;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
declare function UrunDocPanel({ session, docKey, editable, patchPlaceholder, className, }: UrunDocPanelProps): react_jsx_runtime.JSX.Element;
|
|
675
|
+
|
|
676
|
+
interface UrunControlSenderProps {
|
|
677
|
+
session: WorkbenchSession | null;
|
|
678
|
+
|
|
679
|
+
docKey?: string;
|
|
680
|
+
|
|
681
|
+
cap?: number;
|
|
682
|
+
className?: string;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
declare function UrunControlSender({ session, docKey, cap, className, }: UrunControlSenderProps): react_jsx_runtime.JSX.Element;
|
|
686
|
+
|
|
687
|
+
interface UrunEventSpineProps {
|
|
688
|
+
session: WorkbenchSession | null;
|
|
689
|
+
|
|
690
|
+
trackNames?: string[];
|
|
691
|
+
|
|
692
|
+
docKeys?: string[];
|
|
693
|
+
|
|
694
|
+
cap?: number;
|
|
695
|
+
className?: string;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
declare function UrunEventSpine({ session, trackNames, docKeys, cap, className, }: UrunEventSpineProps): react_jsx_runtime.JSX.Element;
|
|
699
|
+
|
|
700
|
+
declare function useSessionPhase(session: WorkbenchSession | null): SessionPhase | null;
|
|
701
|
+
interface UrunSessionStatusProps {
|
|
702
|
+
session: WorkbenchSession | null;
|
|
703
|
+
className?: string;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
declare function UrunSessionStatus({ session, className }: UrunSessionStatusProps): react_jsx_runtime.JSX.Element;
|
|
707
|
+
interface UrunSessionGateProps {
|
|
708
|
+
session: WorkbenchSession | null;
|
|
709
|
+
|
|
710
|
+
children: ReactNode;
|
|
711
|
+
|
|
712
|
+
fallback?: (phase: SessionPhase | null) => ReactNode;
|
|
713
|
+
className?: string;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
declare function UrunSessionGate({ session, children, fallback, className, }: UrunSessionGateProps): react_jsx_runtime.JSX.Element;
|
|
717
|
+
|
|
718
|
+
export { type ChatMessage, type ChatRole, ComponentRenderer, DEFAULT_CAMERA_CONSTRAINTS, DEFAULT_LOG_CAP, DEFAULT_VOICE_CONSTRAINTS, DocPatchForm, ImageFrame, ImageFrameSchema, type JsonObjectParse, MetricsPanel, MetricsPanelSchema, ProgressCard, ProgressCardSchema, type ReactApp, type ReactSession, type ReactSessionDocument, type ReactSessionStream, type RegisteredComponent, type RequestCapableSession, type RequestStream, type SessionRequestOptions, type SpineEntry, StatusBadge, StatusBadgeSchema, type StreamMessageEntry, TextStream, TextStreamSchema, type UrunAccessToken, type UrunAccessTokenProvider, UrunAudio, type UrunAudioHandle, type UrunAudioLevel, type UrunAudioProps, type UrunAudioSessionSource, type UrunAudioStreamSource, type UrunAuthContextValue, UrunAuthProvider, type UrunAuthProviderProps, UrunCamera, type UrunCameraFacing, type UrunCameraHandle, type UrunCameraProps, type UrunCameraSessionSource, type UrunCameraStreamSource, UrunControlSender, type UrunControlSenderProps, UrunDocPanel, type UrunDocPanelProps, UrunErrorBoundary, UrunEventSpine, type UrunEventSpineProps, UrunJwtProvider, UrunProvider, UrunSessionGate, type UrunSessionGateProps, UrunSessionStatus, type UrunSessionStatusProps, UrunStreamTail, type UrunStreamTailProps, UrunVideo, type UrunVideoProps, UrunVoice, type UrunVoiceHandle, type UrunVoiceProps, type UrunVoiceSessionSource, type UrunVoiceStreamSource, type UseChatOptions, type UseChatResult, type UseCompletionOptions, type UseCompletionResult, type UseRequestOptions, type UseRequestResult, type UseSessionDocResult, type UseStreamMessagesOptions, type UseUrunAudioLevelOptions, type WorkbenchDocSource, type WorkbenchSession, type WorkbenchStreamSource, formatPayload, getUrunAudioContext, parseJsonObject, pushCapped, registerComponent, resumeUrunAudioContext, useApp, useChat, useCompletion, useImageFrame, useMetricsPanel, useProgressCard, useRequest, useSessionDoc, useSessionPhase, useSessionTrack, useStatusBadge, useStreamMessages, useTextStream, useUrunAudioLevel, useUrunAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { RefObject, ReactNode, Component, ErrorInfo, ComponentType } from 'react';
|
|
4
4
|
export { UrunAuthMode, authMode, urunPublicEnv, usesWorkOSAuth } from './auth.js';
|
|
5
|
-
import { SessionInterface, SessionDocument, SessionStream, SessionPhase } from '@urun-sh/core';
|
|
5
|
+
import { SessionInterface, SessionDocument, SessionStream, SessionPhase, SessionStatus } from '@urun-sh/core';
|
|
6
6
|
export { App as AppInterface, AppOptions, SessionDocument, Session as SessionInterface, SessionPhase, SessionPhaseName, SessionStream } from '@urun-sh/core';
|
|
7
7
|
import { ZodSchema, z } from 'zod';
|
|
8
8
|
import Player from 'video.js/dist/types/player';
|
|
@@ -74,6 +74,8 @@ interface ReactSession extends Omit<SessionInterface, 'doc' | 'stream'> {
|
|
|
74
74
|
stream(name: string): ReactSessionStream;
|
|
75
75
|
|
|
76
76
|
readonly phase: SessionPhase;
|
|
77
|
+
|
|
78
|
+
readonly status: SessionStatus;
|
|
77
79
|
}
|
|
78
80
|
type ReactApp = Record<string, (args?: Record<string, unknown>) => ReactSession>;
|
|
79
81
|
|
|
@@ -275,12 +277,12 @@ declare const ImageFrameSchema: z.ZodObject<{
|
|
|
275
277
|
caption: z.ZodOptional<z.ZodString>;
|
|
276
278
|
}, "strip", z.ZodTypeAny, {
|
|
277
279
|
src: string;
|
|
278
|
-
alt?: string | undefined;
|
|
279
280
|
caption?: string | undefined;
|
|
281
|
+
alt?: string | undefined;
|
|
280
282
|
}, {
|
|
281
283
|
src: string;
|
|
282
|
-
alt?: string | undefined;
|
|
283
284
|
caption?: string | undefined;
|
|
285
|
+
alt?: string | undefined;
|
|
284
286
|
}>;
|
|
285
287
|
type ImageFrameProps = z.infer<typeof ImageFrameSchema>;
|
|
286
288
|
declare function useImageFrame(props: ImageFrameProps): {
|
|
@@ -296,24 +298,24 @@ declare const MetricsPanelSchema: z.ZodObject<{
|
|
|
296
298
|
value: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
|
|
297
299
|
unit: z.ZodOptional<z.ZodString>;
|
|
298
300
|
}, "strip", z.ZodTypeAny, {
|
|
299
|
-
value: string | number;
|
|
300
301
|
label: string;
|
|
302
|
+
value: string | number;
|
|
301
303
|
unit?: string | undefined;
|
|
302
304
|
}, {
|
|
303
|
-
value: string | number;
|
|
304
305
|
label: string;
|
|
306
|
+
value: string | number;
|
|
305
307
|
unit?: string | undefined;
|
|
306
308
|
}>, "many">;
|
|
307
309
|
}, "strip", z.ZodTypeAny, {
|
|
308
310
|
metrics: {
|
|
309
|
-
value: string | number;
|
|
310
311
|
label: string;
|
|
312
|
+
value: string | number;
|
|
311
313
|
unit?: string | undefined;
|
|
312
314
|
}[];
|
|
313
315
|
}, {
|
|
314
316
|
metrics: {
|
|
315
|
-
value: string | number;
|
|
316
317
|
label: string;
|
|
318
|
+
value: string | number;
|
|
317
319
|
unit?: string | undefined;
|
|
318
320
|
}[];
|
|
319
321
|
}>;
|
|
@@ -415,6 +417,8 @@ interface UrunVoiceSessionSource {
|
|
|
415
417
|
timeout?: number;
|
|
416
418
|
signal?: AbortSignal;
|
|
417
419
|
}): Promise<void>;
|
|
420
|
+
|
|
421
|
+
readonly status?: SessionStatus;
|
|
418
422
|
}
|
|
419
423
|
|
|
420
424
|
interface UrunVoiceHandle {
|
|
@@ -473,6 +477,8 @@ interface UrunCameraSessionSource {
|
|
|
473
477
|
timeout?: number;
|
|
474
478
|
signal?: AbortSignal;
|
|
475
479
|
}): Promise<void>;
|
|
480
|
+
|
|
481
|
+
readonly status?: SessionStatus;
|
|
476
482
|
}
|
|
477
483
|
|
|
478
484
|
type UrunCameraFacing = 'user' | 'environment';
|
|
@@ -555,4 +561,158 @@ declare function getUrunAudioContext(): AudioContext | null;
|
|
|
555
561
|
|
|
556
562
|
declare function resumeUrunAudioContext(): void;
|
|
557
563
|
|
|
558
|
-
|
|
564
|
+
interface WorkbenchStreamSource {
|
|
565
|
+
|
|
566
|
+
readonly track: MediaStreamTrack | null;
|
|
567
|
+
|
|
568
|
+
on(event: 'track', handler: (track: MediaStreamTrack | null) => void): () => void;
|
|
569
|
+
|
|
570
|
+
messages(): AsyncIterable<unknown>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
interface WorkbenchDocSource {
|
|
574
|
+
|
|
575
|
+
get(path?: string, defaultValue?: unknown): unknown;
|
|
576
|
+
|
|
577
|
+
set(patch: Record<string, unknown>): void;
|
|
578
|
+
|
|
579
|
+
on(event: 'change', handler: (snapshot: unknown) => void): () => void;
|
|
580
|
+
|
|
581
|
+
readonly synced: boolean;
|
|
582
|
+
|
|
583
|
+
onSynced(handler: () => void): () => void;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
interface WorkbenchSession {
|
|
587
|
+
|
|
588
|
+
readonly id: string;
|
|
589
|
+
|
|
590
|
+
readonly phase: SessionPhase;
|
|
591
|
+
|
|
592
|
+
onPhase(handler: (phase: SessionPhase) => void): () => void;
|
|
593
|
+
|
|
594
|
+
stream(name: string): WorkbenchStreamSource;
|
|
595
|
+
|
|
596
|
+
doc(key: string): WorkbenchDocSource;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
declare function useSessionTrack(session: WorkbenchSession | null, name: string): MediaStreamTrack | null;
|
|
600
|
+
|
|
601
|
+
interface UseSessionDocResult<T> {
|
|
602
|
+
|
|
603
|
+
snapshot: T | null;
|
|
604
|
+
|
|
605
|
+
synced: boolean;
|
|
606
|
+
|
|
607
|
+
set: (patch: Partial<T> & Record<string, unknown>) => void;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
declare function useSessionDoc<T = Record<string, unknown>>(session: WorkbenchSession | null, key: string): UseSessionDocResult<T>;
|
|
611
|
+
|
|
612
|
+
declare const DEFAULT_LOG_CAP = 200;
|
|
613
|
+
|
|
614
|
+
declare function pushCapped<T>(list: readonly T[], entry: T, cap?: number): T[];
|
|
615
|
+
|
|
616
|
+
interface StreamMessageEntry {
|
|
617
|
+
at: number;
|
|
618
|
+
payload: unknown;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
interface SpineEntry {
|
|
622
|
+
at: number;
|
|
623
|
+
kind: 'phase' | 'track' | 'doc';
|
|
624
|
+
text: string;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
declare function formatPayload(payload: unknown): string;
|
|
628
|
+
type JsonObjectParse = {
|
|
629
|
+
ok: true;
|
|
630
|
+
value: Record<string, unknown>;
|
|
631
|
+
} | {
|
|
632
|
+
ok: false;
|
|
633
|
+
error: string;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
declare function parseJsonObject(text: string): JsonObjectParse;
|
|
637
|
+
|
|
638
|
+
interface UseStreamMessagesOptions {
|
|
639
|
+
|
|
640
|
+
cap?: number;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
declare function useStreamMessages(session: WorkbenchSession | null, name: string, options?: UseStreamMessagesOptions): StreamMessageEntry[];
|
|
644
|
+
|
|
645
|
+
interface UrunStreamTailProps {
|
|
646
|
+
|
|
647
|
+
session: WorkbenchSession | null;
|
|
648
|
+
|
|
649
|
+
name: string;
|
|
650
|
+
|
|
651
|
+
cap?: number;
|
|
652
|
+
className?: string;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
declare function UrunStreamTail({ session, name, cap, className }: UrunStreamTailProps): react_jsx_runtime.JSX.Element;
|
|
656
|
+
|
|
657
|
+
declare function DocPatchForm({ placeholder, buttonLabel, disabled, onApply, }: {
|
|
658
|
+
placeholder?: string;
|
|
659
|
+
buttonLabel: string;
|
|
660
|
+
disabled?: boolean;
|
|
661
|
+
onApply: (patch: Record<string, unknown>, raw: string) => void;
|
|
662
|
+
}): react_jsx_runtime.JSX.Element;
|
|
663
|
+
interface UrunDocPanelProps {
|
|
664
|
+
session: WorkbenchSession | null;
|
|
665
|
+
|
|
666
|
+
docKey: string;
|
|
667
|
+
|
|
668
|
+
editable?: boolean;
|
|
669
|
+
|
|
670
|
+
patchPlaceholder?: string;
|
|
671
|
+
className?: string;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
declare function UrunDocPanel({ session, docKey, editable, patchPlaceholder, className, }: UrunDocPanelProps): react_jsx_runtime.JSX.Element;
|
|
675
|
+
|
|
676
|
+
interface UrunControlSenderProps {
|
|
677
|
+
session: WorkbenchSession | null;
|
|
678
|
+
|
|
679
|
+
docKey?: string;
|
|
680
|
+
|
|
681
|
+
cap?: number;
|
|
682
|
+
className?: string;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
declare function UrunControlSender({ session, docKey, cap, className, }: UrunControlSenderProps): react_jsx_runtime.JSX.Element;
|
|
686
|
+
|
|
687
|
+
interface UrunEventSpineProps {
|
|
688
|
+
session: WorkbenchSession | null;
|
|
689
|
+
|
|
690
|
+
trackNames?: string[];
|
|
691
|
+
|
|
692
|
+
docKeys?: string[];
|
|
693
|
+
|
|
694
|
+
cap?: number;
|
|
695
|
+
className?: string;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
declare function UrunEventSpine({ session, trackNames, docKeys, cap, className, }: UrunEventSpineProps): react_jsx_runtime.JSX.Element;
|
|
699
|
+
|
|
700
|
+
declare function useSessionPhase(session: WorkbenchSession | null): SessionPhase | null;
|
|
701
|
+
interface UrunSessionStatusProps {
|
|
702
|
+
session: WorkbenchSession | null;
|
|
703
|
+
className?: string;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
declare function UrunSessionStatus({ session, className }: UrunSessionStatusProps): react_jsx_runtime.JSX.Element;
|
|
707
|
+
interface UrunSessionGateProps {
|
|
708
|
+
session: WorkbenchSession | null;
|
|
709
|
+
|
|
710
|
+
children: ReactNode;
|
|
711
|
+
|
|
712
|
+
fallback?: (phase: SessionPhase | null) => ReactNode;
|
|
713
|
+
className?: string;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
declare function UrunSessionGate({ session, children, fallback, className, }: UrunSessionGateProps): react_jsx_runtime.JSX.Element;
|
|
717
|
+
|
|
718
|
+
export { type ChatMessage, type ChatRole, ComponentRenderer, DEFAULT_CAMERA_CONSTRAINTS, DEFAULT_LOG_CAP, DEFAULT_VOICE_CONSTRAINTS, DocPatchForm, ImageFrame, ImageFrameSchema, type JsonObjectParse, MetricsPanel, MetricsPanelSchema, ProgressCard, ProgressCardSchema, type ReactApp, type ReactSession, type ReactSessionDocument, type ReactSessionStream, type RegisteredComponent, type RequestCapableSession, type RequestStream, type SessionRequestOptions, type SpineEntry, StatusBadge, StatusBadgeSchema, type StreamMessageEntry, TextStream, TextStreamSchema, type UrunAccessToken, type UrunAccessTokenProvider, UrunAudio, type UrunAudioHandle, type UrunAudioLevel, type UrunAudioProps, type UrunAudioSessionSource, type UrunAudioStreamSource, type UrunAuthContextValue, UrunAuthProvider, type UrunAuthProviderProps, UrunCamera, type UrunCameraFacing, type UrunCameraHandle, type UrunCameraProps, type UrunCameraSessionSource, type UrunCameraStreamSource, UrunControlSender, type UrunControlSenderProps, UrunDocPanel, type UrunDocPanelProps, UrunErrorBoundary, UrunEventSpine, type UrunEventSpineProps, UrunJwtProvider, UrunProvider, UrunSessionGate, type UrunSessionGateProps, UrunSessionStatus, type UrunSessionStatusProps, UrunStreamTail, type UrunStreamTailProps, UrunVideo, type UrunVideoProps, UrunVoice, type UrunVoiceHandle, type UrunVoiceProps, type UrunVoiceSessionSource, type UrunVoiceStreamSource, type UseChatOptions, type UseChatResult, type UseCompletionOptions, type UseCompletionResult, type UseRequestOptions, type UseRequestResult, type UseSessionDocResult, type UseStreamMessagesOptions, type UseUrunAudioLevelOptions, type WorkbenchDocSource, type WorkbenchSession, type WorkbenchStreamSource, formatPayload, getUrunAudioContext, parseJsonObject, pushCapped, registerComponent, resumeUrunAudioContext, useApp, useChat, useCompletion, useImageFrame, useMetricsPanel, useProgressCard, useRequest, useSessionDoc, useSessionPhase, useSessionTrack, useStatusBadge, useStreamMessages, useTextStream, useUrunAudioLevel, useUrunAuth };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var qr=Object.create;var he=Object.defineProperty;var Vr=Object.getOwnPropertyDescriptor;var jr=Object.getOwnPropertyNames;var Br=Object.getPrototypeOf,Dr=Object.prototype.hasOwnProperty;var Hr=(r,e)=>{for(var t in e)he(r,t,{get:e[t],enumerable:!0})},$e=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of jr(e))!Dr.call(r,s)&&s!==t&&he(r,s,{get:()=>e[s],enumerable:!(o=Vr(e,s))||o.enumerable});return r};var Fr=(r,e,t)=>(t=r!=null?qr(Br(r)):{},$e(e||!r||!r.__esModule?he(t,"default",{value:r,enumerable:!0}):t,r)),zr=r=>$e(he({},"__esModule",{value:!0}),r);var it={};Hr(it,{ComponentRenderer:()=>dr,DEFAULT_CAMERA_CONSTRAINTS:()=>Fe,DEFAULT_VOICE_CONSTRAINTS:()=>He,ImageFrame:()=>Sr,ImageFrameSchema:()=>vr,MetricsPanel:()=>kr,MetricsPanelSchema:()=>yr,ProgressCard:()=>pr,ProgressCardSchema:()=>lr,StatusBadge:()=>fr,StatusBadgeSchema:()=>mr,TextStream:()=>hr,TextStreamSchema:()=>gr,UrunAudio:()=>Re,UrunAuthProvider:()=>_e,UrunCamera:()=>Nr,UrunErrorBoundary:()=>ee,UrunJwtProvider:()=>Ze,UrunProvider:()=>Ye,UrunVideo:()=>Pr,UrunVoice:()=>Ar,authMode:()=>ue,getUrunAudioContext:()=>ge,registerComponent:()=>ur,resumeUrunAudioContext:()=>Te,urunPublicEnv:()=>X,useApp:()=>er,useChat:()=>ir,useCompletion:()=>nr,useImageFrame:()=>je,useMetricsPanel:()=>Be,useProgressCard:()=>Oe,useRequest:()=>rr,useStatusBadge:()=>qe,useTextStream:()=>Ve,useUrunAudioLevel:()=>Ir,useUrunAuth:()=>Se,usesWorkOSAuth:()=>Je});module.exports=zr(it);var te=require("react");var Xe=require("react"),ae=require("react/jsx-runtime"),ee=class extends Xe.Component{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error("[urun] Error caught by UrunErrorBoundary:",e,t)}render(){if(this.state.error){let{fallback:e}=this.props;return typeof e=="function"?e(this.state.error):e||(0,ae.jsxs)("div",{role:"status","aria-live":"polite",style:{padding:"16px",border:"1px solid rgba(17, 24, 39, 0.12)",borderRadius:"8px",background:"#ffffff",color:"#111827",fontFamily:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',maxWidth:"360px"},children:[(0,ae.jsx)("p",{style:{margin:0,fontWeight:600},children:"Connection interrupted"}),(0,ae.jsx)("p",{style:{margin:"6px 0 0",color:"#4b5563"},children:"Reconnecting automatically."})]})}return this.props.children}};var We=require("react"),ve=(0,We.createContext)(null);function G(r){return r&&r.trim()?r.trim():void 0}function X(r){switch(r){case"NEXT_PUBLIC_AUTH_MODE":return G(typeof process<"u"?process.env?.NEXT_PUBLIC_AUTH_MODE:void 0);case"NEXT_PUBLIC_AUTH_ENABLED":return G(typeof process<"u"?process.env?.NEXT_PUBLIC_AUTH_ENABLED:void 0);case"NEXT_PUBLIC_SESSION_AUTH_PROVIDER":return G(typeof process<"u"?process.env?.NEXT_PUBLIC_SESSION_AUTH_PROVIDER:void 0);case"NEXT_PUBLIC_SESSION_TOKEN":return G(typeof process<"u"?process.env?.NEXT_PUBLIC_SESSION_TOKEN:void 0);case"NEXT_PUBLIC_URUN_JWT":return G(typeof process<"u"?process.env?.NEXT_PUBLIC_URUN_JWT:void 0);case"VERCEL_ENV":return G(typeof process<"u"?process.env?.VERCEL_ENV:void 0);default:return G(typeof process<"u"?process.env?.[r]:void 0)}}function ue(){let r=X("NEXT_PUBLIC_AUTH_MODE")?.toLowerCase();return r==="jwt"||r==="customer-jwt"||r==="test-jwt"?"jwt":r==="workos"||X("VERCEL_ENV")==="production"?"workos":X("NEXT_PUBLIC_AUTH_ENABLED")==="false"?"jwt":"workos"}function Je(){return ue()==="workos"}var re=require("react"),Ge=require("react/jsx-runtime"),Ke=(0,re.createContext)(null);function _e({getAccessToken:r,children:e}){let t=(0,re.useMemo)(()=>({getAccessToken:r}),[r]);return(0,Ge.jsx)(Ke.Provider,{value:t,children:e})}var Ze=_e;function Se(){return(0,re.useContext)(Ke)}var ye=require("react/jsx-runtime");function Ye({baseUrl:r,orgId:e,appId:t,jwt:o,authProvider:s,fallback:u,children:l}){let[U,c]=(0,te.useState)(),v=Se(),R=X("NEXT_PUBLIC_SESSION_TOKEN")??X("NEXT_PUBLIC_URUN_JWT"),p=ue(),h=p==="workos"&&!o,E=o??(p==="jwt"?R:void 0)??U,k=s??X("NEXT_PUBLIC_SESSION_AUTH_PROVIDER"),C=h&&!E,S=(0,te.useMemo)(()=>({appId:t,baseUrl:r,orgId:e,jwt:E,getAccessToken:h?v?.getAccessToken:void 0,authProvider:k}),[t,v,r,k,E,e,h]);return(0,te.useEffect)(()=>{if(!h||!v)return;let d=!1,m=v;async function f(){try{let y=await m.getAccessToken();d||c(y??void 0)}catch{d||c(void 0)}}f();let x=window.setInterval(()=>{f()},6e4);return()=>{d=!0,window.clearInterval(x)}},[v,h]),(0,ye.jsx)(ee,{fallback:u,children:C?(0,ye.jsx)("div",{role:"status","aria-live":"polite",children:"Signing in..."}):(0,ye.jsx)(ve.Provider,{value:S,children:l})})}var W=require("react"),Qe=require("@urun-sh/core");function $r(r,e){return`${r}:${JSON.stringify(e??{})}`}var Me=class{constructor(e,t){this._doc=e;this._notify=t;this._unsubscribeChange=this._doc.on("change",()=>this._notify())}_doc;_notify;_unsubscribeChange;get(e,t){return this._doc.get(e,t)}set(e){this._doc.set(e),this._notify()}on(e,t){return this._doc.on(e,o=>t(o))}get synced(){return this._doc.synced}onSynced(e){return this._doc.onSynced(()=>{e(),this._notify()})}text(e){let t=this._doc.text(e),o=this._notify;return{append(s){t.append(s),o()},toString:()=>t.toString(),get length(){return t.length},on:(s,u)=>t.on(s,l=>{u(l),o()})}}dispose(){this._unsubscribeChange()}},Ne=class{constructor(e,t){this._stream=e;this._notify=t;this._unsubscribeTrack=this._stream.on("track",()=>this._notify())}_stream;_notify;_unsubscribeTrack;get track(){return this._stream.track}attach(e){return this._stream.attach(e)}attachVideo(e){return this._stream.attachVideo(e)}detach(){return this._stream.detach()}detachVideo(){return this._stream.detachVideo()}seek(e){return this._stream.seek(e)}chunks(e){return this._stream.chunks(e)}onSeeked(e){return this._stream.onSeeked(e)}on(e,t){return this._stream.on(e,t)}messages(){return this._stream.messages()}emit(e,t){return this._stream.emit(e,t)}dispose(){this._unsubscribeTrack()}},Ie=class{constructor(e,t){this._session=e;this._notify=t;this._unsubscribePhase=this._session.onPhase(()=>this._notify())}_session;_notify;_docs=new Map;_streams=new Map;_unsubscribePhase;_disposed=!1;get disposed(){return this._disposed}get id(){return this._session.id}get phase(){return this._session.phase}onPhase(e){return this._session.onPhase(e)}whenLive(e){return this._session.whenLive(e)}request(e,t){return this._session.request(e,t)}requestStream(e,t){return this._session.requestStream(e,t)}complete(e,t){return this._session.complete(e,t)}get recordings(){return this._session.recordings}get artifacts(){return this._session.artifacts}get presence(){return this._session.presence}doc(e){let t=this._docs.get(e);return t||(t=new Me(this._session.doc(e),this._notify),this._docs.set(e,t)),t}stream(e){let t=this._streams.get(e);return t||(t=new Ne(this._session.stream(e),this._notify),this._streams.set(e,t)),t}disconnect(){this._disposed=!0;for(let e of this._docs.values())e.dispose();for(let e of this._streams.values())e.dispose();this._docs.clear(),this._streams.clear(),this._unsubscribePhase(),this._session.disconnect(),this._notify()}};function er(){let r=(0,W.useContext)(ve);if(!r)throw new Error("useApp must be used within <UrunProvider>");if(!r.appId)throw new Error('useApp requires <UrunProvider appId="...">');let[,e]=(0,W.useReducer)(s=>s+1,0),t=(0,W.useRef)(new Map),o=(0,W.useMemo)(()=>(0,Qe.App)(r.appId,{baseUrl:r.baseUrl,orgId:r.orgId,jwt:r.jwt,getAccessToken:r.getAccessToken,authProvider:r.authProvider}),[r.appId,r.baseUrl,r.orgId,r.jwt,r.getAccessToken,r.authProvider]);return(0,W.useMemo)(()=>new Proxy({},{get(s,u){if(typeof u=="string")return l=>{let U=$r(u,l),c=t.current.get(U);if(c&&!c.disposed)return c;let v=new Ie(o[u](l),e);return t.current.set(U,v),v}}}),[o])}var q=require("react");function ne(r){let e=r;if(!e||typeof e.request!="function"||typeof e.requestStream!="function")throw new Error("This session does not support request/requestStream. Upgrade @urun-sh/core to a version that ships the request/response primitive.");return e}function Xr(r){return r instanceof Error?r:new Error(String(r))}function rr(r,e){let t=(0,q.useMemo)(()=>ne(r),[r]),[o,s]=(0,q.useState)(void 0),[u,l]=(0,q.useState)(null),[U,c]=(0,q.useState)(!1),v=(0,q.useRef)(e);v.current=e;let R=(0,q.useRef)(0),p=(0,q.useRef)(null),h=(0,q.useRef)(!0);(0,q.useEffect)(()=>(h.current=!0,()=>{h.current=!1,p.current?.abort()}),[]);let E=(0,q.useCallback)(async S=>{p.current?.abort();let d=new AbortController;p.current=d;let m=++R.current,f=()=>h.current&&R.current===m;f()&&(c(!0),l(null));try{let x=await t.request(S,{...v.current,signal:d.signal});return f()&&(s(x),c(!1),v.current?.onSuccess?.(x)),x}catch(x){let y=Xr(x);throw f()&&(l(y),c(!1),v.current?.onError?.(y)),y}},[t]),k=(0,q.useCallback)(S=>{E(S).catch(()=>{})},[E]),C=(0,q.useCallback)(()=>{R.current++,p.current?.abort(),p.current=null,s(void 0),l(null),c(!1)},[]);return{mutate:k,mutateAsync:E,data:o,error:u,isPending:U,reset:C}}var j=require("react");function tr(r){return r instanceof Error?r:new Error(String(r))}var Wr=r=>typeof r=="string"?r:String(r);function nr(r,e){let t=(0,j.useMemo)(()=>ne(r),[r]),[o,s]=(0,j.useState)(""),[u,l]=(0,j.useState)(!1),[U,c]=(0,j.useState)(null),v=(0,j.useRef)(e);v.current=e;let R=(0,j.useRef)(0),p=(0,j.useRef)(null),h=(0,j.useRef)(!0);(0,j.useEffect)(()=>(h.current=!0,()=>{h.current=!1,p.current?.cancel(),p.current=null}),[]);let E=(0,j.useCallback)(()=>{R.current++,p.current?.cancel(),p.current=null,h.current&&l(!1)},[]),k=(0,j.useCallback)(async C=>{p.current?.cancel();let S=++R.current,d=()=>h.current&&R.current===S,m=v.current,f=m?.parseChunk??Wr,x=m?.buildPayload??(a=>({prompt:a}));d()&&(s(""),c(null),l(!0));let{parseChunk:y,buildPayload:H,onFinish:M,onError:n,...i}=m??{},g="",b;try{b=t.requestStream(x(C),i),p.current=b}catch(a){let w=tr(a);d()&&(c(w),l(!1),m?.onError?.(w));return}try{for await(let a of b){if(R.current!==S)break;g+=f(a),d()&&s(g)}d()&&(l(!1),m?.onFinish?.(g))}catch(a){let w=tr(a);d()&&(c(w),l(!1),m?.onError?.(w))}finally{p.current===b&&(p.current=null)}},[t]);return{completion:o,complete:k,stop:E,isStreaming:u,error:U}}var I=require("react");function or(r){return r instanceof Error?r:new Error(String(r))}var Jr=r=>typeof r=="string"?r:String(r),sr=0;function Le(r){return sr+=1,`${r}-${sr}`}function ir(r,e){let t=(0,I.useMemo)(()=>ne(r),[r]),[o,s]=(0,I.useState)(()=>(e?.initialMessages??[]).map(f=>({id:f.id??Le("msg"),role:f.role,content:f.content}))),[u,l]=(0,I.useState)(""),[U,c]=(0,I.useState)(!1),[v,R]=(0,I.useState)(null),p=(0,I.useRef)(e);p.current=e;let h=(0,I.useRef)(o);h.current=o;let E=(0,I.useRef)(u);E.current=u;let k=(0,I.useRef)(0),C=(0,I.useRef)(null),S=(0,I.useRef)(!0);(0,I.useEffect)(()=>(S.current=!0,()=>{S.current=!1,C.current?.cancel(),C.current=null}),[]);let d=(0,I.useCallback)(()=>{k.current++,C.current?.cancel(),C.current=null,S.current&&c(!1)},[]),m=(0,I.useCallback)(async f=>{let x=f===void 0,y=(x?E.current:f)??"";if(!y.trim())return;C.current?.cancel();let M=++k.current,n=()=>S.current&&k.current===M,i=p.current,g=i?.parseChunk??Jr,b={id:Le("msg"),role:"user",content:y},a={id:Le("msg"),role:"assistant",content:""},w=[...h.current,b].map(N=>({role:N.role,content:N.content})),T=[...h.current,b,a];h.current=T,s(T),x&&l(""),R(null),c(!0);let $=i?.buildPayload??(N=>({messages:N})),{initialMessages:Pe,parseChunk:Ee,buildPayload:we,onFinish:Ae,onError:Lr,..._}=i??{},B=N=>{s(F=>F.map(V=>V.id===a.id?{...V,content:N}:V))},K="",D;try{D=t.requestStream($(w),_),C.current=D}catch(N){let F=or(N);n()&&(R(F),c(!1),i?.onError?.(F));return}try{for await(let N of D){if(k.current!==M)break;K+=g(N),n()&&B(K)}n()&&(c(!1),i?.onFinish?.({...a,content:K}))}catch(N){let F=or(N);n()&&(R(F),c(!1),i?.onError?.(F))}finally{C.current===D&&(C.current=null)}},[t]);return{messages:o,input:u,setInput:l,sendMessage:m,stop:d,isStreaming:U,error:v}}var ar=new Map;function ur(r,e,t){if(!t||typeof t.safeParse!="function")throw new Error(`registerComponent("${r}"): schema must be a valid Zod schema`);ar.set(r,{component:e,schema:t})}function cr(r,e){let t=ar.get(r);if(!t)return{error:`Unknown component: "${r}"`};let o=t.schema.safeParse(e);return o.success?{Component:t.component,validatedProps:o.data}:{error:`Validation failed for "${r}": ${o.error.message}`}}var Y=require("react/jsx-runtime");function dr({name:r,props:e,fallback:t}){let o=cr(r,e);if(o.error)return console.warn(`[urun] ComponentRenderer: ${o.error}`),t?(0,Y.jsx)(Y.Fragment,{children:t}):(0,Y.jsx)("div",{className:"urun-component-error",role:"alert",children:(0,Y.jsx)("span",{className:"urun-component-error-text",children:o.error})});let s=o.Component;return(0,Y.jsx)(s,{...o.validatedProps})}var oe=require("zod"),Q=require("react/jsx-runtime"),lr=oe.z.object({step:oe.z.number().min(0),total:oe.z.number().min(1),label:oe.z.string().optional(),variant:oe.z.enum(["default","success","error"]).default("default")});function Oe(r){let{step:e,total:t,label:o,variant:s="default"}=r,u=Math.min(e/t*100,100),l=e>=t;return{step:e,total:t,label:o,variant:s,percentage:u,isComplete:l}}function pr(r){let{step:e,total:t,label:o,variant:s,percentage:u}=Oe(r);return(0,Q.jsxs)("div",{className:"urun-progress-card","data-variant":s,children:[o&&(0,Q.jsx)("div",{className:"urun-progress-label",children:o}),(0,Q.jsx)("div",{className:"urun-progress-bar",children:(0,Q.jsx)("div",{className:"urun-progress-fill",style:{width:`${u}%`}})}),(0,Q.jsxs)("div",{className:"urun-progress-text",children:[e,"/",t]})]})}var ke=require("zod"),ce=require("react/jsx-runtime"),mr=ke.z.object({state:ke.z.enum(["thinking","generating","idle","error"]),message:ke.z.string().optional()}),Kr={thinking:"Thinking...",generating:"Generating...",idle:"Idle",error:"Error"};function qe(r){let{state:e,message:t}=r,o=e==="thinking"||e==="generating",s=t??Kr[e]??e;return{state:e,message:s,isActive:o}}function fr(r){let{state:e,message:t,isActive:o}=qe(r);return(0,ce.jsxs)("span",{className:"urun-status-badge","data-state":e,children:[(0,ce.jsx)("span",{className:`urun-status-indicator${o?" urun-status-pulse":""}`}),(0,ce.jsx)("span",{className:"urun-status-message",children:t})]})}var de=require("react"),be=require("zod"),le=require("react/jsx-runtime"),gr=be.z.object({text:be.z.string(),streaming:be.z.boolean().default(!1)});function Ve(r){let{text:e,streaming:t=!1}=r,o=e.length===0;return{text:e,streaming:t,isEmpty:o}}function hr(r){let{text:e,streaming:t}=Ve(r),o=(0,de.useRef)(null),s=(0,de.useRef)(0);return(0,de.useEffect)(()=>{let u=o.current;u&&e.length!==s.current&&(u.textContent=e,s.current=e.length)},[e]),(0,le.jsxs)("div",{className:"urun-text-stream",children:[(0,le.jsx)("span",{ref:o,className:"urun-text-content"}),t&&(0,le.jsx)("span",{className:"urun-text-cursor"})]})}var pe=require("zod"),me=require("react/jsx-runtime"),vr=pe.z.object({src:pe.z.string().url(),alt:pe.z.string().optional(),caption:pe.z.string().optional()});function je(r){let{src:e,alt:t,caption:o}=r;return{src:e,alt:t??"",caption:o}}function Sr(r){let{src:e,alt:t,caption:o}=je(r);return(0,me.jsxs)("figure",{className:"urun-image-frame",children:[(0,me.jsx)("img",{className:"urun-image",src:e,alt:t}),o&&(0,me.jsx)("figcaption",{className:"urun-image-caption",children:o})]})}var J=require("zod"),se=require("react/jsx-runtime"),yr=J.z.object({metrics:J.z.array(J.z.object({label:J.z.string(),value:J.z.union([J.z.string(),J.z.number()]),unit:J.z.string().optional()}))});function Be(r){return{metrics:r.metrics.map(t=>({...t,displayValue:t.unit?`${t.value} ${t.unit}`:String(t.value)}))}}function kr(r){let{metrics:e}=Be(r);return(0,se.jsx)("div",{className:"urun-metrics-panel",children:e.map((t,o)=>(0,se.jsxs)("div",{className:"urun-metric-card",children:[(0,se.jsx)("div",{className:"urun-metric-label",children:t.label}),(0,se.jsx)("div",{className:"urun-metric-value",children:t.displayValue})]},o))})}var L=require("react"),xr=Fr(require("video.js")),jt=require("video.js/dist/video-js.css");var ie=require("react");var fe=require("react"),Zr=require("@urun-sh/core/internal");var Gr=require("react/jsx-runtime"),br=(0,fe.createContext)(null);function Cr(r){let e=(0,ie.useContext)(br);if(!e)throw new Error("useTrack must be used within <SessionProvider> or <UrunProvider>");let[t,o]=(0,ie.useState)(null);return(0,ie.useEffect)(()=>{let s=e.getState()._transport;if(!s)return;let u=s.getTrackByName?.bind(s),l=u?.(r);l&&l.readyState!=="ended"&&o(l);let U=s.on("track",c=>{let v=u?.(r);v&&v.id!==c.id||(o(c),c.addEventListener("ended",()=>{o(null)}))});return()=>{U()}},[r,e]),t}var z=require("react/jsx-runtime");function Tr(r){r.posterImage?.hide?.()}var Yr=`
|
|
1
|
+
"use strict";var mt=Object.create;var Ue=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var ht=Object.getPrototypeOf,vt=Object.prototype.hasOwnProperty;var St=(e,r)=>{for(var t in r)Ue(e,t,{get:r[t],enumerable:!0})},mr=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of gt(r))!vt.call(e,o)&&o!==t&&Ue(e,o,{get:()=>r[o],enumerable:!(n=ft(r,o))||n.enumerable});return e};var yt=(e,r,t)=>(t=e!=null?mt(ht(e)):{},mr(r||!e||!e.__esModule?Ue(t,"default",{value:e,enumerable:!0}):t,e)),bt=e=>mr(Ue({},"__esModule",{value:!0}),e);var qt={};St(qt,{ComponentRenderer:()=>Nr,DEFAULT_CAMERA_CONSTRAINTS:()=>dr,DEFAULT_LOG_CAP:()=>re,DEFAULT_VOICE_CONSTRAINTS:()=>cr,DocPatchForm:()=>Re,ImageFrame:()=>jr,ImageFrameSchema:()=>Dr,MetricsPanel:()=>Br,MetricsPanelSchema:()=>Fr,ProgressCard:()=>Lr,ProgressCardSchema:()=>_r,StatusBadge:()=>Ir,StatusBadgeSchema:()=>Or,TextStream:()=>Vr,TextStreamSchema:()=>qr,UrunAudio:()=>Oe,UrunAuthProvider:()=>Ze,UrunCamera:()=>rt,UrunControlSender:()=>it,UrunDocPanel:()=>st,UrunErrorBoundary:()=>ue,UrunEventSpine:()=>ut,UrunJwtProvider:()=>Sr,UrunProvider:()=>br,UrunSessionGate:()=>lt,UrunSessionStatus:()=>ct,UrunStreamTail:()=>ot,UrunVideo:()=>Gr,UrunVoice:()=>Yr,authMode:()=>ve,formatPayload:()=>ge,getUrunAudioContext:()=>Te,parseJsonObject:()=>je,pushCapped:()=>Z,registerComponent:()=>Ar,resumeUrunAudioContext:()=>Le,urunPublicEnv:()=>X,useApp:()=>xr,useChat:()=>Er,useCompletion:()=>Pr,useImageFrame:()=>sr,useMetricsPanel:()=>ar,useProgressCard:()=>tr,useRequest:()=>Cr,useSessionDoc:()=>De,useSessionPhase:()=>We,useSessionTrack:()=>nt,useStatusBadge:()=>nr,useStreamMessages:()=>Be,useTextStream:()=>or,useUrunAudioLevel:()=>tt,useUrunAuth:()=>we,usesWorkOSAuth:()=>hr});module.exports=bt(qt);var le=require("react");var fr=require("react"),he=require("react/jsx-runtime"),ue=class extends fr.Component{constructor(r){super(r),this.state={error:null}}static getDerivedStateFromError(r){return{error:r}}componentDidCatch(r,t){console.error("[urun] Error caught by UrunErrorBoundary:",r,t)}render(){if(this.state.error){let{fallback:r}=this.props;return typeof r=="function"?r(this.state.error):r||(0,he.jsxs)("div",{role:"status","aria-live":"polite",style:{padding:"16px",border:"1px solid rgba(17, 24, 39, 0.12)",borderRadius:"8px",background:"#ffffff",color:"#111827",fontFamily:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',maxWidth:"360px"},children:[(0,he.jsx)("p",{style:{margin:0,fontWeight:600},children:"Connection interrupted"}),(0,he.jsx)("p",{style:{margin:"6px 0 0",color:"#4b5563"},children:"Reconnecting automatically."})]})}return this.props.children}};var gr=require("react"),Ee=(0,gr.createContext)(null);function ne(e){return e&&e.trim()?e.trim():void 0}function X(e){switch(e){case"NEXT_PUBLIC_AUTH_MODE":return ne(typeof process<"u"?process.env?.NEXT_PUBLIC_AUTH_MODE:void 0);case"NEXT_PUBLIC_AUTH_ENABLED":return ne(typeof process<"u"?process.env?.NEXT_PUBLIC_AUTH_ENABLED:void 0);case"NEXT_PUBLIC_SESSION_AUTH_PROVIDER":return ne(typeof process<"u"?process.env?.NEXT_PUBLIC_SESSION_AUTH_PROVIDER:void 0);case"NEXT_PUBLIC_SESSION_TOKEN":return ne(typeof process<"u"?process.env?.NEXT_PUBLIC_SESSION_TOKEN:void 0);case"NEXT_PUBLIC_URUN_JWT":return ne(typeof process<"u"?process.env?.NEXT_PUBLIC_URUN_JWT:void 0);case"VERCEL_ENV":return ne(typeof process<"u"?process.env?.VERCEL_ENV:void 0);default:return ne(typeof process<"u"?process.env?.[e]:void 0)}}function ve(){let e=X("NEXT_PUBLIC_AUTH_MODE")?.toLowerCase();return e==="jwt"||e==="customer-jwt"||e==="test-jwt"?"jwt":e==="workos"||X("VERCEL_ENV")==="production"?"workos":X("NEXT_PUBLIC_AUTH_ENABLED")==="false"?"jwt":"workos"}function hr(){return ve()==="workos"}var ce=require("react"),yr=require("react/jsx-runtime"),vr=(0,ce.createContext)(null);function Ze({getAccessToken:e,children:r}){let t=(0,ce.useMemo)(()=>({getAccessToken:e}),[e]);return(0,yr.jsx)(vr.Provider,{value:t,children:r})}var Sr=Ze;function we(){return(0,ce.useContext)(vr)}var Ae=require("react/jsx-runtime");function br({baseUrl:e,orgId:r,appId:t,jwt:n,authProvider:o,fallback:a,children:i}){let[d,u]=(0,le.useState)(),c=we(),h=X("NEXT_PUBLIC_SESSION_TOKEN")??X("NEXT_PUBLIC_URUN_JWT"),l=ve(),f=l==="workos"&&!n,R=n??(l==="jwt"?h:void 0)??d,x=o??X("NEXT_PUBLIC_SESSION_AUTH_PROVIDER"),T=f&&!R,b=(0,le.useMemo)(()=>({appId:t,baseUrl:e,orgId:r,jwt:R,getAccessToken:f?c?.getAccessToken:void 0,authProvider:x}),[t,c,e,x,R,r,f]);return(0,le.useEffect)(()=>{if(!f||!c)return;let g=!1,v=c;async function S(){try{let k=await v.getAccessToken();g||u(k??void 0)}catch{g||u(void 0)}}S();let U=window.setInterval(()=>{S()},6e4);return()=>{g=!0,window.clearInterval(U)}},[c,f]),(0,Ae.jsx)(ue,{fallback:a,children:T?(0,Ae.jsx)("div",{role:"status","aria-live":"polite",children:"Signing in..."}):(0,Ae.jsx)(Ee.Provider,{value:b,children:i})})}var G=require("react"),kr=require("@urun-sh/core");function kt(e,r){return`${e}:${JSON.stringify(r??{})}`}var Ye=class{constructor(r,t){this._doc=r;this._notify=t;this._unsubscribeChange=this._doc.on("change",()=>this._notify())}_doc;_notify;_unsubscribeChange;get(r,t){return this._doc.get(r,t)}set(r){this._doc.set(r),this._notify()}on(r,t){return this._doc.on(r,n=>t(n))}get synced(){return this._doc.synced}onSynced(r){return this._doc.onSynced(()=>{r(),this._notify()})}text(r){let t=this._doc.text(r),n=this._notify;return{append(o){t.append(o),n()},toString:()=>t.toString(),get length(){return t.length},on:(o,a)=>t.on(o,i=>{a(i),n()})}}dispose(){this._unsubscribeChange()}},Qe=class{constructor(r,t){this._stream=r;this._notify=t;this._unsubscribeTrack=this._stream.on("track",()=>this._notify())}_stream;_notify;_unsubscribeTrack;get track(){return this._stream.track}attach(r){return this._stream.attach(r)}attachVideo(r){return this._stream.attachVideo(r)}detach(){return this._stream.detach()}detachVideo(){return this._stream.detachVideo()}seek(r){return this._stream.seek(r)}chunks(r){return this._stream.chunks(r)}onSeeked(r){return this._stream.onSeeked(r)}on(r,t){return this._stream.on(r,t)}messages(){return this._stream.messages()}emit(r,t){return this._stream.emit(r,t)}dispose(){this._unsubscribeTrack()}},er=class{constructor(r,t){this._session=r;this._notify=t;this._unsubscribePhase=this._session.onPhase(()=>this._notify())}_session;_notify;_docs=new Map;_streams=new Map;_unsubscribePhase;_disposed=!1;get disposed(){return this._disposed}get id(){return this._session.id}get phase(){return this._session.phase}get status(){return this._session.status}onPhase(r){return this._session.onPhase(r)}whenLive(r){return this._session.whenLive(r)}request(r,t){return this._session.request(r,t)}requestStream(r,t){return this._session.requestStream(r,t)}complete(r,t){return this._session.complete(r,t)}get recordings(){return this._session.recordings}get artifacts(){return this._session.artifacts}get presence(){return this._session.presence}doc(r){let t=this._docs.get(r);return t||(t=new Ye(this._session.doc(r),this._notify),this._docs.set(r,t)),t}stream(r){let t=this._streams.get(r);return t||(t=new Qe(this._session.stream(r),this._notify),this._streams.set(r,t)),t}disconnect(){this._disposed=!0;for(let r of this._docs.values())r.dispose();for(let r of this._streams.values())r.dispose();this._docs.clear(),this._streams.clear(),this._unsubscribePhase(),this._session.disconnect(),this._notify()}};function xr(){let e=(0,G.useContext)(Ee);if(!e)throw new Error("useApp must be used within <UrunProvider>");if(!e.appId)throw new Error('useApp requires <UrunProvider appId="...">');let[,r]=(0,G.useReducer)(o=>o+1,0),t=(0,G.useRef)(new Map),n=(0,G.useMemo)(()=>(0,kr.App)(e.appId,{baseUrl:e.baseUrl,orgId:e.orgId,jwt:e.jwt,getAccessToken:e.getAccessToken,authProvider:e.authProvider}),[e.appId,e.baseUrl,e.orgId,e.jwt,e.getAccessToken,e.authProvider]);return(0,G.useMemo)(()=>new Proxy({},{get(o,a){if(typeof a=="string")return i=>{let d=kt(a,i),u=t.current.get(d);if(u&&!u.disposed)return u;let c=new er(n[a](i),r);return t.current.set(d,c),c}}}),[n])}var q=require("react");function de(e){let r=e;if(!r||typeof r.request!="function"||typeof r.requestStream!="function")throw new Error("This session does not support request/requestStream. Upgrade @urun-sh/core to a version that ships the request/response primitive.");return r}function xt(e){return e instanceof Error?e:new Error(String(e))}function Cr(e,r){let t=(0,q.useMemo)(()=>de(e),[e]),[n,o]=(0,q.useState)(void 0),[a,i]=(0,q.useState)(null),[d,u]=(0,q.useState)(!1),c=(0,q.useRef)(r);c.current=r;let h=(0,q.useRef)(0),l=(0,q.useRef)(null),f=(0,q.useRef)(!0);(0,q.useEffect)(()=>(f.current=!0,()=>{f.current=!1,l.current?.abort()}),[]);let R=(0,q.useCallback)(async b=>{l.current?.abort();let g=new AbortController;l.current=g;let v=++h.current,S=()=>f.current&&h.current===v;S()&&(u(!0),i(null));try{let U=await t.request(b,{...c.current,signal:g.signal});return S()&&(o(U),u(!1),c.current?.onSuccess?.(U)),U}catch(U){let k=xt(U);throw S()&&(i(k),u(!1),c.current?.onError?.(k)),k}},[t]),x=(0,q.useCallback)(b=>{R(b).catch(()=>{})},[R]),T=(0,q.useCallback)(()=>{h.current++,l.current?.abort(),l.current=null,o(void 0),i(null),u(!1)},[]);return{mutate:x,mutateAsync:R,data:n,error:a,isPending:d,reset:T}}var V=require("react");function Tr(e){return e instanceof Error?e:new Error(String(e))}var Ct=e=>typeof e=="string"?e:String(e);function Pr(e,r){let t=(0,V.useMemo)(()=>de(e),[e]),[n,o]=(0,V.useState)(""),[a,i]=(0,V.useState)(!1),[d,u]=(0,V.useState)(null),c=(0,V.useRef)(r);c.current=r;let h=(0,V.useRef)(0),l=(0,V.useRef)(null),f=(0,V.useRef)(!0);(0,V.useEffect)(()=>(f.current=!0,()=>{f.current=!1,l.current?.cancel(),l.current=null}),[]);let R=(0,V.useCallback)(()=>{h.current++,l.current?.cancel(),l.current=null,f.current&&i(!1)},[]),x=(0,V.useCallback)(async T=>{l.current?.cancel();let b=++h.current,g=()=>f.current&&h.current===b,v=c.current,S=v?.parseChunk??Ct,U=v?.buildPayload??(m=>({prompt:m}));g()&&(o(""),u(null),i(!0));let{parseChunk:k,buildPayload:z,onFinish:N,onError:s,...p}=v??{},y="",C;try{C=t.requestStream(U(T),p),l.current=C}catch(m){let w=Tr(m);g()&&(u(w),i(!1),v?.onError?.(w));return}try{for await(let m of C){if(h.current!==b)break;y+=S(m),g()&&o(y)}g()&&(i(!1),v?.onFinish?.(y))}catch(m){let w=Tr(m);g()&&(u(w),i(!1),v?.onError?.(w))}finally{l.current===C&&(l.current=null)}},[t]);return{completion:n,complete:x,stop:R,isStreaming:a,error:d}}var L=require("react");function Rr(e){return e instanceof Error?e:new Error(String(e))}var Tt=e=>typeof e=="string"?e:String(e),Ur=0;function rr(e){return Ur+=1,`${e}-${Ur}`}function Er(e,r){let t=(0,L.useMemo)(()=>de(e),[e]),[n,o]=(0,L.useState)(()=>(r?.initialMessages??[]).map(S=>({id:S.id??rr("msg"),role:S.role,content:S.content}))),[a,i]=(0,L.useState)(""),[d,u]=(0,L.useState)(!1),[c,h]=(0,L.useState)(null),l=(0,L.useRef)(r);l.current=r;let f=(0,L.useRef)(n);f.current=n;let R=(0,L.useRef)(a);R.current=a;let x=(0,L.useRef)(0),T=(0,L.useRef)(null),b=(0,L.useRef)(!0);(0,L.useEffect)(()=>(b.current=!0,()=>{b.current=!1,T.current?.cancel(),T.current=null}),[]);let g=(0,L.useCallback)(()=>{x.current++,T.current?.cancel(),T.current=null,b.current&&u(!1)},[]),v=(0,L.useCallback)(async S=>{let U=S===void 0,k=(U?R.current:S)??"";if(!k.trim())return;T.current?.cancel();let N=++x.current,s=()=>b.current&&x.current===N,p=l.current,y=p?.parseChunk??Tt,C={id:rr("msg"),role:"user",content:k},m={id:rr("msg"),role:"assistant",content:""},w=[...f.current,C].map(_=>({role:_.role,content:_.content})),P=[...f.current,C,m];f.current=P,o(P),U&&i(""),h(null),u(!0);let J=p?.buildPayload??(_=>({messages:_})),{initialMessages:Je,parseChunk:Xe,buildPayload:Ge,onFinish:Ke,onError:dt,...M}=p??{},D=_=>{o(H=>H.map(F=>F.id===m.id?{...F,content:_}:F))},ee="",j;try{j=t.requestStream(J(w),M),T.current=j}catch(_){let H=Rr(_);s()&&(h(H),u(!1),p?.onError?.(H));return}try{for await(let _ of j){if(x.current!==N)break;ee+=y(_),s()&&D(ee)}s()&&(u(!1),p?.onFinish?.({...m,content:ee}))}catch(_){let H=Rr(_);s()&&(h(H),u(!1),p?.onError?.(H))}finally{T.current===j&&(T.current=null)}},[t]);return{messages:n,input:a,setInput:i,sendMessage:v,stop:g,isStreaming:d,error:c}}var wr=new Map;function Ar(e,r,t){if(!t||typeof t.safeParse!="function")throw new Error(`registerComponent("${e}"): schema must be a valid Zod schema`);wr.set(e,{component:r,schema:t})}function Mr(e,r){let t=wr.get(e);if(!t)return{error:`Unknown component: "${e}"`};let n=t.schema.safeParse(r);return n.success?{Component:t.component,validatedProps:n.data}:{error:`Validation failed for "${e}": ${n.error.message}`}}var oe=require("react/jsx-runtime");function Nr({name:e,props:r,fallback:t}){let n=Mr(e,r);if(n.error)return console.warn(`[urun] ComponentRenderer: ${n.error}`),t?(0,oe.jsx)(oe.Fragment,{children:t}):(0,oe.jsx)("div",{className:"urun-component-error",role:"alert",children:(0,oe.jsx)("span",{className:"urun-component-error-text",children:n.error})});let o=n.Component;return(0,oe.jsx)(o,{...n.validatedProps})}var pe=require("zod"),se=require("react/jsx-runtime"),_r=pe.z.object({step:pe.z.number().min(0),total:pe.z.number().min(1),label:pe.z.string().optional(),variant:pe.z.enum(["default","success","error"]).default("default")});function tr(e){let{step:r,total:t,label:n,variant:o="default"}=e,a=Math.min(r/t*100,100),i=r>=t;return{step:r,total:t,label:n,variant:o,percentage:a,isComplete:i}}function Lr(e){let{step:r,total:t,label:n,variant:o,percentage:a}=tr(e);return(0,se.jsxs)("div",{className:"urun-progress-card","data-variant":o,children:[n&&(0,se.jsx)("div",{className:"urun-progress-label",children:n}),(0,se.jsx)("div",{className:"urun-progress-bar",children:(0,se.jsx)("div",{className:"urun-progress-fill",style:{width:`${a}%`}})}),(0,se.jsxs)("div",{className:"urun-progress-text",children:[r,"/",t]})]})}var Me=require("zod"),Se=require("react/jsx-runtime"),Or=Me.z.object({state:Me.z.enum(["thinking","generating","idle","error"]),message:Me.z.string().optional()}),Pt={thinking:"Thinking...",generating:"Generating...",idle:"Idle",error:"Error"};function nr(e){let{state:r,message:t}=e,n=r==="thinking"||r==="generating",o=t??Pt[r]??r;return{state:r,message:o,isActive:n}}function Ir(e){let{state:r,message:t,isActive:n}=nr(e);return(0,Se.jsxs)("span",{className:"urun-status-badge","data-state":r,children:[(0,Se.jsx)("span",{className:`urun-status-indicator${n?" urun-status-pulse":""}`}),(0,Se.jsx)("span",{className:"urun-status-message",children:t})]})}var ye=require("react"),Ne=require("zod"),be=require("react/jsx-runtime"),qr=Ne.z.object({text:Ne.z.string(),streaming:Ne.z.boolean().default(!1)});function or(e){let{text:r,streaming:t=!1}=e,n=r.length===0;return{text:r,streaming:t,isEmpty:n}}function Vr(e){let{text:r,streaming:t}=or(e),n=(0,ye.useRef)(null),o=(0,ye.useRef)(0);return(0,ye.useEffect)(()=>{let a=n.current;a&&r.length!==o.current&&(a.textContent=r,o.current=r.length)},[r]),(0,be.jsxs)("div",{className:"urun-text-stream",children:[(0,be.jsx)("span",{ref:n,className:"urun-text-content"}),t&&(0,be.jsx)("span",{className:"urun-text-cursor"})]})}var ke=require("zod"),xe=require("react/jsx-runtime"),Dr=ke.z.object({src:ke.z.string().url(),alt:ke.z.string().optional(),caption:ke.z.string().optional()});function sr(e){let{src:r,alt:t,caption:n}=e;return{src:r,alt:t??"",caption:n}}function jr(e){let{src:r,alt:t,caption:n}=sr(e);return(0,xe.jsxs)("figure",{className:"urun-image-frame",children:[(0,xe.jsx)("img",{className:"urun-image",src:r,alt:t}),n&&(0,xe.jsx)("figcaption",{className:"urun-image-caption",children:n})]})}var K=require("zod"),me=require("react/jsx-runtime"),Fr=K.z.object({metrics:K.z.array(K.z.object({label:K.z.string(),value:K.z.union([K.z.string(),K.z.number()]),unit:K.z.string().optional()}))});function ar(e){return{metrics:e.metrics.map(t=>({...t,displayValue:t.unit?`${t.value} ${t.unit}`:String(t.value)}))}}function Br(e){let{metrics:r}=ar(e);return(0,me.jsx)("div",{className:"urun-metrics-panel",children:r.map((t,n)=>(0,me.jsxs)("div",{className:"urun-metric-card",children:[(0,me.jsx)("div",{className:"urun-metric-label",children:t.label}),(0,me.jsx)("div",{className:"urun-metric-value",children:t.displayValue})]},n))})}var O=require("react"),Jr=yt(require("video.js")),vn=require("video.js/dist/video-js.css");var fe=require("react");var Ce=require("react"),Rt=require("@urun-sh/core/internal");var Ut=require("react/jsx-runtime"),zr=(0,Ce.createContext)(null);function Hr(e){let r=(0,fe.useContext)(zr);if(!r)throw new Error("useTrack must be used within <SessionProvider> or <UrunProvider>");let[t,n]=(0,fe.useState)(null);return(0,fe.useEffect)(()=>{let o=r.getState()._transport;if(!o)return;let a=o.getTrackByName?.bind(o),i=a?.(e);i&&i.readyState!=="ended"&&n(i);let d=o.on("track",u=>{let c=a?.(e);c&&c.id!==u.id||(n(u),u.addEventListener("ended",()=>{n(null)}))});return()=>{d()}},[e,r]),t}var $=require("react/jsx-runtime");function $r(e){e.posterImage?.hide?.()}var Et=`
|
|
2
2
|
[data-urun-video]{width:100%;height:100%}
|
|
3
3
|
[data-urun-video] .video-js,[data-urun-video] .vjs-tech{width:100%;height:100%}
|
|
4
4
|
[data-urun-video] .vjs-tech{object-fit:contain}
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
.urun-video-live.vjs-has-started .vjs-loading-spinner,
|
|
7
7
|
.urun-video-live.vjs-has-started .vjs-big-play-button{display:none !important}
|
|
8
8
|
.urun-video-live .vjs-poster{background-color:transparent}
|
|
9
|
-
`,Rr="urun-video-critical-css";function Qr(){if(typeof document>"u"||document.getElementById(Rr))return;let r=document.createElement("style");r.id=Rr,r.textContent=Yr,document.head.appendChild(r)}var et=["playToggle","volumePanel","fullscreenToggle"],rt=["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","remainingTimeDisplay","fullscreenToggle"],Ur=(0,L.forwardRef)(function(e,t){let{track:o,stream:s,src:u,type:l="video/mp4",className:U,videoClassName:c,poster:v,controls:R=!0,autoPlay:p=!0,muted:h=!0,onVideoElement:E,onPlayerReady:k,children:C}=e,S=typeof u=="string"&&u.length>0,d=!S,m=(0,L.useRef)(null),f=(0,L.useRef)(null),[x,y]=(0,L.useState)(!1),H=(0,L.useCallback)(n=>{m.current=n,typeof t=="function"?t(n):t&&(t.current=n),E?.(n)},[t,E]);(0,L.useImperativeHandle)(t,()=>m.current,[]);let M=(0,L.useCallback)(()=>{let n=m.current;if(!n||!n.srcObject&&!n.src)return;h&&(n.muted=!0,n.defaultMuted=!0),n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline","");let i=n.play();i&&typeof i.then=="function"&&i.then(()=>y(!1)).catch(g=>{(g instanceof Error?g.name:String(g))!=="AbortError"&&y(!0)})},[h]);return(0,L.useEffect)(()=>{if(typeof document>"u")return;let n=m.current;if(!n)return;Qr(),h&&(n.muted=!0,n.defaultMuted=!0,n.setAttribute("muted","")),n.autoplay=p,n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline","");let i=(0,xr.default)(n,{controls:R,autoplay:p,muted:h,playsinline:!0,preload:"auto",fluid:!1,bigPlayButton:!0,poster:v,userActions:{click:!0,doubleClick:!1,hotkeys:!1},controlBar:{children:d?et:rt}});d&&i.addClass("urun-video-live");let g=()=>y(!1),b=()=>{i.hasStarted(!0),Tr(i),g()},a=()=>{d&&M()};return n.addEventListener("playing",b),n.addEventListener("loadedmetadata",a),d&&n.addEventListener("pause",a),f.current=i,k?.(i),()=>{n.removeEventListener("playing",b),n.removeEventListener("loadedmetadata",a),n.removeEventListener("pause",a),k?.(null),f.current&&(f.current.dispose(),f.current=null)}},[d]),(0,L.useEffect)(()=>{if(!S)return;let n=f.current;if(!n)return;let i=n.tech?.(!0)?.el?.();i&&(i.srcObject=null),n.src({src:u,type:l}),p&&M()},[S,u,l,p,M]),(0,L.useEffect)(()=>{if(!d)return;let n=f.current;if(!n)return;let i=o??null,g=s??null;!g&&i&&(g=new MediaStream([i]));let b=n.tech?.(!0)?.el?.()??m.current;if(!b)return;if(!g){b.srcObject=null,y(!1);return}b.srcObject=g,M();let a=g.getVideoTracks()[0]??i??null,w=()=>{n.hasStarted(!0),Tr(n),M()},T=()=>{b.srcObject=null,y(!1)};return a&&(a.addEventListener("unmute",w),a.addEventListener("ended",T),a.muted||w()),()=>{a&&(a.removeEventListener("unmute",w),a.removeEventListener("ended",T))}},[d,o,s,M]),(0,z.jsxs)("div",{className:U,style:{position:"relative",width:"100%",height:"100%"},"data-urun-video":"","data-urun-video-mode":d?"live":"vod",children:[(0,z.jsx)("video",{ref:H,className:["video-js","vjs-default-skin",c].filter(Boolean).join(" "),playsInline:!0}),x&&(0,z.jsx)("button",{type:"button",onClick:M,"aria-label":"Tap to play",style:{position:"absolute",inset:0,zIndex:30,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.6)",border:0,cursor:"pointer",color:"#fff"},children:(0,z.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:8,borderRadius:999,border:"1px solid rgba(255,255,255,0.2)",background:"rgba(255,255,255,0.1)",padding:"10px 20px",fontSize:14,fontWeight:500},children:[(0,z.jsx)("svg",{viewBox:"0 0 24 24",fill:"currentColor",width:16,height:16,"aria-hidden":!0,children:(0,z.jsx)("path",{d:"M8 5v14l11-7z"})}),"Tap to play"]})}),C]})}),tt=(0,L.forwardRef)(function({name:e,...t},o){let s=Cr(e);return(0,z.jsx)(Ur,{ref:o,...t,track:s})}),Pr=(0,L.forwardRef)(function(e,t){return!!e.name&&!e.track&&!e.stream&&!(typeof e.src=="string"&&e.src)?(0,z.jsx)(tt,{ref:t,...e,name:e.name}):(0,z.jsx)(Ur,{ref:t,...e})});var A=require("react");var Ce=null;function nt(){if(typeof window>"u")return null;let r=window;return r.AudioContext??r.webkitAudioContext??null}function ge(){if(Ce)return Ce;let r=nt();return r?(Ce=new r,Ce):null}function Te(){let r=ge();r&&r.state==="suspended"&&r.resume().catch(()=>{})}var wr=require("react/jsx-runtime"),ot=1e3,Er=200;function De(...r){console.debug("[urun-audio]",...r)}var Re=(0,A.forwardRef)(function(e,t){let{session:o,stream:s="audio",track:u,controls:l=!1,className:U,onTrack:c,onUnlockChange:v,onAudioElement:R}=e,p=(0,A.useRef)(null),h=(0,A.useRef)(null),E=(0,A.useRef)(null),k=(0,A.useRef)(null),C=(0,A.useRef)(c);C.current=c;let S=(0,A.useRef)(v);S.current=v;let d=(0,A.useCallback)(n=>{E.current!==n&&(E.current=n,S.current?.(n))},[]),m=(0,A.useCallback)(()=>{if(typeof MediaStream>"u")return null;h.current||(h.current=new MediaStream);let n=p.current;return n&&n.srcObject!==h.current&&(n.srcObject=h.current),h.current},[]),f=(0,A.useCallback)(n=>{let i=p.current;if(!i)return;let g=i.play();!g||typeof g.then!="function"||g.then(()=>{i.muted||d(!0)}).catch(b=>{let a=b instanceof Error?b.name:String(b);if(a==="AbortError"){De(`play() aborted (${n}); retrying in ${Er}ms`),k.current&&clearTimeout(k.current),k.current=setTimeout(()=>{k.current=null,f(`${n}:retry`)},Er);return}if(a==="NotAllowedError"){De(`play() blocked pending a user gesture (${n})`),d(!1);return}De(`play() failed (${n})`,b)})},[d]),x=(0,A.useCallback)(n=>{let i=m();if(i){for(let g of i.getAudioTracks())g!==n&&i.removeTrack(g);n&&!i.getAudioTracks().includes(n)&&i.addTrack(n),n&&f("track-attach"),C.current?.(n)}},[m,f]),y=(0,A.useCallback)(()=>{let n=p.current;n&&(m(),n.muted=!1,f("gesture"),Te(),d(!0))},[m,f,d]);(0,A.useImperativeHandle)(t,()=>({unlock:y,get unlocked(){return E.current===!0},get element(){return p.current}}),[y]);let H=(0,A.useCallback)(n=>{p.current=n,n&&(n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline",""),m()),R?.(n)},[m,R]),M=u!==void 0;return(0,A.useEffect)(()=>{if(M){x(u??null);return}if(!o)return;let n=o.stream(s),i=()=>{let T=h.current;return T?T.getAudioTracks()[0]??null:null},g=T=>{if(T!==i()&&(x(T),T)){let $=()=>{i()===T&&x(null)};T.addEventListener("ended",$)}},b=n.track;b&&b.readyState==="live"&&g(b);let a=n.on("track",T=>{T&&T.readyState!=="live"||g(T)}),w=setInterval(()=>{let T=n.track;T&&T.readyState==="live"&&g(T)},ot);return()=>{a(),clearInterval(w)}},[o,s,M,u,x]),(0,A.useEffect)(()=>()=>{k.current&&clearTimeout(k.current)},[]),(0,wr.jsx)("audio",{ref:H,className:U,autoPlay:!0,playsInline:!0,controls:l,"data-urun-audio":""})});var O=require("react");var _r=require("react/jsx-runtime"),He={channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};function st(...r){console.debug("[urun-voice]",...r)}var Ar=(0,O.forwardRef)(function(e,t){let{session:o,stream:s="audio",constraints:u=He,connectTimeoutMs:l,attempts:U=3,retryDelayMs:c=1500,onActiveChange:v,onError:R,onMicStream:p,onTrack:h,onUnlockChange:E}=e,k=(0,O.useRef)(null),C=(0,O.useRef)(null),S=(0,O.useRef)(!1),d=(0,O.useRef)(v);d.current=v;let m=(0,O.useRef)(R);m.current=R;let f=(0,O.useRef)(p);f.current=p;let x=(0,O.useCallback)(n=>{S.current!==n&&(S.current=n,d.current?.(n))},[]),y=(0,O.useCallback)(()=>{let n=C.current;if(n){for(let i of n.getTracks())i.stop();C.current=null,f.current?.(null)}},[]),H=(0,O.useCallback)(async()=>{y(),x(!1),await o.stream(s).detach().catch(()=>{})},[o,s,y,x]),M=(0,O.useCallback)(async()=>{k.current?.unlock();let n=await navigator.mediaDevices.getUserMedia({audio:u,video:!1});y(),C.current=n,f.current?.(n);let i=n.getAudioTracks()[0];if(!i){y();let a=new Error("no microphone audio track");throw m.current?.(a),a}o.connect?.();let g;for(let a=1;a<=U;a++)try{await o.whenLive(l!==void 0?{timeout:l}:void 0),await o.stream(s).attach(i),x(!0);return}catch(w){g=w,st(`start attempt ${a}/${U} failed`,w),a<U&&await new Promise(T=>setTimeout(T,c))}y(),x(!1);let b=g instanceof Error?g:new Error(String(g??"voice start failed"));throw m.current?.(b),b},[o,s,u,l,U,c,y,x]);return(0,O.useImperativeHandle)(t,()=>({start:M,stop:H,unlock:()=>k.current?.unlock(),get active(){return S.current},get micStream(){return C.current},get audio(){return k.current}}),[M,H]),(0,O.useEffect)(()=>y,[y]),(0,_r.jsx)(Re,{ref:k,session:o,stream:s,onTrack:h,onUnlockChange:E})});var P=require("react"),xe=require("react/jsx-runtime"),Fe={width:{ideal:960},height:{ideal:720},frameRate:{ideal:8}};function Mr(...r){console.debug("[urun-camera]",...r)}var Nr=(0,P.forwardRef)(function(e,t){let{session:o,stream:s="video",constraints:u,facingMode:l="environment",mirror:U="auto",connectTimeoutMs:c,preview:v=!0,className:R,videoClassName:p,onActiveChange:h,onError:E,onStream:k,onTrack:C,children:S}=e,d=(0,P.useRef)(null),m=(0,P.useRef)(null),f=(0,P.useRef)(null),x=(0,P.useRef)(!1),y=(0,P.useRef)(l),[H,M]=(0,P.useState)(l),n=(0,P.useRef)(h);n.current=h;let i=(0,P.useRef)(E);i.current=E;let g=(0,P.useRef)(k);g.current=k;let b=(0,P.useRef)(C);b.current=C;let a=(0,P.useCallback)(_=>{x.current!==_&&(x.current=_,n.current?.(_))},[]),w=(0,P.useCallback)(_=>{let B=d.current;B&&(B.muted=!0,B.srcObject=_,_&&B.play()?.catch?.(K=>Mr("preview play() failed",K)))},[]),T=(0,P.useCallback)(()=>{f.current?.(),f.current=null;let _=m.current;if(_){for(let B of _.getTracks())B.stop();m.current=null,g.current?.(null),b.current?.(null)}w(null)},[w]),$=(0,P.useCallback)(async _=>{let B=m.current,K=f.current,D;try{D=await navigator.mediaDevices.getUserMedia({video:{...Fe,...u,facingMode:_},audio:!1})}catch(V){let Z=V instanceof Error?V:new Error(String(V));throw i.current?.(Z),Z}let N=D.getVideoTracks()[0];if(!N){for(let Z of D.getTracks())Z.stop();let V=new Error("no camera video track");throw i.current?.(V),V}m.current=D,y.current=_,M(_),w(D),g.current?.(D);let F=()=>{m.current===D&&(Mr("camera track ended (device removed or permission revoked)"),T(),a(!1))};N.addEventListener("ended",F),f.current=()=>N.removeEventListener("ended",F);try{o.connect?.(),await o.whenLive(c!==void 0?{timeout:c}:void 0),await o.stream(s).attachVideo(N)}catch(V){N.removeEventListener("ended",F);for(let Or of D.getTracks())Or.stop();m.current===D&&(m.current=B,f.current=K,w(B),g.current?.(B));let Z=V instanceof Error?V:new Error(String(V));throw i.current?.(Z),Z}if(B&&B!==D){K?.();for(let V of B.getTracks())V.stop()}b.current?.(N),a(!0)},[o,s,u,c,w,T,a]),Pe=(0,P.useCallback)(_=>$(_?.facingMode??y.current),[$]),Ee=(0,P.useCallback)(async _=>{x.current&&y.current===_||await $(_)},[$]),we=(0,P.useCallback)(()=>$(y.current==="environment"?"user":"environment"),[$]),Ae=(0,P.useCallback)(async()=>{T(),a(!1),await o.stream(s).detachVideo().catch(()=>{})},[o,s,T,a]);return(0,P.useImperativeHandle)(t,()=>({start:Pe,stop:Ae,flip:we,setFacingMode:Ee,get active(){return x.current},get facingMode(){return y.current},get stream(){return m.current},get element(){return d.current}}),[Pe,Ae,we,Ee]),(0,P.useEffect)(()=>T,[T]),v?(0,xe.jsxs)("div",{className:R,style:{position:"relative",width:"100%",height:"100%"},"data-urun-camera":"","data-urun-camera-facing":H,children:[(0,xe.jsx)("video",{ref:d,className:p,autoPlay:!0,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"contain",...(U==="auto"?H==="user":U)?{transform:"scaleX(-1)"}:{}}}),S]}):null});var Ue=require("react");var ze={level:0,speaking:!1};function Ir(r,e={}){let{fftSize:t=512,intervalMs:o=100,speakingThreshold:s=.02}=e,[u,l]=(0,Ue.useState)(ze);return(0,Ue.useEffect)(()=>{if(!r){l(ze);return}let U=ge();if(!U||typeof MediaStream>"u")return;let c;r instanceof MediaStream?c=r:(c=new MediaStream,c.addTrack(r));let v,R;try{v=U.createMediaStreamSource(c),R=U.createAnalyser(),R.fftSize=t,v.connect(R)}catch{return}let p=new Uint8Array(R.fftSize),E=setInterval(()=>{R.getByteTimeDomainData(p);let k=0;for(let S=0;S<p.length;S++){let d=(p[S]-128)/128;k+=d*d}let C=Math.sqrt(k/p.length);l(S=>{let d=C>s;return Math.abs(S.level-C)<.005&&S.speaking===d?S:{level:C,speaking:d}})},o);return()=>{clearInterval(E),v.disconnect(),l(ze)}},[r,t,o,s]),u}0&&(module.exports={ComponentRenderer,DEFAULT_CAMERA_CONSTRAINTS,DEFAULT_VOICE_CONSTRAINTS,ImageFrame,ImageFrameSchema,MetricsPanel,MetricsPanelSchema,ProgressCard,ProgressCardSchema,StatusBadge,StatusBadgeSchema,TextStream,TextStreamSchema,UrunAudio,UrunAuthProvider,UrunCamera,UrunErrorBoundary,UrunJwtProvider,UrunProvider,UrunVideo,UrunVoice,authMode,getUrunAudioContext,registerComponent,resumeUrunAudioContext,urunPublicEnv,useApp,useChat,useCompletion,useImageFrame,useMetricsPanel,useProgressCard,useRequest,useStatusBadge,useTextStream,useUrunAudioLevel,useUrunAuth,usesWorkOSAuth});
|
|
9
|
+
`,Wr="urun-video-critical-css";function wt(){if(typeof document>"u"||document.getElementById(Wr))return;let e=document.createElement("style");e.id=Wr,e.textContent=Et,document.head.appendChild(e)}var At=["playToggle","volumePanel","fullscreenToggle"],Mt=["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","remainingTimeDisplay","fullscreenToggle"],Xr=(0,O.forwardRef)(function(r,t){let{track:n,stream:o,src:a,type:i="video/mp4",className:d,videoClassName:u,poster:c,controls:h=!0,autoPlay:l=!0,muted:f=!0,onVideoElement:R,onPlayerReady:x,children:T}=r,b=typeof a=="string"&&a.length>0,g=!b,v=(0,O.useRef)(null),S=(0,O.useRef)(null),[U,k]=(0,O.useState)(!1),z=(0,O.useCallback)(s=>{v.current=s,typeof t=="function"?t(s):t&&(t.current=s),R?.(s)},[t,R]);(0,O.useImperativeHandle)(t,()=>v.current,[]);let N=(0,O.useCallback)(()=>{let s=v.current;if(!s||!s.srcObject&&!s.src)return;f&&(s.muted=!0,s.defaultMuted=!0),s.setAttribute("playsinline",""),s.setAttribute("webkit-playsinline","");let p=s.play();p&&typeof p.then=="function"&&p.then(()=>k(!1)).catch(y=>{(y instanceof Error?y.name:String(y))!=="AbortError"&&k(!0)})},[f]);return(0,O.useEffect)(()=>{if(typeof document>"u")return;let s=v.current;if(!s)return;wt(),f&&(s.muted=!0,s.defaultMuted=!0,s.setAttribute("muted","")),s.autoplay=l,s.setAttribute("playsinline",""),s.setAttribute("webkit-playsinline","");let p=(0,Jr.default)(s,{controls:h,autoplay:l,muted:f,playsinline:!0,preload:"auto",fluid:!1,bigPlayButton:!0,poster:c,userActions:{click:!0,doubleClick:!1,hotkeys:!1},controlBar:{children:g?At:Mt}});g&&p.addClass("urun-video-live");let y=()=>k(!1),C=()=>{p.hasStarted(!0),$r(p),y()},m=()=>{g&&N()};return s.addEventListener("playing",C),s.addEventListener("loadedmetadata",m),g&&s.addEventListener("pause",m),S.current=p,x?.(p),()=>{s.removeEventListener("playing",C),s.removeEventListener("loadedmetadata",m),s.removeEventListener("pause",m),x?.(null),S.current&&(S.current.dispose(),S.current=null)}},[g]),(0,O.useEffect)(()=>{if(!b)return;let s=S.current;if(!s)return;let p=s.tech?.(!0)?.el?.();p&&(p.srcObject=null),s.src({src:a,type:i}),l&&N()},[b,a,i,l,N]),(0,O.useEffect)(()=>{if(!g)return;let s=S.current;if(!s)return;let p=n??null,y=o??null;!y&&p&&(y=new MediaStream([p]));let C=s.tech?.(!0)?.el?.()??v.current;if(!C)return;if(!y){C.srcObject=null,k(!1);return}C.srcObject=y,N();let m=y.getVideoTracks()[0]??p??null,w=()=>{s.hasStarted(!0),$r(s),N()},P=()=>{C.srcObject=null,k(!1)};return m&&(m.addEventListener("unmute",w),m.addEventListener("ended",P),m.muted||w()),()=>{m&&(m.removeEventListener("unmute",w),m.removeEventListener("ended",P))}},[g,n,o,N]),(0,$.jsxs)("div",{className:d,style:{position:"relative",width:"100%",height:"100%"},"data-urun-video":"","data-urun-video-mode":g?"live":"vod",children:[(0,$.jsx)("video",{ref:z,className:["video-js","vjs-default-skin",u].filter(Boolean).join(" "),playsInline:!0}),U&&(0,$.jsx)("button",{type:"button",onClick:N,"aria-label":"Tap to play",style:{position:"absolute",inset:0,zIndex:30,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.6)",border:0,cursor:"pointer",color:"#fff"},children:(0,$.jsxs)("span",{style:{display:"inline-flex",alignItems:"center",gap:8,borderRadius:999,border:"1px solid rgba(255,255,255,0.2)",background:"rgba(255,255,255,0.1)",padding:"10px 20px",fontSize:14,fontWeight:500},children:[(0,$.jsx)("svg",{viewBox:"0 0 24 24",fill:"currentColor",width:16,height:16,"aria-hidden":!0,children:(0,$.jsx)("path",{d:"M8 5v14l11-7z"})}),"Tap to play"]})}),T]})}),Nt=(0,O.forwardRef)(function({name:r,...t},n){let o=Hr(r);return(0,$.jsx)(Xr,{ref:n,...t,track:o})}),Gr=(0,O.forwardRef)(function(r,t){return!!r.name&&!r.track&&!r.stream&&!(typeof r.src=="string"&&r.src)?(0,$.jsx)(Nt,{ref:t,...r,name:r.name}):(0,$.jsx)(Xr,{ref:t,...r})});var A=require("react");var _e=null;function _t(){if(typeof window>"u")return null;let e=window;return e.AudioContext??e.webkitAudioContext??null}function Te(){if(_e)return _e;let e=_t();return e?(_e=new e,_e):null}function Le(){let e=Te();e&&e.state==="suspended"&&e.resume().catch(()=>{})}var Zr=require("react/jsx-runtime"),Lt=1e3,Kr=200;function ir(...e){console.debug("[urun-audio]",...e)}var Oe=(0,A.forwardRef)(function(r,t){let{session:n,stream:o="audio",track:a,controls:i=!1,className:d,onTrack:u,onUnlockChange:c,onAudioElement:h}=r,l=(0,A.useRef)(null),f=(0,A.useRef)(null),R=(0,A.useRef)(null),x=(0,A.useRef)(null),T=(0,A.useRef)(u);T.current=u;let b=(0,A.useRef)(c);b.current=c;let g=(0,A.useCallback)(s=>{R.current!==s&&(R.current=s,b.current?.(s))},[]),v=(0,A.useCallback)(()=>{if(typeof MediaStream>"u")return null;f.current||(f.current=new MediaStream);let s=l.current;return s&&s.srcObject!==f.current&&(s.srcObject=f.current),f.current},[]),S=(0,A.useCallback)(s=>{let p=l.current;if(!p)return;let y=p.play();!y||typeof y.then!="function"||y.then(()=>{p.muted||g(!0)}).catch(C=>{let m=C instanceof Error?C.name:String(C);if(m==="AbortError"){ir(`play() aborted (${s}); retrying in ${Kr}ms`),x.current&&clearTimeout(x.current),x.current=setTimeout(()=>{x.current=null,S(`${s}:retry`)},Kr);return}if(m==="NotAllowedError"){ir(`play() blocked pending a user gesture (${s})`),g(!1);return}ir(`play() failed (${s})`,C)})},[g]),U=(0,A.useCallback)(s=>{let p=v();if(p){for(let y of p.getAudioTracks())y!==s&&p.removeTrack(y);s&&!p.getAudioTracks().includes(s)&&p.addTrack(s),s&&S("track-attach"),T.current?.(s)}},[v,S]),k=(0,A.useCallback)(()=>{let s=l.current;s&&(v(),s.muted=!1,S("gesture"),Le(),g(!0))},[v,S,g]);(0,A.useImperativeHandle)(t,()=>({unlock:k,get unlocked(){return R.current===!0},get element(){return l.current}}),[k]);let z=(0,A.useCallback)(s=>{l.current=s,s&&(s.setAttribute("playsinline",""),s.setAttribute("webkit-playsinline",""),v()),h?.(s)},[v,h]),N=a!==void 0;return(0,A.useEffect)(()=>{if(N){U(a??null);return}if(!n)return;let s=n.stream(o),p=()=>{let P=f.current;return P?P.getAudioTracks()[0]??null:null},y=P=>{if(P!==p()&&(U(P),P)){let J=()=>{p()===P&&U(null)};P.addEventListener("ended",J)}},C=s.track;C&&C.readyState==="live"&&y(C);let m=s.on("track",P=>{P&&P.readyState!=="live"||y(P)}),w=setInterval(()=>{let P=s.track;P&&P.readyState==="live"&&y(P)},Lt);return()=>{m(),clearInterval(w)}},[n,o,N,a,U]),(0,A.useEffect)(()=>()=>{x.current&&clearTimeout(x.current)},[]),(0,Zr.jsx)("audio",{ref:z,className:d,autoPlay:!0,playsInline:!0,controls:i,"data-urun-audio":""})});var I=require("react"),ur=require("@urun-sh/core");var Qr=require("react/jsx-runtime"),cr={channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};function Ot(...e){console.debug("[urun-voice]",...e)}var Yr=(0,I.forwardRef)(function(r,t){let{session:n,stream:o="audio",constraints:a=cr,connectTimeoutMs:i,attempts:d=3,retryDelayMs:u=1500,onActiveChange:c,onError:h,onMicStream:l,onTrack:f,onUnlockChange:R}=r,x=(0,I.useRef)(null),T=(0,I.useRef)(null),b=(0,I.useRef)(!1),g=(0,I.useRef)(c);g.current=c;let v=(0,I.useRef)(h);v.current=h;let S=(0,I.useRef)(l);S.current=l;let U=(0,I.useCallback)(s=>{b.current!==s&&(b.current=s,g.current?.(s))},[]),k=(0,I.useCallback)(()=>{let s=T.current;if(s){for(let p of s.getTracks())p.stop();T.current=null,S.current?.(null)}},[]),z=(0,I.useCallback)(async()=>{k(),U(!1),await n.stream(o).detach().catch(()=>{})},[n,o,k,U]),N=(0,I.useCallback)(async()=>{x.current?.unlock();let s;try{s=await navigator.mediaDevices.getUserMedia({audio:a,video:!1})}catch(m){let w=(0,ur.sessionFailureFromMediaError)(m,n.status);throw v.current?.(w),w}k(),T.current=s,S.current?.(s);let p=s.getAudioTracks()[0];if(!p){k();let m=(0,ur.sessionFailureFromMediaError)(Object.assign(new Error("no microphone audio track"),{name:"NotFoundError"}),n.status);throw v.current?.(m),m}n.connect?.();let y;for(let m=1;m<=d;m++)try{await n.whenLive(i!==void 0?{timeout:i}:void 0),await n.stream(o).attach(p),U(!0);return}catch(w){y=w,Ot(`start attempt ${m}/${d} failed`,w),m<d&&await new Promise(P=>setTimeout(P,u))}k(),U(!1);let C=y instanceof Error?y:new Error(String(y??"voice start failed"));throw v.current?.(C),C},[n,o,a,i,d,u,k,U]);return(0,I.useImperativeHandle)(t,()=>({start:N,stop:z,unlock:()=>x.current?.unlock(),get active(){return b.current},get micStream(){return T.current},get audio(){return x.current}}),[N,z]),(0,I.useEffect)(()=>k,[k]),(0,Qr.jsx)(Oe,{ref:x,session:n,stream:o,onTrack:f,onUnlockChange:R})});var lr=require("@urun-sh/core"),E=require("react"),Ie=require("react/jsx-runtime"),dr={width:{ideal:960},height:{ideal:720},frameRate:{ideal:8}};function et(...e){console.debug("[urun-camera]",...e)}var rt=(0,E.forwardRef)(function(r,t){let{session:n,stream:o="video",constraints:a,facingMode:i="environment",mirror:d="auto",connectTimeoutMs:u,preview:c=!0,className:h,videoClassName:l,onActiveChange:f,onError:R,onStream:x,onTrack:T,children:b}=r,g=(0,E.useRef)(null),v=(0,E.useRef)(null),S=(0,E.useRef)(null),U=(0,E.useRef)(!1),k=(0,E.useRef)(i),[z,N]=(0,E.useState)(i),s=(0,E.useRef)(f);s.current=f;let p=(0,E.useRef)(R);p.current=R;let y=(0,E.useRef)(x);y.current=x;let C=(0,E.useRef)(T);C.current=T;let m=(0,E.useCallback)(M=>{U.current!==M&&(U.current=M,s.current?.(M))},[]),w=(0,E.useCallback)(M=>{let D=g.current;D&&(D.muted=!0,D.srcObject=M,M&&D.play()?.catch?.(ee=>et("preview play() failed",ee)))},[]),P=(0,E.useCallback)(()=>{S.current?.(),S.current=null;let M=v.current;if(M){for(let D of M.getTracks())D.stop();v.current=null,y.current?.(null),C.current?.(null)}w(null)},[w]),J=(0,E.useCallback)(async M=>{let D=v.current,ee=S.current,j;try{j=await navigator.mediaDevices.getUserMedia({video:{...dr,...a,facingMode:M},audio:!1})}catch(F){let te=(0,lr.sessionFailureFromMediaError)(F,n.status);throw p.current?.(te),te}let _=j.getVideoTracks()[0];if(!_){for(let te of j.getTracks())te.stop();let F=(0,lr.sessionFailureFromMediaError)(Object.assign(new Error("no camera video track"),{name:"NotFoundError"}),n.status);throw p.current?.(F),F}v.current=j,k.current=M,N(M),w(j),y.current?.(j);let H=()=>{v.current===j&&(et("camera track ended (device removed or permission revoked)"),P(),m(!1))};_.addEventListener("ended",H),S.current=()=>_.removeEventListener("ended",H);try{n.connect?.(),await n.whenLive(u!==void 0?{timeout:u}:void 0),await n.stream(o).attachVideo(_)}catch(F){_.removeEventListener("ended",H);for(let pt of j.getTracks())pt.stop();v.current===j&&(v.current=D,S.current=ee,w(D),y.current?.(D));let te=F instanceof Error?F:new Error(String(F));throw p.current?.(te),te}if(D&&D!==j){ee?.();for(let F of D.getTracks())F.stop()}C.current?.(_),m(!0)},[n,o,a,u,w,P,m]),Je=(0,E.useCallback)(M=>J(M?.facingMode??k.current),[J]),Xe=(0,E.useCallback)(async M=>{U.current&&k.current===M||await J(M)},[J]),Ge=(0,E.useCallback)(()=>J(k.current==="environment"?"user":"environment"),[J]),Ke=(0,E.useCallback)(async()=>{P(),m(!1),await n.stream(o).detachVideo().catch(()=>{})},[n,o,P,m]);return(0,E.useImperativeHandle)(t,()=>({start:Je,stop:Ke,flip:Ge,setFacingMode:Xe,get active(){return U.current},get facingMode(){return k.current},get stream(){return v.current},get element(){return g.current}}),[Je,Ke,Ge,Xe]),(0,E.useEffect)(()=>P,[P]),c?(0,Ie.jsxs)("div",{className:h,style:{position:"relative",width:"100%",height:"100%"},"data-urun-camera":"","data-urun-camera-facing":z,children:[(0,Ie.jsx)("video",{ref:g,className:l,autoPlay:!0,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"contain",...(d==="auto"?z==="user":d)?{transform:"scaleX(-1)"}:{}}}),b]}):null});var qe=require("react");var pr={level:0,speaking:!1};function tt(e,r={}){let{fftSize:t=512,intervalMs:n=100,speakingThreshold:o=.02}=r,[a,i]=(0,qe.useState)(pr);return(0,qe.useEffect)(()=>{if(!e){i(pr);return}let d=Te();if(!d||typeof MediaStream>"u")return;let u;e instanceof MediaStream?u=e:(u=new MediaStream,u.addTrack(e));let c,h;try{c=d.createMediaStreamSource(u),h=d.createAnalyser(),h.fftSize=t,c.connect(h)}catch{return}let l=new Uint8Array(h.fftSize),R=setInterval(()=>{h.getByteTimeDomainData(l);let x=0;for(let b=0;b<l.length;b++){let g=(l[b]-128)/128;x+=g*g}let T=Math.sqrt(x/l.length);i(b=>{let g=T>o;return Math.abs(b.level-T)<.005&&b.speaking===g?b:{level:T,speaking:g}})},n);return()=>{clearInterval(R),c.disconnect(),i(pr)}},[e,t,n,o]),a}var Ve=require("react");function nt(e,r){let[t,n]=(0,Ve.useState)(null);return(0,Ve.useEffect)(()=>{if(!e||!r){n(null);return}let o=e.stream(r);return n(o.track),o.on("track",n)},[e,r]),t}var ae=require("react");function De(e,r){let[t,n]=(0,ae.useState)(null),[o,a]=(0,ae.useState)(!1);(0,ae.useEffect)(()=>{if(!e||!r){n(null),a(!1);return}let d=e.doc(r);n(d.get()??{}),a(d.synced);let u=d.on("change",h=>n(h)),c=d.onSynced(()=>a(!0));return()=>{u(),c()}},[e,r]);let i=(0,ae.useCallback)(d=>{e&&r&&e.doc(r).set(d)},[e,r]);return{snapshot:t,synced:o,set:i}}var Fe=require("react");var re=200;function Z(e,r,t=200){let n=[...e,r];return n.length>t?n.slice(n.length-t):n}function ge(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}function je(e){let r=e.trim();if(!r)return{ok:!1,error:"Enter a JSON object."};let t;try{t=JSON.parse(r)}catch(n){return{ok:!1,error:n instanceof Error?n.message:"Invalid JSON."}}return t===null||typeof t!="object"||Array.isArray(t)?{ok:!1,error:"The payload must be a JSON object."}:{ok:!0,value:t}}function Be(e,r,t={}){let n=t.cap??200,[o,a]=(0,Fe.useState)([]);return(0,Fe.useEffect)(()=>{if(a([]),!e||!r)return;let i=!0,d=e.stream(r).messages()[Symbol.asyncIterator]();return(async()=>{for(;;){let u=await d.next();if(!i||u.done)break;a(c=>Z(c,{at:Date.now(),payload:u.value},n))}})(),()=>{i=!1,d.return?.()}},[e,r,n]),o}var W=require("react/jsx-runtime");function ot({session:e,name:r,cap:t,className:n}){let o=Be(e,r,{cap:t});return(0,W.jsxs)("div",{className:["urun-stream-tail",n].filter(Boolean).join(" "),children:[(0,W.jsxs)("div",{className:"urun-stream-tail-meta",children:[(0,W.jsx)("code",{children:r}),(0,W.jsxs)("span",{className:"urun-stream-tail-count",children:[o.length," messages"]})]}),(0,W.jsx)("div",{className:"urun-stream-tail-log",children:o.length===0?(0,W.jsxs)("span",{className:"urun-stream-tail-empty",children:["Waiting for ",(0,W.jsx)("code",{children:r})," messages\u2026"]}):o.map((a,i)=>(0,W.jsxs)("div",{className:"urun-stream-tail-line",children:[(0,W.jsx)("span",{className:"urun-stream-tail-time",children:new Date(a.at).toLocaleTimeString()})," ",ge(a.payload)]},`${a.at}-${i}`))})]})}var Pe=require("react");var B=require("react/jsx-runtime");function Re({placeholder:e,buttonLabel:r,disabled:t,onApply:n}){let[o,a]=(0,Pe.useState)(""),[i,d]=(0,Pe.useState)(null),u=(0,Pe.useCallback)(()=>{let c=je(o);if(!c.ok){d(c.error);return}d(null),n(c.value,o.trim()),a("")},[o,n]);return(0,B.jsxs)("div",{className:"urun-doc-patch",children:[(0,B.jsx)("textarea",{className:"urun-doc-patch-input",value:o,onChange:c=>a(c.target.value),placeholder:e,rows:3}),(0,B.jsxs)("div",{className:"urun-doc-patch-actions",children:[(0,B.jsx)("button",{type:"button",className:"urun-doc-patch-button",disabled:t||!o.trim(),onClick:u,children:r}),i?(0,B.jsx)("span",{className:"urun-doc-patch-error",role:"alert",children:i}):null]})]})}function st({session:e,docKey:r,editable:t=!0,patchPlaceholder:n='{"desired": {"prompt": {"text": "a sunset"}}}',className:o}){let{snapshot:a,synced:i,set:d}=De(e,r);return(0,B.jsxs)("div",{className:["urun-doc-panel",o].filter(Boolean).join(" "),children:[(0,B.jsxs)("div",{className:"urun-doc-panel-meta",children:[(0,B.jsx)("code",{children:r}),(0,B.jsx)("span",{className:"urun-doc-panel-synced","data-synced":i?"true":"false",children:i?"synced":"syncing\u2026"})]}),(0,B.jsx)("pre",{className:"urun-doc-panel-snapshot",children:JSON.stringify(a??{},null,2)}),t?(0,B.jsx)(Re,{placeholder:n,buttonLabel:"Apply patch",disabled:!e,onApply:u=>d(u)}):null]})}var ze=require("react");var Y=require("react/jsx-runtime");function at(e,r=600){return e.length>r?`${e.slice(0,r)}\u2026`:e}function it({session:e,docKey:r="control",cap:t=200,className:n}){let[o,a]=(0,ze.useState)([]);return(0,ze.useEffect)(()=>(a([]),e?e.doc(r).on("change",d=>{a(u=>Z(u,{at:Date.now(),direction:"in",text:at(ge(d))},t))}):void 0),[e,r,t]),(0,Y.jsxs)("div",{className:["urun-control-sender",n].filter(Boolean).join(" "),children:[(0,Y.jsx)(Re,{placeholder:'{"desired": {"settings": {"values": {}}}}',buttonLabel:`Send to ${r}`,disabled:!e,onApply:(i,d)=>{e?.doc(r).set(i),a(u=>Z(u,{at:Date.now(),direction:"out",text:at(d)},t))}}),(0,Y.jsx)("div",{className:"urun-control-sender-log",children:o.length===0?(0,Y.jsx)("span",{className:"urun-control-sender-empty",children:"Nothing yet."}):[...o].reverse().map((i,d)=>(0,Y.jsxs)("div",{className:"urun-control-sender-line","data-direction":i.direction,children:[(0,Y.jsx)("span",{className:"urun-control-sender-dir",children:i.direction==="out"?"sent":"change"})," ",(0,Y.jsx)("span",{className:"urun-control-sender-time",children:new Date(i.at).toLocaleTimeString()})," ",i.text]},`${i.at}-${d}`))})]})}var He=require("react");var ie=require("react/jsx-runtime");function ut({session:e,trackNames:r=["video","audio"],docKeys:t=["control"],cap:n=200,className:o}){let[a,i]=(0,He.useState)([]),d=r.join(","),u=t.join(",");return(0,He.useEffect)(()=>{if(i([]),!e)return;let c=(l,f)=>i(R=>Z(R,{at:Date.now(),kind:l,text:f},n)),h=[];h.push(e.onPhase(l=>c("phase",`phase \u2192 ${l.name}`)));for(let l of r){let f=e.stream(l);h.push(f.on("track",R=>c("track",`${l}: ${R?"track arrived":"track ended"}`)))}for(let l of t){let f=e.doc(l);h.push(f.on("change",()=>c("doc",`${l} changed`)))}return()=>h.forEach(l=>l())},[e,d,u,n]),(0,ie.jsx)("div",{className:["urun-event-spine",o].filter(Boolean).join(" "),children:a.length===0?(0,ie.jsx)("span",{className:"urun-event-spine-empty",children:"No activity yet \u2014 the spine fills as the session moves through its lifecycle."}):[...a].reverse().map((c,h)=>(0,ie.jsxs)("div",{className:"urun-event-spine-line","data-kind":c.kind,children:[(0,ie.jsx)("span",{className:"urun-event-spine-kind",children:c.kind})," ",(0,ie.jsx)("span",{className:"urun-event-spine-time",children:new Date(c.at).toLocaleTimeString()})," ",c.text]},`${c.at}-${h}`))})}var $e=require("react"),Q=require("react/jsx-runtime"),It={idle:"idle",queued:"queued",provisioning:"provisioning",connecting:"connecting",live:"live",error:"error",ended:"ended"};function We(e){let[r,t]=(0,$e.useState)(e?.phase??null);return(0,$e.useEffect)(()=>{if(!e){t(null);return}return e.onPhase(t)},[e]),r}function ct({session:e,className:r}){let t=We(e),n=t?.name??"idle",o=t?.name==="queued"&&t.queue?`pos ${t.queue.position} / depth ${t.queue.depth}`:t?.name==="error"&&t.error?t.error.reason:null;return(0,Q.jsxs)("span",{className:["urun-session-status",r].filter(Boolean).join(" "),"data-phase":n,children:[(0,Q.jsx)("span",{className:"urun-session-status-dot","data-phase":n}),(0,Q.jsx)("span",{className:"urun-session-status-label",children:It[n]}),o?(0,Q.jsx)("span",{className:"urun-session-status-detail",children:o}):null]})}function lt({session:e,children:r,fallback:t,className:n}){let o=We(e);if(o?.name==="live")return(0,Q.jsx)("div",{className:["urun-session-gate",n].filter(Boolean).join(" "),children:r});let a=t?t(o):(0,Q.jsx)("span",{className:"urun-session-gate-fallback",children:o?.name==="error"?`Session ${o.error?.reason??"failed"}.`:o?.name==="ended"?"Session ended.":"Waiting for a live session\u2026"});return(0,Q.jsx)("div",{className:["urun-session-gate",n].filter(Boolean).join(" "),children:a})}0&&(module.exports={ComponentRenderer,DEFAULT_CAMERA_CONSTRAINTS,DEFAULT_LOG_CAP,DEFAULT_VOICE_CONSTRAINTS,DocPatchForm,ImageFrame,ImageFrameSchema,MetricsPanel,MetricsPanelSchema,ProgressCard,ProgressCardSchema,StatusBadge,StatusBadgeSchema,TextStream,TextStreamSchema,UrunAudio,UrunAuthProvider,UrunCamera,UrunControlSender,UrunDocPanel,UrunErrorBoundary,UrunEventSpine,UrunJwtProvider,UrunProvider,UrunSessionGate,UrunSessionStatus,UrunStreamTail,UrunVideo,UrunVoice,authMode,formatPayload,getUrunAudioContext,parseJsonObject,pushCapped,registerComponent,resumeUrunAudioContext,urunPublicEnv,useApp,useChat,useCompletion,useImageFrame,useMetricsPanel,useProgressCard,useRequest,useSessionDoc,useSessionPhase,useSessionTrack,useStatusBadge,useStreamMessages,useTextStream,useUrunAudioLevel,useUrunAuth,usesWorkOSAuth});
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Z,b as le,c as lr}from"./chunk-SSZO4I6Y.mjs";import{a as pr,b as mr,c as pe}from"./chunk-QAEWAWV4.mjs";import{useEffect as vr,useMemo as Sr,useState as yr}from"react";import{Component as fr}from"react";import{jsx as Me,jsxs as gr}from"react/jsx-runtime";var G=class extends fr{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error("[urun] Error caught by UrunErrorBoundary:",e,t)}render(){if(this.state.error){let{fallback:e}=this.props;return typeof e=="function"?e(this.state.error):e||gr("div",{role:"status","aria-live":"polite",style:{padding:"16px",border:"1px solid rgba(17, 24, 39, 0.12)",borderRadius:"8px",background:"#ffffff",color:"#111827",fontFamily:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',maxWidth:"360px"},children:[Me("p",{style:{margin:0,fontWeight:600},children:"Connection interrupted"}),Me("p",{style:{margin:"6px 0 0",color:"#4b5563"},children:"Reconnecting automatically."})]})}return this.props.children}};import{createContext as hr}from"react";var Y=hr(null);import{jsx as me}from"react/jsx-runtime";function br({baseUrl:r,orgId:e,appId:t,jwt:o,authProvider:s,fallback:u,children:l}){let[P,c]=yr(),v=pe(),x=Z("NEXT_PUBLIC_SESSION_TOKEN")??Z("NEXT_PUBLIC_URUN_JWT"),p=le(),h=p==="workos"&&!o,w=o??(p==="jwt"?x:void 0)??P,b=s??Z("NEXT_PUBLIC_SESSION_AUTH_PROVIDER"),C=h&&!w,S=Sr(()=>({appId:t,baseUrl:r,orgId:e,jwt:w,getAccessToken:h?v?.getAccessToken:void 0,authProvider:b}),[t,v,r,b,w,e,h]);return vr(()=>{if(!h||!v)return;let d=!1,m=v;async function f(){try{let y=await m.getAccessToken();d||c(y??void 0)}catch{d||c(void 0)}}f();let T=window.setInterval(()=>{f()},6e4);return()=>{d=!0,window.clearInterval(T)}},[v,h]),me(G,{fallback:u,children:C?me("div",{role:"status","aria-live":"polite",children:"Signing in..."}):me(Y.Provider,{value:S,children:l})})}import{useContext as kr,useMemo as _e,useReducer as Cr,useRef as Rr}from"react";import{App as xr}from"@urun-sh/core";function Tr(r,e){return`${r}:${JSON.stringify(e??{})}`}var fe=class{constructor(e,t){this._doc=e;this._notify=t;this._unsubscribeChange=this._doc.on("change",()=>this._notify())}_doc;_notify;_unsubscribeChange;get(e,t){return this._doc.get(e,t)}set(e){this._doc.set(e),this._notify()}on(e,t){return this._doc.on(e,o=>t(o))}get synced(){return this._doc.synced}onSynced(e){return this._doc.onSynced(()=>{e(),this._notify()})}text(e){let t=this._doc.text(e),o=this._notify;return{append(s){t.append(s),o()},toString:()=>t.toString(),get length(){return t.length},on:(s,u)=>t.on(s,l=>{u(l),o()})}}dispose(){this._unsubscribeChange()}},ge=class{constructor(e,t){this._stream=e;this._notify=t;this._unsubscribeTrack=this._stream.on("track",()=>this._notify())}_stream;_notify;_unsubscribeTrack;get track(){return this._stream.track}attach(e){return this._stream.attach(e)}attachVideo(e){return this._stream.attachVideo(e)}detach(){return this._stream.detach()}detachVideo(){return this._stream.detachVideo()}seek(e){return this._stream.seek(e)}chunks(e){return this._stream.chunks(e)}onSeeked(e){return this._stream.onSeeked(e)}on(e,t){return this._stream.on(e,t)}messages(){return this._stream.messages()}emit(e,t){return this._stream.emit(e,t)}dispose(){this._unsubscribeTrack()}},he=class{constructor(e,t){this._session=e;this._notify=t;this._unsubscribePhase=this._session.onPhase(()=>this._notify())}_session;_notify;_docs=new Map;_streams=new Map;_unsubscribePhase;_disposed=!1;get disposed(){return this._disposed}get id(){return this._session.id}get phase(){return this._session.phase}onPhase(e){return this._session.onPhase(e)}whenLive(e){return this._session.whenLive(e)}request(e,t){return this._session.request(e,t)}requestStream(e,t){return this._session.requestStream(e,t)}complete(e,t){return this._session.complete(e,t)}get recordings(){return this._session.recordings}get artifacts(){return this._session.artifacts}get presence(){return this._session.presence}doc(e){let t=this._docs.get(e);return t||(t=new fe(this._session.doc(e),this._notify),this._docs.set(e,t)),t}stream(e){let t=this._streams.get(e);return t||(t=new ge(this._session.stream(e),this._notify),this._streams.set(e,t)),t}disconnect(){this._disposed=!0;for(let e of this._docs.values())e.dispose();for(let e of this._streams.values())e.dispose();this._docs.clear(),this._streams.clear(),this._unsubscribePhase(),this._session.disconnect(),this._notify()}};function Pr(){let r=kr(Y);if(!r)throw new Error("useApp must be used within <UrunProvider>");if(!r.appId)throw new Error('useApp requires <UrunProvider appId="...">');let[,e]=Cr(s=>s+1,0),t=Rr(new Map),o=_e(()=>xr(r.appId,{baseUrl:r.baseUrl,orgId:r.orgId,jwt:r.jwt,getAccessToken:r.getAccessToken,authProvider:r.authProvider}),[r.appId,r.baseUrl,r.orgId,r.jwt,r.getAccessToken,r.authProvider]);return _e(()=>new Proxy({},{get(s,u){if(typeof u=="string")return l=>{let P=Tr(u,l),c=t.current.get(P);if(c&&!c.disposed)return c;let v=new he(o[u](l),e);return t.current.set(P,v),v}}}),[o])}import{useCallback as ve,useEffect as wr,useMemo as Ur,useRef as Q,useState as Se}from"react";function B(r){let e=r;if(!e||typeof e.request!="function"||typeof e.requestStream!="function")throw new Error("This session does not support request/requestStream. Upgrade @urun-sh/core to a version that ships the request/response primitive.");return e}function Er(r){return r instanceof Error?r:new Error(String(r))}function Ar(r,e){let t=Ur(()=>B(r),[r]),[o,s]=Se(void 0),[u,l]=Se(null),[P,c]=Se(!1),v=Q(e);v.current=e;let x=Q(0),p=Q(null),h=Q(!0);wr(()=>(h.current=!0,()=>{h.current=!1,p.current?.abort()}),[]);let w=ve(async S=>{p.current?.abort();let d=new AbortController;p.current=d;let m=++x.current,f=()=>h.current&&x.current===m;f()&&(c(!0),l(null));try{let T=await t.request(S,{...v.current,signal:d.signal});return f()&&(s(T),c(!1),v.current?.onSuccess?.(T)),T}catch(T){let y=Er(T);throw f()&&(l(y),c(!1),v.current?.onError?.(y)),y}},[t]),b=ve(S=>{w(S).catch(()=>{})},[w]),C=ve(()=>{x.current++,p.current?.abort(),p.current=null,s(void 0),l(null),c(!1)},[]);return{mutate:b,mutateAsync:w,data:o,error:u,isPending:P,reset:C}}import{useCallback as Ie,useEffect as Mr,useMemo as _r,useRef as ee,useState as ye}from"react";function Ne(r){return r instanceof Error?r:new Error(String(r))}var Ir=r=>typeof r=="string"?r:String(r);function Nr(r,e){let t=_r(()=>B(r),[r]),[o,s]=ye(""),[u,l]=ye(!1),[P,c]=ye(null),v=ee(e);v.current=e;let x=ee(0),p=ee(null),h=ee(!0);Mr(()=>(h.current=!0,()=>{h.current=!1,p.current?.cancel(),p.current=null}),[]);let w=Ie(()=>{x.current++,p.current?.cancel(),p.current=null,h.current&&l(!1)},[]),b=Ie(async C=>{p.current?.cancel();let S=++x.current,d=()=>h.current&&x.current===S,m=v.current,f=m?.parseChunk??Ir,T=m?.buildPayload??(a=>({prompt:a}));d()&&(s(""),c(null),l(!0));let{parseChunk:y,buildPayload:q,onFinish:A,onError:n,...i}=m??{},g="",k;try{k=t.requestStream(T(C),i),p.current=k}catch(a){let U=Ne(a);d()&&(c(U),l(!1),m?.onError?.(U));return}try{for await(let a of k){if(x.current!==S)break;g+=f(a),d()&&s(g)}d()&&(l(!1),m?.onFinish?.(g))}catch(a){let U=Ne(a);d()&&(c(U),l(!1),m?.onError?.(U))}finally{p.current===k&&(p.current=null)}},[t]);return{completion:o,complete:b,stop:w,isStreaming:u,error:P}}import{useCallback as qe,useEffect as qr,useMemo as Or,useRef as $,useState as re}from"react";function Oe(r){return r instanceof Error?r:new Error(String(r))}var Lr=r=>typeof r=="string"?r:String(r),Le=0;function be(r){return Le+=1,`${r}-${Le}`}function Vr(r,e){let t=Or(()=>B(r),[r]),[o,s]=re(()=>(e?.initialMessages??[]).map(f=>({id:f.id??be("msg"),role:f.role,content:f.content}))),[u,l]=re(""),[P,c]=re(!1),[v,x]=re(null),p=$(e);p.current=e;let h=$(o);h.current=o;let w=$(u);w.current=u;let b=$(0),C=$(null),S=$(!0);qr(()=>(S.current=!0,()=>{S.current=!1,C.current?.cancel(),C.current=null}),[]);let d=qe(()=>{b.current++,C.current?.cancel(),C.current=null,S.current&&c(!1)},[]),m=qe(async f=>{let T=f===void 0,y=(T?w.current:f)??"";if(!y.trim())return;C.current?.cancel();let A=++b.current,n=()=>S.current&&b.current===A,i=p.current,g=i?.parseChunk??Lr,k={id:be("msg"),role:"user",content:y},a={id:be("msg"),role:"assistant",content:""},U=[...h.current,k].map(M=>({role:M.role,content:M.content})),R=[...h.current,k,a];h.current=R,s(R),T&&l(""),x(null),c(!0);let L=i?.buildPayload??(M=>({messages:M})),{initialMessages:ae,parseChunk:ue,buildPayload:ce,onFinish:de,onError:cr,...E}=i??{},I=M=>{s(O=>O.map(_=>_.id===a.id?{..._,content:M}:_))},j="",N;try{N=t.requestStream(L(U),E),C.current=N}catch(M){let O=Oe(M);n()&&(x(O),c(!1),i?.onError?.(O));return}try{for await(let M of N){if(b.current!==A)break;j+=g(M),n()&&I(j)}n()&&(c(!1),i?.onFinish?.({...a,content:j}))}catch(M){let O=Oe(M);n()&&(x(O),c(!1),i?.onError?.(O))}finally{C.current===N&&(C.current=null)}},[t]);return{messages:o,input:u,setInput:l,sendMessage:m,stop:d,isStreaming:P,error:v}}var Ve=new Map;function jr(r,e,t){if(!t||typeof t.safeParse!="function")throw new Error(`registerComponent("${r}"): schema must be a valid Zod schema`);Ve.set(r,{component:e,schema:t})}function je(r,e){let t=Ve.get(r);if(!t)return{error:`Unknown component: "${r}"`};let o=t.schema.safeParse(e);return o.success?{Component:t.component,validatedProps:o.data}:{error:`Validation failed for "${r}": ${o.error.message}`}}import{Fragment as Dr,jsx as te}from"react/jsx-runtime";function Fr({name:r,props:e,fallback:t}){let o=je(r,e);if(o.error)return console.warn(`[urun] ComponentRenderer: ${o.error}`),t?te(Dr,{children:t}):te("div",{className:"urun-component-error",role:"alert",children:te("span",{className:"urun-component-error-text",children:o.error})});let s=o.Component;return te(s,{...o.validatedProps})}import{z as K}from"zod";import{jsx as ke,jsxs as Fe}from"react/jsx-runtime";var zr=K.object({step:K.number().min(0),total:K.number().min(1),label:K.string().optional(),variant:K.enum(["default","success","error"]).default("default")});function De(r){let{step:e,total:t,label:o,variant:s="default"}=r,u=Math.min(e/t*100,100),l=e>=t;return{step:e,total:t,label:o,variant:s,percentage:u,isComplete:l}}function Hr(r){let{step:e,total:t,label:o,variant:s,percentage:u}=De(r);return Fe("div",{className:"urun-progress-card","data-variant":s,children:[o&&ke("div",{className:"urun-progress-label",children:o}),ke("div",{className:"urun-progress-bar",children:ke("div",{className:"urun-progress-fill",style:{width:`${u}%`}})}),Fe("div",{className:"urun-progress-text",children:[e,"/",t]})]})}import{z as Ce}from"zod";import{jsx as ze,jsxs as Jr}from"react/jsx-runtime";var Br=Ce.object({state:Ce.enum(["thinking","generating","idle","error"]),message:Ce.string().optional()}),$r={thinking:"Thinking...",generating:"Generating...",idle:"Idle",error:"Error"};function He(r){let{state:e,message:t}=r,o=e==="thinking"||e==="generating",s=t??$r[e]??e;return{state:e,message:s,isActive:o}}function Wr(r){let{state:e,message:t,isActive:o}=He(r);return Jr("span",{className:"urun-status-badge","data-state":e,children:[ze("span",{className:`urun-status-indicator${o?" urun-status-pulse":""}`}),ze("span",{className:"urun-status-message",children:t})]})}import{useRef as Be,useEffect as Xr}from"react";import{z as Re}from"zod";import{jsx as $e,jsxs as Kr}from"react/jsx-runtime";var Zr=Re.object({text:Re.string(),streaming:Re.boolean().default(!1)});function We(r){let{text:e,streaming:t=!1}=r,o=e.length===0;return{text:e,streaming:t,isEmpty:o}}function Gr(r){let{text:e,streaming:t}=We(r),o=Be(null),s=Be(0);return Xr(()=>{let u=o.current;u&&e.length!==s.current&&(u.textContent=e,s.current=e.length)},[e]),Kr("div",{className:"urun-text-stream",children:[$e("span",{ref:o,className:"urun-text-content"}),t&&$e("span",{className:"urun-text-cursor"})]})}import{z as ne}from"zod";import{jsx as Je,jsxs as et}from"react/jsx-runtime";var Yr=ne.object({src:ne.string().url(),alt:ne.string().optional(),caption:ne.string().optional()});function Xe(r){let{src:e,alt:t,caption:o}=r;return{src:e,alt:t??"",caption:o}}function Qr(r){let{src:e,alt:t,caption:o}=Xe(r);return et("figure",{className:"urun-image-frame",children:[Je("img",{className:"urun-image",src:e,alt:t}),o&&Je("figcaption",{className:"urun-image-caption",children:o})]})}import{z as F}from"zod";import{jsx as xe,jsxs as nt}from"react/jsx-runtime";var rt=F.object({metrics:F.array(F.object({label:F.string(),value:F.union([F.string(),F.number()]),unit:F.string().optional()}))});function Ze(r){return{metrics:r.metrics.map(t=>({...t,displayValue:t.unit?`${t.value} ${t.unit}`:String(t.value)}))}}function tt(r){let{metrics:e}=Ze(r);return xe("div",{className:"urun-metrics-panel",children:e.map((t,o)=>nt("div",{className:"urun-metric-card",children:[xe("div",{className:"urun-metric-label",children:t.label}),xe("div",{className:"urun-metric-value",children:t.displayValue})]},o))})}import{forwardRef as Pe,useCallback as Ye,useEffect as Te,useImperativeHandle as ut,useRef as Qe,useState as ct}from"react";import dt from"video.js";import"video.js/dist/video-js.css";import{useContext as st,useState as it,useEffect as at}from"react";import{createContext as ot,useState as Nn,useEffect as qn,useRef as On}from"react";import{TransportSession as Vn}from"@urun-sh/core/internal";import{jsx as Fn}from"react/jsx-runtime";var Ge=ot(null);function Ke(r){let e=st(Ge);if(!e)throw new Error("useTrack must be used within <SessionProvider> or <UrunProvider>");let[t,o]=it(null);return at(()=>{let s=e.getState()._transport;if(!s)return;let u=s.getTrackByName?.bind(s),l=u?.(r);l&&l.readyState!=="ended"&&o(l);let P=s.on("track",c=>{let v=u?.(r);v&&v.id!==c.id||(o(c),c.addEventListener("ended",()=>{o(null)}))});return()=>{P()}},[r,e]),t}import{jsx as H,jsxs as tr}from"react/jsx-runtime";function er(r){r.posterImage?.hide?.()}var lt=`
|
|
1
|
+
import{a as Q,b as xe,c as Nr}from"./chunk-SSZO4I6Y.mjs";import{a as _r,b as Or,c as Ce}from"./chunk-QAEWAWV4.mjs";import{useEffect as Vr,useMemo as jr,useState as Dr}from"react";import{Component as Lr}from"react";import{jsx as We,jsxs as Ir}from"react/jsx-runtime";var ee=class extends Lr{constructor(e){super(e),this.state={error:null}}static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error("[urun] Error caught by UrunErrorBoundary:",e,t)}render(){if(this.state.error){let{fallback:e}=this.props;return typeof e=="function"?e(this.state.error):e||Ir("div",{role:"status","aria-live":"polite",style:{padding:"16px",border:"1px solid rgba(17, 24, 39, 0.12)",borderRadius:"8px",background:"#ffffff",color:"#111827",fontFamily:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',maxWidth:"360px"},children:[We("p",{style:{margin:0,fontWeight:600},children:"Connection interrupted"}),We("p",{style:{margin:"6px 0 0",color:"#4b5563"},children:"Reconnecting automatically."})]})}return this.props.children}};import{createContext as qr}from"react";var se=qr(null);import{jsx as Te}from"react/jsx-runtime";function Fr({baseUrl:r,orgId:e,appId:t,jwt:n,authProvider:s,fallback:a,children:i}){let[d,u]=Dr(),c=Ce(),h=Q("NEXT_PUBLIC_SESSION_TOKEN")??Q("NEXT_PUBLIC_URUN_JWT"),l=xe(),f=l==="workos"&&!n,P=n??(l==="jwt"?h:void 0)??d,x=s??Q("NEXT_PUBLIC_SESSION_AUTH_PROVIDER"),T=f&&!P,y=jr(()=>({appId:t,baseUrl:r,orgId:e,jwt:P,getAccessToken:f?c?.getAccessToken:void 0,authProvider:x}),[t,c,r,x,P,e,f]);return Vr(()=>{if(!f||!c)return;let g=!1,v=c;async function S(){try{let k=await v.getAccessToken();g||u(k??void 0)}catch{g||u(void 0)}}S();let w=window.setInterval(()=>{S()},6e4);return()=>{g=!0,window.clearInterval(w)}},[c,f]),Te(ee,{fallback:a,children:T?Te("div",{role:"status","aria-live":"polite",children:"Signing in..."}):Te(se.Provider,{value:y,children:i})})}import{useContext as zr,useMemo as Je,useReducer as Br,useRef as Hr}from"react";import{App as $r}from"@urun-sh/core";function Wr(r,e){return`${r}:${JSON.stringify(e??{})}`}var Re=class{constructor(e,t){this._doc=e;this._notify=t;this._unsubscribeChange=this._doc.on("change",()=>this._notify())}_doc;_notify;_unsubscribeChange;get(e,t){return this._doc.get(e,t)}set(e){this._doc.set(e),this._notify()}on(e,t){return this._doc.on(e,n=>t(n))}get synced(){return this._doc.synced}onSynced(e){return this._doc.onSynced(()=>{e(),this._notify()})}text(e){let t=this._doc.text(e),n=this._notify;return{append(s){t.append(s),n()},toString:()=>t.toString(),get length(){return t.length},on:(s,a)=>t.on(s,i=>{a(i),n()})}}dispose(){this._unsubscribeChange()}},Pe=class{constructor(e,t){this._stream=e;this._notify=t;this._unsubscribeTrack=this._stream.on("track",()=>this._notify())}_stream;_notify;_unsubscribeTrack;get track(){return this._stream.track}attach(e){return this._stream.attach(e)}attachVideo(e){return this._stream.attachVideo(e)}detach(){return this._stream.detach()}detachVideo(){return this._stream.detachVideo()}seek(e){return this._stream.seek(e)}chunks(e){return this._stream.chunks(e)}onSeeked(e){return this._stream.onSeeked(e)}on(e,t){return this._stream.on(e,t)}messages(){return this._stream.messages()}emit(e,t){return this._stream.emit(e,t)}dispose(){this._unsubscribeTrack()}},we=class{constructor(e,t){this._session=e;this._notify=t;this._unsubscribePhase=this._session.onPhase(()=>this._notify())}_session;_notify;_docs=new Map;_streams=new Map;_unsubscribePhase;_disposed=!1;get disposed(){return this._disposed}get id(){return this._session.id}get phase(){return this._session.phase}get status(){return this._session.status}onPhase(e){return this._session.onPhase(e)}whenLive(e){return this._session.whenLive(e)}request(e,t){return this._session.request(e,t)}requestStream(e,t){return this._session.requestStream(e,t)}complete(e,t){return this._session.complete(e,t)}get recordings(){return this._session.recordings}get artifacts(){return this._session.artifacts}get presence(){return this._session.presence}doc(e){let t=this._docs.get(e);return t||(t=new Re(this._session.doc(e),this._notify),this._docs.set(e,t)),t}stream(e){let t=this._streams.get(e);return t||(t=new Pe(this._session.stream(e),this._notify),this._streams.set(e,t)),t}disconnect(){this._disposed=!0;for(let e of this._docs.values())e.dispose();for(let e of this._streams.values())e.dispose();this._docs.clear(),this._streams.clear(),this._unsubscribePhase(),this._session.disconnect(),this._notify()}};function Jr(){let r=zr(se);if(!r)throw new Error("useApp must be used within <UrunProvider>");if(!r.appId)throw new Error('useApp requires <UrunProvider appId="...">');let[,e]=Br(s=>s+1,0),t=Hr(new Map),n=Je(()=>$r(r.appId,{baseUrl:r.baseUrl,orgId:r.orgId,jwt:r.jwt,getAccessToken:r.getAccessToken,authProvider:r.authProvider}),[r.appId,r.baseUrl,r.orgId,r.jwt,r.getAccessToken,r.authProvider]);return Je(()=>new Proxy({},{get(s,a){if(typeof a=="string")return i=>{let d=Wr(a,i),u=t.current.get(d);if(u&&!u.disposed)return u;let c=new we(n[a](i),e);return t.current.set(d,c),c}}}),[n])}import{useCallback as Ue,useEffect as Gr,useMemo as Xr,useRef as ae,useState as Ee}from"react";function J(r){let e=r;if(!e||typeof e.request!="function"||typeof e.requestStream!="function")throw new Error("This session does not support request/requestStream. Upgrade @urun-sh/core to a version that ships the request/response primitive.");return e}function Zr(r){return r instanceof Error?r:new Error(String(r))}function Kr(r,e){let t=Xr(()=>J(r),[r]),[n,s]=Ee(void 0),[a,i]=Ee(null),[d,u]=Ee(!1),c=ae(e);c.current=e;let h=ae(0),l=ae(null),f=ae(!0);Gr(()=>(f.current=!0,()=>{f.current=!1,l.current?.abort()}),[]);let P=Ue(async y=>{l.current?.abort();let g=new AbortController;l.current=g;let v=++h.current,S=()=>f.current&&h.current===v;S()&&(u(!0),i(null));try{let w=await t.request(y,{...c.current,signal:g.signal});return S()&&(s(w),u(!1),c.current?.onSuccess?.(w)),w}catch(w){let k=Zr(w);throw S()&&(i(k),u(!1),c.current?.onError?.(k)),k}},[t]),x=Ue(y=>{P(y).catch(()=>{})},[P]),T=Ue(()=>{h.current++,l.current?.abort(),l.current=null,s(void 0),i(null),u(!1)},[]);return{mutate:x,mutateAsync:P,data:n,error:a,isPending:d,reset:T}}import{useCallback as Ge,useEffect as Yr,useMemo as Qr,useRef as ie,useState as Ae}from"react";function Xe(r){return r instanceof Error?r:new Error(String(r))}var et=r=>typeof r=="string"?r:String(r);function rt(r,e){let t=Qr(()=>J(r),[r]),[n,s]=Ae(""),[a,i]=Ae(!1),[d,u]=Ae(null),c=ie(e);c.current=e;let h=ie(0),l=ie(null),f=ie(!0);Yr(()=>(f.current=!0,()=>{f.current=!1,l.current?.cancel(),l.current=null}),[]);let P=Ge(()=>{h.current++,l.current?.cancel(),l.current=null,f.current&&i(!1)},[]),x=Ge(async T=>{l.current?.cancel();let y=++h.current,g=()=>f.current&&h.current===y,v=c.current,S=v?.parseChunk??et,w=v?.buildPayload??(m=>({prompt:m}));g()&&(s(""),u(null),i(!0));let{parseChunk:k,buildPayload:L,onFinish:A,onError:o,...p}=v??{},b="",C;try{C=t.requestStream(w(T),p),l.current=C}catch(m){let U=Xe(m);g()&&(u(U),i(!1),v?.onError?.(U));return}try{for await(let m of C){if(h.current!==y)break;b+=S(m),g()&&s(b)}g()&&(i(!1),v?.onFinish?.(b))}catch(m){let U=Xe(m);g()&&(u(U),i(!1),v?.onError?.(U))}finally{l.current===C&&(l.current=null)}},[t]);return{completion:n,complete:x,stop:P,isStreaming:a,error:d}}import{useCallback as Ze,useEffect as tt,useMemo as nt,useRef as G,useState as ue}from"react";function Ke(r){return r instanceof Error?r:new Error(String(r))}var ot=r=>typeof r=="string"?r:String(r),Ye=0;function Me(r){return Ye+=1,`${r}-${Ye}`}function st(r,e){let t=nt(()=>J(r),[r]),[n,s]=ue(()=>(e?.initialMessages??[]).map(S=>({id:S.id??Me("msg"),role:S.role,content:S.content}))),[a,i]=ue(""),[d,u]=ue(!1),[c,h]=ue(null),l=G(e);l.current=e;let f=G(n);f.current=n;let P=G(a);P.current=a;let x=G(0),T=G(null),y=G(!0);tt(()=>(y.current=!0,()=>{y.current=!1,T.current?.cancel(),T.current=null}),[]);let g=Ze(()=>{x.current++,T.current?.cancel(),T.current=null,y.current&&u(!1)},[]),v=Ze(async S=>{let w=S===void 0,k=(w?P.current:S)??"";if(!k.trim())return;T.current?.cancel();let A=++x.current,o=()=>y.current&&x.current===A,p=l.current,b=p?.parseChunk??ot,C={id:Me("msg"),role:"user",content:k},m={id:Me("msg"),role:"assistant",content:""},U=[...f.current,C].map(M=>({role:M.role,content:M.content})),R=[...f.current,C,m];f.current=R,s(R),w&&i(""),h(null),u(!0);let q=p?.buildPayload??(M=>({messages:M})),{initialMessages:Se,parseChunk:be,buildPayload:ye,onFinish:ke,onError:Ar,...E}=p??{},N=M=>{s(I=>I.map(O=>O.id===m.id?{...O,content:M}:O))},j="",_;try{_=t.requestStream(q(U),E),T.current=_}catch(M){let I=Ke(M);o()&&(h(I),u(!1),p?.onError?.(I));return}try{for await(let M of _){if(x.current!==A)break;j+=b(M),o()&&N(j)}o()&&(u(!1),p?.onFinish?.({...m,content:j}))}catch(M){let I=Ke(M);o()&&(h(I),u(!1),p?.onError?.(I))}finally{T.current===_&&(T.current=null)}},[t]);return{messages:n,input:a,setInput:i,sendMessage:v,stop:g,isStreaming:d,error:c}}var Qe=new Map;function at(r,e,t){if(!t||typeof t.safeParse!="function")throw new Error(`registerComponent("${r}"): schema must be a valid Zod schema`);Qe.set(r,{component:e,schema:t})}function er(r,e){let t=Qe.get(r);if(!t)return{error:`Unknown component: "${r}"`};let n=t.schema.safeParse(e);return n.success?{Component:t.component,validatedProps:n.data}:{error:`Validation failed for "${r}": ${n.error.message}`}}import{Fragment as ut,jsx as ce}from"react/jsx-runtime";function it({name:r,props:e,fallback:t}){let n=er(r,e);if(n.error)return console.warn(`[urun] ComponentRenderer: ${n.error}`),t?ce(ut,{children:t}):ce("div",{className:"urun-component-error",role:"alert",children:ce("span",{className:"urun-component-error-text",children:n.error})});let s=n.Component;return ce(s,{...n.validatedProps})}import{z as re}from"zod";import{jsx as Ne,jsxs as rr}from"react/jsx-runtime";var ct=re.object({step:re.number().min(0),total:re.number().min(1),label:re.string().optional(),variant:re.enum(["default","success","error"]).default("default")});function tr(r){let{step:e,total:t,label:n,variant:s="default"}=r,a=Math.min(e/t*100,100),i=e>=t;return{step:e,total:t,label:n,variant:s,percentage:a,isComplete:i}}function lt(r){let{step:e,total:t,label:n,variant:s,percentage:a}=tr(r);return rr("div",{className:"urun-progress-card","data-variant":s,children:[n&&Ne("div",{className:"urun-progress-label",children:n}),Ne("div",{className:"urun-progress-bar",children:Ne("div",{className:"urun-progress-fill",style:{width:`${a}%`}})}),rr("div",{className:"urun-progress-text",children:[e,"/",t]})]})}import{z as _e}from"zod";import{jsx as nr,jsxs as ft}from"react/jsx-runtime";var dt=_e.object({state:_e.enum(["thinking","generating","idle","error"]),message:_e.string().optional()}),pt={thinking:"Thinking...",generating:"Generating...",idle:"Idle",error:"Error"};function or(r){let{state:e,message:t}=r,n=e==="thinking"||e==="generating",s=t??pt[e]??e;return{state:e,message:s,isActive:n}}function mt(r){let{state:e,message:t,isActive:n}=or(r);return ft("span",{className:"urun-status-badge","data-state":e,children:[nr("span",{className:`urun-status-indicator${n?" urun-status-pulse":""}`}),nr("span",{className:"urun-status-message",children:t})]})}import{useRef as sr,useEffect as gt}from"react";import{z as Oe}from"zod";import{jsx as ar,jsxs as St}from"react/jsx-runtime";var ht=Oe.object({text:Oe.string(),streaming:Oe.boolean().default(!1)});function ir(r){let{text:e,streaming:t=!1}=r,n=e.length===0;return{text:e,streaming:t,isEmpty:n}}function vt(r){let{text:e,streaming:t}=ir(r),n=sr(null),s=sr(0);return gt(()=>{let a=n.current;a&&e.length!==s.current&&(a.textContent=e,s.current=e.length)},[e]),St("div",{className:"urun-text-stream",children:[ar("span",{ref:n,className:"urun-text-content"}),t&&ar("span",{className:"urun-text-cursor"})]})}import{z as le}from"zod";import{jsx as ur,jsxs as kt}from"react/jsx-runtime";var bt=le.object({src:le.string().url(),alt:le.string().optional(),caption:le.string().optional()});function cr(r){let{src:e,alt:t,caption:n}=r;return{src:e,alt:t??"",caption:n}}function yt(r){let{src:e,alt:t,caption:n}=cr(r);return kt("figure",{className:"urun-image-frame",children:[ur("img",{className:"urun-image",src:e,alt:t}),n&&ur("figcaption",{className:"urun-image-caption",children:n})]})}import{z as D}from"zod";import{jsx as Le,jsxs as Tt}from"react/jsx-runtime";var xt=D.object({metrics:D.array(D.object({label:D.string(),value:D.union([D.string(),D.number()]),unit:D.string().optional()}))});function lr(r){return{metrics:r.metrics.map(t=>({...t,displayValue:t.unit?`${t.value} ${t.unit}`:String(t.value)}))}}function Ct(r){let{metrics:e}=lr(r);return Le("div",{className:"urun-metrics-panel",children:e.map((t,n)=>Tt("div",{className:"urun-metric-card",children:[Le("div",{className:"urun-metric-label",children:t.label}),Le("div",{className:"urun-metric-value",children:t.displayValue})]},n))})}import{forwardRef as qe,useCallback as mr,useEffect as Ie,useImperativeHandle as Et,useRef as fr,useState as At}from"react";import Mt from"video.js";import"video.js/dist/video-js.css";import{useContext as Pt,useState as wt,useEffect as Ut}from"react";import{createContext as Rt,useState as Ro,useEffect as Po,useRef as wo}from"react";import{TransportSession as Eo}from"@urun-sh/core/internal";import{jsx as Mo}from"react/jsx-runtime";var dr=Rt(null);function pr(r){let e=Pt(dr);if(!e)throw new Error("useTrack must be used within <SessionProvider> or <UrunProvider>");let[t,n]=wt(null);return Ut(()=>{let s=e.getState()._transport;if(!s)return;let a=s.getTrackByName?.bind(s),i=a?.(r);i&&i.readyState!=="ended"&&n(i);let d=s.on("track",u=>{let c=a?.(r);c&&c.id!==u.id||(n(u),u.addEventListener("ended",()=>{n(null)}))});return()=>{d()}},[r,e]),t}import{jsx as H,jsxs as vr}from"react/jsx-runtime";function gr(r){r.posterImage?.hide?.()}var Nt=`
|
|
2
2
|
[data-urun-video]{width:100%;height:100%}
|
|
3
3
|
[data-urun-video] .video-js,[data-urun-video] .vjs-tech{width:100%;height:100%}
|
|
4
4
|
[data-urun-video] .vjs-tech{object-fit:contain}
|
|
@@ -6,4 +6,4 @@ import{a as Z,b as le,c as lr}from"./chunk-SSZO4I6Y.mjs";import{a as pr,b as mr,
|
|
|
6
6
|
.urun-video-live.vjs-has-started .vjs-loading-spinner,
|
|
7
7
|
.urun-video-live.vjs-has-started .vjs-big-play-button{display:none !important}
|
|
8
8
|
.urun-video-live .vjs-poster{background-color:transparent}
|
|
9
|
-
`,rr="urun-video-critical-css";function pt(){if(typeof document>"u"||document.getElementById(rr))return;let r=document.createElement("style");r.id=rr,r.textContent=lt,document.head.appendChild(r)}var mt=["playToggle","volumePanel","fullscreenToggle"],ft=["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","remainingTimeDisplay","fullscreenToggle"],nr=Pe(function(e,t){let{track:o,stream:s,src:u,type:l="video/mp4",className:P,videoClassName:c,poster:v,controls:x=!0,autoPlay:p=!0,muted:h=!0,onVideoElement:w,onPlayerReady:b,children:C}=e,S=typeof u=="string"&&u.length>0,d=!S,m=Qe(null),f=Qe(null),[T,y]=ct(!1),q=Ye(n=>{m.current=n,typeof t=="function"?t(n):t&&(t.current=n),w?.(n)},[t,w]);ut(t,()=>m.current,[]);let A=Ye(()=>{let n=m.current;if(!n||!n.srcObject&&!n.src)return;h&&(n.muted=!0,n.defaultMuted=!0),n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline","");let i=n.play();i&&typeof i.then=="function"&&i.then(()=>y(!1)).catch(g=>{(g instanceof Error?g.name:String(g))!=="AbortError"&&y(!0)})},[h]);return Te(()=>{if(typeof document>"u")return;let n=m.current;if(!n)return;pt(),h&&(n.muted=!0,n.defaultMuted=!0,n.setAttribute("muted","")),n.autoplay=p,n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline","");let i=dt(n,{controls:x,autoplay:p,muted:h,playsinline:!0,preload:"auto",fluid:!1,bigPlayButton:!0,poster:v,userActions:{click:!0,doubleClick:!1,hotkeys:!1},controlBar:{children:d?mt:ft}});d&&i.addClass("urun-video-live");let g=()=>y(!1),k=()=>{i.hasStarted(!0),er(i),g()},a=()=>{d&&A()};return n.addEventListener("playing",k),n.addEventListener("loadedmetadata",a),d&&n.addEventListener("pause",a),f.current=i,b?.(i),()=>{n.removeEventListener("playing",k),n.removeEventListener("loadedmetadata",a),n.removeEventListener("pause",a),b?.(null),f.current&&(f.current.dispose(),f.current=null)}},[d]),Te(()=>{if(!S)return;let n=f.current;if(!n)return;let i=n.tech?.(!0)?.el?.();i&&(i.srcObject=null),n.src({src:u,type:l}),p&&A()},[S,u,l,p,A]),Te(()=>{if(!d)return;let n=f.current;if(!n)return;let i=o??null,g=s??null;!g&&i&&(g=new MediaStream([i]));let k=n.tech?.(!0)?.el?.()??m.current;if(!k)return;if(!g){k.srcObject=null,y(!1);return}k.srcObject=g,A();let a=g.getVideoTracks()[0]??i??null,U=()=>{n.hasStarted(!0),er(n),A()},R=()=>{k.srcObject=null,y(!1)};return a&&(a.addEventListener("unmute",U),a.addEventListener("ended",R),a.muted||U()),()=>{a&&(a.removeEventListener("unmute",U),a.removeEventListener("ended",R))}},[d,o,s,A]),tr("div",{className:P,style:{position:"relative",width:"100%",height:"100%"},"data-urun-video":"","data-urun-video-mode":d?"live":"vod",children:[H("video",{ref:q,className:["video-js","vjs-default-skin",c].filter(Boolean).join(" "),playsInline:!0}),T&&H("button",{type:"button",onClick:A,"aria-label":"Tap to play",style:{position:"absolute",inset:0,zIndex:30,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.6)",border:0,cursor:"pointer",color:"#fff"},children:tr("span",{style:{display:"inline-flex",alignItems:"center",gap:8,borderRadius:999,border:"1px solid rgba(255,255,255,0.2)",background:"rgba(255,255,255,0.1)",padding:"10px 20px",fontSize:14,fontWeight:500},children:[H("svg",{viewBox:"0 0 24 24",fill:"currentColor",width:16,height:16,"aria-hidden":!0,children:H("path",{d:"M8 5v14l11-7z"})}),"Tap to play"]})}),C]})}),gt=Pe(function({name:e,...t},o){let s=Ke(e);return H(nr,{ref:o,...t,track:s})}),ht=Pe(function(e,t){return!!e.name&&!e.track&&!e.stream&&!(typeof e.src=="string"&&e.src)?H(gt,{ref:t,...e,name:e.name}):H(nr,{ref:t,...e})});import{forwardRef as St,useCallback as W,useEffect as or,useImperativeHandle as yt,useRef as J}from"react";var oe=null;function vt(){if(typeof window>"u")return null;let r=window;return r.AudioContext??r.webkitAudioContext??null}function se(){if(oe)return oe;let r=vt();return r?(oe=new r,oe):null}function we(){let r=se();r&&r.state==="suspended"&&r.resume().catch(()=>{})}import{jsx as kt}from"react/jsx-runtime";var bt=1e3,sr=200;function Ue(...r){console.debug("[urun-audio]",...r)}var Ee=St(function(e,t){let{session:o,stream:s="audio",track:u,controls:l=!1,className:P,onTrack:c,onUnlockChange:v,onAudioElement:x}=e,p=J(null),h=J(null),w=J(null),b=J(null),C=J(c);C.current=c;let S=J(v);S.current=v;let d=W(n=>{w.current!==n&&(w.current=n,S.current?.(n))},[]),m=W(()=>{if(typeof MediaStream>"u")return null;h.current||(h.current=new MediaStream);let n=p.current;return n&&n.srcObject!==h.current&&(n.srcObject=h.current),h.current},[]),f=W(n=>{let i=p.current;if(!i)return;let g=i.play();!g||typeof g.then!="function"||g.then(()=>{i.muted||d(!0)}).catch(k=>{let a=k instanceof Error?k.name:String(k);if(a==="AbortError"){Ue(`play() aborted (${n}); retrying in ${sr}ms`),b.current&&clearTimeout(b.current),b.current=setTimeout(()=>{b.current=null,f(`${n}:retry`)},sr);return}if(a==="NotAllowedError"){Ue(`play() blocked pending a user gesture (${n})`),d(!1);return}Ue(`play() failed (${n})`,k)})},[d]),T=W(n=>{let i=m();if(i){for(let g of i.getAudioTracks())g!==n&&i.removeTrack(g);n&&!i.getAudioTracks().includes(n)&&i.addTrack(n),n&&f("track-attach"),C.current?.(n)}},[m,f]),y=W(()=>{let n=p.current;n&&(m(),n.muted=!1,f("gesture"),we(),d(!0))},[m,f,d]);yt(t,()=>({unlock:y,get unlocked(){return w.current===!0},get element(){return p.current}}),[y]);let q=W(n=>{p.current=n,n&&(n.setAttribute("playsinline",""),n.setAttribute("webkit-playsinline",""),m()),x?.(n)},[m,x]),A=u!==void 0;return or(()=>{if(A){T(u??null);return}if(!o)return;let n=o.stream(s),i=()=>{let R=h.current;return R?R.getAudioTracks()[0]??null:null},g=R=>{if(R!==i()&&(T(R),R)){let L=()=>{i()===R&&T(null)};R.addEventListener("ended",L)}},k=n.track;k&&k.readyState==="live"&&g(k);let a=n.on("track",R=>{R&&R.readyState!=="live"||g(R)}),U=setInterval(()=>{let R=n.track;R&&R.readyState==="live"&&g(R)},bt);return()=>{a(),clearInterval(U)}},[o,s,A,u,T]),or(()=>()=>{b.current&&clearTimeout(b.current)},[]),kt("audio",{ref:q,className:P,autoPlay:!0,playsInline:!0,controls:l,"data-urun-audio":""})});import{forwardRef as Ct,useCallback as ie,useEffect as Rt,useImperativeHandle as xt,useRef as X}from"react";import{jsx as wt}from"react/jsx-runtime";var ir={channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};function Tt(...r){console.debug("[urun-voice]",...r)}var Pt=Ct(function(e,t){let{session:o,stream:s="audio",constraints:u=ir,connectTimeoutMs:l,attempts:P=3,retryDelayMs:c=1500,onActiveChange:v,onError:x,onMicStream:p,onTrack:h,onUnlockChange:w}=e,b=X(null),C=X(null),S=X(!1),d=X(v);d.current=v;let m=X(x);m.current=x;let f=X(p);f.current=p;let T=ie(n=>{S.current!==n&&(S.current=n,d.current?.(n))},[]),y=ie(()=>{let n=C.current;if(n){for(let i of n.getTracks())i.stop();C.current=null,f.current?.(null)}},[]),q=ie(async()=>{y(),T(!1),await o.stream(s).detach().catch(()=>{})},[o,s,y,T]),A=ie(async()=>{b.current?.unlock();let n=await navigator.mediaDevices.getUserMedia({audio:u,video:!1});y(),C.current=n,f.current?.(n);let i=n.getAudioTracks()[0];if(!i){y();let a=new Error("no microphone audio track");throw m.current?.(a),a}o.connect?.();let g;for(let a=1;a<=P;a++)try{await o.whenLive(l!==void 0?{timeout:l}:void 0),await o.stream(s).attach(i),T(!0);return}catch(U){g=U,Tt(`start attempt ${a}/${P} failed`,U),a<P&&await new Promise(R=>setTimeout(R,c))}y(),T(!1);let k=g instanceof Error?g:new Error(String(g??"voice start failed"));throw m.current?.(k),k},[o,s,u,l,P,c,y,T]);return xt(t,()=>({start:A,stop:q,unlock:()=>b.current?.unlock(),get active(){return S.current},get micStream(){return C.current},get audio(){return b.current}}),[A,q]),Rt(()=>y,[y]),wt(Ee,{ref:b,session:o,stream:s,onTrack:h,onUnlockChange:w})});import{forwardRef as Ut,useCallback as D,useEffect as Et,useImperativeHandle as At,useRef as V,useState as Mt}from"react";import{jsx as It,jsxs as Nt}from"react/jsx-runtime";var ur={width:{ideal:960},height:{ideal:720},frameRate:{ideal:8}};function ar(...r){console.debug("[urun-camera]",...r)}var _t=Ut(function(e,t){let{session:o,stream:s="video",constraints:u,facingMode:l="environment",mirror:P="auto",connectTimeoutMs:c,preview:v=!0,className:x,videoClassName:p,onActiveChange:h,onError:w,onStream:b,onTrack:C,children:S}=e,d=V(null),m=V(null),f=V(null),T=V(!1),y=V(l),[q,A]=Mt(l),n=V(h);n.current=h;let i=V(w);i.current=w;let g=V(b);g.current=b;let k=V(C);k.current=C;let a=D(E=>{T.current!==E&&(T.current=E,n.current?.(E))},[]),U=D(E=>{let I=d.current;I&&(I.muted=!0,I.srcObject=E,E&&I.play()?.catch?.(j=>ar("preview play() failed",j)))},[]),R=D(()=>{f.current?.(),f.current=null;let E=m.current;if(E){for(let I of E.getTracks())I.stop();m.current=null,g.current?.(null),k.current?.(null)}U(null)},[U]),L=D(async E=>{let I=m.current,j=f.current,N;try{N=await navigator.mediaDevices.getUserMedia({video:{...ur,...u,facingMode:E},audio:!1})}catch(_){let z=_ instanceof Error?_:new Error(String(_));throw i.current?.(z),z}let M=N.getVideoTracks()[0];if(!M){for(let z of N.getTracks())z.stop();let _=new Error("no camera video track");throw i.current?.(_),_}m.current=N,y.current=E,A(E),U(N),g.current?.(N);let O=()=>{m.current===N&&(ar("camera track ended (device removed or permission revoked)"),R(),a(!1))};M.addEventListener("ended",O),f.current=()=>M.removeEventListener("ended",O);try{o.connect?.(),await o.whenLive(c!==void 0?{timeout:c}:void 0),await o.stream(s).attachVideo(M)}catch(_){M.removeEventListener("ended",O);for(let dr of N.getTracks())dr.stop();m.current===N&&(m.current=I,f.current=j,U(I),g.current?.(I));let z=_ instanceof Error?_:new Error(String(_));throw i.current?.(z),z}if(I&&I!==N){j?.();for(let _ of I.getTracks())_.stop()}k.current?.(M),a(!0)},[o,s,u,c,U,R,a]),ae=D(E=>L(E?.facingMode??y.current),[L]),ue=D(async E=>{T.current&&y.current===E||await L(E)},[L]),ce=D(()=>L(y.current==="environment"?"user":"environment"),[L]),de=D(async()=>{R(),a(!1),await o.stream(s).detachVideo().catch(()=>{})},[o,s,R,a]);return At(t,()=>({start:ae,stop:de,flip:ce,setFacingMode:ue,get active(){return T.current},get facingMode(){return y.current},get stream(){return m.current},get element(){return d.current}}),[ae,de,ce,ue]),Et(()=>R,[R]),v?Nt("div",{className:x,style:{position:"relative",width:"100%",height:"100%"},"data-urun-camera":"","data-urun-camera-facing":q,children:[It("video",{ref:d,className:p,autoPlay:!0,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"contain",...(P==="auto"?q==="user":P)?{transform:"scaleX(-1)"}:{}}}),S]}):null});import{useEffect as qt,useState as Ot}from"react";var Ae={level:0,speaking:!1};function Lt(r,e={}){let{fftSize:t=512,intervalMs:o=100,speakingThreshold:s=.02}=e,[u,l]=Ot(Ae);return qt(()=>{if(!r){l(Ae);return}let P=se();if(!P||typeof MediaStream>"u")return;let c;r instanceof MediaStream?c=r:(c=new MediaStream,c.addTrack(r));let v,x;try{v=P.createMediaStreamSource(c),x=P.createAnalyser(),x.fftSize=t,v.connect(x)}catch{return}let p=new Uint8Array(x.fftSize),w=setInterval(()=>{x.getByteTimeDomainData(p);let b=0;for(let S=0;S<p.length;S++){let d=(p[S]-128)/128;b+=d*d}let C=Math.sqrt(b/p.length);l(S=>{let d=C>s;return Math.abs(S.level-C)<.005&&S.speaking===d?S:{level:C,speaking:d}})},o);return()=>{clearInterval(w),v.disconnect(),l(Ae)}},[r,t,o,s]),u}export{Fr as ComponentRenderer,ur as DEFAULT_CAMERA_CONSTRAINTS,ir as DEFAULT_VOICE_CONSTRAINTS,Qr as ImageFrame,Yr as ImageFrameSchema,tt as MetricsPanel,rt as MetricsPanelSchema,Hr as ProgressCard,zr as ProgressCardSchema,Wr as StatusBadge,Br as StatusBadgeSchema,Gr as TextStream,Zr as TextStreamSchema,Ee as UrunAudio,pr as UrunAuthProvider,_t as UrunCamera,G as UrunErrorBoundary,mr as UrunJwtProvider,br as UrunProvider,ht as UrunVideo,Pt as UrunVoice,le as authMode,se as getUrunAudioContext,jr as registerComponent,we as resumeUrunAudioContext,Z as urunPublicEnv,Pr as useApp,Vr as useChat,Nr as useCompletion,Xe as useImageFrame,Ze as useMetricsPanel,De as useProgressCard,Ar as useRequest,He as useStatusBadge,We as useTextStream,Lt as useUrunAudioLevel,pe as useUrunAuth,lr as usesWorkOSAuth};
|
|
9
|
+
`,hr="urun-video-critical-css";function _t(){if(typeof document>"u"||document.getElementById(hr))return;let r=document.createElement("style");r.id=hr,r.textContent=Nt,document.head.appendChild(r)}var Ot=["playToggle","volumePanel","fullscreenToggle"],Lt=["playToggle","volumePanel","currentTimeDisplay","timeDivider","durationDisplay","progressControl","remainingTimeDisplay","fullscreenToggle"],Sr=qe(function(e,t){let{track:n,stream:s,src:a,type:i="video/mp4",className:d,videoClassName:u,poster:c,controls:h=!0,autoPlay:l=!0,muted:f=!0,onVideoElement:P,onPlayerReady:x,children:T}=e,y=typeof a=="string"&&a.length>0,g=!y,v=fr(null),S=fr(null),[w,k]=At(!1),L=mr(o=>{v.current=o,typeof t=="function"?t(o):t&&(t.current=o),P?.(o)},[t,P]);Et(t,()=>v.current,[]);let A=mr(()=>{let o=v.current;if(!o||!o.srcObject&&!o.src)return;f&&(o.muted=!0,o.defaultMuted=!0),o.setAttribute("playsinline",""),o.setAttribute("webkit-playsinline","");let p=o.play();p&&typeof p.then=="function"&&p.then(()=>k(!1)).catch(b=>{(b instanceof Error?b.name:String(b))!=="AbortError"&&k(!0)})},[f]);return Ie(()=>{if(typeof document>"u")return;let o=v.current;if(!o)return;_t(),f&&(o.muted=!0,o.defaultMuted=!0,o.setAttribute("muted","")),o.autoplay=l,o.setAttribute("playsinline",""),o.setAttribute("webkit-playsinline","");let p=Mt(o,{controls:h,autoplay:l,muted:f,playsinline:!0,preload:"auto",fluid:!1,bigPlayButton:!0,poster:c,userActions:{click:!0,doubleClick:!1,hotkeys:!1},controlBar:{children:g?Ot:Lt}});g&&p.addClass("urun-video-live");let b=()=>k(!1),C=()=>{p.hasStarted(!0),gr(p),b()},m=()=>{g&&A()};return o.addEventListener("playing",C),o.addEventListener("loadedmetadata",m),g&&o.addEventListener("pause",m),S.current=p,x?.(p),()=>{o.removeEventListener("playing",C),o.removeEventListener("loadedmetadata",m),o.removeEventListener("pause",m),x?.(null),S.current&&(S.current.dispose(),S.current=null)}},[g]),Ie(()=>{if(!y)return;let o=S.current;if(!o)return;let p=o.tech?.(!0)?.el?.();p&&(p.srcObject=null),o.src({src:a,type:i}),l&&A()},[y,a,i,l,A]),Ie(()=>{if(!g)return;let o=S.current;if(!o)return;let p=n??null,b=s??null;!b&&p&&(b=new MediaStream([p]));let C=o.tech?.(!0)?.el?.()??v.current;if(!C)return;if(!b){C.srcObject=null,k(!1);return}C.srcObject=b,A();let m=b.getVideoTracks()[0]??p??null,U=()=>{o.hasStarted(!0),gr(o),A()},R=()=>{C.srcObject=null,k(!1)};return m&&(m.addEventListener("unmute",U),m.addEventListener("ended",R),m.muted||U()),()=>{m&&(m.removeEventListener("unmute",U),m.removeEventListener("ended",R))}},[g,n,s,A]),vr("div",{className:d,style:{position:"relative",width:"100%",height:"100%"},"data-urun-video":"","data-urun-video-mode":g?"live":"vod",children:[H("video",{ref:L,className:["video-js","vjs-default-skin",u].filter(Boolean).join(" "),playsInline:!0}),w&&H("button",{type:"button",onClick:A,"aria-label":"Tap to play",style:{position:"absolute",inset:0,zIndex:30,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.6)",border:0,cursor:"pointer",color:"#fff"},children:vr("span",{style:{display:"inline-flex",alignItems:"center",gap:8,borderRadius:999,border:"1px solid rgba(255,255,255,0.2)",background:"rgba(255,255,255,0.1)",padding:"10px 20px",fontSize:14,fontWeight:500},children:[H("svg",{viewBox:"0 0 24 24",fill:"currentColor",width:16,height:16,"aria-hidden":!0,children:H("path",{d:"M8 5v14l11-7z"})}),"Tap to play"]})}),T]})}),It=qe(function({name:e,...t},n){let s=pr(e);return H(Sr,{ref:n,...t,track:s})}),qt=qe(function(e,t){return!!e.name&&!e.track&&!e.stream&&!(typeof e.src=="string"&&e.src)?H(It,{ref:t,...e,name:e.name}):H(Sr,{ref:t,...e})});import{forwardRef as jt,useCallback as X,useEffect as br,useImperativeHandle as Dt,useRef as Z}from"react";var de=null;function Vt(){if(typeof window>"u")return null;let r=window;return r.AudioContext??r.webkitAudioContext??null}function pe(){if(de)return de;let r=Vt();return r?(de=new r,de):null}function Ve(){let r=pe();r&&r.state==="suspended"&&r.resume().catch(()=>{})}import{jsx as zt}from"react/jsx-runtime";var Ft=1e3,yr=200;function je(...r){console.debug("[urun-audio]",...r)}var De=jt(function(e,t){let{session:n,stream:s="audio",track:a,controls:i=!1,className:d,onTrack:u,onUnlockChange:c,onAudioElement:h}=e,l=Z(null),f=Z(null),P=Z(null),x=Z(null),T=Z(u);T.current=u;let y=Z(c);y.current=c;let g=X(o=>{P.current!==o&&(P.current=o,y.current?.(o))},[]),v=X(()=>{if(typeof MediaStream>"u")return null;f.current||(f.current=new MediaStream);let o=l.current;return o&&o.srcObject!==f.current&&(o.srcObject=f.current),f.current},[]),S=X(o=>{let p=l.current;if(!p)return;let b=p.play();!b||typeof b.then!="function"||b.then(()=>{p.muted||g(!0)}).catch(C=>{let m=C instanceof Error?C.name:String(C);if(m==="AbortError"){je(`play() aborted (${o}); retrying in ${yr}ms`),x.current&&clearTimeout(x.current),x.current=setTimeout(()=>{x.current=null,S(`${o}:retry`)},yr);return}if(m==="NotAllowedError"){je(`play() blocked pending a user gesture (${o})`),g(!1);return}je(`play() failed (${o})`,C)})},[g]),w=X(o=>{let p=v();if(p){for(let b of p.getAudioTracks())b!==o&&p.removeTrack(b);o&&!p.getAudioTracks().includes(o)&&p.addTrack(o),o&&S("track-attach"),T.current?.(o)}},[v,S]),k=X(()=>{let o=l.current;o&&(v(),o.muted=!1,S("gesture"),Ve(),g(!0))},[v,S,g]);Dt(t,()=>({unlock:k,get unlocked(){return P.current===!0},get element(){return l.current}}),[k]);let L=X(o=>{l.current=o,o&&(o.setAttribute("playsinline",""),o.setAttribute("webkit-playsinline",""),v()),h?.(o)},[v,h]),A=a!==void 0;return br(()=>{if(A){w(a??null);return}if(!n)return;let o=n.stream(s),p=()=>{let R=f.current;return R?R.getAudioTracks()[0]??null:null},b=R=>{if(R!==p()&&(w(R),R)){let q=()=>{p()===R&&w(null)};R.addEventListener("ended",q)}},C=o.track;C&&C.readyState==="live"&&b(C);let m=o.on("track",R=>{R&&R.readyState!=="live"||b(R)}),U=setInterval(()=>{let R=o.track;R&&R.readyState==="live"&&b(R)},Ft);return()=>{m(),clearInterval(U)}},[n,s,A,a,w]),br(()=>()=>{x.current&&clearTimeout(x.current)},[]),zt("audio",{ref:L,className:d,autoPlay:!0,playsInline:!0,controls:i,"data-urun-audio":""})});import{forwardRef as Bt,useCallback as me,useEffect as Ht,useImperativeHandle as $t,useRef as K}from"react";import{sessionFailureFromMediaError as kr}from"@urun-sh/core";import{jsx as Gt}from"react/jsx-runtime";var xr={channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};function Wt(...r){console.debug("[urun-voice]",...r)}var Jt=Bt(function(e,t){let{session:n,stream:s="audio",constraints:a=xr,connectTimeoutMs:i,attempts:d=3,retryDelayMs:u=1500,onActiveChange:c,onError:h,onMicStream:l,onTrack:f,onUnlockChange:P}=e,x=K(null),T=K(null),y=K(!1),g=K(c);g.current=c;let v=K(h);v.current=h;let S=K(l);S.current=l;let w=me(o=>{y.current!==o&&(y.current=o,g.current?.(o))},[]),k=me(()=>{let o=T.current;if(o){for(let p of o.getTracks())p.stop();T.current=null,S.current?.(null)}},[]),L=me(async()=>{k(),w(!1),await n.stream(s).detach().catch(()=>{})},[n,s,k,w]),A=me(async()=>{x.current?.unlock();let o;try{o=await navigator.mediaDevices.getUserMedia({audio:a,video:!1})}catch(m){let U=kr(m,n.status);throw v.current?.(U),U}k(),T.current=o,S.current?.(o);let p=o.getAudioTracks()[0];if(!p){k();let m=kr(Object.assign(new Error("no microphone audio track"),{name:"NotFoundError"}),n.status);throw v.current?.(m),m}n.connect?.();let b;for(let m=1;m<=d;m++)try{await n.whenLive(i!==void 0?{timeout:i}:void 0),await n.stream(s).attach(p),w(!0);return}catch(U){b=U,Wt(`start attempt ${m}/${d} failed`,U),m<d&&await new Promise(R=>setTimeout(R,u))}k(),w(!1);let C=b instanceof Error?b:new Error(String(b??"voice start failed"));throw v.current?.(C),C},[n,s,a,i,d,u,k,w]);return $t(t,()=>({start:A,stop:L,unlock:()=>x.current?.unlock(),get active(){return y.current},get micStream(){return T.current},get audio(){return x.current}}),[A,L]),Ht(()=>k,[k]),Gt(De,{ref:x,session:n,stream:s,onTrack:f,onUnlockChange:P})});import{sessionFailureFromMediaError as Cr}from"@urun-sh/core";import{forwardRef as Xt,useCallback as F,useEffect as Zt,useImperativeHandle as Kt,useRef as V,useState as Yt}from"react";import{jsx as en,jsxs as rn}from"react/jsx-runtime";var Rr={width:{ideal:960},height:{ideal:720},frameRate:{ideal:8}};function Tr(...r){console.debug("[urun-camera]",...r)}var Qt=Xt(function(e,t){let{session:n,stream:s="video",constraints:a,facingMode:i="environment",mirror:d="auto",connectTimeoutMs:u,preview:c=!0,className:h,videoClassName:l,onActiveChange:f,onError:P,onStream:x,onTrack:T,children:y}=e,g=V(null),v=V(null),S=V(null),w=V(!1),k=V(i),[L,A]=Yt(i),o=V(f);o.current=f;let p=V(P);p.current=P;let b=V(x);b.current=x;let C=V(T);C.current=T;let m=F(E=>{w.current!==E&&(w.current=E,o.current?.(E))},[]),U=F(E=>{let N=g.current;N&&(N.muted=!0,N.srcObject=E,E&&N.play()?.catch?.(j=>Tr("preview play() failed",j)))},[]),R=F(()=>{S.current?.(),S.current=null;let E=v.current;if(E){for(let N of E.getTracks())N.stop();v.current=null,b.current?.(null),C.current?.(null)}U(null)},[U]),q=F(async E=>{let N=v.current,j=S.current,_;try{_=await navigator.mediaDevices.getUserMedia({video:{...Rr,...a,facingMode:E},audio:!1})}catch(O){let B=Cr(O,n.status);throw p.current?.(B),B}let M=_.getVideoTracks()[0];if(!M){for(let B of _.getTracks())B.stop();let O=Cr(Object.assign(new Error("no camera video track"),{name:"NotFoundError"}),n.status);throw p.current?.(O),O}v.current=_,k.current=E,A(E),U(_),b.current?.(_);let I=()=>{v.current===_&&(Tr("camera track ended (device removed or permission revoked)"),R(),m(!1))};M.addEventListener("ended",I),S.current=()=>M.removeEventListener("ended",I);try{n.connect?.(),await n.whenLive(u!==void 0?{timeout:u}:void 0),await n.stream(s).attachVideo(M)}catch(O){M.removeEventListener("ended",I);for(let Mr of _.getTracks())Mr.stop();v.current===_&&(v.current=N,S.current=j,U(N),b.current?.(N));let B=O instanceof Error?O:new Error(String(O));throw p.current?.(B),B}if(N&&N!==_){j?.();for(let O of N.getTracks())O.stop()}C.current?.(M),m(!0)},[n,s,a,u,U,R,m]),Se=F(E=>q(E?.facingMode??k.current),[q]),be=F(async E=>{w.current&&k.current===E||await q(E)},[q]),ye=F(()=>q(k.current==="environment"?"user":"environment"),[q]),ke=F(async()=>{R(),m(!1),await n.stream(s).detachVideo().catch(()=>{})},[n,s,R,m]);return Kt(t,()=>({start:Se,stop:ke,flip:ye,setFacingMode:be,get active(){return w.current},get facingMode(){return k.current},get stream(){return v.current},get element(){return g.current}}),[Se,ke,ye,be]),Zt(()=>R,[R]),c?rn("div",{className:h,style:{position:"relative",width:"100%",height:"100%"},"data-urun-camera":"","data-urun-camera-facing":L,children:[en("video",{ref:g,className:l,autoPlay:!0,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"contain",...(d==="auto"?L==="user":d)?{transform:"scaleX(-1)"}:{}}}),y]}):null});import{useEffect as tn,useState as nn}from"react";var Fe={level:0,speaking:!1};function on(r,e={}){let{fftSize:t=512,intervalMs:n=100,speakingThreshold:s=.02}=e,[a,i]=nn(Fe);return tn(()=>{if(!r){i(Fe);return}let d=pe();if(!d||typeof MediaStream>"u")return;let u;r instanceof MediaStream?u=r:(u=new MediaStream,u.addTrack(r));let c,h;try{c=d.createMediaStreamSource(u),h=d.createAnalyser(),h.fftSize=t,c.connect(h)}catch{return}let l=new Uint8Array(h.fftSize),P=setInterval(()=>{h.getByteTimeDomainData(l);let x=0;for(let y=0;y<l.length;y++){let g=(l[y]-128)/128;x+=g*g}let T=Math.sqrt(x/l.length);i(y=>{let g=T>s;return Math.abs(y.level-T)<.005&&y.speaking===g?y:{level:T,speaking:g}})},n);return()=>{clearInterval(P),c.disconnect(),i(Fe)}},[r,t,n,s]),a}import{useEffect as sn,useState as an}from"react";function un(r,e){let[t,n]=an(null);return sn(()=>{if(!r||!e){n(null);return}let s=r.stream(e);return n(s.track),s.on("track",n)},[r,e]),t}import{useCallback as cn,useEffect as ln,useState as Pr}from"react";function ze(r,e){let[t,n]=Pr(null),[s,a]=Pr(!1);ln(()=>{if(!r||!e){n(null),a(!1);return}let d=r.doc(e);n(d.get()??{}),a(d.synced);let u=d.on("change",h=>n(h)),c=d.onSynced(()=>a(!0));return()=>{u(),c()}},[r,e]);let i=cn(d=>{r&&e&&r.doc(e).set(d)},[r,e]);return{snapshot:t,synced:s,set:i}}import{useEffect as dn,useState as pn}from"react";var $=200;function z(r,e,t=200){let n=[...r,e];return n.length>t?n.slice(n.length-t):n}function te(r){if(typeof r=="string")return r;try{return JSON.stringify(r)}catch{return String(r)}}function Be(r){let e=r.trim();if(!e)return{ok:!1,error:"Enter a JSON object."};let t;try{t=JSON.parse(e)}catch(n){return{ok:!1,error:n instanceof Error?n.message:"Invalid JSON."}}return t===null||typeof t!="object"||Array.isArray(t)?{ok:!1,error:"The payload must be a JSON object."}:{ok:!0,value:t}}function He(r,e,t={}){let n=t.cap??200,[s,a]=pn([]);return dn(()=>{if(a([]),!r||!e)return;let i=!0,d=r.stream(e).messages()[Symbol.asyncIterator]();return(async()=>{for(;;){let u=await d.next();if(!i||u.done)break;a(c=>z(c,{at:Date.now(),payload:u.value},n))}})(),()=>{i=!1,d.return?.()}},[r,e,n]),s}import{jsx as fe,jsxs as ne}from"react/jsx-runtime";function mn({session:r,name:e,cap:t,className:n}){let s=He(r,e,{cap:t});return ne("div",{className:["urun-stream-tail",n].filter(Boolean).join(" "),children:[ne("div",{className:"urun-stream-tail-meta",children:[fe("code",{children:e}),ne("span",{className:"urun-stream-tail-count",children:[s.length," messages"]})]}),fe("div",{className:"urun-stream-tail-log",children:s.length===0?ne("span",{className:"urun-stream-tail-empty",children:["Waiting for ",fe("code",{children:e})," messages\u2026"]}):s.map((a,i)=>ne("div",{className:"urun-stream-tail-line",children:[fe("span",{className:"urun-stream-tail-time",children:new Date(a.at).toLocaleTimeString()})," ",te(a.payload)]},`${a.at}-${i}`))})]})}import{useCallback as fn,useState as wr}from"react";import{jsx as W,jsxs as ge}from"react/jsx-runtime";function he({placeholder:r,buttonLabel:e,disabled:t,onApply:n}){let[s,a]=wr(""),[i,d]=wr(null),u=fn(()=>{let c=Be(s);if(!c.ok){d(c.error);return}d(null),n(c.value,s.trim()),a("")},[s,n]);return ge("div",{className:"urun-doc-patch",children:[W("textarea",{className:"urun-doc-patch-input",value:s,onChange:c=>a(c.target.value),placeholder:r,rows:3}),ge("div",{className:"urun-doc-patch-actions",children:[W("button",{type:"button",className:"urun-doc-patch-button",disabled:t||!s.trim(),onClick:u,children:e}),i?W("span",{className:"urun-doc-patch-error",role:"alert",children:i}):null]})]})}function gn({session:r,docKey:e,editable:t=!0,patchPlaceholder:n='{"desired": {"prompt": {"text": "a sunset"}}}',className:s}){let{snapshot:a,synced:i,set:d}=ze(r,e);return ge("div",{className:["urun-doc-panel",s].filter(Boolean).join(" "),children:[ge("div",{className:"urun-doc-panel-meta",children:[W("code",{children:e}),W("span",{className:"urun-doc-panel-synced","data-synced":i?"true":"false",children:i?"synced":"syncing\u2026"})]}),W("pre",{className:"urun-doc-panel-snapshot",children:JSON.stringify(a??{},null,2)}),t?W(he,{placeholder:n,buttonLabel:"Apply patch",disabled:!r,onApply:u=>d(u)}):null]})}import{useEffect as hn,useState as vn}from"react";import{jsx as oe,jsxs as Er}from"react/jsx-runtime";function Ur(r,e=600){return r.length>e?`${r.slice(0,e)}\u2026`:r}function Sn({session:r,docKey:e="control",cap:t=200,className:n}){let[s,a]=vn([]);return hn(()=>(a([]),r?r.doc(e).on("change",d=>{a(u=>z(u,{at:Date.now(),direction:"in",text:Ur(te(d))},t))}):void 0),[r,e,t]),Er("div",{className:["urun-control-sender",n].filter(Boolean).join(" "),children:[oe(he,{placeholder:'{"desired": {"settings": {"values": {}}}}',buttonLabel:`Send to ${e}`,disabled:!r,onApply:(i,d)=>{r?.doc(e).set(i),a(u=>z(u,{at:Date.now(),direction:"out",text:Ur(d)},t))}}),oe("div",{className:"urun-control-sender-log",children:s.length===0?oe("span",{className:"urun-control-sender-empty",children:"Nothing yet."}):[...s].reverse().map((i,d)=>Er("div",{className:"urun-control-sender-line","data-direction":i.direction,children:[oe("span",{className:"urun-control-sender-dir",children:i.direction==="out"?"sent":"change"})," ",oe("span",{className:"urun-control-sender-time",children:new Date(i.at).toLocaleTimeString()})," ",i.text]},`${i.at}-${d}`))})]})}import{useEffect as bn,useState as yn}from"react";import{jsx as ve,jsxs as xn}from"react/jsx-runtime";function kn({session:r,trackNames:e=["video","audio"],docKeys:t=["control"],cap:n=200,className:s}){let[a,i]=yn([]),d=e.join(","),u=t.join(",");return bn(()=>{if(i([]),!r)return;let c=(l,f)=>i(P=>z(P,{at:Date.now(),kind:l,text:f},n)),h=[];h.push(r.onPhase(l=>c("phase",`phase \u2192 ${l.name}`)));for(let l of e){let f=r.stream(l);h.push(f.on("track",P=>c("track",`${l}: ${P?"track arrived":"track ended"}`)))}for(let l of t){let f=r.doc(l);h.push(f.on("change",()=>c("doc",`${l} changed`)))}return()=>h.forEach(l=>l())},[r,d,u,n]),ve("div",{className:["urun-event-spine",s].filter(Boolean).join(" "),children:a.length===0?ve("span",{className:"urun-event-spine-empty",children:"No activity yet \u2014 the spine fills as the session moves through its lifecycle."}):[...a].reverse().map((c,h)=>xn("div",{className:"urun-event-spine-line","data-kind":c.kind,children:[ve("span",{className:"urun-event-spine-kind",children:c.kind})," ",ve("span",{className:"urun-event-spine-time",children:new Date(c.at).toLocaleTimeString()})," ",c.text]},`${c.at}-${h}`))})}import{useEffect as Cn,useState as Tn}from"react";import{jsx as Y,jsxs as Un}from"react/jsx-runtime";var Rn={idle:"idle",queued:"queued",provisioning:"provisioning",connecting:"connecting",live:"live",error:"error",ended:"ended"};function $e(r){let[e,t]=Tn(r?.phase??null);return Cn(()=>{if(!r){t(null);return}return r.onPhase(t)},[r]),e}function Pn({session:r,className:e}){let t=$e(r),n=t?.name??"idle",s=t?.name==="queued"&&t.queue?`pos ${t.queue.position} / depth ${t.queue.depth}`:t?.name==="error"&&t.error?t.error.reason:null;return Un("span",{className:["urun-session-status",e].filter(Boolean).join(" "),"data-phase":n,children:[Y("span",{className:"urun-session-status-dot","data-phase":n}),Y("span",{className:"urun-session-status-label",children:Rn[n]}),s?Y("span",{className:"urun-session-status-detail",children:s}):null]})}function wn({session:r,children:e,fallback:t,className:n}){let s=$e(r);if(s?.name==="live")return Y("div",{className:["urun-session-gate",n].filter(Boolean).join(" "),children:e});let a=t?t(s):Y("span",{className:"urun-session-gate-fallback",children:s?.name==="error"?`Session ${s.error?.reason??"failed"}.`:s?.name==="ended"?"Session ended.":"Waiting for a live session\u2026"});return Y("div",{className:["urun-session-gate",n].filter(Boolean).join(" "),children:a})}export{it as ComponentRenderer,Rr as DEFAULT_CAMERA_CONSTRAINTS,$ as DEFAULT_LOG_CAP,xr as DEFAULT_VOICE_CONSTRAINTS,he as DocPatchForm,yt as ImageFrame,bt as ImageFrameSchema,Ct as MetricsPanel,xt as MetricsPanelSchema,lt as ProgressCard,ct as ProgressCardSchema,mt as StatusBadge,dt as StatusBadgeSchema,vt as TextStream,ht as TextStreamSchema,De as UrunAudio,_r as UrunAuthProvider,Qt as UrunCamera,Sn as UrunControlSender,gn as UrunDocPanel,ee as UrunErrorBoundary,kn as UrunEventSpine,Or as UrunJwtProvider,Fr as UrunProvider,wn as UrunSessionGate,Pn as UrunSessionStatus,mn as UrunStreamTail,qt as UrunVideo,Jt as UrunVoice,xe as authMode,te as formatPayload,pe as getUrunAudioContext,Be as parseJsonObject,z as pushCapped,at as registerComponent,Ve as resumeUrunAudioContext,Q as urunPublicEnv,Jr as useApp,st as useChat,rt as useCompletion,cr as useImageFrame,lr as useMetricsPanel,tr as useProgressCard,Kr as useRequest,ze as useSessionDoc,$e as useSessionPhase,un as useSessionTrack,or as useStatusBadge,He as useStreamMessages,ir as useTextStream,on as useUrunAudioLevel,Ce as useUrunAuth,Nr as usesWorkOSAuth};
|
package/dist/styles.css
CHANGED
|
@@ -251,3 +251,151 @@
|
|
|
251
251
|
.urun-video-live .vjs-poster {
|
|
252
252
|
background-color: transparent;
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
/* ── Session workbench building blocks ─────────────────────────────────────
|
|
256
|
+
* Unstyled-by-default debug/steer blocks: minimal chrome via CSS custom
|
|
257
|
+
* properties so a consumer can theme with --urun-wb-* or override .urun-*. */
|
|
258
|
+
.urun-stream-tail,
|
|
259
|
+
.urun-doc-panel,
|
|
260
|
+
.urun-control-sender,
|
|
261
|
+
.urun-event-spine {
|
|
262
|
+
display: flex;
|
|
263
|
+
flex-direction: column;
|
|
264
|
+
gap: 6px;
|
|
265
|
+
font-size: 12px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.urun-stream-tail-meta,
|
|
269
|
+
.urun-doc-panel-meta {
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
gap: 8px;
|
|
273
|
+
color: var(--urun-wb-muted, #8a8a8a);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.urun-stream-tail-log,
|
|
277
|
+
.urun-control-sender-log {
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-direction: column;
|
|
280
|
+
gap: 2px;
|
|
281
|
+
max-height: 220px;
|
|
282
|
+
overflow: auto;
|
|
283
|
+
padding: 6px;
|
|
284
|
+
border-radius: 6px;
|
|
285
|
+
background: var(--urun-wb-log-bg, rgba(0, 0, 0, 0.25));
|
|
286
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
287
|
+
font-size: 11px;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.urun-stream-tail-time,
|
|
291
|
+
.urun-control-sender-time,
|
|
292
|
+
.urun-event-spine-time {
|
|
293
|
+
color: var(--urun-wb-muted, #8a8a8a);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.urun-doc-panel-snapshot {
|
|
297
|
+
margin: 0;
|
|
298
|
+
padding: 8px;
|
|
299
|
+
max-height: 220px;
|
|
300
|
+
overflow: auto;
|
|
301
|
+
border-radius: 6px;
|
|
302
|
+
background: var(--urun-wb-log-bg, rgba(0, 0, 0, 0.25));
|
|
303
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
304
|
+
font-size: 11px;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.urun-doc-patch,
|
|
308
|
+
.urun-control-sender {
|
|
309
|
+
display: flex;
|
|
310
|
+
flex-direction: column;
|
|
311
|
+
gap: 6px;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.urun-doc-patch-input {
|
|
315
|
+
width: 100%;
|
|
316
|
+
resize: vertical;
|
|
317
|
+
border-radius: 6px;
|
|
318
|
+
border: 1px solid var(--urun-wb-border, rgba(128, 128, 128, 0.4));
|
|
319
|
+
background: var(--urun-wb-input-bg, transparent);
|
|
320
|
+
color: inherit;
|
|
321
|
+
padding: 6px 8px;
|
|
322
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
323
|
+
font-size: 12px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.urun-doc-patch-actions {
|
|
327
|
+
display: flex;
|
|
328
|
+
align-items: center;
|
|
329
|
+
gap: 8px;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.urun-doc-patch-button,
|
|
333
|
+
.urun-mic-button {
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
border-radius: 6px;
|
|
336
|
+
border: 1px solid var(--urun-wb-border, rgba(128, 128, 128, 0.4));
|
|
337
|
+
background: var(--urun-wb-accent, #24db49);
|
|
338
|
+
color: var(--urun-wb-accent-fg, #04120a);
|
|
339
|
+
padding: 4px 12px;
|
|
340
|
+
font-size: 12px;
|
|
341
|
+
font-weight: 600;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.urun-doc-patch-button:disabled {
|
|
345
|
+
cursor: default;
|
|
346
|
+
opacity: 0.5;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.urun-doc-patch-error,
|
|
350
|
+
.urun-mic-error {
|
|
351
|
+
color: var(--urun-wb-danger, #e5484d);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.urun-event-spine {
|
|
355
|
+
max-height: 260px;
|
|
356
|
+
overflow: auto;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.urun-event-spine-line,
|
|
360
|
+
.urun-control-sender-line {
|
|
361
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
362
|
+
font-size: 11px;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.urun-event-spine-kind,
|
|
366
|
+
.urun-control-sender-dir {
|
|
367
|
+
display: inline-block;
|
|
368
|
+
min-width: 3.5em;
|
|
369
|
+
color: var(--urun-wb-muted, #8a8a8a);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/* Session status pill + gate */
|
|
373
|
+
.urun-session-status {
|
|
374
|
+
display: inline-flex;
|
|
375
|
+
align-items: center;
|
|
376
|
+
gap: 6px;
|
|
377
|
+
font-size: 12px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.urun-session-status-dot {
|
|
381
|
+
width: 8px;
|
|
382
|
+
height: 8px;
|
|
383
|
+
border-radius: 50%;
|
|
384
|
+
background: var(--urun-wb-muted, #8a8a8a);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.urun-session-status-dot[data-phase='live'] {
|
|
388
|
+
background: var(--urun-wb-accent, #24db49);
|
|
389
|
+
}
|
|
390
|
+
.urun-session-status-dot[data-phase='connecting'],
|
|
391
|
+
.urun-session-status-dot[data-phase='provisioning'],
|
|
392
|
+
.urun-session-status-dot[data-phase='queued'] {
|
|
393
|
+
background: var(--urun-wb-warn, #ffb224);
|
|
394
|
+
}
|
|
395
|
+
.urun-session-status-dot[data-phase='error'] {
|
|
396
|
+
background: var(--urun-wb-danger, #e5484d);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.urun-session-status-detail {
|
|
400
|
+
color: var(--urun-wb-muted, #8a8a8a);
|
|
401
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@urun-sh/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "React bindings for the urun TypeScript SDK",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"dev": "tsup --watch"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@urun-sh/core": "^0.2.
|
|
51
|
+
"@urun-sh/core": "^0.2.5",
|
|
52
52
|
"@workos-inc/authkit-nextjs": "^3.0.0",
|
|
53
53
|
"@workos-inc/authkit-react": "^0.15.0 || ^0.16.0",
|
|
54
54
|
"next": "^15.0.0 || ^16.0.0",
|