react-native-geofence-manager 0.1.0-beta.11 → 0.1.0-beta.13

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 (52) hide show
  1. package/README.md +173 -37
  2. package/android/src/main/AndroidManifest.xml +17 -16
  3. package/android/src/main/java/com/geofencemanager/GeofenceBroadcastReceiver.kt +133 -0
  4. package/android/src/main/java/com/geofencemanager/GeofenceHeadlessTaskService.kt +98 -141
  5. package/android/src/main/java/com/geofencemanager/GeofenceManagerModule.kt +187 -154
  6. package/ios/GeofenceManager.mm +21 -21
  7. package/lib/module/NativeGeofenceManager.js +1 -7
  8. package/lib/module/NativeGeofenceManager.js.map +1 -1
  9. package/lib/module/geofenceDebugLog.js +22 -0
  10. package/lib/module/geofenceDebugLog.js.map +1 -0
  11. package/lib/module/index.js +79 -35
  12. package/lib/module/index.js.map +1 -1
  13. package/lib/module/models/GeofenceEvent.js +4 -0
  14. package/lib/module/models/GeofenceEvent.js.map +1 -0
  15. package/lib/module/models/GeofenceEventType.js +2 -0
  16. package/lib/module/models/GeofenceEventType.js.map +1 -0
  17. package/lib/module/models/GeofenceModel.js +2 -0
  18. package/lib/module/models/GeofenceModel.js.map +1 -0
  19. package/lib/module/models/index.js +6 -0
  20. package/lib/module/models/index.js.map +1 -0
  21. package/lib/module/package.json +1 -0
  22. package/lib/typescript/package.json +1 -0
  23. package/lib/typescript/src/NativeGeofenceManager.d.ts +3 -16
  24. package/lib/typescript/src/NativeGeofenceManager.d.ts.map +1 -1
  25. package/lib/typescript/src/geofenceDebugLog.d.ts +3 -0
  26. package/lib/typescript/src/geofenceDebugLog.d.ts.map +1 -0
  27. package/lib/typescript/src/index.d.ts +27 -26
  28. package/lib/typescript/src/index.d.ts.map +1 -1
  29. package/lib/typescript/src/models/GeofenceEvent.d.ts +11 -0
  30. package/lib/typescript/src/models/GeofenceEvent.d.ts.map +1 -0
  31. package/lib/typescript/src/models/GeofenceEventType.d.ts +2 -0
  32. package/lib/typescript/src/models/GeofenceEventType.d.ts.map +1 -0
  33. package/lib/typescript/src/models/GeofenceModel.d.ts +8 -0
  34. package/lib/typescript/src/models/GeofenceModel.d.ts.map +1 -0
  35. package/lib/typescript/src/models/index.d.ts +4 -0
  36. package/lib/typescript/src/models/index.d.ts.map +1 -0
  37. package/package.json +16 -15
  38. package/src/NativeGeofenceManager.ts +4 -29
  39. package/src/geofenceDebugLog.ts +28 -0
  40. package/src/index.tsx +99 -71
  41. package/src/models/GeofenceEvent.ts +11 -0
  42. package/src/models/GeofenceEventType.ts +1 -0
  43. package/src/models/GeofenceModel.ts +7 -0
  44. package/src/models/index.ts +3 -0
  45. package/android/src/main/java/com/geofencemanager/GeofenceReceiver.kt +0 -192
  46. package/android/src/main/java/com/geofencemanager/RegionManager.kt +0 -387
  47. package/lib/commonjs/NativeGeofenceManager.js +0 -15
  48. package/lib/commonjs/NativeGeofenceManager.js.map +0 -1
  49. package/lib/commonjs/index.js +0 -47
  50. package/lib/commonjs/index.js.map +0 -1
  51. package/lib/commonjs/package.json +0 -1
  52. package/react-native.config.js +0 -11
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=GeofenceModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["models/GeofenceModel.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ export * from "./GeofenceEventType.js";
4
+ export * from "./GeofenceModel.js";
5
+ export * from "./GeofenceEvent.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["models/index.ts"],"mappings":";;AAAA,cAAc,wBAAqB;AACnC,cAAc,oBAAiB;AAC/B,cAAc,oBAAiB","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -1,21 +1,8 @@
1
1
  import { type TurboModule } from 'react-native';
2
- export type Region = {
3
- id: string;
4
- name: string;
5
- data: string;
6
- latitude: number;
7
- longitude: number;
8
- radius?: number;
9
- };
10
- export type GeofenceOptions = {
11
- dwellDelay?: number;
12
- headlessTaskTimeout?: number;
13
- };
2
+ import type { GeofenceModel } from './models/index';
14
3
  export interface Spec extends TurboModule {
15
- start(regions: Region[], options?: GeofenceOptions): Promise<void>;
16
- stop(): Promise<void>;
17
- isActive(): Promise<boolean>;
18
- getActiveRegions(): Promise<Region[]>;
4
+ addGeofences(geofences: ReadonlyArray<GeofenceModel>): Promise<boolean>;
5
+ removeAllGeofences(): Promise<boolean>;
19
6
  }
20
7
  declare const _default: Spec;
21
8
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"NativeGeofenceManager.d.ts","sourceRoot":"","sources":["../../../src/NativeGeofenceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,MAAM,MAAM,GAAG;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACvC;wBAY8B,IAAI;AAAnC,wBAAoC"}
1
+ {"version":3,"file":"NativeGeofenceManager.d.ts","sourceRoot":"","sources":["../../../src/NativeGeofenceManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;;AAED,wBAAyE"}
@@ -0,0 +1,3 @@
1
+ export declare function geofenceDebugLog(step: string, data?: unknown): void;
2
+ export declare function geofenceDebugWarn(step: string, data?: unknown): void;
3
+ //# sourceMappingURL=geofenceDebugLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geofenceDebugLog.d.ts","sourceRoot":"","sources":["../../../src/geofenceDebugLog.ts"],"names":[],"mappings":"AAaA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAMnE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAMpE"}
@@ -1,27 +1,28 @@
1
- import { type Region, type GeofenceOptions } from './NativeGeofenceManager';
2
- export type GeofenceEventRegion = {
3
- id: string;
4
- name: string;
5
- data: string;
6
- latitude: number;
7
- longitude: number;
8
- radius: number;
9
- };
10
- export type GeofenceEvent = {
11
- event: 'onEnter' | 'onExit' | 'onDwell';
12
- region: GeofenceEventRegion;
13
- timestamp: number;
14
- };
15
- export type GeofenceBackgroundHandler = (event: GeofenceEvent) => Promise<void>;
16
- export declare const GeofenceManager: {
17
- start: (regions: Region[], options?: GeofenceOptions) => Promise<void>;
18
- stop: () => Promise<void>;
19
- onEnter: (cb: (region: GeofenceEventRegion) => void) => import("react-native").EventSubscription;
20
- onExit: (cb: (region: GeofenceEventRegion) => void) => import("react-native").EventSubscription;
21
- onDwell: (cb: (region: GeofenceEventRegion) => void) => import("react-native").EventSubscription;
22
- registerBackgroundHandler: (handler: GeofenceBackgroundHandler) => void;
23
- isActive: () => Promise<boolean>;
24
- getActiveRegions: () => Promise<Region[]>;
25
- };
26
- export type { Region, GeofenceOptions } from './NativeGeofenceManager';
1
+ import type { GeofenceEvent, GeofenceModel } from './models/index';
2
+ export type { GeofenceEventType, GeofenceEvent, GeofenceModel, } from './models/index';
3
+ /** Nome da headless task para eventos de geofence (app morto/background). Deve ser usado com registerGeofenceHeadlessTask no index do app. */
4
+ export declare const GEOFENCE_HEADLESS_TASK_NAME = "GeofenceManagerTransition";
5
+ export declare function addGeofenceEventListener(callback: (event: GeofenceEvent) => void): () => void;
6
+ export declare function onGeofenceEvent(callback: (event: GeofenceEvent) => void): () => void;
7
+ /**
8
+ * Registra o handler da headless task para quando o app é acordado por um evento de geofence
9
+ * (app morto ou em background). Deve ser chamado no index do app, antes de AppRegistry.registerComponent.
10
+ *
11
+ * @example
12
+ * // index.js
13
+ * import { AppRegistry } from 'react-native';
14
+ * import { registerGeofenceHeadlessTask } from 'react-native-geofence-manager';
15
+ * import App from './App';
16
+ * import { name as appName } from './app.json';
17
+ *
18
+ * registerGeofenceHeadlessTask((event) => {
19
+ * console.log('Geofence (headless):', event.geofenceId, event.event);
20
+ * });
21
+ *
22
+ * AppRegistry.registerComponent(appName, () => App);
23
+ */
24
+ export declare function registerGeofenceHeadlessTask(callback: (event: GeofenceEvent) => void): void;
25
+ declare const addGeofences: (geofences: GeofenceModel[]) => Promise<boolean>;
26
+ declare const removeAllGeofences: () => Promise<boolean>;
27
+ export { addGeofences, removeAllGeofences };
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAuB,EACrB,KAAK,MAAM,EACX,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAOjC,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAShF,eAAO,MAAM,eAAe;qBACT,MAAM,EAAE,YAAY,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC;gBAc1D,OAAO,CAAC,IAAI,CAAC;kBAOT,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI;iBAGtC,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI;kBAGpC,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI;yCAGd,yBAAyB,KAAG,IAAI;oBAOvD,OAAO,CAAC,OAAO,CAAC;4BAKR,OAAO,CAAC,MAAM,EAAE,CAAC;CAIxC,CAAC;AAEF,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEnE,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,gBAAgB,CAAC;AAIxB,8IAA8I;AAC9I,eAAO,MAAM,2BAA2B,8BAA8B,CAAC;AAEvE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAeZ;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,MAAM,IAAI,CAEZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GACvC,IAAI,CAWN;AAED,QAAA,MAAM,YAAY,GAChB,WAAW,aAAa,EAAE,KACzB,OAAO,CAAC,OAAO,CAkBjB,CAAC;AAEF,QAAA,MAAM,kBAAkB,QAAa,OAAO,CAAC,OAAO,CAUnD,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { GeofenceEventType } from './GeofenceEventType';
2
+ export type GeofenceEvent = {
3
+ geofenceId: string;
4
+ event: GeofenceEventType;
5
+ timestamp?: number;
6
+ name?: string;
7
+ latitude?: number;
8
+ longitude?: number;
9
+ radius?: number;
10
+ };
11
+ //# sourceMappingURL=GeofenceEvent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeofenceEvent.d.ts","sourceRoot":"","sources":["../../../../src/models/GeofenceEvent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type GeofenceEventType = 'enter' | 'exit' | 'dwell';
2
+ //# sourceMappingURL=GeofenceEventType.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeofenceEventType.d.ts","sourceRoot":"","sources":["../../../../src/models/GeofenceEventType.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface GeofenceModel {
2
+ id: string;
3
+ name?: string;
4
+ radius?: number;
5
+ latitude: number;
6
+ longitude: number;
7
+ }
8
+ //# sourceMappingURL=GeofenceModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeofenceModel.d.ts","sourceRoot":"","sources":["../../../../src/models/GeofenceModel.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,4 @@
1
+ export * from './GeofenceEventType';
2
+ export * from './GeofenceModel';
3
+ export * from './GeofenceEvent';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,19 +1,14 @@
1
1
  {
2
2
  "name": "react-native-geofence-manager",
3
- "version": "0.1.0-beta.11",
4
- "description": "Robust manager for your geofencing areas.",
5
- "main": "./lib/commonjs/index.js",
6
- "module": "./lib/module/index.js",
7
- "react-native": "./src/index.tsx",
8
- "source": "./src/index.tsx",
3
+ "version": "0.1.0-beta.13",
4
+ "description": "React Native library.",
5
+ "main": "./lib/module/index.js",
9
6
  "types": "./lib/typescript/src/index.d.ts",
10
7
  "exports": {
11
8
  ".": {
12
9
  "source": "./src/index.tsx",
13
10
  "types": "./lib/typescript/src/index.d.ts",
14
- "import": "./lib/module/index.js",
15
- "require": "./lib/commonjs/index.js",
16
- "default": "./lib/commonjs/index.js"
11
+ "default": "./lib/module/index.js"
17
12
  },
18
13
  "./package.json": "./package.json"
19
14
  },
@@ -43,9 +38,9 @@
43
38
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
44
39
  "test": "jest",
45
40
  "release": "release-it --only-version",
46
- "build:clean":"rm -rf lib && yarn prepare",
47
- "publish:beta":"npm publish --tag beta",
48
- "clean": "rm -rf node_modules example/node_modules lib android/build example/android/build example/android/app/build example/android/.gradle .yarn/cache && yarn cache clean && yarn install && yarn prepare"
41
+ "clean": "rm -rf node_modules example/node_modules lib android/build example/android/build example/android/app/build example/android/.gradle .yarn/cache && yarn cache clean && yarn install && yarn prepare",
42
+ "clean:caches": "del-cli lib node_modules/.cache example/node_modules/.cache example/android/app/build example/android/build example/android/.gradle example/android/app/.cxx android/build .metro --force",
43
+ "clean:build:android": "yarn clean:caches && yarn clean && yarn example android"
49
44
  },
50
45
  "keywords": [
51
46
  "react-native",
@@ -63,7 +58,8 @@
63
58
  },
64
59
  "homepage": "https://github.com/izidiodev/react-native-geofence-manager#readme",
65
60
  "publishConfig": {
66
- "registry": "https://registry.npmjs.org/"
61
+ "registry": "https://registry.npmjs.org/",
62
+ "tag": "beta"
67
63
  },
68
64
  "devDependencies": {
69
65
  "@commitlint/config-conventional": "^19.8.1",
@@ -102,8 +98,12 @@
102
98
  "source": "src",
103
99
  "output": "lib",
104
100
  "targets": [
105
- "commonjs",
106
- "module",
101
+ [
102
+ "module",
103
+ {
104
+ "esm": true
105
+ }
106
+ ],
107
107
  [
108
108
  "typescript",
109
109
  {
@@ -126,6 +126,7 @@
126
126
  ]
127
127
  },
128
128
  "prettier": {
129
+ "endOfLine": "lf",
129
130
  "quoteProps": "consistent",
130
131
  "singleQuote": true,
131
132
  "tabWidth": 2,
@@ -1,34 +1,9 @@
1
1
  import { TurboModuleRegistry, type TurboModule } from 'react-native';
2
-
3
- export type Region = {
4
- id: string;
5
- name: string;
6
- data: string;
7
- latitude: number;
8
- longitude: number;
9
- radius?: number;
10
- };
11
-
12
- export type GeofenceOptions = {
13
- dwellDelay?: number;
14
- headlessTaskTimeout?: number;
15
- };
2
+ import type { GeofenceModel } from './models/index';
16
3
 
17
4
  export interface Spec extends TurboModule {
18
- start(regions: Region[], options?: GeofenceOptions): Promise<void>;
19
- stop(): Promise<void>;
20
- isActive(): Promise<boolean>;
21
- getActiveRegions(): Promise<Region[]>;
22
- }
23
-
24
- const NativeModule = TurboModuleRegistry.get<Spec>('GeofenceManager');
25
-
26
- if (NativeModule) {
27
- console.log('✅ react-native-geofence-manager: Native module linked successfully');
28
- } else {
29
- console.warn(
30
- '❌ react-native-geofence-manager: Native module not found. Make sure you rebuilt the app after installing the package.'
31
- );
5
+ addGeofences(geofences: ReadonlyArray<GeofenceModel>): Promise<boolean>;
6
+ removeAllGeofences(): Promise<boolean>;
32
7
  }
33
8
 
34
- export default NativeModule as Spec;
9
+ export default TurboModuleRegistry.getEnforcing<Spec>('GeofenceManager');
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Logs de diagnóstico da lib. Aparecem no Metro e no Logcat (Android) com filtro "GeofenceManager".
3
+ */
4
+ const TAG = '[GeofenceManager]';
5
+
6
+ function safeStringify(data: unknown): string {
7
+ try {
8
+ return JSON.stringify(data);
9
+ } catch {
10
+ return String(data);
11
+ }
12
+ }
13
+
14
+ export function geofenceDebugLog(step: string, data?: unknown): void {
15
+ const line =
16
+ data !== undefined
17
+ ? `${TAG} ${step} ${safeStringify(data)}`
18
+ : `${TAG} ${step}`;
19
+ console.log(line);
20
+ }
21
+
22
+ export function geofenceDebugWarn(step: string, data?: unknown): void {
23
+ const line =
24
+ data !== undefined
25
+ ? `${TAG} ${step} ${safeStringify(data)}`
26
+ : `${TAG} ${step}`;
27
+ console.warn(line);
28
+ }
package/src/index.tsx CHANGED
@@ -1,84 +1,112 @@
1
- import NativeGeofence, {
2
- type Region,
3
- type GeofenceOptions,
4
- } from './NativeGeofenceManager';
5
- import { AppRegistry, NativeEventEmitter, Platform } from 'react-native';
1
+ import {
2
+ AppRegistry,
3
+ DeviceEventEmitter,
4
+ type EventSubscription,
5
+ } from 'react-native';
6
+ import NativeGeofenceManager from './NativeGeofenceManager';
7
+ import { geofenceDebugLog, geofenceDebugWarn } from './geofenceDebugLog';
8
+ import type { GeofenceEvent, GeofenceModel } from './models/index';
6
9
 
7
- const emitter = new NativeEventEmitter();
10
+ export type {
11
+ GeofenceEventType,
12
+ GeofenceEvent,
13
+ GeofenceModel,
14
+ } from './models/index';
8
15
 
9
- const MAX_REGIONS = 100;
16
+ const EVENT_NAME = 'onGeofenceTransition';
10
17
 
11
- export type GeofenceEventRegion = {
12
- id: string;
13
- name: string;
14
- data: string;
15
- latitude: number;
16
- longitude: number;
17
- radius: number;
18
- };
18
+ /** Nome da headless task para eventos de geofence (app morto/background). Deve ser usado com registerGeofenceHeadlessTask no index do app. */
19
+ export const GEOFENCE_HEADLESS_TASK_NAME = 'GeofenceManagerTransition';
19
20
 
20
- export type GeofenceEvent = {
21
- event: 'onEnter' | 'onExit' | 'onDwell';
22
- region: GeofenceEventRegion;
23
- timestamp: number;
24
- };
21
+ export function addGeofenceEventListener(
22
+ callback: (event: GeofenceEvent) => void
23
+ ): () => void {
24
+ geofenceDebugLog('JS: addGeofenceEventListener — registering listener', {
25
+ eventName: EVENT_NAME,
26
+ });
27
+ const subscription: EventSubscription = DeviceEventEmitter.addListener(
28
+ EVENT_NAME,
29
+ (payload: unknown) => {
30
+ geofenceDebugLog('JS: addGeofenceEventListener — event received', payload);
31
+ callback(payload as GeofenceEvent);
32
+ }
33
+ );
34
+ return () => {
35
+ geofenceDebugLog('JS: addGeofenceEventListener — unsubscribed');
36
+ subscription.remove();
37
+ };
38
+ }
25
39
 
26
- export type GeofenceBackgroundHandler = (event: GeofenceEvent) => Promise<void>;
40
+ export function onGeofenceEvent(
41
+ callback: (event: GeofenceEvent) => void
42
+ ): () => void {
43
+ return addGeofenceEventListener(callback);
44
+ }
27
45
 
28
- const notLinkedError = () =>
29
- Promise.reject(
30
- new Error(
31
- '❌ react-native-geofence-manager: Native module not linked. Rebuild your app.'
32
- )
46
+ /**
47
+ * Registra o handler da headless task para quando o app é acordado por um evento de geofence
48
+ * (app morto ou em background). Deve ser chamado no index do app, antes de AppRegistry.registerComponent.
49
+ *
50
+ * @example
51
+ * // index.js
52
+ * import { AppRegistry } from 'react-native';
53
+ * import { registerGeofenceHeadlessTask } from 'react-native-geofence-manager';
54
+ * import App from './App';
55
+ * import { name as appName } from './app.json';
56
+ *
57
+ * registerGeofenceHeadlessTask((event) => {
58
+ * console.log('Geofence (headless):', event.geofenceId, event.event);
59
+ * });
60
+ *
61
+ * AppRegistry.registerComponent(appName, () => App);
62
+ */
63
+ export function registerGeofenceHeadlessTask(
64
+ callback: (event: GeofenceEvent) => void
65
+ ): void {
66
+ geofenceDebugLog('JS: registerGeofenceHeadlessTask — registering', {
67
+ taskName: GEOFENCE_HEADLESS_TASK_NAME,
68
+ });
69
+ AppRegistry.registerHeadlessTask(
70
+ GEOFENCE_HEADLESS_TASK_NAME,
71
+ () => (data: unknown) => {
72
+ geofenceDebugLog('JS: headless task invoked', data);
73
+ return Promise.resolve(callback(data as GeofenceEvent));
74
+ }
33
75
  );
76
+ }
34
77
 
35
- export const GeofenceManager = {
36
- start: (regions: Region[], options?: GeofenceOptions): Promise<void> => {
37
- if (!NativeGeofence) return notLinkedError();
38
- if (regions.length > MAX_REGIONS) {
39
- return Promise.reject(
40
- new Error(
41
- `Limite máximo de ${MAX_REGIONS} regiões excedido. Recebido: ${regions.length}`
42
- )
78
+ const addGeofences = async (
79
+ geofences: GeofenceModel[]
80
+ ): Promise<boolean> => {
81
+ geofenceDebugLog('JS: addGeofences calling native', {
82
+ count: geofences.length,
83
+ ids: geofences.map((g) => g.id),
84
+ });
85
+ try {
86
+ const ok = await NativeGeofenceManager.addGeofences(geofences);
87
+ geofenceDebugLog('JS: addGeofences — native result', { success: ok });
88
+ if (!ok) {
89
+ geofenceDebugWarn(
90
+ 'JS: addGeofences — native returned false (empty list, Geofencing API failure, or permissions)'
43
91
  );
44
92
  }
45
- return NativeGeofence.start(regions, options ?? {}).then(() => {
46
- console.log('✅ react-native-geofence-manager: Geofencing started successfully');
47
- });
48
- },
49
-
50
- stop: (): Promise<void> => {
51
- if (!NativeGeofence) return notLinkedError();
52
- return NativeGeofence.stop().then(() => {
53
- console.log('🛑 react-native-geofence-manager: Geofencing stopped');
54
- });
55
- },
56
-
57
- onEnter: (cb: (region: GeofenceEventRegion) => void) =>
58
- emitter.addListener('onEnter', cb as any),
59
-
60
- onExit: (cb: (region: GeofenceEventRegion) => void) =>
61
- emitter.addListener('onExit', cb as any),
62
-
63
- onDwell: (cb: (region: GeofenceEventRegion) => void) =>
64
- emitter.addListener('onDwell', cb as any),
65
-
66
- registerBackgroundHandler: (handler: GeofenceBackgroundHandler): void => {
67
- if (Platform.OS !== 'android') {
68
- return;
69
- }
70
- AppRegistry.registerHeadlessTask('GeofenceHeadlessTask', () => handler);
71
- },
72
-
73
- isActive: (): Promise<boolean> => {
74
- if (!NativeGeofence) return Promise.resolve(false);
75
- return NativeGeofence.isActive();
76
- },
93
+ return ok;
94
+ } catch (e) {
95
+ geofenceDebugWarn('JS: addGeofences — threw (TurboModule missing or bridge error)', e);
96
+ throw e;
97
+ }
98
+ };
77
99
 
78
- getActiveRegions: (): Promise<Region[]> => {
79
- if (!NativeGeofence) return Promise.resolve([]);
80
- return NativeGeofence.getActiveRegions();
81
- },
100
+ const removeAllGeofences = async (): Promise<boolean> => {
101
+ geofenceDebugLog('JS: removeAllGeofences — calling native');
102
+ try {
103
+ const ok = await NativeGeofenceManager.removeAllGeofences();
104
+ geofenceDebugLog('JS: removeAllGeofences — native result', { success: ok });
105
+ return ok;
106
+ } catch (e) {
107
+ geofenceDebugWarn('JS: removeAllGeofences — threw', e);
108
+ throw e;
109
+ }
82
110
  };
83
111
 
84
- export type { Region, GeofenceOptions } from './NativeGeofenceManager';
112
+ export { addGeofences, removeAllGeofences };
@@ -0,0 +1,11 @@
1
+ import type { GeofenceEventType } from './GeofenceEventType';
2
+
3
+ export type GeofenceEvent = {
4
+ geofenceId: string;
5
+ event: GeofenceEventType;
6
+ timestamp?: number;
7
+ name?: string;
8
+ latitude?: number;
9
+ longitude?: number;
10
+ radius?: number;
11
+ };
@@ -0,0 +1 @@
1
+ export type GeofenceEventType = 'enter' | 'exit' | 'dwell';
@@ -0,0 +1,7 @@
1
+ export interface GeofenceModel {
2
+ id: string;
3
+ name?: string;
4
+ radius?: number;
5
+ latitude: number;
6
+ longitude: number;
7
+ }
@@ -0,0 +1,3 @@
1
+ export * from './GeofenceEventType';
2
+ export * from './GeofenceModel';
3
+ export * from './GeofenceEvent';