@edulib-france/expo-yawl 0.0.4 → 0.0.6
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 +49 -2
- package/build/Yawl.types.d.ts +11 -1
- package/build/Yawl.types.d.ts.map +1 -1
- package/build/Yawl.types.js.map +1 -1
- package/build/core/index.d.ts +22 -7
- package/build/core/index.d.ts.map +1 -1
- package/build/core/index.js +28 -9
- package/build/core/index.js.map +1 -1
- package/package.json +8 -6
- package/src/Yawl.types.ts +11 -1
- package/src/core/index.ts +35 -12
package/README.md
CHANGED
|
@@ -55,10 +55,57 @@ yawl.track({
|
|
|
55
55
|
|
|
56
56
|
## Track Views
|
|
57
57
|
|
|
58
|
-
We still need to find the best way to get the view name in React Native. For now, we can use the `page` property to set the view name.
|
|
59
|
-
|
|
60
58
|
```ts
|
|
61
59
|
yawl.trackView({
|
|
62
60
|
page: "page_name",
|
|
61
|
+
title: "page_title",
|
|
62
|
+
properties: {
|
|
63
|
+
// additional properties
|
|
64
|
+
},
|
|
63
65
|
});
|
|
64
66
|
```
|
|
67
|
+
|
|
68
|
+
### React Navigation
|
|
69
|
+
|
|
70
|
+
If you are using React Navigation, you can use the `yawl.setViewTracker()` to record the current screen name and params.
|
|
71
|
+
Based on [their documentation](https://reactnavigation.org/docs/5.x/screen-tracking/) you could :
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
export default () => {
|
|
75
|
+
const navigationRef = useRef();
|
|
76
|
+
const routeNameRef = useRef();
|
|
77
|
+
...
|
|
78
|
+
// sets the view tracker so `yawl.trackView()` can be used anywhere
|
|
79
|
+
yawl.setViewTracker(() => {
|
|
80
|
+
const currentRoute = navigationRef?.current?.getCurrentRoute()
|
|
81
|
+
return ({
|
|
82
|
+
page: currentRoute.name,
|
|
83
|
+
properties: currentRoute.params
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<NavigationContainer
|
|
89
|
+
ref={navigationRef}
|
|
90
|
+
onReady={() =>
|
|
91
|
+
// yawl.trackView() if the app is opened from a cold start
|
|
92
|
+
(routeNameRef.current = navigationRef.current.getCurrentRoute().name)
|
|
93
|
+
}
|
|
94
|
+
onStateChange={async () => {
|
|
95
|
+
const previousRouteName = routeNameRef.current;
|
|
96
|
+
const currentRouteName = navigationRef.current.getCurrentRoute().name;
|
|
97
|
+
|
|
98
|
+
if (previousRouteName !== currentRouteName) {
|
|
99
|
+
// The line below uses the yawl.setViewTracker() setup to get the current screen name and params
|
|
100
|
+
await yawl.trackView();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Save the current route name for later comparison
|
|
104
|
+
routeNameRef.current = currentRouteName;
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
{/* ... */}
|
|
108
|
+
</NavigationContainer>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
```
|
package/build/Yawl.types.d.ts
CHANGED
|
@@ -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
|
|
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;
|
|
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"}
|
package/build/Yawl.types.js.map
CHANGED
|
@@ -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
|
|
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"]}
|
package/build/core/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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;
|
|
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"}
|
package/build/core/index.js
CHANGED
|
@@ -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:
|
|
77
|
-
|
|
78
|
-
|
|
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);
|
package/build/core/index.js.map
CHANGED
|
@@ -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
|
+
"version": "0.0.6",
|
|
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 run clean && npm run 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
|
-
"
|
|
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
|
-
"
|
|
47
|
+
"react-native-queue": "git+https://github.com/edulib-france/react-native-queue-asyncstorage.git#005bb418d27f1a93f4372ba6764292a71d954b6e",
|
|
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
|
|
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
|
-
|
|
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:
|
|
88
|
-
|
|
89
|
-
|
|
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);
|