@doorstepai/dropoff-sdk-capacitor 1.0.2 → 1.0.3

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 (38) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/ai/doorstep/dropoffsdk/capacitor/DoorstepAIDropoffSDKPlugin.kt +133 -1
  3. package/dist/docs.json +282 -1
  4. package/dist/esm/definitions.d.ts +69 -6
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/esm/web.d.ts +13 -1
  7. package/dist/esm/web.js +15 -0
  8. package/dist/esm/web.js.map +1 -1
  9. package/dist/plugin.cjs.js +15 -2
  10. package/dist/plugin.cjs.js.map +1 -1
  11. package/dist/plugin.js +15 -2
  12. package/dist/plugin.js.map +1 -1
  13. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  14. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Info.plist +0 -0
  15. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.abi.json +5365 -1558
  16. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +82 -9
  17. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  18. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftinterface +82 -9
  19. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +11 -11
  20. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  21. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2630 -2113
  22. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
  23. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Info.plist +0 -0
  24. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +5365 -1558
  25. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +82 -9
  26. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  27. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +82 -9
  28. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +5365 -1558
  29. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +82 -9
  30. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  31. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +82 -9
  32. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +21 -21
  33. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
  34. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2630 -2113
  35. package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/DoorstepDropoffSDK.yml +2616 -2102
  36. package/ios/Plugin/DoorstepAIDropoffSDKPlugin.m +5 -0
  37. package/ios/Plugin/DoorstepAIDropoffSDKPlugin.swift +132 -1
  38. package/package.json +1 -1
@@ -43,6 +43,6 @@ dependencies {
43
43
  implementation "com.capacitorjs:core:$capacitorAndroidVersion"
44
44
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
45
45
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
46
- implementation "ai.doorstep.com:doorstepai-dropoff-sdk:2.0.9"
46
+ implementation "ai.doorstep.com:doorstepai-dropoff-sdk:2.1.0"
47
47
  testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.0"
48
48
  }
@@ -2,6 +2,7 @@ package ai.doorstep.dropoffsdk.capacitor
2
2
 
3
3
  import android.Manifest
4
4
  import android.util.Log
5
+ import com.getcapacitor.JSArray
5
6
  import com.getcapacitor.JSObject
6
7
  import com.getcapacitor.Plugin
7
8
  import com.getcapacitor.PluginCall
@@ -13,13 +14,17 @@ import com.doorstepai.sdks.tracking.AddressType
13
14
  import com.doorstepai.sdks.tracking.DoorstepAI
14
15
  import com.doorstepai.sdks.tracking.DropoffType
15
16
  import com.doorstepai.sdks.tracking.LatLngObject
17
+ import com.doorstepai.sdks.tracking.DeliveryStop
18
+ import com.doorstepai.sdks.tracking.RouteGeofenceOptions
16
19
 
17
20
  import kotlinx.coroutines.CoroutineScope
18
21
  import kotlinx.coroutines.Dispatchers
22
+ import kotlinx.coroutines.Job
19
23
  import kotlinx.coroutines.SupervisorJob
20
24
  import kotlinx.coroutines.cancel
21
25
  import kotlinx.coroutines.launch
22
26
  import kotlinx.coroutines.withContext
27
+ import kotlinx.coroutines.flow.collect
23
28
 
24
29
  @CapacitorPlugin(
25
30
  name = "DoorstepAIDropoffSDK",
@@ -35,15 +40,35 @@ import kotlinx.coroutines.withContext
35
40
  alias = "activity",
36
41
  strings = [Manifest.permission.ACTIVITY_RECOGNITION],
37
42
  ),
43
+ // Bluetooth (BLE) — opt-in; request explicitly via
44
+ // requestPermissions({ permissions: ['bluetooth'] }). BLUETOOTH_SCAN is
45
+ // declared by the SDK manifest (merged). API 31+; a no-op below S.
46
+ Permission(
47
+ alias = "bluetooth",
48
+ strings = [Manifest.permission.BLUETOOTH_SCAN],
49
+ ),
38
50
  ],
39
51
  )
40
52
  class DoorstepAIDropoffSDKPlugin : Plugin() {
41
53
 
42
54
  private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
55
+ private var geofenceJob: Job? = null
43
56
 
44
57
  override fun load() {
45
58
  super.load()
46
59
  Log.d(TAG, "load(): plugin attached, ready for calls")
60
+ // Stream native geofence-session events onto the "geofenceSessionEvent" listener.
61
+ geofenceJob = scope.launch {
62
+ DoorstepAI.geofenceSessionEvents.collect { ev ->
63
+ notifyListeners(
64
+ "geofenceSessionEvent",
65
+ JSObject()
66
+ .put("deliveryId", ev.deliveryId)
67
+ .put("type", ev.type.name)
68
+ .put("reason", ev.reason)
69
+ )
70
+ }
71
+ }
47
72
  }
48
73
 
49
74
  override fun handleOnDestroy() {
@@ -307,12 +332,13 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
307
332
  fun newEvent(call: PluginCall) {
308
333
  val eventName = call.getString("eventName")
309
334
  val deliveryId = call.getString("deliveryId")
335
+ val timestamp = call.getDouble("timestamp")
310
336
  Log.d(TAG, "newEvent: eventName=$eventName deliveryId=$deliveryId")
311
337
  if (eventName == null || deliveryId == null) {
312
338
  return call.reject("eventName or deliveryId missing", "BAD_ARGS")
313
339
  }
314
340
  try {
315
- DoorstepAI.newEvent(eventName, deliveryId) { /* result swallowed in Flutter parity */ }
341
+ DoorstepAI.newEvent(eventName, deliveryId, timestamp) { /* fire-and-forget */ }
316
342
  call.resolve()
317
343
  } catch (e: Exception) {
318
344
  call.reject(e.message ?: "Failed to save event", "EVENT_CREATION_ERROR")
@@ -338,4 +364,110 @@ class DoorstepAIDropoffSDKPlugin : Plugin() {
338
364
  if (lat.isNaN() || lng.isNaN()) return null
339
365
  return LatLngObject(lat = lat, lng = lng)
340
366
  }
367
+
368
+ // ---- Route geofencing ----
369
+
370
+ @PluginMethod
371
+ fun startRouteGeofencing(call: PluginCall) {
372
+ val stops = parseStops(call.getArray("stops"))
373
+ if (stops.isEmpty()) {
374
+ return call.reject("startRouteGeofencing requires at least one valid stop (deliveryId + latitude + longitude)", "ROUTE_GEOFENCING_ERROR")
375
+ }
376
+ try {
377
+ DoorstepAI.startRouteGeofencing(stops, parseRouteOptions(call.getObject("options"))) { r ->
378
+ r.onSuccess { call.resolve() }
379
+ .onFailure { call.reject(it.message ?: "Failed to start route geofencing", "ROUTE_GEOFENCING_ERROR") }
380
+ }
381
+ } catch (e: Exception) {
382
+ call.reject(e.message ?: "Failed to start route geofencing", "ROUTE_GEOFENCING_ERROR")
383
+ }
384
+ }
385
+
386
+ @PluginMethod
387
+ fun updateRouteStops(call: PluginCall) {
388
+ try {
389
+ DoorstepAI.updateRouteStops(parseStops(call.getArray("stops"))) { r ->
390
+ r.onSuccess { call.resolve() }
391
+ .onFailure { call.reject(it.message ?: "Failed to update route stops", "ROUTE_GEOFENCING_ERROR") }
392
+ }
393
+ } catch (e: Exception) {
394
+ call.reject(e.message ?: "Failed to update route stops", "ROUTE_GEOFENCING_ERROR")
395
+ }
396
+ }
397
+
398
+ @PluginMethod
399
+ fun stopRouteGeofencing(call: PluginCall) {
400
+ try {
401
+ DoorstepAI.stopRouteGeofencing()
402
+ call.resolve()
403
+ } catch (e: Exception) {
404
+ call.reject(e.message ?: "Failed to stop route geofencing", "ROUTE_GEOFENCING_ERROR")
405
+ }
406
+ }
407
+
408
+ @PluginMethod
409
+ fun resumeRouteGeofencingIfNeeded(call: PluginCall) {
410
+ try {
411
+ DoorstepAI.resumeRouteGeofencingIfNeeded()
412
+ call.resolve()
413
+ } catch (e: Exception) {
414
+ call.reject(e.message ?: "Failed to resume route geofencing", "ROUTE_GEOFENCING_ERROR")
415
+ }
416
+ }
417
+
418
+ @PluginMethod
419
+ fun getMonitoredStops(call: PluginCall) {
420
+ try {
421
+ val arr = JSArray()
422
+ DoorstepAI.monitoredStops.forEach { arr.put(serializeStop(it)) }
423
+ call.resolve(JSObject().put("stops", arr))
424
+ } catch (e: Exception) {
425
+ call.reject(e.message ?: "Failed to get monitored stops", "ROUTE_GEOFENCING_ERROR")
426
+ }
427
+ }
428
+
429
+ private fun parseStops(arr: JSArray?): List<DeliveryStop> {
430
+ if (arr == null) return emptyList()
431
+ val out = ArrayList<DeliveryStop>()
432
+ for (i in 0 until arr.length()) {
433
+ val m = arr.optJSONObject(i) ?: continue
434
+ val deliveryId = m.optString("deliveryId", "")
435
+ if (deliveryId.isEmpty() || !m.has("latitude") || !m.has("longitude")) continue
436
+ out.add(
437
+ DeliveryStop(
438
+ deliveryId = deliveryId,
439
+ address = m.optString("address", ""),
440
+ latitude = m.optDouble("latitude"),
441
+ longitude = m.optDouble("longitude"),
442
+ radiusMeters = if (m.has("radiusMeters")) m.optDouble("radiusMeters") else null,
443
+ customerId = if (m.has("customerId")) m.optString("customerId") else null,
444
+ driverId = if (m.has("driverId")) m.optString("driverId") else null,
445
+ ),
446
+ )
447
+ }
448
+ return out
449
+ }
450
+
451
+ // Android RouteGeofenceOptions carries manualForeground (unlike iOS).
452
+ private fun parseRouteOptions(o: JSObject?): RouteGeofenceOptions {
453
+ if (o == null) return RouteGeofenceOptions()
454
+ return RouteGeofenceOptions(
455
+ defaultRadiusMeters = if (o.has("defaultRadiusMeters")) o.optDouble("defaultRadiusMeters", 250.0) else 250.0,
456
+ timeoutSeconds = if (o.has("timeoutSeconds")) o.optDouble("timeoutSeconds") else null,
457
+ autoStopAfterDropoffSeconds = if (o.has("autoStopAfterDropoffSeconds")) o.optDouble("autoStopAfterDropoffSeconds") else null,
458
+ manualForeground = o.optBoolean("manualForeground", false),
459
+ )
460
+ }
461
+
462
+ private fun serializeStop(s: DeliveryStop): JSObject {
463
+ val o = JSObject()
464
+ o.put("deliveryId", s.deliveryId)
465
+ o.put("address", s.address)
466
+ o.put("latitude", s.latitude)
467
+ o.put("longitude", s.longitude)
468
+ s.radiusMeters?.let { o.put("radiusMeters", it) }
469
+ s.customerId?.let { o.put("customerId", it) }
470
+ s.driverId?.let { o.put("driverId", it) }
471
+ return o
472
+ }
341
473
  }
package/dist/docs.json CHANGED
@@ -203,6 +203,109 @@
203
203
  ],
204
204
  "slug": "stopdelivery"
205
205
  },
206
+ {
207
+ "name": "startRouteGeofencing",
208
+ "signature": "(options: { stops: DeliveryStop[]; options?: RouteGeofenceOptions; }) => Promise<void>",
209
+ "parameters": [
210
+ {
211
+ "name": "options",
212
+ "docs": "",
213
+ "type": "{ stops: DeliveryStop[]; options?: RouteGeofenceOptions | undefined; }"
214
+ }
215
+ ],
216
+ "returns": "Promise<void>",
217
+ "tags": [],
218
+ "docs": "Start route geofencing. ENTER auto-starts a session; EXIT stops it only if a\ndropoff was marked (else the per-session timeout backstops it). Subscribe to\nsession lifecycle via `addListener('geofenceSessionEvent', ...)`.",
219
+ "complexTypes": [
220
+ "DeliveryStop",
221
+ "RouteGeofenceOptions"
222
+ ],
223
+ "slug": "startroutegeofencing"
224
+ },
225
+ {
226
+ "name": "updateRouteStops",
227
+ "signature": "(options: { stops: DeliveryStop[]; }) => Promise<void>",
228
+ "parameters": [
229
+ {
230
+ "name": "options",
231
+ "docs": "",
232
+ "type": "{ stops: DeliveryStop[]; }"
233
+ }
234
+ ],
235
+ "returns": "Promise<void>",
236
+ "tags": [],
237
+ "docs": "Replace the monitored stops in place without tearing down still-present stops.",
238
+ "complexTypes": [
239
+ "DeliveryStop"
240
+ ],
241
+ "slug": "updateroutestops"
242
+ },
243
+ {
244
+ "name": "stopRouteGeofencing",
245
+ "signature": "() => Promise<void>",
246
+ "parameters": [],
247
+ "returns": "Promise<void>",
248
+ "tags": [],
249
+ "docs": "Stop route geofencing and clear all monitored stops.",
250
+ "complexTypes": [],
251
+ "slug": "stoproutegeofencing"
252
+ },
253
+ {
254
+ "name": "resumeRouteGeofencingIfNeeded",
255
+ "signature": "() => Promise<void>",
256
+ "parameters": [],
257
+ "returns": "Promise<void>",
258
+ "tags": [],
259
+ "docs": "Re-arm route geofencing after a process relaunch if a route was active.",
260
+ "complexTypes": [],
261
+ "slug": "resumeroutegeofencingifneeded"
262
+ },
263
+ {
264
+ "name": "getMonitoredStops",
265
+ "signature": "() => Promise<{ stops: DeliveryStop[]; }>",
266
+ "parameters": [],
267
+ "returns": "Promise<{ stops: DeliveryStop[]; }>",
268
+ "tags": [],
269
+ "docs": "The stops currently registered for route geofencing (empty if none).",
270
+ "complexTypes": [
271
+ "DeliveryStop"
272
+ ],
273
+ "slug": "getmonitoredstops"
274
+ },
275
+ {
276
+ "name": "addListener",
277
+ "signature": "(eventName: 'geofenceSessionEvent', listenerFunc: (event: GeofenceSessionEvent) => void) => Promise<PluginListenerHandle>",
278
+ "parameters": [
279
+ {
280
+ "name": "eventName",
281
+ "docs": "",
282
+ "type": "'geofenceSessionEvent'"
283
+ },
284
+ {
285
+ "name": "listenerFunc",
286
+ "docs": "",
287
+ "type": "(event: GeofenceSessionEvent) => void"
288
+ }
289
+ ],
290
+ "returns": "Promise<PluginListenerHandle>",
291
+ "tags": [],
292
+ "docs": "Subscribe to route-geofence session STARTED/STOPPED events.",
293
+ "complexTypes": [
294
+ "PluginListenerHandle",
295
+ "GeofenceSessionEvent"
296
+ ],
297
+ "slug": "addlistenergeofencesessionevent-"
298
+ },
299
+ {
300
+ "name": "removeAllListeners",
301
+ "signature": "() => Promise<void>",
302
+ "parameters": [],
303
+ "returns": "Promise<void>",
304
+ "tags": [],
305
+ "docs": "Remove all listeners registered for this plugin.",
306
+ "complexTypes": [],
307
+ "slug": "removealllisteners"
308
+ },
206
309
  {
207
310
  "name": "checkPermissions",
208
311
  "signature": "() => Promise<PermissionStatus>",
@@ -615,6 +718,13 @@
615
718
  "docs": "",
616
719
  "complexTypes": [],
617
720
  "type": "string"
721
+ },
722
+ {
723
+ "name": "timestamp",
724
+ "tags": [],
725
+ "docs": "Epoch seconds; if omitted the SDK stamps the current time.",
726
+ "complexTypes": [],
727
+ "type": "number | undefined"
618
728
  }
619
729
  ]
620
730
  },
@@ -634,6 +744,149 @@
634
744
  }
635
745
  ]
636
746
  },
747
+ {
748
+ "name": "DeliveryStop",
749
+ "slug": "deliverystop",
750
+ "docs": "A stop monitored for route geofencing. Mirrors the native `DeliveryStop`.",
751
+ "tags": [],
752
+ "methods": [],
753
+ "properties": [
754
+ {
755
+ "name": "deliveryId",
756
+ "tags": [],
757
+ "docs": "",
758
+ "complexTypes": [],
759
+ "type": "string"
760
+ },
761
+ {
762
+ "name": "address",
763
+ "tags": [],
764
+ "docs": "",
765
+ "complexTypes": [],
766
+ "type": "string"
767
+ },
768
+ {
769
+ "name": "latitude",
770
+ "tags": [],
771
+ "docs": "",
772
+ "complexTypes": [],
773
+ "type": "number"
774
+ },
775
+ {
776
+ "name": "longitude",
777
+ "tags": [],
778
+ "docs": "",
779
+ "complexTypes": [],
780
+ "type": "number"
781
+ },
782
+ {
783
+ "name": "radiusMeters",
784
+ "tags": [],
785
+ "docs": "",
786
+ "complexTypes": [],
787
+ "type": "number | undefined"
788
+ },
789
+ {
790
+ "name": "customerId",
791
+ "tags": [],
792
+ "docs": "",
793
+ "complexTypes": [],
794
+ "type": "string | undefined"
795
+ },
796
+ {
797
+ "name": "driverId",
798
+ "tags": [],
799
+ "docs": "",
800
+ "complexTypes": [],
801
+ "type": "string | undefined"
802
+ }
803
+ ]
804
+ },
805
+ {
806
+ "name": "RouteGeofenceOptions",
807
+ "slug": "routegeofenceoptions",
808
+ "docs": "Options for {@link DoorstepAIDropoffSDKPlugin.startRouteGeofencing}.",
809
+ "tags": [],
810
+ "methods": [],
811
+ "properties": [
812
+ {
813
+ "name": "defaultRadiusMeters",
814
+ "tags": [],
815
+ "docs": "",
816
+ "complexTypes": [],
817
+ "type": "number | undefined"
818
+ },
819
+ {
820
+ "name": "timeoutSeconds",
821
+ "tags": [],
822
+ "docs": "",
823
+ "complexTypes": [],
824
+ "type": "number | undefined"
825
+ },
826
+ {
827
+ "name": "autoStopAfterDropoffSeconds",
828
+ "tags": [],
829
+ "docs": "",
830
+ "complexTypes": [],
831
+ "type": "number | undefined"
832
+ },
833
+ {
834
+ "name": "manualForeground",
835
+ "tags": [],
836
+ "docs": "Android only; ignored on iOS (the OS owns background region monitoring).",
837
+ "complexTypes": [],
838
+ "type": "boolean | undefined"
839
+ }
840
+ ]
841
+ },
842
+ {
843
+ "name": "PluginListenerHandle",
844
+ "slug": "pluginlistenerhandle",
845
+ "docs": "",
846
+ "tags": [],
847
+ "methods": [],
848
+ "properties": [
849
+ {
850
+ "name": "remove",
851
+ "tags": [],
852
+ "docs": "",
853
+ "complexTypes": [],
854
+ "type": "() => Promise<void>"
855
+ }
856
+ ]
857
+ },
858
+ {
859
+ "name": "GeofenceSessionEvent",
860
+ "slug": "geofencesessionevent",
861
+ "docs": "Payload delivered to the `'geofenceSessionEvent'` listener.",
862
+ "tags": [],
863
+ "methods": [],
864
+ "properties": [
865
+ {
866
+ "name": "deliveryId",
867
+ "tags": [],
868
+ "docs": "",
869
+ "complexTypes": [],
870
+ "type": "string"
871
+ },
872
+ {
873
+ "name": "type",
874
+ "tags": [],
875
+ "docs": "",
876
+ "complexTypes": [
877
+ "GeofenceSessionEventType"
878
+ ],
879
+ "type": "GeofenceSessionEventType"
880
+ },
881
+ {
882
+ "name": "reason",
883
+ "tags": [],
884
+ "docs": "",
885
+ "complexTypes": [],
886
+ "type": "string"
887
+ }
888
+ ]
889
+ },
637
890
  {
638
891
  "name": "PermissionStatus",
639
892
  "slug": "permissionstatus",
@@ -658,6 +911,15 @@
658
911
  "PermissionState"
659
912
  ],
660
913
  "type": "PermissionState"
914
+ },
915
+ {
916
+ "name": "bluetooth",
917
+ "tags": [],
918
+ "docs": "Bluetooth, needed only for BLE collection (off unless server-enabled).\nAndroid: `BLUETOOTH_SCAN` (API 31+). iOS: `NSBluetoothAlwaysUsageDescription`.\nOpt-in: NOT requested by a no-argument `requestPermissions()` — pass it\nexplicitly (`requestPermissions({ permissions: ['bluetooth'] })`).",
919
+ "complexTypes": [
920
+ "PermissionState"
921
+ ],
922
+ "type": "PermissionState"
661
923
  }
662
924
  ]
663
925
  },
@@ -671,7 +933,7 @@
671
933
  {
672
934
  "name": "permissions",
673
935
  "tags": [],
674
- "docs": "If omitted, requests all permissions.",
936
+ "docs": "Which permissions to request. If omitted, requests the default set\n(location + activity) — Bluetooth is opt-in and must be listed explicitly.",
675
937
  "complexTypes": [
676
938
  "DoorstepPermissionType"
677
939
  ],
@@ -697,6 +959,21 @@
697
959
  }
698
960
  ]
699
961
  },
962
+ {
963
+ "name": "GeofenceSessionEventType",
964
+ "slug": "geofencesessioneventtype",
965
+ "docs": "",
966
+ "types": [
967
+ {
968
+ "text": "'STARTED'",
969
+ "complexTypes": []
970
+ },
971
+ {
972
+ "text": "'STOPPED'",
973
+ "complexTypes": []
974
+ }
975
+ ]
976
+ },
700
977
  {
701
978
  "name": "PermissionState",
702
979
  "slug": "permissionstate",
@@ -732,6 +1009,10 @@
732
1009
  {
733
1010
  "text": "'activity'",
734
1011
  "complexTypes": []
1012
+ },
1013
+ {
1014
+ "text": "'bluetooth'",
1015
+ "complexTypes": []
735
1016
  }
736
1017
  ]
737
1018
  }
@@ -1,3 +1,4 @@
1
+ import type { PluginListenerHandle } from '@capacitor/core';
1
2
  /**
2
3
  * Structured address used by {@link DoorstepAIDropoffSDKPlugin.startDeliveryByAddress}.
3
4
  * Field names mirror the Google Places address-component types.
@@ -16,11 +17,36 @@ export interface LatLngObject {
16
17
  lat: number;
17
18
  lng: number;
18
19
  }
20
+ /** A stop monitored for route geofencing. Mirrors the native `DeliveryStop`. */
21
+ export interface DeliveryStop {
22
+ deliveryId: string;
23
+ address: string;
24
+ latitude: number;
25
+ longitude: number;
26
+ radiusMeters?: number;
27
+ customerId?: string;
28
+ driverId?: string;
29
+ }
30
+ /** Options for {@link DoorstepAIDropoffSDKPlugin.startRouteGeofencing}. */
31
+ export interface RouteGeofenceOptions {
32
+ defaultRadiusMeters?: number;
33
+ timeoutSeconds?: number;
34
+ autoStopAfterDropoffSeconds?: number;
35
+ /** Android only; ignored on iOS (the OS owns background region monitoring). */
36
+ manualForeground?: boolean;
37
+ }
38
+ export type GeofenceSessionEventType = 'STARTED' | 'STOPPED';
39
+ /** Payload delivered to the `'geofenceSessionEvent'` listener. */
40
+ export interface GeofenceSessionEvent {
41
+ deliveryId: string;
42
+ type: GeofenceSessionEventType;
43
+ reason: string;
44
+ }
19
45
  /**
20
46
  * Type of dropoff for {@link DoorstepAIDropoffSDKPlugin.markDropoff}.
21
47
  * Maps to the native SDK's `"pod"` / `"non_pod"` strings.
22
48
  */
23
- export declare type DropoffType = 'pod' | 'non_pod';
49
+ export type DropoffType = 'pod' | 'non_pod';
24
50
  export interface InitOptions {
25
51
  /** Android only: title shown in the foreground-service notification. */
26
52
  notificationTitle?: string;
@@ -34,13 +60,13 @@ export interface SetApiKeyOptions {
34
60
  * Optional caller-supplied identifier for the customer associated with the
35
61
  * delivery. Forwarded verbatim to the native SDK. Optional on every platform.
36
62
  */
37
- declare type CustomerIdOption = {
63
+ type CustomerIdOption = {
38
64
  customerId?: string;
39
65
  };
40
66
  /**
41
67
  * Android-only option shared by every `startDelivery*` method.
42
68
  */
43
- declare type ManualForegroundOption = {
69
+ type ManualForegroundOption = {
44
70
  /**
45
71
  * Android only: when `true`, the host app is responsible for its own
46
72
  * foreground service/notification and the SDK will not start a second one.
@@ -112,12 +138,14 @@ export interface MarkDropoffOptions {
112
138
  export interface NewEventOptions {
113
139
  eventName: string;
114
140
  deliveryId: string;
141
+ /** Epoch seconds; if omitted the SDK stamps the current time. */
142
+ timestamp?: number;
115
143
  }
116
144
  export interface StopDeliveryOptions {
117
145
  deliveryId: string;
118
146
  }
119
- export declare type PermissionState = 'granted' | 'denied' | 'prompt' | 'prompt-with-rationale';
120
- export declare type DoorstepPermissionType = 'location' | 'activity';
147
+ export type PermissionState = 'granted' | 'denied' | 'prompt' | 'prompt-with-rationale';
148
+ export type DoorstepPermissionType = 'location' | 'activity' | 'bluetooth';
121
149
  export interface PermissionStatus {
122
150
  /** Foreground location (when-in-use). Both platforms. */
123
151
  location: PermissionState;
@@ -126,9 +154,19 @@ export interface PermissionStatus {
126
154
  * Android: `ACTIVITY_RECOGNITION`. iOS: `NSMotionUsageDescription`.
127
155
  */
128
156
  activity: PermissionState;
157
+ /**
158
+ * Bluetooth, needed only for BLE collection (off unless server-enabled).
159
+ * Android: `BLUETOOTH_SCAN` (API 31+). iOS: `NSBluetoothAlwaysUsageDescription`.
160
+ * Opt-in: NOT requested by a no-argument `requestPermissions()` — pass it
161
+ * explicitly (`requestPermissions({ permissions: ['bluetooth'] })`).
162
+ */
163
+ bluetooth: PermissionState;
129
164
  }
130
165
  export interface PermissionRequestOptions {
131
- /** If omitted, requests all permissions. */
166
+ /**
167
+ * Which permissions to request. If omitted, requests the default set
168
+ * (location + activity) — Bluetooth is opt-in and must be listed explicitly.
169
+ */
132
170
  permissions?: DoorstepPermissionType[];
133
171
  }
134
172
  export interface DoorstepAIDropoffSDKPlugin {
@@ -150,6 +188,31 @@ export interface DoorstepAIDropoffSDKPlugin {
150
188
  markDropoff(options: MarkDropoffOptions): Promise<void>;
151
189
  newEvent(options: NewEventOptions): Promise<void>;
152
190
  stopDelivery(options: StopDeliveryOptions): Promise<void>;
191
+ /**
192
+ * Start route geofencing. ENTER auto-starts a session; EXIT stops it only if a
193
+ * dropoff was marked (else the per-session timeout backstops it). Subscribe to
194
+ * session lifecycle via `addListener('geofenceSessionEvent', ...)`.
195
+ */
196
+ startRouteGeofencing(options: {
197
+ stops: DeliveryStop[];
198
+ options?: RouteGeofenceOptions;
199
+ }): Promise<void>;
200
+ /** Replace the monitored stops in place without tearing down still-present stops. */
201
+ updateRouteStops(options: {
202
+ stops: DeliveryStop[];
203
+ }): Promise<void>;
204
+ /** Stop route geofencing and clear all monitored stops. */
205
+ stopRouteGeofencing(): Promise<void>;
206
+ /** Re-arm route geofencing after a process relaunch if a route was active. */
207
+ resumeRouteGeofencingIfNeeded(): Promise<void>;
208
+ /** The stops currently registered for route geofencing (empty if none). */
209
+ getMonitoredStops(): Promise<{
210
+ stops: DeliveryStop[];
211
+ }>;
212
+ /** Subscribe to route-geofence session STARTED/STOPPED events. */
213
+ addListener(eventName: 'geofenceSessionEvent', listenerFunc: (event: GeofenceSessionEvent) => void): Promise<PluginListenerHandle>;
214
+ /** Remove all listeners registered for this plugin. */
215
+ removeAllListeners(): Promise<void>;
153
216
  /** Returns the current grant state for each permission the SDK uses. */
154
217
  checkPermissions(): Promise<PermissionStatus>;
155
218
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAI5D,MAAM,MAAM,GAAG,cAAc,CAC3B,sBAAsB,EACtB;IACE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,uBAAuB,EAAE,CAAC;CACtE,CACF,CAAC;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,sCAAsC;AACtC,MAAM,oBAAoB,GAA+B,IAAI,KAAK,CAAC,MAAM,EAAE;IACzE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;QACxB,IAAI,IAAI,KAAK,MAAM,EAAE;YACnB,OAAO,CAAC,OAAqB,EAAiB,EAAE;gBAC9C,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE;oBACzC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;iBAC1B;gBACD,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC,CAAC;SACH;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAI5D,MAAM,MAAM,GAAG,cAAc,CAC3B,sBAAsB,EACtB;IACE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,uBAAuB,EAAE,CAAC;CACtE,CACF,CAAC;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,sCAAsC;AACtC,MAAM,oBAAoB,GAA+B,IAAI,KAAK,CAAC,MAAM,EAAE;IACzE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;QACxB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,OAAqB,EAAiB,EAAE;gBAC9C,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE,CAAC;oBAC1C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC3B,CAAC;gBACD,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
package/dist/esm/web.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
- import type { DoorstepAIDropoffSDKPlugin, InitOptions, MarkDropoffOptions, NewEventOptions, PermissionRequestOptions, PermissionStatus, SetApiKeyOptions, StartDeliveryByAddressOptions, StartDeliveryByAddressStringOptions, StartDeliveryByLatLngOptions, StartDeliveryByPlaceIDOptions, StartDeliveryByPlusCodeOptions, StopDeliveryOptions } from './definitions';
2
+ import type { DoorstepAIDropoffSDKPlugin, InitOptions, MarkDropoffOptions, NewEventOptions, PermissionRequestOptions, PermissionStatus, SetApiKeyOptions, StartDeliveryByAddressOptions, StartDeliveryByAddressStringOptions, StartDeliveryByLatLngOptions, StartDeliveryByPlaceIDOptions, StartDeliveryByPlusCodeOptions, StopDeliveryOptions, DeliveryStop, RouteGeofenceOptions } from './definitions';
3
3
  /**
4
4
  * Web stub. The Dropoff SDK is native-only — every call rejects with
5
5
  * `UNIMPLEMENTED` so failures surface immediately on the web platform
@@ -18,6 +18,18 @@ export declare class DoorstepAIDropoffSDKWeb extends WebPlugin implements Doorst
18
18
  markDropoff(_options: MarkDropoffOptions): Promise<void>;
19
19
  newEvent(_options: NewEventOptions): Promise<void>;
20
20
  stopDelivery(_options: StopDeliveryOptions): Promise<void>;
21
+ startRouteGeofencing(_options: {
22
+ stops: DeliveryStop[];
23
+ options?: RouteGeofenceOptions;
24
+ }): Promise<void>;
25
+ updateRouteStops(_options: {
26
+ stops: DeliveryStop[];
27
+ }): Promise<void>;
28
+ stopRouteGeofencing(): Promise<void>;
29
+ resumeRouteGeofencingIfNeeded(): Promise<void>;
30
+ getMonitoredStops(): Promise<{
31
+ stops: DeliveryStop[];
32
+ }>;
21
33
  checkPermissions(): Promise<PermissionStatus>;
22
34
  requestPermissions(_options?: PermissionRequestOptions): Promise<PermissionStatus>;
23
35
  }