@maplibre/maplibre-react-native 11.0.0-alpha.31 → 11.0.0-alpha.33

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.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/android/src/main/java/org/maplibre/reactnative/MLRNPackage.kt +10 -12
  3. package/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapView.kt +9 -0
  4. package/android/src/main/java/org/maplibre/reactnative/components/mapview/MLRNMapViewManager.kt +5 -1
  5. package/android/src/main/java/org/maplibre/reactnative/modules/MLRNModule.java +6 -24
  6. package/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.kt +561 -0
  7. package/ios/components/map-view/MLRNMapView.h +1 -0
  8. package/ios/components/map-view/MLRNMapView.m +5 -0
  9. package/ios/components/map-view/MLRNMapViewComponentView.mm +4 -0
  10. package/ios/modules/mlrn/MLRNModule.m +0 -13
  11. package/ios/modules/offline/MLRNOfflineModule.h +4 -7
  12. package/ios/modules/offline/MLRNOfflineModule.mm +693 -0
  13. package/lib/commonjs/MLRNModule.js +1 -3
  14. package/lib/commonjs/MLRNModule.js.map +1 -1
  15. package/lib/commonjs/components/map-view/AndroidTextureMapViewNativeComponent.ts +1 -0
  16. package/lib/commonjs/components/map-view/MapView.js.map +1 -1
  17. package/lib/commonjs/components/map-view/MapViewNativeComponent.ts +1 -0
  18. package/lib/commonjs/index.js +0 -8
  19. package/lib/commonjs/index.js.map +1 -1
  20. package/lib/commonjs/modules/offline/NativeOfflineModule.js +9 -0
  21. package/lib/commonjs/modules/offline/NativeOfflineModule.js.map +1 -0
  22. package/lib/commonjs/modules/offline/OfflineManager.js +124 -164
  23. package/lib/commonjs/modules/offline/OfflineManager.js.map +1 -1
  24. package/lib/commonjs/modules/offline/OfflinePack.js +15 -25
  25. package/lib/commonjs/modules/offline/OfflinePack.js.map +1 -1
  26. package/lib/module/MLRNModule.js +0 -1
  27. package/lib/module/MLRNModule.js.map +1 -1
  28. package/lib/module/components/map-view/AndroidTextureMapViewNativeComponent.ts +1 -0
  29. package/lib/module/components/map-view/MapView.js.map +1 -1
  30. package/lib/module/components/map-view/MapViewNativeComponent.ts +1 -0
  31. package/lib/module/index.js +0 -1
  32. package/lib/module/index.js.map +1 -1
  33. package/lib/module/modules/offline/NativeOfflineModule.js +5 -0
  34. package/lib/module/modules/offline/NativeOfflineModule.js.map +1 -0
  35. package/lib/module/modules/offline/OfflineManager.js +123 -163
  36. package/lib/module/modules/offline/OfflineManager.js.map +1 -1
  37. package/lib/module/modules/offline/OfflinePack.js +14 -25
  38. package/lib/module/modules/offline/OfflinePack.js.map +1 -1
  39. package/lib/typescript/commonjs/src/MLRNModule.d.ts +1 -6
  40. package/lib/typescript/commonjs/src/MLRNModule.d.ts.map +1 -1
  41. package/lib/typescript/commonjs/src/components/map-view/AndroidTextureMapViewNativeComponent.d.ts +1 -0
  42. package/lib/typescript/commonjs/src/components/map-view/AndroidTextureMapViewNativeComponent.d.ts.map +1 -1
  43. package/lib/typescript/commonjs/src/components/map-view/MapView.d.ts +6 -0
  44. package/lib/typescript/commonjs/src/components/map-view/MapView.d.ts.map +1 -1
  45. package/lib/typescript/commonjs/src/components/map-view/MapViewNativeComponent.d.ts +1 -0
  46. package/lib/typescript/commonjs/src/components/map-view/MapViewNativeComponent.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/src/index.d.ts +2 -5
  48. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/src/modules/offline/NativeOfflineModule.d.ts +50 -0
  50. package/lib/typescript/commonjs/src/modules/offline/NativeOfflineModule.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/src/modules/offline/OfflineManager.d.ts +66 -69
  52. package/lib/typescript/commonjs/src/modules/offline/OfflineManager.d.ts.map +1 -1
  53. package/lib/typescript/commonjs/src/modules/offline/OfflinePack.d.ts +11 -9
  54. package/lib/typescript/commonjs/src/modules/offline/OfflinePack.d.ts.map +1 -1
  55. package/lib/typescript/module/src/MLRNModule.d.ts +1 -6
  56. package/lib/typescript/module/src/MLRNModule.d.ts.map +1 -1
  57. package/lib/typescript/module/src/components/map-view/AndroidTextureMapViewNativeComponent.d.ts +1 -0
  58. package/lib/typescript/module/src/components/map-view/AndroidTextureMapViewNativeComponent.d.ts.map +1 -1
  59. package/lib/typescript/module/src/components/map-view/MapView.d.ts +6 -0
  60. package/lib/typescript/module/src/components/map-view/MapView.d.ts.map +1 -1
  61. package/lib/typescript/module/src/components/map-view/MapViewNativeComponent.d.ts +1 -0
  62. package/lib/typescript/module/src/components/map-view/MapViewNativeComponent.d.ts.map +1 -1
  63. package/lib/typescript/module/src/index.d.ts +2 -5
  64. package/lib/typescript/module/src/index.d.ts.map +1 -1
  65. package/lib/typescript/module/src/modules/offline/NativeOfflineModule.d.ts +50 -0
  66. package/lib/typescript/module/src/modules/offline/NativeOfflineModule.d.ts.map +1 -0
  67. package/lib/typescript/module/src/modules/offline/OfflineManager.d.ts +66 -69
  68. package/lib/typescript/module/src/modules/offline/OfflineManager.d.ts.map +1 -1
  69. package/lib/typescript/module/src/modules/offline/OfflinePack.d.ts +11 -9
  70. package/lib/typescript/module/src/modules/offline/OfflinePack.d.ts.map +1 -1
  71. package/package.json +7 -3
  72. package/src/MLRNModule.ts +0 -8
  73. package/src/components/map-view/AndroidTextureMapViewNativeComponent.ts +1 -0
  74. package/src/components/map-view/MapView.tsx +7 -0
  75. package/src/components/map-view/MapViewNativeComponent.ts +1 -0
  76. package/src/index.ts +13 -5
  77. package/src/modules/offline/NativeOfflineModule.ts +63 -0
  78. package/src/modules/offline/OfflineManager.ts +174 -210
  79. package/src/modules/offline/OfflinePack.ts +22 -32
  80. package/android/src/main/java/org/maplibre/reactnative/modules/MLRNOfflineModule.java +0 -586
  81. package/ios/modules/offline/MLRNOfflineModule.m +0 -524
  82. package/lib/commonjs/modules/offline/OfflineCreatePackOptions.js +0 -37
  83. package/lib/commonjs/modules/offline/OfflineCreatePackOptions.js.map +0 -1
  84. package/lib/commonjs/utils/makeNativeBounds.js +0 -11
  85. package/lib/commonjs/utils/makeNativeBounds.js.map +0 -1
  86. package/lib/module/modules/offline/OfflineCreatePackOptions.js +0 -32
  87. package/lib/module/modules/offline/OfflineCreatePackOptions.js.map +0 -1
  88. package/lib/module/utils/makeNativeBounds.js +0 -7
  89. package/lib/module/utils/makeNativeBounds.js.map +0 -1
  90. package/lib/typescript/commonjs/src/modules/offline/OfflineCreatePackOptions.d.ts +0 -20
  91. package/lib/typescript/commonjs/src/modules/offline/OfflineCreatePackOptions.d.ts.map +0 -1
  92. package/lib/typescript/commonjs/src/utils/makeNativeBounds.d.ts +0 -2
  93. package/lib/typescript/commonjs/src/utils/makeNativeBounds.d.ts.map +0 -1
  94. package/lib/typescript/module/src/modules/offline/OfflineCreatePackOptions.d.ts +0 -20
  95. package/lib/typescript/module/src/modules/offline/OfflineCreatePackOptions.d.ts.map +0 -1
  96. package/lib/typescript/module/src/utils/makeNativeBounds.d.ts +0 -2
  97. package/lib/typescript/module/src/utils/makeNativeBounds.d.ts.map +0 -1
  98. package/src/modules/offline/OfflineCreatePackOptions.ts +0 -53
  99. package/src/utils/makeNativeBounds.ts +0 -5
@@ -1,52 +1,69 @@
1
- import {
2
- NativeModules,
3
- NativeEventEmitter,
4
- type EventSubscription,
5
- } from "react-native";
6
-
7
- import {
8
- OfflineCreatePackOptions,
9
- type OfflineCreatePackInputOptions,
10
- } from "./OfflineCreatePackOptions";
1
+ import { type EventSubscription } from "react-native";
2
+
3
+ import NativeOfflineModule from "./NativeOfflineModule";
11
4
  import { OfflinePack, type OfflinePackStatus } from "./OfflinePack";
12
- import { isUndefined, isFunction, isAndroid } from "../../utils";
5
+ import type { LngLatBounds } from "../../types/LngLatBounds";
6
+
7
+ export interface OfflinePackCreateOptions {
8
+ mapStyle: string;
9
+ bounds: LngLatBounds;
10
+ minZoom?: number;
11
+ maxZoom?: number;
12
+
13
+ /**
14
+ * User-provided metadata object.
15
+ */
16
+ metadata?: Record<string, unknown>;
17
+ }
13
18
 
14
- const MLRNModule = NativeModules.MLRNModule;
15
- const MLRNOfflineModule = NativeModules.MLRNOfflineModule;
16
- export const OfflineModuleEventEmitter = new NativeEventEmitter(
17
- MLRNOfflineModule,
18
- );
19
+ /**
20
+ * Represents the offline pack download state
21
+ */
22
+ export type OfflinePackDownloadState = "inactive" | "active" | "complete";
19
23
 
20
24
  export type OfflinePackError = {
21
- name: string;
25
+ id: string;
22
26
  message: string;
23
27
  };
24
28
 
25
- type ProgressListener = (pack: OfflinePack, status: OfflinePackStatus) => void;
26
- type ErrorListener = (pack: OfflinePack, err: OfflinePackError) => void;
29
+ export type OfflinePackProgressListener = (
30
+ offlinePack: OfflinePack,
31
+ status: OfflinePackStatus,
32
+ ) => void;
33
+ export type OfflinePackErrorListener = (
34
+ offlinePack: OfflinePack,
35
+ error: OfflinePackError,
36
+ ) => void;
27
37
 
28
38
  /**
29
39
  * OfflineManager implements a singleton (shared object) that manages offline packs.
30
- * All of this classs instance methods are asynchronous, reflecting the fact that offline resources are stored in a database.
40
+ * All of this class's instance methods are asynchronous, reflecting the fact that offline resources are stored in a database.
31
41
  * The shared object maintains a canonical collection of offline packs.
32
42
  */
33
43
  class OfflineManager {
34
- _hasInitialized: boolean;
35
- _offlinePacks: Record<string, OfflinePack>;
36
- _progressListeners: Record<string, ProgressListener>;
37
- _errorListeners: Record<string, ErrorListener>;
38
- subscriptionProgress: EventSubscription | null;
39
- subscriptionError: EventSubscription | null;
44
+ private initialized: boolean;
45
+
46
+ private readonly offlinePacks: Record<string, OfflinePack>;
47
+
48
+ private readonly progressListeners: Record<
49
+ string,
50
+ OfflinePackProgressListener
51
+ >;
52
+ private readonly errorListeners: Record<string, OfflinePackErrorListener>;
53
+
54
+ private subscriptionProgress: EventSubscription | null;
55
+ private subscriptionError: EventSubscription | null;
40
56
 
41
57
  constructor() {
42
- this._hasInitialized = false;
43
- this._offlinePacks = {};
58
+ this.initialized = false;
59
+
60
+ this.offlinePacks = {};
44
61
 
45
- this._progressListeners = {};
46
- this._errorListeners = {};
62
+ this.progressListeners = {};
63
+ this.errorListeners = {};
47
64
 
48
- this._onProgress = this._onProgress.bind(this);
49
- this._onError = this._onError.bind(this);
65
+ this.handleProgress = this.handleProgress.bind(this);
66
+ this.onError = this.onError.bind(this);
50
67
 
51
68
  this.subscriptionProgress = null;
52
69
  this.subscriptionError = null;
@@ -58,39 +75,45 @@ class OfflineManager {
58
75
  * @example
59
76
  *
60
77
  * const progressListener = (offlineRegion, status) => console.log(offlineRegion, status);
61
- * const errorListener = (offlineRegion, err) => console.log(offlineRegion, err);
78
+ * const errorListener = (offlineRegion, error) => console.log(offlineRegion, error);
62
79
  *
63
- * await OfflineManager.createPack({
64
- * name: 'offlinePack',
80
+ * const offlinePack = await OfflineManager.createPack({
65
81
  * styleURL: 'https://demotiles.maplibre.org/tiles/tiles.json',
66
82
  * minZoom: 14,
67
83
  * maxZoom: 20,
68
- * bounds: [[neLng, neLat], [swLng, swLat]]
84
+ * bounds: [west, south, east, north],
85
+ * metadata: { customValue: 'myValue' }
69
86
  * }, progressListener, errorListener)
70
87
  *
71
- * @param {OfflineCreatePackOptions} options Create options for a offline pack that specifices zoom levels, style url, and the region to download.
72
- * @param {ProgressListener} progressListener Callback that listens for status events while downloading the offline resource.
73
- * @param {ErrorListener} errorListener Callback that listens for status events while downloading the offline resource.
74
- * @return {void}
88
+ * @param options Create options for offline pack that specifies zoom levels, style url, and the region to download.
89
+ * @param progressListener Callback that listens for status events while downloading the offline resource.
90
+ * @param errorListener Callback that listens for status events while downloading the offline resource.
91
+ *
92
+ * @return The created offline pack with its generated ID.
75
93
  */
76
94
  async createPack(
77
- options: OfflineCreatePackInputOptions,
78
- progressListener: ProgressListener,
79
- errorListener: ErrorListener,
80
- ): Promise<void> {
81
- await this._initialize();
82
-
83
- const packOptions = new OfflineCreatePackOptions(options);
84
-
85
- if (this._offlinePacks[packOptions.name]) {
86
- throw new Error(
87
- `Offline pack with name ${packOptions.name} already exists.`,
88
- );
89
- }
90
-
91
- this.subscribe(packOptions.name, progressListener, errorListener);
92
- const nativeOfflinePack = await MLRNOfflineModule.createPack(packOptions);
93
- this._offlinePacks[packOptions.name] = new OfflinePack(nativeOfflinePack);
95
+ options: OfflinePackCreateOptions,
96
+ progressListener: OfflinePackProgressListener,
97
+ errorListener: OfflinePackErrorListener,
98
+ ): Promise<OfflinePack> {
99
+ await this.initialize();
100
+
101
+ const offlinePackOptions = {
102
+ mapStyle: options.mapStyle,
103
+ bounds: options.bounds,
104
+ minZoom: options.minZoom ?? 10,
105
+ maxZoom: options.maxZoom ?? 20,
106
+ metadata: JSON.stringify(options.metadata ?? {}),
107
+ };
108
+
109
+ const nativeOfflinePack =
110
+ await NativeOfflineModule.createPack(offlinePackOptions);
111
+ const offlinePack = new OfflinePack(nativeOfflinePack);
112
+
113
+ this.offlinePacks[offlinePack.id] = offlinePack;
114
+ await this.addListener(offlinePack.id, progressListener, errorListener);
115
+
116
+ return offlinePack;
94
117
  }
95
118
 
96
119
  /**
@@ -99,45 +122,31 @@ class OfflineManager {
99
122
  * This is more efficient than deleting the offline pack and downloading it again. If the data stored locally matches that on the server, new data will not be downloaded.
100
123
  *
101
124
  * @example
102
- * await OfflineManager.invalidatePack('packName')
125
+ * await OfflineManager.invalidatePack(pack.id)
103
126
  *
104
- * @param {string} name Name of the offline pack.
105
- * @return {void}
127
+ * @param id ID of the OfflinePack.
106
128
  */
107
- async invalidatePack(name: string): Promise<void> {
108
- if (!name) {
109
- return;
110
- }
111
-
112
- await this._initialize();
129
+ async invalidatePack(id: string): Promise<void> {
130
+ await this.initialize();
113
131
 
114
- const offlinePack = this._offlinePacks[name];
115
- if (offlinePack) {
116
- await MLRNOfflineModule.invalidatePack(name);
117
- }
132
+ const offlinePack = await this.getPack(id);
133
+ await NativeOfflineModule.invalidatePack(offlinePack.id);
118
134
  }
119
135
 
120
136
  /**
121
- * Unregisters the given offline pack and allows resources that are no longer required by any remaining packs to be potentially freed.
137
+ * Unregisters the given OfflinePack and allows resources that are no longer required by any remaining packs to be potentially freed.
122
138
  *
123
139
  * @example
124
- * await OfflineManager.deletePack('packName')
140
+ * await OfflineManager.deletePack(pack.id)
125
141
  *
126
- * @param {string} name Name of the offline pack.
127
- * @return {void}
142
+ * @param id ID of the OfflinePack.
128
143
  */
129
- async deletePack(name: string): Promise<void> {
130
- if (!name) {
131
- return;
132
- }
133
-
134
- await this._initialize();
144
+ async deletePack(id: string): Promise<void> {
145
+ await this.initialize();
135
146
 
136
- const offlinePack = this._offlinePacks[name];
137
- if (offlinePack) {
138
- await MLRNOfflineModule.deletePack(name);
139
- delete this._offlinePacks[name];
140
- }
147
+ const offlinePack = await this.getPack(id);
148
+ await NativeOfflineModule.deletePack(offlinePack.id);
149
+ delete this.offlinePacks[offlinePack.id];
141
150
  }
142
151
 
143
152
  /**
@@ -148,12 +157,10 @@ class OfflineManager {
148
157
  *
149
158
  * @example
150
159
  * await OfflineManager.invalidateAmbientCache();
151
- *
152
- * @return {void}
153
160
  */
154
161
  async invalidateAmbientCache(): Promise<void> {
155
- await this._initialize();
156
- await MLRNOfflineModule.invalidateAmbientCache();
162
+ await this.initialize();
163
+ await NativeOfflineModule.invalidateAmbientCache();
157
164
  }
158
165
 
159
166
  /**
@@ -162,12 +169,10 @@ class OfflineManager {
162
169
  *
163
170
  * @example
164
171
  * await OfflineManager.clearAmbientCache();
165
- *
166
- * @return {void}
167
172
  */
168
173
  async clearAmbientCache(): Promise<void> {
169
- await this._initialize();
170
- await MLRNOfflineModule.clearAmbientCache();
174
+ await this.initialize();
175
+ await NativeOfflineModule.clearAmbientCache();
171
176
  }
172
177
 
173
178
  /**
@@ -177,12 +182,11 @@ class OfflineManager {
177
182
  * @example
178
183
  * await OfflineManager.setMaximumAmbientCacheSize(5000000);
179
184
  *
180
- * @param {number} size Size of ambient cache.
181
- * @return {void}
185
+ * @param size Size of ambient cache.
182
186
  */
183
187
  async setMaximumAmbientCacheSize(size: number): Promise<void> {
184
- await this._initialize();
185
- await MLRNOfflineModule.setMaximumAmbientCacheSize(size);
188
+ await this.initialize();
189
+ await NativeOfflineModule.setMaximumAmbientCacheSize(size);
186
190
  }
187
191
 
188
192
  /**
@@ -190,12 +194,10 @@ class OfflineManager {
190
194
  *
191
195
  * @example
192
196
  * await OfflineManager.resetDatabase();
193
- *
194
- * @return {void}
195
197
  */
196
198
  async resetDatabase(): Promise<void> {
197
- await this._initialize();
198
- await MLRNOfflineModule.resetDatabase();
199
+ await this.initialize();
200
+ await NativeOfflineModule.resetDatabase();
199
201
  }
200
202
 
201
203
  /**
@@ -203,29 +205,28 @@ class OfflineManager {
203
205
  *
204
206
  * @example
205
207
  * const offlinePacks = await OfflineManager.getPacks();
206
- *
207
- * @return {Array<OfflinePack>}
208
208
  */
209
209
  async getPacks(): Promise<OfflinePack[]> {
210
- await this._initialize();
210
+ await this.initialize();
211
211
 
212
- return Object.keys(this._offlinePacks)
213
- .map((name) => this._offlinePacks[name])
214
- .filter((pack) => !!pack);
212
+ return Object.values(this.offlinePacks);
215
213
  }
216
214
 
217
215
  /**
218
- * Retrieves an offline pack that is stored in the database by name.
216
+ * Retrieves an offline pack that is stored in the database by ID.
219
217
  *
220
218
  * @example
221
- * const offlinePack = await OfflineManager.getPack();
222
- *
223
- * @param {string} name Name of the offline pack.
224
- * @return {OfflinePack}
219
+ * const offlinePack = await OfflineManager.getPack(offlinePack.id);
225
220
  */
226
- async getPack(name: string) {
227
- await this._initialize();
228
- return this._offlinePacks[name];
221
+ async getPack(id: string): Promise<OfflinePack> {
222
+ await this.initialize();
223
+ const offlinePack = this.offlinePacks[id];
224
+
225
+ if (!offlinePack) {
226
+ throw new Error(`OfflinePack ${id} not found`);
227
+ }
228
+
229
+ return offlinePack;
229
230
  }
230
231
 
231
232
  /**
@@ -234,12 +235,11 @@ class OfflineManager {
234
235
  * @example
235
236
  * await OfflineManager.mergeOfflineRegions(path);
236
237
  *
237
- * @param {string} path Path to offline tile db on file system.
238
- * @return {void}
238
+ * @param path Path to offline tile db on file system.
239
239
  */
240
240
  async mergeOfflineRegions(path: string): Promise<void> {
241
- await this._initialize();
242
- return MLRNOfflineModule.mergeOfflineRegions(path);
241
+ await this.initialize();
242
+ return NativeOfflineModule.mergeOfflineRegions(path);
243
243
  }
244
244
 
245
245
  /**
@@ -249,11 +249,10 @@ class OfflineManager {
249
249
  * @example
250
250
  * OfflineManager.setTileCountLimit(1000);
251
251
  *
252
- * @param {number} limit Map tile limit count.
253
- * @return {void}
252
+ * @param limit Map tile limit count.
254
253
  */
255
254
  setTileCountLimit(limit: number): void {
256
- MLRNOfflineModule.setTileCountLimit(limit);
255
+ NativeOfflineModule.setTileCountLimit(limit);
257
256
  }
258
257
 
259
258
  /**
@@ -263,11 +262,10 @@ class OfflineManager {
263
262
  * @example
264
263
  * OfflineManager.setProgressEventThrottle(500);
265
264
  *
266
- * @param {number} throttleValue event throttle value in ms.
267
- * @return {void}
265
+ * @param throttleValue Event throttle value in ms.
268
266
  */
269
267
  setProgressEventThrottle(throttleValue: number): void {
270
- MLRNOfflineModule.setProgressEventThrottle(throttleValue);
268
+ NativeOfflineModule.setProgressEventThrottle(throttleValue);
271
269
  }
272
270
 
273
271
  /**
@@ -276,141 +274,107 @@ class OfflineManager {
276
274
  *
277
275
  * @example
278
276
  * const progressListener = (offlinePack, status) => console.log(offlinePack, status)
279
- * const errorListener = (offlinePack, err) => console.log(offlinePack, err)
280
- * OfflineManager.subscribe('packName', progressListener, errorListener)
277
+ * const errorListener = (offlinePack, error) => console.log(offlinePack, error)
278
+ * OfflineManager.addListener(pack.id, progressListener, errorListener)
281
279
  *
282
- * @param {string} packName Name of the offline pack.
283
- * @param {ProgressListener} progressListener Callback that listens for status events while downloading the offline resource.
284
- * @param {ErrorListener} errorListener Callback that listens for status events while downloading the offline resource.
285
- * @return {void}
280
+ * @param id ID of the offline pack.
281
+ * @param progressListener Callback that listens for status events while downloading the offline resource.
282
+ * @param errorListener Callback that listens for status events while downloading the offline resource.
286
283
  */
287
- async subscribe(
288
- packName: string,
289
- progressListener: ProgressListener,
290
- errorListener: ErrorListener,
284
+ async addListener(
285
+ id: string,
286
+ progressListener: OfflinePackProgressListener,
287
+ errorListener: OfflinePackErrorListener,
291
288
  ): Promise<void> {
292
- const totalProgressListeners = Object.keys(this._progressListeners).length;
293
- if (isFunction(progressListener)) {
294
- if (totalProgressListeners === 0) {
295
- this.subscriptionProgress = OfflineModuleEventEmitter.addListener(
296
- MLRNModule.OfflineCallbackName.Progress,
297
- this._onProgress,
298
- );
299
- }
300
- this._progressListeners[packName] = progressListener;
289
+ const totalProgressListeners = Object.keys(this.progressListeners).length;
290
+ if (totalProgressListeners === 0) {
291
+ this.subscriptionProgress = NativeOfflineModule.onProgress(
292
+ this.handleProgress,
293
+ );
301
294
  }
295
+ this.progressListeners[id] = progressListener;
302
296
 
303
- const totalErrorListeners = Object.keys(this._errorListeners).length;
304
- if (isFunction(errorListener)) {
305
- if (totalErrorListeners === 0) {
306
- this.subscriptionError = OfflineModuleEventEmitter.addListener(
307
- MLRNModule.OfflineCallbackName.Error,
308
- this._onError,
309
- );
310
- }
311
- this._errorListeners[packName] = errorListener;
297
+ const totalErrorListeners = Object.keys(this.errorListeners).length;
298
+ if (totalErrorListeners === 0) {
299
+ this.subscriptionError = NativeOfflineModule.onError(this.onError);
312
300
  }
301
+ this.errorListeners[id] = errorListener;
313
302
 
314
- // we need to manually set the pack observer on Android
315
- // if we're resuming a pack download instead of going thru the create flow
316
- if (isAndroid() && this._offlinePacks[packName]) {
317
- try {
318
- // manually set a listener, since listeners are only set on create flow
319
- await MLRNOfflineModule.setPackObserver(packName);
320
- } catch (e) {
321
- console.log("Unable to set pack observer", e);
322
- }
303
+ if (this.offlinePacks[id]) {
304
+ await NativeOfflineModule.setPackObserver(id);
323
305
  }
324
306
  }
325
307
 
326
308
  /**
327
309
  * Unsubscribes any listeners associated with the offline pack.
328
- * It's a good idea to call this on componentWillUnmount.
310
+ * Should be called when the component unmounts.
329
311
  *
330
312
  * @example
331
- * OfflineManager.unsubscribe('packName')
313
+ * useEffect(() => {
314
+ * return () => {
315
+ * OfflineManager.removeListener(pack.id);
316
+ * }
317
+ * }, []);
332
318
  *
333
- * @param {string} packName Name of the offline pack.
334
- * @return {void}
319
+ * @param packId ID of the offline pack.
335
320
  */
336
- unsubscribe(packName: string): void {
337
- delete this._progressListeners[packName];
338
- delete this._errorListeners[packName];
321
+ removeListener(packId: string): void {
322
+ delete this.progressListeners[packId];
323
+ delete this.errorListeners[packId];
339
324
 
340
325
  if (
341
- Object.keys(this._progressListeners).length === 0 &&
326
+ Object.keys(this.progressListeners).length === 0 &&
342
327
  this.subscriptionProgress
343
328
  ) {
344
329
  this.subscriptionProgress.remove();
345
330
  }
346
331
 
347
332
  if (
348
- Object.keys(this._errorListeners).length === 0 &&
333
+ Object.keys(this.errorListeners).length === 0 &&
349
334
  this.subscriptionError
350
335
  ) {
351
336
  this.subscriptionError.remove();
352
337
  }
353
338
  }
354
339
 
355
- async _initialize(): Promise<boolean> {
356
- if (this._hasInitialized) {
340
+ private async initialize(): Promise<boolean> {
341
+ if (this.initialized) {
357
342
  return true;
358
343
  }
359
344
 
360
- const nativeOfflinePacks = await MLRNOfflineModule.getPacks();
345
+ const nativeOfflinePacks = await NativeOfflineModule.getPacks();
361
346
 
362
347
  for (const nativeOfflinePack of nativeOfflinePacks) {
363
348
  const offlinePack = new OfflinePack(nativeOfflinePack);
364
- if (offlinePack.name) {
365
- this._offlinePacks[offlinePack.name] = offlinePack;
366
- }
349
+
350
+ this.offlinePacks[offlinePack.id] = offlinePack;
367
351
  }
368
352
 
369
- this._hasInitialized = true;
353
+ this.initialized = true;
370
354
  return true;
371
355
  }
372
356
 
373
- _onProgress(e: OfflinePackStatus): void {
374
- const { name, state } = e;
357
+ private handleProgress(event: OfflinePackStatus) {
358
+ const { id, state } = event;
359
+ const offlinePack = this.offlinePacks[id];
375
360
 
376
- if (!this._hasListeners(name, this._progressListeners)) {
377
- return;
378
- }
379
-
380
- const pack = this._offlinePacks[name];
381
- if (pack) {
382
- this._progressListeners[name]?.(pack, e);
361
+ if (offlinePack) {
362
+ this.progressListeners[offlinePack.id]?.(offlinePack, event);
383
363
  }
384
364
 
385
- // cleanup listeners now that they are no longer needed
386
- if (state === MLRNModule.OfflinePackDownloadState.Complete) {
387
- this.unsubscribe(name);
365
+ if (state === "complete") {
366
+ this.removeListener(id);
388
367
  }
389
368
  }
390
369
 
391
- _onError(e: OfflinePackError): void {
392
- const { name } = e;
370
+ private onError(event: OfflinePackError) {
371
+ const { id } = event;
393
372
 
394
- if (!this._hasListeners(name, this._errorListeners)) {
395
- return;
396
- }
397
-
398
- const pack = this._offlinePacks[name];
399
- if (pack) {
400
- this._errorListeners[name]?.(pack, e);
373
+ const offlinePack = this.offlinePacks[id];
374
+ if (offlinePack) {
375
+ this.errorListeners[offlinePack.id]?.(offlinePack, event);
401
376
  }
402
377
  }
403
-
404
- _hasListeners(
405
- name: string,
406
- listenerMap:
407
- | Record<string, ProgressListener>
408
- | Record<string, ErrorListener>,
409
- ): boolean {
410
- return (
411
- !isUndefined(this._offlinePacks[name]) && isFunction(listenerMap[name])
412
- );
413
- }
414
378
  }
415
379
 
416
380
  const offlineManager = new OfflineManager();
@@ -1,12 +1,12 @@
1
- import { NativeModules } from "react-native";
2
-
3
- import { OfflineCreatePackOptions } from "./OfflineCreatePackOptions";
4
-
5
- const MLRNOfflineModule = NativeModules.MLRNOfflineModule;
1
+ import NativeOfflineModule, {
2
+ type NativeOfflinePack,
3
+ } from "./NativeOfflineModule";
4
+ import type { OfflinePackDownloadState } from "./OfflineManager";
5
+ import type { LngLatBounds } from "../../types/LngLatBounds";
6
6
 
7
7
  export type OfflinePackStatus = {
8
- name: string;
9
- state: number;
8
+ id: string;
9
+ state: OfflinePackDownloadState;
10
10
  percentage: number;
11
11
  completedResourceCount: number;
12
12
  completedResourceSize: number;
@@ -16,39 +16,29 @@ export type OfflinePackStatus = {
16
16
  };
17
17
 
18
18
  export class OfflinePack {
19
- private pack: OfflineCreatePackOptions;
20
- private _metadata: Record<string, any> | null;
21
-
22
- constructor(pack: OfflineCreatePackOptions) {
23
- this.pack = pack;
24
- this._metadata = null;
25
- }
19
+ /** Unique Identifier (UUID), auto-generated natively during creation. */
20
+ public id: string;
26
21
 
27
- get name(): string | null {
28
- const { metadata } = this;
29
- return metadata && metadata.name;
30
- }
22
+ /** User-provided metadata object. */
23
+ public metadata: Record<string, unknown>;
31
24
 
32
- get bounds(): string {
33
- return this.pack.bounds;
34
- }
25
+ public bounds: LngLatBounds;
35
26
 
36
- get metadata(): Record<string, any> | null {
37
- if (!this._metadata && this.pack.metadata) {
38
- this._metadata = JSON.parse(this.pack.metadata);
39
- }
40
- return this._metadata;
27
+ constructor(pack: NativeOfflinePack) {
28
+ this.id = pack.id;
29
+ this.bounds = pack.bounds as LngLatBounds;
30
+ this.metadata = JSON.parse(pack.metadata);
41
31
  }
42
32
 
43
- status(): Promise<OfflinePackStatus> {
44
- return MLRNOfflineModule.getPackStatus(this.name);
33
+ async status(): Promise<OfflinePackStatus> {
34
+ return NativeOfflineModule.getPackStatus(this.id);
45
35
  }
46
36
 
47
- resume(): Promise<void> {
48
- return MLRNOfflineModule.resumePackDownload(this.name);
37
+ async resume(): Promise<void> {
38
+ return NativeOfflineModule.resumePackDownload(this.id);
49
39
  }
50
40
 
51
- pause(): Promise<void> {
52
- return MLRNOfflineModule.pausePackDownload(this.name);
41
+ async pause(): Promise<void> {
42
+ return NativeOfflineModule.pausePackDownload(this.id);
53
43
  }
54
44
  }