@sailfish-ai/recorder 1.0.0-beta-2 → 1.0.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.
@@ -0,0 +1,37 @@
1
+ import { sendMessage } from "./websocket";
2
+ // Internal state to track the last sent messages
3
+ let lastIdentifyMessage = null;
4
+ let lastMetadataMessage = null;
5
+ let deviceInfoSent = false;
6
+ // Function to send identify message
7
+ export function identify(userId, traits = {}, overwrite = false) {
8
+ const message = {
9
+ type: "identify",
10
+ userId,
11
+ traits,
12
+ };
13
+ // Check if the message is the same as the last one
14
+ if (lastIdentifyMessage &&
15
+ lastIdentifyMessage.userId === userId &&
16
+ JSON.stringify(lastIdentifyMessage.traits) === JSON.stringify(traits)) {
17
+ return;
18
+ }
19
+ // Update the last sent identify message
20
+ lastIdentifyMessage = { userId, traits, overwrite };
21
+ sendMessage(message);
22
+ }
23
+ // Function to send addOrUpdateMetadata message
24
+ export function addOrUpdateMetadata(metadata) {
25
+ const message = {
26
+ type: "addOrUpdateMetadata",
27
+ metadata,
28
+ };
29
+ // Check if the message is the same as the last one
30
+ if (lastMetadataMessage &&
31
+ JSON.stringify(lastMetadataMessage) === JSON.stringify(metadata)) {
32
+ return;
33
+ }
34
+ // Update the last sent metadata message
35
+ lastMetadataMessage = metadata;
36
+ sendMessage(message);
37
+ }
@@ -0,0 +1 @@
1
+ export declare function gatherAndCacheDeviceInfo(): Promise<void>;
@@ -1,3 +1,2 @@
1
- import ReconnectingWebSocket from "reconnecting-websocket";
2
1
  export declare function cacheEvents(event: any): void;
3
- export declare function sendRecordingEvents(webSocket: ReconnectingWebSocket, sessionId: string): void;
2
+ export declare function sendRecordingEvents(webSocket: any): void;
@@ -0,0 +1,4 @@
1
+ export declare function silentFetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
2
+ export declare function exponentialBackoff<T>(fn: () => Promise<T>, action: string, retries?: number, // Max retry attempts
3
+ initialDelay?: number, // Initial delay in ms
4
+ backoffFactor?: number): Promise<T>;
@@ -1,4 +1,6 @@
1
1
  import { CaptureSettingsResponse, GraphQLResponse, StartSessionResponse } from "./types";
2
- export declare function sendGraphQLRequest<T>(operationName: string, query: string, variables: object): Promise<GraphQLResponse<T>>;
2
+ export declare function sendGraphQLRequest<T>(operationName: string, query: string, variables: object, retries?: number, // Number of retries before giving up
3
+ initialBackoff?: number, // Initial backoff in milliseconds
4
+ backoffFactor?: number): Promise<GraphQLResponse<T>>;
3
5
  export declare function fetchCaptureSettings(apiKey: string, backendApi: string): Promise<GraphQLResponse<CaptureSettingsResponse>>;
4
6
  export declare function startRecordingSession(apiKey: string, recordingId: string, backendApi: string): Promise<GraphQLResponse<StartSessionResponse>>;
@@ -12,5 +12,6 @@ export declare function startRecording({ apiKey, backendApi, }: {
12
12
  export * from "./eventCache";
13
13
  export * from "./graphql";
14
14
  export * from "./recording";
15
+ export * from "./sendSailfishMessages";
15
16
  export * from "./types";
16
17
  export * from "./websocket";
@@ -1,4 +1,5 @@
1
1
  import { LogRecordOptions } from "@sailfish-rrweb/rrweb-plugin-console-record";
2
2
  import { NetworkRecordOptions } from "@sailfish-rrweb/rrweb-plugin-network-record";
3
- export declare function initializeRecording(captureSettings: any, // TODO - Sibyl launch - replace type
4
- consoleRecordSettings: LogRecordOptions, networkRecordSettings: NetworkRecordOptions, backendApi: string, apiKey: string, sessionId: string): Promise<void>;
3
+ import ReconnectingWebSocket from "reconnecting-websocket";
4
+ export declare function initializeRecording(captureSettings: any, // TODO - Sibyl post-launch - replace type
5
+ consoleRecordSettings: LogRecordOptions, networkRecordSettings: NetworkRecordOptions, backendApi: string, apiKey: string, sessionId: string): Promise<ReconnectingWebSocket>;
@@ -0,0 +1,2 @@
1
+ export declare function identify(userId: string, traits?: Record<string, any>, overwrite?: boolean): void;
2
+ export declare function addOrUpdateMetadata(metadata: Record<string, any>): void;
@@ -1,2 +1,3 @@
1
1
  import ReconnectingWebSocket from "reconnecting-websocket";
2
2
  export declare function initializeWebSocket(backendApi: string, apiKey: string, sessionId: string): ReconnectingWebSocket;
3
+ export declare function sendMessage(message: Record<string, any>): void;
package/dist/websocket.js CHANGED
@@ -1,27 +1,45 @@
1
1
  import ReconnectingWebSocket from "reconnecting-websocket";
2
2
  import version from "./version";
3
+ // Internal WebSocket instance
4
+ let webSocket = null;
5
+ const messageQueue = [];
6
+ // Helper function to send queued messages
7
+ function flushMessageQueue() {
8
+ if (webSocket && webSocket.readyState === WebSocket.OPEN) {
9
+ while (messageQueue.length > 0) {
10
+ const message = messageQueue.shift();
11
+ if (message) {
12
+ webSocket.send(message);
13
+ }
14
+ }
15
+ }
16
+ }
3
17
  export function initializeWebSocket(backendApi, apiKey, sessionId) {
4
18
  const wsHost = getWebSocketHost(backendApi);
5
19
  const wsScheme = window.location.protocol === "https:" ? "wss" : "ws";
6
20
  const wsUrl = `${wsScheme}://${wsHost}/ws/notify/?apiKey=${apiKey}&sessionId=${sessionId}&sender=JS%2FTS&version=${version}`;
7
21
  const options = {
8
- connectionTimeout: 5000,
22
+ connectionTimeout: 10000,
9
23
  };
10
- const webSocket = new ReconnectingWebSocket(wsUrl, [], options);
11
- // This is done automatically via ReconnectingWebSocket
12
- // webSocket.addEventListener("close", (event: any) => {
13
- // console.log("WebSocket closed:", event);
14
- // if (event.wasClean) {
15
- // console.log(`Closed cleanly, code=${event.code}, reason=${event.reason}`);
16
- // } else {
17
- // console.log("Connection died");
18
- // }
19
- // });
20
- // webSocket.addEventListener("error", (error: any) => {
21
- // console.error("WebSocket error:", error);
22
- // });
24
+ webSocket = new ReconnectingWebSocket(wsUrl, [], options);
25
+ webSocket.addEventListener("open", () => {
26
+ flushMessageQueue();
27
+ });
28
+ webSocket.addEventListener("close", () => {
29
+ // Handle reconnect logic or cleanup here if needed
30
+ webSocket = null;
31
+ });
23
32
  return webSocket;
24
33
  }
34
+ export function sendMessage(message) {
35
+ const messageString = JSON.stringify(message);
36
+ if (webSocket && webSocket.readyState === WebSocket.OPEN) {
37
+ webSocket.send(messageString);
38
+ }
39
+ else {
40
+ messageQueue.push(messageString);
41
+ }
42
+ }
25
43
  function getWebSocketHost(url) {
26
44
  const parser = document.createElement("a");
27
45
  parser.href = url;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/recorder",
3
- "version": "1.0.0-beta-2",
3
+ "version": "1.0.2",
4
4
  "publishPublicly": true,
5
5
  "main": "dist/sailfish-recorder.umd.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -11,20 +11,19 @@
11
11
  "test:watch": "vitest watch",
12
12
  "check-types": "tsc --noEmit",
13
13
  "prepublish": "npm run check-types && npm run build",
14
- "artifactregistry-login": "npx google-artifactregistry-auth"
14
+ "artifactregistry-login": "npx google-artifactregistry-auth",
15
+ "publish-local": "npm publish --registry http://localhost:4873 --//localhost:4873/:_authToken=none"
15
16
  },
16
17
  "files": [
17
18
  "dist"
18
19
  ],
19
20
  "dependencies": {
20
- "@sailfish-rrweb/record": "^0.1.1-sailfish",
21
- "@sailfish-rrweb/rrweb": "^0.1.1-sailfish",
22
- "@sailfish-rrweb/rrweb-plugin-console-record": "^0.1.1-sailfish",
23
- "@sailfish-rrweb/rrweb-plugin-network-record": "^0.1.1-sailfish",
24
- "@sailfish-rrweb/rrweb-snapshot": "^0.1.1-sailfish",
25
- "@sailfish-rrweb/types": "^0.1.1-sailfish",
26
- "@vitejs/plugin-react": "^4.3.1",
27
- "@vitejs/plugin-vue": "^5.0.5",
21
+ "@sailfish-rrweb/record": "0.2.5",
22
+ "@sailfish-rrweb/rrweb": "0.2.5",
23
+ "@sailfish-rrweb/rrweb-plugin-console-record": "0.2.5",
24
+ "@sailfish-rrweb/rrweb-plugin-network-record": "0.2.5",
25
+ "@sailfish-rrweb/rrweb-snapshot": "0.2.5",
26
+ "@sailfish-rrweb/types": "0.2.5",
28
27
  "reconnecting-websocket": "^4.4.0",
29
28
  "uuid": "^10.0.0",
30
29
  "vite": "^5.3.4",
@@ -34,6 +33,8 @@
34
33
  "@types/jest": "^29.5.12",
35
34
  "@types/node": "^18.0.0",
36
35
  "@types/uuid": "^10.0.0",
36
+ "@vitejs/plugin-react": "^4.3.1",
37
+ "@vitejs/plugin-vue": "^5.1.3",
37
38
  "jest": "^29.7.0",
38
39
  "jest-transform-stub": "^2.0.0",
39
40
  "ts-jest": "^29.2.3",