@edulib-france/expo-yawl 0.0.3 → 0.0.5

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.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ ![NPM Version](https://img.shields.io/npm/v/@edulib-france/expo-yawl)
2
+
1
3
  # @edulib-france/expo-yawl
2
4
 
3
5
  Yawl for React Native
@@ -31,6 +33,14 @@ export const yawl = new Yawl({
31
33
 
32
34
  # Usage
33
35
 
36
+ ## Initialize Yawl
37
+
38
+ Must be called before any other Yawl method.
39
+
40
+ ```ts
41
+ await yawl.init();
42
+ ```
43
+
34
44
  ## Track Events
35
45
 
36
46
  ```ts
@@ -49,6 +59,55 @@ We still need to find the best way to get the view name in React Native. For now
49
59
 
50
60
  ```ts
51
61
  yawl.trackView({
52
- page: 'page_name'
62
+ page: "page_name",
63
+ title: "page_title",
64
+ properties: {
65
+ // additional properties
66
+ },
53
67
  });
54
68
  ```
69
+
70
+ ### React Navigation
71
+
72
+ If you are using React Navigation, you can use the `yawl.setViewTracker()` to record the current screen name and params.
73
+ Based on [their documentation](https://reactnavigation.org/docs/5.x/screen-tracking/) you could :
74
+
75
+ ```ts
76
+ export default () => {
77
+ const navigationRef = useRef();
78
+ const routeNameRef = useRef();
79
+ ...
80
+ // sets the view tracker so `yawl.trackView()` can be used anywhere
81
+ yawl.setViewTracker(() => {
82
+ const currentRoute = navigationRef?.current?.getCurrentRoute()
83
+ return ({
84
+ page: currentRoute.name,
85
+ properties: currentRoute.params
86
+ })
87
+ })
88
+
89
+ return (
90
+ <NavigationContainer
91
+ ref={navigationRef}
92
+ onReady={() =>
93
+ // yawl.trackView() if the app is opened from a cold start
94
+ (routeNameRef.current = navigationRef.current.getCurrentRoute().name)
95
+ }
96
+ onStateChange={async () => {
97
+ const previousRouteName = routeNameRef.current;
98
+ const currentRouteName = navigationRef.current.getCurrentRoute().name;
99
+
100
+ if (previousRouteName !== currentRouteName) {
101
+ // The line below uses the yawl.setViewTracker() setup to get the current screen name and params
102
+ await yawl.trackView();
103
+ }
104
+
105
+ // Save the current route name for later comparison
106
+ routeNameRef.current = currentRouteName;
107
+ }}
108
+ >
109
+ {/* ... */}
110
+ </NavigationContainer>
111
+ );
112
+ };
113
+ ```
@@ -5,7 +5,17 @@ export type YawlEvent = {
5
5
  properties?: Record<string, unknown>;
6
6
  user_type?: string;
7
7
  };
8
+ /**
9
+ * YawlView is a type that represents a view tracking event.
10
+ * It contains optional properties for page, title, and additional properties.
11
+ *
12
+ * @param page - Optional path of the page being viewed. ie. "/home". Ignored if viewTracker is set.
13
+ * @param title - Optional title of the page being viewed. ie. "Home". Ignored if viewTracker is set.
14
+ * @param properties - Optional additional properties to be sent with the event. Merged with viewTracker's properties.
15
+ */
8
16
  export type YawlView = {
9
- page: string;
17
+ page?: string;
18
+ title?: string;
19
+ properties?: Record<string, unknown>;
10
20
  };
11
21
  //# sourceMappingURL=Yawl.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Yawl.types.d.ts","sourceRoot":"","sources":["../src/Yawl.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC"}
1
+ {"version":3,"file":"Yawl.types.d.ts","sourceRoot":"","sources":["../src/Yawl.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Yawl.types.js","sourceRoot":"","sources":["../src/Yawl.types.ts"],"names":[],"mappings":"","sourcesContent":["export type YawlEvent = {\n name: string;\n ean?: string;\n establishment_account_id?: string;\n properties?: Record<string, unknown>;\n user_type?: string;\n};\n\nexport type YawlView = {\n page: string;\n};\n"]}
1
+ {"version":3,"file":"Yawl.types.js","sourceRoot":"","sources":["../src/Yawl.types.ts"],"names":[],"mappings":"","sourcesContent":["export type YawlEvent = {\n name: string;\n ean?: string;\n establishment_account_id?: string;\n properties?: Record<string, unknown>;\n user_type?: string;\n};\n\n/**\n * YawlView is a type that represents a view tracking event.\n * It contains optional properties for page, title, and additional properties.\n *\n * @param page - Optional path of the page being viewed. ie. \"/home\". Ignored if viewTracker is set.\n * @param title - Optional title of the page being viewed. ie. \"Home\". Ignored if viewTracker is set.\n * @param properties - Optional additional properties to be sent with the event. Merged with viewTracker's properties.\n */\nexport type YawlView = {\n page?: string;\n title?: string;\n properties?: Record<string, unknown>;\n};\n"]}
@@ -7,12 +7,13 @@ export default class Yawl {
7
7
  private hasInternetAccess;
8
8
  private queue;
9
9
  private api;
10
+ private baseUrl;
11
+ private viewTracker?;
10
12
  constructor({ apiKey, env }: {
11
13
  apiKey: string;
12
14
  env?: Env;
13
15
  });
14
16
  init: () => Promise<void>;
15
- setVisitId: (visitId: string) => Promise<void>;
16
17
  track: (event: YawlEvent) => {
17
18
  event: {
18
19
  name: string;
@@ -26,18 +27,32 @@ export default class Yawl {
26
27
  timestamp: number;
27
28
  };
28
29
  };
29
- trackView: (view: YawlView) => {
30
+ /**
31
+ * Track a view event.
32
+ * `viewTracker` object takes precedence over the `view` parameter.
33
+ * Properties from both `view` and `viewTracker` are merged.
34
+ * If `viewTracker` is not provided, the `view` parameter must contain a page.
35
+ *
36
+ * @param view - Optional view object containing page, title, and properties. Must be set if viewTracker is not provided, otherwise the event will not be sent.
37
+ * @returns the event object with the tracking data.
38
+ */
39
+ trackView: (view?: YawlView) => {
30
40
  event: {
31
- name: string;
32
- url: string;
33
- title: string;
34
- page: string;
41
+ properties: {
42
+ [x: string]: unknown;
43
+ };
35
44
  id: string;
36
45
  visit_token: string;
37
46
  visitor_token: string;
38
47
  timestamp: number;
48
+ page?: string;
49
+ title?: string;
50
+ name: string;
51
+ url: string;
39
52
  };
40
- };
53
+ } | undefined;
54
+ setVisitId: (visitId: string) => Promise<void>;
55
+ setViewTracker: (viewTracker: () => YawlView) => () => YawlView;
41
56
  private loadVisitorId;
42
57
  private getVisitData;
43
58
  private initConnection;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,GAAG,EAAoB,MAAM,OAAO,CAAC;AA6B9C,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,GAAG,CAAU;gBAET,EAAE,MAAM,EAAE,GAAY,EAAE,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE;IAMnE,IAAI,sBAMF;IAEF,UAAU,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAMjD;IAEF,KAAK,GAAI,OAAO,SAAS;;;;;;;;;;;;MAgBvB;IAEF,SAAS,GAAI,MAAM,QAAQ;;;;;;;;;;;MAezB;YAEY,aAAa;YASb,YAAY;IAU1B,OAAO,CAAC,cAAc,CAMpB;IAEF,OAAO,CAAC,SAAS,CAIf;IAEF,OAAO,CAAC,UAAU,CAAwC;IAE1D,OAAO,CAAC,SAAS,CAQf;IAEF,OAAO,CAAC,iBAAiB,CAUvB;IAEF,OAAO,CAAC,iBAAiB,CA4BvB;IAEF,OAAO,CAAC,gBAAgB,CA6BtB;CACH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,GAAG,EAAoB,MAAM,OAAO,CAAC;AA6B9C,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAC,CAAiB;gBAEzB,EAAE,MAAM,EAAE,GAAY,EAAE,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE;IAOnE,IAAI,sBAMF;IAEF,KAAK,GAAI,OAAO,SAAS;;;;;;;;;;;;MAgBvB;IAEF;;;;;;;;OAQG;IACH,SAAS,GAAI,OAAO,QAAQ;;;;;;;;;;;;;;kBAuB1B;IAEF,UAAU,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAMjD;IAEF,cAAc,GAAI,aAAa,MAAM,QAAQ,WAAR,QAAQ,CACV;YAErB,aAAa;YASb,YAAY;IAU1B,OAAO,CAAC,cAAc,CAMpB;IAEF,OAAO,CAAC,SAAS,CAIf;IAEF,OAAO,CAAC,UAAU,CAAwC;IAE1D,OAAO,CAAC,SAAS,CAQf;IAEF,OAAO,CAAC,iBAAiB,CAUvB;IAEF,OAAO,CAAC,iBAAiB,CA4BvB;IAEF,OAAO,CAAC,gBAAgB,CA6BtB;CACH"}
@@ -34,10 +34,13 @@ export default class Yawl {
34
34
  hasInternetAccess = true;
35
35
  queue;
36
36
  api;
37
+ baseUrl;
38
+ viewTracker;
37
39
  constructor({ apiKey, env = "prod" }) {
38
40
  this.api = yawlApi({ apiKey, env });
39
41
  this.visitId = generateUUID();
40
42
  this.visitorId = generateUUID();
43
+ this.baseUrl = `react-native-${apiKey}`;
41
44
  }
42
45
  init = async () => {
43
46
  await this.initConnection();
@@ -46,12 +49,6 @@ export default class Yawl {
46
49
  const data = await this.getVisitData();
47
50
  this.createJob(JOB_VISITOR, data);
48
51
  };
49
- setVisitId = async (visitId) => {
50
- this.visitId = visitId;
51
- if (this.hasInternetAccess) {
52
- this.trackVisit(await this.getVisitData());
53
- }
54
- };
55
52
  track = (event) => {
56
53
  const _event = {
57
54
  event: {
@@ -69,13 +66,28 @@ export default class Yawl {
69
66
  this.createJob(JOB_TRACKING, _event);
70
67
  return _event;
71
68
  };
69
+ /**
70
+ * Track a view event.
71
+ * `viewTracker` object takes precedence over the `view` parameter.
72
+ * Properties from both `view` and `viewTracker` are merged.
73
+ * If `viewTracker` is not provided, the `view` parameter must contain a page.
74
+ *
75
+ * @param view - Optional view object containing page, title, and properties. Must be set if viewTracker is not provided, otherwise the event will not be sent.
76
+ * @returns the event object with the tracking data.
77
+ */
72
78
  trackView = (view) => {
79
+ const trackedView = this.viewTracker?.();
80
+ if (!view?.page && !trackedView?.page) {
81
+ console.warn("Yawl: trackView() - page is required; Either set it in the view param or yawl.setViewTracker(); Event not sent");
82
+ return;
83
+ }
73
84
  const _event = {
74
85
  event: {
75
86
  name: "$view",
76
- url: view.page,
77
- title: view.page,
78
- page: view.page,
87
+ url: this.baseUrl,
88
+ ...view,
89
+ ...trackedView,
90
+ properties: { ...view?.properties, ...trackedView?.properties },
79
91
  id: generateUUID(),
80
92
  visit_token: this.visitId,
81
93
  visitor_token: this.visitorId,
@@ -85,6 +97,13 @@ export default class Yawl {
85
97
  this.createJob(JOB_TRACKING, _event);
86
98
  return _event;
87
99
  };
100
+ setVisitId = async (visitId) => {
101
+ this.visitId = visitId;
102
+ if (this.hasInternetAccess) {
103
+ this.trackVisit(await this.getVisitData());
104
+ }
105
+ };
106
+ setViewTracker = (viewTracker) => (this.viewTracker = viewTracker);
88
107
  async loadVisitorId() {
89
108
  const visitorIdKey = "yawl_visitorId";
90
109
  const visitorId = await AsyncStorage.getItem(visitorIdKey);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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","sourcesContent":["import AsyncStorage from \"@react-native-async-storage/async-storage\";\nimport { addNetworkStateListener, getNetworkStateAsync } from \"expo-network\";\nimport queueFactory from \"react-native-queue\";\n\nimport { YawlEvent, YawlView } from \"../Yawl.types\";\nimport { Env, YawlApi, yawlApi } from \"./api\";\nimport { getDeviceInfo } from \"./deviceInfo\";\nimport { generateUUID } from \"./generateUUID\";\n\n/*\n\nINPUT PARAMETERS:\n{\n visitorId: string - visitor id\n visitData: object - extra visit data to be sent to ahoy server\n onTracking: {\n started: async (event) - function that will be invoked after tracking start\n succeeded: async (event) - function that will be invoked when tracking success\n failure: async (event) - function that will be invoked when tracking failure (before failed)\n failed: async (event) - function that will be invoked if tracking fails\n error: async ({ name, error }) - function that will be invoked when error occured\n }\n offlineMode: boolean - ONLY FOR TESTING PURPOSES, indicates if you want to test with no internet\n}\n*/\n\nconst JOB_VISITOR = \"visitor\";\nconst JOB_TRACKING = \"tracking\";\ntype JOB_TYPES = typeof JOB_TRACKING | typeof JOB_VISITOR;\nconst WORKERS_OPTIONS = {\n timeout: 20000,\n attempts: 1000,\n concurrency: 1,\n};\nexport default class Yawl {\n private visitId: string;\n private visitorId: string;\n private offlineMode: boolean = false;\n private hasInternetAccess: boolean | undefined = true;\n private queue: any;\n private api: YawlApi;\n\n constructor({ apiKey, env = \"prod\" }: { apiKey: string; env?: Env }) {\n this.api = yawlApi({ apiKey, env });\n this.visitId = generateUUID();\n this.visitorId = generateUUID();\n }\n\n init = async () => {\n await this.initConnection();\n await this.initQueue();\n await this.loadVisitorId();\n const data = await this.getVisitData();\n this.createJob(JOB_VISITOR, data);\n };\n\n setVisitId = async (visitId: string): Promise<void> => {\n this.visitId = visitId;\n\n if (this.hasInternetAccess) {\n this.trackVisit(await this.getVisitData());\n }\n };\n\n track = (event: YawlEvent) => {\n const _event = {\n event: {\n id: generateUUID(),\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n timestamp: new Date().getTime() / 1000.0,\n ...event,\n // properties: this.prepareProperties(event.properties),\n },\n };\n // Send event to all services before ahoy queue\n // await this.onTrackingInvoke(\"started\", event);\n // Create ahoy job and add to queue\n this.createJob(JOB_TRACKING, _event);\n return _event;\n };\n\n trackView = (view: YawlView) => {\n const _event = {\n event: {\n name: \"$view\",\n url: view.page,\n title: view.page,\n page: view.page,\n id: generateUUID(),\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n timestamp: new Date().getTime() / 1000.0,\n },\n };\n this.createJob(JOB_TRACKING, _event);\n return _event;\n };\n\n private async loadVisitorId(): Promise<void> {\n const visitorIdKey = \"yawl_visitorId\";\n const visitorId = await AsyncStorage.getItem(visitorIdKey);\n if (!visitorId)\n return await AsyncStorage.setItem(visitorIdKey, this.visitorId);\n\n this.visitorId = visitorId;\n }\n\n private async getVisitData(): Promise<object> {\n return {\n visit: {\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n ...getDeviceInfo(),\n },\n };\n }\n\n private initConnection = async () => {\n const state = await getNetworkStateAsync();\n this.hasInternetAccess = state.isConnected;\n addNetworkStateListener(\n (state) => (this.hasInternetAccess = state.isConnected)\n );\n };\n\n private initQueue = async () => {\n this.queue = await queueFactory(true);\n this.addTrackingWorker();\n this.addVisitorWorker();\n };\n\n private trackVisit = (event) => this.api.sendVisit(event);\n\n private createJob = (name: JOB_TYPES, event: object) => {\n if (this.offlineMode) {\n this.hasInternetAccess = false;\n }\n\n if (this.queue) {\n this.queue.createJob(name, event);\n }\n };\n\n private prepareProperties = (inter: object) => {\n const properties = {\n // applicationBundleId: this.applicationBundleId,\n };\n Object.keys(inter).map((name, key) => {\n const k = name.replace(/[^a-z0-9_]/gi, \"\");\n const val = inter[name];\n properties[k] = typeof val === \"boolean\" ? val.toString() : val;\n });\n return properties;\n };\n\n private addTrackingWorker = () => {\n this.queue.addWorker(\n JOB_TRACKING,\n async (id, event) => {\n if (this.hasInternetAccess) {\n const res = await this.api.sendEvent(event);\n // TODO: parse response\n console.debug(\"🚀 ===> ~ res:\", res);\n return { ok: true };\n }\n throw new Error(\"Network request failed\");\n },\n {\n onSuccess: async (id, event) => {\n console.debug(\"🚀 ===> JOB_TRACKING onSuccess\", id, event);\n // await this.onTrackingInvoke(\"succeeded\", event);\n },\n onFailure: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_TRACKING onFailure\", id, event, error);\n // await this.onTrackingInvoke(\"failure\", event, error);\n },\n onFailed: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_TRACKING onFailed\", id, event, error);\n // await this.onTrackingInvoke(\"failed\", event, error);\n },\n ...WORKERS_OPTIONS,\n }\n );\n };\n\n private addVisitorWorker = () => {\n this.queue.addWorker(\n JOB_VISITOR,\n async (id, event) => {\n if (this.hasInternetAccess) {\n const res = await this.trackVisit(event);\n // TODO: parse response\n console.debug(\"🚀 ===> ~ res:\", res);\n return { ok: true };\n }\n\n throw new Error(\"Network request failed\");\n },\n {\n onSuccess: async (id, event) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onSuccess: ~ event:\", id, event);\n // await this.onTrackingInvoke(\"succeeded\", event);\n },\n onFailure: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onFailure: ~ error:\", id, error);\n // await this.onTrackingInvoke(\"failure\", event, error);\n },\n onFailed: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onFailed: ~ error:\", id, error);\n // await this.onTrackingInvoke(\"failed\", event, error);\n },\n ...WORKERS_OPTIONS,\n }\n );\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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","sourcesContent":["import AsyncStorage from \"@react-native-async-storage/async-storage\";\nimport { addNetworkStateListener, getNetworkStateAsync } from \"expo-network\";\nimport queueFactory from \"react-native-queue\";\n\nimport { YawlEvent, YawlView } from \"../Yawl.types\";\nimport { Env, YawlApi, yawlApi } from \"./api\";\nimport { getDeviceInfo } from \"./deviceInfo\";\nimport { generateUUID } from \"./generateUUID\";\n\n/*\n\nINPUT PARAMETERS:\n{\n visitorId: string - visitor id\n visitData: object - extra visit data to be sent to ahoy server\n onTracking: {\n started: async (event) - function that will be invoked after tracking start\n succeeded: async (event) - function that will be invoked when tracking success\n failure: async (event) - function that will be invoked when tracking failure (before failed)\n failed: async (event) - function that will be invoked if tracking fails\n error: async ({ name, error }) - function that will be invoked when error occured\n }\n offlineMode: boolean - ONLY FOR TESTING PURPOSES, indicates if you want to test with no internet\n}\n*/\n\nconst JOB_VISITOR = \"visitor\";\nconst JOB_TRACKING = \"tracking\";\ntype JOB_TYPES = typeof JOB_TRACKING | typeof JOB_VISITOR;\nconst WORKERS_OPTIONS = {\n timeout: 20000,\n attempts: 1000,\n concurrency: 1,\n};\nexport default class Yawl {\n private visitId: string;\n private visitorId: string;\n private offlineMode: boolean = false;\n private hasInternetAccess: boolean | undefined = true;\n private queue: any;\n private api: YawlApi;\n private baseUrl: string;\n private viewTracker?: () => YawlView;\n\n constructor({ apiKey, env = \"prod\" }: { apiKey: string; env?: Env }) {\n this.api = yawlApi({ apiKey, env });\n this.visitId = generateUUID();\n this.visitorId = generateUUID();\n this.baseUrl = `react-native-${apiKey}`;\n }\n\n init = async () => {\n await this.initConnection();\n await this.initQueue();\n await this.loadVisitorId();\n const data = await this.getVisitData();\n this.createJob(JOB_VISITOR, data);\n };\n\n track = (event: YawlEvent) => {\n const _event = {\n event: {\n id: generateUUID(),\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n timestamp: new Date().getTime() / 1000.0,\n ...event,\n // properties: this.prepareProperties(event.properties),\n },\n };\n // Send event to all services before ahoy queue\n // await this.onTrackingInvoke(\"started\", event);\n // Create ahoy job and add to queue\n this.createJob(JOB_TRACKING, _event);\n return _event;\n };\n\n /**\n * Track a view event.\n * `viewTracker` object takes precedence over the `view` parameter.\n * Properties from both `view` and `viewTracker` are merged.\n * If `viewTracker` is not provided, the `view` parameter must contain a page.\n *\n * @param view - Optional view object containing page, title, and properties. Must be set if viewTracker is not provided, otherwise the event will not be sent.\n * @returns the event object with the tracking data.\n */\n trackView = (view?: YawlView) => {\n const trackedView = this.viewTracker?.();\n if (!view?.page && !trackedView?.page) {\n console.warn(\n \"Yawl: trackView() - page is required; Either set it in the view param or yawl.setViewTracker(); Event not sent\"\n );\n return;\n }\n const _event = {\n event: {\n name: \"$view\",\n url: this.baseUrl,\n ...view,\n ...trackedView,\n properties: { ...view?.properties, ...trackedView?.properties },\n id: generateUUID(),\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n timestamp: new Date().getTime() / 1000.0,\n },\n };\n this.createJob(JOB_TRACKING, _event);\n return _event;\n };\n\n setVisitId = async (visitId: string): Promise<void> => {\n this.visitId = visitId;\n\n if (this.hasInternetAccess) {\n this.trackVisit(await this.getVisitData());\n }\n };\n\n setViewTracker = (viewTracker: () => YawlView) =>\n (this.viewTracker = viewTracker);\n\n private async loadVisitorId(): Promise<void> {\n const visitorIdKey = \"yawl_visitorId\";\n const visitorId = await AsyncStorage.getItem(visitorIdKey);\n if (!visitorId)\n return await AsyncStorage.setItem(visitorIdKey, this.visitorId);\n\n this.visitorId = visitorId;\n }\n\n private async getVisitData(): Promise<object> {\n return {\n visit: {\n visit_token: this.visitId,\n visitor_token: this.visitorId,\n ...getDeviceInfo(),\n },\n };\n }\n\n private initConnection = async () => {\n const state = await getNetworkStateAsync();\n this.hasInternetAccess = state.isConnected;\n addNetworkStateListener(\n (state) => (this.hasInternetAccess = state.isConnected)\n );\n };\n\n private initQueue = async () => {\n this.queue = await queueFactory(true);\n this.addTrackingWorker();\n this.addVisitorWorker();\n };\n\n private trackVisit = (event) => this.api.sendVisit(event);\n\n private createJob = (name: JOB_TYPES, event: object) => {\n if (this.offlineMode) {\n this.hasInternetAccess = false;\n }\n\n if (this.queue) {\n this.queue.createJob(name, event);\n }\n };\n\n private prepareProperties = (inter: object) => {\n const properties = {\n // applicationBundleId: this.applicationBundleId,\n };\n Object.keys(inter).map((name, key) => {\n const k = name.replace(/[^a-z0-9_]/gi, \"\");\n const val = inter[name];\n properties[k] = typeof val === \"boolean\" ? val.toString() : val;\n });\n return properties;\n };\n\n private addTrackingWorker = () => {\n this.queue.addWorker(\n JOB_TRACKING,\n async (id, event) => {\n if (this.hasInternetAccess) {\n const res = await this.api.sendEvent(event);\n // TODO: parse response\n console.debug(\"🚀 ===> ~ res:\", res);\n return { ok: true };\n }\n throw new Error(\"Network request failed\");\n },\n {\n onSuccess: async (id, event) => {\n console.debug(\"🚀 ===> JOB_TRACKING onSuccess\", id, event);\n // await this.onTrackingInvoke(\"succeeded\", event);\n },\n onFailure: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_TRACKING onFailure\", id, event, error);\n // await this.onTrackingInvoke(\"failure\", event, error);\n },\n onFailed: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_TRACKING onFailed\", id, event, error);\n // await this.onTrackingInvoke(\"failed\", event, error);\n },\n ...WORKERS_OPTIONS,\n }\n );\n };\n\n private addVisitorWorker = () => {\n this.queue.addWorker(\n JOB_VISITOR,\n async (id, event) => {\n if (this.hasInternetAccess) {\n const res = await this.trackVisit(event);\n // TODO: parse response\n console.debug(\"🚀 ===> ~ res:\", res);\n return { ok: true };\n }\n\n throw new Error(\"Network request failed\");\n },\n {\n onSuccess: async (id, event) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onSuccess: ~ event:\", id, event);\n // await this.onTrackingInvoke(\"succeeded\", event);\n },\n onFailure: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onFailure: ~ error:\", id, error);\n // await this.onTrackingInvoke(\"failure\", event, error);\n },\n onFailed: async (id, event, error) => {\n console.debug(\"🚀 ===> JOB_VISITOR ~ onFailed: ~ error:\", id, error);\n // await this.onTrackingInvoke(\"failed\", event, error);\n },\n ...WORKERS_OPTIONS,\n }\n );\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edulib-france/expo-yawl",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,12 +10,13 @@
10
10
  "types": "build/index.d.ts",
11
11
  "scripts": {
12
12
  "build": "expo-module build",
13
+ "build:ci": "export EXPO_NONINTERACTIVE=1 && expo-module build",
13
14
  "clean": "expo-module clean",
14
15
  "lint": "expo-module lint",
15
16
  "test": "vitest",
16
17
  "prepare": "expo-module prepare",
17
18
  "prepublishOnly": "expo-module prepublishOnly",
18
- "publish:npm": "npm clean && npm build && npm publish",
19
+ "publish:npm": "npm run clean && npm run build:ci && npm publish",
19
20
  "expo-module": "expo-module",
20
21
  "open:ios": "xed example/ios",
21
22
  "open:android": "open -a \"Android Studio\" example/android"
@@ -38,12 +39,13 @@
38
39
  "homepage": "https://github.com/edulib-france/expo-yawl#readme",
39
40
  "dependencies": {
40
41
  "@react-native-async-storage/async-storage": "1.23.1",
41
- "react-native-queue": "git+https://github.com/Bravado-network/react-native-queue-asyncstorage.git#async-storage-galatea-384",
42
- "wretch": "^2.11.0",
43
- "expo-device": "~7.0.3",
42
+ "expo": "~52.0.46",
44
43
  "expo-application": "~6.0.2",
44
+ "expo-crypto": "~14.0.2",
45
+ "expo-device": "~7.0.3",
45
46
  "expo-network": "~7.0.5",
46
- "expo-crypto": "~14.0.2"
47
+ "react-native-queue": "git+https://github.com/edulib-france/react-native-queue-asyncstorage.git#005bb41",
48
+ "wretch": "^2.11.0"
47
49
  },
48
50
  "devDependencies": {
49
51
  "@types/react": "~18.3.12",
package/src/Yawl.types.ts CHANGED
@@ -6,6 +6,16 @@ export type YawlEvent = {
6
6
  user_type?: string;
7
7
  };
8
8
 
9
+ /**
10
+ * YawlView is a type that represents a view tracking event.
11
+ * It contains optional properties for page, title, and additional properties.
12
+ *
13
+ * @param page - Optional path of the page being viewed. ie. "/home". Ignored if viewTracker is set.
14
+ * @param title - Optional title of the page being viewed. ie. "Home". Ignored if viewTracker is set.
15
+ * @param properties - Optional additional properties to be sent with the event. Merged with viewTracker's properties.
16
+ */
9
17
  export type YawlView = {
10
- page: string;
18
+ page?: string;
19
+ title?: string;
20
+ properties?: Record<string, unknown>;
11
21
  };
package/src/core/index.ts CHANGED
@@ -39,11 +39,14 @@ export default class Yawl {
39
39
  private hasInternetAccess: boolean | undefined = true;
40
40
  private queue: any;
41
41
  private api: YawlApi;
42
+ private baseUrl: string;
43
+ private viewTracker?: () => YawlView;
42
44
 
43
45
  constructor({ apiKey, env = "prod" }: { apiKey: string; env?: Env }) {
44
46
  this.api = yawlApi({ apiKey, env });
45
47
  this.visitId = generateUUID();
46
48
  this.visitorId = generateUUID();
49
+ this.baseUrl = `react-native-${apiKey}`;
47
50
  }
48
51
 
49
52
  init = async () => {
@@ -54,14 +57,6 @@ export default class Yawl {
54
57
  this.createJob(JOB_VISITOR, data);
55
58
  };
56
59
 
57
- setVisitId = async (visitId: string): Promise<void> => {
58
- this.visitId = visitId;
59
-
60
- if (this.hasInternetAccess) {
61
- this.trackVisit(await this.getVisitData());
62
- }
63
- };
64
-
65
60
  track = (event: YawlEvent) => {
66
61
  const _event = {
67
62
  event: {
@@ -80,13 +75,30 @@ export default class Yawl {
80
75
  return _event;
81
76
  };
82
77
 
83
- trackView = (view: YawlView) => {
78
+ /**
79
+ * Track a view event.
80
+ * `viewTracker` object takes precedence over the `view` parameter.
81
+ * Properties from both `view` and `viewTracker` are merged.
82
+ * If `viewTracker` is not provided, the `view` parameter must contain a page.
83
+ *
84
+ * @param view - Optional view object containing page, title, and properties. Must be set if viewTracker is not provided, otherwise the event will not be sent.
85
+ * @returns the event object with the tracking data.
86
+ */
87
+ trackView = (view?: YawlView) => {
88
+ const trackedView = this.viewTracker?.();
89
+ if (!view?.page && !trackedView?.page) {
90
+ console.warn(
91
+ "Yawl: trackView() - page is required; Either set it in the view param or yawl.setViewTracker(); Event not sent"
92
+ );
93
+ return;
94
+ }
84
95
  const _event = {
85
96
  event: {
86
97
  name: "$view",
87
- url: view.page,
88
- title: view.page,
89
- page: view.page,
98
+ url: this.baseUrl,
99
+ ...view,
100
+ ...trackedView,
101
+ properties: { ...view?.properties, ...trackedView?.properties },
90
102
  id: generateUUID(),
91
103
  visit_token: this.visitId,
92
104
  visitor_token: this.visitorId,
@@ -97,6 +109,17 @@ export default class Yawl {
97
109
  return _event;
98
110
  };
99
111
 
112
+ setVisitId = async (visitId: string): Promise<void> => {
113
+ this.visitId = visitId;
114
+
115
+ if (this.hasInternetAccess) {
116
+ this.trackVisit(await this.getVisitData());
117
+ }
118
+ };
119
+
120
+ setViewTracker = (viewTracker: () => YawlView) =>
121
+ (this.viewTracker = viewTracker);
122
+
100
123
  private async loadVisitorId(): Promise<void> {
101
124
  const visitorIdKey = "yawl_visitorId";
102
125
  const visitorId = await AsyncStorage.getItem(visitorIdKey);