@xh/hoist 73.0.0-SNAPSHOT.1745976013413 → 73.0.0-SNAPSHOT.1746025071597

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/CHANGELOG.md CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  ### 💥 Breaking Changes (upgrade difficulty: 🟢 TRIVIAL - minor upgrade to Hoist Core)
6
6
 
7
- Requires `hoist-core >= 30.0` with new APIs to support the consolidated Admin Console "Clients" tab.
7
+ Requires `hoist-core >= 30.0` with new APIs to support the consolidated Admin Console "Clients" tab
8
+ and new properties on `TrackLog`.
8
9
 
9
10
  ### 🎁 New Features
10
11
 
@@ -12,6 +13,9 @@ Requires `hoist-core >= 30.0` with new APIs to support the consolidated Admin Co
12
13
  across all instances in the cluster.
13
14
  * Updated `FormModel` to support `persistWith` for storing and recalling its values, including
14
15
  developer options to persist all or a provided subset of fields.
16
+ * Enhanced all activity tracking messages with new `tabId` and `loadId` properties, to disambiguate
17
+ tracking activity for users with multiple browser tabs and multiple full refreshes/restarts of a
18
+ client app within the same tab.
15
19
 
16
20
  ### 🐞 Bug Fixes
17
21
 
package/admin/App.scss CHANGED
@@ -25,6 +25,12 @@
25
25
  height: 80vh;
26
26
  width: 80vw;
27
27
  }
28
+
29
+ .xh-badge-col {
30
+ --xh-badge-font-size: 0.9em;
31
+ background-color: var(--xh-intent-primary-darker);
32
+ font-family: var(--xh-font-family-mono);
33
+ }
28
34
  }
29
35
 
30
36
  .xh-units-label {
@@ -4,11 +4,19 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {badgeCol} from '@xh/hoist/admin/columns';
8
7
  import * as Col from '@xh/hoist/cmp/grid/columns';
9
8
  import {ColumnSpec} from '@xh/hoist/cmp/grid/columns';
10
9
  import {Icon} from '@xh/hoist/icon';
11
10
 
11
+ export const createdTime: ColumnSpec = {
12
+ field: {
13
+ name: 'createdTime',
14
+ type: 'date',
15
+ displayName: 'Created'
16
+ },
17
+ ...Col.compactDate
18
+ };
19
+
12
20
  export const isOpen: ColumnSpec = {
13
21
  field: {name: 'isOpen', type: 'bool'},
14
22
  headerName: '',
@@ -29,23 +37,14 @@ export const key: ColumnSpec = {
29
37
  width: 160
30
38
  };
31
39
 
32
- export const createdTime: ColumnSpec = {
40
+ export const lastReceivedTime: ColumnSpec = {
33
41
  field: {
34
- name: 'createdTime',
42
+ name: 'lastReceivedTime',
35
43
  type: 'date',
36
- displayName: 'Created'
37
- },
38
- ...Col.compactDate
39
- };
40
-
41
- export const sentMessageCount: ColumnSpec = {
42
- field: {
43
- name: 'sentMessageCount',
44
- type: 'int',
45
- displayName: 'Sent'
44
+ displayName: 'Last Received'
46
45
  },
47
- ...Col.number,
48
- width: 90
46
+ ...Col.compactDate,
47
+ width: 140
49
48
  };
50
49
 
51
50
  export const lastSentTime: ColumnSpec = {
@@ -68,44 +67,12 @@ export const receivedMessageCount: ColumnSpec = {
68
67
  width: 90
69
68
  };
70
69
 
71
- export const lastReceivedTime: ColumnSpec = {
72
- field: {
73
- name: 'lastReceivedTime',
74
- type: 'date',
75
- displayName: 'Last Received'
76
- },
77
- ...Col.compactDate,
78
- width: 140
79
- };
80
-
81
- export const appVersion: ColumnSpec = {
82
- field: {
83
- name: 'appVersion',
84
- displayName: 'Version',
85
- type: 'string'
86
- },
87
- width: 120
88
- };
89
-
90
- export const appBuild: ColumnSpec = {
91
- field: {
92
- name: 'appBuild',
93
- displayName: 'Build',
94
- type: 'string'
95
- },
96
- width: 120
97
- };
98
- export const loadId: ColumnSpec = {
99
- field: {
100
- name: 'loadId',
101
- type: 'string'
102
- },
103
- ...badgeCol
104
- };
105
- export const tabId: ColumnSpec = {
70
+ export const sentMessageCount: ColumnSpec = {
106
71
  field: {
107
- name: 'tabId',
108
- type: 'string'
72
+ name: 'sentMessageCount',
73
+ type: 'int',
74
+ displayName: 'Sent'
109
75
  },
110
- ...badgeCol
76
+ ...Col.number,
77
+ width: 90
111
78
  };
@@ -11,15 +11,29 @@ import {dateTimeRenderer} from '@xh/hoist/format';
11
11
  import {Icon} from '@xh/hoist/icon';
12
12
  import copy from 'clipboard-copy';
13
13
 
14
- export const name: ColumnSpec = {
15
- field: {name: 'name', type: 'string'},
16
- width: 200
14
+ export const badgeCol: ColumnSpec = {
15
+ autosizable: false,
16
+ width: 100,
17
+ renderer: badgeRenderer
17
18
  };
18
19
 
19
- export const type: ColumnSpec = {
20
- field: {name: 'type', type: 'string'},
21
- width: 100
22
- };
20
+ export function badgeRenderer(v) {
21
+ return v
22
+ ? badge({
23
+ item: v,
24
+ className: 'xh-badge-col',
25
+ style: {cursor: 'copy'},
26
+ title: 'Double-click to copy',
27
+ onDoubleClick: () => {
28
+ copy(v);
29
+ XH.toast({
30
+ icon: Icon.copy(),
31
+ message: `Copied ${v}`
32
+ });
33
+ }
34
+ })
35
+ : '-';
36
+ }
23
37
 
24
38
  export const description: ColumnSpec = {
25
39
  field: {name: 'description', type: 'string'},
@@ -27,11 +41,9 @@ export const description: ColumnSpec = {
27
41
  minWidth: 200
28
42
  };
29
43
 
30
- export const notes: ColumnSpec = {
31
- field: {name: 'notes', type: 'string'},
32
- minWidth: 60,
33
- flex: true,
34
- tooltip: true
44
+ export const name: ColumnSpec = {
45
+ field: {name: 'name', type: 'string'},
46
+ width: 200
35
47
  };
36
48
 
37
49
  export const note: ColumnSpec = {
@@ -45,33 +57,20 @@ export const note: ColumnSpec = {
45
57
  tooltip: true
46
58
  };
47
59
 
60
+ export const notes: ColumnSpec = {
61
+ field: {name: 'notes', type: 'string'},
62
+ minWidth: 60,
63
+ flex: true,
64
+ tooltip: true
65
+ };
66
+
48
67
  export const timestampNoYear: ColumnSpec = {
49
68
  field: {name: 'timestamp', type: 'date'},
50
69
  ...dateTimeSec,
51
70
  renderer: dateTimeRenderer({fmt: 'MMM DD HH:mm:ss.SSS'})
52
71
  };
53
72
 
54
- export function badgeRenderer(v) {
55
- return v
56
- ? badge({
57
- item: v,
58
- className: 'xh-font-family-mono',
59
- style: {cursor: 'copy'},
60
- intent: 'primary',
61
- title: 'Double-click to copy',
62
- onDoubleClick: () => {
63
- copy(v);
64
- XH.toast({
65
- icon: Icon.copy(),
66
- message: `Copied ${v}`
67
- });
68
- }
69
- })
70
- : '-';
71
- }
72
-
73
- export const badgeCol: ColumnSpec = {
74
- autosizable: false,
75
- width: 90,
76
- renderer: badgeRenderer
73
+ export const type: ColumnSpec = {
74
+ field: {name: 'type', type: 'string'},
75
+ width: 100
77
76
  };
@@ -4,13 +4,22 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {badgeRenderer} from '@xh/hoist/admin/columns';
7
+ import {badgeCol, badgeRenderer} from '@xh/hoist/admin/columns';
8
8
  import {RangeAggregator} from '@xh/hoist/admin/tabs/activity/aggregators/RangeAggregator';
9
9
  import * as Col from '@xh/hoist/cmp/grid/columns';
10
10
  import {ColumnSpec} from '@xh/hoist/cmp/grid/columns';
11
11
  import {fmtDate, fmtSpan, numberRenderer} from '@xh/hoist/format';
12
12
  import {Icon} from '@xh/hoist/icon';
13
13
 
14
+ export const appBuild: ColumnSpec = {
15
+ field: {
16
+ name: 'appBuild',
17
+ displayName: 'Build',
18
+ type: 'string'
19
+ },
20
+ width: 120
21
+ };
22
+
14
23
  export const appEnvironment: ColumnSpec = {
15
24
  field: {
16
25
  name: 'appEnvironment',
@@ -21,8 +30,12 @@ export const appEnvironment: ColumnSpec = {
21
30
  };
22
31
 
23
32
  export const appVersion: ColumnSpec = {
24
- field: {name: 'appVersion', type: 'string'},
25
- width: 130
33
+ field: {
34
+ name: 'appVersion',
35
+ displayName: 'Version',
36
+ type: 'string'
37
+ },
38
+ width: 120
26
39
  };
27
40
 
28
41
  export const browser: ColumnSpec = {
@@ -35,24 +48,25 @@ export const browser: ColumnSpec = {
35
48
  width: 100
36
49
  };
37
50
 
38
- export const severity: ColumnSpec = {
51
+ export const category: ColumnSpec = {
39
52
  field: {
40
- name: 'severity',
53
+ name: 'category',
41
54
  type: 'string',
42
55
  isDimension: true,
43
56
  aggregator: 'UNIQUE'
44
57
  },
45
- width: 80
58
+ width: 100
46
59
  };
47
60
 
48
- export const category: ColumnSpec = {
61
+ export const correlationId: ColumnSpec = {
49
62
  field: {
50
- name: 'category',
63
+ name: 'correlationId',
51
64
  type: 'string',
52
- isDimension: true,
53
- aggregator: 'UNIQUE'
65
+ displayName: 'Correlation ID'
54
66
  },
55
- width: 100
67
+ renderer: badgeRenderer,
68
+ width: 180,
69
+ autosizeBufferPx: 20
56
70
  };
57
71
 
58
72
  export const data: ColumnSpec = {
@@ -71,6 +85,20 @@ export const day: ColumnSpec = {
71
85
  displayName: 'App Day'
72
86
  };
73
87
 
88
+ export const dayRange: ColumnSpec = {
89
+ field: {
90
+ name: 'dayRange',
91
+ type: 'json',
92
+ aggregator: new RangeAggregator(),
93
+ displayName: 'App Day Range'
94
+ },
95
+ align: 'right',
96
+ width: 200,
97
+ renderer: dayRangeRenderer,
98
+ exportValue: dayRangeRenderer,
99
+ comparator: dayRangeComparator
100
+ };
101
+
74
102
  export const device: ColumnSpec = {
75
103
  field: {
76
104
  name: 'device',
@@ -117,24 +145,33 @@ export const entryId: ColumnSpec = {
117
145
  align: 'right'
118
146
  };
119
147
 
120
- export const correlationId: ColumnSpec = {
148
+ export const error: ColumnSpec = {
121
149
  field: {
122
- name: 'correlationId',
150
+ name: 'error',
151
+ type: 'string'
152
+ },
153
+ width: 250,
154
+ autosizeMaxWidth: 400,
155
+ renderer: e => fmtSpan(e, {className: 'xh-font-family-mono xh-font-size-small'})
156
+ };
157
+
158
+ export const instance: ColumnSpec = {
159
+ field: {
160
+ name: 'instance',
123
161
  type: 'string',
124
- displayName: 'Correlation ID'
162
+ isDimension: true,
163
+ aggregator: 'UNIQUE'
125
164
  },
126
165
  renderer: badgeRenderer,
127
166
  width: 100
128
167
  };
129
168
 
130
- export const error: ColumnSpec = {
169
+ export const loadId: ColumnSpec = {
131
170
  field: {
132
- name: 'error',
171
+ name: 'loadId',
133
172
  type: 'string'
134
173
  },
135
- width: 250,
136
- autosizeMaxWidth: 400,
137
- renderer: e => fmtSpan(e, {className: 'xh-font-family-mono xh-font-size-small'})
174
+ ...badgeCol
138
175
  };
139
176
 
140
177
  export const msg: ColumnSpec = {
@@ -149,25 +186,32 @@ export const msg: ColumnSpec = {
149
186
  autosizeMaxWidth: 400
150
187
  };
151
188
 
152
- export const url: ColumnSpec = {
189
+ export const severity: ColumnSpec = {
153
190
  field: {
154
- name: 'url',
191
+ name: 'severity',
155
192
  type: 'string',
156
- displayName: 'URL'
193
+ isDimension: true,
194
+ aggregator: 'UNIQUE'
157
195
  },
158
- width: 250,
159
- autosizeMaxWidth: 400
196
+ width: 80
160
197
  };
161
198
 
162
- export const instance: ColumnSpec = {
199
+ export const tabId: ColumnSpec = {
163
200
  field: {
164
- name: 'instance',
201
+ name: 'tabId',
202
+ type: 'string'
203
+ },
204
+ ...badgeCol
205
+ };
206
+
207
+ export const url: ColumnSpec = {
208
+ field: {
209
+ name: 'url',
165
210
  type: 'string',
166
- isDimension: true,
167
- aggregator: 'UNIQUE'
211
+ displayName: 'URL'
168
212
  },
169
- renderer: badgeRenderer,
170
- width: 100
213
+ width: 250,
214
+ autosizeMaxWidth: 400
171
215
  };
172
216
 
173
217
  export const userAgent: ColumnSpec = {
@@ -207,20 +251,6 @@ export const userMessageFlag: ColumnSpec = {
207
251
  }
208
252
  };
209
253
 
210
- export const dayRange: ColumnSpec = {
211
- field: {
212
- name: 'dayRange',
213
- type: 'json',
214
- aggregator: new RangeAggregator(),
215
- displayName: 'App Day Range'
216
- },
217
- align: 'right',
218
- width: 200,
219
- renderer: dayRangeRenderer,
220
- exportValue: dayRangeRenderer,
221
- comparator: dayRangeComparator
222
- };
223
-
224
254
  //-----------------------
225
255
  // Implementation
226
256
  //-----------------------
@@ -1,3 +1,4 @@
1
+ export * from './Clients';
1
2
  export * from './Core';
2
3
  export * from './Rest';
3
4
  export * from './Tracking';
@@ -105,7 +105,9 @@ export class ActivityTrackingModel extends HoistModel {
105
105
  Col.url.field,
106
106
  Col.instance.field,
107
107
  Col.appVersion.field,
108
- Col.appEnvironment.field
108
+ Col.appEnvironment.field,
109
+ Col.loadId.field,
110
+ Col.tabId.field
109
111
  ] as CubeFieldSpec[]
110
112
  });
111
113
 
@@ -133,6 +135,8 @@ export class ActivityTrackingModel extends HoistModel {
133
135
  {field: 'instance'},
134
136
  {field: 'severity'},
135
137
  {field: 'appVersion'},
138
+ {field: 'loadId'},
139
+ {field: 'tabId'},
136
140
  {field: 'appEnvironment', displayName: 'Environment'}
137
141
  ]
138
142
  });
@@ -183,6 +187,8 @@ export class ActivityTrackingModel extends HoistModel {
183
187
  {field: 'count', hidden},
184
188
  {...Col.appEnvironment, hidden},
185
189
  {...Col.appVersion, hidden},
190
+ {...Col.loadId, hidden},
191
+ {...Col.tabId, hidden},
186
192
  {...Col.url, hidden},
187
193
  {...Col.instance, hidden}
188
194
  ]
@@ -31,7 +31,6 @@ export class ActivityDetailModel extends HoistModel {
31
31
 
32
32
  override onLinked() {
33
33
  const hidden = true;
34
-
35
34
  this.gridModel = new GridModel({
36
35
  sortBy: 'dateCreated|desc',
37
36
  colChooserModel: true,
@@ -53,11 +52,13 @@ export class ActivityDetailModel extends HoistModel {
53
52
  {...Col.device},
54
53
  {...Col.userAgent, hidden},
55
54
  {...Col.appVersion},
55
+ {...Col.loadId},
56
+ {...Col.tabId},
56
57
  {...Col.appEnvironment, hidden},
57
58
  {...Col.data, hidden},
58
59
  {...Col.url},
59
- {...Col.correlationId},
60
60
  {...Col.instance, hidden},
61
+ {...Col.correlationId},
61
62
  {...Col.severity, hidden},
62
63
  {...Col.elapsed},
63
64
  {...Col.dateCreatedWithSec, displayName: 'Timestamp'}
@@ -4,11 +4,11 @@
4
4
  *
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
- import {correlationId, instance} from '@xh/hoist/admin/columns';
7
+ import {badgeRenderer} from '@xh/hoist/admin/columns';
8
8
  import {form} from '@xh/hoist/cmp/form';
9
9
  import {grid, gridCountLabel} from '@xh/hoist/cmp/grid';
10
10
  import {a, div, filler, h3, hframe, placeholder, span} from '@xh/hoist/cmp/layout';
11
- import {hoistCmp, creates} from '@xh/hoist/core';
11
+ import {creates, hoistCmp} from '@xh/hoist/core';
12
12
  import {colChooserButton, exportButton} from '@xh/hoist/desktop/cmp/button';
13
13
  import {formField} from '@xh/hoist/desktop/cmp/form';
14
14
  import {gridFindField} from '@xh/hoist/desktop/cmp/grid';
@@ -95,17 +95,25 @@ const detailRecForm = hoistCmp.factory<ActivityDetailModel>(({model}) => {
95
95
  return `${appVersion} (${appEnvironment})`;
96
96
  }
97
97
  }),
98
+ formField({
99
+ field: 'loadId',
100
+ readonlyRenderer: badgeRenderer
101
+ }),
102
+ formField({
103
+ field: 'tabId',
104
+ readonlyRenderer: badgeRenderer
105
+ }),
98
106
  formField({
99
107
  field: 'url',
100
108
  readonlyRenderer: hyperlinkVal
101
109
  }),
102
110
  formField({
103
111
  field: 'instance',
104
- readonlyRenderer: v => instance.renderer(v, null)
112
+ readonlyRenderer: badgeRenderer
105
113
  }),
106
114
  formField({
107
115
  field: 'correlationId',
108
- readonlyRenderer: v => correlationId.renderer(v, null)
116
+ readonlyRenderer: badgeRenderer
109
117
  }),
110
118
  formField({
111
119
  field: 'elapsed',
@@ -18,7 +18,6 @@ import {Timer} from '@xh/hoist/utils/async';
18
18
  import {SECONDS} from '@xh/hoist/utils/datetime';
19
19
  import {pluralize} from '@xh/hoist/utils/js';
20
20
  import {isEmpty} from 'lodash';
21
- import * as WSCol from './ClientsColumns';
22
21
  import {BaseAdminTabModel} from '@xh/hoist/admin/tabs/BaseAdminTabModel';
23
22
 
24
23
  export class ClientsModel extends BaseAdminTabModel {
@@ -177,32 +176,32 @@ export class ClientsModel extends BaseAdminTabModel {
177
176
  },
178
177
  sortBy: ['user'],
179
178
  columns: [
180
- WSCol.isOpen,
179
+ Col.isOpen,
181
180
  Col.user,
182
181
  {
183
182
  headerName: 'Session',
184
183
  headerAlign: 'center',
185
184
  children: [
186
- WSCol.createdTime,
187
- {...WSCol.key, hidden},
185
+ Col.createdTime,
186
+ {...Col.key, hidden},
188
187
  Col.instance,
189
- WSCol.loadId,
190
- WSCol.tabId
188
+ Col.loadId,
189
+ Col.tabId
191
190
  ]
192
191
  },
193
192
  {
194
193
  headerName: 'Client App',
195
194
  headerAlign: 'center',
196
- children: [WSCol.appVersion, WSCol.appBuild]
195
+ children: [Col.appVersion, Col.appBuild]
197
196
  },
198
197
  {
199
198
  headerName: 'Send/Receive',
200
199
  headerAlign: 'center',
201
200
  children: [
202
- WSCol.sentMessageCount,
203
- WSCol.lastSentTime,
204
- WSCol.receivedMessageCount,
205
- WSCol.lastReceivedTime
201
+ Col.sentMessageCount,
202
+ Col.lastSentTime,
203
+ Col.receivedMessageCount,
204
+ Col.lastReceivedTime
206
205
  ]
207
206
  }
208
207
  ]
@@ -1,12 +1,8 @@
1
1
  import { ColumnSpec } from '@xh/hoist/cmp/grid/columns';
2
+ export declare const createdTime: ColumnSpec;
2
3
  export declare const isOpen: ColumnSpec;
3
4
  export declare const key: ColumnSpec;
4
- export declare const createdTime: ColumnSpec;
5
- export declare const sentMessageCount: ColumnSpec;
5
+ export declare const lastReceivedTime: ColumnSpec;
6
6
  export declare const lastSentTime: ColumnSpec;
7
7
  export declare const receivedMessageCount: ColumnSpec;
8
- export declare const lastReceivedTime: ColumnSpec;
9
- export declare const appVersion: ColumnSpec;
10
- export declare const appBuild: ColumnSpec;
11
- export declare const loadId: ColumnSpec;
12
- export declare const tabId: ColumnSpec;
8
+ export declare const sentMessageCount: ColumnSpec;
@@ -1,10 +1,10 @@
1
1
  /// <reference types="react" />
2
2
  import { ColumnSpec } from '@xh/hoist/cmp/grid';
3
- export declare const name: ColumnSpec;
4
- export declare const type: ColumnSpec;
3
+ export declare const badgeCol: ColumnSpec;
4
+ export declare function badgeRenderer(v: any): "-" | import("react").ReactElement<import("@xh/hoist/cmp/badge").BadgeProps, any>;
5
5
  export declare const description: ColumnSpec;
6
- export declare const notes: ColumnSpec;
6
+ export declare const name: ColumnSpec;
7
7
  export declare const note: ColumnSpec;
8
+ export declare const notes: ColumnSpec;
8
9
  export declare const timestampNoYear: ColumnSpec;
9
- export declare function badgeRenderer(v: any): "-" | import("react").ReactElement<import("@xh/hoist/cmp/badge").BadgeProps, any>;
10
- export declare const badgeCol: ColumnSpec;
10
+ export declare const type: ColumnSpec;
@@ -1,21 +1,24 @@
1
1
  import { ColumnSpec } from '@xh/hoist/cmp/grid/columns';
2
+ export declare const appBuild: ColumnSpec;
2
3
  export declare const appEnvironment: ColumnSpec;
3
4
  export declare const appVersion: ColumnSpec;
4
5
  export declare const browser: ColumnSpec;
5
- export declare const severity: ColumnSpec;
6
6
  export declare const category: ColumnSpec;
7
+ export declare const correlationId: ColumnSpec;
7
8
  export declare const data: ColumnSpec;
8
9
  export declare const day: ColumnSpec;
10
+ export declare const dayRange: ColumnSpec;
9
11
  export declare const device: ColumnSpec;
10
12
  export declare const elapsed: ColumnSpec;
11
13
  export declare const entryCount: ColumnSpec;
12
14
  export declare const entryId: ColumnSpec;
13
- export declare const correlationId: ColumnSpec;
14
15
  export declare const error: ColumnSpec;
16
+ export declare const instance: ColumnSpec;
17
+ export declare const loadId: ColumnSpec;
15
18
  export declare const msg: ColumnSpec;
19
+ export declare const severity: ColumnSpec;
20
+ export declare const tabId: ColumnSpec;
16
21
  export declare const url: ColumnSpec;
17
- export declare const instance: ColumnSpec;
18
22
  export declare const userAgent: ColumnSpec;
19
23
  export declare const userAlertedFlag: ColumnSpec;
20
24
  export declare const userMessageFlag: ColumnSpec;
21
- export declare const dayRange: ColumnSpec;
@@ -1,3 +1,4 @@
1
+ export * from './Clients';
1
2
  export * from './Core';
2
3
  export * from './Rest';
3
4
  export * from './Tracking';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "73.0.0-SNAPSHOT.1745976013413",
3
+ "version": "73.0.0-SNAPSHOT.1746025071597",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": "github:xh/hoist-react",
6
6
  "homepage": "https://xh.io",
@@ -119,6 +119,8 @@ export class TrackService extends HoistService {
119
119
  msg: stripTags(options.message),
120
120
  clientUsername: XH.getUsername(),
121
121
  appVersion: XH.getEnv('clientVersion'),
122
+ loadId: XH.loadId,
123
+ tabId: XH.tabId,
122
124
  url: window.location.href,
123
125
  timestamp: Date.now()
124
126
  };