sos-portal-components-react 0.3.0 → 0.3.2

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.
@@ -4,7 +4,8 @@ export type RealtimeCallSession = Readonly<{
4
4
  callId: string;
5
5
  localStream: MediaStream;
6
6
  remoteStream: MediaStream;
7
- answered: Promise<void>;
7
+ answered: Promise<void>; /** Present on the shared client; optional for retained injected legacy adapters. */
8
+ ended?: Promise<void>;
8
9
  end(outcome?: RealtimeCallEndOutcome): Promise<void>;
9
10
  }>;
10
11
  export type LiveKitJoinSession<Conversation> = Readonly<{
@@ -28,6 +29,10 @@ export declare function createLiveKitRealtimeCallClient<Conversation>(dependenci
28
29
  }>): Promise<void>;
29
30
  loadLiveKit?: () => Promise<LiveKitModule>;
30
31
  createMediaStream?: () => MediaStream;
32
+ readCallState?: (input: Readonly<{
33
+ conversation: Conversation;
34
+ callId: string;
35
+ }>) => Promise<PortalRtcCallState>;
31
36
  }>): {
32
37
  start(input: Readonly<{
33
38
  conversation: Conversation;
@@ -36,7 +41,8 @@ export declare function createLiveKitRealtimeCallClient<Conversation>(dependenci
36
41
  callId: string;
37
42
  localStream: MediaStream;
38
43
  remoteStream: MediaStream;
39
- answered: Promise<void>;
44
+ answered: Promise<void>; /** Present on the shared client; optional for retained injected legacy adapters. */
45
+ ended?: Promise<void>;
40
46
  end(outcome?: RealtimeCallEndOutcome): Promise<void>;
41
47
  }>>;
42
48
  accept(input: Readonly<{
@@ -47,9 +53,11 @@ export declare function createLiveKitRealtimeCallClient<Conversation>(dependenci
47
53
  callId: string;
48
54
  localStream: MediaStream;
49
55
  remoteStream: MediaStream;
50
- answered: Promise<void>;
56
+ answered: Promise<void>; /** Present on the shared client; optional for retained injected legacy adapters. */
57
+ ended?: Promise<void>;
51
58
  end(outcome?: RealtimeCallEndOutcome): Promise<void>;
52
59
  }>>;
53
60
  };
61
+ import { PortalRtcCallState } from 'sos-data-utils-ts/portal-rtc-call';
54
62
  export {};
55
63
  //# sourceMappingURL=LiveKitRealtimeCallClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LiveKitRealtimeCallClient.d.ts","sourceRoot":"","sources":["../src/LiveKitRealtimeCallClient.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,CAAA;AAC3D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,GAAG,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAA;AAClM,MAAM,MAAM,kBAAkB,CAAC,YAAY,IAAI,QAAQ,CAAC;IAAE,YAAY,EAAE,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAAC,CAAA;AAC7I,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAE3G,KAAK,aAAa,GAAG,cAAc,gBAAgB,CAAC,CAAA;AAEpD,yFAAyF;AACzF,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC;IACnF,YAAY,CAAC,KAAK,EAAE,kBAAkB,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACnF,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,sBAAsB,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1C,iBAAiB,CAAC,EAAE,MAAM,WAAW,CAAA;CACtC,CAAC;iBAmCe,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;KAAE,CAAC;gBA/CzC,MAAM;qBAAe,WAAW;sBAAgB,WAAW;kBAAY,OAAO,CAAC,IAAI,CAAC;sBAAgB,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;;kBAgD7K,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;KAAE,CAAC;gBAhD1D,MAAM;qBAAe,WAAW;sBAAgB,WAAW;kBAAY,OAAO,CAAC,IAAI,CAAC;sBAAgB,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;;EAkD9L"}
1
+ {"version":3,"file":"LiveKitRealtimeCallClient.d.ts","sourceRoot":"","sources":["../src/LiveKitRealtimeCallClient.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,CAAA;AAC3D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,oFAAoF;IAAC,KAAK,CAAC,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,GAAG,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAAA;AAC7S,MAAM,MAAM,kBAAkB,CAAC,YAAY,IAAI,QAAQ,CAAC;IAAE,YAAY,EAAE,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAAC,CAAA;AAC7I,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAE3G,KAAK,aAAa,GAAG,cAAc,gBAAgB,CAAC,CAAA;AAEpD,yFAAyF;AACzF,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC;IACnF,YAAY,CAAC,KAAK,EAAE,kBAAkB,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACnF,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,sBAAsB,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1C,iBAAiB,CAAC,EAAE,MAAM,WAAW,CAAA;IACrC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAC,QAAQ,CAAC;QAAC,YAAY,EAAC,YAAY,CAAC;QAAA,MAAM,EAAC,MAAM,CAAA;KAAC,CAAC,KAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACzG,CAAC;iBAwEe,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;KAAE,CAAC;gBArFzC,MAAM;qBAAe,WAAW;sBAAgB,WAAW;kBAAY,OAAO,CAAC,IAAI,CAAC,EAAE,oFAAoF;gBAAQ,OAAO,CAAC,IAAI,CAAC;sBAAgB,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;;kBAsFxR,QAAQ,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;KAAE,CAAC;gBAtF1D,MAAM;qBAAe,WAAW;sBAAgB,WAAW;kBAAY,OAAO,CAAC,IAAI,CAAC,EAAE,oFAAoF;gBAAQ,OAAO,CAAC,IAAI,CAAC;sBAAgB,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;;EAwFzS;AACD,OAAO,EAAC,kBAAkB,EAAC,MAAM,mCAAmC,CAAA"}
@@ -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":"AAQA,yFAAyF;AACzF,MAAM,UAAU,+BAA+B,CAAe,YAK5D;IACA,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAChF,MAAM,iBAAiB,GAAG,YAAY,CAAC,iBAAiB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,WAAW,EAAE,CAAC,CAAA;IAErF,KAAK,UAAU,OAAO,CAAC,KAAuC;QAC5D,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC7F,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACvE,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAA;QACvC,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAA;QACxC,IAAI,eAAyC,CAAA;QAC7C,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,GAAG,eAAe,GAAG,OAAO,CAAA,CAAC,CAAC,CAAC,CAAA;QAC5E,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE;YACjD,MAAM,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAA;YACzC,IAAI,UAAU;gBAAE,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;YACjD,eAAe,EAAE,EAAE,CAAA;YACnB,eAAe,GAAG,SAAS,CAAA;QAC7B,CAAC,CAAC,CAAA;QACF,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAC3D,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAA;QACzF,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACrF,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3E,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,EAAE,gBAAgB,CAAA;YACtD,IAAI,UAAU;gBAAE,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QAClD,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ;YACzD,KAAK,CAAC,GAAG,CAAC,OAAgC;gBACxC,IAAI,CAAC,UAAU,EAAE,CAAA;gBACjB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,SAAS,EAAE;oBAAE,KAAK,CAAC,IAAI,EAAE,CAAA;gBACzD,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;YACzH,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,KAAK,CAAC,KAAoF,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC;QACrH,MAAM,CAAC,KAAoG,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC;KACvI,CAAA;AACH,CAAC"}
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"}
@@ -0,0 +1,32 @@
1
+ export type SubjectCardLocatorValue = Readonly<{
2
+ method: 'card-number' | 'did-qr';
3
+ subjectKind: '' | 'person' | 'animal';
4
+ taxonomyId: string;
5
+ locator: string;
6
+ }>;
7
+ export type SubjectCardLocatorCopy = Readonly<{
8
+ method: string;
9
+ number: string;
10
+ didQr: string;
11
+ subjectKind: string;
12
+ choose: string;
13
+ person: string;
14
+ animal: string;
15
+ species: string;
16
+ taxonomy: string;
17
+ otherSpecies: string;
18
+ value: string;
19
+ }>;
20
+ export type SubjectCardLocatorFieldsProps = Readonly<{
21
+ copy: SubjectCardLocatorCopy;
22
+ value: SubjectCardLocatorValue;
23
+ speciesOptions: readonly Readonly<{
24
+ taxonomyId: string;
25
+ label: string;
26
+ }>[];
27
+ disabled?: boolean;
28
+ onChange(value: SubjectCardLocatorValue): void;
29
+ }>;
30
+ /** Controlled identification fields shared by portal modes; the host resolves and authorizes. */
31
+ export declare function SubjectCardLocatorFields({ copy, value, speciesOptions, disabled, onChange }: SubjectCardLocatorFieldsProps): import("react").JSX.Element;
32
+ //# sourceMappingURL=SubjectCardLocatorFields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubjectCardLocatorFields.d.ts","sourceRoot":"","sources":["../src/SubjectCardLocatorFields.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAC,QAAQ,CAAC;IAC3C,MAAM,EAAC,aAAa,GAAC,QAAQ,CAAA;IAC7B,WAAW,EAAC,EAAE,GAAC,QAAQ,GAAC,QAAQ,CAAA;IAChC,UAAU,EAAC,MAAM,CAAA;IACjB,OAAO,EAAC,MAAM,CAAA;CACf,CAAC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAC,QAAQ,CAAC;IAC1C,MAAM,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAA;IACzE,MAAM,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAA;CAC5F,CAAC,CAAA;AACF,MAAM,MAAM,6BAA6B,GAAC,QAAQ,CAAC;IACjD,IAAI,EAAC,sBAAsB,CAAA;IAC3B,KAAK,EAAC,uBAAuB,CAAA;IAC7B,cAAc,EAAC,SAAS,QAAQ,CAAC;QAAC,UAAU,EAAC,MAAM,CAAC;QAAA,KAAK,EAAC,MAAM,CAAA;KAAC,CAAC,EAAE,CAAA;IACpE,QAAQ,CAAC,EAAC,OAAO,CAAA;IACjB,QAAQ,CAAC,KAAK,EAAC,uBAAuB,GAAE,IAAI,CAAA;CAC7C,CAAC,CAAA;AAEF,iGAAiG;AACjG,wBAAgB,wBAAwB,CAAC,EAAC,IAAI,EAAC,KAAK,EAAC,cAAc,EAAC,QAAQ,EAAC,QAAQ,EAAC,EAAC,6BAA6B,+BAoBnH"}
@@ -0,0 +1,9 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ /** Controlled identification fields shared by portal modes; the host resolves and authorizes. */
4
+ export function SubjectCardLocatorFields({ copy, value, speciesOptions, disabled, onChange }) {
5
+ const animalNumber = value.method === 'card-number' && value.subjectKind === 'animal';
6
+ const otherSpecies = Boolean(value.taxonomyId) && !speciesOptions.some(option => option.taxonomyId === value.taxonomyId);
7
+ return _jsxs("div", { className: "subject-card-locator-fields", children: [_jsxs("label", { children: [copy.method, _jsxs("select", { disabled: disabled, value: value.method, onChange: event => onChange({ ...value, method: event.currentTarget.value, subjectKind: '', taxonomyId: '' }), children: [_jsx("option", { value: "card-number", children: copy.number }), _jsx("option", { value: "did-qr", children: copy.didQr })] })] }), value.method === 'card-number' ? _jsxs("label", { children: [copy.subjectKind, _jsxs("select", { disabled: disabled, value: value.subjectKind, onChange: event => onChange({ ...value, subjectKind: event.currentTarget.value, taxonomyId: '' }), children: [_jsx("option", { value: "", children: copy.choose }), _jsx("option", { value: "person", children: copy.person }), _jsx("option", { value: "animal", children: copy.animal })] })] }) : null, animalNumber ? _jsxs(_Fragment, { children: [_jsxs("label", { children: [copy.species, _jsxs("select", { disabled: disabled, value: otherSpecies ? 'other' : value.taxonomyId, onChange: event => onChange({ ...value, taxonomyId: event.currentTarget.value }), children: [_jsx("option", { value: "", children: copy.choose }), speciesOptions.map(option => _jsx("option", { value: option.taxonomyId, children: option.label }, option.taxonomyId)), _jsx("option", { value: "other", children: copy.otherSpecies })] })] }), otherSpecies ? _jsxs("label", { children: [copy.taxonomy, _jsx("input", { disabled: disabled, inputMode: "numeric", value: value.taxonomyId === 'other' ? '' : value.taxonomyId, onChange: event => onChange({ ...value, taxonomyId: event.currentTarget.value || 'other' }) })] }) : null] }) : null, _jsxs("label", { children: [copy.value, _jsx("input", { disabled: disabled, autoComplete: "off", inputMode: value.method === 'card-number' ? 'numeric' : 'text', value: value.locator, onChange: event => onChange({ ...value, locator: event.currentTarget.value }) })] })] });
8
+ }
9
+ //# sourceMappingURL=SubjectCardLocatorFields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubjectCardLocatorFields.js","sourceRoot":"","sources":["../src/SubjectCardLocatorFields.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export * from './SubjectConversationChat.js';
2
2
  export * from './DeviceAssistancePreferences.js';
3
+ export * from './SubjectCardLocatorFields.js';
3
4
  export * from './LiveKitRealtimeCallClient.js';
5
+ export * from './EmergencyContactCardDirectory.js';
6
+ export * from './PushNotificationRegistration.js';
7
+ export * from './useRealtimeCallSessionLifecycle.js';
4
8
  //# 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,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,sCAAsC,CAAA"}
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  export * from './SubjectConversationChat.js';
2
2
  export * from './DeviceAssistancePreferences.js';
3
+ export * from './SubjectCardLocatorFields.js';
3
4
  export * from './LiveKitRealtimeCallClient.js';
5
+ export * from './EmergencyContactCardDirectory.js';
6
+ export * from './PushNotificationRegistration.js';
7
+ export * from './useRealtimeCallSessionLifecycle.js';
4
8
  //# 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,+BAA+B,CAAA;AAC7C,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,100 @@
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.2",
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
+ "./subject-card-locator-fields": {
11
+ "types": "./dist/SubjectCardLocatorFields.d.ts",
12
+ "default": "./dist/SubjectCardLocatorFields.js"
13
+ },
14
+ "./device-assistance-preferences": {
15
+ "types": "./dist/DeviceAssistancePreferences.d.ts",
16
+ "default": "./dist/DeviceAssistancePreferences.js"
17
+ },
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./subject-conversation-chat": {
23
+ "types": "./dist/SubjectConversationChat.d.ts",
24
+ "default": "./dist/SubjectConversationChat.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "CHANGELOG.md"
31
+ ],
32
+ "scripts": {
33
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
34
+ "build": "npm run clean && tsc -p tsconfig.build.json",
35
+ "typecheck": "tsc -p tsconfig.json --noEmit",
36
+ "test": "vitest run --maxWorkers=1",
37
+ "check": "npm run typecheck && npm test && npm run build",
38
+ "prepack": "npm run check"
39
+ },
40
+ "engines": {
41
+ "node": ">=24.0.0"
42
+ },
43
+ "peerDependencies": {
44
+ "@kesha-antonov/react-native-chat": "^6.0.1",
45
+ "livekit-client": ">=2.23.0 <3",
46
+ "react": ">=18.3.0",
47
+ "react-dom": ">=18.3.0",
48
+ "react-native": ">=0.82.0",
49
+ "react-native-gesture-handler": ">=3.0.0",
50
+ "react-native-keyboard-controller": ">=1.0.0",
51
+ "react-native-reanimated": ">=3.0.0",
52
+ "react-native-safe-area-context": ">=5.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "@kesha-antonov/react-native-chat": {
56
+ "optional": true
57
+ },
58
+ "livekit-client": {
59
+ "optional": true
60
+ },
61
+ "react-native": {
62
+ "optional": true
63
+ },
64
+ "react-native-gesture-handler": {
65
+ "optional": true
66
+ },
67
+ "react-native-keyboard-controller": {
68
+ "optional": true
69
+ },
70
+ "react-native-reanimated": {
71
+ "optional": true
72
+ },
73
+ "react-native-safe-area-context": {
74
+ "optional": true
75
+ }
76
+ },
77
+ "dependencies": {
78
+ "antifraud-portal-components-react": "0.3.0",
79
+ "sos-data-utils-ts": "0.6.30"
80
+ },
81
+ "devDependencies": {
82
+ "@testing-library/react": "^16.3.2",
83
+ "@types/node": "22.19.15",
84
+ "@types/react": "19.2.17",
85
+ "@types/react-dom": "19.2.3",
86
+ "jsdom": "26.1.0",
87
+ "livekit-client": "2.23.0",
88
+ "react": "19.2.8",
89
+ "react-dom": "19.2.8",
90
+ "typescript": "5.9.3",
91
+ "vitest": "4.1.12"
92
+ },
93
+ "publishConfig": {
94
+ "access": "public"
95
+ },
96
+ "repository": {
97
+ "type": "git",
98
+ "url": "git+https://github.com/soschain/sos-portal-components-react.git"
99
+ }
100
+ }