web-remarq 0.5.0 → 0.7.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.
@@ -26,6 +26,16 @@ interface ElementFingerprint {
26
26
  detectedSource: string | null;
27
27
  detectedComponent: string | null;
28
28
  }
29
+ type AnnotationStatus = 'pending' | 'in_progress' | 'fixed_unverified' | 'verified' | 'dismissed';
30
+ type Actor = 'designer' | 'agent' | 'developer';
31
+ type AnnotationEventType = 'created' | 'acknowledged' | 'fix_claimed' | 'verified' | 'rejected' | 'dismissed' | 'reopened' | 'migrated';
32
+ interface AnnotationEvent {
33
+ type: AnnotationEventType;
34
+ actor: Actor | null;
35
+ actorName?: string;
36
+ timestamp: number;
37
+ reason?: string;
38
+ }
29
39
  interface Annotation {
30
40
  id: string;
31
41
  comment: string;
@@ -34,7 +44,8 @@ interface Annotation {
34
44
  viewport: string;
35
45
  viewportBucket: number;
36
46
  timestamp: number;
37
- status: 'pending' | 'resolved';
47
+ status: AnnotationStatus;
48
+ lifecycle: AnnotationEvent[];
38
49
  }
39
50
  interface AnnotationStore {
40
51
  version: 1;
@@ -47,6 +58,7 @@ interface WebRemarqOptions {
47
58
  dataAttribute?: string;
48
59
  position?: ToolbarPosition;
49
60
  shortcuts?: boolean;
61
+ storage?: StorageAdapter;
50
62
  }
51
63
  type SearchConfidence = 'high' | 'medium' | 'low';
52
64
  interface GrepQuery {
@@ -66,14 +78,21 @@ interface AgentAnnotationSource {
66
78
  column: number;
67
79
  component: string | null;
68
80
  }
81
+ interface AgentLifecycleEvent {
82
+ type: AnnotationEventType;
83
+ actor: Actor | null;
84
+ timestamp: number;
85
+ reason?: string;
86
+ }
69
87
  interface AgentAnnotation {
70
88
  id: string;
71
89
  route: string;
72
90
  comment: string;
73
- status: 'pending' | 'resolved';
91
+ status: AnnotationStatus;
74
92
  timestamp: number;
75
93
  source: AgentAnnotationSource | null;
76
94
  searchHints: AgentSearchHints;
95
+ lifecycle: AgentLifecycleEvent[];
77
96
  }
78
97
  interface AgentExport {
79
98
  version: 1;
@@ -81,27 +100,54 @@ interface AgentExport {
81
100
  viewportBucket: number;
82
101
  annotations: AgentAnnotation[];
83
102
  }
103
+ interface StorageChangeEvent {
104
+ type: 'add' | 'update' | 'remove' | 'clear';
105
+ annotation?: Annotation;
106
+ id?: string;
107
+ }
108
+ interface StorageAdapter {
109
+ load(): Promise<AnnotationStore | null>;
110
+ save(annotation: Annotation): Promise<void>;
111
+ remove(id: string): Promise<void>;
112
+ clear(): Promise<void>;
113
+ subscribe?(callback: (event: StorageChangeEvent) => void): () => void;
114
+ readonly isMemoryOnly?: boolean;
115
+ }
84
116
 
85
117
  declare function createFingerprint(el: HTMLElement, options?: Pick<WebRemarqOptions, 'classFilter' | 'dataAttribute'>): ElementFingerprint;
86
118
 
87
119
  declare function matchElement(fp: ElementFingerprint, options?: Pick<WebRemarqOptions, 'dataAttribute'>): HTMLElement | null;
88
120
 
121
+ declare function migrateAnnotation(legacy: any): Annotation;
89
122
  declare class AnnotationStorage {
90
- private annotations;
91
- private extraFields;
92
- isMemoryOnly: boolean;
93
- constructor();
123
+ private adapter;
124
+ private cache;
125
+ readonly ready: Promise<void>;
126
+ constructor(adapter: StorageAdapter);
127
+ get isMemoryOnly(): boolean;
94
128
  getAll(): Annotation[];
95
129
  getByRoute(route: string): Annotation[];
96
- add(annotation: Annotation): void;
97
- remove(id: string): void;
98
- update(id: string, changes: Partial<Annotation>): void;
99
- clearAll(): void;
130
+ getById(id: string): Annotation | undefined;
131
+ add(annotation: Annotation): Promise<void>;
132
+ remove(id: string): Promise<void>;
133
+ update(id: string, changes: Partial<Annotation>): Promise<void>;
134
+ clearAll(): Promise<void>;
100
135
  exportJSON(): AnnotationStore;
101
- importJSON(data: AnnotationStore): void;
136
+ importJSON(data: AnnotationStore): Promise<void>;
137
+ private init;
102
138
  private migrateViewportBuckets;
103
- private load;
104
- private save;
139
+ }
140
+
141
+ declare class LocalStorageAdapter implements StorageAdapter {
142
+ isMemoryOnly: boolean;
143
+ private extraFields;
144
+ private memoryStore;
145
+ load(): Promise<AnnotationStore | null>;
146
+ save(annotation: Annotation): Promise<void>;
147
+ remove(id: string): Promise<void>;
148
+ clear(): Promise<void>;
149
+ private ensureStore;
150
+ private persist;
105
151
  }
106
152
 
107
153
  /**
@@ -116,4 +162,20 @@ declare function detectSource(el: HTMLElement): SourceDetectionResult;
116
162
 
117
163
  declare function generateAgentExport(annotations: Annotation[], viewportBucket: number): AgentExport;
118
164
 
119
- export { type AgentAnnotation, type AgentAnnotationSource, type AgentExport, type AgentSearchHints, type Annotation, AnnotationStorage, type AnnotationStore, type CSSModuleClass, type ElementFingerprint, type GrepQuery, type SearchConfidence, type SourceDetectionResult, type ToolbarPosition, createFingerprint, detectRemarqPlugin, detectSource, generateAgentExport, matchElement };
165
+ type LifecycleAction = 'acknowledge' | 'claimFix' | 'verify' | 'reject' | 'dismiss' | 'reopen';
166
+ declare class InvalidTransitionError extends Error {
167
+ constructor(from: AnnotationStatus, action: LifecycleAction);
168
+ }
169
+ interface EventOpts {
170
+ actor?: Actor;
171
+ actorName?: string;
172
+ reason?: string;
173
+ timestamp?: number;
174
+ }
175
+ declare function createEvent(type: AnnotationEventType, opts?: EventOpts): AnnotationEvent;
176
+ declare function transition(annotation: Annotation, action: LifecycleAction, opts?: EventOpts): {
177
+ status: AnnotationStatus;
178
+ event: AnnotationEvent;
179
+ };
180
+
181
+ export { type Actor, type AgentAnnotation, type AgentAnnotationSource, type AgentExport, type AgentLifecycleEvent, type AgentSearchHints, type Annotation, type AnnotationEvent, type AnnotationEventType, type AnnotationStatus, AnnotationStorage, type AnnotationStore, type CSSModuleClass, type ElementFingerprint, type EventOpts, type GrepQuery, InvalidTransitionError, type LifecycleAction, LocalStorageAdapter, type SearchConfidence, type SourceDetectionResult, type StorageAdapter, type StorageChangeEvent, type ToolbarPosition, createEvent, createFingerprint, detectRemarqPlugin, detectSource, generateAgentExport, matchElement, migrateAnnotation, transition };
@@ -26,6 +26,16 @@ interface ElementFingerprint {
26
26
  detectedSource: string | null;
27
27
  detectedComponent: string | null;
28
28
  }
29
+ type AnnotationStatus = 'pending' | 'in_progress' | 'fixed_unverified' | 'verified' | 'dismissed';
30
+ type Actor = 'designer' | 'agent' | 'developer';
31
+ type AnnotationEventType = 'created' | 'acknowledged' | 'fix_claimed' | 'verified' | 'rejected' | 'dismissed' | 'reopened' | 'migrated';
32
+ interface AnnotationEvent {
33
+ type: AnnotationEventType;
34
+ actor: Actor | null;
35
+ actorName?: string;
36
+ timestamp: number;
37
+ reason?: string;
38
+ }
29
39
  interface Annotation {
30
40
  id: string;
31
41
  comment: string;
@@ -34,7 +44,8 @@ interface Annotation {
34
44
  viewport: string;
35
45
  viewportBucket: number;
36
46
  timestamp: number;
37
- status: 'pending' | 'resolved';
47
+ status: AnnotationStatus;
48
+ lifecycle: AnnotationEvent[];
38
49
  }
39
50
  interface AnnotationStore {
40
51
  version: 1;
@@ -47,6 +58,7 @@ interface WebRemarqOptions {
47
58
  dataAttribute?: string;
48
59
  position?: ToolbarPosition;
49
60
  shortcuts?: boolean;
61
+ storage?: StorageAdapter;
50
62
  }
51
63
  type SearchConfidence = 'high' | 'medium' | 'low';
52
64
  interface GrepQuery {
@@ -66,14 +78,21 @@ interface AgentAnnotationSource {
66
78
  column: number;
67
79
  component: string | null;
68
80
  }
81
+ interface AgentLifecycleEvent {
82
+ type: AnnotationEventType;
83
+ actor: Actor | null;
84
+ timestamp: number;
85
+ reason?: string;
86
+ }
69
87
  interface AgentAnnotation {
70
88
  id: string;
71
89
  route: string;
72
90
  comment: string;
73
- status: 'pending' | 'resolved';
91
+ status: AnnotationStatus;
74
92
  timestamp: number;
75
93
  source: AgentAnnotationSource | null;
76
94
  searchHints: AgentSearchHints;
95
+ lifecycle: AgentLifecycleEvent[];
77
96
  }
78
97
  interface AgentExport {
79
98
  version: 1;
@@ -81,27 +100,54 @@ interface AgentExport {
81
100
  viewportBucket: number;
82
101
  annotations: AgentAnnotation[];
83
102
  }
103
+ interface StorageChangeEvent {
104
+ type: 'add' | 'update' | 'remove' | 'clear';
105
+ annotation?: Annotation;
106
+ id?: string;
107
+ }
108
+ interface StorageAdapter {
109
+ load(): Promise<AnnotationStore | null>;
110
+ save(annotation: Annotation): Promise<void>;
111
+ remove(id: string): Promise<void>;
112
+ clear(): Promise<void>;
113
+ subscribe?(callback: (event: StorageChangeEvent) => void): () => void;
114
+ readonly isMemoryOnly?: boolean;
115
+ }
84
116
 
85
117
  declare function createFingerprint(el: HTMLElement, options?: Pick<WebRemarqOptions, 'classFilter' | 'dataAttribute'>): ElementFingerprint;
86
118
 
87
119
  declare function matchElement(fp: ElementFingerprint, options?: Pick<WebRemarqOptions, 'dataAttribute'>): HTMLElement | null;
88
120
 
121
+ declare function migrateAnnotation(legacy: any): Annotation;
89
122
  declare class AnnotationStorage {
90
- private annotations;
91
- private extraFields;
92
- isMemoryOnly: boolean;
93
- constructor();
123
+ private adapter;
124
+ private cache;
125
+ readonly ready: Promise<void>;
126
+ constructor(adapter: StorageAdapter);
127
+ get isMemoryOnly(): boolean;
94
128
  getAll(): Annotation[];
95
129
  getByRoute(route: string): Annotation[];
96
- add(annotation: Annotation): void;
97
- remove(id: string): void;
98
- update(id: string, changes: Partial<Annotation>): void;
99
- clearAll(): void;
130
+ getById(id: string): Annotation | undefined;
131
+ add(annotation: Annotation): Promise<void>;
132
+ remove(id: string): Promise<void>;
133
+ update(id: string, changes: Partial<Annotation>): Promise<void>;
134
+ clearAll(): Promise<void>;
100
135
  exportJSON(): AnnotationStore;
101
- importJSON(data: AnnotationStore): void;
136
+ importJSON(data: AnnotationStore): Promise<void>;
137
+ private init;
102
138
  private migrateViewportBuckets;
103
- private load;
104
- private save;
139
+ }
140
+
141
+ declare class LocalStorageAdapter implements StorageAdapter {
142
+ isMemoryOnly: boolean;
143
+ private extraFields;
144
+ private memoryStore;
145
+ load(): Promise<AnnotationStore | null>;
146
+ save(annotation: Annotation): Promise<void>;
147
+ remove(id: string): Promise<void>;
148
+ clear(): Promise<void>;
149
+ private ensureStore;
150
+ private persist;
105
151
  }
106
152
 
107
153
  /**
@@ -116,4 +162,20 @@ declare function detectSource(el: HTMLElement): SourceDetectionResult;
116
162
 
117
163
  declare function generateAgentExport(annotations: Annotation[], viewportBucket: number): AgentExport;
118
164
 
119
- export { type AgentAnnotation, type AgentAnnotationSource, type AgentExport, type AgentSearchHints, type Annotation, AnnotationStorage, type AnnotationStore, type CSSModuleClass, type ElementFingerprint, type GrepQuery, type SearchConfidence, type SourceDetectionResult, type ToolbarPosition, createFingerprint, detectRemarqPlugin, detectSource, generateAgentExport, matchElement };
165
+ type LifecycleAction = 'acknowledge' | 'claimFix' | 'verify' | 'reject' | 'dismiss' | 'reopen';
166
+ declare class InvalidTransitionError extends Error {
167
+ constructor(from: AnnotationStatus, action: LifecycleAction);
168
+ }
169
+ interface EventOpts {
170
+ actor?: Actor;
171
+ actorName?: string;
172
+ reason?: string;
173
+ timestamp?: number;
174
+ }
175
+ declare function createEvent(type: AnnotationEventType, opts?: EventOpts): AnnotationEvent;
176
+ declare function transition(annotation: Annotation, action: LifecycleAction, opts?: EventOpts): {
177
+ status: AnnotationStatus;
178
+ event: AnnotationEvent;
179
+ };
180
+
181
+ export { type Actor, type AgentAnnotation, type AgentAnnotationSource, type AgentExport, type AgentLifecycleEvent, type AgentSearchHints, type Annotation, type AnnotationEvent, type AnnotationEventType, type AnnotationStatus, AnnotationStorage, type AnnotationStore, type CSSModuleClass, type ElementFingerprint, type EventOpts, type GrepQuery, InvalidTransitionError, type LifecycleAction, LocalStorageAdapter, type SearchConfidence, type SourceDetectionResult, type StorageAdapter, type StorageChangeEvent, type ToolbarPosition, createEvent, createFingerprint, detectRemarqPlugin, detectSource, generateAgentExport, matchElement, migrateAnnotation, transition };
@@ -351,79 +351,151 @@ function toBucket(width) {
351
351
  }
352
352
 
353
353
  // src/core/storage.ts
354
- var STORAGE_KEY = "remarq:annotations";
354
+ function migrateAnnotation(legacy) {
355
+ const rawStatus = legacy.status;
356
+ const status = rawStatus === "resolved" ? "verified" : rawStatus;
357
+ if (Array.isArray(legacy.lifecycle) && legacy.lifecycle.length > 0) {
358
+ return __spreadProps(__spreadValues({}, legacy), { status, lifecycle: legacy.lifecycle });
359
+ }
360
+ const createdTs = typeof legacy.timestamp === "number" ? legacy.timestamp : Date.now();
361
+ const lifecycle = [
362
+ { type: "created", actor: "designer", timestamp: createdTs }
363
+ ];
364
+ if (rawStatus === "resolved") {
365
+ lifecycle.push({ type: "migrated", actor: null, timestamp: Date.now() });
366
+ }
367
+ return __spreadProps(__spreadValues({}, legacy), { status, lifecycle });
368
+ }
355
369
  var AnnotationStorage = class {
356
- constructor() {
357
- this.annotations = [];
358
- this.extraFields = {};
359
- this.isMemoryOnly = false;
360
- this.load();
370
+ constructor(adapter) {
371
+ this.adapter = adapter;
372
+ this.cache = [];
373
+ this.ready = this.init();
374
+ }
375
+ get isMemoryOnly() {
376
+ var _a;
377
+ return (_a = this.adapter.isMemoryOnly) != null ? _a : false;
361
378
  }
362
379
  getAll() {
363
- return [...this.annotations];
380
+ return [...this.cache];
364
381
  }
365
382
  getByRoute(route) {
366
- return this.annotations.filter((a) => a.route === route);
383
+ return this.cache.filter((a) => a.route === route);
367
384
  }
368
- add(annotation) {
369
- this.annotations.push(annotation);
370
- this.save();
385
+ getById(id) {
386
+ return this.cache.find((a) => a.id === id);
371
387
  }
372
- remove(id) {
373
- this.annotations = this.annotations.filter((a) => a.id !== id);
374
- this.save();
388
+ async add(annotation) {
389
+ this.cache.push(annotation);
390
+ await this.adapter.save(annotation);
375
391
  }
376
- update(id, changes) {
377
- const idx = this.annotations.findIndex((a) => a.id === id);
378
- if (idx !== -1) {
379
- this.annotations[idx] = __spreadValues(__spreadValues({}, this.annotations[idx]), changes);
380
- this.save();
381
- }
392
+ async remove(id) {
393
+ this.cache = this.cache.filter((a) => a.id !== id);
394
+ await this.adapter.remove(id);
395
+ }
396
+ async update(id, changes) {
397
+ const idx = this.cache.findIndex((a) => a.id === id);
398
+ if (idx === -1) return;
399
+ const updated = __spreadValues(__spreadValues({}, this.cache[idx]), changes);
400
+ this.cache[idx] = updated;
401
+ await this.adapter.save(updated);
382
402
  }
383
- clearAll() {
384
- this.annotations = [];
385
- this.save();
403
+ async clearAll() {
404
+ this.cache = [];
405
+ await this.adapter.clear();
386
406
  }
387
407
  exportJSON() {
388
408
  return {
389
409
  version: 1,
390
- annotations: [...this.annotations]
410
+ annotations: [...this.cache]
391
411
  };
392
412
  }
393
- importJSON(data) {
394
- this.annotations = [...data.annotations];
413
+ async importJSON(data) {
414
+ this.cache = data.annotations.map(migrateAnnotation);
395
415
  this.migrateViewportBuckets();
396
- this.save();
416
+ await this.adapter.clear();
417
+ for (const ann of this.cache) {
418
+ await this.adapter.save(ann);
419
+ }
420
+ }
421
+ async init() {
422
+ const data = await this.adapter.load();
423
+ if (data) {
424
+ this.cache = data.annotations.map(migrateAnnotation);
425
+ this.migrateViewportBuckets();
426
+ }
397
427
  }
398
428
  migrateViewportBuckets() {
399
- for (const ann of this.annotations) {
429
+ for (const ann of this.cache) {
400
430
  if (ann.viewportBucket == null && ann.viewport) {
401
431
  const width = parseInt(ann.viewport.split("x")[0], 10);
402
432
  ann.viewportBucket = toBucket(width);
403
433
  }
404
434
  }
405
435
  }
406
- load() {
436
+ };
437
+
438
+ // src/core/local-storage-adapter.ts
439
+ var STORAGE_KEY = "remarq:annotations";
440
+ var LocalStorageAdapter = class {
441
+ constructor() {
442
+ this.isMemoryOnly = false;
443
+ this.extraFields = {};
444
+ this.memoryStore = null;
445
+ }
446
+ async load() {
447
+ if (this.isMemoryOnly) return this.memoryStore;
407
448
  try {
408
449
  const raw = localStorage.getItem(STORAGE_KEY);
409
- if (raw) {
410
- const parsed = JSON.parse(raw);
411
- const _a = parsed, { version, annotations } = _a, rest = __objRest(_a, ["version", "annotations"]);
412
- this.annotations = annotations != null ? annotations : [];
413
- this.extraFields = rest;
414
- this.migrateViewportBuckets();
415
- }
450
+ if (!raw) return null;
451
+ const parsed = JSON.parse(raw);
452
+ const _a = parsed, { version, annotations } = _a, rest = __objRest(_a, ["version", "annotations"]);
453
+ this.extraFields = rest;
454
+ const store = {
455
+ version: 1,
456
+ annotations: Array.isArray(annotations) ? annotations : []
457
+ };
458
+ this.memoryStore = store;
459
+ return store;
416
460
  } catch (e) {
417
461
  this.isMemoryOnly = true;
462
+ return this.memoryStore;
418
463
  }
419
464
  }
420
- save() {
465
+ async save(annotation) {
466
+ const store = await this.ensureStore();
467
+ const idx = store.annotations.findIndex((a) => a.id === annotation.id);
468
+ if (idx === -1) {
469
+ store.annotations.push(annotation);
470
+ } else {
471
+ store.annotations[idx] = annotation;
472
+ }
473
+ this.persist(store);
474
+ }
475
+ async remove(id) {
476
+ const store = await this.ensureStore();
477
+ store.annotations = store.annotations.filter((a) => a.id !== id);
478
+ this.persist(store);
479
+ }
480
+ async clear() {
481
+ const store = await this.ensureStore();
482
+ store.annotations = [];
483
+ this.persist(store);
484
+ }
485
+ async ensureStore() {
486
+ if (this.memoryStore) return this.memoryStore;
487
+ const loaded = await this.load();
488
+ if (loaded) return loaded;
489
+ this.memoryStore = { version: 1, annotations: [] };
490
+ return this.memoryStore;
491
+ }
492
+ persist(store) {
421
493
  if (this.isMemoryOnly) return;
422
494
  try {
423
495
  const data = __spreadProps(__spreadValues({
424
496
  version: 1
425
497
  }, this.extraFields), {
426
- annotations: this.annotations
498
+ annotations: store.annotations
427
499
  });
428
500
  localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
429
501
  } catch (e) {
@@ -504,7 +576,16 @@ function generateAgentExport(annotations, viewportBucket) {
504
576
  status: ann.status,
505
577
  timestamp: ann.timestamp,
506
578
  source: resolveSource(ann.fingerprint),
507
- searchHints: buildSearchHints(ann.fingerprint)
579
+ searchHints: buildSearchHints(ann.fingerprint),
580
+ lifecycle: ann.lifecycle.map((ev) => {
581
+ const out = {
582
+ type: ev.type,
583
+ actor: ev.actor,
584
+ timestamp: ev.timestamp
585
+ };
586
+ if (ev.reason !== void 0) out.reason = ev.reason;
587
+ return out;
588
+ })
508
589
  }));
509
590
  return {
510
591
  version: 1,
@@ -513,12 +594,78 @@ function generateAgentExport(annotations, viewportBucket) {
513
594
  annotations: agentAnnotations
514
595
  };
515
596
  }
597
+
598
+ // src/core/lifecycle.ts
599
+ var InvalidTransitionError = class extends Error {
600
+ constructor(from, action) {
601
+ super(`Cannot ${action} from status "${from}"`);
602
+ this.name = "InvalidTransitionError";
603
+ }
604
+ };
605
+ var ACTION_TO_EVENT = {
606
+ acknowledge: "acknowledged",
607
+ claimFix: "fix_claimed",
608
+ verify: "verified",
609
+ reject: "rejected",
610
+ dismiss: "dismissed",
611
+ reopen: "reopened"
612
+ };
613
+ var DEFAULT_ACTOR_BY_EVENT = {
614
+ created: "designer",
615
+ acknowledged: "developer",
616
+ fix_claimed: "agent",
617
+ verified: "developer",
618
+ rejected: "developer",
619
+ dismissed: "developer",
620
+ reopened: "developer",
621
+ migrated: null
622
+ };
623
+ function createEvent(type, opts = {}) {
624
+ var _a, _b;
625
+ const event = {
626
+ type,
627
+ actor: (_a = opts.actor) != null ? _a : DEFAULT_ACTOR_BY_EVENT[type],
628
+ timestamp: (_b = opts.timestamp) != null ? _b : Date.now()
629
+ };
630
+ if (opts.actorName !== void 0) event.actorName = opts.actorName;
631
+ if (opts.reason !== void 0) event.reason = opts.reason;
632
+ return event;
633
+ }
634
+ function nextStatus(from, action) {
635
+ switch (action) {
636
+ case "acknowledge":
637
+ return from === "pending" ? "in_progress" : null;
638
+ case "claimFix":
639
+ return from === "pending" || from === "in_progress" ? "fixed_unverified" : null;
640
+ case "verify":
641
+ return from === "fixed_unverified" || from === "in_progress" ? "verified" : null;
642
+ case "reject":
643
+ return from === "fixed_unverified" ? "pending" : null;
644
+ case "dismiss":
645
+ return from === "pending" || from === "in_progress" || from === "fixed_unverified" ? "dismissed" : null;
646
+ case "reopen":
647
+ return from === "dismissed" || from === "verified" ? "pending" : null;
648
+ }
649
+ }
650
+ function transition(annotation, action, opts = {}) {
651
+ const next = nextStatus(annotation.status, action);
652
+ if (next === null) {
653
+ throw new InvalidTransitionError(annotation.status, action);
654
+ }
655
+ const event = createEvent(ACTION_TO_EVENT[action], opts);
656
+ return { status: next, event };
657
+ }
516
658
  export {
517
659
  AnnotationStorage,
660
+ InvalidTransitionError,
661
+ LocalStorageAdapter,
662
+ createEvent,
518
663
  createFingerprint,
519
664
  detectRemarqPlugin,
520
665
  detectSource,
521
666
  generateAgentExport,
522
- matchElement
667
+ matchElement,
668
+ migrateAnnotation,
669
+ transition
523
670
  };
524
671
  //# sourceMappingURL=index.js.map