@perspective-ai/sdk 1.0.0-alpha.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.
Files changed (45) hide show
  1. package/README.md +333 -0
  2. package/dist/browser.cjs +1939 -0
  3. package/dist/browser.cjs.map +1 -0
  4. package/dist/browser.d.cts +213 -0
  5. package/dist/browser.d.ts +213 -0
  6. package/dist/browser.js +1900 -0
  7. package/dist/browser.js.map +1 -0
  8. package/dist/cdn/perspective.global.js +406 -0
  9. package/dist/cdn/perspective.global.js.map +1 -0
  10. package/dist/constants.cjs +142 -0
  11. package/dist/constants.cjs.map +1 -0
  12. package/dist/constants.d.cts +104 -0
  13. package/dist/constants.d.ts +104 -0
  14. package/dist/constants.js +127 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/index.cjs +1596 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.cts +155 -0
  19. package/dist/index.d.ts +155 -0
  20. package/dist/index.js +1579 -0
  21. package/dist/index.js.map +1 -0
  22. package/package.json +83 -0
  23. package/src/browser.test.ts +388 -0
  24. package/src/browser.ts +509 -0
  25. package/src/config.test.ts +81 -0
  26. package/src/config.ts +95 -0
  27. package/src/constants.ts +214 -0
  28. package/src/float.test.ts +332 -0
  29. package/src/float.ts +231 -0
  30. package/src/fullpage.test.ts +224 -0
  31. package/src/fullpage.ts +126 -0
  32. package/src/iframe.test.ts +1037 -0
  33. package/src/iframe.ts +421 -0
  34. package/src/index.ts +61 -0
  35. package/src/loading.ts +90 -0
  36. package/src/popup.test.ts +344 -0
  37. package/src/popup.ts +157 -0
  38. package/src/slider.test.ts +277 -0
  39. package/src/slider.ts +158 -0
  40. package/src/styles.ts +395 -0
  41. package/src/types.ts +148 -0
  42. package/src/utils.test.ts +162 -0
  43. package/src/utils.ts +86 -0
  44. package/src/widget.test.ts +375 -0
  45. package/src/widget.ts +195 -0
package/README.md ADDED
@@ -0,0 +1,333 @@
1
+ # @perspective-ai/sdk
2
+
3
+ Embed SDK for [Perspective AI](https://getperspective.ai).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @perspective-ai/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Vanilla JavaScript
14
+
15
+ ```html
16
+ <button id="feedback-btn">Give Feedback</button>
17
+
18
+ <script type="module">
19
+ import { openPopup } from "@perspective-ai/sdk";
20
+
21
+ document.getElementById("feedback-btn").addEventListener("click", () => {
22
+ openPopup({
23
+ researchId: "your-research-id",
24
+ onSubmit: () => {
25
+ console.log("Thank you for your feedback!");
26
+ },
27
+ });
28
+ });
29
+ </script>
30
+ ```
31
+
32
+ > **React?** Use [`@perspective-ai/sdk-react`](https://www.npmjs.com/package/@perspective-ai/sdk-react) for hooks and components.
33
+
34
+ ## Embed Types
35
+
36
+ | Type | Function | Description |
37
+ | -------- | --------------------------------- | ------------------------------- |
38
+ | Widget | `createWidget(container, config)` | Inline embed in a container |
39
+ | Popup | `openPopup(config)` | Centered modal overlay |
40
+ | Slider | `openSlider(config)` | Side panel slides in from right |
41
+ | Float | `createFloatBubble(config)` | Floating chat bubble in corner |
42
+ | Fullpage | `createFullpage(config)` | Full viewport takeover |
43
+
44
+ ### Widget (Inline Embed)
45
+
46
+ ```typescript
47
+ import { createWidget } from "@perspective-ai/sdk";
48
+
49
+ const container = document.getElementById("interview-container");
50
+ const handle = createWidget(container, {
51
+ researchId: "your-research-id",
52
+ });
53
+ ```
54
+
55
+ ### Popup Modal
56
+
57
+ ```typescript
58
+ import { openPopup } from "@perspective-ai/sdk";
59
+
60
+ const handle = openPopup({
61
+ researchId: "your-research-id",
62
+ theme: "dark",
63
+ });
64
+ ```
65
+
66
+ ### Slider Panel
67
+
68
+ ```typescript
69
+ import { openSlider } from "@perspective-ai/sdk";
70
+
71
+ const handle = openSlider({
72
+ researchId: "your-research-id",
73
+ });
74
+ ```
75
+
76
+ ### Float Bubble
77
+
78
+ ```typescript
79
+ import { createFloatBubble } from "@perspective-ai/sdk";
80
+
81
+ const handle = createFloatBubble({
82
+ researchId: "your-research-id",
83
+ });
84
+
85
+ // Control the bubble
86
+ handle.open();
87
+ handle.close();
88
+ handle.toggle();
89
+ console.log(handle.isOpen); // boolean
90
+ ```
91
+
92
+ ### Fullpage
93
+
94
+ ```typescript
95
+ import { createFullpage } from "@perspective-ai/sdk";
96
+
97
+ const handle = createFullpage({
98
+ researchId: "your-research-id",
99
+ });
100
+ ```
101
+
102
+ ## Configuration
103
+
104
+ ```typescript
105
+ interface EmbedConfig {
106
+ // Required
107
+ researchId: string;
108
+
109
+ // Optional
110
+ host?: string; // Custom API host
111
+ theme?: "light" | "dark" | "system"; // Theme preference (default: "system")
112
+ params?: Record<string, string>; // Custom URL parameters for tracking
113
+ brand?: {
114
+ light?: BrandColors; // Light mode brand colors
115
+ dark?: BrandColors; // Dark mode brand colors
116
+ };
117
+
118
+ // Callbacks
119
+ onReady?: () => void;
120
+ onSubmit?: (data: { researchId: string }) => void;
121
+ onClose?: () => void;
122
+ onNavigate?: (url: string) => void; // Handle navigation (default: window.location.href)
123
+ onError?: (error: EmbedError) => void;
124
+ }
125
+
126
+ interface BrandColors {
127
+ primary?: string; // Primary brand color
128
+ secondary?: string; // Secondary brand color
129
+ bg?: string; // Background color
130
+ text?: string; // Text color
131
+ }
132
+ ```
133
+
134
+ ## Handle API
135
+
136
+ All embed functions return a handle for programmatic control:
137
+
138
+ ### EmbedHandle (Widget, Popup, Slider, Fullpage)
139
+
140
+ ```typescript
141
+ interface EmbedHandle {
142
+ unmount(): void; // Remove the embed
143
+ update(options): void; // Update callbacks
144
+ destroy(): void; // Alias for unmount (deprecated)
145
+ readonly iframe: HTMLIFrameElement | null;
146
+ readonly container: HTMLElement | null;
147
+ readonly researchId: string;
148
+ readonly type: EmbedType;
149
+ }
150
+ ```
151
+
152
+ ### FloatHandle (Float Bubble)
153
+
154
+ ```typescript
155
+ interface FloatHandle extends EmbedHandle {
156
+ open(): void; // Open the chat window
157
+ close(): void; // Close the chat window
158
+ toggle(): void; // Toggle open/close
159
+ readonly isOpen: boolean; // Current state
160
+ readonly type: "float";
161
+ }
162
+ ```
163
+
164
+ ## Global Configuration
165
+
166
+ Configure SDK-wide defaults before creating embeds:
167
+
168
+ ```typescript
169
+ import { configure, getConfig } from "@perspective-ai/sdk";
170
+
171
+ // Set global host
172
+ configure({ host: "https://custom-host.example.com" });
173
+
174
+ // Get current config
175
+ const config = getConfig();
176
+ ```
177
+
178
+ ## Custom Parameters
179
+
180
+ Pass tracking or attribution parameters:
181
+
182
+ ```typescript
183
+ openPopup({
184
+ researchId: "your-research-id",
185
+ params: {
186
+ email: "user@example.com",
187
+ name: "John Doe",
188
+ source: "marketing-campaign",
189
+ },
190
+ });
191
+ ```
192
+
193
+ ### Reserved Parameters
194
+
195
+ These parameters are managed by the SDK and cannot be overridden via `params`:
196
+
197
+ - `embed`, `embed_type`, `theme`
198
+ - Brand colors: `brand.primary`, `brand.bg`, etc.
199
+ - UTM parameters: `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`
200
+
201
+ ## Constants
202
+
203
+ Import SSR-safe constants for advanced use cases:
204
+
205
+ ```typescript
206
+ import {
207
+ SDK_VERSION,
208
+ MESSAGE_TYPES,
209
+ DATA_ATTRS,
210
+ PARAM_KEYS,
211
+ THEME_VALUES,
212
+ } from "@perspective-ai/sdk";
213
+
214
+ // Or import from the constants submodule
215
+ import { MESSAGE_TYPES } from "@perspective-ai/sdk/constants";
216
+ ```
217
+
218
+ ### Available Constants
219
+
220
+ | Constant | Description |
221
+ | --------------- | ------------------------------------- |
222
+ | `SDK_VERSION` | Current SDK version |
223
+ | `FEATURES` | Feature flags for version negotiation |
224
+ | `MESSAGE_TYPES` | PostMessage event types |
225
+ | `DATA_ATTRS` | HTML data attribute names |
226
+ | `PARAM_KEYS` | URL parameter keys |
227
+ | `BRAND_KEYS` | Brand color parameter keys |
228
+ | `THEME_VALUES` | Valid theme values |
229
+
230
+ ## Types
231
+
232
+ All types are exported for TypeScript users:
233
+
234
+ ```typescript
235
+ import type {
236
+ EmbedConfig,
237
+ EmbedHandle,
238
+ FloatHandle,
239
+ EmbedError,
240
+ EmbedType,
241
+ BrandColors,
242
+ ThemeConfig,
243
+ SDKConfig,
244
+ } from "@perspective-ai/sdk";
245
+ ```
246
+
247
+ ## CDN / Script Tag Usage
248
+
249
+ For non-module environments, use the browser bundle:
250
+
251
+ ```html
252
+ <script src="https://getperspective.ai/v1/perspective.js"></script>
253
+ ```
254
+
255
+ ### Declarative (Data Attributes)
256
+
257
+ ```html
258
+ <!-- Inline widget -->
259
+ <div data-perspective-widget="your-research-id"></div>
260
+
261
+ <!-- Popup trigger -->
262
+ <button data-perspective-popup="your-research-id">Start Interview</button>
263
+
264
+ <!-- Slider trigger -->
265
+ <button data-perspective-slider="your-research-id">Open Survey</button>
266
+
267
+ <!-- Float bubble -->
268
+ <div data-perspective-float="your-research-id"></div>
269
+
270
+ <!-- Fullpage -->
271
+ <div data-perspective-fullpage="your-research-id"></div>
272
+ ```
273
+
274
+ ### Data Attributes Reference
275
+
276
+ | Attribute | Description |
277
+ | ----------------------------- | ------------------------------------------- |
278
+ | `data-perspective-widget` | Inline widget embed |
279
+ | `data-perspective-popup` | Popup trigger button |
280
+ | `data-perspective-slider` | Slider trigger button |
281
+ | `data-perspective-float` | Floating chat bubble |
282
+ | `data-perspective-fullpage` | Full page embed |
283
+ | `data-perspective-params` | Custom params: `"key1=value1,key2=value2"` |
284
+ | `data-perspective-theme` | Theme: `"light"`, `"dark"`, or `"system"` |
285
+ | `data-perspective-brand` | Light mode colors: `"primary=#xxx,bg=#yyy"` |
286
+ | `data-perspective-brand-dark` | Dark mode colors |
287
+ | `data-perspective-no-style` | Disable auto-styling on trigger buttons |
288
+
289
+ ### Programmatic (Global API)
290
+
291
+ ```html
292
+ <script>
293
+ // Direct functions
294
+ Perspective.openPopup({ researchId: "xxx" });
295
+ Perspective.openSlider({ researchId: "xxx" });
296
+ Perspective.createFloatBubble({ researchId: "xxx" });
297
+ Perspective.createFullpage({ researchId: "xxx" });
298
+
299
+ // Mount widget into container
300
+ Perspective.mount("#container", { researchId: "xxx" });
301
+
302
+ // Generic init with type
303
+ Perspective.init({ researchId: "xxx", type: "popup" });
304
+
305
+ // Destroy by researchId
306
+ Perspective.destroy("xxx");
307
+ Perspective.destroyAll();
308
+
309
+ // Configuration
310
+ Perspective.configure({ host: "https://custom.example.com" });
311
+ </script>
312
+ ```
313
+
314
+ ## SSR Safety
315
+
316
+ The SDK is SSR-safe. All DOM access is guarded and returns no-op handles on the server:
317
+
318
+ ```typescript
319
+ // Safe to call during SSR - returns a no-op handle
320
+ const handle = openPopup({ researchId: "xxx" });
321
+ handle.unmount(); // No-op on server
322
+ ```
323
+
324
+ ## Browser Support
325
+
326
+ - Chrome 80+
327
+ - Firefox 80+
328
+ - Safari 14+
329
+ - Edge 80+
330
+
331
+ ## License
332
+
333
+ MIT