@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.
- package/README.md +333 -0
- package/dist/browser.cjs +1939 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +213 -0
- package/dist/browser.d.ts +213 -0
- package/dist/browser.js +1900 -0
- package/dist/browser.js.map +1 -0
- package/dist/cdn/perspective.global.js +406 -0
- package/dist/cdn/perspective.global.js.map +1 -0
- package/dist/constants.cjs +142 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +104 -0
- package/dist/constants.d.ts +104 -0
- package/dist/constants.js +127 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.cjs +1596 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +155 -0
- package/dist/index.d.ts +155 -0
- package/dist/index.js +1579 -0
- package/dist/index.js.map +1 -0
- package/package.json +83 -0
- package/src/browser.test.ts +388 -0
- package/src/browser.ts +509 -0
- package/src/config.test.ts +81 -0
- package/src/config.ts +95 -0
- package/src/constants.ts +214 -0
- package/src/float.test.ts +332 -0
- package/src/float.ts +231 -0
- package/src/fullpage.test.ts +224 -0
- package/src/fullpage.ts +126 -0
- package/src/iframe.test.ts +1037 -0
- package/src/iframe.ts +421 -0
- package/src/index.ts +61 -0
- package/src/loading.ts +90 -0
- package/src/popup.test.ts +344 -0
- package/src/popup.ts +157 -0
- package/src/slider.test.ts +277 -0
- package/src/slider.ts +158 -0
- package/src/styles.ts +395 -0
- package/src/types.ts +148 -0
- package/src/utils.test.ts +162 -0
- package/src/utils.ts +86 -0
- package/src/widget.test.ts +375 -0
- 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
|