@upscopeio/react-native-sdk 2026.3.0
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 +291 -0
- package/android/build.gradle.kts +36 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/kotlin/io/upscope/reactnative/UpscopeMaskedViewManager.kt +31 -0
- package/android/src/main/kotlin/io/upscope/reactnative/UpscopeModule.kt +297 -0
- package/android/src/main/kotlin/io/upscope/reactnative/UpscopePackage.kt +31 -0
- package/ios/UpscopeMaskedView.swift +18 -0
- package/ios/UpscopeMaskedViewManager.mm +4 -0
- package/ios/UpscopeMaskedViewManager.swift +13 -0
- package/ios/UpscopeModule.mm +31 -0
- package/ios/UpscopeModule.swift +243 -0
- package/lib/commonjs/NativeUpscopeMaskedView.js +10 -0
- package/lib/commonjs/NativeUpscopeMaskedView.js.map +1 -0
- package/lib/commonjs/NativeUpscopeModule.js +9 -0
- package/lib/commonjs/NativeUpscopeModule.js.map +1 -0
- package/lib/commonjs/Upscope.js +95 -0
- package/lib/commonjs/Upscope.js.map +1 -0
- package/lib/commonjs/UpscopeMasked.js +22 -0
- package/lib/commonjs/UpscopeMasked.js.map +1 -0
- package/lib/commonjs/hooks.js +98 -0
- package/lib/commonjs/hooks.js.map +1 -0
- package/lib/commonjs/index.js +58 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/NativeUpscopeMaskedView.js +5 -0
- package/lib/module/NativeUpscopeMaskedView.js.map +1 -0
- package/lib/module/NativeUpscopeModule.js +5 -0
- package/lib/module/NativeUpscopeModule.js.map +1 -0
- package/lib/module/Upscope.js +91 -0
- package/lib/module/Upscope.js.map +1 -0
- package/lib/module/UpscopeMasked.js +17 -0
- package/lib/module/UpscopeMasked.js.map +1 -0
- package/lib/module/hooks.js +89 -0
- package/lib/module/hooks.js.map +1 -0
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/NativeUpscopeMaskedView.d.ts +7 -0
- package/lib/typescript/NativeUpscopeMaskedView.d.ts.map +1 -0
- package/lib/typescript/NativeUpscopeModule.d.ts +20 -0
- package/lib/typescript/NativeUpscopeModule.d.ts.map +1 -0
- package/lib/typescript/Upscope.d.ts +60 -0
- package/lib/typescript/Upscope.d.ts.map +1 -0
- package/lib/typescript/UpscopeMasked.d.ts +7 -0
- package/lib/typescript/UpscopeMasked.d.ts.map +1 -0
- package/lib/typescript/hooks.d.ts +36 -0
- package/lib/typescript/hooks.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +8 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +79 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +94 -0
- package/src/NativeUpscopeMaskedView.ts +9 -0
- package/src/NativeUpscopeModule.ts +32 -0
- package/src/Upscope.ts +113 -0
- package/src/UpscopeMasked.tsx +19 -0
- package/src/hooks.ts +99 -0
- package/src/index.ts +34 -0
- package/src/types.ts +109 -0
- package/upscopeio-react-native-sdk.podspec +17 -0
package/src/Upscope.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { NativeEventEmitter } from "react-native";
|
|
2
|
+
import NativeUpscopeModule from "./NativeUpscopeModule";
|
|
3
|
+
import type {
|
|
4
|
+
UpscopeConfig,
|
|
5
|
+
ConnectionUpdateParams,
|
|
6
|
+
UpscopeEventMap,
|
|
7
|
+
UpscopeEventName,
|
|
8
|
+
} from "./types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscription handle returned by addListener. Callers must invoke remove()
|
|
12
|
+
* to avoid memory leaks when the component/scope unmounts.
|
|
13
|
+
*/
|
|
14
|
+
export interface EventSubscription {
|
|
15
|
+
remove(): void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Module-level emitter — one instance for the lifetime of the JS runtime.
|
|
19
|
+
const emitter = new NativeEventEmitter(NativeUpscopeModule);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Imperative JS API over the native Upscope TurboModule.
|
|
23
|
+
*
|
|
24
|
+
* All methods are thin typed wrappers; no business logic lives here.
|
|
25
|
+
* Prefer using the React hooks in this package inside components.
|
|
26
|
+
*/
|
|
27
|
+
const Upscope = {
|
|
28
|
+
/** Initialise the SDK. Must be called before any other method. */
|
|
29
|
+
initialize(config: UpscopeConfig): void {
|
|
30
|
+
NativeUpscopeModule.initialize(config as unknown as Object);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/** Open a WebSocket connection to the Upscope service. */
|
|
34
|
+
connect(): void {
|
|
35
|
+
NativeUpscopeModule.connect();
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/** Close the WebSocket connection. */
|
|
39
|
+
disconnect(): void {
|
|
40
|
+
NativeUpscopeModule.disconnect();
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Reset the connection state.
|
|
45
|
+
* @param reconnect - Whether to reconnect immediately after reset. Defaults to true.
|
|
46
|
+
*/
|
|
47
|
+
reset(reconnect: boolean = true): void {
|
|
48
|
+
NativeUpscopeModule.reset(reconnect);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Update user identity and metadata sent to the Upscope service.
|
|
53
|
+
* Safe to call at any time; changes are pushed on the next sync.
|
|
54
|
+
*/
|
|
55
|
+
updateConnection(params: ConnectionUpdateParams): void {
|
|
56
|
+
NativeUpscopeModule.updateConnection(params as unknown as Object);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
/** Terminate the active co-browsing session. */
|
|
60
|
+
stopSession(): void {
|
|
61
|
+
NativeUpscopeModule.stopSession();
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/** Request that an agent join the current session. */
|
|
65
|
+
requestAgent(): void {
|
|
66
|
+
NativeUpscopeModule.requestAgent();
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
/** Cancel a pending agent-join request. */
|
|
70
|
+
cancelAgentRequest(): void {
|
|
71
|
+
NativeUpscopeModule.cancelAgentRequest();
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Ask the native layer to emit the current lookup code via the
|
|
76
|
+
* `lookupCodeChanged` event. The lookup code itself is delivered
|
|
77
|
+
* asynchronously through the event system.
|
|
78
|
+
*/
|
|
79
|
+
getLookupCode(): void {
|
|
80
|
+
NativeUpscopeModule.getLookupCode();
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/** Resolve the current short ID, or null if not yet assigned. */
|
|
84
|
+
getShortId(): Promise<string | null> {
|
|
85
|
+
return NativeUpscopeModule.getShortId();
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/** Resolve the watch link for the current session, or null if unavailable. */
|
|
89
|
+
getWatchLink(): Promise<string | null> {
|
|
90
|
+
return NativeUpscopeModule.getWatchLink();
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
/** Send an arbitrary string message to all connected observers. */
|
|
94
|
+
sendCustomMessage(message: string): void {
|
|
95
|
+
NativeUpscopeModule.sendCustomMessage(message);
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Subscribe to a typed Upscope event.
|
|
100
|
+
*
|
|
101
|
+
* @param eventName - One of the well-known event names from UpscopeEventMap.
|
|
102
|
+
* @param callback - Invoked with the strongly-typed payload on each event.
|
|
103
|
+
* @returns A subscription handle. Call `.remove()` to unsubscribe.
|
|
104
|
+
*/
|
|
105
|
+
addListener<E extends UpscopeEventName>(
|
|
106
|
+
eventName: E,
|
|
107
|
+
callback: (event: UpscopeEventMap[E]) => void,
|
|
108
|
+
): EventSubscription {
|
|
109
|
+
return emitter.addListener(eventName, callback);
|
|
110
|
+
},
|
|
111
|
+
} as const;
|
|
112
|
+
|
|
113
|
+
export default Upscope;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { ViewProps } from "react-native";
|
|
3
|
+
import NativeUpscopeMaskedView from "./NativeUpscopeMaskedView";
|
|
4
|
+
|
|
5
|
+
export interface UpscopeMaskedProps extends ViewProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function UpscopeMasked({
|
|
10
|
+
children,
|
|
11
|
+
style,
|
|
12
|
+
...props
|
|
13
|
+
}: UpscopeMaskedProps) {
|
|
14
|
+
return (
|
|
15
|
+
<NativeUpscopeMaskedView style={style} {...props}>
|
|
16
|
+
{children}
|
|
17
|
+
</NativeUpscopeMaskedView>
|
|
18
|
+
);
|
|
19
|
+
}
|
package/src/hooks.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from "react";
|
|
2
|
+
import Upscope from "./Upscope";
|
|
3
|
+
import type { ConnectionState, SessionState } from "./types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the current WebSocket connection state, updated reactively via the
|
|
7
|
+
* `connectionStateChanged` event. Starts as "inactive" before the first event.
|
|
8
|
+
*/
|
|
9
|
+
export function useConnectionState(): ConnectionState {
|
|
10
|
+
const [state, setState] = useState<ConnectionState>("inactive");
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const sub = Upscope.addListener("connectionStateChanged", (event) => {
|
|
14
|
+
setState(event.state);
|
|
15
|
+
});
|
|
16
|
+
return () => sub.remove();
|
|
17
|
+
}, []);
|
|
18
|
+
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the current co-browsing session state. Transitions to "active" on
|
|
24
|
+
* `sessionStarted` and back to "inactive" on `sessionEnded`.
|
|
25
|
+
*/
|
|
26
|
+
export function useSessionState(): SessionState {
|
|
27
|
+
const [state, setState] = useState<SessionState>("inactive");
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const subStart = Upscope.addListener("sessionStarted", () => {
|
|
31
|
+
setState("active");
|
|
32
|
+
});
|
|
33
|
+
const subEnd = Upscope.addListener("sessionEnded", () => {
|
|
34
|
+
setState("inactive");
|
|
35
|
+
});
|
|
36
|
+
return () => {
|
|
37
|
+
subStart.remove();
|
|
38
|
+
subEnd.remove();
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
41
|
+
|
|
42
|
+
return state;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns the SDK short ID, or null if not yet assigned.
|
|
47
|
+
* Resolves the current value on mount and stays in sync via `shortIdChanged`.
|
|
48
|
+
*/
|
|
49
|
+
export function useShortId(): string | null {
|
|
50
|
+
const [shortId, setShortId] = useState<string | null>(null);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
// Seed with the current value; the listener handles all subsequent changes.
|
|
54
|
+
Upscope.getShortId().then(setShortId);
|
|
55
|
+
const sub = Upscope.addListener("shortIdChanged", (event) => {
|
|
56
|
+
setShortId(event.shortId);
|
|
57
|
+
});
|
|
58
|
+
return () => sub.remove();
|
|
59
|
+
}, []);
|
|
60
|
+
|
|
61
|
+
return shortId;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the current lookup code, or null until the native layer emits one.
|
|
66
|
+
* Updated reactively via `lookupCodeChanged`.
|
|
67
|
+
*/
|
|
68
|
+
export function useLookupCode(): string | null {
|
|
69
|
+
const [code, setCode] = useState<string | null>(null);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const sub = Upscope.addListener("lookupCodeChanged", (event) => {
|
|
73
|
+
setCode(event.lookupCode);
|
|
74
|
+
});
|
|
75
|
+
return () => sub.remove();
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
return code;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns a stable object of imperative Upscope action methods.
|
|
83
|
+
* Safe to use as a dependency in `useCallback` / `useEffect`.
|
|
84
|
+
*/
|
|
85
|
+
export function useUpscope() {
|
|
86
|
+
return useMemo(
|
|
87
|
+
() => ({
|
|
88
|
+
connect: Upscope.connect,
|
|
89
|
+
disconnect: Upscope.disconnect,
|
|
90
|
+
stopSession: Upscope.stopSession,
|
|
91
|
+
requestAgent: Upscope.requestAgent,
|
|
92
|
+
cancelAgentRequest: Upscope.cancelAgentRequest,
|
|
93
|
+
sendCustomMessage: Upscope.sendCustomMessage,
|
|
94
|
+
getLookupCode: Upscope.getLookupCode,
|
|
95
|
+
reset: Upscope.reset,
|
|
96
|
+
}),
|
|
97
|
+
[],
|
|
98
|
+
);
|
|
99
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { default as default } from "./Upscope";
|
|
2
|
+
export { default as Upscope } from "./Upscope";
|
|
3
|
+
export type { EventSubscription } from "./Upscope";
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
useConnectionState,
|
|
7
|
+
useSessionState,
|
|
8
|
+
useShortId,
|
|
9
|
+
useLookupCode,
|
|
10
|
+
useUpscope,
|
|
11
|
+
} from "./hooks";
|
|
12
|
+
|
|
13
|
+
export { UpscopeMasked } from "./UpscopeMasked";
|
|
14
|
+
export type { UpscopeMaskedProps } from "./UpscopeMasked";
|
|
15
|
+
|
|
16
|
+
export type {
|
|
17
|
+
ConnectionState,
|
|
18
|
+
SessionState,
|
|
19
|
+
SessionEndReason,
|
|
20
|
+
UpscopeError,
|
|
21
|
+
UpscopeConfig,
|
|
22
|
+
ConnectionUpdateParams,
|
|
23
|
+
Observer,
|
|
24
|
+
UpscopeEventMap,
|
|
25
|
+
UpscopeEventName,
|
|
26
|
+
ConnectionStateChangedEvent,
|
|
27
|
+
SessionStartedEvent,
|
|
28
|
+
SessionEndedEvent,
|
|
29
|
+
CustomMessageEvent,
|
|
30
|
+
ObserverCountChangedEvent,
|
|
31
|
+
ObserverLeftEvent,
|
|
32
|
+
ShortIdChangedEvent,
|
|
33
|
+
LookupCodeChangedEvent,
|
|
34
|
+
} from "./types";
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export type ConnectionState =
|
|
2
|
+
| "inactive"
|
|
3
|
+
| "connecting"
|
|
4
|
+
| "connected"
|
|
5
|
+
| "reconnecting"
|
|
6
|
+
| "error";
|
|
7
|
+
|
|
8
|
+
export type SessionState =
|
|
9
|
+
| "inactive"
|
|
10
|
+
| "pendingRequest"
|
|
11
|
+
| "active"
|
|
12
|
+
| "paused"
|
|
13
|
+
| "ended";
|
|
14
|
+
|
|
15
|
+
export type SessionEndReason =
|
|
16
|
+
| "userStopped"
|
|
17
|
+
| "agentStopped"
|
|
18
|
+
| "timeout"
|
|
19
|
+
| "error";
|
|
20
|
+
|
|
21
|
+
export interface UpscopeError {
|
|
22
|
+
readonly code: string;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface UpscopeConfig {
|
|
27
|
+
readonly apiKey: string;
|
|
28
|
+
readonly requireAuthorizationForSession?: boolean;
|
|
29
|
+
readonly autoConnect?: boolean;
|
|
30
|
+
readonly region?: string;
|
|
31
|
+
readonly showBanner?: boolean;
|
|
32
|
+
readonly showTerminateButton?: boolean;
|
|
33
|
+
readonly authorizationPromptTitle?: string;
|
|
34
|
+
readonly authorizationPromptMessage?: string;
|
|
35
|
+
readonly endOfSessionMessage?: string;
|
|
36
|
+
readonly stopSessionText?: string;
|
|
37
|
+
readonly allowRemoteClick?: boolean;
|
|
38
|
+
readonly allowRemoteScroll?: boolean;
|
|
39
|
+
readonly requireControlRequest?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ConnectionUpdateParams {
|
|
43
|
+
readonly uniqueId?: string;
|
|
44
|
+
readonly callName?: string;
|
|
45
|
+
readonly tags?: readonly string[];
|
|
46
|
+
readonly identities?: readonly string[];
|
|
47
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface Observer {
|
|
51
|
+
readonly id: string;
|
|
52
|
+
readonly name: string | null;
|
|
53
|
+
readonly screenWidth: number;
|
|
54
|
+
readonly screenHeight: number;
|
|
55
|
+
readonly windowWidth: number;
|
|
56
|
+
readonly windowHeight: number;
|
|
57
|
+
readonly hasFocus: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Event payload types
|
|
61
|
+
export interface ConnectionStateChangedEvent {
|
|
62
|
+
readonly state: ConnectionState;
|
|
63
|
+
readonly error?: UpscopeError;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface SessionStartedEvent {
|
|
67
|
+
readonly agentName: string | null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface SessionEndedEvent {
|
|
71
|
+
readonly reason: SessionEndReason;
|
|
72
|
+
readonly error?: UpscopeError;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface CustomMessageEvent {
|
|
76
|
+
readonly message: string;
|
|
77
|
+
readonly observerId: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ObserverCountChangedEvent {
|
|
81
|
+
readonly count: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ObserverLeftEvent {
|
|
85
|
+
readonly observerId: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface ShortIdChangedEvent {
|
|
89
|
+
readonly shortId: string | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface LookupCodeChangedEvent {
|
|
93
|
+
readonly lookupCode: string | null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type UpscopeEventMap = {
|
|
97
|
+
readonly connectionStateChanged: ConnectionStateChangedEvent;
|
|
98
|
+
readonly sessionStarted: SessionStartedEvent;
|
|
99
|
+
readonly sessionEnded: SessionEndedEvent;
|
|
100
|
+
readonly customMessageReceived: CustomMessageEvent;
|
|
101
|
+
readonly error: UpscopeError;
|
|
102
|
+
readonly observerJoined: Observer;
|
|
103
|
+
readonly observerLeft: ObserverLeftEvent;
|
|
104
|
+
readonly observerCountChanged: ObserverCountChangedEvent;
|
|
105
|
+
readonly shortIdChanged: ShortIdChangedEvent;
|
|
106
|
+
readonly lookupCodeChanged: LookupCodeChangedEvent;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type UpscopeEventName = keyof UpscopeEventMap;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Pod::Spec.new do |s|
|
|
2
|
+
s.name = "upscopeio-react-native-sdk"
|
|
3
|
+
s.version = "0.1.0"
|
|
4
|
+
s.summary = "React Native SDK for Upscope cobrowsing"
|
|
5
|
+
s.homepage = "https://github.com/upscopeio/react-native-sdk"
|
|
6
|
+
s.license = "MIT"
|
|
7
|
+
s.authors = "Upscope"
|
|
8
|
+
s.source = { :git => "https://github.com/upscopeio/react-native-sdk.git", :tag => s.version }
|
|
9
|
+
|
|
10
|
+
s.platforms = { :ios => "14.0" }
|
|
11
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
12
|
+
s.swift_version = "5.9"
|
|
13
|
+
|
|
14
|
+
s.dependency "UpscopeSDK"
|
|
15
|
+
|
|
16
|
+
install_modules_dependencies(s)
|
|
17
|
+
end
|