@wapitee/typhoonx-hydrogen 0.4.6 → 0.6.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"TyphoonX.d.ts","sourceRoot":"","sources":["../src/TyphoonX.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0BD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,sCAYpD"}
1
+ {"version":3,"file":"TyphoonX.d.ts","sourceRoot":"","sources":["../src/TyphoonX.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmCD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,sCAqBpD"}
package/dist/TyphoonX.js CHANGED
@@ -1,14 +1,21 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { flattenConnection, parseGid, useAnalytics } from '@shopify/hydrogen';
3
3
  import { useEffect, useRef, useState } from 'react';
4
- import { getOrCreateClientId } from './client-id.js';
4
+ import { getOrCreateClientId, hasClientId } from './client-id.js';
5
5
  const COLLECT_ENDPOINT = 'https://spell.typhoonx.io/api/v1/receive';
6
6
  export default function TyphoonX(props) {
7
+ const { subscribe } = useAnalytics();
8
+ const isInsideProvider = subscribe.length > 0;
7
9
  const [isClient, setIsClient] = useState(false);
8
10
  useEffect(() => {
9
11
  setIsClient(true);
10
12
  }, []);
11
- if (!isClient) {
13
+ useEffect(() => {
14
+ if (!isInsideProvider) {
15
+ console.error('[TyphoonX] <TyphoonX> must be rendered inside <Analytics.Provider>.');
16
+ }
17
+ }, [isInsideProvider]);
18
+ if (!isClient || !isInsideProvider) {
12
19
  return null;
13
20
  }
14
21
  return _jsx(TyphoonXClient, { ...props });
@@ -18,6 +25,17 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
18
25
  const { ready } = register('TyphoonX');
19
26
  const currentUrlRef = useRef(null);
20
27
  const previousUrlRef = useRef(null);
28
+ useEffect(() => {
29
+ try {
30
+ if (!hasClientId()) {
31
+ window.localStorage.setItem('__typhoon_first_visit_time', new Date().toISOString());
32
+ window.localStorage.setItem('__typhoon_first_visit_url', window.location.href);
33
+ }
34
+ }
35
+ catch {
36
+ // Do nothing
37
+ }
38
+ }, [hasClientId()]);
21
39
  useEffect(() => {
22
40
  const clientId = getOrCreateClientId(cookieDomain);
23
41
  const referrerFor = (url) => {
@@ -44,9 +62,8 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
44
62
  });
45
63
  subscribe('cart_viewed', (data) => {
46
64
  const { cart } = data;
47
- if (!cart?.lines) {
65
+ if (!cart?.lines)
48
66
  return;
49
- }
50
67
  const cartLines = flattenConnection(cart.lines);
51
68
  send({
52
69
  ...shared(data.url, data.shop?.currency),
@@ -63,9 +80,8 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
63
80
  });
64
81
  subscribe('collection_viewed', (data) => {
65
82
  const { collection } = data;
66
- if (!collection.id) {
83
+ if (!collection.id)
67
84
  return;
68
- }
69
85
  send({
70
86
  ...shared(data.url, data.shop?.currency),
71
87
  event: 'view_item_list',
@@ -74,16 +90,33 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
74
90
  });
75
91
  });
76
92
  subscribe('page_viewed', (data) => {
93
+ const payload = shared(data.url);
77
94
  send({
78
- ...shared(data.url),
95
+ ...payload,
79
96
  event: 'page_view',
80
97
  });
98
+ try {
99
+ const visitTime = window.localStorage.getItem('__typhoon_first_visit_time');
100
+ const visitUrl = window.localStorage.getItem('__typhoon_first_visit_url');
101
+ if (!visitTime || !visitUrl)
102
+ return;
103
+ send({
104
+ ...payload,
105
+ request_page_url: visitUrl,
106
+ timestamp: visitTime,
107
+ event: 'first_visit',
108
+ });
109
+ window.localStorage.removeItem('__typhoon_first_visit_time');
110
+ window.localStorage.removeItem('__typhoon_first_visit_url');
111
+ }
112
+ catch {
113
+ // Do nothing
114
+ }
81
115
  });
82
116
  subscribe('product_added_to_cart', (data) => {
83
117
  const { currentLine } = data;
84
- if (currentLine === undefined) {
118
+ if (currentLine === undefined)
85
119
  return;
86
- }
87
120
  send({
88
121
  ...shared(window.location.href, data.shop?.currency),
89
122
  event: 'add_to_cart',
@@ -102,9 +135,8 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
102
135
  subscribe('product_removed_from_cart', (data) => {
103
136
  const { currentLine, prevLine } = data;
104
137
  const quantity = (prevLine?.quantity ?? 0) - (currentLine?.quantity ?? 0);
105
- if (prevLine === undefined || quantity <= 0) {
138
+ if (prevLine === undefined || quantity <= 0)
106
139
  return;
107
- }
108
140
  send({
109
141
  ...shared(window.location.href, data.shop?.currency),
110
142
  event: 'remove_from_cart',
@@ -123,9 +155,8 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
123
155
  });
124
156
  subscribe('product_viewed', (data) => {
125
157
  const product = data.products[0];
126
- if (product === undefined) {
158
+ if (product === undefined)
127
159
  return;
128
- }
129
160
  send({
130
161
  ...shared(data.url, data.shop?.currency),
131
162
  event: 'view_item',
@@ -141,6 +172,16 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
141
172
  value: product.price,
142
173
  });
143
174
  });
175
+ subscribe('search_viewed', (data) => {
176
+ const { searchTerm } = data;
177
+ if (!searchTerm)
178
+ return;
179
+ send({
180
+ ...shared(data.url, data.shop?.currency),
181
+ event: 'search',
182
+ search_term: searchTerm,
183
+ });
184
+ });
144
185
  ready();
145
186
  }, [cookieDomain, merchantId, shopId, canTrack, ready, subscribe]);
146
187
  return null;
@@ -1,3 +1,5 @@
1
+ /** Whether `__typhoon_client_id` is already set. */
2
+ export declare function hasClientId(): boolean;
1
3
  /** Existing `__typhoon_client_id`, or a new UUID cookie on the apex domain. */
2
4
  export declare function getOrCreateClientId(cookieDomain?: string): string;
3
5
  //# sourceMappingURL=client-id.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-id.d.ts","sourceRoot":"","sources":["../src/client-id.ts"],"names":[],"mappings":"AAwBA,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAWjE"}
1
+ {"version":3,"file":"client-id.d.ts","sourceRoot":"","sources":["../src/client-id.ts"],"names":[],"mappings":"AAwBA,oDAAoD;AACpD,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAWjE"}
package/dist/client-id.js CHANGED
@@ -8,6 +8,10 @@ const cookies = new Cookies(null, {
8
8
  sameSite: 'lax',
9
9
  maxAge: MAX_AGE,
10
10
  });
11
+ /** Whether `__typhoon_client_id` is already set. */
12
+ export function hasClientId() {
13
+ return cookies.get(COOKIE, { doNotParse: true }) !== undefined;
14
+ }
11
15
  /** Existing `__typhoon_client_id`, or a new UUID cookie on the apex domain. */
12
16
  export function getOrCreateClientId(cookieDomain) {
13
17
  const existing = cookies.get(COOKIE, { doNotParse: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wapitee/typhoonx-hydrogen",
3
- "version": "0.4.6",
3
+ "version": "0.6.0",
4
4
  "description": "TyphoonX Hydrogen Analytics subscriber",
5
5
  "keywords": [
6
6
  "typhoonx",