@zohodesk/i18n 1.0.0-beta.34 → 1.0.0-beta.36-murphy

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 (51) hide show
  1. package/docs/murphy/01-MURPHY_OVERVIEW.md +148 -0
  2. package/docs/murphy/02-MURPHY_ARCHITECTURE.md +283 -0
  3. package/docs/murphy/03-MURPHY_BACKEND_CONFIG.md +337 -0
  4. package/docs/murphy/04-MURPHY_FRONTEND_INIT.md +437 -0
  5. package/docs/murphy/05-MURPHY_DESK_CLIENT_USAGE.md +467 -0
  6. package/docs/murphy/06-MURPHY_I18N_INTEGRATION.md +402 -0
  7. package/docs/murphy/07-MURPHY_WHY_I18N_APPROACH.md +391 -0
  8. package/es/components/DateTimeDiffFormat.js +5 -19
  9. package/es/components/FormatText.js +2 -2
  10. package/es/components/HOCI18N.js +32 -43
  11. package/es/components/I18N.js +2 -13
  12. package/es/components/I18NProvider.js +0 -9
  13. package/es/components/PluralFormat.js +3 -5
  14. package/es/components/UserTimeDiffFormat.js +5 -9
  15. package/es/components/__tests__/DateTimeDiffFormat.spec.js +157 -221
  16. package/es/components/__tests__/FormatText.spec.js +2 -2
  17. package/es/components/__tests__/HOCI18N.spec.js +2 -4
  18. package/es/components/__tests__/I18N.spec.js +6 -4
  19. package/es/components/__tests__/I18NProvider.spec.js +4 -4
  20. package/es/components/__tests__/PluralFormat.spec.js +2 -2
  21. package/es/components/__tests__/UserTimeDiffFormat.spec.js +249 -348
  22. package/es/index.js +1 -0
  23. package/es/utils/__tests__/jsxTranslations.spec.js +3 -7
  24. package/es/utils/errorReporter.js +35 -0
  25. package/es/utils/index.js +42 -92
  26. package/es/utils/jsxTranslations.js +34 -52
  27. package/lib/I18NContext.js +2 -7
  28. package/lib/components/DateTimeDiffFormat.js +46 -87
  29. package/lib/components/FormatText.js +18 -41
  30. package/lib/components/HOCI18N.js +24 -59
  31. package/lib/components/I18N.js +27 -64
  32. package/lib/components/I18NProvider.js +27 -63
  33. package/lib/components/PluralFormat.js +24 -50
  34. package/lib/components/UserTimeDiffFormat.js +43 -72
  35. package/lib/components/__tests__/DateTimeDiffFormat.spec.js +95 -165
  36. package/lib/components/__tests__/FormatText.spec.js +3 -10
  37. package/lib/components/__tests__/HOCI18N.spec.js +3 -14
  38. package/lib/components/__tests__/I18N.spec.js +4 -12
  39. package/lib/components/__tests__/I18NProvider.spec.js +8 -23
  40. package/lib/components/__tests__/PluralFormat.spec.js +3 -11
  41. package/lib/components/__tests__/UserTimeDiffFormat.spec.js +157 -225
  42. package/lib/index.js +25 -23
  43. package/lib/utils/__tests__/jsxTranslations.spec.js +1 -12
  44. package/lib/utils/errorReporter.js +44 -0
  45. package/lib/utils/index.js +49 -125
  46. package/lib/utils/jsxTranslations.js +61 -100
  47. package/package.json +1 -1
  48. package/src/index.js +5 -0
  49. package/src/utils/errorReporter.js +41 -0
  50. package/src/utils/index.js +8 -1
  51. package/src/utils/jsxTranslations.js +8 -1
@@ -0,0 +1,437 @@
1
+ # Murphy Frontend Initialization
2
+
3
+ ## Overview
4
+
5
+ Murphy SDK is loaded from CDN and initialized on the client side using configuration injected from the backend.
6
+
7
+ ---
8
+
9
+ ## Initialization Timeline
10
+
11
+ ```
12
+ +-------------------------------------------------------------------+
13
+ | MURPHY INITIALIZATION TIMELINE |
14
+ +-------------------------------------------------------------------+
15
+ | |
16
+ | 1. HTML Document Loads |
17
+ | +----------------------------------------------------------+ |
18
+ | | <script nonce="..."> | |
19
+ | | var desk_urls = { | |
20
+ | | murphyAppKey: "755747375", | |
21
+ | | murphyAppDomain: "murphy.zoho.com", | |
22
+ | | murphyAuthKey: "..." | |
23
+ | | }; | |
24
+ | | </script> | |
25
+ | +----------------------------------------------------------+ |
26
+ | | |
27
+ | v |
28
+ | 2. InitMurphy() Called |
29
+ | +----------------------------------------------------------+ |
30
+ | | - Checks if Murphy is enabled | |
31
+ | | - Fetches build release JSON (for version info) | |
32
+ | | - Loads Murphy SDK from CDN | |
33
+ | +----------------------------------------------------------+ |
34
+ | | |
35
+ | v |
36
+ | 3. Murphy SDK Loaded from CDN |
37
+ | +----------------------------------------------------------+ |
38
+ | | URL: {staticDomain}/murphysdk/3.0.0/murphy.min.js | |
39
+ | | | |
40
+ | | Creates global: window.murphy | |
41
+ | +----------------------------------------------------------+ |
42
+ | | |
43
+ | v |
44
+ | 4. Wait for desk_urls (retry mechanism) |
45
+ | +----------------------------------------------------------+ |
46
+ | | - Checks isInitialDataPresent() | |
47
+ | | - Retries up to 100 times with 10ms delay | |
48
+ | | - Ensures desk_urls has Murphy credentials | |
49
+ | +----------------------------------------------------------+ |
50
+ | | |
51
+ | v |
52
+ | 5. murphyInit() Configures SDK |
53
+ | +----------------------------------------------------------+ |
54
+ | | murphy.install({ | |
55
+ | | config: { appKey, appDomain, authKey, ... } | |
56
+ | | }); | |
57
+ | +----------------------------------------------------------+ |
58
+ | | |
59
+ | v |
60
+ | 6. Client Metrics Installed |
61
+ | +----------------------------------------------------------+ |
62
+ | | murphy.clientmetrics.install(config) | |
63
+ | | - Performance monitoring enabled | |
64
+ | | - Time to Interactive tracking | |
65
+ | | - Soft navigation tracking | |
66
+ | +----------------------------------------------------------+ |
67
+ | | |
68
+ | v |
69
+ | 7. Global murphy Object Ready! |
70
+ | +----------------------------------------------------------+ |
71
+ | | murphy.error(...) -> Track errors | |
72
+ | | murphy.appLog(...) -> Application logs | |
73
+ | | murphy.clientmetrics -> Performance metrics | |
74
+ | | murphy.telemetry -> User behavior tracking | |
75
+ | +----------------------------------------------------------+ |
76
+ | |
77
+ +-------------------------------------------------------------------+
78
+ ```
79
+
80
+ ---
81
+
82
+ ## Key Files
83
+
84
+ ### 1. initial_html/index.js - Entry Point
85
+
86
+ ```javascript
87
+ // Path: src/library/murphy/initial_html/index.js
88
+
89
+ import { loadResource } from '../../../_utils/loadResource.js';
90
+ import { isMurphyEnabled, murphyIntegrationName } from './constants.js';
91
+ import { murphySDKUrl } from './Urls.js';
92
+ import {
93
+ fetchReleaseJson,
94
+ installMurphyClientMetrics,
95
+ isClientMetricsSupported,
96
+ isInitialDataPresent,
97
+ murphyInit
98
+ } from './utils.js';
99
+
100
+ export default function InitMurphy() {
101
+ // Guard: Check if Murphy is enabled
102
+ if (!isMurphyEnabled || !murphySDKUrl) {
103
+ return;
104
+ }
105
+
106
+ let initialDataCheckCount = 0;
107
+ const max_iterations = 100;
108
+
109
+ // Load Murphy SDK and build info in parallel
110
+ Promise.all([
111
+ isDevMode ? Promise.resolve() : fetchReleaseJson(),
112
+ loadResource(murphySDKUrl, 'js', murphyIntegrationName, null, false)
113
+ ]).then(function murphyCb(responseArr) {
114
+ let [releaseJson = {}] = responseArr;
115
+
116
+ try {
117
+ // Prevent infinite loop
118
+ if (initialDataCheckCount >= max_iterations) {
119
+ return;
120
+ }
121
+
122
+ // Wait for desk_urls to be populated
123
+ if (isInitialDataPresent()) {
124
+ murphyInit(releaseJson);
125
+ InitMurphyClientMetrics(releaseJson);
126
+ } else {
127
+ // Retry after 10ms
128
+ setTimeout(() => murphyCb(responseArr), 10);
129
+ }
130
+
131
+ initialDataCheckCount += 1;
132
+ } catch (ex) {
133
+ console.log('Init Murphy Error', ex);
134
+ }
135
+ });
136
+ }
137
+
138
+ // Auto-execute on load
139
+ InitMurphy();
140
+ ```
141
+
142
+ ### 2. initial_html/utils.js - Core Functions
143
+
144
+ ```javascript
145
+ // Path: src/library/murphy/initial_html/utils.js
146
+
147
+ import {
148
+ enableTracking,
149
+ envi,
150
+ maxTrackData,
151
+ pushLogs
152
+ } from './constants';
153
+
154
+ /**
155
+ * Check if desk_urls has Murphy configuration
156
+ */
157
+ export function isInitialDataPresent() {
158
+ return (
159
+ globalThis.desk_urls &&
160
+ typeof globalThis.desk_urls === 'object' &&
161
+ Boolean(Object.keys(getInitialData()).length)
162
+ );
163
+ }
164
+
165
+ /**
166
+ * Extract Murphy config from desk_urls
167
+ */
168
+ function getInitialData() {
169
+ const appDomain = globalThis.desk_urls.murphyAppDomain;
170
+ const appKey = globalThis.desk_urls.murphyAppKey;
171
+ const authKey = globalThis.desk_urls.murphyAuthKey;
172
+ return { appDomain, appKey, authKey };
173
+ }
174
+
175
+ /**
176
+ * Initialize Murphy SDK with configuration
177
+ */
178
+ export function murphyInit(buildInfoJson = {}) {
179
+ const { appDomain, appKey, authKey } = getInitialData();
180
+
181
+ murphy.install({
182
+ config: {
183
+ appKey, // Application identifier
184
+ appDomain, // Murphy server domain
185
+ environment: envi, // Environment (prod/dev)
186
+ pushLogs, // Enable log pushing
187
+ enableTracking, // Enable tracking
188
+ maxTrackData, // Max tracking data size
189
+ authKey, // Authentication key
190
+
191
+ // Rage click detection
192
+ rageClick: {
193
+ enable: true,
194
+ tokenLimit: 5
195
+ },
196
+
197
+ // Rage request detection
198
+ rageRequest: {
199
+ enable: true
200
+ },
201
+
202
+ // User behavior telemetry
203
+ telemetry: {
204
+ enable: true
205
+ }
206
+ },
207
+
208
+ // Tags attached to all errors
209
+ setTags() {
210
+ return {
211
+ buildId: agentClientVersion,
212
+ zuid: userInfo.zuid,
213
+ zgid: currentOrg.id,
214
+ releaseDetails: {
215
+ releaseName: buildInfoJson.BuildLabel,
216
+ releaseRevision: buildInfoJson.Source_Changeset
217
+ }
218
+ };
219
+ }
220
+ });
221
+ }
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Configuration Options
227
+
228
+ ### murphy.install() Config
229
+
230
+ ```
231
+ +-------------------------------------------------------------------+
232
+ | MURPHY.INSTALL() CONFIGURATION OPTIONS |
233
+ +-------------------------------------------------------------------+
234
+ | |
235
+ | Required: |
236
+ | +---------------------------------------------------------------+ |
237
+ | | appKey | Application ID from Murphy dashboard | |
238
+ | | appDomain | Murphy server URL (murphy.zoho.com) | |
239
+ | | authKey | Authentication token | |
240
+ | +---------------------------------------------------------------+ |
241
+ | |
242
+ | Optional: |
243
+ | +---------------------------------------------------------------+ |
244
+ | | environment | 'production' or 'development' | |
245
+ | | pushLogs | Enable sending logs to server (boolean) | |
246
+ | | maxTrackData| Maximum size of tracking data | |
247
+ | +---------------------------------------------------------------+ |
248
+ | |
249
+ | Feature Flags: |
250
+ | +---------------------------------------------------------------+ |
251
+ | | rageClick | { enable: true, tokenLimit: 5 } | |
252
+ | | | Detects frustrated clicking | |
253
+ | +---------------------------------------------------------------+ |
254
+ | | rageRequest | { enable: true } | |
255
+ | | | Detects repeated failed API calls | |
256
+ | +---------------------------------------------------------------+ |
257
+ | | telemetry | { enable: true } | |
258
+ | | | Tracks user behavior patterns | |
259
+ | +---------------------------------------------------------------+ |
260
+ | |
261
+ +-------------------------------------------------------------------+
262
+ ```
263
+
264
+ ### setTags() - Custom Tags
265
+
266
+ ```javascript
267
+ setTags() {
268
+ return {
269
+ // Build identification
270
+ buildId: agentClientVersion, // e.g., "2024.01.15.1"
271
+
272
+ // User identification
273
+ zuid: userInfo.zuid, // Zoho User ID
274
+ zgid: currentOrg.id, // Organization ID
275
+
276
+ // Release information
277
+ releaseDetails: {
278
+ releaseName: buildInfoJson.BuildLabel,
279
+ releaseRevision: buildInfoJson.Source_Changeset
280
+ }
281
+ };
282
+ }
283
+ ```
284
+
285
+ ---
286
+
287
+ ## Client Metrics Installation
288
+
289
+ ```javascript
290
+ /**
291
+ * Install performance monitoring capabilities
292
+ */
293
+ export function installMurphyClientMetrics(buildInfoJson) {
294
+ // Set custom tags for all metrics
295
+ murphy.clientmetrics.setCustomTags({
296
+ buildId: agentClientVersion,
297
+ zuid: userInfo.zuid,
298
+ zgid: currentOrg.id
299
+ });
300
+
301
+ // Set release info for tracking
302
+ murphy.clientmetrics.setUserEnvInfo({
303
+ releaseDetails: {
304
+ buildId: agentClientVersion,
305
+ releaseName: buildInfoJson.BuildLabel,
306
+ releaseRevision: buildInfoJson.Source_Changeset
307
+ }
308
+ });
309
+
310
+ // Configure and install
311
+ let config = murphy.sendUserInfo();
312
+ config.isMonitoringEnabled = isMonitoringEnabled();
313
+ config.clientmetricsWorkerUrl = getWorkerObjectUrl();
314
+ config.isTimeToInteractiveEnabled = true;
315
+ config.isClientMetricsSoftNavigationEnabled = true;
316
+ config.isInterruptionMonitoringEnabled = true;
317
+
318
+ murphy.clientmetrics.install(config);
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ ## Retry Mechanism
325
+
326
+ The initialization includes a retry mechanism to handle race conditions:
327
+
328
+ ```
329
+ +-------------------------------------------------------------------+
330
+ | RETRY MECHANISM |
331
+ +-------------------------------------------------------------------+
332
+ | |
333
+ | Problem: desk_urls may not be populated when InitMurphy runs |
334
+ | |
335
+ | Solution: |
336
+ | |
337
+ | +------------------+ No +------------------------+ |
338
+ | | isInitialData | ----------> | Wait 10ms | |
339
+ | | Present()? | | Increment counter | |
340
+ | +------------------+ | Retry (max 100 times) | |
341
+ | | +------------------------+ |
342
+ | | Yes | |
343
+ | v | |
344
+ | +------------------+ | |
345
+ | | murphyInit() | | |
346
+ | | Initialize SDK | <----------------------+ |
347
+ | +------------------+ |
348
+ | |
349
+ | Max Wait Time: 100 * 10ms = 1 second |
350
+ | |
351
+ +-------------------------------------------------------------------+
352
+ ```
353
+
354
+ ---
355
+
356
+ ## SDK Loading
357
+
358
+ ### CDN URL Pattern
359
+
360
+ ```javascript
361
+ // URL is constructed dynamically based on datacenter
362
+ const murphySDKUrl = `${desk_urls.staticDomain}/murphysdk/3.0.0/murphy.min.js`;
363
+
364
+ // Examples:
365
+ // US: https://static.zohocdn.com/murphysdk/3.0.0/murphy.min.js
366
+ // EU: https://static.zohocdn.eu/murphysdk/3.0.0/murphy.min.js
367
+ // IN: https://static.zohocdn.in/murphysdk/3.0.0/murphy.min.js
368
+ ```
369
+
370
+ ### loadResource() Utility
371
+
372
+ ```javascript
373
+ // Loads JavaScript file from CDN
374
+ loadResource(murphySDKUrl, 'js', murphyIntegrationName, null, false);
375
+ ```
376
+
377
+ ---
378
+
379
+ ## Global Murphy Object
380
+
381
+ After initialization, the global `murphy` object is available:
382
+
383
+ ```javascript
384
+ // Check if Murphy is available
385
+ if (typeof murphy !== 'undefined') {
386
+ // Error tracking
387
+ murphy.error(error, undefined, { customTags: {...} });
388
+
389
+ // Application logging
390
+ murphy.appLog('INFO', 'User action completed', { userId: 123 });
391
+
392
+ // Custom tracking
393
+ murphy.addCustomTracking({ event: 'feature_used' });
394
+
395
+ // Performance metrics
396
+ murphy.clientmetrics.setTimeToInteractive();
397
+ murphy.clientmetrics.startSoftNavigation({ from_url, to_url });
398
+ murphy.clientmetrics.endSoftNavigation();
399
+ }
400
+ ```
401
+
402
+ ---
403
+
404
+ ## Summary
405
+
406
+ ```
407
+ +-------------------------------------------------------------------+
408
+ | FRONTEND INIT SUMMARY |
409
+ +-------------------------------------------------------------------+
410
+ | |
411
+ | Entry Point: InitMurphy() |
412
+ | +-- Loads SDK from CDN |
413
+ | +-- Waits for desk_urls |
414
+ | +-- Initializes with murphyInit() |
415
+ | |
416
+ | Configuration Source: globalThis.desk_urls |
417
+ | +-- murphyAppKey |
418
+ | +-- murphyAppDomain |
419
+ | +-- murphyAuthKey |
420
+ | |
421
+ | Result: Global murphy object with: |
422
+ | +-- murphy.error() -> Error tracking |
423
+ | +-- murphy.appLog() -> Application logs |
424
+ | +-- murphy.addCustomTracking() -> Custom events |
425
+ | +-- murphy.clientmetrics -> Performance monitoring |
426
+ | +-- murphy.telemetry -> User behavior |
427
+ | |
428
+ +-------------------------------------------------------------------+
429
+ ```
430
+
431
+ ---
432
+
433
+ ## Related Documents
434
+
435
+ - [02-MURPHY_ARCHITECTURE.md](./02-MURPHY_ARCHITECTURE.md) - Full architecture
436
+ - [03-MURPHY_BACKEND_CONFIG.md](./03-MURPHY_BACKEND_CONFIG.md) - Backend configuration
437
+ - [05-MURPHY_DESK_CLIENT_USAGE.md](./05-MURPHY_DESK_CLIENT_USAGE.md) - Usage in desk client