scandit-datacapture-frameworks-core 8.0.0-beta.1 → 8.0.0-beta.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.
@@ -0,0 +1,64 @@
1
+ import { FactoryMaker, loadCoreDefaults } from '../src';
2
+
3
+ const mockCoreDefaultsData = {
4
+ "Camera": {
5
+ "defaultPosition": "worldFacing",
6
+ "Settings": {
7
+ "zoomFactor": 1,
8
+ "zoomGestureZoomFactor": 2,
9
+ "focusGestureStrategy": "manualUntilCapture",
10
+ "focusRange": "near",
11
+ "preferredResolution": "auto",
12
+ "shouldPreferSmoothAutoFocus": false,
13
+ "properties": {}
14
+ },
15
+ "availablePositions": ["worldFacing", "userFacing"]
16
+ },
17
+ "Version": "8.1.0-test",
18
+ "deviceID": "test-device-id",
19
+ "AimerViewfinder": {
20
+ "dotColor": "ffffffcc",
21
+ "frameColor": "ffffffff"
22
+ },
23
+ "RectangularViewfinder": {
24
+ "defaultStyle": "rounded",
25
+ "styles": {
26
+ "rounded": {
27
+ "color": "ffffffff",
28
+ "size": "{\"aspect\":1.0,\"shorterDimension\":{\"unit\":\"fraction\",\"value\":0.75}}",
29
+ "disabledDimming": 0,
30
+ "dimming": 0,
31
+ "animation": "{\"looping\":true}",
32
+ "style": "rounded",
33
+ "disabledColor": "00000000",
34
+ "lineStyle": "light"
35
+ }
36
+ }
37
+ },
38
+ "DataCaptureView": {
39
+ "zoomGesture": "{\"type\":\"swipeToZoom\"}",
40
+ "pointOfInterest": "{\"x\":{\"unit\":\"fraction\",\"value\":0.5},\"y\":{\"unit\":\"fraction\",\"value\":0.5}}",
41
+ "focusGesture": "{\"showUIIndicator\":true,\"type\":\"tapToFocus\"}",
42
+ "logoStyle": "extended",
43
+ "logoOffset": "{\"x\":{\"unit\":\"fraction\",\"value\":0.0},\"y\":{\"unit\":\"fraction\",\"value\":0.0}}",
44
+ "logoAnchor": "bottomRight",
45
+ "scanAreaMargins": "{\"bottom\":{\"unit\":\"fraction\",\"value\":0.0},\"left\":{\"unit\":\"fraction\",\"value\":0.0},\"right\":{\"unit\":\"fraction\",\"value\":0.0},\"top\":{\"unit\":\"fraction\",\"value\":0.0}}"
46
+ },
47
+ "Brush": {
48
+ "fillColor": "00000000",
49
+ "strokeColor": "00000000",
50
+ "strokeWidth": 0
51
+ },
52
+ "LaserlineViewfinder": {
53
+ "width": "{\"unit\":\"fraction\",\"value\":0.8}",
54
+ "enabledColor": "#FFFFFFFF",
55
+ "disabledColor": "#00000000"
56
+ }
57
+ };
58
+
59
+ export function loadMockDefaults() {
60
+ loadCoreDefaults(mockCoreDefaultsData);
61
+ }
62
+
63
+ loadMockDefaults();
64
+
@@ -0,0 +1,148 @@
1
+ import { jest } from '@jest/globals';
2
+ import { NativeCaller } from '../src';
3
+ import { EventEmitter } from "eventemitter3";
4
+
5
+ export class MockDataCaptureView {
6
+ public get viewId(): number {
7
+ return 1;
8
+ }
9
+
10
+ addOverlay = jest.fn((overlay: any): Promise<void> => {
11
+ overlay.view = this as any;
12
+ return Promise.resolve();
13
+ });
14
+
15
+ removeOverlay = jest.fn((overlay: any): Promise<void> => {
16
+ overlay.view = null;
17
+ return Promise.resolve();
18
+ });
19
+ }
20
+
21
+ export class MockDataCaptureContext {
22
+ public controller: any = null;
23
+
24
+ constructor() {
25
+ this.controller = {
26
+ updateContextFromJSON: jest.fn(() => Promise.resolve())
27
+ };
28
+ }
29
+
30
+ addMode = jest.fn((mode: any): Promise<void> => {
31
+ mode._context = this;
32
+ return Promise.resolve();
33
+ });
34
+
35
+ setMode = jest.fn((mode: any): Promise<void> => {
36
+ mode._context = this;
37
+ return Promise.resolve();
38
+ });
39
+
40
+ setFrameSource = jest.fn(async (frameSource: any) => {
41
+ if (frameSource) {
42
+ if (typeof frameSource.setNativeFrameSourceIsBeingCreated === 'function') {
43
+ frameSource.setNativeFrameSourceIsBeingCreated();
44
+ }
45
+ await this.update();
46
+ frameSource.context = this;
47
+ }
48
+ });
49
+
50
+ update = jest.fn(async () => {
51
+ if (this.controller) {
52
+ await this.controller.updateContextFromJSON();
53
+ }
54
+ return Promise.resolve();
55
+ });
56
+
57
+ initializeAsync = jest.fn(() => Promise.resolve());
58
+ }
59
+
60
+ class MockEmitterSubscription {
61
+ constructor(
62
+ private emitter: EventEmitter,
63
+ private eventType: string,
64
+ private listener: (...args: any[]) => void
65
+ ) {}
66
+
67
+ remove(): void {
68
+ this.emitter.removeListener(this.eventType, this.listener);
69
+ }
70
+ }
71
+
72
+ export class MockNativeEventEmitter {
73
+ private emitter: EventEmitter;
74
+
75
+ constructor() {
76
+ this.emitter = new EventEmitter();
77
+ }
78
+
79
+ addListener(eventType: string, listener: (...args: any[]) => void): MockEmitterSubscription {
80
+ this.emitter.addListener(eventType, listener);
81
+ return new MockEmitterSubscription(this.emitter, eventType, listener);
82
+ }
83
+
84
+ removeAllListeners(eventType?: string): void {
85
+ this.emitter.removeAllListeners(eventType);
86
+ }
87
+
88
+ emit(eventType: string, ...args: any[]): boolean {
89
+ return this.emitter.emit(eventType, ...args);
90
+ }
91
+ }
92
+
93
+ export class MockCaller implements NativeCaller {
94
+ constructor(public nativeModule: any, public emitter: MockNativeEventEmitter) {}
95
+
96
+ eventHook(args: any) {
97
+ return args;
98
+ }
99
+
100
+ callFn(fnName: string, args: object | undefined | null): Promise<any> {
101
+ if (typeof this.nativeModule[fnName] === 'function') {
102
+ return this.nativeModule[fnName](args);
103
+ }
104
+ return Promise.resolve(undefined);
105
+ }
106
+
107
+ async registerEvent(evName: string, handler: (args: any) => Promise<void>): Promise<any> {
108
+ return this.emitter.addListener(evName, handler);
109
+ }
110
+
111
+ async unregisterEvent(evName: string, subscription: any): Promise<void> {
112
+ if (subscription && subscription.remove) {
113
+ await subscription.remove();
114
+ }
115
+ }
116
+ }
117
+
118
+ export function createMockCameraNativeModule() {
119
+ return {
120
+ $getCurrentCameraState: jest.fn(() => Promise.resolve({ data: 'off' })),
121
+ $switchCameraToDesiredState: jest.fn(() => Promise.resolve()),
122
+ $isTorchAvailable: jest.fn(() => Promise.resolve({ data: 'true' })),
123
+ $registerListenerForCameraEvents: jest.fn(() => Promise.resolve()),
124
+ $unregisterListenerForCameraEvents: jest.fn(() => Promise.resolve()),
125
+ $getFrame: jest.fn(() => Promise.resolve(null)),
126
+ };
127
+ }
128
+
129
+ export function createMockDataCaptureContextNativeModule() {
130
+ return {
131
+ $contextFromJSON: jest.fn(() => Promise.resolve({ data: '{}' })),
132
+ $updateContextFromJSON: jest.fn(() => Promise.resolve()),
133
+ $subscribeContextListener: jest.fn(),
134
+ $unsubscribeContextListener: jest.fn(() => Promise.resolve()),
135
+ $addModeToContext: jest.fn(() => Promise.resolve()),
136
+ $removeModeFromContext: jest.fn(() => Promise.resolve()),
137
+ $removeAllModes: jest.fn(() => Promise.resolve()),
138
+ $getOpenSourceSoftwareLicenseInfo: jest.fn(() => Promise.resolve({ data: '[]' })),
139
+ $disposeContext: jest.fn(() => Promise.resolve()),
140
+ };
141
+ }
142
+
143
+ export function createMockFeedbackNativeModule() {
144
+ return {
145
+ $emit: jest.fn(() => Promise.resolve()),
146
+ };
147
+ }
148
+
@@ -5,6 +5,25 @@ import { CameraController } from "./CameraController";
5
5
  import { TorchState } from "./TorchState";
6
6
  import { CameraPosition } from "../camerahelpers/CameraPosition";
7
7
  import { CameraSettings } from "./CameraSettings";
8
+ /**
9
+ * Camera lifecycle and operation handling:
10
+ *
11
+ * Phase 1 - Initial State (before native creation starts):
12
+ * - Camera object exists in TypeScript but not yet being created on native side
13
+ * - State changes (torch, desired state, settings) only update TypeScript properties
14
+ * - No native calls are triggered
15
+ *
16
+ * Phase 2 - Native Creation In Progress (after setFrameSource, before context set):
17
+ * - setFrameSource() called on DataCaptureContext, triggering setNativeFrameSourceIsBeingCreated()
18
+ * - A promise is created that will resolve when the native camera is ready
19
+ * - State changes during this phase await the native ready promise before executing
20
+ * - Native camera is created asynchronously
21
+ *
22
+ * Phase 3 - Active State (after context set):
23
+ * - Native camera is ready and available
24
+ * - The native ready promise is resolved
25
+ * - All state changes execute immediately on native side
26
+ */
8
27
  export declare class Camera extends DefaultSerializeable implements FrameSource {
9
28
  private type;
10
29
  private settings;
@@ -14,10 +33,15 @@ export declare class Camera extends DefaultSerializeable implements FrameSource
14
33
  private currentCameraState;
15
34
  private listeners;
16
35
  private _context;
36
+ private nativeReadyResolver;
37
+ private nativeReadyRejecter;
38
+ private nativeReadyPromise;
39
+ private nativeReadyTimeout;
17
40
  private static readonly _cameraInstances;
18
41
  private static get coreDefaults();
19
42
  private set context(value);
20
43
  private get context();
44
+ private setNativeFrameSourceIsBeingCreated;
21
45
  private get isActiveCamera();
22
46
  private controller;
23
47
  static get default(): Camera | null;
@@ -36,6 +60,7 @@ export declare class Camera extends DefaultSerializeable implements FrameSource
36
60
  removeListener(listener: FrameSourceListener | null): void;
37
61
  applySettings(settings: CameraSettings): Promise<void>;
38
62
  private didChange;
63
+ private resetPhaseState;
39
64
  }
40
65
  export interface PrivateCamera {
41
66
  context: DataCaptureContext | null;
@@ -33,14 +33,14 @@ export declare class DataCaptureContext extends DefaultSerializeable {
33
33
  setFrameSource(frameSource: FrameSource | null): Promise<void>;
34
34
  addListener(listener: DataCaptureContextListener): void;
35
35
  removeListener(listener: DataCaptureContextListener): void;
36
- addMode(mode: DataCaptureMode): void;
37
- setMode(mode: DataCaptureMode): void;
36
+ addMode(mode: DataCaptureMode): Promise<void>;
37
+ setMode(mode: DataCaptureMode): Promise<void>;
38
38
  private addModeInternal;
39
- removeCurrentMode(): void;
40
- removeMode(mode: DataCaptureMode): void;
39
+ removeCurrentMode(): Promise<void>;
40
+ removeMode(mode: DataCaptureMode): Promise<void>;
41
41
  private removeModeInternal;
42
- removeAllModes(): void;
43
- dispose(): void;
42
+ removeAllModes(): Promise<void>;
43
+ dispose(): Promise<void>;
44
44
  applySettings(settings: DataCaptureContextSettings): Promise<void>;
45
45
  static getOpenSourceSoftwareLicenseInfo(): Promise<OpenSourceSoftwareLicenseInfo>;
46
46
  private update;
@@ -4,6 +4,7 @@ import { FrameSourceListener } from "./FrameSourceListener";
4
4
  import { DataCaptureContext } from "../context/DataCaptureContext";
5
5
  export interface PrivateFrameSource {
6
6
  context: DataCaptureContext | null;
7
+ setNativeFrameSourceIsBeingCreated(): void;
7
8
  }
8
9
  export interface FrameSource extends Serializeable {
9
10
  readonly desiredState: FrameSourceState;
package/dist/index.js CHANGED
@@ -1716,16 +1716,73 @@ var TorchState;
1716
1716
  TorchState["Auto"] = "auto";
1717
1717
  })(TorchState || (TorchState = {}));
1718
1718
 
1719
+ /**
1720
+ * Camera lifecycle and operation handling:
1721
+ *
1722
+ * Phase 1 - Initial State (before native creation starts):
1723
+ * - Camera object exists in TypeScript but not yet being created on native side
1724
+ * - State changes (torch, desired state, settings) only update TypeScript properties
1725
+ * - No native calls are triggered
1726
+ *
1727
+ * Phase 2 - Native Creation In Progress (after setFrameSource, before context set):
1728
+ * - setFrameSource() called on DataCaptureContext, triggering setNativeFrameSourceIsBeingCreated()
1729
+ * - A promise is created that will resolve when the native camera is ready
1730
+ * - State changes during this phase await the native ready promise before executing
1731
+ * - Native camera is created asynchronously
1732
+ *
1733
+ * Phase 3 - Active State (after context set):
1734
+ * - Native camera is ready and available
1735
+ * - The native ready promise is resolved
1736
+ * - All state changes execute immediately on native side
1737
+ */
1719
1738
  class Camera extends DefaultSerializeable {
1720
1739
  static get coreDefaults() {
1721
1740
  return getCoreDefaults();
1722
1741
  }
1723
1742
  set context(newContext) {
1724
1743
  this._context = newContext;
1744
+ if (newContext) {
1745
+ // Phase 3: Native camera is ready, resolve the promise so waiting operations can proceed
1746
+ if (this.nativeReadyTimeout) {
1747
+ clearTimeout(this.nativeReadyTimeout);
1748
+ this.nativeReadyTimeout = null;
1749
+ }
1750
+ if (this.nativeReadyResolver) {
1751
+ this.nativeReadyResolver();
1752
+ this.nativeReadyResolver = null;
1753
+ this.nativeReadyRejecter = null;
1754
+ this.nativeReadyPromise = null;
1755
+ }
1756
+ }
1757
+ else {
1758
+ // When context is removed, reset everything
1759
+ if (this.nativeReadyTimeout) {
1760
+ clearTimeout(this.nativeReadyTimeout);
1761
+ this.nativeReadyTimeout = null;
1762
+ }
1763
+ this.nativeReadyResolver = null;
1764
+ this.nativeReadyRejecter = null;
1765
+ this.nativeReadyPromise = null;
1766
+ }
1725
1767
  }
1726
1768
  get context() {
1727
1769
  return this._context;
1728
1770
  }
1771
+ setNativeFrameSourceIsBeingCreated() {
1772
+ this.nativeReadyPromise = new Promise((resolve, reject) => {
1773
+ this.nativeReadyResolver = resolve;
1774
+ this.nativeReadyRejecter = reject;
1775
+ this.nativeReadyTimeout = setTimeout(() => {
1776
+ this.nativeReadyTimeout = null;
1777
+ if (this.nativeReadyRejecter) {
1778
+ this.nativeReadyRejecter(new Error('Camera native initialization timed out after 5 seconds'));
1779
+ this.nativeReadyResolver = null;
1780
+ this.nativeReadyRejecter = null;
1781
+ this.nativeReadyPromise = null;
1782
+ }
1783
+ }, 5000);
1784
+ });
1785
+ }
1729
1786
  get isActiveCamera() {
1730
1787
  return this._context !== null;
1731
1788
  }
@@ -1757,7 +1814,15 @@ class Camera extends DefaultSerializeable {
1757
1814
  }
1758
1815
  set desiredTorchState(desiredTorchState) {
1759
1816
  this._desiredTorchState = desiredTorchState;
1760
- this.didChange();
1817
+ if (this.nativeReadyPromise) {
1818
+ // Phase 2: Wait for native camera to be ready, then update
1819
+ this.nativeReadyPromise.then(() => this.didChange());
1820
+ }
1821
+ else if (this.isActiveCamera) {
1822
+ // Phase 3: Execute immediately
1823
+ this.didChange();
1824
+ }
1825
+ // Phase 1: Just update the property, no action needed
1761
1826
  }
1762
1827
  get desiredTorchState() {
1763
1828
  return this._desiredTorchState;
@@ -1771,6 +1836,10 @@ class Camera extends DefaultSerializeable {
1771
1836
  this.currentCameraState = FrameSourceState.Off;
1772
1837
  this.listeners = [];
1773
1838
  this._context = null;
1839
+ this.nativeReadyResolver = null;
1840
+ this.nativeReadyRejecter = null;
1841
+ this.nativeReadyPromise = null;
1842
+ this.nativeReadyTimeout = null;
1774
1843
  this.position = position || Camera.coreDefaults.Camera.defaultPosition;
1775
1844
  this.settings = settings || null;
1776
1845
  this._desiredTorchState = desiredTorchState || TorchState.Off;
@@ -1784,6 +1853,7 @@ class Camera extends DefaultSerializeable {
1784
1853
  }
1785
1854
  const existingCamera = Camera._cameraInstances.get(cameraPosition);
1786
1855
  if (existingCamera) {
1856
+ existingCamera.resetPhaseState();
1787
1857
  if (settings !== undefined) {
1788
1858
  existingCamera.settings = settings;
1789
1859
  }
@@ -1806,14 +1876,20 @@ class Camera extends DefaultSerializeable {
1806
1876
  }
1807
1877
  switchToDesiredState(state) {
1808
1878
  return __awaiter(this, void 0, void 0, function* () {
1879
+ this._desiredState = state;
1880
+ if (this.nativeReadyPromise) {
1881
+ // Phase 2: Wait for native camera to be ready, then switch state
1882
+ yield this.nativeReadyPromise;
1883
+ yield this.controller.switchCameraToDesiredState(state);
1884
+ return;
1885
+ }
1809
1886
  if (!this.isActiveCamera) {
1887
+ // Phase 1: Not yet added to context
1810
1888
  console.warn('The current camera is not added to the DataCaptureContext. Add camera to the DataCaptureContext first.');
1811
1889
  return;
1812
1890
  }
1813
- if (state !== this.currentCameraState) {
1814
- this._desiredState = state;
1815
- return this.controller.switchCameraToDesiredState(state);
1816
- }
1891
+ // Phase 3: Execute immediately
1892
+ yield this.controller.switchCameraToDesiredState(state);
1817
1893
  });
1818
1894
  }
1819
1895
  getCurrentState() {
@@ -1826,9 +1902,6 @@ class Camera extends DefaultSerializeable {
1826
1902
  if (listener == null) {
1827
1903
  return;
1828
1904
  }
1829
- if (this.listeners.length === 0) {
1830
- this.controller.subscribeListener();
1831
- }
1832
1905
  if (this.listeners.includes(listener)) {
1833
1906
  return;
1834
1907
  }
@@ -1844,8 +1917,19 @@ class Camera extends DefaultSerializeable {
1844
1917
  this.listeners.splice(this.listeners.indexOf(listener), 1);
1845
1918
  }
1846
1919
  applySettings(settings) {
1847
- this.settings = settings;
1848
- return this.didChange();
1920
+ return __awaiter(this, void 0, void 0, function* () {
1921
+ this.settings = settings;
1922
+ if (this.nativeReadyPromise) {
1923
+ // Phase 2: Wait for native camera to be ready, then apply settings
1924
+ yield this.nativeReadyPromise;
1925
+ yield this.didChange();
1926
+ }
1927
+ else if (this.isActiveCamera) {
1928
+ // Phase 3: Execute immediately
1929
+ yield this.didChange();
1930
+ }
1931
+ // Phase 1: Just update the property, no action needed
1932
+ });
1849
1933
  }
1850
1934
  didChange() {
1851
1935
  return __awaiter(this, void 0, void 0, function* () {
@@ -1854,6 +1938,15 @@ class Camera extends DefaultSerializeable {
1854
1938
  }
1855
1939
  });
1856
1940
  }
1941
+ resetPhaseState() {
1942
+ if (this.nativeReadyTimeout) {
1943
+ clearTimeout(this.nativeReadyTimeout);
1944
+ this.nativeReadyTimeout = null;
1945
+ }
1946
+ this.nativeReadyResolver = null;
1947
+ this.nativeReadyRejecter = null;
1948
+ this.nativeReadyPromise = null;
1949
+ }
1857
1950
  }
1858
1951
  Camera._cameraInstances = new Map();
1859
1952
  __decorate([
@@ -1874,6 +1967,18 @@ __decorate([
1874
1967
  __decorate([
1875
1968
  ignoreFromSerialization
1876
1969
  ], Camera.prototype, "_context", void 0);
1970
+ __decorate([
1971
+ ignoreFromSerialization
1972
+ ], Camera.prototype, "nativeReadyResolver", void 0);
1973
+ __decorate([
1974
+ ignoreFromSerialization
1975
+ ], Camera.prototype, "nativeReadyRejecter", void 0);
1976
+ __decorate([
1977
+ ignoreFromSerialization
1978
+ ], Camera.prototype, "nativeReadyPromise", void 0);
1979
+ __decorate([
1980
+ ignoreFromSerialization
1981
+ ], Camera.prototype, "nativeReadyTimeout", void 0);
1877
1982
  __decorate([
1878
1983
  ignoreFromSerialization
1879
1984
  ], Camera.prototype, "controller", void 0);
@@ -2536,14 +2641,21 @@ class DataCaptureContext extends DefaultSerializeable {
2536
2641
  }
2537
2642
  }
2538
2643
  setFrameSource(frameSource) {
2539
- if (this._frameSource) {
2540
- this._frameSource.context = null;
2541
- }
2542
- this._frameSource = frameSource;
2543
- if (frameSource) {
2544
- frameSource.context = this;
2545
- }
2546
- return this.update();
2644
+ return __awaiter(this, void 0, void 0, function* () {
2645
+ if (this._frameSource) {
2646
+ this._frameSource.context = null;
2647
+ }
2648
+ this._frameSource = frameSource;
2649
+ if (frameSource) {
2650
+ // Set the flag to indicate that the native frame source is being created
2651
+ frameSource.setNativeFrameSourceIsBeingCreated();
2652
+ }
2653
+ yield this.update();
2654
+ // Make camera active once the set on native side is complete
2655
+ if (frameSource) {
2656
+ frameSource.context = this;
2657
+ }
2658
+ });
2547
2659
  }
2548
2660
  addListener(listener) {
2549
2661
  if (this.listeners.length === 0) {
@@ -2564,30 +2676,40 @@ class DataCaptureContext extends DefaultSerializeable {
2564
2676
  }
2565
2677
  }
2566
2678
  addMode(mode) {
2567
- this.addModeInternal(mode);
2679
+ return __awaiter(this, void 0, void 0, function* () {
2680
+ yield this.addModeInternal(mode);
2681
+ });
2568
2682
  }
2569
2683
  setMode(mode) {
2570
- this.removeAllModes();
2571
- this.addModeInternal(mode);
2684
+ return __awaiter(this, void 0, void 0, function* () {
2685
+ yield this.removeAllModes();
2686
+ yield this.addModeInternal(mode);
2687
+ });
2572
2688
  }
2573
2689
  addModeInternal(mode) {
2574
- if (!this.modes.includes(mode)) {
2575
- this.modes.push(mode);
2576
- this.controller.addModeToContext(mode);
2577
- mode._context = this;
2578
- }
2690
+ return __awaiter(this, void 0, void 0, function* () {
2691
+ if (!this.modes.includes(mode)) {
2692
+ this.modes.push(mode);
2693
+ yield this.controller.addModeToContext(mode);
2694
+ mode._context = this;
2695
+ }
2696
+ });
2579
2697
  }
2580
2698
  removeCurrentMode() {
2581
- if (this.modes.length === 0) {
2582
- return;
2583
- }
2584
- if (this.modes.length > 1) {
2585
- console.warn('removeCurrentMode() called with multiple modes active. Consider using removeMode() for specific mode removal. Only the first mode will be removed.');
2586
- }
2587
- this.removeModeInternal(this.modes[0]);
2699
+ return __awaiter(this, void 0, void 0, function* () {
2700
+ if (this.modes.length === 0) {
2701
+ return;
2702
+ }
2703
+ if (this.modes.length > 1) {
2704
+ console.warn('removeCurrentMode() called with multiple modes active. Consider using removeMode() for specific mode removal. Only the first mode will be removed.');
2705
+ }
2706
+ yield this.removeModeInternal(this.modes[0]);
2707
+ });
2588
2708
  }
2589
2709
  removeMode(mode) {
2590
- this.removeModeInternal(mode);
2710
+ return __awaiter(this, void 0, void 0, function* () {
2711
+ yield this.removeModeInternal(mode);
2712
+ });
2591
2713
  }
2592
2714
  removeModeInternal(mode) {
2593
2715
  return __awaiter(this, void 0, void 0, function* () {
@@ -2600,27 +2722,33 @@ class DataCaptureContext extends DefaultSerializeable {
2600
2722
  });
2601
2723
  }
2602
2724
  removeAllModes() {
2603
- if (this.modes.length === 0) {
2604
- return;
2605
- }
2606
- this.modes.forEach(mode => {
2607
- mode._context = null;
2725
+ return __awaiter(this, void 0, void 0, function* () {
2726
+ if (this.modes.length === 0) {
2727
+ return;
2728
+ }
2729
+ this.modes.forEach(mode => {
2730
+ mode._context = null;
2731
+ });
2732
+ this.modes = [];
2733
+ yield this.controller.removeAllModesFromContext();
2608
2734
  });
2609
- this.modes = [];
2610
- this.controller.removeAllModesFromContext();
2611
2735
  }
2612
2736
  dispose() {
2613
- var _a;
2614
- if (!this.controller) {
2615
- return;
2616
- }
2617
- (_a = this.view) === null || _a === void 0 ? void 0 : _a.dispose();
2618
- this.removeAllModes();
2619
- this.controller.dispose();
2737
+ return __awaiter(this, void 0, void 0, function* () {
2738
+ var _a;
2739
+ if (!this.controller) {
2740
+ return;
2741
+ }
2742
+ (_a = this.view) === null || _a === void 0 ? void 0 : _a.dispose();
2743
+ yield this.removeAllModes();
2744
+ this.controller.dispose();
2745
+ });
2620
2746
  }
2621
2747
  applySettings(settings) {
2622
- this.settings = settings;
2623
- return this.update();
2748
+ return __awaiter(this, void 0, void 0, function* () {
2749
+ this.settings = settings;
2750
+ yield this.update();
2751
+ });
2624
2752
  }
2625
2753
  static getOpenSourceSoftwareLicenseInfo() {
2626
2754
  return __awaiter(this, void 0, void 0, function* () {
@@ -2628,10 +2756,12 @@ class DataCaptureContext extends DefaultSerializeable {
2628
2756
  });
2629
2757
  }
2630
2758
  update() {
2631
- if (!this.controller) {
2632
- return Promise.resolve();
2633
- }
2634
- return this.controller.updateContextFromJSON();
2759
+ return __awaiter(this, void 0, void 0, function* () {
2760
+ if (!this.controller) {
2761
+ return;
2762
+ }
2763
+ yield this.controller.updateContextFromJSON();
2764
+ });
2635
2765
  }
2636
2766
  }
2637
2767
  __decorate([