sos-portal-components-react 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,12 +3,57 @@ export function createLiveKitRealtimeCallClient(dependencies) {
3
3
  const loadLiveKit = dependencies.loadLiveKit ?? (() => import('livekit-client'));
4
4
  const createMediaStream = dependencies.createMediaStream ?? (() => new MediaStream());
5
5
  async function connect(input) {
6
- const [liveKit, grant] = await Promise.all([loadLiveKit(), dependencies.issueSession(input)]);
6
+ // Establish browser capability before creating a persisted invitation.
7
+ const liveKit = await loadLiveKit();
8
+ const grant = await dependencies.issueSession(input);
7
9
  const room = new liveKit.Room({ adaptiveStream: true, dynacast: true });
8
10
  const localStream = createMediaStream();
9
11
  const remoteStream = createMediaStream();
10
12
  let resolveAnswered;
11
13
  const answered = new Promise(resolve => { resolveAnswered = resolve; });
14
+ let resolveEnded, rejectEnded;
15
+ const ended = new Promise((resolve, reject) => { resolveEnded = resolve; rejectEnded = reject; });
16
+ void ended.catch(() => undefined); // A disconnect may precede the host receiving its session; retain the original rejection for that host.
17
+ let closing = false, connected = false, disconnected = false, released = false, pendingEnd;
18
+ let timer;
19
+ function end(outcome) {
20
+ if (pendingEnd)
21
+ return pendingEnd;
22
+ closing = true;
23
+ clearTimeout(timer);
24
+ pendingEnd = (async () => {
25
+ const failures = [];
26
+ if (!released) {
27
+ released = true;
28
+ const tracks = new Set([...localStream.getTracks(), ...remoteStream.getTracks(), ...Array.from(room.localParticipant.trackPublications.values(), publication => publication.track?.mediaStreamTrack).filter((track) => Boolean(track))]);
29
+ for (const track of tracks)
30
+ track.stop();
31
+ }
32
+ try {
33
+ if (!disconnected) {
34
+ await room.disconnect();
35
+ disconnected = true;
36
+ }
37
+ }
38
+ catch (error) {
39
+ failures.push(error);
40
+ }
41
+ try {
42
+ await dependencies.endCall({ conversation: input.conversation, callId: grant.callId, ...(outcome ? { outcome } : {}) });
43
+ }
44
+ catch (error) {
45
+ failures.push(error);
46
+ }
47
+ if (failures.length)
48
+ throw failures.length === 1 ? failures[0] : new AggregateError(failures, 'portal_rtc_close_failed');
49
+ resolveEnded();
50
+ })().catch(error => { pendingEnd = undefined; rejectEnded(error); throw error; });
51
+ return pendingEnd;
52
+ }
53
+ const remoteEnded = () => { if (!closing)
54
+ void end(connected ? undefined : 'cancelled').catch(() => undefined); };
55
+ room.on(liveKit.RoomEvent.ParticipantDisconnected, remoteEnded);
56
+ room.on(liveKit.RoomEvent.Disconnected, remoteEnded);
12
57
  room.on(liveKit.RoomEvent.TrackSubscribed, track => {
13
58
  const mediaTrack = track.mediaStreamTrack;
14
59
  if (mediaTrack)
@@ -16,24 +61,47 @@ export function createLiveKitRealtimeCallClient(dependencies) {
16
61
  resolveAnswered?.();
17
62
  resolveAnswered = undefined;
18
63
  });
19
- await room.connect(grant.serverUrl, grant.participantToken);
20
- if (input.media.includes('audio'))
21
- await room.localParticipant.setMicrophoneEnabled(true);
22
- if (input.media.includes('video'))
23
- await room.localParticipant.setCameraEnabled(true);
24
- for (const publication of room.localParticipant.trackPublications.values()) {
25
- const mediaTrack = publication.track?.mediaStreamTrack;
26
- if (mediaTrack)
27
- localStream.addTrack(mediaTrack);
64
+ try {
65
+ await room.connect(grant.serverUrl, grant.participantToken);
66
+ connected = true;
67
+ if (!closing && input.media.includes('audio'))
68
+ await room.localParticipant.setMicrophoneEnabled(true);
69
+ if (!closing && input.media.includes('video'))
70
+ await room.localParticipant.setCameraEnabled(true);
71
+ if (!closing)
72
+ for (const publication of room.localParticipant.trackPublications.values()) {
73
+ const mediaTrack = publication.track?.mediaStreamTrack;
74
+ if (mediaTrack)
75
+ localStream.addTrack(mediaTrack);
76
+ }
77
+ }
78
+ catch (error) {
79
+ try {
80
+ await end('cancelled');
81
+ }
82
+ catch (closeError) {
83
+ throw new AggregateError([error, closeError], 'portal_rtc_connection_and_history_failed');
84
+ }
85
+ throw error;
86
+ }
87
+ async function watch() {
88
+ if (closing || !dependencies.readCallState)
89
+ return;
90
+ try {
91
+ const state = await dependencies.readCallState({ conversation: input.conversation, callId: grant.callId });
92
+ if (Object.values(PortalRtcCallState).includes(state) && state !== PortalRtcCallState.Ringing && state !== PortalRtcCallState.Received) {
93
+ await end(state === 'cancelled' || state === 'missed' ? state : undefined);
94
+ return;
95
+ }
96
+ }
97
+ catch { /* A failed read is not an end state. A close failure remains on ended for the host to handle/retry. */ }
98
+ if (!closing)
99
+ timer = setTimeout(() => void watch(), 2000);
28
100
  }
101
+ if (dependencies.readCallState && !closing)
102
+ timer = setTimeout(() => void watch(), 2000);
29
103
  return Object.freeze({
30
- callId: grant.callId, localStream, remoteStream, answered,
31
- async end(outcome) {
32
- room.disconnect();
33
- for (const track of localStream.getTracks())
34
- track.stop();
35
- await dependencies.endCall({ conversation: input.conversation, callId: grant.callId, ...(outcome ? { outcome } : {}) });
36
- },
104
+ callId: grant.callId, localStream, remoteStream, answered, ended, end,
37
105
  });
38
106
  }
39
107
  return {
@@ -41,4 +109,5 @@ export function createLiveKitRealtimeCallClient(dependencies) {
41
109
  accept(input) { return connect(input); },
42
110
  };
43
111
  }
112
+ import { PortalRtcCallState } from 'sos-data-utils-ts/portal-rtc-call';
44
113
  //# sourceMappingURL=LiveKitRealtimeCallClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveKitRealtimeCallClient.js","sourceRoot":"","sources":["../src/LiveKitRealtimeCallClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LiveKitRealtimeCallClient.js","sourceRoot":"","sources":["../src/LiveKitRealtimeCallClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export type PushNotificationRegistrationCopy = Readonly<{
2
+ title: string;
3
+ description: string;
4
+ enable: string;
5
+ disable: string;
6
+ enabled: string;
7
+ disabled: string;
8
+ unavailable: string;
9
+ denied: string;
10
+ otherDevice: string;
11
+ revoke: string;
12
+ total: string;
13
+ }>;
14
+ export type PushNotificationRegistrationProps = Readonly<{
15
+ copy: PushNotificationRegistrationCopy;
16
+ status: 'enabled' | 'disabled' | 'unavailable' | 'denied';
17
+ devices: readonly Readonly<{
18
+ keyId: string;
19
+ }>[];
20
+ currentKeyId?: string;
21
+ busy?: boolean;
22
+ progress?: string;
23
+ error?: string;
24
+ className?: string;
25
+ actionClassName?: string;
26
+ onEnable(): void | Promise<void>;
27
+ onRevoke(keyId: string): void | Promise<void>;
28
+ }>;
29
+ /** Shared controlled presentation; the host supplies the browser/native registration and owning BFF. */
30
+ export declare function PushNotificationRegistration({ copy, status, devices, currentKeyId, busy, progress, error, className, actionClassName, onEnable, onRevoke }: PushNotificationRegistrationProps): import("react").JSX.Element;
31
+ //# sourceMappingURL=PushNotificationRegistration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PushNotificationRegistration.d.ts","sourceRoot":"","sources":["../src/PushNotificationRegistration.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,gCAAgC,GAAC,QAAQ,CAAC;IACpD,KAAK,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAA;IAC3F,WAAW,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAA;CAC/E,CAAC,CAAA;AACF,MAAM,MAAM,iCAAiC,GAAC,QAAQ,CAAC;IACrD,IAAI,EAAC,gCAAgC,CAAA;IACrC,MAAM,EAAC,SAAS,GAAC,UAAU,GAAC,aAAa,GAAC,QAAQ,CAAA;IAClD,OAAO,EAAC,SAAS,QAAQ,CAAC;QAAC,KAAK,EAAC,MAAM,CAAA;KAAC,CAAC,EAAE,CAAA;IAC3C,YAAY,CAAC,EAAC,MAAM,CAAA;IACpB,IAAI,CAAC,EAAC,OAAO,CAAA;IACb,QAAQ,CAAC,EAAC,MAAM,CAAA;IAChB,KAAK,CAAC,EAAC,MAAM,CAAA;IACb,SAAS,CAAC,EAAC,MAAM,CAAA;IACjB,eAAe,CAAC,EAAC,MAAM,CAAA;IACvB,QAAQ,IAAG,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAC,MAAM,GAAE,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1C,CAAC,CAAA;AACF,wGAAwG;AACxG,wBAAgB,4BAA4B,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,YAAY,EAAC,IAAI,EAAC,QAAQ,EAAC,KAAK,EAAC,SAAS,EAAC,eAAe,EAAC,QAAQ,EAAC,QAAQ,EAAC,EAAC,iCAAiC,+BAahL"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ /** Shared controlled presentation; the host supplies the browser/native registration and owning BFF. */
5
+ export function PushNotificationRegistration({ copy, status, devices, currentKeyId, busy, progress, error, className, actionClassName, onEnable, onRevoke }) {
6
+ const id = useId();
7
+ return _jsxs("details", { className: className, children: [_jsx("summary", { id: id, children: copy.title }), _jsxs("section", { "aria-labelledby": id, "aria-busy": busy, children: [_jsx("p", { children: copy.description }), _jsx("p", { role: "status", children: busy && progress ? progress : copy[status] }), status === 'disabled' ? _jsx("button", { type: "button", disabled: busy, className: actionClassName, onClick: () => { if (!busy)
8
+ void onEnable(); }, children: copy.enable }) : null, status === 'enabled' && currentKeyId ? _jsx("button", { type: "button", disabled: busy, className: actionClassName, onClick: () => { if (!busy)
9
+ void onRevoke(currentKeyId); }, children: copy.disable }) : null, _jsxs("p", { children: [copy.total, ": ", devices.length] }), devices.filter(device => device.keyId !== currentKeyId).length ? _jsx("ul", { children: devices.filter(device => device.keyId !== currentKeyId).map((device, index) => _jsxs("li", { children: [copy.otherDevice, " ", index + 1, " ", _jsx("button", { type: "button", disabled: busy, className: actionClassName, onClick: () => { if (!busy)
10
+ void onRevoke(device.keyId); }, children: copy.revoke })] }, device.keyId)) }) : null, error ? _jsx("p", { role: "alert", children: error }) : null] })] });
11
+ }
12
+ //# sourceMappingURL=PushNotificationRegistration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PushNotificationRegistration.js","sourceRoot":"","sources":["../src/PushNotificationRegistration.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AACZ,OAAO,EAAC,KAAK,EAAC,MAAM,OAAO,CAAA;AAkB3B,wGAAwG;AACxG,MAAM,UAAU,4BAA4B,CAAC,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,YAAY,EAAC,IAAI,EAAC,QAAQ,EAAC,KAAK,EAAC,SAAS,EAAC,eAAe,EAAC,QAAQ,EAAC,QAAQ,EAAmC;IAC/K,MAAM,EAAE,GAAC,KAAK,EAAE,CAAA;IAChB,OAAO,mBAAS,SAAS,EAAE,SAAS,aAClC,kBAAS,EAAE,EAAE,EAAE,YAAG,IAAI,CAAC,KAAK,GAAW,EACvC,sCAA0B,EAAE,eAAa,IAAI,aAC3C,sBAAI,IAAI,CAAC,WAAW,GAAK,EAAA,YAAG,IAAI,EAAC,QAAQ,YAAE,IAAI,IAAE,QAAQ,CAAA,CAAC,CAAA,QAAQ,CAAA,CAAC,CAAA,IAAI,CAAC,MAAM,CAAC,GAAK,EACnF,MAAM,KAAG,UAAU,CAAA,CAAC,CAAA,iBAAQ,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,GAAE,EAAE,GAAC,IAAG,CAAC,IAAI;4BAAC,KAAK,QAAQ,EAAE,CAAA,CAAA,CAAC,YAAG,IAAI,CAAC,MAAM,GAAU,CAAA,CAAC,CAAA,IAAI,EAC1J,MAAM,KAAG,SAAS,IAAE,YAAY,CAAA,CAAC,CAAA,iBAAQ,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,GAAE,EAAE,GAAC,IAAG,CAAC,IAAI;4BAAC,KAAK,QAAQ,CAAC,YAAY,CAAC,CAAA,CAAA,CAAC,YAAG,IAAI,CAAC,OAAO,GAAU,CAAA,CAAC,CAAA,IAAI,EACrL,wBAAI,IAAI,CAAC,KAAK,QAAI,OAAO,CAAC,MAAM,IAAK,EACpC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAA,EAAE,CAAA,MAAM,CAAC,KAAK,KAAG,YAAY,CAAC,CAAC,MAAM,CAAA,CAAC,CAAA,uBAAK,OAAO,CAAC,MAAM,CAAC,MAAM,CAAA,EAAE,CAAA,MAAM,CAAC,KAAK,KAAG,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAC,KAAK,EAAC,EAAE,CAAA,yBAAwB,IAAI,CAAC,WAAW,OAAG,KAAK,GAAC,CAAC,OAAE,iBAAQ,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,GAAE,EAAE,GAAC,IAAG,CAAC,IAAI;wCAAC,KAAK,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,CAAA,CAAC,YAAG,IAAI,CAAC,MAAM,GAAU,KAAxL,MAAM,CAAC,KAAK,CAAiL,CAAC,GAAM,CAAA,CAAC,CAAA,IAAI,EAC1V,KAAK,CAAA,CAAC,CAAA,YAAG,IAAI,EAAC,OAAO,YAAE,KAAK,GAAK,CAAA,CAAC,CAAA,IAAI,IAC/B,IACF,CAAA;AACZ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from './SubjectConversationChat.js';
2
2
  export * from './DeviceAssistancePreferences.js';
3
3
  export * from './LiveKitRealtimeCallClient.js';
4
+ export * from './EmergencyContactCardDirectory.js';
5
+ export * from './PushNotificationRegistration.js';
6
+ export * from './useRealtimeCallSessionLifecycle.js';
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,kCAAkC,CAAA;AAChD,cAAc,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,kCAAkC,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,sCAAsC,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from './SubjectConversationChat.js';
2
2
  export * from './DeviceAssistancePreferences.js';
3
3
  export * from './LiveKitRealtimeCallClient.js';
4
+ export * from './EmergencyContactCardDirectory.js';
5
+ export * from './PushNotificationRegistration.js';
6
+ export * from './useRealtimeCallSessionLifecycle.js';
4
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,kCAAkC,CAAA;AAChD,cAAc,gCAAgC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAA;AAC5C,cAAc,kCAAkC,CAAA;AAChD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,sCAAsC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { RealtimeCallSession, RealtimeCallEndOutcome } from './LiveKitRealtimeCallClient.js';
2
+ /** Shared profile-owned media lifetime; hosts retain their own state and error presentation. */
3
+ export declare function useRealtimeCallSessionLifecycle(session: RealtimeCallSession | undefined, callbacks: Readonly<{
4
+ onEnded: (session: RealtimeCallSession) => void;
5
+ onError: (error: unknown, session: RealtimeCallSession) => void;
6
+ }>): (target: RealtimeCallSession, outcome?: RealtimeCallEndOutcome) => Promise<void>;
7
+ //# sourceMappingURL=useRealtimeCallSessionLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRealtimeCallSessionLifecycle.d.ts","sourceRoot":"","sources":["../src/useRealtimeCallSessionLifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,mBAAmB,EAAC,sBAAsB,EAAC,MAAM,gCAAgC,CAAA;AAE9F,gGAAgG;AAChG,wBAAgB,+BAA+B,CAAC,OAAO,EAAC,mBAAmB,GAAC,SAAS,EAAC,SAAS,EAAC,QAAQ,CAAC;IACvG,OAAO,EAAC,CAAC,OAAO,EAAC,mBAAmB,KAAG,IAAI,CAAA;IAC3C,OAAO,EAAC,CAAC,KAAK,EAAC,OAAO,EAAC,OAAO,EAAC,mBAAmB,KAAG,IAAI,CAAA;CAC1D,CAAC,YAGqC,mBAAmB,YAAU,sBAAsB,mBAwBzF"}
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+ import { useCallback, useEffect, useRef } from 'react';
3
+ /** Shared profile-owned media lifetime; hosts retain their own state and error presentation. */
4
+ export function useRealtimeCallSessionLifecycle(session, callbacks) {
5
+ const latest = useRef(callbacks), mountedSession = useRef(undefined);
6
+ const closing = useRef(new WeakSet());
7
+ const endSession = useCallback((target, outcome) => {
8
+ closing.current.add(target);
9
+ return target.end(outcome);
10
+ }, []);
11
+ useEffect(() => { latest.current = callbacks; }, [callbacks]);
12
+ useEffect(() => {
13
+ if (!session)
14
+ return;
15
+ mountedSession.current = session;
16
+ let active = true;
17
+ void session.ended?.then(() => { closing.current.add(session); if (active)
18
+ latest.current.onEnded(session); }, error => { closing.current.add(session); if (active)
19
+ latest.current.onError(error, session); });
20
+ return () => {
21
+ active = false;
22
+ if (mountedSession.current === session)
23
+ mountedSession.current = undefined;
24
+ // React Strict Mode replays mount effects synchronously. End only if this
25
+ // exact session was not mounted again; a replacement/closed profile ends it.
26
+ queueMicrotask(() => {
27
+ if (mountedSession.current !== session && !closing.current.has(session)) {
28
+ closing.current.add(session);
29
+ void Promise.resolve(session.end()).catch(() => undefined);
30
+ }
31
+ });
32
+ };
33
+ }, [session]);
34
+ return endSession;
35
+ }
36
+ //# sourceMappingURL=useRealtimeCallSessionLifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRealtimeCallSessionLifecycle.js","sourceRoot":"","sources":["../src/useRealtimeCallSessionLifecycle.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAAC,WAAW,EAAC,SAAS,EAAC,MAAM,EAAC,MAAM,OAAO,CAAA;AAGlD,gGAAgG;AAChG,MAAM,UAAU,+BAA+B,CAAC,OAAqC,EAAC,SAGpF;IACA,MAAM,MAAM,GAAC,MAAM,CAAC,SAAS,CAAC,EAAC,cAAc,GAAC,MAAM,CAAgC,SAAS,CAAC,CAAA;IAC9F,MAAM,OAAO,GAAC,MAAM,CAAC,IAAI,OAAO,EAAuB,CAAC,CAAA;IACxD,MAAM,UAAU,GAAC,WAAW,CAAC,CAAC,MAA0B,EAAC,OAA+B,EAAC,EAAE;QACzF,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC3B,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC,EAAC,EAAE,CAAC,CAAA;IACL,SAAS,CAAC,GAAE,EAAE,GAAC,MAAM,CAAC,OAAO,GAAC,SAAS,CAAA,CAAA,CAAC,EAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IACrD,SAAS,CAAC,GAAE,EAAE;QACZ,IAAG,CAAC,OAAO;YAAC,OAAM;QAClB,cAAc,CAAC,OAAO,GAAC,OAAO,CAAA;QAC9B,IAAI,MAAM,GAAC,IAAI,CAAA;QACf,KAAK,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAE,EAAE,GAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA,IAAG,MAAM;YAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA,CAAA,CAAC,EAAC,KAAK,CAAA,EAAE,GAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA,IAAG,MAAM;YAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAC,OAAO,CAAC,CAAA,CAAA,CAAC,CAAC,CAAA;QAC5L,OAAM,GAAE,EAAE;YACR,MAAM,GAAC,KAAK,CAAA;YACZ,IAAG,cAAc,CAAC,OAAO,KAAG,OAAO;gBAAC,cAAc,CAAC,OAAO,GAAC,SAAS,CAAA;YACpE,0EAA0E;YAC1E,6EAA6E;YAC7E,cAAc,CAAC,GAAE,EAAE;gBACjB,IAAG,cAAc,CAAC,OAAO,KAAG,OAAO,IAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAC,CAAC;oBAClE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBAC5B,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,GAAE,EAAE,CAAA,SAAS,CAAC,CAAA;gBAC1D,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAA;IACZ,OAAO,UAAU,CAAA;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,96 +1,96 @@
1
- {
2
- "name": "sos-portal-components-react",
3
- "version": "0.3.0",
4
- "description": "Shared portal UI for base components",
5
- "license": "Apache-2.0",
6
- "type": "module",
7
- "main": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- "./device-assistance-preferences": {
11
- "types": "./dist/DeviceAssistancePreferences.d.ts",
12
- "default": "./dist/DeviceAssistancePreferences.js"
13
- },
14
- ".": {
15
- "types": "./dist/index.d.ts",
16
- "default": "./dist/index.js"
17
- },
18
- "./subject-conversation-chat": {
19
- "types": "./dist/SubjectConversationChat.d.ts",
20
- "default": "./dist/SubjectConversationChat.js"
21
- }
22
- },
23
- "files": [
24
- "dist",
25
- "README.md",
26
- "CHANGELOG.md"
27
- ],
28
- "scripts": {
29
- "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
30
- "build": "npm run clean && tsc -p tsconfig.build.json",
31
- "typecheck": "tsc -p tsconfig.json --noEmit",
32
- "test": "vitest run",
33
- "check": "npm run typecheck && npm test && npm run build",
34
- "prepack": "npm run check"
35
- },
36
- "engines": {
37
- "node": ">=24.0.0"
38
- },
39
- "peerDependencies": {
40
- "@kesha-antonov/react-native-chat": "^6.0.1",
41
- "livekit-client": ">=2.23.0 <3",
42
- "react": ">=18.3.0",
43
- "react-dom": ">=18.3.0",
44
- "react-native": ">=0.82.0",
45
- "react-native-gesture-handler": ">=3.0.0",
46
- "react-native-keyboard-controller": ">=1.0.0",
47
- "react-native-reanimated": ">=3.0.0",
48
- "react-native-safe-area-context": ">=5.0.0"
49
- },
50
- "peerDependenciesMeta": {
51
- "@kesha-antonov/react-native-chat": {
52
- "optional": true
53
- },
54
- "livekit-client": {
55
- "optional": true
56
- },
57
- "react-native": {
58
- "optional": true
59
- },
60
- "react-native-gesture-handler": {
61
- "optional": true
62
- },
63
- "react-native-keyboard-controller": {
64
- "optional": true
65
- },
66
- "react-native-reanimated": {
67
- "optional": true
68
- },
69
- "react-native-safe-area-context": {
70
- "optional": true
71
- }
72
- },
73
- "dependencies": {
74
- "antifraud-portal-components-react": "0.3.0",
75
- "sos-data-utils-ts": "0.6.29"
76
- },
77
- "devDependencies": {
78
- "@testing-library/react": "^16.3.2",
79
- "@types/node": "22.19.15",
80
- "@types/react": "19.2.17",
81
- "@types/react-dom": "19.2.3",
82
- "jsdom": "26.1.0",
83
- "livekit-client": "2.23.0",
84
- "react": "19.2.8",
85
- "react-dom": "19.2.8",
86
- "typescript": "5.9.3",
87
- "vitest": "4.1.12"
88
- },
89
- "publishConfig": {
90
- "access": "public"
91
- },
92
- "repository": {
93
- "type": "git",
94
- "url": "git+https://github.com/soschain/sos-portal-components-react.git"
95
- }
96
- }
1
+ {
2
+ "name": "sos-portal-components-react",
3
+ "version": "0.3.1",
4
+ "description": "Shared portal UI for base components",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ "./device-assistance-preferences": {
11
+ "types": "./dist/DeviceAssistancePreferences.d.ts",
12
+ "default": "./dist/DeviceAssistancePreferences.js"
13
+ },
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./subject-conversation-chat": {
19
+ "types": "./dist/SubjectConversationChat.d.ts",
20
+ "default": "./dist/SubjectConversationChat.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "CHANGELOG.md"
27
+ ],
28
+ "scripts": {
29
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
30
+ "build": "npm run clean && tsc -p tsconfig.build.json",
31
+ "typecheck": "tsc -p tsconfig.json --noEmit",
32
+ "test": "vitest run --maxWorkers=1",
33
+ "check": "npm run typecheck && npm test && npm run build",
34
+ "prepack": "npm run check"
35
+ },
36
+ "engines": {
37
+ "node": ">=24.0.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@kesha-antonov/react-native-chat": "^6.0.1",
41
+ "livekit-client": ">=2.23.0 <3",
42
+ "react": ">=18.3.0",
43
+ "react-dom": ">=18.3.0",
44
+ "react-native": ">=0.82.0",
45
+ "react-native-gesture-handler": ">=3.0.0",
46
+ "react-native-keyboard-controller": ">=1.0.0",
47
+ "react-native-reanimated": ">=3.0.0",
48
+ "react-native-safe-area-context": ">=5.0.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "@kesha-antonov/react-native-chat": {
52
+ "optional": true
53
+ },
54
+ "livekit-client": {
55
+ "optional": true
56
+ },
57
+ "react-native": {
58
+ "optional": true
59
+ },
60
+ "react-native-gesture-handler": {
61
+ "optional": true
62
+ },
63
+ "react-native-keyboard-controller": {
64
+ "optional": true
65
+ },
66
+ "react-native-reanimated": {
67
+ "optional": true
68
+ },
69
+ "react-native-safe-area-context": {
70
+ "optional": true
71
+ }
72
+ },
73
+ "dependencies": {
74
+ "antifraud-portal-components-react": "0.3.0",
75
+ "sos-data-utils-ts": "0.6.30"
76
+ },
77
+ "devDependencies": {
78
+ "@testing-library/react": "^16.3.2",
79
+ "@types/node": "22.19.15",
80
+ "@types/react": "19.2.17",
81
+ "@types/react-dom": "19.2.3",
82
+ "jsdom": "26.1.0",
83
+ "livekit-client": "2.23.0",
84
+ "react": "19.2.8",
85
+ "react-dom": "19.2.8",
86
+ "typescript": "5.9.3",
87
+ "vitest": "4.1.12"
88
+ },
89
+ "publishConfig": {
90
+ "access": "public"
91
+ },
92
+ "repository": {
93
+ "type": "git",
94
+ "url": "git+https://github.com/soschain/sos-portal-components-react.git"
95
+ }
96
+ }