@tern-secure/shared 1.2.0 → 1.2.1

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 (129) hide show
  1. package/dist/browser.d.mts +28 -0
  2. package/dist/browser.d.ts +28 -0
  3. package/dist/browser.js +95 -0
  4. package/dist/browser.js.map +1 -0
  5. package/dist/browser.mjs +66 -0
  6. package/dist/browser.mjs.map +1 -0
  7. package/dist/chunk-2UQ43P4P.mjs +45 -0
  8. package/dist/chunk-2UQ43P4P.mjs.map +1 -0
  9. package/dist/{chunk-HATJQ74R.mjs → chunk-33U3M4YY.mjs} +2 -2
  10. package/dist/chunk-33U3M4YY.mjs.map +1 -0
  11. package/dist/chunk-CGGW4CI3.mjs +265 -0
  12. package/dist/chunk-CGGW4CI3.mjs.map +1 -0
  13. package/dist/{chunk-XCVOYULH.mjs → chunk-PHCVLVZY.mjs} +2 -2
  14. package/dist/{chunk-XCVOYULH.mjs.map → chunk-PHCVLVZY.mjs.map} +1 -1
  15. package/dist/cookie.d.mts +4 -1
  16. package/dist/cookie.d.ts +4 -1
  17. package/dist/cookie.js +35 -2
  18. package/dist/cookie.js.map +1 -1
  19. package/dist/cookie.mjs +33 -1
  20. package/dist/cookie.mjs.map +1 -1
  21. package/dist/derivedAuthState.d.mts +13 -7
  22. package/dist/derivedAuthState.d.ts +13 -7
  23. package/dist/derivedAuthState.js +22 -34
  24. package/dist/derivedAuthState.js.map +1 -1
  25. package/dist/derivedAuthState.mjs +22 -33
  26. package/dist/derivedAuthState.mjs.map +1 -1
  27. package/dist/errors-api.d.mts +49 -0
  28. package/dist/errors-api.d.ts +49 -0
  29. package/dist/errors-api.js +124 -0
  30. package/dist/errors-api.js.map +1 -0
  31. package/dist/errors-api.mjs +91 -0
  32. package/dist/errors-api.mjs.map +1 -0
  33. package/dist/errors.d.mts +17 -0
  34. package/dist/errors.d.ts +17 -0
  35. package/dist/errors.js +139 -0
  36. package/dist/errors.js.map +1 -0
  37. package/dist/errors.mjs +111 -0
  38. package/dist/errors.mjs.map +1 -0
  39. package/dist/eventBus.d.mts +28 -7
  40. package/dist/eventBus.d.ts +28 -7
  41. package/dist/eventBus.js +36 -21
  42. package/dist/eventBus.js.map +1 -1
  43. package/dist/eventBus.mjs +4 -26
  44. package/dist/eventBus.mjs.map +1 -1
  45. package/dist/{types/eventBus.d.ts → eventEmitter.d.mts} +4 -2
  46. package/dist/eventEmitter.d.ts +9 -0
  47. package/dist/eventEmitter.js +57 -0
  48. package/dist/eventEmitter.js.map +1 -0
  49. package/dist/eventEmitter.mjs +32 -0
  50. package/dist/eventEmitter.mjs.map +1 -0
  51. package/dist/loadScript.js +1 -1
  52. package/dist/loadScript.js.map +1 -1
  53. package/dist/loadScript.mjs +1 -1
  54. package/dist/loadTernUIScript.js +5 -3
  55. package/dist/loadTernUIScript.js.map +1 -1
  56. package/dist/loadTernUIScript.mjs +7 -5
  57. package/dist/loadTernUIScript.mjs.map +1 -1
  58. package/dist/pathMatcher.d.mts +14 -0
  59. package/dist/pathMatcher.d.ts +14 -0
  60. package/dist/pathMatcher.js +263 -0
  61. package/dist/pathMatcher.js.map +1 -0
  62. package/dist/pathMatcher.mjs +17 -0
  63. package/dist/pathMatcher.mjs.map +1 -0
  64. package/dist/pathToRegexp.d.mts +81 -0
  65. package/dist/pathToRegexp.d.ts +81 -0
  66. package/dist/pathToRegexp.js +292 -0
  67. package/dist/pathToRegexp.js.map +1 -0
  68. package/dist/pathToRegexp.mjs +9 -0
  69. package/dist/pathToRegexp.mjs.map +1 -0
  70. package/dist/react/index.d.mts +8 -2
  71. package/dist/react/index.d.ts +8 -2
  72. package/dist/react/index.js +28 -2
  73. package/dist/react/index.js.map +1 -1
  74. package/dist/react/index.mjs +25 -2
  75. package/dist/react/index.mjs.map +1 -1
  76. package/dist/resolveVersion.js +1 -1
  77. package/dist/resolveVersion.js.map +1 -1
  78. package/dist/resolveVersion.mjs +1 -1
  79. package/dist/serviceWorker.js +1 -1
  80. package/dist/serviceWorker.js.map +1 -1
  81. package/dist/serviceWorker.mjs +1 -1
  82. package/dist/serviceWorker.mjs.map +1 -1
  83. package/dist/ternStatusEvent.d.mts +15 -0
  84. package/dist/ternStatusEvent.d.ts +15 -0
  85. package/dist/ternStatusEvent.js +81 -0
  86. package/dist/ternStatusEvent.js.map +1 -0
  87. package/dist/ternStatusEvent.mjs +16 -0
  88. package/dist/ternStatusEvent.mjs.map +1 -0
  89. package/dist/url.d.mts +3 -0
  90. package/dist/url.d.ts +3 -0
  91. package/dist/url.js +33 -0
  92. package/dist/url.js.map +1 -0
  93. package/dist/url.mjs +8 -0
  94. package/dist/url.mjs.map +1 -0
  95. package/dist/utils/index.d.mts +5 -0
  96. package/dist/utils/index.d.ts +5 -0
  97. package/dist/utils/index.js +44 -0
  98. package/dist/utils/index.js.map +1 -0
  99. package/dist/utils/index.mjs +17 -0
  100. package/dist/utils/index.mjs.map +1 -0
  101. package/package.json +22 -6
  102. package/dist/chunk-HATJQ74R.mjs.map +0 -1
  103. package/dist/types/cookie.d.ts +0 -12
  104. package/dist/types/cookie.d.ts.map +0 -1
  105. package/dist/types/derivedAuthState.d.ts +0 -7
  106. package/dist/types/derivedAuthState.d.ts.map +0 -1
  107. package/dist/types/eventBus.d.ts.map +0 -1
  108. package/dist/types/loadScript.d.ts +0 -10
  109. package/dist/types/loadScript.d.ts.map +0 -1
  110. package/dist/types/loadTernUIScript.d.ts +0 -20
  111. package/dist/types/loadTernUIScript.d.ts.map +0 -1
  112. package/dist/types/nextjs/client/auth-actions.d.ts +0 -1
  113. package/dist/types/nextjs/client/auth-actions.d.ts.map +0 -1
  114. package/dist/types/react/hooks/index.d.ts +0 -2
  115. package/dist/types/react/hooks/index.d.ts.map +0 -1
  116. package/dist/types/react/hooks/useTernSecure.d.ts +0 -3
  117. package/dist/types/react/hooks/useTernSecure.d.ts.map +0 -1
  118. package/dist/types/react/index.d.ts +0 -4
  119. package/dist/types/react/index.d.ts.map +0 -1
  120. package/dist/types/react/ternsecureCtx.d.ts +0 -26
  121. package/dist/types/react/ternsecureCtx.d.ts.map +0 -1
  122. package/dist/types/react/ternsecureProvider.d.ts +0 -20
  123. package/dist/types/react/ternsecureProvider.d.ts.map +0 -1
  124. package/dist/types/resolveVersion.d.ts +0 -2
  125. package/dist/types/resolveVersion.d.ts.map +0 -1
  126. package/dist/types/retry.d.ts +0 -46
  127. package/dist/types/retry.d.ts.map +0 -1
  128. package/dist/types/serviceWorker.d.ts +0 -12
  129. package/dist/types/serviceWorker.d.ts.map +0 -1
@@ -0,0 +1,91 @@
1
+ // src/errors-api.ts
2
+ function isUnauthorizedError(e) {
3
+ var _a, _b;
4
+ const status = e == null ? void 0 : e.status;
5
+ const code = (_b = (_a = e == null ? void 0 : e.errors) == null ? void 0 : _a[0]) == null ? void 0 : _b.code;
6
+ return code === "authentication_invalid" && status === 401;
7
+ }
8
+ function isCaptchaError(e) {
9
+ return ["captcha_invalid", "captcha_not_enabled", "captcha_missing_token"].includes(e.errors[0].code);
10
+ }
11
+ function is4xxError(e) {
12
+ const status = e == null ? void 0 : e.status;
13
+ return !!status && status >= 400 && status < 500;
14
+ }
15
+ function isNetworkError(e) {
16
+ const message = (`${e.message}${e.name}` || "").toLowerCase().replace(/\s+/g, "");
17
+ return message.includes("networkerror");
18
+ }
19
+ function parseErrors(data = []) {
20
+ return data.length > 0 ? data.map(parseError) : [];
21
+ }
22
+ function parseError(error) {
23
+ return {
24
+ code: error.code,
25
+ message: error.message
26
+ };
27
+ }
28
+ function errorToJSON(error) {
29
+ return {
30
+ code: (error == null ? void 0 : error.code) || "",
31
+ message: (error == null ? void 0 : error.message) || ""
32
+ };
33
+ }
34
+ var TernSecureAPIResponseError = class _TernSecureAPIResponseError extends Error {
35
+ constructor(message, { data, status, retryAfter }) {
36
+ super(message);
37
+ this.toString = () => {
38
+ const message = `[${this.name}]
39
+ Message:${this.message}
40
+ Status:${this.status}
41
+ Serialized errors: ${this.errors.map(
42
+ (e) => JSON.stringify(e)
43
+ )}`;
44
+ return message;
45
+ };
46
+ Object.setPrototypeOf(this, _TernSecureAPIResponseError.prototype);
47
+ this.status = status;
48
+ this.message = message;
49
+ this.retryAfter = retryAfter;
50
+ this.ternSecureError = true;
51
+ this.errors = parseErrors(data);
52
+ }
53
+ };
54
+ var TernSecureRuntimeError = class _TernSecureRuntimeError extends Error {
55
+ constructor(message, { code }) {
56
+ const prefix = "\u{1F512} TernSecure:";
57
+ const regex = new RegExp(prefix.replace(" ", "\\s*"), "i");
58
+ const sanitized = message.replace(regex, "");
59
+ const _message = `${prefix} ${sanitized.trim()}
60
+
61
+ (code="${code}")
62
+ `;
63
+ super(_message);
64
+ /**
65
+ * Returns a string representation of the error.
66
+ *
67
+ * @returns {string} A formatted string with the error name and message.
68
+ */
69
+ this.toString = () => {
70
+ return `[${this.name}]
71
+ Message:${this.message}`;
72
+ };
73
+ Object.setPrototypeOf(this, _TernSecureRuntimeError.prototype);
74
+ this.code = code;
75
+ this.message = _message;
76
+ this.ternSecureRuntimeError = true;
77
+ this.name = "TernSecureRuntimeError";
78
+ }
79
+ };
80
+ export {
81
+ TernSecureAPIResponseError,
82
+ TernSecureRuntimeError,
83
+ errorToJSON,
84
+ is4xxError,
85
+ isCaptchaError,
86
+ isNetworkError,
87
+ isUnauthorizedError,
88
+ parseError,
89
+ parseErrors
90
+ };
91
+ //# sourceMappingURL=errors-api.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors-api.ts"],"sourcesContent":["import type { TernSecureAPIError, TernSecureApiErrorJSON} from \"@tern-secure/types\";\n\nexport function isUnauthorizedError(e: any): boolean {\n const status = e?.status;\n const code = e?.errors?.[0]?.code;\n return code === 'authentication_invalid' && status === 401;\n}\n\nexport function isCaptchaError(e: TernSecureAPIResponseError): boolean {\n return ['captcha_invalid', 'captcha_not_enabled', 'captcha_missing_token'].includes(e.errors[0].code);\n}\n\nexport function is4xxError(e: any): boolean {\n const status = e?.status;\n return !!status && status >= 400 && status < 500;\n}\n\nexport function isNetworkError(e: any): boolean {\n // TODO: revise during error handling epic\n const message = (`${e.message}${e.name}` || '').toLowerCase().replace(/\\s+/g, '');\n return message.includes('networkerror');\n}\n\nexport function parseErrors(data: TernSecureApiErrorJSON[] = []): TernSecureAPIError[] {\n return data.length > 0 ? data.map(parseError) : [];\n}\n\n\nexport function parseError(error: TernSecureApiErrorJSON): TernSecureAPIError {\n return {\n code: error.code,\n message: error.message,\n };\n}\n\nexport function errorToJSON(error: TernSecureAPIError | null): TernSecureApiErrorJSON {\n return {\n code: error?.code || '',\n message: error?.message || '',\n };\n}\n\ninterface TernSecureAPIResponseOptions {\n data: TernSecureApiErrorJSON[];\n status: number;\n retryAfter?: number;\n}\n\n\n\nexport class TernSecureAPIResponseError extends Error {\n ternSecureError: true;\n\n status: number;\n message: string;\n retryAfter?: number;\n\n errors: TernSecureAPIError[];\n\n constructor(message: string, { data, status, retryAfter }: TernSecureAPIResponseOptions) {\n super(message);\n\n Object.setPrototypeOf(this, TernSecureAPIResponseError.prototype);\n\n this.status = status;\n this.message = message;\n this.retryAfter = retryAfter;\n this.ternSecureError = true;\n this.errors = parseErrors(data);\n }\n\n public toString = () => {\n const message = `[${this.name}]\\nMessage:${this.message}\\nStatus:${this.status}\\nSerialized errors: ${this.errors.map(\n e => JSON.stringify(e),\n )}`;\n\n return message;\n };\n}\n\n\n\nexport class TernSecureRuntimeError extends Error {\n ternSecureRuntimeError: true;\n\n /**\n * The error message.\n *\n * @type {string}\n */\n message: string;\n\n /**\n * A unique code identifying the error, can be used for localization.\n *\n * @type {string}\n */\n code: string;\n\n constructor(message: string, { code }: { code: string }) {\n const prefix = '🔒 TernSecure:';\n const regex = new RegExp(prefix.replace(' ', '\\\\s*'), 'i');\n const sanitized = message.replace(regex, '');\n const _message = `${prefix} ${sanitized.trim()}\\n\\n(code=\"${code}\")\\n`;\n super(_message);\n\n Object.setPrototypeOf(this, TernSecureRuntimeError.prototype);\n\n this.code = code;\n this.message = _message;\n this.ternSecureRuntimeError = true;\n this.name = 'TernSecureRuntimeError';\n }\n\n /**\n * Returns a string representation of the error.\n *\n * @returns {string} A formatted string with the error name and message.\n */\n public toString = () => {\n return `[${this.name}]\\nMessage:${this.message}`;\n };\n}"],"mappings":";AAEO,SAAS,oBAAoB,GAAiB;AAFrD;AAGE,QAAM,SAAS,uBAAG;AAClB,QAAM,QAAO,kCAAG,WAAH,mBAAY,OAAZ,mBAAgB;AAC7B,SAAO,SAAS,4BAA4B,WAAW;AACzD;AAEO,SAAS,eAAe,GAAwC;AACrE,SAAO,CAAC,mBAAmB,uBAAuB,uBAAuB,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,IAAI;AACtG;AAEO,SAAS,WAAW,GAAiB;AAC1C,QAAM,SAAS,uBAAG;AAClB,SAAO,CAAC,CAAC,UAAU,UAAU,OAAO,SAAS;AAC/C;AAEO,SAAS,eAAe,GAAiB;AAE9C,QAAM,WAAW,GAAG,EAAE,OAAO,GAAG,EAAE,IAAI,MAAM,IAAI,YAAY,EAAE,QAAQ,QAAQ,EAAE;AAChF,SAAO,QAAQ,SAAS,cAAc;AACxC;AAEO,SAAS,YAAY,OAAiC,CAAC,GAAyB;AACrF,SAAO,KAAK,SAAS,IAAI,KAAK,IAAI,UAAU,IAAI,CAAC;AACnD;AAGO,SAAS,WAAW,OAAmD;AAC5E,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,SAAS,MAAM;AAAA,EACjB;AACF;AAEO,SAAS,YAAY,OAA0D;AACpF,SAAO;AAAA,IACL,OAAM,+BAAO,SAAQ;AAAA,IACrB,UAAS,+BAAO,YAAW;AAAA,EAC7B;AACF;AAUO,IAAM,6BAAN,MAAM,oCAAmC,MAAM;AAAA,EASpD,YAAY,SAAiB,EAAE,MAAM,QAAQ,WAAW,GAAiC;AACvF,UAAM,OAAO;AAWf,SAAO,WAAW,MAAM;AACtB,YAAM,UAAU,IAAI,KAAK,IAAI;AAAA,UAAc,KAAK,OAAO;AAAA,SAAY,KAAK,MAAM;AAAA,qBAAwB,KAAK,OAAO;AAAA,QAChH,OAAK,KAAK,UAAU,CAAC;AAAA,MACvB,CAAC;AAED,aAAO;AAAA,IACT;AAfE,WAAO,eAAe,MAAM,4BAA2B,SAAS;AAEhE,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,SAAS,YAAY,IAAI;AAAA,EAChC;AASF;AAIO,IAAM,yBAAN,MAAM,gCAA+B,MAAM;AAAA,EAiBhD,YAAY,SAAiB,EAAE,KAAK,GAAqB;AACvD,UAAM,SAAS;AACf,UAAM,QAAQ,IAAI,OAAO,OAAO,QAAQ,KAAK,MAAM,GAAG,GAAG;AACzD,UAAM,YAAY,QAAQ,QAAQ,OAAO,EAAE;AAC3C,UAAM,WAAW,GAAG,MAAM,IAAI,UAAU,KAAK,CAAC;AAAA;AAAA,SAAc,IAAI;AAAA;AAChE,UAAM,QAAQ;AAehB;AAAA;AAAA;AAAA;AAAA;AAAA,SAAO,WAAW,MAAM;AACtB,aAAO,IAAI,KAAK,IAAI;AAAA,UAAc,KAAK,OAAO;AAAA,IAChD;AAfE,WAAO,eAAe,MAAM,wBAAuB,SAAS;AAE5D,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,yBAAyB;AAC9B,SAAK,OAAO;AAAA,EACd;AAUF;","names":[]}
@@ -0,0 +1,17 @@
1
+ import { ErrorCode, AuthErrorResponse } from '@tern-secure/types';
2
+
3
+ declare class TernSecureError extends Error {
4
+ code: ErrorCode;
5
+ constructor(code: ErrorCode, message?: string);
6
+ }
7
+ /**
8
+ * Handles Firebase authentication errors with multiple fallback mechanisms
9
+ */
10
+ declare function handleFirebaseAuthError(error: unknown): AuthErrorResponse;
11
+ /**
12
+ * Type guard to check if a response is an AuthErrorResponse
13
+ */
14
+ declare function isAuthErrorResponse(response: unknown): response is AuthErrorResponse;
15
+ declare function getErrorAlertVariant(error: any | undefined): "destructive" | "default";
16
+
17
+ export { TernSecureError, getErrorAlertVariant, handleFirebaseAuthError, isAuthErrorResponse };
@@ -0,0 +1,17 @@
1
+ import { ErrorCode, AuthErrorResponse } from '@tern-secure/types';
2
+
3
+ declare class TernSecureError extends Error {
4
+ code: ErrorCode;
5
+ constructor(code: ErrorCode, message?: string);
6
+ }
7
+ /**
8
+ * Handles Firebase authentication errors with multiple fallback mechanisms
9
+ */
10
+ declare function handleFirebaseAuthError(error: unknown): AuthErrorResponse;
11
+ /**
12
+ * Type guard to check if a response is an AuthErrorResponse
13
+ */
14
+ declare function isAuthErrorResponse(response: unknown): response is AuthErrorResponse;
15
+ declare function getErrorAlertVariant(error: any | undefined): "destructive" | "default";
16
+
17
+ export { TernSecureError, getErrorAlertVariant, handleFirebaseAuthError, isAuthErrorResponse };
package/dist/errors.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/errors.ts
21
+ var errors_exports = {};
22
+ __export(errors_exports, {
23
+ TernSecureError: () => TernSecureError,
24
+ getErrorAlertVariant: () => getErrorAlertVariant,
25
+ handleFirebaseAuthError: () => handleFirebaseAuthError,
26
+ isAuthErrorResponse: () => isAuthErrorResponse
27
+ });
28
+ module.exports = __toCommonJS(errors_exports);
29
+ var TernSecureError = class extends Error {
30
+ constructor(code, message) {
31
+ super(message || code);
32
+ this.name = "TernSecureError";
33
+ this.code = code;
34
+ }
35
+ };
36
+ function handleFirebaseAuthError(error) {
37
+ function extractErrorInfo(input) {
38
+ if (typeof input === "string") {
39
+ const match = input.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
40
+ if (match) {
41
+ return { code: match[1], message: input };
42
+ }
43
+ }
44
+ if (input && typeof input === "object") {
45
+ const err = input;
46
+ if (err.message) {
47
+ const match = err.message.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
48
+ if (match) {
49
+ return { code: match[1], message: err.message };
50
+ }
51
+ }
52
+ if (err.code) {
53
+ return {
54
+ code: err.code.replace("auth/", ""),
55
+ message: err.message || ""
56
+ };
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+ const ERROR_MESSAGES = {
62
+ "invalid-email": { message: "Invalid email format", code: "INVALID_EMAIL" },
63
+ "invalid-tenant-id": { message: "Invalid tenant ID", code: "INVALID_ARGUMENT" },
64
+ "invalid-credential": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
65
+ "invalid-login-credentials": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
66
+ "wrong-password": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
67
+ "user-not-found": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
68
+ "user-disabled": { message: "This account has been disabled", code: "USER_DISABLED" },
69
+ "too-many-requests": { message: "Too many attempts. Please try again later", code: "TOO_MANY_ATTEMPTS" },
70
+ "network-request-failed": { message: "Network error. Please check your connection", code: "NETWORK_ERROR" },
71
+ "email-already-in-use": { message: "This email is already in use", code: "EMAIL_EXISTS" },
72
+ "weak-password": { message: "Password is too weak", code: "WEAK_PASSWORD" },
73
+ "operation-not-allowed": { message: "This login method is not enabled", code: "OPERATION_NOT_ALLOWED" },
74
+ "popup-blocked": { message: "Login popup was blocked. Please enable popups", code: "POPUP_BLOCKED" },
75
+ "expired-action-code": { message: "Your session has expired. Please login again", code: "EXPIRED_TOKEN" },
76
+ "user-token-expired": { message: "Your session has expired. Please login again", code: "EXPIRED_TOKEN" },
77
+ "tenant-not-found": { message: "There is no tenant corresponding to the provided identifier.", code: "INVALID_ARGUMENT" }
78
+ };
79
+ try {
80
+ const errorInfo = extractErrorInfo(error);
81
+ if (errorInfo) {
82
+ const mappedError = ERROR_MESSAGES[errorInfo.code];
83
+ if (mappedError) {
84
+ return {
85
+ success: false,
86
+ message: mappedError.message,
87
+ code: mappedError.code
88
+ };
89
+ }
90
+ }
91
+ const errorString = String(error);
92
+ const lastMatch = errorString.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
93
+ if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {
94
+ return {
95
+ success: false,
96
+ ...ERROR_MESSAGES[lastMatch[1]]
97
+ };
98
+ }
99
+ } catch (e) {
100
+ }
101
+ return {
102
+ success: false,
103
+ message: "An unexpected error occurred. Please try again later",
104
+ code: "INTERNAL_ERROR"
105
+ };
106
+ }
107
+ function isAuthErrorResponse(response) {
108
+ return typeof response === "object" && response !== null && "success" in response && response.success === false && "code" in response && "message" in response;
109
+ }
110
+ function getErrorAlertVariant(error) {
111
+ if (!error) return "destructive";
112
+ switch (error.error) {
113
+ case "AUTHENTICATED":
114
+ return "default";
115
+ case "EMAIL_EXISTS":
116
+ case "UNAUTHENTICATED":
117
+ case "UNVERIFIED":
118
+ case "REQUIRES_VERIFICATION":
119
+ case "INVALID_EMAIL":
120
+ case "INVALID_TOKEN":
121
+ case "INTERNAL_ERROR":
122
+ case "USER_DISABLED":
123
+ case "TOO_MANY_ATTEMPTS":
124
+ case "NETWORK_ERROR":
125
+ case "SESSION_EXPIRED":
126
+ case "EXPIRED_TOKEN":
127
+ case "INVALID_CREDENTIALS":
128
+ default:
129
+ return "destructive";
130
+ }
131
+ }
132
+ // Annotate the CommonJS export names for ESM import in node:
133
+ 0 && (module.exports = {
134
+ TernSecureError,
135
+ getErrorAlertVariant,
136
+ handleFirebaseAuthError,
137
+ isAuthErrorResponse
138
+ });
139
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
@@ -0,0 +1,111 @@
1
+ // src/errors.ts
2
+ var TernSecureError = class extends Error {
3
+ constructor(code, message) {
4
+ super(message || code);
5
+ this.name = "TernSecureError";
6
+ this.code = code;
7
+ }
8
+ };
9
+ function handleFirebaseAuthError(error) {
10
+ function extractErrorInfo(input) {
11
+ if (typeof input === "string") {
12
+ const match = input.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
13
+ if (match) {
14
+ return { code: match[1], message: input };
15
+ }
16
+ }
17
+ if (input && typeof input === "object") {
18
+ const err = input;
19
+ if (err.message) {
20
+ const match = err.message.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
21
+ if (match) {
22
+ return { code: match[1], message: err.message };
23
+ }
24
+ }
25
+ if (err.code) {
26
+ return {
27
+ code: err.code.replace("auth/", ""),
28
+ message: err.message || ""
29
+ };
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ const ERROR_MESSAGES = {
35
+ "invalid-email": { message: "Invalid email format", code: "INVALID_EMAIL" },
36
+ "invalid-tenant-id": { message: "Invalid tenant ID", code: "INVALID_ARGUMENT" },
37
+ "invalid-credential": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
38
+ "invalid-login-credentials": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
39
+ "wrong-password": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
40
+ "user-not-found": { message: "Invalid email or password", code: "INVALID_CREDENTIALS" },
41
+ "user-disabled": { message: "This account has been disabled", code: "USER_DISABLED" },
42
+ "too-many-requests": { message: "Too many attempts. Please try again later", code: "TOO_MANY_ATTEMPTS" },
43
+ "network-request-failed": { message: "Network error. Please check your connection", code: "NETWORK_ERROR" },
44
+ "email-already-in-use": { message: "This email is already in use", code: "EMAIL_EXISTS" },
45
+ "weak-password": { message: "Password is too weak", code: "WEAK_PASSWORD" },
46
+ "operation-not-allowed": { message: "This login method is not enabled", code: "OPERATION_NOT_ALLOWED" },
47
+ "popup-blocked": { message: "Login popup was blocked. Please enable popups", code: "POPUP_BLOCKED" },
48
+ "expired-action-code": { message: "Your session has expired. Please login again", code: "EXPIRED_TOKEN" },
49
+ "user-token-expired": { message: "Your session has expired. Please login again", code: "EXPIRED_TOKEN" },
50
+ "tenant-not-found": { message: "There is no tenant corresponding to the provided identifier.", code: "INVALID_ARGUMENT" }
51
+ };
52
+ try {
53
+ const errorInfo = extractErrorInfo(error);
54
+ if (errorInfo) {
55
+ const mappedError = ERROR_MESSAGES[errorInfo.code];
56
+ if (mappedError) {
57
+ return {
58
+ success: false,
59
+ message: mappedError.message,
60
+ code: mappedError.code
61
+ };
62
+ }
63
+ }
64
+ const errorString = String(error);
65
+ const lastMatch = errorString.match(/Firebase:\s*Error\s*\(auth\/([^)]+)\)/);
66
+ if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {
67
+ return {
68
+ success: false,
69
+ ...ERROR_MESSAGES[lastMatch[1]]
70
+ };
71
+ }
72
+ } catch (e) {
73
+ }
74
+ return {
75
+ success: false,
76
+ message: "An unexpected error occurred. Please try again later",
77
+ code: "INTERNAL_ERROR"
78
+ };
79
+ }
80
+ function isAuthErrorResponse(response) {
81
+ return typeof response === "object" && response !== null && "success" in response && response.success === false && "code" in response && "message" in response;
82
+ }
83
+ function getErrorAlertVariant(error) {
84
+ if (!error) return "destructive";
85
+ switch (error.error) {
86
+ case "AUTHENTICATED":
87
+ return "default";
88
+ case "EMAIL_EXISTS":
89
+ case "UNAUTHENTICATED":
90
+ case "UNVERIFIED":
91
+ case "REQUIRES_VERIFICATION":
92
+ case "INVALID_EMAIL":
93
+ case "INVALID_TOKEN":
94
+ case "INTERNAL_ERROR":
95
+ case "USER_DISABLED":
96
+ case "TOO_MANY_ATTEMPTS":
97
+ case "NETWORK_ERROR":
98
+ case "SESSION_EXPIRED":
99
+ case "EXPIRED_TOKEN":
100
+ case "INVALID_CREDENTIALS":
101
+ default:
102
+ return "destructive";
103
+ }
104
+ }
105
+ export {
106
+ TernSecureError,
107
+ getErrorAlertVariant,
108
+ handleFirebaseAuthError,
109
+ isAuthErrorResponse
110
+ };
111
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { AuthErrorResponse, ErrorCode } from \"@tern-secure/types\";\n\n\nexport class TernSecureError extends Error {\n code: ErrorCode\n\n constructor(code: ErrorCode, message?: string) {\n super(message || code)\n this.name = \"TernSecureError\"\n this.code = code\n }\n}\n\n\n/**\n * Handles Firebase authentication errors with multiple fallback mechanisms\n */\nexport function handleFirebaseAuthError(error: unknown): AuthErrorResponse {\n function extractErrorInfo(input: unknown): { code: string; message: string } | null {\n // Case 1: String input (direct Firebase error message)\n if (typeof input === 'string') {\n const match = input.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: input };\n }\n }\n\n // Case 2: Error object\n if (input && typeof input === 'object') {\n const err = input as { code?: string; message?: string };\n \n // Check for bundled message format first\n if (err.message) {\n const match = err.message.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (match) {\n return { code: match[1], message: err.message };\n }\n }\n\n // Check for direct code\n if (err.code) {\n return {\n code: err.code.replace('auth/', ''),\n message: err.message || ''\n };\n }\n }\n\n return null;\n }\n\n // Map error codes to user-friendly messages\n const ERROR_MESSAGES: Record<string, { message: string; code: ErrorCode }> = {\n 'invalid-email': { message: 'Invalid email format', code: 'INVALID_EMAIL' },\n 'invalid-tenant-id': { message: 'Invalid tenant ID', code: 'INVALID_ARGUMENT' },\n 'invalid-credential': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'invalid-login-credentials': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'wrong-password': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-not-found': { message: 'Invalid email or password', code: 'INVALID_CREDENTIALS' },\n 'user-disabled': { message: 'This account has been disabled', code: 'USER_DISABLED' },\n 'too-many-requests': { message: 'Too many attempts. Please try again later', code: 'TOO_MANY_ATTEMPTS' },\n 'network-request-failed': { message: 'Network error. Please check your connection', code: 'NETWORK_ERROR' },\n 'email-already-in-use': { message: 'This email is already in use', code: 'EMAIL_EXISTS' },\n 'weak-password': { message: 'Password is too weak', code: 'WEAK_PASSWORD' },\n 'operation-not-allowed': { message: 'This login method is not enabled', code: 'OPERATION_NOT_ALLOWED' },\n 'popup-blocked': { message: 'Login popup was blocked. Please enable popups', code: 'POPUP_BLOCKED' },\n 'expired-action-code': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'user-token-expired': { message: 'Your session has expired. Please login again', code: 'EXPIRED_TOKEN' },\n 'tenant-not-found': { message: 'There is no tenant corresponding to the provided identifier.', code: 'INVALID_ARGUMENT' },\n };\n\n try {\n // Extract error information\n const errorInfo = extractErrorInfo(error);\n \n if (errorInfo) {\n const mappedError = ERROR_MESSAGES[errorInfo.code];\n if (mappedError) {\n return {\n success: false,\n message: mappedError.message,\n code: mappedError.code\n };\n }\n }\n\n // If we couldn't extract or map the error, try one last time with string conversion\n const errorString = String(error);\n const lastMatch = errorString.match(/Firebase:\\s*Error\\s*\\(auth\\/([^)]+)\\)/);\n if (lastMatch && ERROR_MESSAGES[lastMatch[1]]) {\n return {\n success: false,\n ...ERROR_MESSAGES[lastMatch[1]]\n };\n }\n\n } catch (e) {\n // Silent catch - we'll return the default error\n }\n\n // Default fallback\n return {\n success: false,\n message: 'An unexpected error occurred. Please try again later',\n code: 'INTERNAL_ERROR'\n };\n}\n\n/**\n * Type guard to check if a response is an AuthErrorResponse\n */\nexport function isAuthErrorResponse(response: unknown): response is AuthErrorResponse {\n return (\n typeof response === \"object\" &&\n response !== null &&\n \"success\" in response &&\n (response as { success: boolean }).success === false &&\n \"code\" in response &&\n \"message\" in response\n )\n}\n\nexport function getErrorAlertVariant(error: any | undefined) {\n if (!error) return \"destructive\"\n\n switch (error.error) {\n case \"AUTHENTICATED\":\n return \"default\"\n case \"EMAIL_EXISTS\":\n case \"UNAUTHENTICATED\":\n case \"UNVERIFIED\":\n case \"REQUIRES_VERIFICATION\":\n case \"INVALID_EMAIL\":\n case \"INVALID_TOKEN\":\n case \"INTERNAL_ERROR\":\n case \"USER_DISABLED\":\n case \"TOO_MANY_ATTEMPTS\":\n case \"NETWORK_ERROR\":\n case \"SESSION_EXPIRED\":\n case \"EXPIRED_TOKEN\":\n case \"INVALID_CREDENTIALS\":\n default:\n return \"destructive\"\n }\n}"],"mappings":"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","names":[]}
@@ -1,8 +1,29 @@
1
- declare class EventEmitter {
2
- private listeners;
3
- on(eventName: string, listener: (...args: any[]) => void): () => void;
4
- emit(eventName: string, ...args: any[]): void;
5
- off(eventName: string, listener: (...args: any[]) => void): void;
6
- }
1
+ type EventHandler<Events extends Record<string, unknown>, Key extends keyof Events> = (payload: Events[Key]) => void;
2
+ type EventBus<Events extends Record<string, unknown>> = {
3
+ /**
4
+ * Subscribe to an event
5
+ *
6
+ * @param event - The event name to subscribe to
7
+ * @param handler - The callback function to execute when the event is dispatched
8
+ * @param opts - Optional configuration
9
+ * @param opts.notify - If true and the event was previously dispatched, handler will be called immediately with the latest payload
10
+ * @returns void
11
+ */
12
+ on: <Event extends keyof Events>(event: Event, handler: EventHandler<Events, Event>, opts?: {
13
+ notify?: boolean;
14
+ }) => void;
15
+ /**
16
+ * Publish an event with a payload
17
+ * Triggers all registered handlers for the event
18
+ *
19
+ * @param event - The event name to publish
20
+ * @param payload - The data to pass to event handlers
21
+ * @returns void
22
+ */
23
+ emit: <Event extends keyof Events>(event: Event, payload: Events[Event]) => void;
24
+ off: <Event extends keyof Events>(event: Event, handler?: EventHandler<Events, Event>) => void;
25
+ getListeners: <Event extends keyof Events>(event: Event) => Array<(...args: any[]) => void>;
26
+ };
27
+ declare const createEventBus: <Events extends Record<string, unknown>>() => EventBus<Events>;
7
28
 
8
- export { EventEmitter };
29
+ export { createEventBus };
@@ -1,8 +1,29 @@
1
- declare class EventEmitter {
2
- private listeners;
3
- on(eventName: string, listener: (...args: any[]) => void): () => void;
4
- emit(eventName: string, ...args: any[]): void;
5
- off(eventName: string, listener: (...args: any[]) => void): void;
6
- }
1
+ type EventHandler<Events extends Record<string, unknown>, Key extends keyof Events> = (payload: Events[Key]) => void;
2
+ type EventBus<Events extends Record<string, unknown>> = {
3
+ /**
4
+ * Subscribe to an event
5
+ *
6
+ * @param event - The event name to subscribe to
7
+ * @param handler - The callback function to execute when the event is dispatched
8
+ * @param opts - Optional configuration
9
+ * @param opts.notify - If true and the event was previously dispatched, handler will be called immediately with the latest payload
10
+ * @returns void
11
+ */
12
+ on: <Event extends keyof Events>(event: Event, handler: EventHandler<Events, Event>, opts?: {
13
+ notify?: boolean;
14
+ }) => void;
15
+ /**
16
+ * Publish an event with a payload
17
+ * Triggers all registered handlers for the event
18
+ *
19
+ * @param event - The event name to publish
20
+ * @param payload - The data to pass to event handlers
21
+ * @returns void
22
+ */
23
+ emit: <Event extends keyof Events>(event: Event, payload: Events[Event]) => void;
24
+ off: <Event extends keyof Events>(event: Event, handler?: EventHandler<Events, Event>) => void;
25
+ getListeners: <Event extends keyof Events>(event: Event) => Array<(...args: any[]) => void>;
26
+ };
27
+ declare const createEventBus: <Events extends Record<string, unknown>>() => EventBus<Events>;
7
28
 
8
- export { EventEmitter };
29
+ export { createEventBus };
package/dist/eventBus.js CHANGED
@@ -20,35 +20,50 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/eventBus.ts
21
21
  var eventBus_exports = {};
22
22
  __export(eventBus_exports, {
23
- EventEmitter: () => EventEmitter
23
+ createEventBus: () => createEventBus
24
24
  });
25
25
  module.exports = __toCommonJS(eventBus_exports);
26
- var EventEmitter = class {
27
- constructor() {
28
- this.listeners = {};
29
- }
30
- on(eventName, listener) {
31
- if (!this.listeners[eventName]) {
32
- this.listeners[eventName] = [];
26
+ var _off = (eventToHandlersMap, event, handler) => {
27
+ const handlers = eventToHandlersMap.get(event);
28
+ if (handlers) {
29
+ if (handler) {
30
+ handlers.splice(handlers.indexOf(handler) >>> 0, 1);
31
+ } else {
32
+ eventToHandlersMap.set(event, []);
33
33
  }
34
- this.listeners[eventName].push(listener);
35
- return () => {
36
- this.listeners[eventName] = this.listeners[eventName].filter((l) => l !== listener);
37
- };
38
34
  }
39
- emit(eventName, ...args) {
40
- if (this.listeners[eventName]) {
41
- this.listeners[eventName].forEach((listener) => listener(...args));
42
- }
35
+ };
36
+ var _on = (eventToHandlersMap, latestPayloadMap, event, handler, opts) => {
37
+ const { notify } = opts || {};
38
+ let handlers = eventToHandlersMap.get(event);
39
+ if (!handlers) {
40
+ handlers = [];
41
+ eventToHandlersMap.set(event, handlers);
43
42
  }
44
- off(eventName, listener) {
45
- if (this.listeners[eventName]) {
46
- this.listeners[eventName] = this.listeners[eventName].filter((l) => l !== listener);
47
- }
43
+ handlers.push(handler);
44
+ if (notify && latestPayloadMap.has(event)) {
45
+ handler(latestPayloadMap.get(event));
48
46
  }
49
47
  };
48
+ var _dispatch = (eventToHandlersMap, event, payload) => (eventToHandlersMap.get(event) || []).map((h) => h(payload));
49
+ var createEventBus = () => {
50
+ const eventToHandlersMap = /* @__PURE__ */ new Map();
51
+ const latestPayloadMap = /* @__PURE__ */ new Map();
52
+ const eventToPredispatchHandlersMap = /* @__PURE__ */ new Map();
53
+ const emit = (event, payload) => {
54
+ latestPayloadMap.set(event, payload);
55
+ _dispatch(eventToPredispatchHandlersMap, event, payload);
56
+ _dispatch(eventToHandlersMap, event, payload);
57
+ };
58
+ return {
59
+ on: (...args) => _on(eventToHandlersMap, latestPayloadMap, ...args),
60
+ emit,
61
+ off: (...args) => _off(eventToHandlersMap, ...args),
62
+ getListeners: (event) => eventToHandlersMap.get(event) || []
63
+ };
64
+ };
50
65
  // Annotate the CommonJS export names for ESM import in node:
51
66
  0 && (module.exports = {
52
- EventEmitter
67
+ createEventBus
53
68
  });
54
69
  //# sourceMappingURL=eventBus.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/eventBus.ts"],"sourcesContent":["export class EventEmitter {\n private listeners: { [eventName: string]: Array<(...args: any[]) => void> } = {};\n\n on(eventName: string, listener: (...args: any[]) => void): () => void {\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = [];\n }\n this.listeners[eventName].push(listener);\n return () => {\n this.listeners[eventName] = this.listeners[eventName].filter(l => l !== listener);\n };\n }\n\n emit(eventName: string, ...args: any[]): void {\n if (this.listeners[eventName]) {\n this.listeners[eventName].forEach(listener => listener(...args));\n }\n }\n\n off(eventName: string, listener: (...args: any[]) => void): void {\n if (this.listeners[eventName]) {\n this.listeners[eventName] = this.listeners[eventName].filter(l => l !== listener);\n }\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,eAAN,MAAmB;AAAA,EAAnB;AACH,SAAQ,YAAsE,CAAC;AAAA;AAAA,EAE/E,GAAG,WAAmB,UAAgD;AAClE,QAAI,CAAC,KAAK,UAAU,SAAS,GAAG;AAC5B,WAAK,UAAU,SAAS,IAAI,CAAC;AAAA,IACjC;AACA,SAAK,UAAU,SAAS,EAAE,KAAK,QAAQ;AACvC,WAAO,MAAM;AACT,WAAK,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,EAAE,OAAO,OAAK,MAAM,QAAQ;AAAA,IACpF;AAAA,EACJ;AAAA,EAEA,KAAK,cAAsB,MAAmB;AAC1C,QAAI,KAAK,UAAU,SAAS,GAAG;AAC3B,WAAK,UAAU,SAAS,EAAE,QAAQ,cAAY,SAAS,GAAG,IAAI,CAAC;AAAA,IACnE;AAAA,EACJ;AAAA,EAEA,IAAI,WAAmB,UAA0C;AAC7D,QAAI,KAAK,UAAU,SAAS,GAAG;AAC3B,WAAK,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,EAAE,OAAO,OAAK,MAAM,QAAQ;AAAA,IACpF;AAAA,EACJ;AACJ;","names":[]}
1
+ {"version":3,"sources":["../src/eventBus.ts"],"sourcesContent":["type EventHandler<\n Events extends Record<string, unknown>,\n Key extends keyof Events,\n> = (payload: Events[Key]) => void;\n\ntype EventBus<Events extends Record<string, unknown>> = {\n /**\n * Subscribe to an event\n *\n * @param event - The event name to subscribe to\n * @param handler - The callback function to execute when the event is dispatched\n * @param opts - Optional configuration\n * @param opts.notify - If true and the event was previously dispatched, handler will be called immediately with the latest payload\n * @returns void\n */\n on: <Event extends keyof Events>(\n event: Event,\n handler: EventHandler<Events, Event>,\n opts?: { notify?: boolean }\n ) => void;\n\n /**\n * Publish an event with a payload\n * Triggers all registered handlers for the event\n *\n * @param event - The event name to publish\n * @param payload - The data to pass to event handlers\n * @returns void\n */\n emit: <Event extends keyof Events>(\n event: Event,\n payload: Events[Event]\n ) => void;\n off: <Event extends keyof Events>(\n event: Event,\n handler?: EventHandler<Events, Event>\n ) => void;\n getListeners: <Event extends keyof Events>(\n event: Event\n ) => Array<(...args: any[]) => void>;\n};\n\n/**\n * @internal\n */\ntype InternalOn = <\n Events extends Record<string, unknown>,\n Event extends keyof Events,\n>(\n eventToHandlersMap: Map<keyof Events, Array<(...args: any[]) => void>>,\n latestPayloadMap: Map<keyof Events, any>,\n event: Event,\n handler: EventHandler<Events, Event>,\n opts?: { notify?: boolean }\n) => void;\n\n/**\n * @internal\n */\ntype InternalOff = <\n Events extends Record<string, unknown>,\n Event extends keyof Events,\n>(\n eventToHandlersMap: Map<keyof Events, Array<(...args: any[]) => void>>,\n event: Event,\n handler?: EventHandler<Events, Event>\n) => void;\n\n/**\n * @internal\n */\ntype InternalDispatch = <\n Events extends Record<string, unknown>,\n Event extends keyof Events,\n>(\n eventToHandlersMap: Map<keyof Events, Array<(...args: any[]) => void>>,\n event: Event,\n payload: Events[Event]\n) => void;\n\n/**\n * @internal\n */\nconst _off: InternalOff = (eventToHandlersMap, event, handler) => {\n const handlers = eventToHandlersMap.get(event);\n if (handlers) {\n if (handler) {\n handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n } else {\n eventToHandlersMap.set(event, []);\n }\n }\n};\n\n/**\n * @internal\n */\nconst _on: InternalOn = (\n eventToHandlersMap,\n latestPayloadMap,\n event,\n handler,\n opts\n) => {\n const { notify } = opts || {};\n let handlers = eventToHandlersMap.get(event);\n\n if (!handlers) {\n handlers = [];\n eventToHandlersMap.set(event, handlers);\n }\n\n handlers.push(handler);\n if (notify && latestPayloadMap.has(event)) {\n handler(latestPayloadMap.get(event));\n }\n};\n\n/**\n * @internal\n */\n\nconst _dispatch: InternalDispatch = (eventToHandlersMap, event, payload) =>\n (eventToHandlersMap.get(event) || []).map((h) => h(payload));\n\nexport const createEventBus = <\n Events extends Record<string, unknown>,\n>(): EventBus<Events> => {\n const eventToHandlersMap = new Map<\n keyof Events,\n Array<(...args: any[]) => void>\n >();\n const latestPayloadMap = new Map<keyof Events, any>();\n const eventToPredispatchHandlersMap = new Map<\n keyof Events,\n Array<(...args: any[]) => void>\n >();\n\n const emit: EventBus<Events>[\"emit\"] = (event, payload) => {\n latestPayloadMap.set(event, payload);\n _dispatch(eventToPredispatchHandlersMap, event, payload);\n _dispatch(eventToHandlersMap, event, payload);\n };\n\n return {\n on: (...args) => _on(eventToHandlersMap, latestPayloadMap, ...args),\n emit,\n off: (...args) => _off(eventToHandlersMap, ...args),\n getListeners: (event) => eventToHandlersMap.get(event) || [],\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmFA,IAAM,OAAoB,CAAC,oBAAoB,OAAO,YAAY;AAChE,QAAM,WAAW,mBAAmB,IAAI,KAAK;AAC7C,MAAI,UAAU;AACZ,QAAI,SAAS;AACX,eAAS,OAAO,SAAS,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,IACpD,OAAO;AACL,yBAAmB,IAAI,OAAO,CAAC,CAAC;AAAA,IAClC;AAAA,EACF;AACF;AAKA,IAAM,MAAkB,CACtB,oBACA,kBACA,OACA,SACA,SACG;AACH,QAAM,EAAE,OAAO,IAAI,QAAQ,CAAC;AAC5B,MAAI,WAAW,mBAAmB,IAAI,KAAK;AAE3C,MAAI,CAAC,UAAU;AACb,eAAW,CAAC;AACZ,uBAAmB,IAAI,OAAO,QAAQ;AAAA,EACxC;AAEA,WAAS,KAAK,OAAO;AACrB,MAAI,UAAU,iBAAiB,IAAI,KAAK,GAAG;AACzC,YAAQ,iBAAiB,IAAI,KAAK,CAAC;AAAA,EACrC;AACF;AAMA,IAAM,YAA8B,CAAC,oBAAoB,OAAO,aAC7D,mBAAmB,IAAI,KAAK,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAEtD,IAAM,iBAAiB,MAEL;AACvB,QAAM,qBAAqB,oBAAI,IAG7B;AACF,QAAM,mBAAmB,oBAAI,IAAuB;AACpD,QAAM,gCAAgC,oBAAI,IAGxC;AAEF,QAAM,OAAiC,CAAC,OAAO,YAAY;AACzD,qBAAiB,IAAI,OAAO,OAAO;AACnC,cAAU,+BAA+B,OAAO,OAAO;AACvD,cAAU,oBAAoB,OAAO,OAAO;AAAA,EAC9C;AAEA,SAAO;AAAA,IACL,IAAI,IAAI,SAAS,IAAI,oBAAoB,kBAAkB,GAAG,IAAI;AAAA,IAClE;AAAA,IACA,KAAK,IAAI,SAAS,KAAK,oBAAoB,GAAG,IAAI;AAAA,IAClD,cAAc,CAAC,UAAU,mBAAmB,IAAI,KAAK,KAAK,CAAC;AAAA,EAC7D;AACF;","names":[]}
package/dist/eventBus.mjs CHANGED
@@ -1,29 +1,7 @@
1
- // src/eventBus.ts
2
- var EventEmitter = class {
3
- constructor() {
4
- this.listeners = {};
5
- }
6
- on(eventName, listener) {
7
- if (!this.listeners[eventName]) {
8
- this.listeners[eventName] = [];
9
- }
10
- this.listeners[eventName].push(listener);
11
- return () => {
12
- this.listeners[eventName] = this.listeners[eventName].filter((l) => l !== listener);
13
- };
14
- }
15
- emit(eventName, ...args) {
16
- if (this.listeners[eventName]) {
17
- this.listeners[eventName].forEach((listener) => listener(...args));
18
- }
19
- }
20
- off(eventName, listener) {
21
- if (this.listeners[eventName]) {
22
- this.listeners[eventName] = this.listeners[eventName].filter((l) => l !== listener);
23
- }
24
- }
25
- };
1
+ import {
2
+ createEventBus
3
+ } from "./chunk-2UQ43P4P.mjs";
26
4
  export {
27
- EventEmitter
5
+ createEventBus
28
6
  };
29
7
  //# sourceMappingURL=eventBus.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/eventBus.ts"],"sourcesContent":["export class EventEmitter {\n private listeners: { [eventName: string]: Array<(...args: any[]) => void> } = {};\n\n on(eventName: string, listener: (...args: any[]) => void): () => void {\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = [];\n }\n this.listeners[eventName].push(listener);\n return () => {\n this.listeners[eventName] = this.listeners[eventName].filter(l => l !== listener);\n };\n }\n\n emit(eventName: string, ...args: any[]): void {\n if (this.listeners[eventName]) {\n this.listeners[eventName].forEach(listener => listener(...args));\n }\n }\n\n off(eventName: string, listener: (...args: any[]) => void): void {\n if (this.listeners[eventName]) {\n this.listeners[eventName] = this.listeners[eventName].filter(l => l !== listener);\n }\n }\n}"],"mappings":";AAAO,IAAM,eAAN,MAAmB;AAAA,EAAnB;AACH,SAAQ,YAAsE,CAAC;AAAA;AAAA,EAE/E,GAAG,WAAmB,UAAgD;AAClE,QAAI,CAAC,KAAK,UAAU,SAAS,GAAG;AAC5B,WAAK,UAAU,SAAS,IAAI,CAAC;AAAA,IACjC;AACA,SAAK,UAAU,SAAS,EAAE,KAAK,QAAQ;AACvC,WAAO,MAAM;AACT,WAAK,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,EAAE,OAAO,OAAK,MAAM,QAAQ;AAAA,IACpF;AAAA,EACJ;AAAA,EAEA,KAAK,cAAsB,MAAmB;AAC1C,QAAI,KAAK,UAAU,SAAS,GAAG;AAC3B,WAAK,UAAU,SAAS,EAAE,QAAQ,cAAY,SAAS,GAAG,IAAI,CAAC;AAAA,IACnE;AAAA,EACJ;AAAA,EAEA,IAAI,WAAmB,UAA0C;AAC7D,QAAI,KAAK,UAAU,SAAS,GAAG;AAC3B,WAAK,UAAU,SAAS,IAAI,KAAK,UAAU,SAAS,EAAE,OAAO,OAAK,MAAM,QAAQ;AAAA,IACpF;AAAA,EACJ;AACJ;","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}