@openmrs/esm-extensions 3.2.0 → 3.2.1-pre.1015
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/openmrs-esm-extensions.js +1 -1
- package/dist/openmrs-esm-extensions.js.map +1 -1
- package/package.json +5 -5
- package/src/extensions.ts +174 -209
- package/src/index.ts +9 -1
- package/src/render.ts +6 -2
- package/src/store.ts +73 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-extensions",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1-pre.1015",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Coordinates extensions and extension points in the OpenMRS Frontend",
|
|
6
6
|
"browser": "dist/openmrs-esm-extensions.js",
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"single-spa": "5.x"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@openmrs/esm-api": "^3.2.
|
|
46
|
-
"@openmrs/esm-config": "^3.2.
|
|
47
|
-
"@openmrs/esm-state": "^3.2.
|
|
45
|
+
"@openmrs/esm-api": "^3.2.1-pre.1015",
|
|
46
|
+
"@openmrs/esm-config": "^3.2.1-pre.1015",
|
|
47
|
+
"@openmrs/esm-state": "^3.2.1-pre.1015",
|
|
48
48
|
"single-spa": "^5.9.2"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"lodash-es": "^4.17.21"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "2a10b8956cd63006bd913b18a2a482fa9a0134ec"
|
|
54
54
|
}
|
package/src/extensions.ts
CHANGED
|
@@ -1,42 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* We have the following extension modes:
|
|
3
|
+
*
|
|
4
|
+
* - attached (set via code in form of: attach, detach, ...)
|
|
5
|
+
* - configured (set via configuration in form of: added, removed, ...)
|
|
6
|
+
* - assigned (computed from attached and configured)
|
|
7
|
+
* - connected (computed from assigned using connectivity and online / offline)
|
|
8
|
+
*/
|
|
9
|
+
|
|
1
10
|
import {
|
|
2
11
|
ExtensionSlotConfigObject,
|
|
3
|
-
|
|
12
|
+
getExtensionSlotConfigStore,
|
|
4
13
|
} from "@openmrs/esm-config";
|
|
5
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getExtensionInternalStore,
|
|
16
|
+
ExtensionSlotState,
|
|
17
|
+
AssignedExtension,
|
|
18
|
+
checkStatusFor,
|
|
19
|
+
ConnectedExtension,
|
|
20
|
+
} from ".";
|
|
6
21
|
import {
|
|
7
22
|
ExtensionRegistration,
|
|
8
23
|
ExtensionSlotInfo,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
updateExtensionStore,
|
|
24
|
+
ExtensionInternalStore,
|
|
25
|
+
getExtensionStore,
|
|
26
|
+
updateInternalExtensionStore,
|
|
13
27
|
} from "./store";
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
|
|
29
|
+
const extensionInternalStore = getExtensionInternalStore();
|
|
30
|
+
const extensionStore = getExtensionStore();
|
|
31
|
+
|
|
32
|
+
// Keep the output store updated
|
|
33
|
+
extensionInternalStore.subscribe((internalStore) => {
|
|
34
|
+
const slots: Record<string, ExtensionSlotState> = {};
|
|
35
|
+
for (let [slotName, slot] of Object.entries(internalStore.slots)) {
|
|
36
|
+
if (slot.moduleName) {
|
|
37
|
+
// Only include registered slots
|
|
38
|
+
const assignedExtensions = getAssignedExtensions(slotName);
|
|
39
|
+
slots[slotName] = { moduleName: slot.moduleName, assignedExtensions };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
extensionStore.setState({ slots: slots });
|
|
43
|
+
});
|
|
22
44
|
|
|
23
45
|
function createNewExtensionSlotInfo(
|
|
24
|
-
|
|
46
|
+
slotName: string,
|
|
47
|
+
moduleName?: string
|
|
25
48
|
): ExtensionSlotInfo {
|
|
26
49
|
return {
|
|
27
|
-
|
|
50
|
+
moduleName,
|
|
51
|
+
name: slotName,
|
|
28
52
|
attachedIds: [],
|
|
29
|
-
|
|
53
|
+
config: null,
|
|
30
54
|
};
|
|
31
55
|
}
|
|
32
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Given an extension ID, which is a string uniquely identifying
|
|
59
|
+
* an instance of an extension within an extension slot, this
|
|
60
|
+
* returns the extension name.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```js
|
|
64
|
+
* getExtensionNameFromId("foo#bar")
|
|
65
|
+
* --> "foo"
|
|
66
|
+
* getExtensionNameFromId("baz")
|
|
67
|
+
* --> "baz"
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
33
70
|
export function getExtensionNameFromId(extensionId: string) {
|
|
34
71
|
const [extensionName] = extensionId.split("#");
|
|
35
72
|
return extensionName;
|
|
36
73
|
}
|
|
37
74
|
|
|
38
75
|
export function getExtensionRegistrationFrom(
|
|
39
|
-
state:
|
|
76
|
+
state: ExtensionInternalStore,
|
|
40
77
|
extensionId: string
|
|
41
78
|
): ExtensionRegistration | undefined {
|
|
42
79
|
const name = getExtensionNameFromId(extensionId);
|
|
@@ -46,43 +83,57 @@ export function getExtensionRegistrationFrom(
|
|
|
46
83
|
export function getExtensionRegistration(
|
|
47
84
|
extensionId: string
|
|
48
85
|
): ExtensionRegistration | undefined {
|
|
49
|
-
const state =
|
|
86
|
+
const state = extensionInternalStore.getState();
|
|
50
87
|
return getExtensionRegistrationFrom(state, extensionId);
|
|
51
88
|
}
|
|
52
89
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
order?: number;
|
|
60
|
-
}
|
|
61
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Extensions must be registered in order to be rendered.
|
|
92
|
+
* This is handled by the app shell, when extensions are provided
|
|
93
|
+
* via the `setupOpenMRS` return object.
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
62
96
|
export const registerExtension: (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
) =>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
...details,
|
|
69
|
-
name,
|
|
97
|
+
extensionRegistration: ExtensionRegistration
|
|
98
|
+
) => void = extensionInternalStore.action(
|
|
99
|
+
(state, extensionRegistration: ExtensionRegistration) => {
|
|
100
|
+
state.extensions[extensionRegistration.name] = {
|
|
101
|
+
...extensionRegistration,
|
|
70
102
|
instances: {},
|
|
71
103
|
};
|
|
72
104
|
}
|
|
73
105
|
);
|
|
74
106
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Attach an extension to an extension slot.
|
|
109
|
+
*
|
|
110
|
+
* This will cause the extension to be rendered into the specified
|
|
111
|
+
* extension slot, unless it is removed by configuration. Using
|
|
112
|
+
* `attach` is an alternative to specifying the `slot` or `slots`
|
|
113
|
+
* in the extension declaration.
|
|
114
|
+
*
|
|
115
|
+
* It is particularly useful when creating a slot into which
|
|
116
|
+
* you want to render an existing extension. This enables you
|
|
117
|
+
* to do so without modifying the extension's declaration, which
|
|
118
|
+
* may be impractical or inappropriate, for example if you are
|
|
119
|
+
* writing a module for a specific implementation.
|
|
120
|
+
*
|
|
121
|
+
* @param slotName a name uniquely identifying the slot
|
|
122
|
+
* @param extensionId an extension name, with an optional #-suffix
|
|
123
|
+
* to distinguish it from other instances of the same extension
|
|
124
|
+
* attached to the same slot.
|
|
125
|
+
*/
|
|
126
|
+
export function attach(slotName: string, extensionId: string) {
|
|
127
|
+
updateInternalExtensionStore((state) => {
|
|
128
|
+
const existingSlot = state.slots[slotName];
|
|
78
129
|
|
|
79
130
|
if (!existingSlot) {
|
|
80
131
|
return {
|
|
81
132
|
...state,
|
|
82
133
|
slots: {
|
|
83
134
|
...state.slots,
|
|
84
|
-
[
|
|
85
|
-
...createNewExtensionSlotInfo(
|
|
135
|
+
[slotName]: {
|
|
136
|
+
...createNewExtensionSlotInfo(slotName),
|
|
86
137
|
attachedIds: [extensionId],
|
|
87
138
|
},
|
|
88
139
|
},
|
|
@@ -92,7 +143,7 @@ export function attach(extensionSlotName: string, extensionId: string) {
|
|
|
92
143
|
...state,
|
|
93
144
|
slots: {
|
|
94
145
|
...state.slots,
|
|
95
|
-
[
|
|
146
|
+
[slotName]: {
|
|
96
147
|
...existingSlot,
|
|
97
148
|
attachedIds: [...existingSlot.attachedIds, extensionId],
|
|
98
149
|
},
|
|
@@ -102,8 +153,9 @@ export function attach(extensionSlotName: string, extensionId: string) {
|
|
|
102
153
|
});
|
|
103
154
|
}
|
|
104
155
|
|
|
156
|
+
/** Avoid using this. Extension attachments should be considered declarative. */
|
|
105
157
|
export function detach(extensionSlotName: string, extensionId: string) {
|
|
106
|
-
|
|
158
|
+
updateInternalExtensionStore((state) => {
|
|
107
159
|
const existingSlot = state.slots[extensionSlotName];
|
|
108
160
|
|
|
109
161
|
if (existingSlot && existingSlot.attachedIds.includes(extensionId)) {
|
|
@@ -125,8 +177,9 @@ export function detach(extensionSlotName: string, extensionId: string) {
|
|
|
125
177
|
});
|
|
126
178
|
}
|
|
127
179
|
|
|
180
|
+
/** Avoid using this. Extension attachments should be considered declarative. */
|
|
128
181
|
export function detachAll(extensionSlotName: string) {
|
|
129
|
-
|
|
182
|
+
updateInternalExtensionStore((state) => {
|
|
130
183
|
const existingSlot = state.slots[extensionSlotName];
|
|
131
184
|
|
|
132
185
|
if (existingSlot) {
|
|
@@ -175,15 +228,55 @@ function getOrder(
|
|
|
175
228
|
}
|
|
176
229
|
}
|
|
177
230
|
|
|
178
|
-
|
|
179
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Filters a list of extensions according to whether they support the
|
|
233
|
+
* current connectivity status.
|
|
234
|
+
*
|
|
235
|
+
* @param assignedExtensions The list of extensions to filter.
|
|
236
|
+
* @param online Whether the app is currently online. If `null`, uses `navigator.onLine`.
|
|
237
|
+
* @returns A list of extensions that should be rendered
|
|
238
|
+
*/
|
|
239
|
+
export function getConnectedExtensions(
|
|
240
|
+
assignedExtensions: Array<AssignedExtension>,
|
|
241
|
+
online: boolean | null = null
|
|
242
|
+
): Array<ConnectedExtension> {
|
|
243
|
+
const isOnline = online ?? navigator.onLine;
|
|
244
|
+
return assignedExtensions.filter((e) =>
|
|
245
|
+
checkStatusFor(isOnline, e.online, e.offline)
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export function getAssignedExtensions(
|
|
250
|
+
slotName: string
|
|
251
|
+
): Array<AssignedExtension> {
|
|
252
|
+
const internalState = extensionInternalStore.getState();
|
|
253
|
+
const config = getExtensionSlotConfigStore(slotName).getState().config;
|
|
254
|
+
const attachedIds = internalState.slots[slotName].attachedIds;
|
|
255
|
+
const assignedIds = calculateAssignedIds(config, attachedIds);
|
|
256
|
+
const extensions: Array<AssignedExtension> = [];
|
|
257
|
+
for (let id of assignedIds) {
|
|
258
|
+
const name = getExtensionNameFromId(id);
|
|
259
|
+
const extension = internalState.extensions[name];
|
|
260
|
+
extensions.push({
|
|
261
|
+
id,
|
|
262
|
+
name,
|
|
263
|
+
moduleName: extension.moduleName,
|
|
264
|
+
meta: extension.meta,
|
|
265
|
+
online: extension.online,
|
|
266
|
+
offline: extension.offline,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return extensions;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function calculateAssignedIds(
|
|
180
273
|
config: ExtensionSlotConfigObject,
|
|
181
274
|
attachedIds: Array<string>
|
|
182
275
|
) {
|
|
183
276
|
const addedIds = config.add || [];
|
|
184
277
|
const removedIds = config.remove || [];
|
|
185
278
|
const idOrder = config.order || [];
|
|
186
|
-
const { extensions } =
|
|
279
|
+
const { extensions } = extensionInternalStore.getState();
|
|
187
280
|
|
|
188
281
|
return [...attachedIds, ...addedIds]
|
|
189
282
|
.filter((id) => !removedIds.includes(id))
|
|
@@ -211,101 +304,49 @@ export function getAssignedIds(
|
|
|
211
304
|
});
|
|
212
305
|
}
|
|
213
306
|
|
|
214
|
-
function getUpdatedExtensionSlotInfoForRegistration(
|
|
215
|
-
existingSlot: ExtensionSlotInfo,
|
|
216
|
-
slotName: string,
|
|
217
|
-
moduleName: string
|
|
218
|
-
) {
|
|
219
|
-
if (!existingSlot) {
|
|
220
|
-
return getUpdatedExtensionSlotInfo(slotName, moduleName, {
|
|
221
|
-
...createNewExtensionSlotInfo(slotName),
|
|
222
|
-
instances: {
|
|
223
|
-
[moduleName]: createNewExtensionSlotInstance(),
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
} else if (moduleName in existingSlot.instances) {
|
|
227
|
-
return getUpdatedExtensionSlotInfo(slotName, moduleName, existingSlot);
|
|
228
|
-
} else {
|
|
229
|
-
return getUpdatedExtensionSlotInfo(slotName, moduleName, {
|
|
230
|
-
...existingSlot,
|
|
231
|
-
instances: {
|
|
232
|
-
...existingSlot.instances,
|
|
233
|
-
[moduleName]: createNewExtensionSlotInstance(),
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function getUpdatedExtensionSlotInfoForUnregistration(
|
|
240
|
-
existingSlot: ExtensionSlotInfo,
|
|
241
|
-
extensionSlotName: string,
|
|
242
|
-
moduleName: string
|
|
243
|
-
) {
|
|
244
|
-
const { [moduleName]: existing, ...instances } = existingSlot.instances;
|
|
245
|
-
|
|
246
|
-
return getUpdatedExtensionSlotInfo(extensionSlotName, moduleName, {
|
|
247
|
-
...existingSlot,
|
|
248
|
-
instances,
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
|
|
252
307
|
/**
|
|
308
|
+
* Used by by extension slots at mount time.
|
|
309
|
+
*
|
|
253
310
|
* @param moduleName The name of the module that contains the extension slot
|
|
254
311
|
* @param slotName The extension slot name that is actually used
|
|
312
|
+
* @internal
|
|
255
313
|
*/
|
|
256
|
-
export
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
314
|
+
export const registerExtensionSlot: (
|
|
315
|
+
moduleName: string,
|
|
316
|
+
slotName: string
|
|
317
|
+
) => void = extensionInternalStore.action((state, moduleName, slotName) => {
|
|
318
|
+
const existingModuleName = state.slots[slotName]?.moduleName;
|
|
319
|
+
if (existingModuleName && existingModuleName != moduleName) {
|
|
320
|
+
console.warn(
|
|
321
|
+
`An extension slot with the name '${slotName}' already exists. Refusing to register the same slot name twice (in "registerExtensionSlot"). The existing one is from module ${existingModuleName}.`
|
|
263
322
|
);
|
|
264
|
-
|
|
265
|
-
if (existingSlot !== updatedSlot) {
|
|
266
|
-
return {
|
|
267
|
-
...state,
|
|
268
|
-
slots: {
|
|
269
|
-
...state.slots,
|
|
270
|
-
[slotName]: updatedSlot,
|
|
271
|
-
},
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
323
|
return state;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
export function unregisterExtensionSlot(moduleName: string, slotName: string) {
|
|
280
|
-
updateExtensionStore((state) => {
|
|
281
|
-
const existingSlot = state.slots[slotName];
|
|
282
|
-
|
|
283
|
-
if (existingSlot && moduleName in existingSlot.instances) {
|
|
284
|
-
const updatedSlot = getUpdatedExtensionSlotInfoForUnregistration(
|
|
285
|
-
existingSlot,
|
|
286
|
-
slotName,
|
|
287
|
-
moduleName
|
|
288
|
-
);
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
...state,
|
|
292
|
-
slots: {
|
|
293
|
-
...state.slots,
|
|
294
|
-
[slotName]: updatedSlot,
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
324
|
+
}
|
|
325
|
+
if (existingModuleName && existingModuleName == moduleName) {
|
|
326
|
+
// Re-rendering an existing slot
|
|
299
327
|
return state;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
328
|
+
}
|
|
329
|
+
if (state.slots[slotName]) {
|
|
330
|
+
return {
|
|
331
|
+
...state,
|
|
332
|
+
slots: {
|
|
333
|
+
...state.slots,
|
|
334
|
+
[slotName]: {
|
|
335
|
+
...state.slots[slotName],
|
|
336
|
+
moduleName,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
const slot = createNewExtensionSlotInfo(slotName, moduleName);
|
|
342
|
+
return {
|
|
343
|
+
...state,
|
|
344
|
+
slots: {
|
|
345
|
+
...state.slots,
|
|
346
|
+
[slotName]: slot,
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
});
|
|
309
350
|
|
|
310
351
|
/**
|
|
311
352
|
* @internal
|
|
@@ -317,79 +358,3 @@ export const reset: () => void = extensionStore.action(() => {
|
|
|
317
358
|
extensions: {},
|
|
318
359
|
};
|
|
319
360
|
});
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Returns information describing all extensions which can be rendered into an extension slot with
|
|
323
|
-
* the specified name.
|
|
324
|
-
* The returned information describe the extension itself, as well as the extension slot name(s)
|
|
325
|
-
* with which it has been attached.
|
|
326
|
-
* @param slotName The extension slot name for which matching extension info should be returned.
|
|
327
|
-
* @param moduleName The module name. Used for applying extension-specific config values to the result.
|
|
328
|
-
* @param extensionSlot The extension slot information object.
|
|
329
|
-
*/
|
|
330
|
-
export function getUpdatedExtensionSlotInfo(
|
|
331
|
-
slotName: string,
|
|
332
|
-
moduleName: string,
|
|
333
|
-
extensionSlot: ExtensionSlotInfo
|
|
334
|
-
): ExtensionSlotInfo {
|
|
335
|
-
let instance = extensionSlot.instances[moduleName];
|
|
336
|
-
|
|
337
|
-
if (instance) {
|
|
338
|
-
const originalInstance = instance;
|
|
339
|
-
const config =
|
|
340
|
-
getExtensionSlotsConfigStore(moduleName).getState().extensionSlotConfigs[
|
|
341
|
-
slotName
|
|
342
|
-
] ?? {};
|
|
343
|
-
|
|
344
|
-
if (Array.isArray(config.add)) {
|
|
345
|
-
config.add.forEach((extensionId) => {
|
|
346
|
-
if (!instance.addedIds.includes(extensionId)) {
|
|
347
|
-
instance = {
|
|
348
|
-
...instance,
|
|
349
|
-
addedIds: [...instance.addedIds, extensionId],
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (Array.isArray(config.remove)) {
|
|
356
|
-
config.remove.forEach((extensionId) => {
|
|
357
|
-
if (!instance.removedIds.includes(extensionId)) {
|
|
358
|
-
instance = {
|
|
359
|
-
...instance,
|
|
360
|
-
removedIds: [...instance.removedIds, extensionId],
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if (Array.isArray(config.order)) {
|
|
367
|
-
const testOrder = config.order.join(",");
|
|
368
|
-
const fullOrder = instance.idOrder.join(",");
|
|
369
|
-
|
|
370
|
-
if (!fullOrder.endsWith(testOrder)) {
|
|
371
|
-
config.order.forEach((extensionId) => {
|
|
372
|
-
instance = {
|
|
373
|
-
...instance,
|
|
374
|
-
idOrder: [
|
|
375
|
-
...instance.idOrder.filter((m) => m !== extensionId),
|
|
376
|
-
extensionId,
|
|
377
|
-
],
|
|
378
|
-
};
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (instance !== originalInstance) {
|
|
384
|
-
return {
|
|
385
|
-
...extensionSlot,
|
|
386
|
-
instances: {
|
|
387
|
-
...extensionSlot.instances,
|
|
388
|
-
[moduleName]: instance,
|
|
389
|
-
},
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
return extensionSlot;
|
|
395
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
export * from "./contexts";
|
|
2
|
+
export * from "./store";
|
|
2
3
|
export * from "./extensions";
|
|
3
4
|
export * from "./helpers";
|
|
4
5
|
export * from "./render";
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
// Temporary compatibility hack
|
|
8
|
+
// What is now `extensionInternalStore` used to be exposed
|
|
9
|
+
// and used as `extensionStore`.
|
|
10
|
+
import { getExtensionInternalStore } from "./store";
|
|
11
|
+
/** @deprecated Use `getExtensionStore`. The structure of this store has also changed. */
|
|
12
|
+
const internalStore = getExtensionInternalStore();
|
|
13
|
+
export { internalStore as extensionStore };
|
package/src/render.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { update } from "@openmrs/esm-state";
|
|
|
3
3
|
import { mountRootParcel, Parcel } from "single-spa";
|
|
4
4
|
import { getExtensionNameFromId, getExtensionRegistration } from "./extensions";
|
|
5
5
|
import { checkStatus, getCustomProps } from "./helpers";
|
|
6
|
-
import {
|
|
6
|
+
import { updateInternalExtensionStore } from "./store";
|
|
7
7
|
|
|
8
8
|
export interface CancelLoading {
|
|
9
9
|
(): void;
|
|
@@ -54,7 +54,7 @@ export function renderExtension(
|
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
updateInternalExtensionStore((state) =>
|
|
58
58
|
update(
|
|
59
59
|
state,
|
|
60
60
|
[
|
|
@@ -68,6 +68,10 @@ export function renderExtension(
|
|
|
68
68
|
)
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
|
+
} else {
|
|
72
|
+
console.warn(
|
|
73
|
+
`Tried to render ${extensionId} into ${extensionSlotName} but no DOM element was available.`
|
|
74
|
+
);
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
return () => {
|