@chatinfra/client 0.0.4 → 0.0.6
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/README.md +299 -0
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/react-native.d.mts +23 -1
- package/dist/react-native.d.ts +23 -1
- package/dist/react-native.js +97 -3
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +91 -1
- package/dist/react-native.mjs.map +1 -1
- package/package.json +22 -24
package/README.md
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# ChatInfra SDK - Installation Guide
|
|
2
|
+
|
|
3
|
+
This guide shows how to install and use the ChatInfra client SDK in:
|
|
4
|
+
- React Native / Expo
|
|
5
|
+
- Web (Browser)
|
|
6
|
+
|
|
7
|
+
> Recommended: **do NOT ship your org secret key in mobile apps**. For production, mint tokens on your backend and return them to the app.
|
|
8
|
+
> If you're prototyping, client-side token minting can work (as shown below).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1) Install (React Native / Expo)
|
|
13
|
+
|
|
14
|
+
### A. Install dependencies
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @chatinfra/client
|
|
18
|
+
pnpm add crypto-js
|
|
19
|
+
pnpm add @pusher/pusher-websocket-react-native
|
|
20
|
+
expo install expo-secure-store
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### B. If you're using TypeScript
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add -D @types/crypto-js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### C. Create a client wrapper (drop-in style)
|
|
29
|
+
|
|
30
|
+
Create `src/services/chat/ChatInfraClient.ts`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import CryptoJS from "crypto-js";
|
|
34
|
+
import * as SecureStore from "expo-secure-store";
|
|
35
|
+
|
|
36
|
+
import {
|
|
37
|
+
createChatClient,
|
|
38
|
+
PusherReactNativeTransport,
|
|
39
|
+
type Page,
|
|
40
|
+
type Message,
|
|
41
|
+
type Conversation,
|
|
42
|
+
type Identity,
|
|
43
|
+
type TokenStorage,
|
|
44
|
+
} from "@chatinfra/client";
|
|
45
|
+
|
|
46
|
+
export type { Identity, Conversation, Message, Page };
|
|
47
|
+
|
|
48
|
+
type RealtimeCfg = { key: string; cluster: string; force_tls: boolean };
|
|
49
|
+
|
|
50
|
+
type InitTokenPayload = {
|
|
51
|
+
widget_slug: string;
|
|
52
|
+
identity: {
|
|
53
|
+
external_id: string;
|
|
54
|
+
type_key: string;
|
|
55
|
+
fullname?: string | null;
|
|
56
|
+
email?: string | null;
|
|
57
|
+
};
|
|
58
|
+
ttl?: number;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type ClientOpts = {
|
|
62
|
+
apiBase: string;
|
|
63
|
+
widgetSlug: string;
|
|
64
|
+
|
|
65
|
+
// optional cached token
|
|
66
|
+
token?: string | null;
|
|
67
|
+
|
|
68
|
+
// client-side minting keys (prototype only)
|
|
69
|
+
orgPublicKey: string;
|
|
70
|
+
orgSecretKey: string;
|
|
71
|
+
|
|
72
|
+
// identity
|
|
73
|
+
identity: InitTokenPayload["identity"];
|
|
74
|
+
|
|
75
|
+
// optional
|
|
76
|
+
ttl?: number;
|
|
77
|
+
realtime?: RealtimeCfg | null;
|
|
78
|
+
tokenStorageKey?: string; // must be SecureStore-safe
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
function trimSlash(s: string) {
|
|
82
|
+
return (s || "").replace(/\/+$/, "");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// NOTE: SecureStore keys must be alphanumeric + dot + dash + underscore.
|
|
86
|
+
// Avoid ":" in key names.
|
|
87
|
+
function createExpoTokenStorage(prefix = "chatinfra_"): TokenStorage {
|
|
88
|
+
const keyOf = (k: string) => `${prefix}${k}`;
|
|
89
|
+
return {
|
|
90
|
+
async get(key: string) { return await SecureStore.getItemAsync(keyOf(key)); },
|
|
91
|
+
async set(key: string, value: string) { await SecureStore.setItemAsync(keyOf(key), value); },
|
|
92
|
+
async del(key: string) { await SecureStore.deleteItemAsync(keyOf(key)); },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function safeJson(res: Response) {
|
|
97
|
+
const text = await res.text();
|
|
98
|
+
try { return JSON.parse(text); }
|
|
99
|
+
catch { throw new Error(`Non-JSON response (status ${res.status}): ${text}`); }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function mintTokenWithOrgSecret(params: {
|
|
103
|
+
apiBase: string;
|
|
104
|
+
widgetSlug: string;
|
|
105
|
+
identity: InitTokenPayload["identity"];
|
|
106
|
+
ttl: number;
|
|
107
|
+
orgPublicKey: string;
|
|
108
|
+
orgSecretKey: string;
|
|
109
|
+
}): Promise<string> {
|
|
110
|
+
const payload: InitTokenPayload = {
|
|
111
|
+
widget_slug: params.widgetSlug,
|
|
112
|
+
identity: params.identity,
|
|
113
|
+
ttl: params.ttl,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const raw = JSON.stringify(payload);
|
|
117
|
+
const ts = Math.floor(Date.now() / 1000);
|
|
118
|
+
const sig = CryptoJS.HmacSHA256(raw, params.orgSecretKey).toString(CryptoJS.enc.Hex);
|
|
119
|
+
|
|
120
|
+
const res = await fetch(params.apiBase + "/api/v1/widget/init", {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: {
|
|
123
|
+
Accept: "application/json",
|
|
124
|
+
"Content-Type": "application/json",
|
|
125
|
+
"X-ORG-KEY": params.orgPublicKey,
|
|
126
|
+
"X-TIMESTAMP": String(ts),
|
|
127
|
+
"X-SIGNATURE": sig,
|
|
128
|
+
},
|
|
129
|
+
body: raw,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const json = await safeJson(res);
|
|
133
|
+
if (!json?.ok) throw new Error(json?.message || "Failed to mint token");
|
|
134
|
+
|
|
135
|
+
const t = json?.data?.token || json?.data?.access_token;
|
|
136
|
+
if (!t) throw new Error("Token missing in response");
|
|
137
|
+
return String(t);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export class ChatInfraClient {
|
|
141
|
+
private sdk: ReturnType<typeof createChatClient>;
|
|
142
|
+
private me: Identity | null = null;
|
|
143
|
+
private rt: RealtimeCfg | null = null;
|
|
144
|
+
|
|
145
|
+
private storage: TokenStorage;
|
|
146
|
+
private tokenStorageKey: string;
|
|
147
|
+
private apiBase: string;
|
|
148
|
+
|
|
149
|
+
constructor(private opts: ClientOpts) {
|
|
150
|
+
this.apiBase = trimSlash(opts.apiBase);
|
|
151
|
+
this.storage = createExpoTokenStorage();
|
|
152
|
+
this.tokenStorageKey = opts.tokenStorageKey || "chatinfra_token"; // must be SecureStore-safe
|
|
153
|
+
|
|
154
|
+
this.sdk = createChatClient({
|
|
155
|
+
baseUrl: this.apiBase,
|
|
156
|
+
widgetSlug: opts.widgetSlug,
|
|
157
|
+
|
|
158
|
+
identity: {
|
|
159
|
+
externalId: opts.identity.external_id,
|
|
160
|
+
typeKey: opts.identity.type_key,
|
|
161
|
+
fullname: opts.identity.fullname ?? undefined,
|
|
162
|
+
email: opts.identity.email ?? undefined,
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
storage: this.storage,
|
|
166
|
+
tokenStorageKey: this.tokenStorageKey,
|
|
167
|
+
|
|
168
|
+
realtimeTransport: new PusherReactNativeTransport(),
|
|
169
|
+
|
|
170
|
+
tokenProvider: async () => {
|
|
171
|
+
if (opts.token) return String(opts.token);
|
|
172
|
+
|
|
173
|
+
const cached = await this.storage.get(this.tokenStorageKey);
|
|
174
|
+
if (cached) return cached;
|
|
175
|
+
|
|
176
|
+
const token = await mintTokenWithOrgSecret({
|
|
177
|
+
apiBase: this.apiBase,
|
|
178
|
+
widgetSlug: opts.widgetSlug,
|
|
179
|
+
identity: opts.identity,
|
|
180
|
+
ttl: typeof opts.ttl === "number" ? opts.ttl : 3600,
|
|
181
|
+
orgPublicKey: opts.orgPublicKey,
|
|
182
|
+
orgSecretKey: opts.orgSecretKey,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
await this.storage.set(this.tokenStorageKey, token);
|
|
186
|
+
return token;
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (opts.realtime) {
|
|
191
|
+
this.sdk.setRealtimeConfig({
|
|
192
|
+
key: opts.realtime.key,
|
|
193
|
+
cluster: opts.realtime.cluster,
|
|
194
|
+
force_tls: !!opts.realtime.force_tls,
|
|
195
|
+
});
|
|
196
|
+
this.rt = opts.realtime;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async init() {
|
|
201
|
+
const info = await this.sdk.init();
|
|
202
|
+
this.me = info.me;
|
|
203
|
+
|
|
204
|
+
this.rt = info.realtime
|
|
205
|
+
? ({ key: info.realtime.key, cluster: info.realtime.cluster, force_tls: !!info.realtime.force_tls } as any)
|
|
206
|
+
: (this.opts.realtime ?? null);
|
|
207
|
+
|
|
208
|
+
return { me: this.me!, realtime: this.rt, token: info.token };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async listConversations(cursor?: string | null) { return await this.sdk.listConversations(cursor ?? null); }
|
|
212
|
+
async listMessages(conversationId: number, cursor?: string | null) { return await this.sdk.listMessages(conversationId, cursor ?? null); }
|
|
213
|
+
async sendMessage(conversationId: number, body: string) { return await this.sdk.sendMessage(conversationId, body); }
|
|
214
|
+
async subscribeConversation(conversationId: number, handlers: any) { return await this.sdk.subscribeConversation(conversationId, handlers); }
|
|
215
|
+
async triggerTyping(conversationId: number, payload: any) { return await this.sdk.triggerTyping(conversationId, payload); }
|
|
216
|
+
async disconnect() { await this.sdk.disconnect(); }
|
|
217
|
+
getMe() { return this.me; }
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### D. Use it in your screen (same constructor shape)
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
const client = new ChatInfraClient({
|
|
225
|
+
apiBase: "https://your-chatinfra-domain.com",
|
|
226
|
+
widgetSlug: "drivon_customer",
|
|
227
|
+
token: cachedToken,
|
|
228
|
+
|
|
229
|
+
orgPublicKey: "pk_...",
|
|
230
|
+
orgSecretKey: "sk_...",
|
|
231
|
+
|
|
232
|
+
identity: {
|
|
233
|
+
external_id: "customer_123",
|
|
234
|
+
type_key: "customer",
|
|
235
|
+
fullname: "Ebuka Mbanusi",
|
|
236
|
+
email: "frankemmanuel249@gmail.com",
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 2) Install (Web)
|
|
244
|
+
|
|
245
|
+
### A. Install dependencies
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
pnpm add @chatinfra/client
|
|
249
|
+
pnpm add pusher-js
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### B. If you ever see `@react-native-community/netinfo` in the import stack
|
|
253
|
+
That means the **React Native build accidentally imported the web Pusher transport** (which uses `pusher-js/dist/react-native`).
|
|
254
|
+
|
|
255
|
+
Fix:
|
|
256
|
+
- In React Native, only use `PusherReactNativeTransport` and ensure you're importing from the RN entry (or from `@chatinfra/client` if it already exports the RN transport).
|
|
257
|
+
- Remove `@chatinfra/realtime-pusher-web` from your RN dependency graph.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 3) Troubleshooting
|
|
262
|
+
|
|
263
|
+
### SecureStore: "Invalid key provided..."
|
|
264
|
+
Expo SecureStore only accepts keys containing:
|
|
265
|
+
- letters and numbers
|
|
266
|
+
- `.`, `-`, `_`
|
|
267
|
+
|
|
268
|
+
So these are invalid:
|
|
269
|
+
- `chatinfra:token` (contains `:`)
|
|
270
|
+
|
|
271
|
+
Use safe keys like:
|
|
272
|
+
- `chatinfra_token`
|
|
273
|
+
- `chatinfra.token`
|
|
274
|
+
- `chatinfra-token`
|
|
275
|
+
|
|
276
|
+
In the wrapper above we use a safe prefix `chatinfra_`.
|
|
277
|
+
|
|
278
|
+
### Conversations not listing but no error
|
|
279
|
+
- Log your network calls:
|
|
280
|
+
- `/api/v1/widget/init` (token mint)
|
|
281
|
+
- `/api/v1/me`
|
|
282
|
+
- `/api/v1/conversations`
|
|
283
|
+
- If `/api/v1/sdk/config` does not exist, pass `realtime` config in the constructor OR add that endpoint in your backend.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 4) Minimal backend endpoints expected by the SDK
|
|
288
|
+
|
|
289
|
+
- `POST /api/v1/widget/init` (if minting in client)
|
|
290
|
+
- `GET /api/v1/me`
|
|
291
|
+
- `GET /api/v1/conversations`
|
|
292
|
+
- `GET /api/v1/conversations/{id}/messages`
|
|
293
|
+
- `POST /api/v1/conversations/{id}/messages`
|
|
294
|
+
- `POST /api/v1/broadcast/auth` (Pusher channel auth)
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## License / Notes
|
|
299
|
+
For production mobile apps, move token minting to your backend to avoid exposing org secrets.
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/react-native.d.mts
CHANGED
|
@@ -1,2 +1,24 @@
|
|
|
1
|
+
import { RealtimeTransport } from '@chatinfra/sdk';
|
|
1
2
|
export * from '@chatinfra/sdk';
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
declare class PusherReactNativeTransport implements RealtimeTransport {
|
|
5
|
+
private pusher;
|
|
6
|
+
private inited;
|
|
7
|
+
private connected;
|
|
8
|
+
private subscribed;
|
|
9
|
+
private onDebug?;
|
|
10
|
+
init(cfg: {
|
|
11
|
+
key: string;
|
|
12
|
+
cluster: string;
|
|
13
|
+
forceTLS: boolean;
|
|
14
|
+
authorizer: (channelName: string, socketId: string) => Promise<any>;
|
|
15
|
+
onDebug?: (msg: string, data?: any) => void;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
connect(): Promise<void>;
|
|
18
|
+
subscribe(channelName: string, onEvent: (eventName: string, data: any) => void): Promise<void>;
|
|
19
|
+
unsubscribe(channelName: string): Promise<void>;
|
|
20
|
+
trigger(channelName: string, eventName: string, data: any): Promise<void>;
|
|
21
|
+
disconnect(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { PusherReactNativeTransport };
|
package/dist/react-native.d.ts
CHANGED
|
@@ -1,2 +1,24 @@
|
|
|
1
|
+
import { RealtimeTransport } from '@chatinfra/sdk';
|
|
1
2
|
export * from '@chatinfra/sdk';
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
declare class PusherReactNativeTransport implements RealtimeTransport {
|
|
5
|
+
private pusher;
|
|
6
|
+
private inited;
|
|
7
|
+
private connected;
|
|
8
|
+
private subscribed;
|
|
9
|
+
private onDebug?;
|
|
10
|
+
init(cfg: {
|
|
11
|
+
key: string;
|
|
12
|
+
cluster: string;
|
|
13
|
+
forceTLS: boolean;
|
|
14
|
+
authorizer: (channelName: string, socketId: string) => Promise<any>;
|
|
15
|
+
onDebug?: (msg: string, data?: any) => void;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
connect(): Promise<void>;
|
|
18
|
+
subscribe(channelName: string, onEvent: (eventName: string, data: any) => void): Promise<void>;
|
|
19
|
+
unsubscribe(channelName: string): Promise<void>;
|
|
20
|
+
trigger(channelName: string, eventName: string, data: any): Promise<void>;
|
|
21
|
+
disconnect(): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { PusherReactNativeTransport };
|
package/dist/react-native.js
CHANGED
|
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
6
10
|
var __copyProps = (to, from, except, desc) => {
|
|
7
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
12
|
for (let key of __getOwnPropNames(from))
|
|
@@ -16,12 +20,102 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
16
20
|
|
|
17
21
|
// src/react-native.ts
|
|
18
22
|
var react_native_exports = {};
|
|
23
|
+
__export(react_native_exports, {
|
|
24
|
+
PusherReactNativeTransport: () => PusherReactNativeTransport
|
|
25
|
+
});
|
|
19
26
|
module.exports = __toCommonJS(react_native_exports);
|
|
20
27
|
__reExport(react_native_exports, require("@chatinfra/sdk"), module.exports);
|
|
21
|
-
|
|
28
|
+
|
|
29
|
+
// src/transports/pusher-react-native.ts
|
|
30
|
+
var import_pusher_websocket_react_native = require("@pusher/pusher-websocket-react-native");
|
|
31
|
+
var PusherReactNativeTransport = class {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.pusher = import_pusher_websocket_react_native.Pusher.getInstance();
|
|
34
|
+
this.inited = false;
|
|
35
|
+
this.connected = false;
|
|
36
|
+
this.subscribed = /* @__PURE__ */ new Set();
|
|
37
|
+
}
|
|
38
|
+
async init(cfg) {
|
|
39
|
+
if (this.inited) return;
|
|
40
|
+
this.onDebug = cfg.onDebug;
|
|
41
|
+
await this.pusher.init({
|
|
42
|
+
apiKey: cfg.key,
|
|
43
|
+
cluster: cfg.cluster,
|
|
44
|
+
useTLS: !!cfg.forceTLS,
|
|
45
|
+
onAuthorizer: async (channelName, socketId) => {
|
|
46
|
+
this.onDebug?.("authorizer", { channelName, socketId });
|
|
47
|
+
return await cfg.authorizer(channelName, socketId);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
this.inited = true;
|
|
51
|
+
}
|
|
52
|
+
async connect() {
|
|
53
|
+
if (!this.inited || this.connected) return;
|
|
54
|
+
try {
|
|
55
|
+
await this.pusher.connect();
|
|
56
|
+
this.connected = true;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
this.onDebug?.("connect_failed", e);
|
|
59
|
+
throw e;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async subscribe(channelName, onEvent) {
|
|
63
|
+
if (!this.inited) throw new Error("PusherReactNativeTransport not initialized");
|
|
64
|
+
if (!this.connected) await this.connect();
|
|
65
|
+
if (this.subscribed.has(channelName)) return;
|
|
66
|
+
await this.pusher.subscribe({
|
|
67
|
+
channelName,
|
|
68
|
+
onEvent: (event) => {
|
|
69
|
+
let data = event.data;
|
|
70
|
+
try {
|
|
71
|
+
data = typeof data === "string" ? JSON.parse(data) : data;
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
onEvent(event.eventName, data);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
this.subscribed.add(channelName);
|
|
78
|
+
}
|
|
79
|
+
async unsubscribe(channelName) {
|
|
80
|
+
if (!this.inited) return;
|
|
81
|
+
if (!this.subscribed.has(channelName)) return;
|
|
82
|
+
try {
|
|
83
|
+
await this.pusher.unsubscribe({ channelName });
|
|
84
|
+
} catch (e) {
|
|
85
|
+
this.onDebug?.("unsubscribe_failed", e);
|
|
86
|
+
} finally {
|
|
87
|
+
this.subscribed.delete(channelName);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async trigger(channelName, eventName, data) {
|
|
91
|
+
if (!this.inited || !this.connected) return;
|
|
92
|
+
try {
|
|
93
|
+
await this.pusher.trigger({ channelName, eventName, data });
|
|
94
|
+
} catch (e) {
|
|
95
|
+
this.onDebug?.("trigger_failed", e);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async disconnect() {
|
|
99
|
+
if (!this.inited || !this.connected) return;
|
|
100
|
+
try {
|
|
101
|
+
for (const ch of Array.from(this.subscribed)) {
|
|
102
|
+
try {
|
|
103
|
+
await this.pusher.unsubscribe({ channelName: ch });
|
|
104
|
+
} catch {
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.subscribed.clear();
|
|
108
|
+
await this.pusher.disconnect();
|
|
109
|
+
} catch (e) {
|
|
110
|
+
this.onDebug?.("disconnect_failed", e);
|
|
111
|
+
} finally {
|
|
112
|
+
this.connected = false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
22
116
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23
117
|
0 && (module.exports = {
|
|
24
|
-
|
|
25
|
-
...require("@chatinfra/
|
|
118
|
+
PusherReactNativeTransport,
|
|
119
|
+
...require("@chatinfra/sdk")
|
|
26
120
|
});
|
|
27
121
|
//# sourceMappingURL=react-native.js.map
|
package/dist/react-native.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react-native.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/react-native.ts","../src/transports/pusher-react-native.ts"],"sourcesContent":["// packages/client/src/react-native.ts\nexport * from \"@chatinfra/sdk\";\nexport { PusherReactNativeTransport } from \"./transports/pusher-react-native\";\n","// packages/client/src/transports/pusher-react-native.ts\nimport { Pusher, type PusherEvent } from \"@pusher/pusher-websocket-react-native\";\nimport type { RealtimeTransport } from \"@chatinfra/sdk\";\n\nexport class PusherReactNativeTransport implements RealtimeTransport {\n private pusher = Pusher.getInstance();\n private inited = false;\n private connected = false;\n private subscribed = new Set<string>();\n private onDebug?: (msg: string, data?: any) => void;\n\n async init(cfg: {\n key: string;\n cluster: string;\n forceTLS: boolean;\n authorizer: (channelName: string, socketId: string) => Promise<any>;\n onDebug?: (msg: string, data?: any) => void;\n }) {\n if (this.inited) return;\n\n this.onDebug = cfg.onDebug;\n\n await this.pusher.init({\n apiKey: cfg.key,\n cluster: cfg.cluster,\n useTLS: !!cfg.forceTLS,\n onAuthorizer: async (channelName: string, socketId: string) => {\n this.onDebug?.(\"authorizer\", { channelName, socketId });\n return await cfg.authorizer(channelName, socketId);\n },\n });\n\n this.inited = true;\n }\n\n async connect() {\n if (!this.inited || this.connected) return;\n try {\n await this.pusher.connect();\n this.connected = true;\n } catch (e) {\n this.onDebug?.(\"connect_failed\", e);\n throw e;\n }\n }\n\n async subscribe(channelName: string, onEvent: (eventName: string, data: any) => void) {\n if (!this.inited) throw new Error(\"PusherReactNativeTransport not initialized\");\n if (!this.connected) await this.connect();\n if (this.subscribed.has(channelName)) return;\n\n await this.pusher.subscribe({\n channelName,\n onEvent: (event: PusherEvent) => {\n let data: any = event.data;\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : data;\n } catch {}\n onEvent(event.eventName, data);\n },\n });\n\n this.subscribed.add(channelName);\n }\n\n async unsubscribe(channelName: string) {\n if (!this.inited) return;\n if (!this.subscribed.has(channelName)) return;\n\n try {\n await this.pusher.unsubscribe({ channelName });\n } catch (e) {\n // ignore native edge cases\n this.onDebug?.(\"unsubscribe_failed\", e);\n } finally {\n this.subscribed.delete(channelName);\n }\n }\n\n async trigger(channelName: string, eventName: string, data: any) {\n if (!this.inited || !this.connected) return;\n try {\n await this.pusher.trigger({ channelName, eventName, data });\n } catch (e) {\n this.onDebug?.(\"trigger_failed\", e);\n }\n }\n\n async disconnect() {\n // ✅ avoid crash: don't call native disconnect if never connected\n if (!this.inited || !this.connected) return;\n\n try {\n // unsubscribe defensively\n for (const ch of Array.from(this.subscribed)) {\n try {\n await this.pusher.unsubscribe({ channelName: ch });\n } catch {}\n }\n this.subscribed.clear();\n\n await this.pusher.disconnect();\n } catch (e) {\n // ✅ swallow native disconnect crash scenarios\n this.onDebug?.(\"disconnect_failed\", e);\n } finally {\n this.connected = false;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iCAAc,2BADd;;;ACCA,2CAAyC;AAGlC,IAAM,6BAAN,MAA8D;AAAA,EAA9D;AACL,SAAQ,SAAS,4CAAO,YAAY;AACpC,SAAQ,SAAS;AACjB,SAAQ,YAAY;AACpB,SAAQ,aAAa,oBAAI,IAAY;AAAA;AAAA,EAGrC,MAAM,KAAK,KAMR;AACD,QAAI,KAAK,OAAQ;AAEjB,SAAK,UAAU,IAAI;AAEnB,UAAM,KAAK,OAAO,KAAK;AAAA,MACrB,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,QAAQ,CAAC,CAAC,IAAI;AAAA,MACd,cAAc,OAAO,aAAqB,aAAqB;AAC7D,aAAK,UAAU,cAAc,EAAE,aAAa,SAAS,CAAC;AACtD,eAAO,MAAM,IAAI,WAAW,aAAa,QAAQ;AAAA,MACnD;AAAA,IACF,CAAC;AAED,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,CAAC,KAAK,UAAU,KAAK,UAAW;AACpC,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ;AAC1B,WAAK,YAAY;AAAA,IACnB,SAAS,GAAG;AACV,WAAK,UAAU,kBAAkB,CAAC;AAClC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,aAAqB,SAAiD;AACpF,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,4CAA4C;AAC9E,QAAI,CAAC,KAAK,UAAW,OAAM,KAAK,QAAQ;AACxC,QAAI,KAAK,WAAW,IAAI,WAAW,EAAG;AAEtC,UAAM,KAAK,OAAO,UAAU;AAAA,MAC1B;AAAA,MACA,SAAS,CAAC,UAAuB;AAC/B,YAAI,OAAY,MAAM;AACtB,YAAI;AACF,iBAAO,OAAO,SAAS,WAAW,KAAK,MAAM,IAAI,IAAI;AAAA,QACvD,QAAQ;AAAA,QAAC;AACT,gBAAQ,MAAM,WAAW,IAAI;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,SAAK,WAAW,IAAI,WAAW;AAAA,EACjC;AAAA,EAEA,MAAM,YAAY,aAAqB;AACrC,QAAI,CAAC,KAAK,OAAQ;AAClB,QAAI,CAAC,KAAK,WAAW,IAAI,WAAW,EAAG;AAEvC,QAAI;AACF,YAAM,KAAK,OAAO,YAAY,EAAE,YAAY,CAAC;AAAA,IAC/C,SAAS,GAAG;AAEV,WAAK,UAAU,sBAAsB,CAAC;AAAA,IACxC,UAAE;AACA,WAAK,WAAW,OAAO,WAAW;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,aAAqB,WAAmB,MAAW;AAC/D,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAW;AACrC,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ,EAAE,aAAa,WAAW,KAAK,CAAC;AAAA,IAC5D,SAAS,GAAG;AACV,WAAK,UAAU,kBAAkB,CAAC;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,aAAa;AAEjB,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAW;AAErC,QAAI;AAEF,iBAAW,MAAM,MAAM,KAAK,KAAK,UAAU,GAAG;AAC5C,YAAI;AACF,gBAAM,KAAK,OAAO,YAAY,EAAE,aAAa,GAAG,CAAC;AAAA,QACnD,QAAQ;AAAA,QAAC;AAAA,MACX;AACA,WAAK,WAAW,MAAM;AAEtB,YAAM,KAAK,OAAO,WAAW;AAAA,IAC/B,SAAS,GAAG;AAEV,WAAK,UAAU,qBAAqB,CAAC;AAAA,IACvC,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}
|
package/dist/react-native.mjs
CHANGED
|
@@ -1,4 +1,94 @@
|
|
|
1
1
|
// src/react-native.ts
|
|
2
2
|
export * from "@chatinfra/sdk";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// src/transports/pusher-react-native.ts
|
|
5
|
+
import { Pusher } from "@pusher/pusher-websocket-react-native";
|
|
6
|
+
var PusherReactNativeTransport = class {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.pusher = Pusher.getInstance();
|
|
9
|
+
this.inited = false;
|
|
10
|
+
this.connected = false;
|
|
11
|
+
this.subscribed = /* @__PURE__ */ new Set();
|
|
12
|
+
}
|
|
13
|
+
async init(cfg) {
|
|
14
|
+
if (this.inited) return;
|
|
15
|
+
this.onDebug = cfg.onDebug;
|
|
16
|
+
await this.pusher.init({
|
|
17
|
+
apiKey: cfg.key,
|
|
18
|
+
cluster: cfg.cluster,
|
|
19
|
+
useTLS: !!cfg.forceTLS,
|
|
20
|
+
onAuthorizer: async (channelName, socketId) => {
|
|
21
|
+
this.onDebug?.("authorizer", { channelName, socketId });
|
|
22
|
+
return await cfg.authorizer(channelName, socketId);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
this.inited = true;
|
|
26
|
+
}
|
|
27
|
+
async connect() {
|
|
28
|
+
if (!this.inited || this.connected) return;
|
|
29
|
+
try {
|
|
30
|
+
await this.pusher.connect();
|
|
31
|
+
this.connected = true;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
this.onDebug?.("connect_failed", e);
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async subscribe(channelName, onEvent) {
|
|
38
|
+
if (!this.inited) throw new Error("PusherReactNativeTransport not initialized");
|
|
39
|
+
if (!this.connected) await this.connect();
|
|
40
|
+
if (this.subscribed.has(channelName)) return;
|
|
41
|
+
await this.pusher.subscribe({
|
|
42
|
+
channelName,
|
|
43
|
+
onEvent: (event) => {
|
|
44
|
+
let data = event.data;
|
|
45
|
+
try {
|
|
46
|
+
data = typeof data === "string" ? JSON.parse(data) : data;
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
onEvent(event.eventName, data);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
this.subscribed.add(channelName);
|
|
53
|
+
}
|
|
54
|
+
async unsubscribe(channelName) {
|
|
55
|
+
if (!this.inited) return;
|
|
56
|
+
if (!this.subscribed.has(channelName)) return;
|
|
57
|
+
try {
|
|
58
|
+
await this.pusher.unsubscribe({ channelName });
|
|
59
|
+
} catch (e) {
|
|
60
|
+
this.onDebug?.("unsubscribe_failed", e);
|
|
61
|
+
} finally {
|
|
62
|
+
this.subscribed.delete(channelName);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async trigger(channelName, eventName, data) {
|
|
66
|
+
if (!this.inited || !this.connected) return;
|
|
67
|
+
try {
|
|
68
|
+
await this.pusher.trigger({ channelName, eventName, data });
|
|
69
|
+
} catch (e) {
|
|
70
|
+
this.onDebug?.("trigger_failed", e);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async disconnect() {
|
|
74
|
+
if (!this.inited || !this.connected) return;
|
|
75
|
+
try {
|
|
76
|
+
for (const ch of Array.from(this.subscribed)) {
|
|
77
|
+
try {
|
|
78
|
+
await this.pusher.unsubscribe({ channelName: ch });
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.subscribed.clear();
|
|
83
|
+
await this.pusher.disconnect();
|
|
84
|
+
} catch (e) {
|
|
85
|
+
this.onDebug?.("disconnect_failed", e);
|
|
86
|
+
} finally {
|
|
87
|
+
this.connected = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export {
|
|
92
|
+
PusherReactNativeTransport
|
|
93
|
+
};
|
|
4
94
|
//# sourceMappingURL=react-native.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react-native.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/react-native.ts","../src/transports/pusher-react-native.ts"],"sourcesContent":["// packages/client/src/react-native.ts\nexport * from \"@chatinfra/sdk\";\nexport { PusherReactNativeTransport } from \"./transports/pusher-react-native\";\n","// packages/client/src/transports/pusher-react-native.ts\nimport { Pusher, type PusherEvent } from \"@pusher/pusher-websocket-react-native\";\nimport type { RealtimeTransport } from \"@chatinfra/sdk\";\n\nexport class PusherReactNativeTransport implements RealtimeTransport {\n private pusher = Pusher.getInstance();\n private inited = false;\n private connected = false;\n private subscribed = new Set<string>();\n private onDebug?: (msg: string, data?: any) => void;\n\n async init(cfg: {\n key: string;\n cluster: string;\n forceTLS: boolean;\n authorizer: (channelName: string, socketId: string) => Promise<any>;\n onDebug?: (msg: string, data?: any) => void;\n }) {\n if (this.inited) return;\n\n this.onDebug = cfg.onDebug;\n\n await this.pusher.init({\n apiKey: cfg.key,\n cluster: cfg.cluster,\n useTLS: !!cfg.forceTLS,\n onAuthorizer: async (channelName: string, socketId: string) => {\n this.onDebug?.(\"authorizer\", { channelName, socketId });\n return await cfg.authorizer(channelName, socketId);\n },\n });\n\n this.inited = true;\n }\n\n async connect() {\n if (!this.inited || this.connected) return;\n try {\n await this.pusher.connect();\n this.connected = true;\n } catch (e) {\n this.onDebug?.(\"connect_failed\", e);\n throw e;\n }\n }\n\n async subscribe(channelName: string, onEvent: (eventName: string, data: any) => void) {\n if (!this.inited) throw new Error(\"PusherReactNativeTransport not initialized\");\n if (!this.connected) await this.connect();\n if (this.subscribed.has(channelName)) return;\n\n await this.pusher.subscribe({\n channelName,\n onEvent: (event: PusherEvent) => {\n let data: any = event.data;\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : data;\n } catch {}\n onEvent(event.eventName, data);\n },\n });\n\n this.subscribed.add(channelName);\n }\n\n async unsubscribe(channelName: string) {\n if (!this.inited) return;\n if (!this.subscribed.has(channelName)) return;\n\n try {\n await this.pusher.unsubscribe({ channelName });\n } catch (e) {\n // ignore native edge cases\n this.onDebug?.(\"unsubscribe_failed\", e);\n } finally {\n this.subscribed.delete(channelName);\n }\n }\n\n async trigger(channelName: string, eventName: string, data: any) {\n if (!this.inited || !this.connected) return;\n try {\n await this.pusher.trigger({ channelName, eventName, data });\n } catch (e) {\n this.onDebug?.(\"trigger_failed\", e);\n }\n }\n\n async disconnect() {\n // ✅ avoid crash: don't call native disconnect if never connected\n if (!this.inited || !this.connected) return;\n\n try {\n // unsubscribe defensively\n for (const ch of Array.from(this.subscribed)) {\n try {\n await this.pusher.unsubscribe({ channelName: ch });\n } catch {}\n }\n this.subscribed.clear();\n\n await this.pusher.disconnect();\n } catch (e) {\n // ✅ swallow native disconnect crash scenarios\n this.onDebug?.(\"disconnect_failed\", e);\n } finally {\n this.connected = false;\n }\n }\n}\n"],"mappings":";AACA,cAAc;;;ACAd,SAAS,cAAgC;AAGlC,IAAM,6BAAN,MAA8D;AAAA,EAA9D;AACL,SAAQ,SAAS,OAAO,YAAY;AACpC,SAAQ,SAAS;AACjB,SAAQ,YAAY;AACpB,SAAQ,aAAa,oBAAI,IAAY;AAAA;AAAA,EAGrC,MAAM,KAAK,KAMR;AACD,QAAI,KAAK,OAAQ;AAEjB,SAAK,UAAU,IAAI;AAEnB,UAAM,KAAK,OAAO,KAAK;AAAA,MACrB,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,QAAQ,CAAC,CAAC,IAAI;AAAA,MACd,cAAc,OAAO,aAAqB,aAAqB;AAC7D,aAAK,UAAU,cAAc,EAAE,aAAa,SAAS,CAAC;AACtD,eAAO,MAAM,IAAI,WAAW,aAAa,QAAQ;AAAA,MACnD;AAAA,IACF,CAAC;AAED,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,UAAU;AACd,QAAI,CAAC,KAAK,UAAU,KAAK,UAAW;AACpC,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ;AAC1B,WAAK,YAAY;AAAA,IACnB,SAAS,GAAG;AACV,WAAK,UAAU,kBAAkB,CAAC;AAClC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,aAAqB,SAAiD;AACpF,QAAI,CAAC,KAAK,OAAQ,OAAM,IAAI,MAAM,4CAA4C;AAC9E,QAAI,CAAC,KAAK,UAAW,OAAM,KAAK,QAAQ;AACxC,QAAI,KAAK,WAAW,IAAI,WAAW,EAAG;AAEtC,UAAM,KAAK,OAAO,UAAU;AAAA,MAC1B;AAAA,MACA,SAAS,CAAC,UAAuB;AAC/B,YAAI,OAAY,MAAM;AACtB,YAAI;AACF,iBAAO,OAAO,SAAS,WAAW,KAAK,MAAM,IAAI,IAAI;AAAA,QACvD,QAAQ;AAAA,QAAC;AACT,gBAAQ,MAAM,WAAW,IAAI;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,SAAK,WAAW,IAAI,WAAW;AAAA,EACjC;AAAA,EAEA,MAAM,YAAY,aAAqB;AACrC,QAAI,CAAC,KAAK,OAAQ;AAClB,QAAI,CAAC,KAAK,WAAW,IAAI,WAAW,EAAG;AAEvC,QAAI;AACF,YAAM,KAAK,OAAO,YAAY,EAAE,YAAY,CAAC;AAAA,IAC/C,SAAS,GAAG;AAEV,WAAK,UAAU,sBAAsB,CAAC;AAAA,IACxC,UAAE;AACA,WAAK,WAAW,OAAO,WAAW;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,aAAqB,WAAmB,MAAW;AAC/D,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAW;AACrC,QAAI;AACF,YAAM,KAAK,OAAO,QAAQ,EAAE,aAAa,WAAW,KAAK,CAAC;AAAA,IAC5D,SAAS,GAAG;AACV,WAAK,UAAU,kBAAkB,CAAC;AAAA,IACpC;AAAA,EACF;AAAA,EAEA,MAAM,aAAa;AAEjB,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAW;AAErC,QAAI;AAEF,iBAAW,MAAM,MAAM,KAAK,KAAK,UAAU,GAAG;AAC5C,YAAI;AACF,gBAAM,KAAK,OAAO,YAAY,EAAE,aAAa,GAAG,CAAC;AAAA,QACnD,QAAQ;AAAA,QAAC;AAAA,MACX;AACA,WAAK,WAAW,MAAM;AAEtB,YAAM,KAAK,OAAO,WAAW;AAAA,IAC/B,SAAS,GAAG;AAEV,WAAK,UAAU,qBAAqB,CAAC;AAAA,IACvC,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatinfra/client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"import": "./dist/react-native.mjs"
|
|
14
|
-
},
|
|
15
|
-
"import": {
|
|
16
|
-
"types": "./dist/index.d.ts",
|
|
17
|
-
"default": "./dist/index.mjs"
|
|
18
|
-
},
|
|
19
|
-
"require": {
|
|
20
|
-
"types": "./dist/index.d.ts",
|
|
21
|
-
"default": "./dist/index.js"
|
|
22
|
-
}
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"import": "./dist/index.mjs"
|
|
23
16
|
},
|
|
24
17
|
"./react-native": {
|
|
25
18
|
"types": "./dist/react-native.d.ts",
|
|
@@ -32,18 +25,23 @@
|
|
|
32
25
|
"import": "./dist/web.mjs"
|
|
33
26
|
}
|
|
34
27
|
},
|
|
35
|
-
"files": [
|
|
36
|
-
"dist"
|
|
37
|
-
],
|
|
38
28
|
"dependencies": {
|
|
39
|
-
"@chatinfra/sdk": "0.0.1"
|
|
40
|
-
},
|
|
41
|
-
"optionalDependencies": {
|
|
42
|
-
"@chatinfra/realtime-pusher-rn": "0.0.1",
|
|
29
|
+
"@chatinfra/sdk": "0.0.1",
|
|
43
30
|
"@chatinfra/realtime-pusher-web": "0.0.1",
|
|
44
|
-
"@chatinfra/storage-web": "0.0.1"
|
|
31
|
+
"@chatinfra/storage-web": "0.0.1",
|
|
32
|
+
"@chatinfra/realtime-pusher-rn": "0.0.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"tsup": "^8.5.1",
|
|
36
|
+
"typescript": "^5.9.3",
|
|
37
|
+
"@pusher/pusher-websocket-react-native": "^1.3.2",
|
|
38
|
+
"expo-secure-store": "^15.0.8"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@pusher/pusher-websocket-react-native": "^1.3.2",
|
|
42
|
+
"expo-secure-store": "*"
|
|
45
43
|
},
|
|
46
44
|
"scripts": {
|
|
47
|
-
"build": "pnpm exec tsup"
|
|
45
|
+
"build": "pnpm exec tsup --config tsup.config.ts"
|
|
48
46
|
}
|
|
49
47
|
}
|