@zohodesk/i18n 1.0.0-beta.36-murphy → 1.0.0-beta.38-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.
package/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { formatDate, pad, replaceI18NValuesWithRegex, unescapeUnicode, getValues, getI18NInfo, isToday, isYesterday, isTomorrow, isWithinAWeek, isTwoWeeksOrMore, userDateFormat, getDiffObj, getLyears, getSuffix, getDatePatternWithoutYear, setLocalizedData, setI18NKeyMapping, dayi18n, monthi18n, timei18n } from "./utils";
2
- export { reportI18NError, clearReportedKeys, I18N_ERROR_TYPES } from "./utils/errorReporter";
2
+ export { reportI18NError, flushI18NErrors, clearReportedKeys, I18N_ERROR_TYPES } from "./utils/errorReporter";
3
3
  import { getI18NValue as getI18NValue1 } from "./utils";
4
4
  export { I18NContext } from "./I18NContext";
5
5
  export { default as I18NProvider, i18NProviderUtils } from "./components/I18NProvider";
@@ -4,30 +4,135 @@ export const I18N_ERROR_TYPES = {
4
4
  NUMERIC_FALLBACK: 'I18N_NUMERIC_FALLBACK'
5
5
  };
6
6
  const reportedKeys = new Set();
7
+ const pendingErrors = new Map();
8
+ const MAX_PENDING_ERRORS = 100;
7
9
  function isMurphyAvailable() {
8
10
  return typeof murphy !== 'undefined' && typeof murphy.error === 'function';
9
11
  }
12
+ function isDebugEnabled() {
13
+ return typeof window !== 'undefined' && window.__I18N_DEBUG__ === true;
14
+ }
15
+ function debugLog(message, meta) {
16
+ if (!isDebugEnabled() || typeof console === 'undefined') {
17
+ return;
18
+ }
19
+ if (typeof console.log !== 'function') {
20
+ return;
21
+ }
22
+ if (typeof meta === 'undefined') {
23
+ console.log(`[i18n] ${message}`);
24
+ } else {
25
+ console.log(`[i18n] ${message}`, meta);
26
+ }
27
+ }
28
+ function sendToMurphy(type, key) {
29
+ debugLog('reporting i18n error', {
30
+ type,
31
+ key
32
+ });
33
+ const error = new Error(`i18n ${type}: ${key}`);
34
+ error.name = type;
35
+ murphy.error(error, undefined, {
36
+ customTags: {
37
+ errorType: type,
38
+ i18nKey: key,
39
+ category: 'i18n'
40
+ },
41
+ preventClientGrouping: true
42
+ });
43
+ }
44
+ function queuePendingError(dedupeKey, type, key) {
45
+ if (pendingErrors.has(dedupeKey)) {
46
+ debugLog('pending i18n error deduped', {
47
+ type,
48
+ key
49
+ });
50
+ return;
51
+ }
52
+ if (pendingErrors.size >= MAX_PENDING_ERRORS) {
53
+ const oldestKey = pendingErrors.keys().next().value;
54
+ pendingErrors.delete(oldestKey);
55
+ debugLog('pending i18n error dropped (queue full)', {
56
+ droppedKey: oldestKey,
57
+ pendingSize: pendingErrors.size
58
+ });
59
+ }
60
+ pendingErrors.set(dedupeKey, {
61
+ type,
62
+ key
63
+ });
64
+ debugLog('queued i18n error (murphy not ready)', {
65
+ type,
66
+ key,
67
+ pendingSize: pendingErrors.size
68
+ });
69
+ }
70
+ export function flushI18NErrors() {
71
+ if (!isMurphyAvailable()) {
72
+ debugLog('flush skipped (murphy not available)', {
73
+ pendingSize: pendingErrors.size
74
+ });
75
+ return;
76
+ }
77
+ if (pendingErrors.size === 0) {
78
+ debugLog('flush skipped (no pending errors)');
79
+ return;
80
+ }
81
+ debugLog('flushing pending i18n errors', {
82
+ pendingSize: pendingErrors.size
83
+ });
84
+ let flushedCount = 0;
85
+ for (const [dedupeKey, data] of pendingErrors) {
86
+ if (reportedKeys.has(dedupeKey)) {
87
+ pendingErrors.delete(dedupeKey);
88
+ continue;
89
+ }
90
+ sendToMurphy(data.type, data.key);
91
+ reportedKeys.add(dedupeKey);
92
+ pendingErrors.delete(dedupeKey);
93
+ flushedCount += 1;
94
+ }
95
+ debugLog('flush complete', {
96
+ flushedCount,
97
+ pendingRemaining: pendingErrors.size
98
+ });
99
+ }
10
100
  export function reportI18NError(type, key) {
101
+ debugLog('reportI18NError called', {
102
+ type,
103
+ key
104
+ });
11
105
  const dedupeKey = `${type}:${key}`;
12
106
  if (reportedKeys.has(dedupeKey)) {
107
+ debugLog('reported i18n error deduped', {
108
+ type,
109
+ key
110
+ });
13
111
  return;
14
112
  }
15
- reportedKeys.add(dedupeKey);
16
- if (isMurphyAvailable()) {
17
- const error = new Error(`i18n ${type}: ${key}`);
18
- error.name = type;
19
- murphy.error(error, undefined, {
20
- customTags: {
21
- errorType: type,
22
- i18nKey: key,
23
- category: 'i18n'
24
- },
25
- preventClientGrouping: true
113
+ if (!isMurphyAvailable()) {
114
+ debugLog('murphy not available, queueing i18n error', {
115
+ type,
116
+ key
26
117
  });
118
+ queuePendingError(dedupeKey, type, key);
119
+ return;
27
120
  }
121
+ flushI18NErrors();
122
+ if (reportedKeys.has(dedupeKey)) {
123
+ debugLog('reported i18n error deduped after flush', {
124
+ type,
125
+ key
126
+ });
127
+ return;
128
+ }
129
+ sendToMurphy(type, key);
130
+ reportedKeys.add(dedupeKey);
28
131
  }
29
132
  export function clearReportedKeys() {
30
133
  reportedKeys.clear();
134
+ pendingErrors.clear();
135
+ debugLog('cleared reported and pending i18n errors');
31
136
  }
32
137
  export function getFallbackText(key) {
33
138
  const isNumeric = /^\d+$/.test(key);
package/lib/index.js CHANGED
@@ -70,6 +70,12 @@ Object.defineProperty(exports, "dayi18n", {
70
70
  return _utils.dayi18n;
71
71
  }
72
72
  });
73
+ Object.defineProperty(exports, "flushI18NErrors", {
74
+ enumerable: true,
75
+ get: function get() {
76
+ return _errorReporter.flushI18NErrors;
77
+ }
78
+ });
73
79
  Object.defineProperty(exports, "formatDate", {
74
80
  enumerable: true,
75
81
  get: function get() {
@@ -5,38 +5,162 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.I18N_ERROR_TYPES = void 0;
7
7
  exports.clearReportedKeys = clearReportedKeys;
8
+ exports.flushI18NErrors = flushI18NErrors;
8
9
  exports.getFallbackText = getFallbackText;
9
10
  exports.reportI18NError = reportI18NError;
11
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
12
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
14
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
15
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
16
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
17
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
18
  var I18N_ERROR_TYPES = exports.I18N_ERROR_TYPES = {
11
19
  UNDEFINED_OBJECT: 'I18N_UNDEFINED_OBJECT',
12
20
  MISSING_KEY: 'I18N_MISSING_KEY',
13
21
  NUMERIC_FALLBACK: 'I18N_NUMERIC_FALLBACK'
14
22
  };
15
23
  var reportedKeys = new Set();
24
+ var pendingErrors = new Map();
25
+ var MAX_PENDING_ERRORS = 100;
16
26
  function isMurphyAvailable() {
17
27
  return typeof murphy !== 'undefined' && typeof murphy.error === 'function';
18
28
  }
29
+ function isDebugEnabled() {
30
+ return typeof window !== 'undefined' && window.__I18N_DEBUG__ === true;
31
+ }
32
+ function debugLog(message, meta) {
33
+ if (!isDebugEnabled() || typeof console === 'undefined') {
34
+ return;
35
+ }
36
+ if (typeof console.log !== 'function') {
37
+ return;
38
+ }
39
+ if (typeof meta === 'undefined') {
40
+ console.log("[i18n] ".concat(message));
41
+ } else {
42
+ console.log("[i18n] ".concat(message), meta);
43
+ }
44
+ }
45
+ function sendToMurphy(type, key) {
46
+ debugLog('reporting i18n error', {
47
+ type: type,
48
+ key: key
49
+ });
50
+ var error = new Error("i18n ".concat(type, ": ").concat(key));
51
+ error.name = type;
52
+ murphy.error(error, undefined, {
53
+ customTags: {
54
+ errorType: type,
55
+ i18nKey: key,
56
+ category: 'i18n'
57
+ },
58
+ preventClientGrouping: true
59
+ });
60
+ }
61
+ function queuePendingError(dedupeKey, type, key) {
62
+ if (pendingErrors.has(dedupeKey)) {
63
+ debugLog('pending i18n error deduped', {
64
+ type: type,
65
+ key: key
66
+ });
67
+ return;
68
+ }
69
+ if (pendingErrors.size >= MAX_PENDING_ERRORS) {
70
+ var oldestKey = pendingErrors.keys().next().value;
71
+ pendingErrors["delete"](oldestKey);
72
+ debugLog('pending i18n error dropped (queue full)', {
73
+ droppedKey: oldestKey,
74
+ pendingSize: pendingErrors.size
75
+ });
76
+ }
77
+ pendingErrors.set(dedupeKey, {
78
+ type: type,
79
+ key: key
80
+ });
81
+ debugLog('queued i18n error (murphy not ready)', {
82
+ type: type,
83
+ key: key,
84
+ pendingSize: pendingErrors.size
85
+ });
86
+ }
87
+ function flushI18NErrors() {
88
+ if (!isMurphyAvailable()) {
89
+ debugLog('flush skipped (murphy not available)', {
90
+ pendingSize: pendingErrors.size
91
+ });
92
+ return;
93
+ }
94
+ if (pendingErrors.size === 0) {
95
+ debugLog('flush skipped (no pending errors)');
96
+ return;
97
+ }
98
+ debugLog('flushing pending i18n errors', {
99
+ pendingSize: pendingErrors.size
100
+ });
101
+ var flushedCount = 0;
102
+ var _iterator = _createForOfIteratorHelper(pendingErrors),
103
+ _step;
104
+ try {
105
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
106
+ var _step$value = _slicedToArray(_step.value, 2),
107
+ dedupeKey = _step$value[0],
108
+ data = _step$value[1];
109
+ if (reportedKeys.has(dedupeKey)) {
110
+ pendingErrors["delete"](dedupeKey);
111
+ continue;
112
+ }
113
+ sendToMurphy(data.type, data.key);
114
+ reportedKeys.add(dedupeKey);
115
+ pendingErrors["delete"](dedupeKey);
116
+ flushedCount += 1;
117
+ }
118
+ } catch (err) {
119
+ _iterator.e(err);
120
+ } finally {
121
+ _iterator.f();
122
+ }
123
+ debugLog('flush complete', {
124
+ flushedCount: flushedCount,
125
+ pendingRemaining: pendingErrors.size
126
+ });
127
+ }
19
128
  function reportI18NError(type, key) {
129
+ debugLog('reportI18NError called', {
130
+ type: type,
131
+ key: key
132
+ });
20
133
  var dedupeKey = "".concat(type, ":").concat(key);
21
134
  if (reportedKeys.has(dedupeKey)) {
135
+ debugLog('reported i18n error deduped', {
136
+ type: type,
137
+ key: key
138
+ });
22
139
  return;
23
140
  }
24
- reportedKeys.add(dedupeKey);
25
- if (isMurphyAvailable()) {
26
- var error = new Error("i18n ".concat(type, ": ").concat(key));
27
- error.name = type;
28
- murphy.error(error, undefined, {
29
- customTags: {
30
- errorType: type,
31
- i18nKey: key,
32
- category: 'i18n'
33
- },
34
- preventClientGrouping: true
141
+ if (!isMurphyAvailable()) {
142
+ debugLog('murphy not available, queueing i18n error', {
143
+ type: type,
144
+ key: key
35
145
  });
146
+ queuePendingError(dedupeKey, type, key);
147
+ return;
36
148
  }
149
+ flushI18NErrors();
150
+ if (reportedKeys.has(dedupeKey)) {
151
+ debugLog('reported i18n error deduped after flush', {
152
+ type: type,
153
+ key: key
154
+ });
155
+ return;
156
+ }
157
+ sendToMurphy(type, key);
158
+ reportedKeys.add(dedupeKey);
37
159
  }
38
160
  function clearReportedKeys() {
39
161
  reportedKeys.clear();
162
+ pendingErrors.clear();
163
+ debugLog('cleared reported and pending i18n errors');
40
164
  }
41
165
  function getFallbackText(key) {
42
166
  var isNumeric = /^\d+$/.test(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/i18n",
3
- "version": "1.0.0-beta.36-murphy",
3
+ "version": "1.0.0-beta.38-murphy",
4
4
  "main": "lib/index",
5
5
  "module": "es/index.js",
6
6
  "jsnext:main": "es/index.js",
package/src/index.js CHANGED
@@ -23,6 +23,7 @@ export {
23
23
  } from './utils';
24
24
  export {
25
25
  reportI18NError,
26
+ flushI18NErrors,
26
27
  clearReportedKeys,
27
28
  I18N_ERROR_TYPES
28
29
  } from './utils/errorReporter';
@@ -5,34 +5,131 @@ export const I18N_ERROR_TYPES = {
5
5
  };
6
6
 
7
7
  const reportedKeys = new Set();
8
+ const pendingErrors = new Map();
9
+ const MAX_PENDING_ERRORS = 100;
8
10
 
9
11
  function isMurphyAvailable() {
10
12
  return typeof murphy !== 'undefined' && typeof murphy.error === 'function';
11
13
  }
12
14
 
15
+ function isDebugEnabled() {
16
+ return typeof window !== 'undefined' && window.__I18N_DEBUG__ === true;
17
+ }
18
+
19
+ function debugLog(message, meta) {
20
+ if (!isDebugEnabled() || typeof console === 'undefined') {
21
+ return;
22
+ }
23
+ if (typeof console.log !== 'function') {
24
+ return;
25
+ }
26
+ if (typeof meta === 'undefined') {
27
+ console.log(`[i18n] ${message}`);
28
+ } else {
29
+ console.log(`[i18n] ${message}`, meta);
30
+ }
31
+ }
32
+
33
+ function sendToMurphy(type, key) {
34
+ debugLog('reporting i18n error', { type, key });
35
+ const error = new Error(`i18n ${type}: ${key}`);
36
+ error.name = type;
37
+
38
+ murphy.error(error, undefined, {
39
+ customTags: {
40
+ errorType: type,
41
+ i18nKey: key,
42
+ category: 'i18n'
43
+ },
44
+ preventClientGrouping: true
45
+ });
46
+ }
47
+
48
+ function queuePendingError(dedupeKey, type, key) {
49
+ if (pendingErrors.has(dedupeKey)) {
50
+ debugLog('pending i18n error deduped', { type, key });
51
+ return;
52
+ }
53
+
54
+ if (pendingErrors.size >= MAX_PENDING_ERRORS) {
55
+ const oldestKey = pendingErrors.keys().next().value;
56
+ pendingErrors.delete(oldestKey);
57
+ debugLog('pending i18n error dropped (queue full)', {
58
+ droppedKey: oldestKey,
59
+ pendingSize: pendingErrors.size
60
+ });
61
+ }
62
+
63
+ pendingErrors.set(dedupeKey, { type, key });
64
+ debugLog('queued i18n error (murphy not ready)', {
65
+ type,
66
+ key,
67
+ pendingSize: pendingErrors.size
68
+ });
69
+ }
70
+
71
+ export function flushI18NErrors() {
72
+ if (!isMurphyAvailable()) {
73
+ debugLog('flush skipped (murphy not available)', {
74
+ pendingSize: pendingErrors.size
75
+ });
76
+ return;
77
+ }
78
+
79
+ if (pendingErrors.size === 0) {
80
+ debugLog('flush skipped (no pending errors)');
81
+ return;
82
+ }
83
+
84
+ debugLog('flushing pending i18n errors', {
85
+ pendingSize: pendingErrors.size
86
+ });
87
+
88
+ let flushedCount = 0;
89
+ for (const [dedupeKey, data] of pendingErrors) {
90
+ if (reportedKeys.has(dedupeKey)) {
91
+ pendingErrors.delete(dedupeKey);
92
+ continue;
93
+ }
94
+ sendToMurphy(data.type, data.key);
95
+ reportedKeys.add(dedupeKey);
96
+ pendingErrors.delete(dedupeKey);
97
+ flushedCount += 1;
98
+ }
99
+
100
+ debugLog('flush complete', {
101
+ flushedCount,
102
+ pendingRemaining: pendingErrors.size
103
+ });
104
+ }
105
+
13
106
  export function reportI18NError(type, key) {
107
+ debugLog('reportI18NError called', { type, key });
14
108
  const dedupeKey = `${type}:${key}`;
15
109
  if (reportedKeys.has(dedupeKey)) {
110
+ debugLog('reported i18n error deduped', { type, key });
16
111
  return;
17
112
  }
18
- reportedKeys.add(dedupeKey);
19
113
 
20
- if (isMurphyAvailable()) {
21
- const error = new Error(`i18n ${type}: ${key}`);
22
- error.name = type;
23
-
24
- murphy.error(error, undefined, {
25
- customTags: {
26
- errorType: type,
27
- i18nKey: key,
28
- category: 'i18n'
29
- },
30
- preventClientGrouping: true
31
- });
114
+ if (!isMurphyAvailable()) {
115
+ debugLog('murphy not available, queueing i18n error', { type, key });
116
+ queuePendingError(dedupeKey, type, key);
117
+ return;
118
+ }
119
+
120
+ flushI18NErrors();
121
+ if (reportedKeys.has(dedupeKey)) {
122
+ debugLog('reported i18n error deduped after flush', { type, key });
123
+ return;
32
124
  }
125
+
126
+ sendToMurphy(type, key);
127
+ reportedKeys.add(dedupeKey);
33
128
  }
34
129
  export function clearReportedKeys() {
35
130
  reportedKeys.clear();
131
+ pendingErrors.clear();
132
+ debugLog('cleared reported and pending i18n errors');
36
133
  }
37
134
 
38
135
  export function getFallbackText(key) {