@servicetitan/web-components 30.0.0 → 30.1.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/contexts/mfe-data-context.d.ts +2 -4
- package/dist/contexts/mfe-data-context.d.ts.map +1 -1
- package/dist/contexts/mfe-data-context.js.map +1 -1
- package/dist/event-bus.d.ts +51 -15
- package/dist/event-bus.d.ts.map +1 -1
- package/dist/event-bus.js +46 -17
- package/dist/event-bus.js.map +1 -1
- package/dist/loader.d.ts +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +5 -2
- package/dist/loader.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/__tests__/event-bus-types.test.ts +507 -0
- package/src/__tests__/event-bus.test.ts +5 -18
- package/src/contexts/mfe-data-context.ts +2 -11
- package/src/event-bus.ts +105 -32
- package/src/loader.tsx +6 -1
- package/src/types.ts +10 -0
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context used to pass data from the host to the MFEs
|
|
3
3
|
*/
|
|
4
|
-
import { JSON,
|
|
5
|
-
export type MFEContextData<T> =
|
|
6
|
-
[P in keyof T]: T[P] extends JSONPrimitive ? T[P] : T[P] extends (infer U)[] ? MFEContextData<U>[] : T[P] extends JSON ? MFEContextData<T[P]> : never;
|
|
7
|
-
};
|
|
4
|
+
import { JSON, Serializable } from '../types';
|
|
5
|
+
export type MFEContextData<T> = Serializable<T>;
|
|
8
6
|
export declare const MFEDataContext: import("react").Context<JSON>;
|
|
9
7
|
export declare function useMFEDataContext<T extends MFEContextData<T>>(): T;
|
|
10
8
|
//# sourceMappingURL=mfe-data-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mfe-data-context.d.ts","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"mfe-data-context.d.ts","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;AAEhD,eAAO,MAAM,cAAc,+BAA0B,CAAC;AAEtD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,OAI5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mfe-data-context.js","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"mfe-data-context.js","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAKlD,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAO,EAAE,CAAC,CAAC;AAEtD,MAAM,UAAU,iBAAiB;IAC7B,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAM,CAAC;IAEhD,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
package/dist/event-bus.d.ts
CHANGED
|
@@ -1,25 +1,61 @@
|
|
|
1
1
|
import { SymbolToken } from '@servicetitan/react-ioc';
|
|
2
|
-
import { JSON } from './types';
|
|
3
|
-
export
|
|
2
|
+
import { JSON, JSONPrimitive, Serializable } from './types';
|
|
3
|
+
export declare const EVENT_BUS_TOKEN: SymbolToken<EventBus<never>>;
|
|
4
|
+
export declare function typedEventBusToken<EventTypes extends Serializable<EventTypes>>(): SymbolToken<EventBus<EventTypes>>;
|
|
5
|
+
export type EventHandler<EventTypes, Event> = (data: Event extends SymbolToken<infer DataType> ? Serializable<DataType> : Event extends keyof EventTypes ? EventTypes[Event] : never) => void;
|
|
4
6
|
type JobPayload = JSON | void;
|
|
5
|
-
export type JobEventHandler<
|
|
6
|
-
|
|
7
|
+
export type JobEventHandler<Event> = (defer: {
|
|
8
|
+
/**
|
|
9
|
+
* Successfully complete a job.
|
|
10
|
+
* @param result The value to return from the successfully completed job.
|
|
11
|
+
*/
|
|
12
|
+
resolve(...result: Event extends SymbolToken<infer ResultType> ? undefined extends ResultType ? [Serializable<ResultType>?] : [Serializable<ResultType>] : [JobPayload]): void;
|
|
13
|
+
/**
|
|
14
|
+
* Fail a job.
|
|
15
|
+
* @param reason The error to return from the failed job.
|
|
16
|
+
*/
|
|
7
17
|
reject(reason?: string | Error): void;
|
|
8
18
|
}) => void;
|
|
9
|
-
export
|
|
10
|
-
export type SymbolTokenEventType<T, U extends EventType = EventType> = U extends SymbolToken<any> ? SymbolToken<T> : U;
|
|
11
|
-
export declare const EVENT_BUS_TOKEN: SymbolToken<EventBus>;
|
|
12
|
-
export declare class EventBus {
|
|
19
|
+
export declare class EventBus<EventTypes extends Serializable<EventTypes> = never> {
|
|
13
20
|
job: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Register a job event handler. Jobs event handlers return a result or an error.
|
|
23
|
+
* @param event The job event to handle.
|
|
24
|
+
* @param handler The handler to call when the event occurs. This handler is passed a `resolve` callback to return a successful result, and a `reject` callback to return an error.
|
|
25
|
+
*/
|
|
26
|
+
on: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event, handler: JobEventHandler<Event>) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Deregister a job event handler.
|
|
29
|
+
* @param event The previously registered event.
|
|
30
|
+
* @param handler The previously registered handler.
|
|
31
|
+
*/
|
|
32
|
+
off: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event, handler: JobEventHandler<Event>) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Send a job event.
|
|
35
|
+
* @param event The event to send.
|
|
36
|
+
* @returns a Promise that resolves or rejects depending on whether the job completes successfully.
|
|
37
|
+
*/
|
|
38
|
+
emit: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event) => Promise<Event extends SymbolToken<infer ResultType> ? Serializable<ResultType> : JobPayload>;
|
|
17
39
|
};
|
|
18
40
|
private emitter;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Register an event handler.
|
|
43
|
+
* @param event The event to handle.
|
|
44
|
+
* @param handler The handler to call when the event occurs.
|
|
45
|
+
*/
|
|
46
|
+
on: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event, handler: EventHandler<EventTypes, Event>) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Deregister an event handler.
|
|
49
|
+
* @param event The previously registered event.
|
|
50
|
+
* @param handler The previously registered handler.
|
|
51
|
+
*/
|
|
52
|
+
off: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event, handler: EventHandler<EventTypes, Event>) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Send an event.
|
|
55
|
+
* @param event The event to send.
|
|
56
|
+
* @param data The data to pass to the event's handler.
|
|
57
|
+
*/
|
|
58
|
+
emit: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event, ...data: Event extends SymbolToken<infer DataType> ? undefined extends DataType ? [Serializable<DataType>?] : [Serializable<DataType>] : [EventTypes] extends [never] ? [(JSON | JSONPrimitive)?] : Event extends keyof EventTypes ? undefined extends EventTypes[Event] ? [EventTypes[Event]?] : [EventTypes[Event]] extends [never] ? [] : [EventTypes[Event]] : never) => void;
|
|
22
59
|
}
|
|
23
|
-
export declare function useEventBus(): EventBus;
|
|
24
60
|
export {};
|
|
25
61
|
//# sourceMappingURL=event-bus.d.ts.map
|
package/dist/event-bus.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"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"}
|
package/dist/event-bus.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import mitt from 'mitt';
|
|
2
1
|
import { symbolToken } from '@servicetitan/react-ioc';
|
|
3
|
-
import
|
|
2
|
+
import mitt from 'mitt';
|
|
4
3
|
export const EVENT_BUS_TOKEN = symbolToken('EVENT_BUS_TOKEN');
|
|
4
|
+
export function typedEventBusToken() {
|
|
5
|
+
return symbolToken('EVENT_BUS_TOKEN');
|
|
6
|
+
}
|
|
5
7
|
export class EventBus {
|
|
6
8
|
constructor() {
|
|
7
9
|
Object.defineProperty(this, "job", {
|
|
@@ -9,15 +11,30 @@ export class EventBus {
|
|
|
9
11
|
configurable: true,
|
|
10
12
|
writable: true,
|
|
11
13
|
value: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Register a job event handler. Jobs event handlers return a result or an error.
|
|
16
|
+
* @param event The job event to handle.
|
|
17
|
+
* @param handler The handler to call when the event occurs. This handler is passed a `resolve` callback to return a successful result, and a `reject` callback to return an error.
|
|
18
|
+
*/
|
|
19
|
+
on: (event, handler) => {
|
|
20
|
+
this.emitter.on(event, handler);
|
|
14
21
|
},
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Deregister a job event handler.
|
|
24
|
+
* @param event The previously registered event.
|
|
25
|
+
* @param handler The previously registered handler.
|
|
26
|
+
*/
|
|
27
|
+
off: (event, handler) => {
|
|
28
|
+
this.emitter.off(event, handler);
|
|
17
29
|
},
|
|
18
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Send a job event.
|
|
32
|
+
* @param event The event to send.
|
|
33
|
+
* @returns a Promise that resolves or rejects depending on whether the job completes successfully.
|
|
34
|
+
*/
|
|
35
|
+
emit: (event) => {
|
|
19
36
|
return new Promise((resolve, reject) => {
|
|
20
|
-
this.emitter.emit(
|
|
37
|
+
this.emitter.emit(event, {
|
|
21
38
|
resolve,
|
|
22
39
|
reject: (reason) => {
|
|
23
40
|
if (typeof reason === 'string' || reason instanceof Error) {
|
|
@@ -38,33 +55,45 @@ export class EventBus {
|
|
|
38
55
|
writable: true,
|
|
39
56
|
value: mitt()
|
|
40
57
|
});
|
|
58
|
+
/**
|
|
59
|
+
* Register an event handler.
|
|
60
|
+
* @param event The event to handle.
|
|
61
|
+
* @param handler The handler to call when the event occurs.
|
|
62
|
+
*/
|
|
41
63
|
Object.defineProperty(this, "on", {
|
|
42
64
|
enumerable: true,
|
|
43
65
|
configurable: true,
|
|
44
66
|
writable: true,
|
|
45
|
-
value: (
|
|
46
|
-
this.emitter.on(
|
|
67
|
+
value: (event, handler) => {
|
|
68
|
+
this.emitter.on(event, handler);
|
|
47
69
|
}
|
|
48
70
|
});
|
|
71
|
+
/**
|
|
72
|
+
* Deregister an event handler.
|
|
73
|
+
* @param event The previously registered event.
|
|
74
|
+
* @param handler The previously registered handler.
|
|
75
|
+
*/
|
|
49
76
|
Object.defineProperty(this, "off", {
|
|
50
77
|
enumerable: true,
|
|
51
78
|
configurable: true,
|
|
52
79
|
writable: true,
|
|
53
|
-
value: (
|
|
54
|
-
this.emitter.off(
|
|
80
|
+
value: (event, handler) => {
|
|
81
|
+
this.emitter.off(event, handler);
|
|
55
82
|
}
|
|
56
83
|
});
|
|
84
|
+
/**
|
|
85
|
+
* Send an event.
|
|
86
|
+
* @param event The event to send.
|
|
87
|
+
* @param data The data to pass to the event's handler.
|
|
88
|
+
*/
|
|
57
89
|
Object.defineProperty(this, "emit", {
|
|
58
90
|
enumerable: true,
|
|
59
91
|
configurable: true,
|
|
60
92
|
writable: true,
|
|
61
|
-
value: (
|
|
62
|
-
this.emitter.emit(
|
|
93
|
+
value: (event, ...data) => {
|
|
94
|
+
this.emitter.emit(event, data[0]);
|
|
63
95
|
}
|
|
64
96
|
});
|
|
65
97
|
}
|
|
66
98
|
}
|
|
67
|
-
export function useEventBus() {
|
|
68
|
-
return useRef(new EventBus()).current;
|
|
69
|
-
}
|
|
70
99
|
//# sourceMappingURL=event-bus.js.map
|
package/dist/event-bus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../src/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,MAAM,yBAAyB,CAAC;AACnE,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAW,iBAAiB,CAAC,CAAC;AAExE,MAAM,UAAU,kBAAkB;IAC9B,OAAO,WAAW,CAAuB,iBAAiB,CAAC,CAAC;AAChE,CAAC;AA+BD,MAAM,OAAO,QAAQ;IAArB;QACI;;;;mBAAM;gBACF;;;;mBAIG;gBACH,EAAE,EAAE,CACA,KAAY,EACZ,OAA+B,EACjC,EAAE;oBACA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACpC,CAAC;gBAED;;;;mBAIG;gBACH,GAAG,EAAE,CACD,KAAY,EACZ,OAA+B,EACjC,EAAE;oBACA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBACrC,CAAC;gBAED;;;;mBAIG;gBACH,IAAI,EAAE,CAAoD,KAAY,EAAE,EAAE;oBACtE,OAAO,IAAI,OAAO,CAEhB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBAClB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE;4BACrB,OAAO;4BACP,MAAM,EAAE,CAAC,MAAuB,EAAE,EAAE;gCAChC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;oCACxD,MAAM,CAAC,MAAM,CAAC,CAAC;gCACnB,CAAC;qCAAM,CAAC;oCACJ,MAAM,EAAE,CAAC;gCACb,CAAC;4BACL,CAAC;yBACJ,CAAC,CAAC;oBACP,CAAC,CAAC,CAAC;gBACP,CAAC;aACJ;WAAC;QAEM;;;;mBAAU,IAAI,EAAO;WAAC;QAE9B;;;;WAIG;QACH;;;;mBAAK,CACD,KAAY,EACZ,OAAwC,EAC1C,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,CAAC;WAAC;QAEF;;;;WAIG;QACH;;;;mBAAM,CACF,KAAY,EACZ,OAAwC,EAC1C,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACrC,CAAC;WAAC;QAEF;;;;WAIG;QACH;;;;mBAAO,CACH,KAAY,EACZ,GAAG,IAYY,EACjB,EAAE;gBACA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC;WAAC;IACN,CAAC;CAAA"}
|
package/dist/loader.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export interface LoaderProps<T> {
|
|
|
21
21
|
export type LoaderDataProps = Pick<LoaderProps<{}>, 'data' | 'className'> & {
|
|
22
22
|
LoadingFallback: () => JSX.Element;
|
|
23
23
|
};
|
|
24
|
-
export declare const Loader: import("react").ForwardRefExoticComponent<LoaderProps<{}> & import("react").RefAttributes<
|
|
24
|
+
export declare const Loader: import("react").ForwardRefExoticComponent<LoaderProps<{}> & import("react").RefAttributes<LoaderRef>>;
|
|
25
25
|
//# sourceMappingURL=loader.d.ts.map
|
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEH,SAAS,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEH,SAAS,EAQZ,MAAM,OAAO,CAAC;AAMf,OAAO,EAKH,YAAY,EAEf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAmB,MAAM,aAAa,CAAC;AAYxD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AAEzD,MAAM,WAAW,WAAW,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uHAAuH;IACvH,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG;IACxE,eAAe,EAAE,MAAM,GAAG,CAAC,OAAO,CAAC;CACtC,CAAC;AAEF,eAAO,MAAM,MAAM,uGAuEjB,CAAC"}
|
package/dist/loader.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense, forwardRef, lazy, useEffect, useImperativeHandle, useMemo, } from 'react';
|
|
2
|
+
import { Suspense, forwardRef, lazy, useEffect, useImperativeHandle, useMemo, useRef, } from 'react';
|
|
3
3
|
import { ErrorBoundary } from '@servicetitan/error-boundary';
|
|
4
4
|
import { Log } from '@servicetitan/log-service';
|
|
5
5
|
import { useOptionalDependencies } from '@servicetitan/react-ioc';
|
|
6
6
|
import { EXPOSED_DEPENDENCIES_TOKEN, EXPOSED_INSTANCE_DEPENDENCIES_TOKEN, useCancelation, } from './common';
|
|
7
7
|
import { Delayed } from './delayed';
|
|
8
|
-
import {
|
|
8
|
+
import { EventBus, EVENT_BUS_TOKEN } from './event-bus';
|
|
9
9
|
import { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';
|
|
10
10
|
import { TtlCache, getBundleInfo, getLDServiceToken, validateBundleInfo, loadScripts, webComponent, } from './utils';
|
|
11
11
|
export const Loader = forwardRef((props, ref) => {
|
|
@@ -136,6 +136,9 @@ function ensureLDService(exposedInstanceDependencies, ldService) {
|
|
|
136
136
|
}
|
|
137
137
|
return exposedInstanceDependencies;
|
|
138
138
|
}
|
|
139
|
+
function useEventBus() {
|
|
140
|
+
return useRef(new EventBus()).current;
|
|
141
|
+
}
|
|
139
142
|
const MINUTE = 1000 * 60;
|
|
140
143
|
const bundleCache = new TtlCache({ ttlMs: 15 * MINUTE });
|
|
141
144
|
//# sourceMappingURL=loader.js.map
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAGH,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,SAAS,EACT,mBAAmB,EACnB,OAAO,
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,4 +2,7 @@ export type JSONPrimitive = string | number | boolean | null | undefined;
|
|
|
2
2
|
export type JSON = {
|
|
3
3
|
[key: string]: JSONPrimitive | JSON[] | JSON;
|
|
4
4
|
};
|
|
5
|
+
export type Serializable<T> = {
|
|
6
|
+
[P in keyof T]: T[P] extends JSONPrimitive ? T[P] : T[P] extends (infer U)[] ? Serializable<U>[] : T[P] extends JSON | undefined ? Serializable<T[P]> : never;
|
|
7
|
+
};
|
|
5
8
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAGzE,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAGzE,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC;AAEpE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,aAAa,GACpC,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACtB,YAAY,CAAC,CAAC,CAAC,EAAE,GACjB,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,SAAS,GAC3B,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAClB,KAAK;CAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/web-components",
|
|
3
|
-
"version": "30.
|
|
3
|
+
"version": "30.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,20 +15,20 @@
|
|
|
15
15
|
"src"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@servicetitan/error-boundary": "30.
|
|
18
|
+
"@servicetitan/error-boundary": "30.1.0",
|
|
19
19
|
"lodash.get": "~4.4.2",
|
|
20
20
|
"mitt": "~3.0.1",
|
|
21
21
|
"semver": "~7.7.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@servicetitan/anvil2": "^1.
|
|
25
|
-
"@servicetitan/design-system": "~14.5.
|
|
26
|
-
"@servicetitan/launchdarkly-service": "30.
|
|
27
|
-
"@servicetitan/log-service": "30.
|
|
28
|
-
"@servicetitan/react-ioc": "30.
|
|
24
|
+
"@servicetitan/anvil2": "^1.31.0",
|
|
25
|
+
"@servicetitan/design-system": "~14.5.2",
|
|
26
|
+
"@servicetitan/launchdarkly-service": "30.1.0",
|
|
27
|
+
"@servicetitan/log-service": "30.1.0",
|
|
28
|
+
"@servicetitan/react-ioc": "30.1.0",
|
|
29
29
|
"@testing-library/dom": "^10.4.0",
|
|
30
30
|
"@testing-library/jest-dom": "^6.6.3",
|
|
31
|
-
"@testing-library/react": "^16.
|
|
31
|
+
"@testing-library/react": "^16.3.0",
|
|
32
32
|
"@types/history": "~4.7.10",
|
|
33
33
|
"@types/lodash.get": "~4.4.6",
|
|
34
34
|
"@types/react": "~18.3.3",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"shadow-dom-testing-library": "^1.12.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@servicetitan/anvil2": ">=1.
|
|
45
|
-
"@servicetitan/design-system": ">=14.5.
|
|
46
|
-
"@servicetitan/launchdarkly-service": "30.
|
|
47
|
-
"@servicetitan/log-service": "30.
|
|
48
|
-
"@servicetitan/react-ioc": "30.
|
|
44
|
+
"@servicetitan/anvil2": ">=1.31.0",
|
|
45
|
+
"@servicetitan/design-system": ">=14.5.2",
|
|
46
|
+
"@servicetitan/launchdarkly-service": "30.1.0",
|
|
47
|
+
"@servicetitan/log-service": "30.1.0",
|
|
48
|
+
"@servicetitan/react-ioc": "30.1.0",
|
|
49
49
|
"history": "~4.10.1",
|
|
50
50
|
"react": ">=17.0.2",
|
|
51
51
|
"react-dom": ">=17.0.2"
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"cli": {
|
|
68
68
|
"webpack": false
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "ebfab3b30337bab2d2c7b1bf6a1caeedc262c884"
|
|
71
71
|
}
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { symbolToken } from '@servicetitan/react-ioc';
|
|
2
|
+
import { EventBus } from '../event-bus';
|
|
3
|
+
|
|
4
|
+
jest.mock('../event-bus', () => {
|
|
5
|
+
return {
|
|
6
|
+
EventBus: jest.fn().mockImplementation(() => {
|
|
7
|
+
return {
|
|
8
|
+
job: {
|
|
9
|
+
emit: jest.fn(),
|
|
10
|
+
on: jest.fn(),
|
|
11
|
+
off: jest.fn(),
|
|
12
|
+
},
|
|
13
|
+
emit: jest.fn(),
|
|
14
|
+
on: jest.fn(),
|
|
15
|
+
off: jest.fn(),
|
|
16
|
+
};
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe(`[web-components] ${EventBus.name}`, () => {
|
|
22
|
+
describe('type definitions', () => {
|
|
23
|
+
describe('EventBus<T>', () => {
|
|
24
|
+
test('rejects invalid data type', () => {
|
|
25
|
+
// @ts-expect-error Types of property 'foo' are incompatible.
|
|
26
|
+
eventBus = EventBus<{ foo: () => void }>;
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('when eventBus is not typed', () => {
|
|
31
|
+
const eventBus = new EventBus();
|
|
32
|
+
|
|
33
|
+
describe('emit', () => {
|
|
34
|
+
test('accepts valid event with valid data', () => {
|
|
35
|
+
eventBus.emit('foo', '');
|
|
36
|
+
eventBus.emit('bar', { value: 1 });
|
|
37
|
+
eventBus.emit(Symbol(), '');
|
|
38
|
+
eventBus.emit(123, '');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('accepts event with no data', () => {
|
|
42
|
+
eventBus.emit('foo');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('rejects invalid event', () => {
|
|
46
|
+
// @ts-expect-error Argument of type '() => void' is not assignable to parameter of type 'string | number | symbol | SymbolToken<any>'.
|
|
47
|
+
eventBus.emit(() => {}, '');
|
|
48
|
+
|
|
49
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'string | number | symbol | SymbolToken<any>'.
|
|
50
|
+
eventBus.emit(new Date(), '');
|
|
51
|
+
|
|
52
|
+
// @ts-expect-error Argument of type 'boolean' is not assignable to parameter of type 'string | number | symbol | SymbolToken<any>'.
|
|
53
|
+
eventBus.emit(true, '');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('rejects invalid data', () => {
|
|
57
|
+
// @ts-expect-error Argument of type '() => void' is not assignable to parameter of type 'JSON | JSONPrimitive'
|
|
58
|
+
eventBus.emit('foo', () => {});
|
|
59
|
+
|
|
60
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
61
|
+
eventBus.emit('foo', new Date());
|
|
62
|
+
|
|
63
|
+
eventBus.emit('foo', {
|
|
64
|
+
value: 1,
|
|
65
|
+
// @ts-expect-error Type '() => void' is not assignable to type 'JSON | JSONPrimitive | JSON[]'.
|
|
66
|
+
otherValue: () => {},
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('on', () => {
|
|
72
|
+
test('accepts valid event with any handler', () => {
|
|
73
|
+
eventBus.on('foo', () => {});
|
|
74
|
+
eventBus.on('bar', (_value: string) => {});
|
|
75
|
+
eventBus.on('baz', ({ value: _value }: { value: Date }) => {});
|
|
76
|
+
eventBus.on(Symbol(), () => {});
|
|
77
|
+
eventBus.on(123, () => {});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('rejects invalid event', () => {
|
|
81
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
82
|
+
eventBus.on(new Date(), () => {});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('off', () => {
|
|
87
|
+
test('accepts valid event with any handler', () => {
|
|
88
|
+
eventBus.off('foo', () => {});
|
|
89
|
+
eventBus.off('bar', (_value: string) => {});
|
|
90
|
+
eventBus.off('baz', ({ value: _value }: { value: Date }) => {});
|
|
91
|
+
eventBus.off(Symbol(), () => {});
|
|
92
|
+
eventBus.off(123, () => {});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('rejects invalid event', () => {
|
|
96
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
97
|
+
eventBus.off(new Date(), () => {});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('job.emit', () => {
|
|
102
|
+
test('accepts valid event', () => {
|
|
103
|
+
eventBus.job.emit('foo');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('rejects invalid event', () => {
|
|
107
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
108
|
+
eventBus.job.emit(new Date());
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('job.on', () => {
|
|
113
|
+
test('accepts valid event with valid handler', () => {
|
|
114
|
+
eventBus.job.on('foo', () => {});
|
|
115
|
+
eventBus.job.on('foo', ({ resolve }) => resolve({ value: '' }));
|
|
116
|
+
eventBus.job.on('foo', ({ reject }) => reject(new Error('Oops!')));
|
|
117
|
+
eventBus.job.on('foo', ({ reject }) => reject('Oops!'));
|
|
118
|
+
eventBus.job.on(Symbol(), () => {});
|
|
119
|
+
eventBus.job.on(123, () => {});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('rejects invalid event', () => {
|
|
123
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
124
|
+
eventBus.job.on(new Date(), () => {});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('rejects invalid handler', () => {
|
|
128
|
+
eventBus.job.on('foo', ({ reject }) => {
|
|
129
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
130
|
+
reject(123);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('job.off', () => {
|
|
136
|
+
test('accepts valid event with valid handler', () => {
|
|
137
|
+
eventBus.job.off('foo', () => {});
|
|
138
|
+
eventBus.job.off('foo', ({ resolve }) => resolve({ value: '' }));
|
|
139
|
+
eventBus.job.off('foo', ({ reject }) => reject(new Error('Oops!')));
|
|
140
|
+
eventBus.job.off('foo', ({ reject }) => reject('Oops!'));
|
|
141
|
+
eventBus.job.off(Symbol(), () => {});
|
|
142
|
+
eventBus.job.off(123, () => {});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('rejects invalid event', () => {
|
|
146
|
+
// @ts-expect-error Argument of type 'Date' is not assignable to parameter of type 'JSON | JSONPrimitive'.
|
|
147
|
+
eventBus.job.off(new Date(), () => {});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('rejects invalid handler', () => {
|
|
151
|
+
eventBus.job.off('foo', ({ reject }) => {
|
|
152
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
153
|
+
reject(123);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
describe('when event is symbolToken', () => {
|
|
159
|
+
const token = symbolToken<{ value: number }>('token');
|
|
160
|
+
const optionalPayloadToken = symbolToken<{ value: number } | undefined>(
|
|
161
|
+
'optionalToken'
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
describe('emit', () => {
|
|
165
|
+
test('accepts valid data', () => {
|
|
166
|
+
eventBus.emit(token, { value: 1 });
|
|
167
|
+
eventBus.emit(optionalPayloadToken, { value: 1 });
|
|
168
|
+
eventBus.emit(optionalPayloadToken);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('rejects invalid data', () => {
|
|
172
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'
|
|
173
|
+
eventBus.emit(token, { value: '' });
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('rejects missing data', () => {
|
|
177
|
+
// @ts-expect-error Expected 2 arguments, but got 1
|
|
178
|
+
eventBus.emit(token);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('rejects invalid data type', () => {
|
|
182
|
+
const token = symbolToken<{ value: () => void }>('token');
|
|
183
|
+
|
|
184
|
+
// @ts-expect-error Argument of type 'SymbolToken<{ value: () => void; }>' is not assignable to parameter of type ...
|
|
185
|
+
eventBus.emit(token, { value: () => {} });
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('on', () => {
|
|
190
|
+
test('accepts valid handler', () => {
|
|
191
|
+
eventBus.on(token, () => {});
|
|
192
|
+
eventBus.on(token, data => data.value++);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('rejects invalid handler', () => {
|
|
196
|
+
// @ts-expect-error Argument of type '(_: number) => void' is not assignable to parameter of type ...
|
|
197
|
+
eventBus.on(token, (_: number) => {});
|
|
198
|
+
|
|
199
|
+
// @ts-expect-error Argument of type '(data: { value: string; }) => number' is not assignable to parameter of type ...
|
|
200
|
+
eventBus.on(token, (data: { value: string }) => data.value.split(''));
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('off', () => {
|
|
205
|
+
test('accepts valid handler', () => {
|
|
206
|
+
eventBus.off(token, () => {});
|
|
207
|
+
eventBus.off(token, (data: { value: number }) => data.value++);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('rejects invalid handler', () => {
|
|
211
|
+
// @ts-expect-error Argument of type '(_: number) => void' is not assignable to parameter of type ...
|
|
212
|
+
eventBus.off(token, (_: number) => {});
|
|
213
|
+
|
|
214
|
+
// @ts-expect-error Argument of type '(data: { value: string; }) => number' is not assignable to parameter of type ...
|
|
215
|
+
eventBus.off(token, (data: { value: string }) => data.value.split(''));
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('job.emit', () => {
|
|
220
|
+
test('accepts token', () => {
|
|
221
|
+
eventBus.job.emit(token);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe('job.on', () => {
|
|
226
|
+
test('accepts valid handler', () => {
|
|
227
|
+
eventBus.job.on(token, ({ resolve }) => resolve({ value: 1 }));
|
|
228
|
+
eventBus.job.on(token, ({ reject }) => reject(new Error('Oops!')));
|
|
229
|
+
eventBus.job.on(token, ({ reject }) => reject('Oops!'));
|
|
230
|
+
eventBus.job.on(optionalPayloadToken, ({ resolve }) =>
|
|
231
|
+
resolve({ value: 1 })
|
|
232
|
+
);
|
|
233
|
+
eventBus.job.on(optionalPayloadToken, ({ resolve }) => resolve());
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('rejects invalid handler', () => {
|
|
237
|
+
eventBus.job.on(token, ({ resolve }) => {
|
|
238
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'.ts(2322)
|
|
239
|
+
resolve({ value: '' });
|
|
240
|
+
});
|
|
241
|
+
eventBus.job.on(token, ({ reject }) => {
|
|
242
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
243
|
+
reject(123);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe('job.off', () => {
|
|
249
|
+
test('accepts valid handler', () => {
|
|
250
|
+
eventBus.job.off(token, ({ resolve }) => resolve({ value: 1 }));
|
|
251
|
+
eventBus.job.off(token, ({ reject }) => reject(new Error('Oops!')));
|
|
252
|
+
eventBus.job.off(token, ({ reject }) => reject('Oops!'));
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('rejects invalid handler', () => {
|
|
256
|
+
eventBus.job.off(token, ({ resolve }) => {
|
|
257
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'.ts(2322)
|
|
258
|
+
resolve({ value: '' });
|
|
259
|
+
});
|
|
260
|
+
eventBus.job.off(token, ({ reject }) => {
|
|
261
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
262
|
+
reject(123);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
describe('when eventBus is typed', () => {
|
|
270
|
+
interface TestEvents {
|
|
271
|
+
'number-event': { value: number };
|
|
272
|
+
'string-event': { value: string };
|
|
273
|
+
'optional-payload-event': { value: number } | undefined;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const eventBus = new EventBus<TestEvents>();
|
|
277
|
+
|
|
278
|
+
describe('emit', () => {
|
|
279
|
+
test('accepts valid events and data', () => {
|
|
280
|
+
eventBus.emit('number-event', { value: 1 });
|
|
281
|
+
eventBus.emit('string-event', { value: '' });
|
|
282
|
+
eventBus.emit('optional-payload-event', { value: 1 });
|
|
283
|
+
eventBus.emit('optional-payload-event');
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test('rejects invalid event', () => {
|
|
287
|
+
// @ts-expect-error '"foo"' is not assignable to parameter of type 'keyof TestEvents'
|
|
288
|
+
eventBus.emit('foo', { value: 1 });
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test('rejects invalid data', () => {
|
|
292
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'
|
|
293
|
+
eventBus.emit('number-event', { value: '' });
|
|
294
|
+
|
|
295
|
+
// @ts-expect-error 'foo' does not exist in type '{ value: number; }'
|
|
296
|
+
eventBus.emit('number-event', { foo: 1 });
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test('rejects missing data', () => {
|
|
300
|
+
// @ts-expect-error Expected 2 arguments, but got 1
|
|
301
|
+
eventBus.emit('number-event');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test('accepts event with no data', () => {
|
|
305
|
+
new EventBus<{ foo: never }>().emit('foo');
|
|
306
|
+
new EventBus<{ foo: undefined }>().emit('foo');
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
describe('on', () => {
|
|
311
|
+
test('accepts valid event and handler', () => {
|
|
312
|
+
eventBus.on('number-event', () => {});
|
|
313
|
+
eventBus.on('number-event', data => data.value++);
|
|
314
|
+
eventBus.on('string-event', data => data.value.split(''));
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test('rejects invalid event', () => {
|
|
318
|
+
// @ts-expect-error Argument of type '"foo"' is not assignable to parameter of type 'keyof TestEvents'
|
|
319
|
+
eventBus.on('foo', () => {});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
test('rejects invalid handler', () => {
|
|
323
|
+
// @ts-expect-error Property 'split' does not exist on type 'number'.
|
|
324
|
+
eventBus.on('number-event', data => data.value.split(''));
|
|
325
|
+
|
|
326
|
+
// @ts-expect-error An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.
|
|
327
|
+
eventBus.on('string-event', data => data.value++);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
describe('off', () => {
|
|
332
|
+
test('accepts valid event and handler', () => {
|
|
333
|
+
eventBus.off('number-event', () => {});
|
|
334
|
+
eventBus.off('number-event', data => data.value++);
|
|
335
|
+
eventBus.off('string-event', data => data.value.split(''));
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test('rejects invalid event', () => {
|
|
339
|
+
// @ts-expect-error Argument of type '"foo"' is not assignable to parameter of type 'keyof TestEvents'
|
|
340
|
+
eventBus.off('foo', () => {});
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test('rejects invalid handler', () => {
|
|
344
|
+
// @ts-expect-error Property 'split' does not exist on type 'number'.
|
|
345
|
+
eventBus.off('number-event', data => data.value.split(''));
|
|
346
|
+
|
|
347
|
+
// @ts-expect-error An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.
|
|
348
|
+
eventBus.off('string-event', data => data.value++);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
describe('job.emit', () => {
|
|
353
|
+
test('accepts valid event', () => {
|
|
354
|
+
eventBus.job.emit('number-event');
|
|
355
|
+
eventBus.job.emit('string-event');
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test('rejects invalid event', () => {
|
|
359
|
+
// @ts-expect-error Argument of type '"foo"' is not assignable to parameter of type 'keyof TestEvents'.
|
|
360
|
+
eventBus.job.emit('foo');
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
describe('job.on', () => {
|
|
365
|
+
test('accepts valid event and handler', () => {
|
|
366
|
+
eventBus.job.on('number-event', () => {});
|
|
367
|
+
eventBus.job.on('number-event', ({ resolve }) => resolve({ foo: 1 }));
|
|
368
|
+
eventBus.job.on('string-event', ({ resolve }) => resolve({ foo: 1 }));
|
|
369
|
+
eventBus.job.on('string-event', ({ reject }) => reject(new Error('Oops!')));
|
|
370
|
+
eventBus.job.on('number-event', ({ reject }) => reject('Oops!'));
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
test('rejects invalid event', () => {
|
|
374
|
+
// @ts-expect-error Argument of type '"foo"' is not assignable to parameter of type 'keyof TestEvents'.
|
|
375
|
+
eventBus.job.on('foo', () => {});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test('rejects invalid handler', () => {
|
|
379
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'
|
|
380
|
+
eventBus.job.on('number-event', ({ reject }) => reject(123));
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
describe('job.off', () => {
|
|
385
|
+
test('accepts valid event and handler', () => {
|
|
386
|
+
eventBus.job.off('number-event', () => {});
|
|
387
|
+
eventBus.job.off('number-event', ({ resolve }) => resolve({ foo: 1 }));
|
|
388
|
+
eventBus.job.off('string-event', ({ resolve }) => resolve({ foo: 1 }));
|
|
389
|
+
eventBus.job.off('string-event', ({ reject }) => reject(new Error('Oops!')));
|
|
390
|
+
eventBus.job.off('number-event', ({ reject }) => reject('Oops!'));
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test('rejects invalid event', () => {
|
|
394
|
+
// @ts-expect-error Argument of type '"foo"' is not assignable to parameter of type 'keyof TestEvents'.
|
|
395
|
+
eventBus.job.off('foo', () => {});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test('rejects invalid handler', () => {
|
|
399
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'
|
|
400
|
+
eventBus.job.off('number-event', ({ reject }) => reject(123));
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
describe('when event is symbolToken', () => {
|
|
405
|
+
const token = symbolToken<{ value: number }>('token');
|
|
406
|
+
const optionalPayloadToken = symbolToken<{ value: number } | undefined>(
|
|
407
|
+
'optionalToken'
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
const eventBus = new EventBus<TestEvents>();
|
|
411
|
+
|
|
412
|
+
describe('emit', () => {
|
|
413
|
+
test('accepts valid data', () => {
|
|
414
|
+
eventBus.emit(token, { value: 1 });
|
|
415
|
+
eventBus.emit(optionalPayloadToken, { value: 1 });
|
|
416
|
+
eventBus.emit(optionalPayloadToken);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
test('rejects invalid data', () => {
|
|
420
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'
|
|
421
|
+
eventBus.emit(token, { value: '' });
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test('rejects missing value', () => {
|
|
425
|
+
// @ts-expect-error Expected 2 arguments, but got 1
|
|
426
|
+
eventBus.emit(token);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
describe('on', () => {
|
|
431
|
+
test('accepts valid handler', () => {
|
|
432
|
+
eventBus.on(token, () => {});
|
|
433
|
+
eventBus.on(token, data => data.value++);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test('rejects invalid handler', () => {
|
|
437
|
+
// @ts-expect-error Argument of type '(_: number) => void' is not assignable to parameter of type ...
|
|
438
|
+
eventBus.on(token, (_: number) => {});
|
|
439
|
+
|
|
440
|
+
// @ts-expect-error Argument of type '(data: { value: string; }) => number' is not assignable to parameter of type ...
|
|
441
|
+
eventBus.on(token, (data: { value: string }) => data.value.split(''));
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
describe('off', () => {
|
|
446
|
+
test('accepts valid handler', () => {
|
|
447
|
+
eventBus.off(token, () => {});
|
|
448
|
+
eventBus.off(token, data => data.value++);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
test('rejects invalid handler', () => {
|
|
452
|
+
// @ts-expect-error Argument of type '(_: number) => void' is not assignable to parameter of type ...
|
|
453
|
+
eventBus.off(token, (_: number) => {});
|
|
454
|
+
|
|
455
|
+
// @ts-expect-error Argument of type '(data: { value: string; }) => number' is not assignable to parameter of type ...
|
|
456
|
+
eventBus.off(token, (data: { value: string }) => data.value.split(''));
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
describe('job.emit', () => {
|
|
461
|
+
test('accepts token', () => {
|
|
462
|
+
eventBus.job.emit(token);
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
describe('job.on', () => {
|
|
467
|
+
test('accepts valid handler', () => {
|
|
468
|
+
eventBus.job.on(token, ({ resolve }) => resolve({ value: 1 }));
|
|
469
|
+
eventBus.job.on(token, ({ reject }) => reject(new Error('Oops!')));
|
|
470
|
+
eventBus.job.on(token, ({ reject }) => reject('Oops!'));
|
|
471
|
+
eventBus.job.on(optionalPayloadToken, ({ resolve }) => resolve());
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
test('rejects invalid handler', () => {
|
|
475
|
+
eventBus.job.on(token, ({ resolve }) => {
|
|
476
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'.ts(2322)
|
|
477
|
+
resolve({ value: '' });
|
|
478
|
+
});
|
|
479
|
+
eventBus.job.on(token, ({ reject }) => {
|
|
480
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
481
|
+
reject(123);
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
describe('job.off', () => {
|
|
487
|
+
test('accepts valid handler', () => {
|
|
488
|
+
eventBus.job.off(token, ({ resolve }) => resolve({ value: 1 }));
|
|
489
|
+
eventBus.job.off(token, ({ reject }) => reject(new Error('Oops!')));
|
|
490
|
+
eventBus.job.off(token, ({ reject }) => reject('Oops!'));
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
test('rejects invalid handler', () => {
|
|
494
|
+
eventBus.job.off(token, ({ resolve }) => {
|
|
495
|
+
// @ts-expect-error Type 'string' is not assignable to type 'number'.ts(2322)
|
|
496
|
+
resolve({ value: '' });
|
|
497
|
+
});
|
|
498
|
+
eventBus.job.off(token, ({ reject }) => {
|
|
499
|
+
// @ts-expect-error Argument of type '123' is not assignable to parameter of type 'string | Error | undefined'.
|
|
500
|
+
reject(123);
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as mitt from 'mitt';
|
|
2
|
-
import {
|
|
3
|
-
import { useEventBus, EventBus } from '../event-bus';
|
|
2
|
+
import { EventBus, typedEventBusToken, EVENT_BUS_TOKEN } from '../event-bus';
|
|
4
3
|
|
|
5
4
|
jest.mock('mitt', () => jest.fn());
|
|
6
5
|
|
|
@@ -126,22 +125,10 @@ describe(`[web-components] ${EventBus.name}`, () => {
|
|
|
126
125
|
});
|
|
127
126
|
});
|
|
128
127
|
|
|
129
|
-
describe(`[web-components] ${
|
|
130
|
-
|
|
131
|
-
return renderHook(() => useEventBus());
|
|
132
|
-
}
|
|
128
|
+
describe(`[web-components] ${typedEventBusToken.name}`, () => {
|
|
129
|
+
const subject = () => typedEventBusToken<any>();
|
|
133
130
|
|
|
134
|
-
test('
|
|
135
|
-
expect(subject()
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
test('when the component using useEventBus is re-rendered, useEventBus provides the same event bus instance', () => {
|
|
139
|
-
const { result, rerender } = subject();
|
|
140
|
-
|
|
141
|
-
const firstInstance = result.current;
|
|
142
|
-
rerender();
|
|
143
|
-
|
|
144
|
-
const secondInstance = result.current;
|
|
145
|
-
expect(firstInstance).toBe(secondInstance);
|
|
131
|
+
test('returns EVENT_BUS_TOKEN', () => {
|
|
132
|
+
expect(subject()).toBe(EVENT_BUS_TOKEN);
|
|
146
133
|
});
|
|
147
134
|
});
|
|
@@ -3,18 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { createContext, useContext } from 'react';
|
|
6
|
-
import { JSON,
|
|
6
|
+
import { JSON, Serializable } from '../types';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
export type MFEContextData<T> = {
|
|
10
|
-
[P in keyof T]: T[P] extends JSONPrimitive
|
|
11
|
-
? T[P]
|
|
12
|
-
: T[P] extends (infer U)[]
|
|
13
|
-
? MFEContextData<U>[]
|
|
14
|
-
: T[P] extends JSON
|
|
15
|
-
? MFEContextData<T[P]>
|
|
16
|
-
: never;
|
|
17
|
-
};
|
|
8
|
+
export type MFEContextData<T> = Serializable<T>;
|
|
18
9
|
|
|
19
10
|
export const MFEDataContext = createContext<JSON>({});
|
|
20
11
|
|
package/src/event-bus.ts
CHANGED
|
@@ -1,32 +1,79 @@
|
|
|
1
|
+
import { symbolToken, SymbolToken } from '@servicetitan/react-ioc';
|
|
1
2
|
import mitt from 'mitt';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { JSON, JSONPrimitive, Serializable } from './types';
|
|
5
|
+
|
|
6
|
+
export const EVENT_BUS_TOKEN = symbolToken<EventBus>('EVENT_BUS_TOKEN');
|
|
7
|
+
|
|
8
|
+
export function typedEventBusToken<EventTypes extends Serializable<EventTypes>>() {
|
|
9
|
+
return symbolToken<EventBus<EventTypes>>('EVENT_BUS_TOKEN');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type EventHandler<EventTypes, Event> = (
|
|
13
|
+
data: Event extends SymbolToken<infer DataType>
|
|
14
|
+
? Serializable<DataType>
|
|
15
|
+
: Event extends keyof EventTypes
|
|
16
|
+
? EventTypes[Event]
|
|
17
|
+
: never
|
|
18
|
+
) => void;
|
|
6
19
|
|
|
7
|
-
export type EventHandler<T = unknown> = (data: T) => void;
|
|
8
20
|
type JobPayload = JSON | void;
|
|
9
21
|
|
|
10
|
-
export type JobEventHandler<
|
|
11
|
-
|
|
22
|
+
export type JobEventHandler<Event> = (defer: {
|
|
23
|
+
/**
|
|
24
|
+
* Successfully complete a job.
|
|
25
|
+
* @param result The value to return from the successfully completed job.
|
|
26
|
+
*/
|
|
27
|
+
resolve(
|
|
28
|
+
...result: Event extends SymbolToken<infer ResultType>
|
|
29
|
+
? undefined extends ResultType
|
|
30
|
+
? [Serializable<ResultType>?]
|
|
31
|
+
: [Serializable<ResultType>]
|
|
32
|
+
: [JobPayload]
|
|
33
|
+
): void;
|
|
34
|
+
/**
|
|
35
|
+
* Fail a job.
|
|
36
|
+
* @param reason The error to return from the failed job.
|
|
37
|
+
*/
|
|
12
38
|
reject(reason?: string | Error): void;
|
|
13
39
|
}) => void;
|
|
14
|
-
export type EventType = string | number | symbol;
|
|
15
|
-
export type SymbolTokenEventType<T, U extends EventType = EventType> =
|
|
16
|
-
U extends SymbolToken<any> ? SymbolToken<T> : U;
|
|
17
40
|
|
|
18
|
-
export
|
|
19
|
-
export class EventBus {
|
|
41
|
+
export class EventBus<EventTypes extends Serializable<EventTypes> = never> {
|
|
20
42
|
job = {
|
|
21
|
-
|
|
22
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Register a job event handler. Jobs event handlers return a result or an error.
|
|
45
|
+
* @param event The job event to handle.
|
|
46
|
+
* @param handler The handler to call when the event occurs. This handler is passed a `resolve` callback to return a successful result, and a `reject` callback to return an error.
|
|
47
|
+
*/
|
|
48
|
+
on: <Event extends SymbolToken<any> | keyof EventTypes>(
|
|
49
|
+
event: Event,
|
|
50
|
+
handler: JobEventHandler<Event>
|
|
51
|
+
) => {
|
|
52
|
+
this.emitter.on(event, handler);
|
|
23
53
|
},
|
|
24
|
-
|
|
25
|
-
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Deregister a job event handler.
|
|
57
|
+
* @param event The previously registered event.
|
|
58
|
+
* @param handler The previously registered handler.
|
|
59
|
+
*/
|
|
60
|
+
off: <Event extends SymbolToken<any> | keyof EventTypes>(
|
|
61
|
+
event: Event,
|
|
62
|
+
handler: JobEventHandler<Event>
|
|
63
|
+
) => {
|
|
64
|
+
this.emitter.off(event, handler);
|
|
26
65
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Send a job event.
|
|
69
|
+
* @param event The event to send.
|
|
70
|
+
* @returns a Promise that resolves or rejects depending on whether the job completes successfully.
|
|
71
|
+
*/
|
|
72
|
+
emit: <Event extends SymbolToken<any> | keyof EventTypes>(event: Event) => {
|
|
73
|
+
return new Promise<
|
|
74
|
+
Event extends SymbolToken<infer ResultType> ? Serializable<ResultType> : JobPayload
|
|
75
|
+
>((resolve, reject) => {
|
|
76
|
+
this.emitter.emit(event, {
|
|
30
77
|
resolve,
|
|
31
78
|
reject: (reason?: string | Error) => {
|
|
32
79
|
if (typeof reason === 'string' || reason instanceof Error) {
|
|
@@ -42,25 +89,51 @@ export class EventBus {
|
|
|
42
89
|
|
|
43
90
|
private emitter = mitt<any>();
|
|
44
91
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Register an event handler.
|
|
94
|
+
* @param event The event to handle.
|
|
95
|
+
* @param handler The handler to call when the event occurs.
|
|
96
|
+
*/
|
|
97
|
+
on = <Event extends SymbolToken<any> | keyof EventTypes>(
|
|
98
|
+
event: Event,
|
|
99
|
+
handler: EventHandler<EventTypes, Event>
|
|
48
100
|
) => {
|
|
49
|
-
this.emitter.on(
|
|
101
|
+
this.emitter.on(event, handler);
|
|
50
102
|
};
|
|
51
103
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Deregister an event handler.
|
|
106
|
+
* @param event The previously registered event.
|
|
107
|
+
* @param handler The previously registered handler.
|
|
108
|
+
*/
|
|
109
|
+
off = <Event extends SymbolToken<any> | keyof EventTypes>(
|
|
110
|
+
event: Event,
|
|
111
|
+
handler: EventHandler<EventTypes, Event>
|
|
55
112
|
) => {
|
|
56
|
-
this.emitter.off(
|
|
113
|
+
this.emitter.off(event, handler);
|
|
57
114
|
};
|
|
58
115
|
|
|
59
|
-
|
|
60
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Send an event.
|
|
118
|
+
* @param event The event to send.
|
|
119
|
+
* @param data The data to pass to the event's handler.
|
|
120
|
+
*/
|
|
121
|
+
emit = <Event extends SymbolToken<any> | keyof EventTypes>(
|
|
122
|
+
event: Event,
|
|
123
|
+
...data: Event extends SymbolToken<infer DataType>
|
|
124
|
+
? undefined extends DataType
|
|
125
|
+
? [Serializable<DataType>?]
|
|
126
|
+
: [Serializable<DataType>]
|
|
127
|
+
: [EventTypes] extends [never]
|
|
128
|
+
? [(JSON | JSONPrimitive)?]
|
|
129
|
+
: Event extends keyof EventTypes
|
|
130
|
+
? undefined extends EventTypes[Event]
|
|
131
|
+
? [EventTypes[Event]?]
|
|
132
|
+
: [EventTypes[Event]] extends [never]
|
|
133
|
+
? []
|
|
134
|
+
: [EventTypes[Event]]
|
|
135
|
+
: never
|
|
136
|
+
) => {
|
|
137
|
+
this.emitter.emit(event, data[0]);
|
|
61
138
|
};
|
|
62
139
|
}
|
|
63
|
-
|
|
64
|
-
export function useEventBus() {
|
|
65
|
-
return useRef(new EventBus()).current;
|
|
66
|
-
}
|
package/src/loader.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
useEffect,
|
|
8
8
|
useImperativeHandle,
|
|
9
9
|
useMemo,
|
|
10
|
+
useRef,
|
|
10
11
|
} from 'react';
|
|
11
12
|
import { ErrorBoundary } from '@servicetitan/error-boundary';
|
|
12
13
|
import { type LDService } from '@servicetitan/launchdarkly-service';
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
} from './common';
|
|
24
25
|
import { MFEContextData } from './contexts/mfe-data-context';
|
|
25
26
|
import { Delayed } from './delayed';
|
|
26
|
-
import { EventBus, EVENT_BUS_TOKEN
|
|
27
|
+
import { EventBus, EVENT_BUS_TOKEN } from './event-bus';
|
|
27
28
|
import { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';
|
|
28
29
|
import {
|
|
29
30
|
BundleInfo,
|
|
@@ -260,5 +261,9 @@ function ensureLDService(
|
|
|
260
261
|
return exposedInstanceDependencies;
|
|
261
262
|
}
|
|
262
263
|
|
|
264
|
+
function useEventBus() {
|
|
265
|
+
return useRef(new EventBus()).current;
|
|
266
|
+
}
|
|
267
|
+
|
|
263
268
|
const MINUTE = 1000 * 60;
|
|
264
269
|
const bundleCache = new TtlCache<BundleInfo>({ ttlMs: 15 * MINUTE });
|
package/src/types.ts
CHANGED
|
@@ -2,3 +2,13 @@ export type JSONPrimitive = string | number | boolean | null | undefined;
|
|
|
2
2
|
|
|
3
3
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
4
4
|
export type JSON = { [key: string]: JSONPrimitive | JSON[] | JSON };
|
|
5
|
+
|
|
6
|
+
export type Serializable<T> = {
|
|
7
|
+
[P in keyof T]: T[P] extends JSONPrimitive
|
|
8
|
+
? T[P]
|
|
9
|
+
: T[P] extends (infer U)[]
|
|
10
|
+
? Serializable<U>[]
|
|
11
|
+
: T[P] extends JSON | undefined
|
|
12
|
+
? Serializable<T[P]>
|
|
13
|
+
: never;
|
|
14
|
+
};
|