@siteping/widget 0.9.6 → 0.9.7

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/dist/schema.d.ts CHANGED
@@ -62,6 +62,15 @@ export declare const SITEPING_MODELS: Readonly<{
62
62
  readonly url: {
63
63
  readonly type: "String";
64
64
  };
65
+ readonly urlPattern: {
66
+ readonly type: "String";
67
+ readonly optional: true;
68
+ };
69
+ readonly screenshotUrl: {
70
+ readonly type: "String";
71
+ readonly optional: true;
72
+ readonly nativeType: "Text";
73
+ };
65
74
  readonly viewport: {
66
75
  readonly type: "String";
67
76
  };
@@ -102,6 +111,8 @@ export declare const SITEPING_MODELS: Readonly<{
102
111
  readonly fields: ["projectName"];
103
112
  }, {
104
113
  readonly fields: ["projectName", "status", "createdAt"];
114
+ }, {
115
+ readonly fields: ["projectName", "url"];
105
116
  }];
106
117
  };
107
118
  readonly SitepingAnnotation: {
@@ -158,6 +169,10 @@ export declare const SITEPING_MODELS: Readonly<{
158
169
  readonly type: "String";
159
170
  readonly nativeType: "Text";
160
171
  };
172
+ readonly anchorKey: {
173
+ readonly type: "String";
174
+ readonly optional: true;
175
+ };
161
176
  readonly xPct: {
162
177
  readonly type: "Float";
163
178
  };
@@ -1,4 +1,5 @@
1
1
  export type { FieldDef, IndexDef, ModelDef } from "./schema.js";
2
2
  export { SITEPING_MODELS } from "./schema.js";
3
- export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, FeedbackCreateInput, FeedbackPayload, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackStatus, FeedbackType, FeedbackUpdateInput, RectData, SitepingConfig, SitepingInstance, SitepingPublicEvents, SitepingStore, } from "./types.js";
3
+ export type { ScreenshotStorage } from "./screenshot-storage.js";
4
+ export type { AnchorData, AnnotationCreateInput, AnnotationPayload, AnnotationRecord, AnnotationResponse, FeedbackCreateInput, FeedbackPayload, FeedbackQuery, FeedbackRecord, FeedbackResponse, FeedbackStatus, FeedbackType, FeedbackUpdateInput, PageScope, RectData, SitepingConfig, SitepingInstance, SitepingPublicEvents, SitepingStore, } from "./types.js";
4
5
  export { FEEDBACK_STATUSES, FEEDBACK_TYPES, flattenAnnotation, isStoreDuplicate, isStoreNotFound, StoreDuplicateError, StoreNotFoundError, } from "./types.js";
package/dist/types.d.ts CHANGED
@@ -18,6 +18,45 @@ export interface SitepingConfig {
18
18
  theme?: "light" | "dark" | "auto";
19
19
  /** UI locale — defaults to 'en'. Built-in: en, fr, de, es, it, pt (Brazilian), ru. Any other string falls back to English. */
20
20
  locale?: "en" | "fr" | "de" | "es" | "it" | "pt" | "ru" | (string & {}) | undefined;
21
+ /**
22
+ * Returns the current page scope for annotations and panel filtering.
23
+ * Called on initial markers load and on `instance.refresh()`.
24
+ *
25
+ * Default: `{ url: window.location.pathname, urlPattern: null }` — annotations
26
+ * are scoped strictly to the current pathname.
27
+ *
28
+ * Apps with parameterized routes (e.g. React Router) should return both the
29
+ * concrete URL and the route template (e.g. `/orders/:orderId`) so the panel
30
+ * can offer a "this type of page" filter that groups feedbacks by template.
31
+ */
32
+ getPageScope?: (() => PageScope) | undefined;
33
+ /**
34
+ * When true (default), the widget filters initial markers and panel results
35
+ * by `feedback.url === scope.url`, so annotations created on one page never
36
+ * leak to other pages — even if their CSS selector accidentally matches.
37
+ * Set to `false` to revert to the legacy project-wide behavior.
38
+ */
39
+ scopeAnnotationsByUrl?: boolean | undefined;
40
+ /**
41
+ * Capture a JPEG screenshot of the annotated area on submit. Defaults to
42
+ * `false` — opt-in because:
43
+ *
44
+ * - it adds runtime weight (~40 KB gzip dynamic chunk for html2canvas,
45
+ * loaded only on first capture),
46
+ * - it embeds page content in the feedback (privacy/GDPR consideration —
47
+ * inform end users in your widget host UI when enabling).
48
+ *
49
+ * `html2canvas` ships as a regular dependency of `@siteping/widget` so the
50
+ * dynamic import always resolves; you don't need to install anything extra.
51
+ *
52
+ * **Masking sensitive elements:** add `data-siteping-ignore="true"` to any
53
+ * element you do NOT want captured (password fields, credit-card forms,
54
+ * API tokens shown in the UI, etc.). The capture predicate skips matching
55
+ * elements *and their descendants*. Do this BEFORE turning on screenshots
56
+ * in production — once a feedback is saved, the screenshot is in your DB
57
+ * (or object storage) regardless of what was on the page.
58
+ */
59
+ enableScreenshot?: boolean | undefined;
21
60
  /** Called when the widget is skipped (production mode, mobile viewport) */
22
61
  onSkip?: (reason: "production" | "mobile") => void;
23
62
  /** Called when the feedback panel is opened. */
@@ -59,6 +98,19 @@ export type FeedbackType = (typeof FEEDBACK_TYPES)[number];
59
98
  /** Single source of truth for feedback statuses. */
60
99
  export declare const FEEDBACK_STATUSES: readonly ["open", "resolved"];
61
100
  export type FeedbackStatus = (typeof FEEDBACK_STATUSES)[number];
101
+ /**
102
+ * Page scope returned by `SitepingConfig.getPageScope()`.
103
+ *
104
+ * - `url`: concrete page identifier — usually `window.location.pathname`,
105
+ * used as the strict scope for marker rendering.
106
+ * - `urlPattern`: optional parameterized template (e.g. `/orders/:orderId`)
107
+ * used by the panel's "this type of page" filter to group feedbacks across
108
+ * instances of the same page kind.
109
+ */
110
+ export interface PageScope {
111
+ url: string;
112
+ urlPattern: string | null;
113
+ }
62
114
  /** Input for creating a feedback record in the store. */
63
115
  export interface FeedbackCreateInput {
64
116
  projectName: string;
@@ -66,12 +118,28 @@ export interface FeedbackCreateInput {
66
118
  message: string;
67
119
  status: FeedbackStatus;
68
120
  url: string;
121
+ /**
122
+ * Optional parameterized URL template (e.g. `/orders/:orderId`) for the page
123
+ * where the feedback was created. Allows the panel to filter feedbacks by
124
+ * "this type of page" across different instances. Null when the host did not
125
+ * provide a `getPageScope` callback or the route has no template.
126
+ */
127
+ urlPattern?: string | null | undefined;
69
128
  viewport: string;
70
129
  userAgent: string;
71
130
  authorName: string;
72
131
  authorEmail: string;
73
132
  clientId: string;
74
133
  annotations: AnnotationCreateInput[];
134
+ /**
135
+ * Base64 JPEG `data:` URL captured by the widget at submit time.
136
+ *
137
+ * Adapters with a configured `ScreenshotStorage` are expected to upload
138
+ * this and persist the returned URL on `FeedbackRecord.screenshotUrl`.
139
+ * Adapters without storage may persist the data URL inline (memory /
140
+ * localStorage / dev) — the widget then renders it directly.
141
+ */
142
+ screenshotDataUrl?: string | null | undefined;
75
143
  }
76
144
  /** Input for a single annotation when creating a feedback. */
77
145
  export interface AnnotationCreateInput {
@@ -84,6 +152,13 @@ export interface AnnotationCreateInput {
84
152
  textSuffix: string;
85
153
  fingerprint: string;
86
154
  neighborText: string;
155
+ /**
156
+ * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`
157
+ * attribute. When set, this is the most stable re-anchoring signal because
158
+ * hosts deliberately place these on layout/section roots that survive DOM
159
+ * refactors and viewport changes. Null when no semantic ancestor exists.
160
+ */
161
+ anchorKey?: string | null | undefined;
87
162
  xPct: number;
88
163
  yPct: number;
89
164
  wPct: number;
@@ -102,6 +177,17 @@ export interface FeedbackQuery {
102
177
  search?: string | undefined;
103
178
  page?: number | undefined;
104
179
  limit?: number | undefined;
180
+ /**
181
+ * Filter to feedbacks created on this exact URL (path). Used by the panel's
182
+ * "this page" filter and by the markers loader to keep page scopes isolated.
183
+ */
184
+ url?: string | undefined;
185
+ /**
186
+ * Filter to feedbacks created on this URL pattern (e.g. `/orders/:orderId`).
187
+ * Used by the panel's "this type of page" filter to group feedbacks across
188
+ * different concrete instances of the same template.
189
+ */
190
+ urlPattern?: string | undefined;
105
191
  }
106
192
  /** Update payload for patching a feedback. */
107
193
  export interface FeedbackUpdateInput {
@@ -116,6 +202,11 @@ export interface FeedbackRecord {
116
202
  status: FeedbackStatus;
117
203
  projectName: string;
118
204
  url: string;
205
+ /**
206
+ * Parameterized URL template the feedback was created on.
207
+ * Null for legacy records or hosts without `getPageScope`.
208
+ */
209
+ urlPattern: string | null;
119
210
  authorName: string;
120
211
  authorEmail: string;
121
212
  viewport: string;
@@ -125,6 +216,13 @@ export interface FeedbackRecord {
125
216
  createdAt: Date;
126
217
  updatedAt: Date;
127
218
  annotations: AnnotationRecord[];
219
+ /**
220
+ * URL the widget renders as `<img src>`. Either an `https://...` from a
221
+ * configured `ScreenshotStorage`, or a `data:image/jpeg;base64,...` URL
222
+ * inline-persisted by adapters without storage. Null when no screenshot
223
+ * was captured (legacy records, capture failed, or host disabled it).
224
+ */
225
+ screenshotUrl: string | null;
128
226
  }
129
227
  /** A persisted annotation record returned by the store. */
130
228
  export interface AnnotationRecord {
@@ -139,6 +237,11 @@ export interface AnnotationRecord {
139
237
  textSuffix: string;
140
238
  fingerprint: string;
141
239
  neighborText: string;
240
+ /**
241
+ * Semantic anchor identifier from `data-feedback-anchor`. Null for legacy
242
+ * annotations or those drawn outside any anchored region.
243
+ */
244
+ anchorKey: string | null;
142
245
  xPct: number;
143
246
  yPct: number;
144
247
  wPct: number;
@@ -214,6 +317,11 @@ export interface FeedbackPayload {
214
317
  type: FeedbackType;
215
318
  message: string;
216
319
  url: string;
320
+ /**
321
+ * Parameterized URL template (e.g. `/orders/:orderId`) supplied by
322
+ * `SitepingConfig.getPageScope()`. Null when the host did not provide one.
323
+ */
324
+ urlPattern?: string | null | undefined;
217
325
  viewport: string;
218
326
  userAgent: string;
219
327
  authorName: string;
@@ -221,6 +329,12 @@ export interface FeedbackPayload {
221
329
  annotations: AnnotationPayload[];
222
330
  /** Client-generated UUID for deduplication */
223
331
  clientId: string;
332
+ /**
333
+ * Base64 JPEG `data:` URL of the annotated area. Captured by the widget
334
+ * when `enableScreenshot: true` is set in `SitepingConfig`. Null when
335
+ * disabled or when capture failed silently.
336
+ */
337
+ screenshotDataUrl?: string | null | undefined;
224
338
  }
225
339
  /** DOM anchoring data for re-attaching annotations to page elements. */
226
340
  export interface AnchorData {
@@ -242,6 +356,13 @@ export interface AnchorData {
242
356
  fingerprint: string;
243
357
  /** Text content of adjacent sibling elements (context) */
244
358
  neighborText: string;
359
+ /**
360
+ * Semantic anchor identifier from the closest ancestor's `data-feedback-anchor`
361
+ * attribute. When set, this is the highest-priority re-anchoring signal —
362
+ * hosts deliberately place these on layout/section roots that survive
363
+ * viewport changes and DOM refactors.
364
+ */
365
+ anchorKey?: string | null | undefined;
245
366
  }
246
367
  /** Drawn rectangle coordinates as percentages relative to the anchor element. */
247
368
  export interface RectData {
@@ -272,6 +393,8 @@ export interface FeedbackResponse {
272
393
  message: string;
273
394
  status: FeedbackStatus;
274
395
  url: string;
396
+ /** Parameterized URL template the feedback was created on, or null. */
397
+ urlPattern: string | null;
275
398
  viewport: string;
276
399
  userAgent: string;
277
400
  authorName: string;
@@ -280,6 +403,8 @@ export interface FeedbackResponse {
280
403
  createdAt: string;
281
404
  updatedAt: string;
282
405
  annotations: AnnotationResponse[];
406
+ /** Screenshot URL (data: or http:) — see `FeedbackRecord.screenshotUrl`. */
407
+ screenshotUrl: string | null;
283
408
  }
284
409
  /** Annotation record as returned by the API. */
285
410
  export interface AnnotationResponse {
@@ -294,6 +419,8 @@ export interface AnnotationResponse {
294
419
  textSuffix: string;
295
420
  fingerprint: string;
296
421
  neighborText: string;
422
+ /** Semantic anchor identifier from `data-feedback-anchor`, or null. */
423
+ anchorKey: string | null;
297
424
  xPct: number;
298
425
  yPct: number;
299
426
  wPct: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siteping/widget",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Feedback widget for client review during development — annotations, bugs, questions directly on the site",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -53,6 +53,9 @@
53
53
  "engines": {
54
54
  "node": ">=18"
55
55
  },
56
+ "dependencies": {
57
+ "html2canvas": "^1.4.1"
58
+ },
56
59
  "devDependencies": {
57
60
  "@medv/finder": "^3.2.0",
58
61
  "@siteping/core": "workspace:*"