@popmelt.com/core 0.15.0 → 0.16.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.
@@ -0,0 +1,426 @@
1
+ declare const STICKER_COLOR_NAMES: readonly ["slate", "gray", "zinc", "neutral", "stone", "red", "orange", "amber", "yellow", "lime", "green", "emerald", "teal", "cyan", "sky", "blue", "indigo", "violet", "purple", "fuchsia", "pink", "rose"];
2
+ type StickerColorName = (typeof STICKER_COLOR_NAMES)[number];
3
+ declare const STICKER_COLOR_STEPS: readonly [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
4
+ type StickerColorStep = (typeof STICKER_COLOR_STEPS)[number];
5
+
6
+ declare const STICKER_FAMILIES: readonly ["padding", "margin", "border", "radius", "stack", "grid", "text", "color", "transform", "opacity"];
7
+ type StickerFamily = (typeof STICKER_FAMILIES)[number];
8
+ declare const SPACING_STEPS: readonly [0, 1, 2, 3, 4, 6, 8, 10, 12, 16];
9
+ declare const TRANSLATE_STEPS: readonly [-16, -12, -10, -8, -6, -4, -3, -2, -1, 0, 1, 2, 3, 4, 6, 8, 10, 12, 16];
10
+ declare const BORDER_STEPS: readonly [0, 1, 2, 4, 8];
11
+ declare const DIRECTION_STEPS: readonly ["vertical", "horizontal"];
12
+ declare const ALIGN_STEPS: readonly ["stretch", "start", "center", "end", "baseline"];
13
+ declare const JUSTIFY_STEPS: readonly ["start", "center", "end", "between", "around", "evenly"];
14
+ declare const GRID_COUNT_STEPS: readonly [1, 2, 3, 4, 5, 6];
15
+ declare const FONT_SIZE_STEPS: readonly ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl"];
16
+ declare const FONT_WEIGHT_STEPS: readonly [300, 400, 500, 600, 700, 800];
17
+ declare const LINE_HEIGHT_STEPS: readonly ["none", "tight", "snug", "normal", "relaxed", "loose"];
18
+ declare const LETTER_SPACING_STEPS: readonly ["tighter", "tight", "normal", "wide", "wider", "widest"];
19
+ declare const TEXT_ALIGN_STEPS: readonly ["left", "center", "right", "justify"];
20
+ declare const SCALE_STEPS: readonly [25, 50, 75, 90, 95, 100, 105, 110, 125, 150];
21
+ declare const ROTATE_STEPS: readonly [-180, -90, -45, -25, -12, -6, -3, -2, -1, 0, 1, 2, 3, 6, 12, 25, 45, 90, 180];
22
+ declare const OPACITY_STEPS: readonly [0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90, 95, 100];
23
+ declare const MIX_BLEND_STEPS: readonly ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"];
24
+ type StickerStep = (typeof SPACING_STEPS)[number] | (typeof BORDER_STEPS)[number] | (typeof DIRECTION_STEPS)[number] | (typeof ALIGN_STEPS)[number] | (typeof JUSTIFY_STEPS)[number] | (typeof GRID_COUNT_STEPS)[number] | (typeof FONT_SIZE_STEPS)[number] | (typeof FONT_WEIGHT_STEPS)[number] | (typeof LINE_HEIGHT_STEPS)[number] | (typeof LETTER_SPACING_STEPS)[number] | (typeof TEXT_ALIGN_STEPS)[number] | (typeof TRANSLATE_STEPS)[number] | (typeof SCALE_STEPS)[number] | (typeof ROTATE_STEPS)[number] | (typeof OPACITY_STEPS)[number] | (typeof MIX_BLEND_STEPS)[number] | StickerColorStep;
25
+ type StickerSubproperty = 'all' | 'x' | 'y' | 'top' | 'right' | 'bottom' | 'left' | 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left' | 'vertical' | 'horizontal' | 'direction' | 'gap' | 'align' | 'justify' | 'rows' | 'columns' | 'size' | 'weight' | 'line-height' | 'letter-spacing' | 'text-align' | 'color' | 'translate' | 'scale' | 'rotate' | 'opacity' | 'mix-blend' | StickerColorName;
26
+
27
+ type AnnotationLifecycleStatus = 'pending' | 'sending' | 'in_flight' | 'resolved' | 'needs_review' | 'dismissed' | 'waiting_input' | 'failed';
28
+ type ScopeBreadth = 'instance' | 'pattern';
29
+ type ScopeTarget = 'element' | 'component' | 'token';
30
+ type Scope = {
31
+ breadth: ScopeBreadth;
32
+ target: ScopeTarget;
33
+ };
34
+ declare const TOOL_TYPES: readonly ["inspector", "sticker", "model"];
35
+ type ToolType = (typeof TOOL_TYPES)[number];
36
+ declare const LEGACY_ANNOTATION_TYPES: readonly ["freehand", "line", "rectangle", "circle"];
37
+ type LegacyAnnotationType = (typeof LEGACY_ANNOTATION_TYPES)[number];
38
+ type AnnotationType = LegacyAnnotationType | 'text';
39
+ type Point = {
40
+ x: number;
41
+ y: number;
42
+ };
43
+ type AnnotationRevealStep = {
44
+ triggerSelector: string;
45
+ targetSelector?: string;
46
+ label: string;
47
+ };
48
+ type AnnotationRevealRecipe = {
49
+ steps: AnnotationRevealStep[];
50
+ location: string[];
51
+ };
52
+ type ReactSourceLocation = {
53
+ fileName: string;
54
+ lineNumber: number;
55
+ columnNumber?: number;
56
+ };
57
+ /** Coordinates refer to the original image, not its responsive DOM rectangle. */
58
+ type ImageObjectContext = {
59
+ src: string;
60
+ alt: string;
61
+ width: number;
62
+ height: number;
63
+ box: {
64
+ x: number;
65
+ y: number;
66
+ width: number;
67
+ height: number;
68
+ };
69
+ normalizedBox: {
70
+ x: number;
71
+ y: number;
72
+ width: number;
73
+ height: number;
74
+ };
75
+ };
76
+ type SubjectFeedbackAttachment = {
77
+ /** Zero-based index in this annotation's transported images. */
78
+ cropImageIndex?: number;
79
+ warning?: string;
80
+ };
81
+ type ElementInfo = {
82
+ selector: string;
83
+ tagName: string;
84
+ /** Adapter-owned semantic name for a non-DOM subject. */
85
+ subjectLabel?: string;
86
+ id?: string;
87
+ className?: string;
88
+ textContent?: string;
89
+ dataAttributes?: Record<string, string>;
90
+ reactComponent?: string;
91
+ reactComponentPath?: string[];
92
+ reactSource?: ReactSourceLocation;
93
+ imageObject?: ImageObjectContext;
94
+ /** The real DOM surface, rather than the subject's hidden projection. */
95
+ sourceElement?: ElementInfo;
96
+ context?: string;
97
+ revealRecipe?: AnnotationRevealRecipe;
98
+ };
99
+ /** Renderer-owned identity for a target that does not exist as a DOM node. */
100
+ type OpaqueTargetReference = {
101
+ adapter: string;
102
+ key: string;
103
+ };
104
+ type StyleChange = {
105
+ property: string;
106
+ original: string;
107
+ modified: string;
108
+ token?: string;
109
+ sticker?: {
110
+ family: StickerFamily;
111
+ subproperty: StickerSubproperty;
112
+ step: StickerStep;
113
+ axisSteps?: {
114
+ x: StickerStep;
115
+ y: StickerStep;
116
+ };
117
+ };
118
+ };
119
+ type StyleModification = {
120
+ selector: string;
121
+ durableSelector?: string;
122
+ element: ElementInfo;
123
+ changes: StyleChange[];
124
+ createdAt?: number;
125
+ annotationNumber?: number;
126
+ captured?: boolean;
127
+ pathname?: string;
128
+ };
129
+ type TextModification = {
130
+ selector: string;
131
+ durableSelector?: string;
132
+ element: ElementInfo;
133
+ textNodePath: number[];
134
+ original: string;
135
+ modified: string;
136
+ createdAt?: number;
137
+ annotationNumber?: number;
138
+ captured?: boolean;
139
+ pathname?: string;
140
+ };
141
+ type DomInsertionPlacement = 'before' | 'after';
142
+ type DomModification = {
143
+ id: string;
144
+ operation: 'move' | 'copy';
145
+ selector: string;
146
+ durableSelector?: string;
147
+ element: ElementInfo;
148
+ sourceSelector?: string;
149
+ sourceDurableSelector?: string;
150
+ sourceElement?: ElementInfo;
151
+ originalParentSelector?: string;
152
+ originalParentDurableSelector?: string;
153
+ originalIndex?: number;
154
+ targetParentSelector: string;
155
+ targetParentDurableSelector?: string;
156
+ targetIndex: number;
157
+ referenceSelector?: string;
158
+ referenceDurableSelector?: string;
159
+ placement: DomInsertionPlacement;
160
+ captured?: boolean;
161
+ pathname?: string;
162
+ };
163
+ type SpacingElementEvidence = {
164
+ selector: string;
165
+ reactComponent?: string;
166
+ className: string;
167
+ property: string;
168
+ matchedClass?: string;
169
+ suggestedClass?: string;
170
+ };
171
+ type SpacingTokenChange = {
172
+ id: string;
173
+ tokenPath: string;
174
+ tokenName: string;
175
+ originalPx: number;
176
+ newPx: number;
177
+ captured?: boolean;
178
+ affectedElements: SpacingElementEvidence[];
179
+ };
180
+ type AnnotationAttachment = {
181
+ id: string;
182
+ name: string;
183
+ mimeType: string;
184
+ size: number;
185
+ kind: 'svg' | 'text';
186
+ };
187
+ type Annotation = {
188
+ id: string;
189
+ type: AnnotationType;
190
+ points: Point[];
191
+ color: string;
192
+ strokeWidth: number;
193
+ text?: string;
194
+ fontSize?: number;
195
+ timestamp: number;
196
+ groupId?: string;
197
+ captured?: boolean;
198
+ status?: AnnotationLifecycleStatus;
199
+ question?: string;
200
+ resolutionSummary?: string;
201
+ scope?: Scope | null;
202
+ replyCount?: number;
203
+ replyJobIds?: string[];
204
+ threadId?: string;
205
+ targetBindingId?: string;
206
+ target?: OpaqueTargetReference;
207
+ pathname?: string;
208
+ elements?: ElementInfo[];
209
+ linkedSelector?: string;
210
+ linkedAnchor?: 'top-left' | 'bottom-left';
211
+ imageCount?: number;
212
+ attachments?: AnnotationAttachment[];
213
+ };
214
+ type BridgeStatus = {
215
+ ok: boolean;
216
+ activeJob: {
217
+ id: string;
218
+ status: string;
219
+ } | null;
220
+ queueDepth: number;
221
+ sessionId: string | null;
222
+ };
223
+ type ClaudeResponse = {
224
+ jobId: string;
225
+ sessionId?: string;
226
+ text: string;
227
+ success: boolean;
228
+ toolsUsed: string[];
229
+ };
230
+
231
+ type PopmeltSubjectBounds = {
232
+ left: number;
233
+ top: number;
234
+ width: number;
235
+ height: number;
236
+ };
237
+ type PopmeltSubject = {
238
+ key: string;
239
+ label: string;
240
+ bounds: PopmeltSubjectBounds;
241
+ /** Viewport bounds of the renderer surface that owns this subject. */
242
+ surfaceBounds?: PopmeltSubjectBounds;
243
+ context?: string;
244
+ data?: Record<string, string>;
245
+ /** Live owning surface; never serialized or included in model context. */
246
+ sourceElement?: Element;
247
+ imageObject?: ImageObjectContext;
248
+ };
249
+ type PopmeltSurfaceSnapshot = {
250
+ element: HTMLCanvasElement;
251
+ dataUrl: string;
252
+ };
253
+ type PopmeltSubjectCreationSession = {
254
+ key: string;
255
+ update(clientPoint: {
256
+ x: number;
257
+ y: number;
258
+ }): PopmeltSubject | null;
259
+ commit(): PopmeltSubject | null;
260
+ cancel(): void;
261
+ };
262
+ /**
263
+ * Minimal renderer boundary for non-DOM subjects. The adapter owns hit testing,
264
+ * durable keys, and viewport projection; Popmelt owns annotations and threads.
265
+ */
266
+ type PopmeltSubjectAdapter = {
267
+ id: string;
268
+ /** Surface ownership; an explicit image adapter replaces Core's default. */
269
+ surfaceKind?: 'image';
270
+ hitTest(clientPoint: {
271
+ x: number;
272
+ y: number;
273
+ }): PopmeltSubject | null;
274
+ resolve(key: string): PopmeltSubject | null;
275
+ /** Optional clean subject crop, without Popmelt's overlay. */
276
+ captureSubject?(key: string): Blob | null | Promise<Blob | null>;
277
+ /** Optional bitmap capture for renderer surfaces that DOM cloning cannot read. */
278
+ captureSurfaces?(): readonly PopmeltSurfaceSnapshot[] | Promise<readonly PopmeltSurfaceSnapshot[]>;
279
+ /** Begin a context-aware subject-creation gesture at a viewport point. */
280
+ beginCreate?(clientPoint: {
281
+ x: number;
282
+ y: number;
283
+ }): PopmeltSubjectCreationSession | null;
284
+ /** Rename a subject without changing its durable key. */
285
+ renameSubject?(key: string, label: string): PopmeltSubject | null;
286
+ /** Replace a subject's viewport bounds, projected back into adapter space. */
287
+ updateSubjectBounds?(key: string, bounds: PopmeltSubjectBounds): PopmeltSubject | null;
288
+ /** Remove a user-created subject or hide an adapter-owned subject. */
289
+ removeSubject?(key: string): void;
290
+ };
291
+
292
+ /** Geometry is normalized against the loaded image, not its rendered size. */
293
+ type ImageObjectBox = {
294
+ left: number;
295
+ top: number;
296
+ width: number;
297
+ height: number;
298
+ };
299
+ /** A provider's observation; no inference runtime is required by Core. */
300
+ type ImageObjectObservation = {
301
+ label: string;
302
+ score: number;
303
+ box: ImageObjectBox;
304
+ };
305
+
306
+ type PersistedImageSubject = {
307
+ id: string;
308
+ label: string;
309
+ detectedLabel?: string;
310
+ score: number;
311
+ box: ImageObjectBox;
312
+ detectedBox?: ImageObjectBox;
313
+ origin: 'detected' | 'manual';
314
+ boundsOverridden?: boolean;
315
+ };
316
+ type PersistedImageSuppression = {
317
+ detectedLabel: string;
318
+ detectedBox: ImageObjectBox;
319
+ };
320
+ type PersistedImageAnalysis = {
321
+ schemaVersion: 1;
322
+ source: string;
323
+ imageHash: string;
324
+ inferenceKey: string;
325
+ dedupeKey: string;
326
+ subjects: readonly PersistedImageSubject[];
327
+ /** Inferred objects explicitly removed by the user for this image hash. */
328
+ suppressions?: readonly PersistedImageSuppression[];
329
+ updatedAt: number;
330
+ };
331
+ type ImageSubjectStore = {
332
+ load(key: string): PersistedImageAnalysis | null | Promise<PersistedImageAnalysis | null>;
333
+ save(key: string, analysis: PersistedImageAnalysis): void | Promise<void>;
334
+ remove?(key: string): void | Promise<void>;
335
+ /** Older content-hash versions retained before the active record changed. */
336
+ loadHistory?(key: string): readonly PersistedImageAnalysis[] | Promise<readonly PersistedImageAnalysis[]>;
337
+ };
338
+ type BrowserImageSubjectStoreOptions = {
339
+ /** Prefix used for browser storage entries. */
340
+ namespace?: string;
341
+ /** Override localStorage, primarily for embedded browsers and tests. */
342
+ storage?: Storage;
343
+ };
344
+ declare function createBrowserImageSubjectStore(options?: BrowserImageSubjectStoreOptions): ImageSubjectStore;
345
+ declare function createMemoryImageSubjectStore(): ImageSubjectStore;
346
+
347
+ type ImageContentHasher = (image: HTMLImageElement) => string | Promise<string>;
348
+ /** Optional perception boundary. Core keeps media authoring usable without it. */
349
+ type ImageRecognitionProvider = {
350
+ cacheKey: string;
351
+ configurationKey: string;
352
+ detect(image: HTMLImageElement): Promise<readonly ImageObjectObservation[]>;
353
+ reconcile(observations: readonly ImageObjectObservation[], previousSubjects: readonly PersistedImageSubject[], suppressions: readonly PersistedImageSuppression[]): readonly PersistedImageSubject[];
354
+ dispose?(): void | Promise<void>;
355
+ };
356
+ type ImageSubjectAdapterOptions = {
357
+ /** Optional perception; omit for manual-only image annotation. */
358
+ recognition?: ImageRecognitionProvider;
359
+ /** Restore saved subjects without hashing or running recognition. */
360
+ hydrateOnly?: boolean;
361
+ /** Images to analyze when the adapter starts. Defaults to every image. */
362
+ selector?: string;
363
+ /** Root to scan and observe. Defaults to document. */
364
+ root?: Document | Element;
365
+ /** Observe added images and src changes. Defaults to true. */
366
+ observe?: boolean;
367
+ /** Override the durable Core adapter id. */
368
+ id?: string;
369
+ /** Persist detections and user overrides. Omit to keep adapter state ephemeral. */
370
+ store?: ImageSubjectStore;
371
+ /** Override content hashing, primarily for authenticated or virtual images. */
372
+ imageHasher?: ImageContentHasher;
373
+ onError?: (error: unknown, image: HTMLImageElement) => void;
374
+ };
375
+ declare class ImageSubjectAdapter implements PopmeltSubjectAdapter {
376
+ private readonly options;
377
+ readonly surfaceKind: "image";
378
+ readonly id: string;
379
+ private readonly records;
380
+ private readonly imageKeys;
381
+ private readonly analyzedSources;
382
+ private readonly pending;
383
+ private readonly analysisMetadata;
384
+ private readonly suppressions;
385
+ private readonly writeChains;
386
+ private readonly pendingWrites;
387
+ private readonly observer;
388
+ private refreshQueued;
389
+ private destroyed;
390
+ private readyPromise;
391
+ private manualSequence;
392
+ constructor(options?: ImageSubjectAdapterOptions);
393
+ whenReady(): Promise<void>;
394
+ listSubjects(): readonly PopmeltSubject[];
395
+ refresh(): Promise<void>;
396
+ hitTest(clientPoint: {
397
+ x: number;
398
+ y: number;
399
+ }): PopmeltSubject | null;
400
+ resolve(key: string): PopmeltSubject | null;
401
+ private imageObjectContext;
402
+ captureSubject(key: string): Promise<Blob | null>;
403
+ beginCreate(clientPoint: {
404
+ x: number;
405
+ y: number;
406
+ }): PopmeltSubjectCreationSession | null;
407
+ renameSubject(key: string, label: string): PopmeltSubject | null;
408
+ updateSubjectBounds(key: string, bounds: PopmeltSubjectBounds): PopmeltSubject | null;
409
+ removeSubject(key: string): void;
410
+ destroy(): Promise<void>;
411
+ private queueRefresh;
412
+ private analyze;
413
+ private replaceImageRecords;
414
+ private imageIdentity;
415
+ private matchingImages;
416
+ private clampedImagePoint;
417
+ private newObjectId;
418
+ private persistImage;
419
+ private saveImage;
420
+ private imageSubjects;
421
+ private persistencePayload;
422
+ private removeImage;
423
+ }
424
+ declare function createImageSubjectAdapter(options?: ImageSubjectAdapterOptions): ImageSubjectAdapter;
425
+
426
+ export { type Annotation as A, type BridgeStatus as B, type ClaudeResponse as C, type DomModification as D, type ElementInfo as E, type ImageRecognitionProvider as I, type OpaqueTargetReference as O, type PopmeltSubjectAdapter as P, type ReactSourceLocation as R, type SubjectFeedbackAttachment as S, type TextModification as T, type ImageSubjectAdapterOptions as a, type AnnotationAttachment as b, type StyleModification as c, type SpacingTokenChange as d, type AnnotationType as e, type ImageObjectContext as f, type Point as g, type PopmeltSubject as h, type PopmeltSubjectBounds as i, type PopmeltSubjectCreationSession as j, type PopmeltSurfaceSnapshot as k, type StyleChange as l, type ToolType as m, type ImageObjectBox as n, type BrowserImageSubjectStoreOptions as o, type ImageContentHasher as p, type ImageObjectObservation as q, ImageSubjectAdapter as r, type ImageSubjectStore as s, type PersistedImageAnalysis as t, type PersistedImageSubject as u, type PersistedImageSuppression as v, createBrowserImageSubjectStore as w, createImageSubjectAdapter as x, createMemoryImageSubjectStore as y };