@openmrs/esm-emr-api 8.0.1-pre.3605 → 8.0.1-pre.3614

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.
@@ -1,3 +1,3 @@
1
- [0] Successfully compiled: 19 files with swc (122.56ms)
1
+ [0] Successfully compiled: 21 files with swc (174.5ms)
2
2
  [0] swc --strip-leading-paths src -d dist exited with code 0
3
3
  [1] tsc --project tsconfig.build.json exited with code 0
@@ -0,0 +1,11 @@
1
+ import { type EventsWithPayload, type OpenmrsEvent, type EventsWithoutPayload, type EventTypes } from './types';
2
+ export { type OpenmrsEvent, type EventTypes as OpenmrsEventTypes } from './types';
3
+ export declare function fireOpenmrsEvent<T extends EventsWithoutPayload>(event: T, payload?: never): boolean;
4
+ export declare function fireOpenmrsEvent<T extends EventsWithPayload>(event: T, payload: EventTypes[T]): boolean;
5
+ /**
6
+ * Subscribes to a custom OpenMRS event
7
+ *
8
+ * @param event The name of the event to listen to
9
+ * @param handler The callback to be called when the event fires
10
+ */
11
+ export declare function subscribeOpenmrsEvent<T extends OpenmrsEvent>(event: T, handler: (payload?: EventTypes[T]) => boolean | void): () => void;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Fires an OpenMRS custom event
3
+ *
4
+ * @param event The custom event to fire
5
+ * @param payload The payload associated with this type of event
6
+ * @returns true if the event was not cancelled and false, i.e., the result of `dispatchEvent()`
7
+ */ export function fireOpenmrsEvent(event, payload) {
8
+ const evt = new CustomEvent(`openmrs:${event}`, {
9
+ detail: payload ?? undefined,
10
+ cancelable: true,
11
+ bubbles: true
12
+ });
13
+ return window.dispatchEvent(evt);
14
+ }
15
+ /**
16
+ * Subscribes to a custom OpenMRS event
17
+ *
18
+ * @param event The name of the event to listen to
19
+ * @param handler The callback to be called when the event fires
20
+ */ export function subscribeOpenmrsEvent(event, handler) {
21
+ const internalHandler = (event)=>{
22
+ const detail = 'detail' in event && event.detail !== null ? event.detail : undefined;
23
+ handler(detail);
24
+ };
25
+ window.addEventListener(`openmrs:${event}`, internalHandler);
26
+ return ()=>{
27
+ window.removeEventListener(`openmrs:${event}`, internalHandler);
28
+ };
29
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Payload returned from the "page-change" event
3
+ */
4
+ export interface PageChanged {
5
+ /**
6
+ * This function controls whether or not the page change goes ahead.
7
+ * Call this to interrupt the page navigation, e.g., if a user requested
8
+ * not to change the page.
9
+ *
10
+ * @param val If this is a value that ultimately results as "true", then navigation
11
+ * is cancelled, which is the default value.
12
+ */
13
+ cancelNavigation(val?: boolean | Promise<boolean> | (() => boolean | Promise<boolean>)): void;
14
+ /**
15
+ * The name of the main content page that will be displayed, e.g., "@openmrs/esm-my-app-page-0".
16
+ * May be undefined if the navigation will not result in a main content page.
17
+ */
18
+ newPage: string | undefined;
19
+ /**
20
+ * The URL currently used by single-spa to determine the layout
21
+ */
22
+ oldUrl: string;
23
+ /**
24
+ * The URL that will be in effect once this update cycle is complete
25
+ */
26
+ newUrl: string;
27
+ }
28
+ /**
29
+ * This is the set of events supported by the custom event system
30
+ */
31
+ export interface EventTypes {
32
+ /**
33
+ * The started event is fired once when the app started.
34
+ * Listeners should use this as an opportunity to do any initialization required.
35
+ */
36
+ started: never;
37
+ /**
38
+ * The before-page-changed event is fired before the active page in the application changes
39
+ */
40
+ 'before-page-changed': PageChanged;
41
+ }
42
+ /**
43
+ * This type is the union of all supported events
44
+ */
45
+ export type OpenmrsEvent = keyof EventTypes;
46
+ export type EventsWithoutPayload = {
47
+ [K in OpenmrsEvent]: EventTypes[K] extends undefined ? K : never;
48
+ }[OpenmrsEvent];
49
+ export type EventsWithPayload = {
50
+ [K in OpenmrsEvent]: EventTypes[K] extends undefined ? never : K;
51
+ }[OpenmrsEvent];
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Payload returned from the "page-change" event
3
+ */ export { };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './attachments';
2
2
  export * from './current-patient';
3
+ export * from './events';
3
4
  export * from './location';
4
5
  export * from './types';
5
6
  export * from './visit-type';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./attachments.js";
2
2
  export * from "./current-patient.js";
3
+ export * from "./events/index.js";
3
4
  export * from "./location.js";
4
5
  export * from "./types/index.js";
5
6
  export * from "./visit-type.js";
package/dist/public.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './attachments';
2
2
  export * from './current-patient';
3
+ export { subscribeOpenmrsEvent, type OpenmrsEvent, type OpenmrsEventTypes } from './events';
3
4
  export * from './types';
4
5
  export * from './visit-utils';
5
6
  export * from './visit-type';
package/dist/public.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./attachments.js";
2
2
  export * from "./current-patient.js";
3
+ export { subscribeOpenmrsEvent } from "./events/index.js";
3
4
  export * from "./types/index.js";
4
5
  export * from "./visit-utils.js";
5
6
  export * from "./visit-type.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-emr-api",
3
- "version": "8.0.1-pre.3605",
3
+ "version": "8.0.1-pre.3614",
4
4
  "license": "MPL-2.0",
5
5
  "description": "The javascript module for interacting with the OpenMRS API",
6
6
  "type": "module",
@@ -62,9 +62,9 @@
62
62
  "@openmrs/esm-state": "6.x"
63
63
  },
64
64
  "devDependencies": {
65
- "@openmrs/esm-api": "8.0.1-pre.3605",
66
- "@openmrs/esm-offline": "8.0.1-pre.3605",
67
- "@openmrs/esm-state": "8.0.1-pre.3605",
65
+ "@openmrs/esm-api": "8.0.1-pre.3614",
66
+ "@openmrs/esm-offline": "8.0.1-pre.3614",
67
+ "@openmrs/esm-state": "8.0.1-pre.3614",
68
68
  "@swc/cli": "^0.7.7",
69
69
  "@swc/core": "^1.11.29",
70
70
  "@vitest/coverage-v8": "^4.0.7",
@@ -0,0 +1,136 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { fireOpenmrsEvent, subscribeOpenmrsEvent } from './index';
3
+
4
+ describe('Event system', () => {
5
+ describe('fireOpenmrsEvent', () => {
6
+ it('dispatches an event on window by default', () => {
7
+ const handler = vi.fn();
8
+ window.addEventListener('openmrs:started', handler);
9
+
10
+ fireOpenmrsEvent('started');
11
+
12
+ expect(handler).toHaveBeenCalledOnce();
13
+ window.removeEventListener('openmrs:started', handler);
14
+ });
15
+
16
+ it('dispatches an event with payload', () => {
17
+ const handler = vi.fn();
18
+ window.addEventListener('openmrs:before-page-changed', handler);
19
+
20
+ const payload = {
21
+ cancelNavigation: vi.fn(),
22
+ newPage: '/home',
23
+ oldUrl: 'http://localhost/old',
24
+ newUrl: 'http://localhost/new',
25
+ };
26
+ fireOpenmrsEvent('before-page-changed', payload);
27
+
28
+ expect(handler).toHaveBeenCalledOnce();
29
+ const event = handler.mock.calls[0][0] as CustomEvent;
30
+ expect(event.detail).toEqual(payload);
31
+ window.removeEventListener('openmrs:before-page-changed', handler);
32
+ });
33
+
34
+ it('returns true when event is not cancelled', () => {
35
+ const result = fireOpenmrsEvent('started');
36
+ expect(result).toBe(true);
37
+ });
38
+
39
+ it('returns false when event is cancelled', () => {
40
+ const handler = (e: Event) => e.preventDefault();
41
+ window.addEventListener('openmrs:started', handler);
42
+
43
+ const result = fireOpenmrsEvent('started');
44
+
45
+ expect(result).toBe(false);
46
+ window.removeEventListener('openmrs:started', handler);
47
+ });
48
+ });
49
+
50
+ describe('subscribeOpenmrsEvent', () => {
51
+ it('subscribes to an event on window by default', () => {
52
+ const handler = vi.fn();
53
+ const unsubscribe = subscribeOpenmrsEvent('started', handler);
54
+
55
+ fireOpenmrsEvent('started');
56
+
57
+ expect(handler).toHaveBeenCalledOnce();
58
+ unsubscribe();
59
+ });
60
+
61
+ it('receives the event payload', () => {
62
+ const handler = vi.fn();
63
+ const unsubscribe = subscribeOpenmrsEvent('before-page-changed', handler);
64
+
65
+ const payload = {
66
+ cancelNavigation: vi.fn(),
67
+ newPage: '/home',
68
+ oldUrl: 'http://localhost/old',
69
+ newUrl: 'http://localhost/new',
70
+ };
71
+ fireOpenmrsEvent('before-page-changed', payload);
72
+
73
+ expect(handler).toHaveBeenCalledWith(payload);
74
+ unsubscribe();
75
+ });
76
+
77
+ it('receives undefined for events without payload', () => {
78
+ const handler = vi.fn();
79
+ const unsubscribe = subscribeOpenmrsEvent('started', handler);
80
+
81
+ fireOpenmrsEvent('started');
82
+
83
+ expect(handler).toHaveBeenCalledWith(undefined);
84
+ unsubscribe();
85
+ });
86
+
87
+ it('unsubscribes correctly', () => {
88
+ const handler = vi.fn();
89
+ const unsubscribe = subscribeOpenmrsEvent('started', handler);
90
+
91
+ fireOpenmrsEvent('started');
92
+ expect(handler).toHaveBeenCalledOnce();
93
+
94
+ unsubscribe();
95
+
96
+ fireOpenmrsEvent('started');
97
+ expect(handler).toHaveBeenCalledOnce();
98
+ });
99
+
100
+ it('allows multiple subscribers to the same event', () => {
101
+ const handler1 = vi.fn();
102
+ const handler2 = vi.fn();
103
+ const unsubscribe1 = subscribeOpenmrsEvent('started', handler1);
104
+ const unsubscribe2 = subscribeOpenmrsEvent('started', handler2);
105
+
106
+ fireOpenmrsEvent('started');
107
+
108
+ expect(handler1).toHaveBeenCalledOnce();
109
+ expect(handler2).toHaveBeenCalledOnce();
110
+ unsubscribe1();
111
+ unsubscribe2();
112
+ });
113
+
114
+ it('calling unsubscribe multiple times is safe', () => {
115
+ const handler = vi.fn();
116
+ const unsubscribe = subscribeOpenmrsEvent('started', handler);
117
+
118
+ unsubscribe();
119
+ expect(() => unsubscribe()).not.toThrow();
120
+ });
121
+
122
+ it('unsubscribing one handler does not affect others', () => {
123
+ const handler1 = vi.fn();
124
+ const handler2 = vi.fn();
125
+ const unsubscribe1 = subscribeOpenmrsEvent('started', handler1);
126
+ const unsubscribe2 = subscribeOpenmrsEvent('started', handler2);
127
+
128
+ unsubscribe1();
129
+ fireOpenmrsEvent('started');
130
+
131
+ expect(handler1).not.toHaveBeenCalled();
132
+ expect(handler2).toHaveBeenCalledOnce();
133
+ unsubscribe2();
134
+ });
135
+ });
136
+ });
@@ -0,0 +1,37 @@
1
+ import { type EventsWithPayload, type OpenmrsEvent, type EventsWithoutPayload, type EventTypes } from './types';
2
+ export { type OpenmrsEvent, type EventTypes as OpenmrsEventTypes } from './types';
3
+
4
+ export function fireOpenmrsEvent<T extends EventsWithoutPayload>(event: T, payload?: never): boolean;
5
+ export function fireOpenmrsEvent<T extends EventsWithPayload>(event: T, payload: EventTypes[T]): boolean;
6
+ /**
7
+ * Fires an OpenMRS custom event
8
+ *
9
+ * @param event The custom event to fire
10
+ * @param payload The payload associated with this type of event
11
+ * @returns true if the event was not cancelled and false, i.e., the result of `dispatchEvent()`
12
+ */
13
+ export function fireOpenmrsEvent<T extends OpenmrsEvent>(event: T, payload?: EventTypes[T]): boolean {
14
+ const evt = new CustomEvent(`openmrs:${event}`, { detail: payload ?? undefined, cancelable: true, bubbles: true });
15
+ return window.dispatchEvent(evt);
16
+ }
17
+
18
+ /**
19
+ * Subscribes to a custom OpenMRS event
20
+ *
21
+ * @param event The name of the event to listen to
22
+ * @param handler The callback to be called when the event fires
23
+ */
24
+ export function subscribeOpenmrsEvent<T extends OpenmrsEvent>(
25
+ event: T,
26
+ handler: (payload?: EventTypes[T]) => boolean | void,
27
+ ): () => void {
28
+ const internalHandler = (event: Event) => {
29
+ const detail = 'detail' in event && event.detail !== null ? event.detail : undefined;
30
+ handler(detail as EventTypes[T]);
31
+ };
32
+
33
+ window.addEventListener(`openmrs:${event}`, internalHandler);
34
+ return () => {
35
+ window.removeEventListener(`openmrs:${event}`, internalHandler);
36
+ };
37
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Payload returned from the "page-change" event
3
+ */
4
+ export interface PageChanged {
5
+ /**
6
+ * This function controls whether or not the page change goes ahead.
7
+ * Call this to interrupt the page navigation, e.g., if a user requested
8
+ * not to change the page.
9
+ *
10
+ * @param val If this is a value that ultimately results as "true", then navigation
11
+ * is cancelled, which is the default value.
12
+ */
13
+ cancelNavigation(val?: boolean | Promise<boolean> | (() => boolean | Promise<boolean>)): void;
14
+ /**
15
+ * The name of the main content page that will be displayed, e.g., "@openmrs/esm-my-app-page-0".
16
+ * May be undefined if the navigation will not result in a main content page.
17
+ */
18
+ newPage: string | undefined;
19
+ /**
20
+ * The URL currently used by single-spa to determine the layout
21
+ */
22
+ oldUrl: string;
23
+ /**
24
+ * The URL that will be in effect once this update cycle is complete
25
+ */
26
+ newUrl: string;
27
+ }
28
+
29
+ /**
30
+ * This is the set of events supported by the custom event system
31
+ */
32
+ export interface EventTypes {
33
+ /**
34
+ * The started event is fired once when the app started.
35
+ * Listeners should use this as an opportunity to do any initialization required.
36
+ */
37
+ started: never;
38
+ /**
39
+ * The before-page-changed event is fired before the active page in the application changes
40
+ */
41
+ 'before-page-changed': PageChanged;
42
+ }
43
+
44
+ /**
45
+ * This type is the union of all supported events
46
+ */
47
+ export type OpenmrsEvent = keyof EventTypes;
48
+
49
+ export type EventsWithoutPayload = {
50
+ [K in OpenmrsEvent]: EventTypes[K] extends undefined ? K : never;
51
+ }[OpenmrsEvent];
52
+
53
+ export type EventsWithPayload = {
54
+ [K in OpenmrsEvent]: EventTypes[K] extends undefined ? never : K;
55
+ }[OpenmrsEvent];
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './attachments';
2
2
  export * from './current-patient';
3
+ export * from './events';
3
4
  export * from './location';
4
5
  export * from './types';
5
6
  export * from './visit-type';
package/src/public.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './attachments';
2
2
  export * from './current-patient';
3
+ export { subscribeOpenmrsEvent, type OpenmrsEvent, type OpenmrsEventTypes } from './events';
3
4
  export * from './types';
4
5
  export * from './visit-utils';
5
6
  export * from './visit-type';