farvex 0.2.0 → 1.0.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.
@@ -0,0 +1,206 @@
1
+ type Auth = {
2
+ getAccessToken: () => string | Promise<string>;
3
+ onUnauthorized?: () => void | Promise<void>;
4
+ };
5
+ declare class CallpadError extends Error {
6
+ readonly code: string;
7
+ readonly status?: number | undefined;
8
+ constructor(code: string, message: string, status?: number | undefined);
9
+ }
10
+
11
+ type RealtimeToken = {
12
+ url: string;
13
+ token: string;
14
+ channel: string;
15
+ expiresAt: string;
16
+ };
17
+ type VoiceDirection = 'inbound' | 'outbound';
18
+ type VoiceSessionState = 'ringing' | 'active' | 'ended';
19
+ type VoiceEndReason = 'completed' | 'declined' | 'closed' | 'no_route';
20
+ type VoiceParticipantKind = 'agent' | 'vendor_user' | 'customer' | 'contact' | 'phone';
21
+ type VoiceParticipantRole = 'host' | 'participant';
22
+ type VoiceTransport = 'webrtc' | 'sip';
23
+ type VoiceParticipantState = 'invited' | 'accepted' | 'joined' | 'left' | 'rejected' | 'removed';
24
+ type VoiceParticipant = {
25
+ id: string;
26
+ kind: VoiceParticipantKind;
27
+ role: VoiceParticipantRole;
28
+ transport: VoiceTransport;
29
+ state: VoiceParticipantState;
30
+ identity: string;
31
+ userId: number | null;
32
+ agentId: string | null;
33
+ contactId: string | null;
34
+ phone: string | null;
35
+ firstName: string | null;
36
+ lastName: string | null;
37
+ profilePhoto: string | null;
38
+ inviteExpiresAt: string | null;
39
+ acceptedAt: string | null;
40
+ joinedAt: string | null;
41
+ leftAt: string | null;
42
+ };
43
+ type VoiceSession = {
44
+ id: string;
45
+ vendor: string;
46
+ version: number;
47
+ direction: VoiceDirection;
48
+ state: VoiceSessionState;
49
+ createdAt: string;
50
+ answeredAt: string | null;
51
+ endedAt: string | null;
52
+ endReason: VoiceEndReason | null;
53
+ recording: SessionRecording;
54
+ participants: Array<VoiceParticipant>;
55
+ };
56
+ type SessionRecordingStatus = 'off' | 'starting' | 'recording' | 'stopping';
57
+ type SessionRecording = {
58
+ status: SessionRecordingStatus;
59
+ startedAt: string | null;
60
+ };
61
+ type SessionRecordingControl = {
62
+ sessionId: string;
63
+ sessionVersion: number;
64
+ recording: SessionRecording;
65
+ };
66
+ type VoiceJoinGrant = {
67
+ url: string;
68
+ roomName: string;
69
+ token: string;
70
+ participantIdentity: string;
71
+ participantId: string;
72
+ expiresAt: string;
73
+ };
74
+ type StartedSession = {
75
+ session: VoiceSession;
76
+ join: VoiceJoinGrant | null;
77
+ };
78
+ type ListSessionsResponse = {
79
+ items: Array<VoiceSession>;
80
+ };
81
+ type ListSessionsData = {
82
+ body?: never;
83
+ path?: never;
84
+ query?: {
85
+ vendor?: string;
86
+ state?: 'active' | 'ended' | 'all';
87
+ before?: string;
88
+ limit?: number;
89
+ };
90
+ url: '/api/v1/sessions';
91
+ };
92
+
93
+ type Nullable<T> = T | null;
94
+
95
+ type ClientStatus = "idle" | "connecting" | "ready" | "reconnecting" | "offline" | "disposed";
96
+ type SessionAction = "accept" | "reject" | "join" | "leave" | "end" | "addParticipant" | "removeParticipant" | "startRecording" | "stopRecording";
97
+ type Unsubscribe = () => void;
98
+ type StoreTopic = "status" | "sessions" | "invites" | `session:${string}`;
99
+ type SessionInvite = {
100
+ session: VoiceSession;
101
+ participant: VoiceParticipant;
102
+ };
103
+ type SessionDuration = {
104
+ seconds: number;
105
+ startedAt: Nullable<string>;
106
+ endedAt: Nullable<string>;
107
+ running: boolean;
108
+ };
109
+ type ClientEvents = {
110
+ status: ClientStatus;
111
+ "session.added": VoiceSession;
112
+ "session.updated": VoiceSession;
113
+ "session.removed": {
114
+ sessionId: string;
115
+ vendor?: string;
116
+ version?: number;
117
+ };
118
+ error: Error;
119
+ };
120
+ type SessionClientConfig = {
121
+ apiUrl: string;
122
+ userId: number;
123
+ auth: Auth;
124
+ fetch?: typeof fetch;
125
+ };
126
+ type HostClientConfig = SessionClientConfig & {
127
+ vendor: string;
128
+ };
129
+ type ListQuery = NonNullable<ListSessionsData["query"]>;
130
+ type CustomerStartInput = {
131
+ vendor: string;
132
+ target: {
133
+ type: "vendor_user";
134
+ userId: number;
135
+ };
136
+ };
137
+ type HostStartInput = {
138
+ target: {
139
+ type: "customer";
140
+ userId: number;
141
+ } | {
142
+ type: "contact";
143
+ contactId: string;
144
+ } | {
145
+ type: "phone";
146
+ phone: string;
147
+ };
148
+ };
149
+ type ParticipantRef = {
150
+ sessionId: string;
151
+ participantId: string;
152
+ };
153
+ type HostParticipantInput = {
154
+ sessionId: string;
155
+ target: {
156
+ type: "contact";
157
+ contactId: string;
158
+ } | {
159
+ type: "phone";
160
+ phone: string;
161
+ };
162
+ };
163
+ type Invites = {
164
+ list: () => readonly SessionInvite[];
165
+ get: (sessionId: string) => Nullable<SessionInvite>;
166
+ };
167
+ type Sessions = {
168
+ list: () => readonly VoiceSession[];
169
+ get: (sessionId?: string) => Nullable<VoiceSession>;
170
+ sync: (query?: ListQuery) => Promise<readonly VoiceSession[]>;
171
+ start: (input: CustomerStartInput) => Promise<StartedSession>;
172
+ join: (sessionId: string) => Promise<VoiceJoinGrant>;
173
+ accept: (input: ParticipantRef) => Promise<StartedSession>;
174
+ reject: (input: ParticipantRef) => Promise<VoiceSession>;
175
+ leave: (sessionId: string) => Promise<VoiceSession>;
176
+ can: (session: VoiceSession, action: SessionAction) => boolean;
177
+ };
178
+ type HostSessions = Omit<Sessions, "start"> & {
179
+ start: (input: HostStartInput) => Promise<StartedSession>;
180
+ };
181
+ type HostControls = {
182
+ end: (sessionId: string) => Promise<void>;
183
+ addParticipant: (input: HostParticipantInput) => Promise<StartedSession>;
184
+ removeParticipant: (input: ParticipantRef) => Promise<VoiceSession>;
185
+ startRecording: (sessionId: string) => Promise<SessionRecordingControl>;
186
+ stopRecording: (sessionId: string) => Promise<SessionRecordingControl>;
187
+ };
188
+ type SessionClient = {
189
+ readonly kind: "session";
190
+ readonly status: ClientStatus;
191
+ readonly sessions: Sessions;
192
+ readonly invites: Invites;
193
+ connect: () => Promise<void>;
194
+ disconnect: () => Promise<void>;
195
+ dispose: () => Promise<void>;
196
+ on: <K extends keyof ClientEvents>(event: K, fn: (payload: ClientEvents[K]) => void) => Unsubscribe;
197
+ subscribe: (topic: StoreTopic, fn: () => void) => Unsubscribe;
198
+ };
199
+ type HostClient = Omit<SessionClient, "kind" | "sessions"> & {
200
+ readonly kind: "host";
201
+ readonly vendor: string;
202
+ readonly sessions: HostSessions;
203
+ readonly host: HostControls;
204
+ };
205
+
206
+ export { CallpadError as C, type HostClient as H, type Invites as I, type ListQuery as L, type Nullable as N, type ParticipantRef as P, type RealtimeToken as R, type SessionAction as S, type Unsubscribe as U, type VoiceJoinGrant as V, type ClientEvents as a, type ClientStatus as b, type CustomerStartInput as c, type HostClientConfig as d, type HostControls as e, type HostParticipantInput as f, type HostSessions as g, type HostStartInput as h, type ListSessionsResponse as i, type SessionClient as j, type SessionClientConfig as k, type SessionDuration as l, type SessionInvite as m, type SessionRecording as n, type SessionRecordingControl as o, type Sessions as p, type StartedSession as q, type StoreTopic as r, type VoiceParticipant as s, type VoiceSession as t };
@@ -0,0 +1,206 @@
1
+ type Auth = {
2
+ getAccessToken: () => string | Promise<string>;
3
+ onUnauthorized?: () => void | Promise<void>;
4
+ };
5
+ declare class CallpadError extends Error {
6
+ readonly code: string;
7
+ readonly status?: number | undefined;
8
+ constructor(code: string, message: string, status?: number | undefined);
9
+ }
10
+
11
+ type RealtimeToken = {
12
+ url: string;
13
+ token: string;
14
+ channel: string;
15
+ expiresAt: string;
16
+ };
17
+ type VoiceDirection = 'inbound' | 'outbound';
18
+ type VoiceSessionState = 'ringing' | 'active' | 'ended';
19
+ type VoiceEndReason = 'completed' | 'declined' | 'closed' | 'no_route';
20
+ type VoiceParticipantKind = 'agent' | 'vendor_user' | 'customer' | 'contact' | 'phone';
21
+ type VoiceParticipantRole = 'host' | 'participant';
22
+ type VoiceTransport = 'webrtc' | 'sip';
23
+ type VoiceParticipantState = 'invited' | 'accepted' | 'joined' | 'left' | 'rejected' | 'removed';
24
+ type VoiceParticipant = {
25
+ id: string;
26
+ kind: VoiceParticipantKind;
27
+ role: VoiceParticipantRole;
28
+ transport: VoiceTransport;
29
+ state: VoiceParticipantState;
30
+ identity: string;
31
+ userId: number | null;
32
+ agentId: string | null;
33
+ contactId: string | null;
34
+ phone: string | null;
35
+ firstName: string | null;
36
+ lastName: string | null;
37
+ profilePhoto: string | null;
38
+ inviteExpiresAt: string | null;
39
+ acceptedAt: string | null;
40
+ joinedAt: string | null;
41
+ leftAt: string | null;
42
+ };
43
+ type VoiceSession = {
44
+ id: string;
45
+ vendor: string;
46
+ version: number;
47
+ direction: VoiceDirection;
48
+ state: VoiceSessionState;
49
+ createdAt: string;
50
+ answeredAt: string | null;
51
+ endedAt: string | null;
52
+ endReason: VoiceEndReason | null;
53
+ recording: SessionRecording;
54
+ participants: Array<VoiceParticipant>;
55
+ };
56
+ type SessionRecordingStatus = 'off' | 'starting' | 'recording' | 'stopping';
57
+ type SessionRecording = {
58
+ status: SessionRecordingStatus;
59
+ startedAt: string | null;
60
+ };
61
+ type SessionRecordingControl = {
62
+ sessionId: string;
63
+ sessionVersion: number;
64
+ recording: SessionRecording;
65
+ };
66
+ type VoiceJoinGrant = {
67
+ url: string;
68
+ roomName: string;
69
+ token: string;
70
+ participantIdentity: string;
71
+ participantId: string;
72
+ expiresAt: string;
73
+ };
74
+ type StartedSession = {
75
+ session: VoiceSession;
76
+ join: VoiceJoinGrant | null;
77
+ };
78
+ type ListSessionsResponse = {
79
+ items: Array<VoiceSession>;
80
+ };
81
+ type ListSessionsData = {
82
+ body?: never;
83
+ path?: never;
84
+ query?: {
85
+ vendor?: string;
86
+ state?: 'active' | 'ended' | 'all';
87
+ before?: string;
88
+ limit?: number;
89
+ };
90
+ url: '/api/v1/sessions';
91
+ };
92
+
93
+ type Nullable<T> = T | null;
94
+
95
+ type ClientStatus = "idle" | "connecting" | "ready" | "reconnecting" | "offline" | "disposed";
96
+ type SessionAction = "accept" | "reject" | "join" | "leave" | "end" | "addParticipant" | "removeParticipant" | "startRecording" | "stopRecording";
97
+ type Unsubscribe = () => void;
98
+ type StoreTopic = "status" | "sessions" | "invites" | `session:${string}`;
99
+ type SessionInvite = {
100
+ session: VoiceSession;
101
+ participant: VoiceParticipant;
102
+ };
103
+ type SessionDuration = {
104
+ seconds: number;
105
+ startedAt: Nullable<string>;
106
+ endedAt: Nullable<string>;
107
+ running: boolean;
108
+ };
109
+ type ClientEvents = {
110
+ status: ClientStatus;
111
+ "session.added": VoiceSession;
112
+ "session.updated": VoiceSession;
113
+ "session.removed": {
114
+ sessionId: string;
115
+ vendor?: string;
116
+ version?: number;
117
+ };
118
+ error: Error;
119
+ };
120
+ type SessionClientConfig = {
121
+ apiUrl: string;
122
+ userId: number;
123
+ auth: Auth;
124
+ fetch?: typeof fetch;
125
+ };
126
+ type HostClientConfig = SessionClientConfig & {
127
+ vendor: string;
128
+ };
129
+ type ListQuery = NonNullable<ListSessionsData["query"]>;
130
+ type CustomerStartInput = {
131
+ vendor: string;
132
+ target: {
133
+ type: "vendor_user";
134
+ userId: number;
135
+ };
136
+ };
137
+ type HostStartInput = {
138
+ target: {
139
+ type: "customer";
140
+ userId: number;
141
+ } | {
142
+ type: "contact";
143
+ contactId: string;
144
+ } | {
145
+ type: "phone";
146
+ phone: string;
147
+ };
148
+ };
149
+ type ParticipantRef = {
150
+ sessionId: string;
151
+ participantId: string;
152
+ };
153
+ type HostParticipantInput = {
154
+ sessionId: string;
155
+ target: {
156
+ type: "contact";
157
+ contactId: string;
158
+ } | {
159
+ type: "phone";
160
+ phone: string;
161
+ };
162
+ };
163
+ type Invites = {
164
+ list: () => readonly SessionInvite[];
165
+ get: (sessionId: string) => Nullable<SessionInvite>;
166
+ };
167
+ type Sessions = {
168
+ list: () => readonly VoiceSession[];
169
+ get: (sessionId?: string) => Nullable<VoiceSession>;
170
+ sync: (query?: ListQuery) => Promise<readonly VoiceSession[]>;
171
+ start: (input: CustomerStartInput) => Promise<StartedSession>;
172
+ join: (sessionId: string) => Promise<VoiceJoinGrant>;
173
+ accept: (input: ParticipantRef) => Promise<StartedSession>;
174
+ reject: (input: ParticipantRef) => Promise<VoiceSession>;
175
+ leave: (sessionId: string) => Promise<VoiceSession>;
176
+ can: (session: VoiceSession, action: SessionAction) => boolean;
177
+ };
178
+ type HostSessions = Omit<Sessions, "start"> & {
179
+ start: (input: HostStartInput) => Promise<StartedSession>;
180
+ };
181
+ type HostControls = {
182
+ end: (sessionId: string) => Promise<void>;
183
+ addParticipant: (input: HostParticipantInput) => Promise<StartedSession>;
184
+ removeParticipant: (input: ParticipantRef) => Promise<VoiceSession>;
185
+ startRecording: (sessionId: string) => Promise<SessionRecordingControl>;
186
+ stopRecording: (sessionId: string) => Promise<SessionRecordingControl>;
187
+ };
188
+ type SessionClient = {
189
+ readonly kind: "session";
190
+ readonly status: ClientStatus;
191
+ readonly sessions: Sessions;
192
+ readonly invites: Invites;
193
+ connect: () => Promise<void>;
194
+ disconnect: () => Promise<void>;
195
+ dispose: () => Promise<void>;
196
+ on: <K extends keyof ClientEvents>(event: K, fn: (payload: ClientEvents[K]) => void) => Unsubscribe;
197
+ subscribe: (topic: StoreTopic, fn: () => void) => Unsubscribe;
198
+ };
199
+ type HostClient = Omit<SessionClient, "kind" | "sessions"> & {
200
+ readonly kind: "host";
201
+ readonly vendor: string;
202
+ readonly sessions: HostSessions;
203
+ readonly host: HostControls;
204
+ };
205
+
206
+ export { CallpadError as C, type HostClient as H, type Invites as I, type ListQuery as L, type Nullable as N, type ParticipantRef as P, type RealtimeToken as R, type SessionAction as S, type Unsubscribe as U, type VoiceJoinGrant as V, type ClientEvents as a, type ClientStatus as b, type CustomerStartInput as c, type HostClientConfig as d, type HostControls as e, type HostParticipantInput as f, type HostSessions as g, type HostStartInput as h, type ListSessionsResponse as i, type SessionClient as j, type SessionClientConfig as k, type SessionDuration as l, type SessionInvite as m, type SessionRecording as n, type SessionRecordingControl as o, type Sessions as p, type StartedSession as q, type StoreTopic as r, type VoiceParticipant as s, type VoiceSession as t };
package/package.json CHANGED
@@ -1,15 +1,23 @@
1
1
  {
2
2
  "name": "farvex",
3
- "version": "0.2.0",
4
- "description": "Web SDK for Callpad sessions (LiveKit + Pulse)",
3
+ "version": "1.0.1",
4
+ "description": "Web SDK for Callpad voice sessions",
5
+ "keywords": [
6
+ "callpad",
7
+ "livekit",
8
+ "react",
9
+ "realtime",
10
+ "sessions",
11
+ "webrtc"
12
+ ],
5
13
  "license": "UNLICENSED",
6
- "type": "module",
7
- "sideEffects": false,
8
14
  "files": [
9
15
  "dist",
10
16
  "README.md",
11
17
  "CHANGELOG.md"
12
18
  ],
19
+ "type": "module",
20
+ "sideEffects": false,
13
21
  "exports": {
14
22
  ".": {
15
23
  "import": {
@@ -21,16 +29,6 @@
21
29
  "default": "./dist/index.cjs"
22
30
  }
23
31
  },
24
- "./core": {
25
- "import": {
26
- "types": "./dist/core/index.d.ts",
27
- "default": "./dist/core/index.js"
28
- },
29
- "require": {
30
- "types": "./dist/core/index.d.cts",
31
- "default": "./dist/core/index.cjs"
32
- }
33
- },
34
32
  "./react": {
35
33
  "import": {
36
34
  "types": "./dist/react/index.d.ts",
@@ -51,80 +49,63 @@
51
49
  "default": "./dist/livekit/index.cjs"
52
50
  }
53
51
  },
54
- "./mock": {
55
- "import": {
56
- "types": "./dist/mock/index.d.ts",
57
- "default": "./dist/mock/index.js"
58
- },
59
- "require": {
60
- "types": "./dist/mock/index.d.cts",
61
- "default": "./dist/mock/index.cjs"
62
- }
63
- },
64
52
  "./package.json": "./package.json"
65
53
  },
66
- "peerDependencies": {
67
- "react": "^18 || ^19",
68
- "react-dom": "^18 || ^19"
54
+ "publishConfig": {
55
+ "access": "public"
69
56
  },
70
- "peerDependenciesMeta": {
71
- "react": {
72
- "optional": true
73
- },
74
- "react-dom": {
75
- "optional": true
76
- }
57
+ "scripts": {
58
+ "changeset": "changeset",
59
+ "version": "changeset version",
60
+ "release": "changeset publish",
61
+ "generate": "openapi-ts",
62
+ "build": "bun run generate && tsup",
63
+ "dev": "tsup --watch",
64
+ "typecheck": "tsc --noEmit",
65
+ "lint": "oxlint .",
66
+ "format": "oxfmt .",
67
+ "format:check": "oxfmt --check .",
68
+ "check": "bun run generate && bun run lint && bun run format:check && bun run typecheck",
69
+ "prepublishOnly": "bun run check && bun run build"
77
70
  },
78
71
  "dependencies": {
79
- "@livekit/components-react": "^2.9.0",
80
- "livekit-client": "^2.13.0",
81
- "socket.io-client": "^4.8.1"
72
+ "centrifuge": "5.6.0"
82
73
  },
83
74
  "devDependencies": {
84
- "@hey-api/openapi-ts": "^0.73.0",
85
- "@testing-library/jest-dom": "^6.5.0",
86
- "@testing-library/react": "^16.0.0",
75
+ "@changesets/cli": "^2.27.0",
76
+ "@hey-api/openapi-ts": "0.97.2",
77
+ "@livekit/components-react": "^2.9.0",
87
78
  "@types/react": "^18.3.0",
88
79
  "@types/react-dom": "^18.3.0",
89
- "jsdom": "^25.0.0",
80
+ "livekit-client": "^2.13.0",
90
81
  "oxfmt": "^0.38.0",
91
82
  "oxlint": "^1.53.0",
92
83
  "react": "^18.3.0",
93
84
  "react-dom": "^18.3.0",
94
85
  "tsup": "^8.3.0",
95
- "typescript": "5.8.3",
96
- "vitest": "^2.1.0"
86
+ "typescript": "5.8.3"
97
87
  },
98
- "scripts": {
99
- "build": "bun run generate:api && tsup",
100
- "dev": "tsup --watch",
101
- "typecheck": "tsc --noEmit",
102
- "test": "vitest run",
103
- "test:watch": "vitest",
104
- "lint": "oxlint .",
105
- "format": "oxfmt .",
106
- "format:check": "oxfmt --check .",
107
- "check": "bun run generate:api && bun run lint && bun run format:check && bun run typecheck",
108
- "generate:api": "openapi-ts",
109
- "generate:api:watch": "openapi-ts --watch",
110
- "changeset": "changeset",
111
- "version": "changeset version",
112
- "release": "bun run build && changeset publish",
113
- "prepublishOnly": "bun run check && bun run test && bun run build"
88
+ "peerDependencies": {
89
+ "@livekit/components-react": "^2",
90
+ "livekit-client": "^2",
91
+ "react": "^18 || ^19",
92
+ "react-dom": "^18 || ^19"
114
93
  },
115
- "publishConfig": {
116
- "access": "public"
94
+ "peerDependenciesMeta": {
95
+ "@livekit/components-react": {
96
+ "optional": true
97
+ },
98
+ "livekit-client": {
99
+ "optional": true
100
+ },
101
+ "react": {
102
+ "optional": true
103
+ },
104
+ "react-dom": {
105
+ "optional": true
106
+ }
117
107
  },
118
108
  "engines": {
119
109
  "node": ">=18"
120
- },
121
- "keywords": [
122
- "callpad",
123
- "sessions",
124
- "livekit",
125
- "webrtc",
126
- "sip",
127
- "realtime",
128
- "react"
129
- ]
110
+ }
130
111
  }