@servicetitan/log-service 33.1.0 → 34.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bind-log.d.ts.map +1 -1
- package/dist/bind-log.js.map +1 -1
- package/dist/connection-service.js +1 -1
- package/dist/connection-service.js.map +1 -1
- package/dist/global-error-handler.d.ts.map +1 -1
- package/dist/global-error-handler.js +2 -2
- package/dist/global-error-handler.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/log-config-provider.d.ts.map +1 -1
- package/dist/log-config-provider.js.map +1 -1
- package/dist/log-sender.d.ts.map +1 -1
- package/dist/log-sender.js +3 -3
- package/dist/log-sender.js.map +1 -1
- package/dist/log-service.d.ts.map +1 -1
- package/dist/log-service.js +1 -1
- package/dist/log-service.js.map +1 -1
- package/dist/log-storage.d.ts.map +1 -1
- package/dist/log-storage.js +2 -2
- package/dist/log-storage.js.map +1 -1
- package/dist/log.d.ts +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +4 -4
- package/dist/log.js.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/global-error-handler.test.ts +1 -1
- package/src/__tests__/log-config-provider.test.tsx +0 -1
- package/src/__tests__/log-sender.test.ts +1 -2
- package/src/__tests__/log-service.test.tsx +2 -3
- package/src/__tests__/log-storage.test.ts +0 -1
- package/src/bind-log.ts +0 -1
- package/src/connection-service.ts +1 -1
- package/src/global-error-handler.ts +2 -3
- package/src/index.ts +4 -4
- package/src/log-config-provider.tsx +0 -1
- package/src/log-sender.ts +4 -6
- package/src/log-service.tsx +1 -1
- package/src/log-storage.ts +1 -2
- package/src/log.ts +2 -3
package/dist/bind-log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bind-log.d.ts","sourceRoot":"","sources":["../src/bind-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"bind-log.d.ts","sourceRoot":"","sources":["../src/bind-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAQpD,wBAAgB,OAAO,CAAC,SAAS,EAAE,SAAS,QAO3C"}
|
package/dist/bind-log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bind-log.ts"],"sourcesContent":["import { Container } from '@servicetitan/react-ioc';\
|
|
1
|
+
{"version":3,"sources":["../src/bind-log.ts"],"sourcesContent":["import { Container } from '@servicetitan/react-ioc';\nimport { ConnectionService } from './connection-service';\nimport { GlobalErrorHandler } from './global-error-handler';\nimport { Log } from './log';\nimport { LOG_CONFIG_TOKEN, LogConfig, defaultLogConfig } from './log-config';\nimport { LogSender } from './log-sender';\nimport { LogStorage } from './log-storage';\n\nexport function bindLog(container: Container) {\n container.bind<LogConfig>(LOG_CONFIG_TOKEN).toConstantValue(defaultLogConfig);\n container.bind<LogStorage>(LogStorage).toSelf().inSingletonScope();\n container.bind<Log>(Log).toSelf().inSingletonScope();\n container.bind<ConnectionService>(ConnectionService).toSelf().inSingletonScope();\n container.bind<LogSender>(LogSender).toSelf().inSingletonScope();\n container.bind<GlobalErrorHandler>(GlobalErrorHandler).toSelf().inSingletonScope();\n}\n"],"names":["ConnectionService","GlobalErrorHandler","Log","LOG_CONFIG_TOKEN","defaultLogConfig","LogSender","LogStorage","bindLog","container","bind","toConstantValue","toSelf","inSingletonScope"],"mappings":"AACA,SAASA,iBAAiB,QAAQ,uBAAuB;AACzD,SAASC,kBAAkB,QAAQ,yBAAyB;AAC5D,SAASC,GAAG,QAAQ,QAAQ;AAC5B,SAASC,gBAAgB,EAAaC,gBAAgB,QAAQ,eAAe;AAC7E,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,UAAU,QAAQ,gBAAgB;AAE3C,OAAO,SAASC,QAAQC,SAAoB;IACxCA,UAAUC,IAAI,CAAYN,kBAAkBO,eAAe,CAACN;IAC5DI,UAAUC,IAAI,CAAaH,YAAYK,MAAM,GAAGC,gBAAgB;IAChEJ,UAAUC,IAAI,CAAMP,KAAKS,MAAM,GAAGC,gBAAgB;IAClDJ,UAAUC,IAAI,CAAoBT,mBAAmBW,MAAM,GAAGC,gBAAgB;IAC9EJ,UAAUC,IAAI,CAAYJ,WAAWM,MAAM,GAAGC,gBAAgB;IAC9DJ,UAAUC,IAAI,CAAqBR,oBAAoBU,MAAM,GAAGC,gBAAgB;AACpF"}
|
|
@@ -21,7 +21,7 @@ function _ts_metadata(k, v) {
|
|
|
21
21
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
22
22
|
}
|
|
23
23
|
import { injectable } from '@servicetitan/react-ioc';
|
|
24
|
-
import {
|
|
24
|
+
import { action, makeObservable, observable } from 'mobx';
|
|
25
25
|
export class ConnectionService {
|
|
26
26
|
setOnline(status) {
|
|
27
27
|
this.online = status;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection-service.ts"],"sourcesContent":["import { injectable } from '@servicetitan/react-ioc';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/connection-service.ts"],"sourcesContent":["import { injectable } from '@servicetitan/react-ioc';\nimport { action, makeObservable, observable } from 'mobx';\n\n@injectable()\nexport class ConnectionService {\n @observable\n online: boolean = window.navigator.onLine;\n\n constructor() {\n makeObservable(this);\n\n window.addEventListener('online', () => this.setOnline(true));\n window.addEventListener('offline', () => this.setOnline(false));\n }\n\n @action\n setOnline(status: boolean) {\n this.online = status;\n }\n}\n"],"names":["injectable","action","makeObservable","observable","ConnectionService","setOnline","status","online","window","navigator","onLine","addEventListener"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,UAAU,QAAQ,0BAA0B;AACrD,SAASC,MAAM,EAAEC,cAAc,EAAEC,UAAU,QAAQ,OAAO;AAG1D,OAAO,MAAMC;IAYTC,UAAUC,MAAe,EAAE;QACvB,IAAI,CAACC,MAAM,GAAGD;IAClB;IAVA,aAAc;QAHd,uBACAC,UAAkBC,OAAOC,SAAS,CAACC,MAAM;QAGrCR,eAAe,IAAI;QAEnBM,OAAOG,gBAAgB,CAAC,UAAU,IAAM,IAAI,CAACN,SAAS,CAAC;QACvDG,OAAOG,gBAAgB,CAAC,WAAW,IAAM,IAAI,CAACN,SAAS,CAAC;IAC5D;AAMJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-error-handler.d.ts","sourceRoot":"","sources":["../src/global-error-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"global-error-handler.d.ts","sourceRoot":"","sources":["../src/global-error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,GAAG,EAAE,MAAM,OAAO,CAAC;AAU3C,qBACa,kBAAkB;IACF,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,GAAG;IAEzD,UAAU,CAAC,MAAM,EAAE,MAAM;IAKzB,OAAO,GACH,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,OAAO,MAAM,EACb,SAAS,MAAM,EACf,QAAQ,KAAK,EACb,qBAAkB,UAwCpB;IAEF,QAAQ,GAAI,OAAO;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,UAiBpC;IAEF,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,WAAW;CAgBtB"}
|
|
@@ -25,7 +25,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
import {
|
|
28
|
+
import { inject, injectable } from '@servicetitan/react-ioc';
|
|
29
29
|
import { Log } from './log';
|
|
30
30
|
import { serializeWithMetadata } from './serialize-with-metadata';
|
|
31
31
|
export class GlobalErrorHandler {
|
|
@@ -87,8 +87,8 @@ export class GlobalErrorHandler {
|
|
|
87
87
|
err.code = 'NonUniform';
|
|
88
88
|
}
|
|
89
89
|
if (isUnhandled) {
|
|
90
|
-
err.category = 'UnhandledError';
|
|
91
90
|
var _err_code;
|
|
91
|
+
err.category = 'UnhandledError';
|
|
92
92
|
err.code = (_err_code = err.code) !== null && _err_code !== void 0 ? _err_code : 'UnhandledError';
|
|
93
93
|
}
|
|
94
94
|
this.dispatch(err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/global-error-handler.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/global-error-handler.ts"],"sourcesContent":["import { inject, injectable } from '@servicetitan/react-ioc';\nimport { ArbitraryData, Log } from './log';\nimport { serializeWithMetadata } from './serialize-with-metadata';\n\ninterface ExtendedError extends Error {\n category?: string;\n code?: string;\n data?: ArbitraryData;\n stack?: string;\n}\n\n@injectable()\nexport class GlobalErrorHandler {\n constructor(@inject(Log) private readonly logService: Log) {}\n\n instrument(window: Window) {\n consolidate(window, 'onerror', this.onError);\n consolidate(window, 'onunhandledrejection', this.onReject);\n }\n\n onError = (\n message: string,\n url?: string,\n line?: number,\n column?: number,\n error?: Error,\n isUnhandled = true\n ) => {\n try {\n if (this.isIgnorable(message)) {\n return;\n }\n let msg = '';\n if (typeof message === 'string') {\n msg = message;\n } else {\n /*\n * By specification message is always a string\n * this condition covers manual nonuniform window.onerror call\n */\n msg = serializeWithMetadata(message);\n }\n\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Message - ${msg}${\n error ? ';Error - ' + serializeWithMetadata(error) : ''\n }`;\n err = new Error(errorMessage);\n err.stack += `\\n\\tat somewhere (${url}:${line}:${column})`;\n err.code = 'NonUniform';\n }\n if (isUnhandled) {\n err.category = 'UnhandledError';\n err.code = err.code ?? 'UnhandledError';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', message);\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', e);\n }\n };\n\n onReject = (event: { reason: unknown }) => {\n try {\n const error = event.reason;\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Unhandled rejection - ${serializeWithMetadata(error)}`;\n err = new Error(errorMessage);\n err.code = 'NonUniform';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onReject/failsafe', e);\n }\n };\n\n private dispatch(error: ExtendedError) {\n this.logService.error(\n {\n error,\n category: error.category,\n code: error.code,\n message: error.message,\n data: error.data,\n },\n { skipConsole: true }\n );\n }\n\n private isIgnorable(message: string) {\n if (typeof message !== 'string') {\n return false;\n }\n\n const ignoreSubstrings = [\n // 'Script error.', // cross-domain\n 'gCrWeb',\n 'Geolocation',\n 'kCLErrorDomain',\n 'The last location provider was disabled',\n 'Location services are disabled',\n ];\n\n return ignoreSubstrings.some(sub => message.includes(sub));\n }\n}\n\nfunction consolidate(object: { [key: string]: any }, methodName: string, fn: Function) {\n if (typeof object[methodName] === 'function') {\n const fnPrev = object[methodName];\n\n object[methodName] = (...args: unknown[]) => {\n try {\n fn(...args);\n } finally {\n fnPrev(...args);\n }\n };\n return;\n }\n if (object[methodName] != null) {\n throw new TypeError('attempt to instrument non-function value');\n }\n\n object[methodName] = fn;\n}\n"],"names":["inject","injectable","Log","serializeWithMetadata","GlobalErrorHandler","instrument","window","consolidate","onError","onReject","dispatch","error","logService","category","code","message","data","skipConsole","isIgnorable","ignoreSubstrings","some","sub","includes","url","line","column","isUnhandled","msg","err","Error","errorMessage","stack","e","console","event","reason","object","methodName","fn","fnPrev","args","TypeError"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { bindLog } from './bind-log';
|
|
2
|
+
import { ConnectionService } from './connection-service';
|
|
3
|
+
import { GlobalErrorHandler } from './global-error-handler';
|
|
2
4
|
import { ArbitraryData, EntryComplete, EntryCompleteError, ILog, LOG_CONFIG_TOKEN, Log, LogConfig, LogEntry, LogEntryType, LogError, LogInfo, LogWarning } from './log';
|
|
3
5
|
import { LogConfigProvider } from './log-config-provider';
|
|
4
|
-
import { LogStorage, StorageItem } from './log-storage';
|
|
5
6
|
import { LogSender } from './log-sender';
|
|
6
7
|
import { LogService } from './log-service';
|
|
7
|
-
import {
|
|
8
|
-
import { GlobalErrorHandler } from './global-error-handler';
|
|
8
|
+
import { LogStorage, StorageItem } from './log-storage';
|
|
9
9
|
export type { ArbitraryData, EntryComplete, EntryCompleteError, ILog, LogConfig, LogEntry, LogError, LogInfo, LogWarning, StorageItem, };
|
|
10
|
-
export {
|
|
10
|
+
export { ConnectionService, GlobalErrorHandler, LOG_CONFIG_TOKEN, Log, LogConfigProvider, LogEntryType, LogSender, LogService, LogStorage, bindLog, };
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EACH,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,IAAI,EACJ,gBAAgB,EAChB,GAAG,EACH,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,UAAU,EACb,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACH,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,IAAI,EACJ,gBAAgB,EAChB,GAAG,EACH,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,UAAU,EACb,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAExD,YAAY,EACR,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,UAAU,EACV,WAAW,GACd,CAAC;AAEF,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,GAAG,EACH,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,EACV,OAAO,GACV,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { bindLog } from './bind-log';
|
|
2
|
+
import { ConnectionService } from './connection-service';
|
|
3
|
+
import { GlobalErrorHandler } from './global-error-handler';
|
|
2
4
|
import { LOG_CONFIG_TOKEN, Log, LogEntryType } from './log';
|
|
3
5
|
import { LogConfigProvider } from './log-config-provider';
|
|
4
|
-
import { LogStorage } from './log-storage';
|
|
5
6
|
import { LogSender } from './log-sender';
|
|
6
7
|
import { LogService } from './log-service';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export { bindLog, ConnectionService, GlobalErrorHandler, LOG_CONFIG_TOKEN, Log, LogConfigProvider, LogEntryType, LogSender, LogService, LogStorage };
|
|
8
|
+
import { LogStorage } from './log-storage';
|
|
9
|
+
export { ConnectionService, GlobalErrorHandler, LOG_CONFIG_TOKEN, Log, LogConfigProvider, LogEntryType, LogSender, LogService, LogStorage, bindLog };
|
|
10
10
|
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { bindLog } from './bind-log';\nimport {\n ArbitraryData,\n EntryComplete,\n EntryCompleteError,\n ILog,\n LOG_CONFIG_TOKEN,\n Log,\n LogConfig,\n LogEntry,\n LogEntryType,\n LogError,\n LogInfo,\n LogWarning,\n} from './log';\nimport { LogConfigProvider } from './log-config-provider';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { bindLog } from './bind-log';\nimport { ConnectionService } from './connection-service';\nimport { GlobalErrorHandler } from './global-error-handler';\nimport {\n ArbitraryData,\n EntryComplete,\n EntryCompleteError,\n ILog,\n LOG_CONFIG_TOKEN,\n Log,\n LogConfig,\n LogEntry,\n LogEntryType,\n LogError,\n LogInfo,\n LogWarning,\n} from './log';\nimport { LogConfigProvider } from './log-config-provider';\nimport { LogSender } from './log-sender';\nimport { LogService } from './log-service';\nimport { LogStorage, StorageItem } from './log-storage';\n\nexport type {\n ArbitraryData,\n EntryComplete,\n EntryCompleteError,\n ILog,\n LogConfig,\n LogEntry,\n LogError,\n LogInfo,\n LogWarning,\n StorageItem,\n};\n\nexport {\n ConnectionService,\n GlobalErrorHandler,\n LOG_CONFIG_TOKEN,\n Log,\n LogConfigProvider,\n LogEntryType,\n LogSender,\n LogService,\n LogStorage,\n bindLog,\n};\n"],"names":["bindLog","ConnectionService","GlobalErrorHandler","LOG_CONFIG_TOKEN","Log","LogEntryType","LogConfigProvider","LogSender","LogService","LogStorage"],"mappings":"AAAA,SAASA,OAAO,QAAQ,aAAa;AACrC,SAASC,iBAAiB,QAAQ,uBAAuB;AACzD,SAASC,kBAAkB,QAAQ,yBAAyB;AAC5D,SAKIC,gBAAgB,EAChBC,GAAG,EAGHC,YAAY,QAIT,QAAQ;AACf,SAASC,iBAAiB,QAAQ,wBAAwB;AAC1D,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,UAAU,QAAQ,gBAAgB;AAC3C,SAASC,UAAU,QAAqB,gBAAgB;AAexD,SACIR,iBAAiB,EACjBC,kBAAkB,EAClBC,gBAAgB,EAChBC,GAAG,EACHE,iBAAiB,EACjBD,YAAY,EACZE,SAAS,EACTC,UAAU,EACVC,UAAU,EACVT,OAAO,GACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-config-provider.d.ts","sourceRoot":"","sources":["../src/log-config-provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"log-config-provider.d.ts","sourceRoot":"","sources":["../src/log-config-provider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAoB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE3D,KAAK,sBAAsB,GAAG,iBAAiB,CAAC;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAEtE,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAExD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log-config-provider.tsx"],"sourcesContent":["import { Provider } from '@servicetitan/react-ioc';\nimport { FC, PropsWithChildren } from 'react';\
|
|
1
|
+
{"version":3,"sources":["../src/log-config-provider.tsx"],"sourcesContent":["import { Provider } from '@servicetitan/react-ioc';\nimport { FC, PropsWithChildren } from 'react';\nimport { LOG_CONFIG_TOKEN, LogConfig } from './log-config';\n\ntype LogConfigProviderProps = PropsWithChildren<{ value: LogConfig }>;\n\nexport const LogConfigProvider: FC<LogConfigProviderProps> = ({ value, children }) => (\n <Provider singletons={[{ provide: LOG_CONFIG_TOKEN, useValue: value }]}>{children}</Provider>\n);\n"],"names":["Provider","LOG_CONFIG_TOKEN","LogConfigProvider","value","children","singletons","provide","useValue"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,0BAA0B;AAEnD,SAASC,gBAAgB,QAAmB,eAAe;AAI3D,OAAO,MAAMC,oBAAgD,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAAE,iBAC7E,KAACJ;QAASK,YAAY;YAAC;gBAAEC,SAASL;gBAAkBM,UAAUJ;YAAM;SAAE;kBAAGC;OAC3E"}
|
package/dist/log-sender.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-sender.d.ts","sourceRoot":"","sources":["../src/log-sender.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log-sender.d.ts","sourceRoot":"","sources":["../src/log-sender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,GAAG,EAAoB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAU,UAAU,EAAe,MAAM,eAAe,CAAC;AAQhE,qBACa,SAAU,SAAQ,KAAK;IAQD,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB;IACpD,QAAQ,CAAC,UAAU,EAAE,UAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IACvC,QAAQ,CAAC,GAAG,EAAE,GAAG;IAVlC,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,sBAAsB,CAAC,CAAoB;IACnD,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,UAAU,CAAC,CAAS;gBAGY,iBAAiB,EAAE,iBAAiB,EAC3C,UAAU,EAAE,UAAU,EACR,SAAS,EAAE,SAAS,EACzC,GAAG,EAAE,GAAG;IAMlC,OAAO;IAIP,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,IAAI;YAuBE,UAAU;IA2BxB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,oBAAoB;CAK/B"}
|
package/dist/log-sender.js
CHANGED
|
@@ -25,12 +25,12 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
import { inject, injectable, Store } from '@servicetitan/react-ioc';
|
|
28
29
|
import axios from 'axios';
|
|
29
|
-
import { injectable, inject, Store } from '@servicetitan/react-ioc';
|
|
30
30
|
import { reaction } from 'mobx';
|
|
31
31
|
import { ConnectionService } from './connection-service';
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
32
|
+
import { Log, LOG_CONFIG_TOKEN } from './log';
|
|
33
|
+
import { lastId, LogStorage } from './log-storage';
|
|
34
34
|
const SECOND = 1000;
|
|
35
35
|
const DEFAULT_SEND_INTERVAL = 60 * SECOND;
|
|
36
36
|
const INITIAL_RETRY_INTERVAL = SECOND;
|
package/dist/log-sender.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log-sender.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../src/log-sender.ts"],"sourcesContent":["import { inject, injectable, Store } from '@servicetitan/react-ioc';\nimport axios from 'axios';\nimport { IReactionDisposer, reaction } from 'mobx';\nimport { ConnectionService } from './connection-service';\nimport type { LogConfig } from './log';\nimport { Log, LOG_CONFIG_TOKEN } from './log';\nimport { lastId, LogStorage, StorageItem } from './log-storage';\n\nconst SECOND = 1000;\nconst DEFAULT_SEND_INTERVAL = 60 * SECOND;\nconst INITIAL_RETRY_INTERVAL = SECOND;\nconst MAX_RETRY_INTERVAL = INITIAL_RETRY_INTERVAL * 512;\nconst BATCH_SIZE = 128;\n\n@injectable()\nexport class LogSender extends Store {\n private inSendFailedScenario = false;\n private isSending = false;\n private onItemsChangedDisposer?: IReactionDisposer;\n private sendInterval = DEFAULT_SEND_INTERVAL;\n private intervalId?: number;\n\n constructor(\n @inject(ConnectionService) readonly connectionService: ConnectionService,\n @inject(LogStorage) readonly logStorage: LogStorage,\n @inject(LOG_CONFIG_TOKEN) private readonly logConfig: LogConfig,\n @inject(Log) readonly log: Log\n ) {\n super();\n this.setRegularSendScenario();\n }\n\n dispose() {\n window.clearInterval(this.intervalId);\n }\n\n private onItemsChanged(items: StorageItem[]) {\n if (items.length >= BATCH_SIZE) {\n this.send();\n }\n }\n\n private setSendInterval(interval: number) {\n this.sendInterval = interval;\n window.clearInterval(this.intervalId);\n this.intervalId = window.setInterval(() => {\n if (this.logStorage.items.length > 0) {\n this.send();\n }\n }, interval);\n }\n\n private send() {\n // If offline, punt\n if (!this.connectionService.online) {\n return;\n }\n\n /*\n * Using Web Locks API to prevent multiple tabs from simultaneously\n * sending previously saved items. If the API isn't available, ¯\\_(ツ)_/¯\n */\n if (!('locks' in globalThis.navigator)) {\n this.sendEvents();\n return;\n }\n\n // eslint-disable-next-line no-restricted-globals\n navigator.locks.request(this.logConfig.storageKey, { ifAvailable: true }, async lock => {\n if (lock) {\n await this.sendEvents();\n }\n });\n }\n\n private async sendEvents() {\n if (this.isSending) {\n return;\n }\n\n this.isSending = true;\n try {\n const logEvents = this.logStorage.loadBatch(BATCH_SIZE);\n if (logEvents.length) {\n await axios.post(this.logConfig.endpoint, logEvents);\n this.logStorage.deleteToId(lastId(logEvents));\n\n if (this.inSendFailedScenario) {\n this.setRegularSendScenario();\n }\n }\n } catch (e) {\n this.setFailedSendScenario();\n /* istanbul ignore next */\n if (process.env.NODE_ENV !== 'test') {\n throw e;\n }\n } finally {\n this.isSending = false;\n }\n }\n\n private setRegularSendScenario() {\n this.inSendFailedScenario = false;\n this.setSendInterval(DEFAULT_SEND_INTERVAL);\n this.onItemsChangedDisposer = reaction(\n () => this.logStorage.items,\n items => this.onItemsChanged(items)\n );\n }\n\n private setFailedSendScenario() {\n if (this.inSendFailedScenario) {\n this.increaseSendInterval();\n return;\n }\n\n this.inSendFailedScenario = true;\n this.setSendInterval(INITIAL_RETRY_INTERVAL);\n this.onItemsChangedDisposer?.();\n }\n\n private increaseSendInterval() {\n if (this.sendInterval < MAX_RETRY_INTERVAL) {\n this.setSendInterval(this.sendInterval * 2);\n }\n }\n}\n"],"names":["inject","injectable","Store","axios","reaction","ConnectionService","Log","LOG_CONFIG_TOKEN","lastId","LogStorage","SECOND","DEFAULT_SEND_INTERVAL","INITIAL_RETRY_INTERVAL","MAX_RETRY_INTERVAL","BATCH_SIZE","LogSender","dispose","window","clearInterval","intervalId","onItemsChanged","items","length","send","setSendInterval","interval","sendInterval","setInterval","logStorage","connectionService","online","globalThis","navigator","sendEvents","locks","request","logConfig","storageKey","ifAvailable","lock","isSending","logEvents","loadBatch","post","endpoint","deleteToId","inSendFailedScenario","setRegularSendScenario","e","setFailedSendScenario","process","env","NODE_ENV","onItemsChangedDisposer","increaseSendInterval","log"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-service.d.ts","sourceRoot":"","sources":["../src/log-service.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log-service.d.ts","sourceRoot":"","sources":["../src/log-service.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAW,MAAM,OAAO,CAAC;AAOvD,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA2B1C,CAAC"}
|
package/dist/log-service.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
2
|
import { Provider, useDependencies, useOptionalDependencies } from '@servicetitan/react-ioc';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
4
|
import { ConnectionService } from './connection-service';
|
|
5
5
|
import { LOG_PARENT_TOKEN, Log } from './log';
|
|
6
6
|
import { LOG_CONFIG_TOKEN, defaultLogConfig } from './log-config';
|
package/dist/log-service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log-service.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/log-service.tsx"],"sourcesContent":["import {\n Provider,\n ProviderProps,\n useDependencies,\n useOptionalDependencies,\n} from '@servicetitan/react-ioc';\nimport { FC, PropsWithChildren, useMemo } from 'react';\nimport { ConnectionService } from './connection-service';\nimport { LOG_PARENT_TOKEN, Log } from './log';\nimport { LOG_CONFIG_TOKEN, defaultLogConfig } from './log-config';\nimport { LogSender } from './log-sender';\nimport { LogStorage } from './log-storage';\n\nexport interface LogServiceProps extends PropsWithChildren {\n endpoint?: string;\n storageKey?: string;\n}\n\nexport const LogService: FC<LogServiceProps> = ({\n children,\n endpoint = defaultLogConfig.endpoint,\n storageKey = defaultLogConfig.storageKey,\n}) => {\n const [parentLog] = useOptionalDependencies(Log);\n\n const singletons = useMemo(() => {\n const result: ProviderProps['singletons'] = [\n { provide: LOG_CONFIG_TOKEN, useValue: { endpoint, storageKey } },\n ConnectionService,\n Log,\n LogStorage,\n LogSender,\n ];\n if (parentLog) {\n result.push({ provide: LOG_PARENT_TOKEN, useValue: parentLog });\n }\n return result;\n }, [endpoint, parentLog, storageKey]);\n\n return (\n <Provider singletons={singletons}>\n <InitializeLogSender />\n {children}\n </Provider>\n );\n};\n\nconst InitializeLogSender: FC = () => {\n useDependencies(LogSender);\n return null;\n};\n"],"names":["Provider","useDependencies","useOptionalDependencies","useMemo","ConnectionService","LOG_PARENT_TOKEN","Log","LOG_CONFIG_TOKEN","defaultLogConfig","LogSender","LogStorage","LogService","children","endpoint","storageKey","parentLog","singletons","result","provide","useValue","push","InitializeLogSender"],"mappings":";AAAA,SACIA,QAAQ,EAERC,eAAe,EACfC,uBAAuB,QACpB,0BAA0B;AACjC,SAAgCC,OAAO,QAAQ,QAAQ;AACvD,SAASC,iBAAiB,QAAQ,uBAAuB;AACzD,SAASC,gBAAgB,EAAEC,GAAG,QAAQ,QAAQ;AAC9C,SAASC,gBAAgB,EAAEC,gBAAgB,QAAQ,eAAe;AAClE,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,UAAU,QAAQ,gBAAgB;AAO3C,OAAO,MAAMC,aAAkC,CAAC,EAC5CC,QAAQ,EACRC,WAAWL,iBAAiBK,QAAQ,EACpCC,aAAaN,iBAAiBM,UAAU,EAC3C;IACG,MAAM,CAACC,UAAU,GAAGb,wBAAwBI;IAE5C,MAAMU,aAAab,QAAQ;QACvB,MAAMc,SAAsC;YACxC;gBAAEC,SAASX;gBAAkBY,UAAU;oBAAEN;oBAAUC;gBAAW;YAAE;YAChEV;YACAE;YACAI;YACAD;SACH;QACD,IAAIM,WAAW;YACXE,OAAOG,IAAI,CAAC;gBAAEF,SAASb;gBAAkBc,UAAUJ;YAAU;QACjE;QACA,OAAOE;IACX,GAAG;QAACJ;QAAUE;QAAWD;KAAW;IAEpC,qBACI,MAACd;QAASgB,YAAYA;;0BAClB,KAACK;YACAT;;;AAGb,EAAE;AAEF,MAAMS,sBAA0B;IAC5BpB,gBAAgBQ;IAChB,OAAO;AACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-storage.d.ts","sourceRoot":"","sources":["../src/log-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"log-storage.d.ts","sourceRoot":"","sources":["../src/log-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACrB;AAWD,qBACa,UAAW,SAAQ,KAAK;IAUK,OAAO,CAAC,QAAQ,CAAC,SAAS;IARhE,KAAK,EAAE,WAAW,EAAE,CAAM;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAK;IAE7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAmB;gBAEoB,SAAS,EAAE,SAAS;IA0B3E,OAAO;IAIP,IAAI,MAAM,IAAI,SAAS,CAEtB;IAED,KAAK,CAAC,KAAK,EAAE,aAAa;IAgB1B,UAAU,CAAC,EAAE,EAAE,MAAM;IAcrB,SAAS,CAAC,SAAS,EAAE,MAAM;IAI3B,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,QAAQ;IAKhB,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,CAAC,cAAc;CAIzB;AAMD,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAMnD"}
|
package/dist/log-storage.js
CHANGED
|
@@ -26,7 +26,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
import { inject, injectable, Store } from '@servicetitan/react-ioc';
|
|
29
|
-
import {
|
|
29
|
+
import { action, makeObservable, observable, toJS } from 'mobx';
|
|
30
30
|
import { LOG_CONFIG_TOKEN } from './log-config';
|
|
31
31
|
var EventType = /*#__PURE__*/ function(EventType) {
|
|
32
32
|
EventType["Delete"] = "delete";
|
|
@@ -83,7 +83,7 @@ export class LogStorage extends Store {
|
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
this.setItems(items);
|
|
86
|
-
} catch (
|
|
86
|
+
} catch (unused) {
|
|
87
87
|
this.setItems([]);
|
|
88
88
|
}
|
|
89
89
|
}
|
package/dist/log-storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log-storage.ts"],"sourcesContent":["import { inject, injectable, Store } from '@servicetitan/react-ioc';\nimport { observable, action, makeObservable, toJS } from 'mobx';\n\nimport { EntryComplete, Nullable } from './log';\nimport type { LogConfig } from './log-config';\nimport { LOG_CONFIG_TOKEN } from './log-config';\n\nexport interface StorageItem {\n id: number;\n type: string;\n category: Nullable<string>;\n code: Nullable<string>;\n message: Nullable<string>;\n data: string;\n exception: string;\n}\n\nenum EventType {\n Delete = 'delete',\n}\n\ninterface DeleteEvent {\n type: EventType;\n items: StorageItem[];\n}\n\n@injectable()\nexport class LogStorage extends Store {\n @observable\n items: StorageItem[] = [];\n\n private readonly maxLogSize = 1000;\n private readonly version = 1;\n\n private nextItemId: number;\n private channel?: BroadcastChannel;\n\n constructor(@inject(LOG_CONFIG_TOKEN) private readonly logConfig: LogConfig) {\n super();\n makeObservable(this);\n\n const version = window.parseInt(localStorage.getItem(this.storageVersionKey) as string);\n if (version !== this.version) {\n localStorage.removeItem(this.storageKey);\n localStorage.setItem(this.storageVersionKey, String(this.version));\n }\n\n this.loadSavedItems();\n this.nextItemId = lastId(this.items) + 1;\n\n /*\n * Use the BroadcastChannel API to prevent different tabs from processing\n * the saved items. The first one to process the items sends a \"delete\" event\n * that causes all other instances to discard them from memory.\n */\n if ('BroadcastChannel' in globalThis) {\n this.channel = new BroadcastChannel(logConfig.storageKey);\n this.channel.addEventListener('message', ({ data }: MessageEvent<DeleteEvent>) =>\n this.handleDeleteEvent(data)\n );\n }\n }\n\n dispose() {\n this.channel?.close();\n }\n\n get config(): LogConfig {\n return this.logConfig;\n }\n\n store(entry: EntryComplete) {\n const item: StorageItem = {\n id: this.nextItemId++,\n type: entry.type,\n category: entry.category,\n code: entry.code,\n message: entry.message,\n data: JSON.stringify(entry.data),\n exception: this.stringifyError(entry.error),\n };\n\n let items = [...this.items, item];\n items = items.slice(-this.maxLogSize);\n this.setItems(items);\n }\n\n deleteToId(id: number) {\n const deletedItems: StorageItem[] = [];\n const items = this.items.filter(item => {\n if (item.id > id) {\n return true;\n }\n deletedItems.push(item);\n return false;\n });\n\n this.setItems(items);\n this.postDeleteEvent(deletedItems);\n }\n\n loadBatch(batchSize: number) {\n return this.items.slice(0, batchSize);\n }\n\n private loadSavedItems() {\n try {\n const items = JSON.parse(localStorage.getItem(this.storageKey) as string) ?? [];\n\n /* migrate error -> exception */\n items.forEach((item: StorageItem & { error?: string }) => {\n if (typeof item.error === 'string') {\n item.exception = item.error;\n delete item.error;\n }\n });\n this.setItems(items);\n } catch {\n this.setItems([]);\n }\n }\n\n private postDeleteEvent(items: StorageItem[]) {\n if (this.channel) {\n const event: DeleteEvent = {\n type: EventType.Delete,\n items: items.map(item => toJS(item)),\n };\n this.channel.postMessage(event);\n }\n }\n\n private handleDeleteEvent(event: DeleteEvent) {\n /* istanbul ignore next: because there's only one event type */\n if (event.type !== EventType.Delete) {\n return;\n }\n\n // Map item id to object for fast lookup\n const map = new Map<number, StorageItem>(event.items.map(item => [item.id, item]));\n\n // Discard deleted items\n const items = this.items.filter(item => !isEqual(item, map.get(item.id)));\n this.setItems(items);\n\n // If no more items, close channel; all saved items have been processed\n if (items.length === 0 && this.channel) {\n this.channel.close();\n delete this.channel;\n }\n }\n\n @action\n private setItems(items: StorageItem[]) {\n this.items = [...items];\n localStorage.setItem(this.storageKey, JSON.stringify(this.items));\n }\n\n private get storageKey() {\n return this.logConfig.storageKey;\n }\n\n private get storageVersionKey() {\n return `${this.storageKey}Version`;\n }\n\n private stringifyError(error: Nullable<Error>) {\n const detail = error ? { message: error.message.toString(), stack: error.stack } : null;\n return JSON.stringify(detail);\n }\n}\n\nfunction isEqual(a: StorageItem, b?: StorageItem) {\n return b && Object.keys(a).every((key: keyof StorageItem) => a[key] === b[key]);\n}\n\nexport function lastId(items: StorageItem[]): number {\n if (!items.length) {\n return 0;\n }\n const item = items[items.length - 1];\n return item.id;\n}\n"],"names":["inject","injectable","Store","observable","action","makeObservable","toJS","LOG_CONFIG_TOKEN","EventType","LogStorage","dispose","channel","close","config","logConfig","store","entry","item","id","nextItemId","type","category","code","message","data","JSON","stringify","exception","stringifyError","error","items","slice","maxLogSize","setItems","deleteToId","deletedItems","filter","push","postDeleteEvent","loadBatch","batchSize","loadSavedItems","parse","localStorage","getItem","storageKey","forEach","event","map","postMessage","handleDeleteEvent","Map","isEqual","get","length","setItem","storageVersionKey","detail","toString","stack","version","window","parseInt","removeItem","String","lastId","globalThis","BroadcastChannel","addEventListener","a","b","Object","keys","every","key"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/log-storage.ts"],"sourcesContent":["import { inject, injectable, Store } from '@servicetitan/react-ioc';\nimport { action, makeObservable, observable, toJS } from 'mobx';\nimport { EntryComplete, Nullable } from './log';\nimport type { LogConfig } from './log-config';\nimport { LOG_CONFIG_TOKEN } from './log-config';\n\nexport interface StorageItem {\n id: number;\n type: string;\n category: Nullable<string>;\n code: Nullable<string>;\n message: Nullable<string>;\n data: string;\n exception: string;\n}\n\nenum EventType {\n Delete = 'delete',\n}\n\ninterface DeleteEvent {\n type: EventType;\n items: StorageItem[];\n}\n\n@injectable()\nexport class LogStorage extends Store {\n @observable\n items: StorageItem[] = [];\n\n private readonly maxLogSize = 1000;\n private readonly version = 1;\n\n private nextItemId: number;\n private channel?: BroadcastChannel;\n\n constructor(@inject(LOG_CONFIG_TOKEN) private readonly logConfig: LogConfig) {\n super();\n makeObservable(this);\n\n const version = window.parseInt(localStorage.getItem(this.storageVersionKey) as string);\n if (version !== this.version) {\n localStorage.removeItem(this.storageKey);\n localStorage.setItem(this.storageVersionKey, String(this.version));\n }\n\n this.loadSavedItems();\n this.nextItemId = lastId(this.items) + 1;\n\n /*\n * Use the BroadcastChannel API to prevent different tabs from processing\n * the saved items. The first one to process the items sends a \"delete\" event\n * that causes all other instances to discard them from memory.\n */\n if ('BroadcastChannel' in globalThis) {\n this.channel = new BroadcastChannel(logConfig.storageKey);\n this.channel.addEventListener('message', ({ data }: MessageEvent<DeleteEvent>) =>\n this.handleDeleteEvent(data)\n );\n }\n }\n\n dispose() {\n this.channel?.close();\n }\n\n get config(): LogConfig {\n return this.logConfig;\n }\n\n store(entry: EntryComplete) {\n const item: StorageItem = {\n id: this.nextItemId++,\n type: entry.type,\n category: entry.category,\n code: entry.code,\n message: entry.message,\n data: JSON.stringify(entry.data),\n exception: this.stringifyError(entry.error),\n };\n\n let items = [...this.items, item];\n items = items.slice(-this.maxLogSize);\n this.setItems(items);\n }\n\n deleteToId(id: number) {\n const deletedItems: StorageItem[] = [];\n const items = this.items.filter(item => {\n if (item.id > id) {\n return true;\n }\n deletedItems.push(item);\n return false;\n });\n\n this.setItems(items);\n this.postDeleteEvent(deletedItems);\n }\n\n loadBatch(batchSize: number) {\n return this.items.slice(0, batchSize);\n }\n\n private loadSavedItems() {\n try {\n const items = JSON.parse(localStorage.getItem(this.storageKey) as string) ?? [];\n\n /* migrate error -> exception */\n items.forEach((item: StorageItem & { error?: string }) => {\n if (typeof item.error === 'string') {\n item.exception = item.error;\n delete item.error;\n }\n });\n this.setItems(items);\n } catch {\n this.setItems([]);\n }\n }\n\n private postDeleteEvent(items: StorageItem[]) {\n if (this.channel) {\n const event: DeleteEvent = {\n type: EventType.Delete,\n items: items.map(item => toJS(item)),\n };\n this.channel.postMessage(event);\n }\n }\n\n private handleDeleteEvent(event: DeleteEvent) {\n /* istanbul ignore next: because there's only one event type */\n if (event.type !== EventType.Delete) {\n return;\n }\n\n // Map item id to object for fast lookup\n const map = new Map<number, StorageItem>(event.items.map(item => [item.id, item]));\n\n // Discard deleted items\n const items = this.items.filter(item => !isEqual(item, map.get(item.id)));\n this.setItems(items);\n\n // If no more items, close channel; all saved items have been processed\n if (items.length === 0 && this.channel) {\n this.channel.close();\n delete this.channel;\n }\n }\n\n @action\n private setItems(items: StorageItem[]) {\n this.items = [...items];\n localStorage.setItem(this.storageKey, JSON.stringify(this.items));\n }\n\n private get storageKey() {\n return this.logConfig.storageKey;\n }\n\n private get storageVersionKey() {\n return `${this.storageKey}Version`;\n }\n\n private stringifyError(error: Nullable<Error>) {\n const detail = error ? { message: error.message.toString(), stack: error.stack } : null;\n return JSON.stringify(detail);\n }\n}\n\nfunction isEqual(a: StorageItem, b?: StorageItem) {\n return b && Object.keys(a).every((key: keyof StorageItem) => a[key] === b[key]);\n}\n\nexport function lastId(items: StorageItem[]): number {\n if (!items.length) {\n return 0;\n }\n const item = items[items.length - 1];\n return item.id;\n}\n"],"names":["inject","injectable","Store","action","makeObservable","observable","toJS","LOG_CONFIG_TOKEN","EventType","LogStorage","dispose","channel","close","config","logConfig","store","entry","item","id","nextItemId","type","category","code","message","data","JSON","stringify","exception","stringifyError","error","items","slice","maxLogSize","setItems","deleteToId","deletedItems","filter","push","postDeleteEvent","loadBatch","batchSize","loadSavedItems","parse","localStorage","getItem","storageKey","forEach","event","map","postMessage","handleDeleteEvent","Map","isEqual","get","length","setItem","storageVersionKey","detail","toString","stack","version","window","parseInt","removeItem","String","lastId","globalThis","BroadcastChannel","addEventListener","a","b","Object","keys","every","key"],"mappings":"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"}
|
package/dist/log.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LogStorage } from './log-storage';
|
|
2
|
-
export type { LogConfig } from './log-config';
|
|
3
2
|
export { LOG_CONFIG_TOKEN } from './log-config';
|
|
3
|
+
export type { LogConfig } from './log-config';
|
|
4
4
|
export interface ArbitraryData extends Record<string, boolean | number | string | Date> {
|
|
5
5
|
}
|
|
6
6
|
export interface LogEntry {
|
package/dist/log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,aAAc,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAAG;AAE1F,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,OAAQ,SAAQ,QAAQ;CAAG;AAE5C,MAAM,WAAW,UAAW,SAAQ,QAAQ;CAAG;AAE/C,MAAM,WAAW,QAAS,SAAQ,QAAQ;IACtC,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,IAAI;IACjB,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACxD;AAED,oBAAY,YAAY;IACpB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,KAAK,UAAU;CAClB;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG;IAC7C,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,oDAAuC,CAAC;AAYrE,qBACa,GAAI,YAAW,IAAI;IAIJ,OAAO,CAAC,QAAQ,CAAC,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAJlE,OAAO,CAAC,eAAe,CAAkB;gBAGA,UAAU,EAAE,UAAU,EACJ,MAAM,CAAC,EAAE,GAAG,YAAA;IAMvE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK1B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAKhC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,WAAmB,EAAE;;KAAK,GAAG,IAAI;IAa1D,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,QAAQ;CAUnB"}
|
package/dist/log.js
CHANGED
|
@@ -25,8 +25,8 @@ function _ts_param(paramIndex, decorator) {
|
|
|
25
25
|
decorator(target, key, paramIndex);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
+
import { inject, injectable, optional, symbolToken } from '@servicetitan/react-ioc';
|
|
28
29
|
import throttle from 'lodash.throttle';
|
|
29
|
-
import { injectable, inject, optional, symbolToken } from '@servicetitan/react-ioc';
|
|
30
30
|
import { defaultLogConfig } from './log-config';
|
|
31
31
|
import { LogStorage } from './log-storage';
|
|
32
32
|
import { serializeWithMetadata } from './serialize-with-metadata';
|
|
@@ -62,9 +62,9 @@ export class Log {
|
|
|
62
62
|
var _this_parent;
|
|
63
63
|
(_this_parent = this.parent) === null || _this_parent === void 0 ? void 0 : _this_parent.error(entry);
|
|
64
64
|
if (!skipConsole) {
|
|
65
|
-
var
|
|
65
|
+
var _ref, _ref1;
|
|
66
66
|
// eslint-disable-next-line no-console
|
|
67
|
-
console.error('@log-service/error', entry, ensureError((_ref = (
|
|
67
|
+
console.error('@log-service/error', entry, ensureError((_ref = (_ref1 = entry === null || entry === void 0 ? void 0 : entry.error) !== null && _ref1 !== void 0 ? _ref1 : entry === null || entry === void 0 ? void 0 : entry.message) !== null && _ref !== void 0 ? _ref : 'Undefined entry'));
|
|
68
68
|
}
|
|
69
69
|
return this.errorLogHandler.handle(this.expandError(entry)); // with errorLogHandler throttling
|
|
70
70
|
}
|
|
@@ -221,7 +221,7 @@ function plugins() {
|
|
|
221
221
|
p.filename,
|
|
222
222
|
p.description
|
|
223
223
|
].join(',')).join('/');
|
|
224
|
-
} catch (
|
|
224
|
+
} catch (unused) {
|
|
225
225
|
return 'unknown';
|
|
226
226
|
}
|
|
227
227
|
}
|
package/dist/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["import throttle from 'lodash.throttle';\nimport { injectable, inject, optional, symbolToken } from '@servicetitan/react-ioc';\n\nimport { defaultLogConfig } from './log-config';\nimport { LogStorage } from './log-storage';\nimport { serializeWithMetadata } from './serialize-with-metadata';\n\nexport type { LogConfig } from './log-config';\nexport { LOG_CONFIG_TOKEN } from './log-config';\n\nexport interface ArbitraryData extends Record<string, boolean | number | string | Date> {}\n\nexport interface LogEntry {\n category?: string;\n code?: string;\n message?: string;\n data?: ArbitraryData;\n}\n\nexport interface LogInfo extends LogEntry {}\n\nexport interface LogWarning extends LogEntry {}\n\nexport interface LogError extends LogEntry {\n error: unknown;\n}\n\nexport interface ErrorOptions {\n skipConsole?: boolean;\n}\n\nexport interface ILog {\n info(entry: LogInfo): void;\n warning(entry: LogWarning): void;\n error(entry: LogError, options?: ErrorOptions): void;\n}\n\nexport enum LogEntryType {\n Info = 'Info',\n Warning = 'Warning',\n Error = 'Error',\n}\n\nexport type Nullable<T> = T | null;\n\nexport interface EntryComplete {\n type: LogEntryType;\n category: Nullable<string>;\n code: Nullable<string>;\n message: Nullable<string>;\n data: ArbitraryData;\n error: Nullable<Error>;\n}\n\nexport type EntryCompleteError = EntryComplete & {\n error: Error;\n};\n\nexport const LOG_PARENT_TOKEN = symbolToken<Log>('LOG_PARENT_TOKEN');\n\nfunction ensureError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n if (typeof error === 'string') {\n return new Error(error);\n }\n return new Error(serializeWithMetadata(error));\n}\n\n@injectable()\nexport class Log implements ILog {\n private errorLogHandler: ErrorLogHandler;\n\n constructor(\n @inject(LogStorage) private readonly logStorage: LogStorage,\n @inject(LOG_PARENT_TOKEN) @optional() private readonly parent?: Log\n ) {\n this.validate();\n this.errorLogHandler = new ErrorLogHandler(this, this.logStorage);\n }\n\n info(entry: LogInfo): void {\n this.parent?.info(entry);\n return this.store(this.expand(LogEntryType.Info, entry));\n }\n\n warning(entry: LogWarning): void {\n this.parent?.warning(entry);\n return this.store(this.expand(LogEntryType.Warning, entry));\n }\n\n error(entry: LogError, { skipConsole = false } = {}): void {\n this.parent?.error(entry);\n if (!skipConsole) {\n // eslint-disable-next-line no-console\n console.error(\n '@log-service/error',\n entry,\n ensureError(entry?.error ?? entry?.message ?? 'Undefined entry')\n );\n }\n return this.errorLogHandler.handle(this.expandError(entry)); // with errorLogHandler throttling\n }\n\n private store(entry: EntryComplete) {\n return this.logStorage.store(entry);\n }\n\n private expand(type: LogEntryType, entry: LogEntry): EntryComplete {\n const data = {\n ...entry.data,\n ...this.dataDefault(),\n };\n\n return {\n type,\n category: null,\n message: null,\n code: null,\n ...entry,\n error: null,\n data,\n };\n }\n\n private expandError(entry: LogError): EntryCompleteError {\n let error: Error;\n if (entry.error instanceof Error) {\n error = entry.error;\n } else {\n error = new Error(serializeWithMetadata(entry.error));\n }\n\n const { message, ...rest } = this.expand(LogEntryType.Error, entry);\n\n return {\n message: message ?? error.message,\n ...rest,\n error,\n };\n }\n\n private dataDefault() {\n return {\n CreatedOn: new Date(),\n Online: window.navigator.onLine,\n Url: window.location.toString(),\n UserAgent: window.navigator.userAgent,\n Source: 'Frontend',\n Plugins: plugins(),\n ...timezoneInfo(),\n };\n }\n\n private validate() {\n if (!this.parent) {\n return;\n }\n\n const { endpoint, storageKey } = this.logStorage.config;\n if (endpoint === defaultLogConfig.endpoint || storageKey === defaultLogConfig.storageKey) {\n throw new Error('nested Log cannot use default configuration');\n }\n }\n}\n\nclass ErrorLogHandler {\n private logService: Log;\n private logStorage: LogStorage;\n\n private logTable = new HashTable<EntryCompleteError>();\n private repetitiveLogsCache = new HashTable<boolean>();\n\n private readonly cacheFlushDuration = 30000;\n private readonly throttleLogsDuration = 2000;\n\n private flushThrottled = throttle(() => this.flush(), this.throttleLogsDuration, {\n leading: false,\n trailing: true,\n });\n\n constructor(logService: Log, logStorage: LogStorage) {\n this.logService = logService;\n this.logStorage = logStorage;\n\n setInterval(() => this.repetitiveLogsCache.clear(), this.cacheFlushDuration);\n }\n\n handle(entry: EntryCompleteError) {\n this.add(entry);\n this.flushThrottled();\n }\n\n private add(entry: EntryCompleteError) {\n const key = this.keyFor(entry);\n if (this.repetitiveLogsCache.get(key)) {\n /* error is a repetitive error and has been reported, we don't need to report it again */\n return;\n }\n\n if (this.logTable.get(key) == null) {\n this.logTable.set(key, entry);\n } else {\n /* present in entry table, hence a duplicate, don't set, rather increase count */\n const entry = this.logTable.get(key) as EntryCompleteError & {\n data: { count?: number };\n };\n if (typeof entry.data.count === 'number') {\n entry.data.count++;\n } else {\n entry.data.count = 2;\n }\n this.logTable.set(key, entry);\n }\n }\n\n private keyFor(entry: EntryCompleteError) {\n return {\n message: entry.error.message,\n stack: entry.error.stack ?? '',\n };\n }\n\n private flush() {\n const hashes = this.logTable.getHashes();\n for (const key of hashes) {\n const entry = this.logTable.get(key);\n\n if ('count' in entry.data) {\n /* insert into cache if it is a repetitive error */\n this.repetitiveLogsCache.set(key, true);\n }\n\n this.logStorage.store(entry);\n }\n\n this.logTable.clear();\n }\n}\n\nclass HashTable<T> {\n private hashes: Record<string, T> = {};\n\n set(key: { message: string; stack: string }, value: T) {\n this.hashes[JSON.stringify(key)] = value;\n }\n\n get(key: { message: string; stack: string }): T {\n return this.hashes[JSON.stringify(key)];\n }\n\n getHashes() {\n return Object.keys(this.hashes).map(value => JSON.parse(value));\n }\n\n clear() {\n this.hashes = {};\n }\n}\n\nfunction plugins() {\n try {\n return Array.prototype.slice\n .call(window.navigator.plugins)\n .map(p => [p.name, p.filename, p.description].join(','))\n .join('/');\n } catch {\n return 'unknown';\n }\n}\n\nfunction timezoneInfo() {\n // https://stackoverflow.com/questions/11887934/how-to-check-if-dst-daylight-saving-time-is-in-effect-and-if-so-the-offset\n\n const now = new Date();\n const jan = new Date(now.getFullYear(), 0, 1);\n const jul = new Date(now.getFullYear(), 6, 1);\n\n const TzOffset = now.getTimezoneOffset();\n const IsDst = TzOffset < Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());\n const IsDstSubject = jan.getTimezoneOffset() !== jul.getTimezoneOffset();\n\n return {\n TzOffset,\n IsDst,\n IsDstSubject,\n };\n}\n"],"names":["throttle","injectable","inject","optional","symbolToken","defaultLogConfig","LogStorage","serializeWithMetadata","LOG_CONFIG_TOKEN","LogEntryType","LOG_PARENT_TOKEN","ensureError","error","Error","Log","info","entry","parent","store","expand","warning","skipConsole","console","message","errorLogHandler","handle","expandError","logStorage","type","data","dataDefault","category","code","rest","CreatedOn","Date","Online","window","navigator","onLine","Url","location","toString","UserAgent","userAgent","Source","Plugins","plugins","timezoneInfo","validate","endpoint","storageKey","config","ErrorLogHandler","add","flushThrottled","key","keyFor","repetitiveLogsCache","get","logTable","set","count","stack","flush","hashes","getHashes","clear","logService","HashTable","cacheFlushDuration","throttleLogsDuration","leading","trailing","setInterval","value","JSON","stringify","Object","keys","map","parse","Array","prototype","slice","call","p","name","filename","description","join","now","jan","getFullYear","jul","TzOffset","getTimezoneOffset","IsDst","Math","max","IsDstSubject"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/log.ts"],"sourcesContent":["import { inject, injectable, optional, symbolToken } from '@servicetitan/react-ioc';\nimport throttle from 'lodash.throttle';\nimport { defaultLogConfig } from './log-config';\nimport { LogStorage } from './log-storage';\nimport { serializeWithMetadata } from './serialize-with-metadata';\n\nexport { LOG_CONFIG_TOKEN } from './log-config';\nexport type { LogConfig } from './log-config';\n\nexport interface ArbitraryData extends Record<string, boolean | number | string | Date> {}\n\nexport interface LogEntry {\n category?: string;\n code?: string;\n message?: string;\n data?: ArbitraryData;\n}\n\nexport interface LogInfo extends LogEntry {}\n\nexport interface LogWarning extends LogEntry {}\n\nexport interface LogError extends LogEntry {\n error: unknown;\n}\n\nexport interface ErrorOptions {\n skipConsole?: boolean;\n}\n\nexport interface ILog {\n info(entry: LogInfo): void;\n warning(entry: LogWarning): void;\n error(entry: LogError, options?: ErrorOptions): void;\n}\n\nexport enum LogEntryType {\n Info = 'Info',\n Warning = 'Warning',\n Error = 'Error',\n}\n\nexport type Nullable<T> = T | null;\n\nexport interface EntryComplete {\n type: LogEntryType;\n category: Nullable<string>;\n code: Nullable<string>;\n message: Nullable<string>;\n data: ArbitraryData;\n error: Nullable<Error>;\n}\n\nexport type EntryCompleteError = EntryComplete & {\n error: Error;\n};\n\nexport const LOG_PARENT_TOKEN = symbolToken<Log>('LOG_PARENT_TOKEN');\n\nfunction ensureError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n if (typeof error === 'string') {\n return new Error(error);\n }\n return new Error(serializeWithMetadata(error));\n}\n\n@injectable()\nexport class Log implements ILog {\n private errorLogHandler: ErrorLogHandler;\n\n constructor(\n @inject(LogStorage) private readonly logStorage: LogStorage,\n @inject(LOG_PARENT_TOKEN) @optional() private readonly parent?: Log\n ) {\n this.validate();\n this.errorLogHandler = new ErrorLogHandler(this, this.logStorage);\n }\n\n info(entry: LogInfo): void {\n this.parent?.info(entry);\n return this.store(this.expand(LogEntryType.Info, entry));\n }\n\n warning(entry: LogWarning): void {\n this.parent?.warning(entry);\n return this.store(this.expand(LogEntryType.Warning, entry));\n }\n\n error(entry: LogError, { skipConsole = false } = {}): void {\n this.parent?.error(entry);\n if (!skipConsole) {\n // eslint-disable-next-line no-console\n console.error(\n '@log-service/error',\n entry,\n ensureError(entry?.error ?? entry?.message ?? 'Undefined entry')\n );\n }\n return this.errorLogHandler.handle(this.expandError(entry)); // with errorLogHandler throttling\n }\n\n private store(entry: EntryComplete) {\n return this.logStorage.store(entry);\n }\n\n private expand(type: LogEntryType, entry: LogEntry): EntryComplete {\n const data = {\n ...entry.data,\n ...this.dataDefault(),\n };\n\n return {\n type,\n category: null,\n message: null,\n code: null,\n ...entry,\n error: null,\n data,\n };\n }\n\n private expandError(entry: LogError): EntryCompleteError {\n let error: Error;\n if (entry.error instanceof Error) {\n error = entry.error;\n } else {\n error = new Error(serializeWithMetadata(entry.error));\n }\n\n const { message, ...rest } = this.expand(LogEntryType.Error, entry);\n\n return {\n message: message ?? error.message,\n ...rest,\n error,\n };\n }\n\n private dataDefault() {\n return {\n CreatedOn: new Date(),\n Online: window.navigator.onLine,\n Url: window.location.toString(),\n UserAgent: window.navigator.userAgent,\n Source: 'Frontend',\n Plugins: plugins(),\n ...timezoneInfo(),\n };\n }\n\n private validate() {\n if (!this.parent) {\n return;\n }\n\n const { endpoint, storageKey } = this.logStorage.config;\n if (endpoint === defaultLogConfig.endpoint || storageKey === defaultLogConfig.storageKey) {\n throw new Error('nested Log cannot use default configuration');\n }\n }\n}\n\nclass ErrorLogHandler {\n private logService: Log;\n private logStorage: LogStorage;\n\n private logTable = new HashTable<EntryCompleteError>();\n private repetitiveLogsCache = new HashTable<boolean>();\n\n private readonly cacheFlushDuration = 30000;\n private readonly throttleLogsDuration = 2000;\n\n private flushThrottled = throttle(() => this.flush(), this.throttleLogsDuration, {\n leading: false,\n trailing: true,\n });\n\n constructor(logService: Log, logStorage: LogStorage) {\n this.logService = logService;\n this.logStorage = logStorage;\n\n setInterval(() => this.repetitiveLogsCache.clear(), this.cacheFlushDuration);\n }\n\n handle(entry: EntryCompleteError) {\n this.add(entry);\n this.flushThrottled();\n }\n\n private add(entry: EntryCompleteError) {\n const key = this.keyFor(entry);\n if (this.repetitiveLogsCache.get(key)) {\n /* error is a repetitive error and has been reported, we don't need to report it again */\n return;\n }\n\n if (this.logTable.get(key) == null) {\n this.logTable.set(key, entry);\n } else {\n /* present in entry table, hence a duplicate, don't set, rather increase count */\n const entry = this.logTable.get(key) as EntryCompleteError & {\n data: { count?: number };\n };\n if (typeof entry.data.count === 'number') {\n entry.data.count++;\n } else {\n entry.data.count = 2;\n }\n this.logTable.set(key, entry);\n }\n }\n\n private keyFor(entry: EntryCompleteError) {\n return {\n message: entry.error.message,\n stack: entry.error.stack ?? '',\n };\n }\n\n private flush() {\n const hashes = this.logTable.getHashes();\n for (const key of hashes) {\n const entry = this.logTable.get(key);\n\n if ('count' in entry.data) {\n /* insert into cache if it is a repetitive error */\n this.repetitiveLogsCache.set(key, true);\n }\n\n this.logStorage.store(entry);\n }\n\n this.logTable.clear();\n }\n}\n\nclass HashTable<T> {\n private hashes: Record<string, T> = {};\n\n set(key: { message: string; stack: string }, value: T) {\n this.hashes[JSON.stringify(key)] = value;\n }\n\n get(key: { message: string; stack: string }): T {\n return this.hashes[JSON.stringify(key)];\n }\n\n getHashes() {\n return Object.keys(this.hashes).map(value => JSON.parse(value));\n }\n\n clear() {\n this.hashes = {};\n }\n}\n\nfunction plugins() {\n try {\n return Array.prototype.slice\n .call(window.navigator.plugins)\n .map(p => [p.name, p.filename, p.description].join(','))\n .join('/');\n } catch {\n return 'unknown';\n }\n}\n\nfunction timezoneInfo() {\n // https://stackoverflow.com/questions/11887934/how-to-check-if-dst-daylight-saving-time-is-in-effect-and-if-so-the-offset\n\n const now = new Date();\n const jan = new Date(now.getFullYear(), 0, 1);\n const jul = new Date(now.getFullYear(), 6, 1);\n\n const TzOffset = now.getTimezoneOffset();\n const IsDst = TzOffset < Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());\n const IsDstSubject = jan.getTimezoneOffset() !== jul.getTimezoneOffset();\n\n return {\n TzOffset,\n IsDst,\n IsDstSubject,\n };\n}\n"],"names":["inject","injectable","optional","symbolToken","throttle","defaultLogConfig","LogStorage","serializeWithMetadata","LOG_CONFIG_TOKEN","LogEntryType","LOG_PARENT_TOKEN","ensureError","error","Error","Log","info","entry","parent","store","expand","warning","skipConsole","console","message","errorLogHandler","handle","expandError","logStorage","type","data","dataDefault","category","code","rest","CreatedOn","Date","Online","window","navigator","onLine","Url","location","toString","UserAgent","userAgent","Source","Plugins","plugins","timezoneInfo","validate","endpoint","storageKey","config","ErrorLogHandler","add","flushThrottled","key","keyFor","repetitiveLogsCache","get","logTable","set","count","stack","flush","hashes","getHashes","clear","logService","HashTable","cacheFlushDuration","throttleLogsDuration","leading","trailing","setInterval","value","JSON","stringify","Object","keys","map","parse","Array","prototype","slice","call","p","name","filename","description","join","now","jan","getFullYear","jul","TzOffset","getTimezoneOffset","IsDst","Math","max","IsDstSubject"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/log-service",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
5
|
-
"homepage": "https://docs.st.dev/docs/frontend/log-service",
|
|
3
|
+
"version": "34.0.0",
|
|
4
|
+
"description": "Service to send events to Kibana logs via the backend log service",
|
|
5
|
+
"homepage": "https://docs.st.dev/docs/frontend/uikit/log-service",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/servicetitan/uikit.git",
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
"src"
|
|
17
17
|
],
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@servicetitan/react-ioc": "
|
|
19
|
+
"@servicetitan/react-ioc": "34.0.0",
|
|
20
20
|
"@testing-library/dom": "^10.4.1",
|
|
21
|
-
"@testing-library/react": "^16.3.
|
|
21
|
+
"@testing-library/react": "^16.3.2",
|
|
22
22
|
"@types/lodash.throttle": "~4.1.6",
|
|
23
|
-
"axios": "^1.
|
|
23
|
+
"axios": "^1.13.2",
|
|
24
24
|
"mobx": "~6.13.7",
|
|
25
25
|
"react": "~18.3.1"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@servicetitan/react-ioc": "
|
|
28
|
+
"@servicetitan/react-ioc": "34.0.0",
|
|
29
29
|
"axios": ">=0.30.0 <1 || ^1.8.3",
|
|
30
30
|
"mobx": ">=6.13.7",
|
|
31
31
|
"react": ">=17.0.2"
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"cli": {
|
|
40
40
|
"webpack": false
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "e193dc22703963f67099874a24de535d0696b6e2"
|
|
43
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { GlobalErrorHandler } from '../global-error-handler';
|
|
1
2
|
import { Log } from '../log';
|
|
2
3
|
import { serializeWithMetadata } from '../serialize-with-metadata';
|
|
3
|
-
import { GlobalErrorHandler } from '../global-error-handler';
|
|
4
4
|
|
|
5
5
|
describe(`[log-service] ${GlobalErrorHandler.name}`, () => {
|
|
6
6
|
const log: Pick<Log, 'error'> = { error: jest.fn() };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useDependencies } from '@servicetitan/react-ioc';
|
|
2
2
|
import { render } from '@testing-library/react';
|
|
3
3
|
import { FC } from 'react';
|
|
4
|
-
|
|
5
4
|
import { LOG_CONFIG_TOKEN, LogConfig } from '../log-config';
|
|
6
5
|
import { LogConfigProvider } from '../log-config-provider';
|
|
7
6
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { ConnectionService } from '../connection-service';
|
|
3
3
|
import { Log, LogConfig, LogEntryType, LogInfo, LogWarning } from '../log';
|
|
4
|
-
import { lastId, LogStorage } from '../log-storage';
|
|
5
|
-
|
|
6
4
|
import { LogSender } from '../log-sender';
|
|
5
|
+
import { lastId, LogStorage } from '../log-storage';
|
|
7
6
|
|
|
8
7
|
jest.mock('axios', () => ({ post: jest.fn() }));
|
|
9
8
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
1
|
import {
|
|
3
2
|
Provider,
|
|
4
3
|
ProviderProps,
|
|
@@ -6,11 +5,11 @@ import {
|
|
|
6
5
|
useOptionalDependencies,
|
|
7
6
|
} from '@servicetitan/react-ioc';
|
|
8
7
|
import { render } from '@testing-library/react';
|
|
8
|
+
import { FC } from 'react';
|
|
9
9
|
import { LOG_CONFIG_TOKEN, LOG_PARENT_TOKEN, Log, LogConfig } from '../log';
|
|
10
10
|
import { defaultLogConfig } from '../log-config';
|
|
11
|
-
import { LogStorage } from '../log-storage';
|
|
12
|
-
|
|
13
11
|
import { LogService, LogServiceProps } from '../log-service';
|
|
12
|
+
import { LogStorage } from '../log-storage';
|
|
14
13
|
|
|
15
14
|
describe(`[log-service] ${LogService.name}`, () => {
|
|
16
15
|
let props: LogServiceProps;
|
package/src/bind-log.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { Log, ArbitraryData } from './log';
|
|
1
|
+
import { inject, injectable } from '@servicetitan/react-ioc';
|
|
2
|
+
import { ArbitraryData, Log } from './log';
|
|
4
3
|
import { serializeWithMetadata } from './serialize-with-metadata';
|
|
5
4
|
|
|
6
5
|
interface ExtendedError extends Error {
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { bindLog } from './bind-log';
|
|
2
|
+
import { ConnectionService } from './connection-service';
|
|
3
|
+
import { GlobalErrorHandler } from './global-error-handler';
|
|
2
4
|
import {
|
|
3
5
|
ArbitraryData,
|
|
4
6
|
EntryComplete,
|
|
@@ -14,11 +16,9 @@ import {
|
|
|
14
16
|
LogWarning,
|
|
15
17
|
} from './log';
|
|
16
18
|
import { LogConfigProvider } from './log-config-provider';
|
|
17
|
-
import { LogStorage, StorageItem } from './log-storage';
|
|
18
19
|
import { LogSender } from './log-sender';
|
|
19
20
|
import { LogService } from './log-service';
|
|
20
|
-
import {
|
|
21
|
-
import { GlobalErrorHandler } from './global-error-handler';
|
|
21
|
+
import { LogStorage, StorageItem } from './log-storage';
|
|
22
22
|
|
|
23
23
|
export type {
|
|
24
24
|
ArbitraryData,
|
|
@@ -34,7 +34,6 @@ export type {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export {
|
|
37
|
-
bindLog,
|
|
38
37
|
ConnectionService,
|
|
39
38
|
GlobalErrorHandler,
|
|
40
39
|
LOG_CONFIG_TOKEN,
|
|
@@ -44,4 +43,5 @@ export {
|
|
|
44
43
|
LogSender,
|
|
45
44
|
LogService,
|
|
46
45
|
LogStorage,
|
|
46
|
+
bindLog,
|
|
47
47
|
};
|
package/src/log-sender.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
+
import { inject, injectable, Store } from '@servicetitan/react-ioc';
|
|
1
2
|
import axios from 'axios';
|
|
2
|
-
|
|
3
|
-
import { injectable, inject, Store } from '@servicetitan/react-ioc';
|
|
4
|
-
import { reaction, IReactionDisposer } from 'mobx';
|
|
5
|
-
|
|
3
|
+
import { IReactionDisposer, reaction } from 'mobx';
|
|
6
4
|
import { ConnectionService } from './connection-service';
|
|
7
5
|
import type { LogConfig } from './log';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { Log, LOG_CONFIG_TOKEN } from './log';
|
|
7
|
+
import { lastId, LogStorage, StorageItem } from './log-storage';
|
|
10
8
|
|
|
11
9
|
const SECOND = 1000;
|
|
12
10
|
const DEFAULT_SEND_INTERVAL = 60 * SECOND;
|
package/src/log-service.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
2
1
|
import {
|
|
3
2
|
Provider,
|
|
4
3
|
ProviderProps,
|
|
5
4
|
useDependencies,
|
|
6
5
|
useOptionalDependencies,
|
|
7
6
|
} from '@servicetitan/react-ioc';
|
|
7
|
+
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
8
8
|
import { ConnectionService } from './connection-service';
|
|
9
9
|
import { LOG_PARENT_TOKEN, Log } from './log';
|
|
10
10
|
import { LOG_CONFIG_TOKEN, defaultLogConfig } from './log-config';
|
package/src/log-storage.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { inject, injectable, Store } from '@servicetitan/react-ioc';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { action, makeObservable, observable, toJS } from 'mobx';
|
|
4
3
|
import { EntryComplete, Nullable } from './log';
|
|
5
4
|
import type { LogConfig } from './log-config';
|
|
6
5
|
import { LOG_CONFIG_TOKEN } from './log-config';
|
package/src/log.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import { inject, injectable, optional, symbolToken } from '@servicetitan/react-ioc';
|
|
1
2
|
import throttle from 'lodash.throttle';
|
|
2
|
-
import { injectable, inject, optional, symbolToken } from '@servicetitan/react-ioc';
|
|
3
|
-
|
|
4
3
|
import { defaultLogConfig } from './log-config';
|
|
5
4
|
import { LogStorage } from './log-storage';
|
|
6
5
|
import { serializeWithMetadata } from './serialize-with-metadata';
|
|
7
6
|
|
|
8
|
-
export type { LogConfig } from './log-config';
|
|
9
7
|
export { LOG_CONFIG_TOKEN } from './log-config';
|
|
8
|
+
export type { LogConfig } from './log-config';
|
|
10
9
|
|
|
11
10
|
export interface ArbitraryData extends Record<string, boolean | number | string | Date> {}
|
|
12
11
|
|