@firstlook-uat/sdk 0.2.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 ADDED
@@ -0,0 +1,139 @@
1
+ # @firstlook/sdk
2
+
3
+ A framework-agnostic UAT (User Acceptance Testing) SDK for web applications. Embed quest-driven test flows, session recording, voice annotations, and shake-to-report bug reporting into any web app with a single script tag or npm import.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # npm
9
+ npm install @firstlook/sdk
10
+
11
+ # yarn
12
+ yarn add @firstlook/sdk
13
+
14
+ # pnpm
15
+ pnpm add @firstlook/sdk
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ### npm / ES Module
21
+
22
+ ```ts
23
+ import { FirstLookSDK } from "@firstlook/sdk";
24
+
25
+ const sdk = new FirstLookSDK();
26
+
27
+ await sdk.init({
28
+ projectId: "proj_xxx",
29
+ apiKey: "flk_xxx",
30
+ userId: "tester@example.com",
31
+ });
32
+
33
+ sdk.activate();
34
+
35
+ await sdk.startSession([
36
+ { id: "q1", title: "Add to Cart", description: "Add any item to the cart", order: 1 },
37
+ { id: "q2", title: "Checkout", description: "Complete the checkout flow", order: 2, blocking: true },
38
+ ]);
39
+ ```
40
+
41
+ ### CDN / UMD
42
+
43
+ ```html
44
+ <script src="https://unpkg.com/@firstlook/sdk/dist/firstlook.umd.js"></script>
45
+ <script>
46
+ const sdk = new FirstLook.FirstLookSDK();
47
+ sdk.init({
48
+ projectId: "proj_xxx",
49
+ apiKey: "flk_xxx",
50
+ userId: "tester@example.com",
51
+ }).then(() => sdk.activate());
52
+ </script>
53
+ ```
54
+
55
+ ## Configuration
56
+
57
+ All options are passed to `sdk.init()`. Only `projectId`, `apiKey`, and `userId` are required.
58
+
59
+ | Option | Type | Default | Description |
60
+ |--------|------|---------|-------------|
61
+ | `projectId` | `string` | *required* | Project ID from the FirstLook dashboard |
62
+ | `apiKey` | `string` | *required* | API key for authentication |
63
+ | `userId` | `string` | *required* | Unique identifier for the current tester |
64
+ | `role` | `string` | `undefined` | Optional role label (e.g. `"admin"`, `"tester"`) |
65
+ | `context` | `Record<string, unknown>` | `{}` | Arbitrary metadata attached to the session |
66
+ | `endpoint` | `string` | Production URL | Custom endpoint for session data upload |
67
+ | `triggers.tapCount` | `number` | `5` | Number of taps to open the debug menu |
68
+ | `triggers.deepLink` | `boolean` | `true` | Enable deep link activation (`?firstlook=1`) |
69
+ | `triggers.shake` | `boolean` | `true` | Enable shake-to-activate on mobile |
70
+ | `triggers.customCheck` | `() => boolean` | `undefined` | Custom function to auto-activate on init |
71
+ | `security.watermark` | `boolean` | `true` | Show dynamic watermark during recording |
72
+ | `security.maskSelectors` | `string[]` | `['input[type="password"]', '[data-sensitive]', '[data-mask]', '.uat-mask']` | CSS selectors for fields to mask |
73
+ | `recording.domSnapshot` | `boolean` | `true` | Enable DOM mutation recording |
74
+ | `recording.voice` | `boolean` | `true` | Enable voice recording |
75
+ | `recording.maxDuration` | `number` | `600` | Max recording duration in seconds |
76
+ | `recording.snapshotInterval` | `number` | `1000` | DOM snapshot interval in milliseconds |
77
+
78
+ ## API Reference
79
+
80
+ ### `init(config: FirstLookConfig): Promise<void>`
81
+
82
+ Initialize the SDK. Sets up triggers, IndexedDB storage, and Shadow DOM host. Does **not** activate the UI.
83
+
84
+ ### `activate(): void`
85
+
86
+ Manually activate the SDK UI, bypassing configured triggers. Must be called after `init()`.
87
+
88
+ ### `startSession(quests: Quest[]): Promise<string>`
89
+
90
+ Start a UAT session with a list of quests. Returns the generated session ID. The SDK must be in the `active` state.
91
+
92
+ ### `startSessionFromRemote(questSetId: string): Promise<string>`
93
+
94
+ Fetch quest definitions from the API by quest set ID, then start a session. Returns the session ID.
95
+
96
+ ### `endSession(): Promise<SessionData | null>`
97
+
98
+ End the current recording session. Stops all recorders, persists data to IndexedDB, and enqueues the session for upload. Returns the session data or `null` if no session was active.
99
+
100
+ ### `on(type: SDKEventType | "*", listener: SDKEventListener): () => void`
101
+
102
+ Subscribe to SDK events. Returns an unsubscribe function.
103
+
104
+ Available event types: `sdk:initialized`, `sdk:activated`, `sdk:deactivated`, `session:started`, `session:ended`, `quest:started`, `quest:completed`, `quest:failed`, `quest:blocked`, `recording:started`, `recording:stopped`, `report:submitted`, `error`.
105
+
106
+ ```ts
107
+ const unsubscribe = sdk.on("session:ended", (event) => {
108
+ console.log("Session ended:", event.sessionId);
109
+ });
110
+
111
+ // Later...
112
+ unsubscribe();
113
+ ```
114
+
115
+ ### `getState(): SDKState`
116
+
117
+ Returns the current SDK state: `"idle"` | `"initialized"` | `"active"` | `"recording"` | `"finished"`.
118
+
119
+ ### `destroy(): void`
120
+
121
+ Completely destroy the SDK instance. Removes all DOM elements, stops recorders, clears timers, and resets state to `idle`.
122
+
123
+ ## Quest Format
124
+
125
+ Each quest in the `quests` array must conform to:
126
+
127
+ ```ts
128
+ interface Quest {
129
+ id: string; // Unique quest identifier
130
+ title: string; // Short display title
131
+ description: string; // Instructions for the tester
132
+ order: number; // Sequence order (1-based)
133
+ blocking?: boolean; // If true, failure blocks subsequent quests
134
+ }
135
+ ```
136
+
137
+ ## License
138
+
139
+ MIT