@openmrs/esm-extensions 10.0.1-pre.5542 → 10.0.1-pre.5561
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/.turbo/turbo-build.log +1 -1
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +2 -12
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +64 -67
- package/dist/store.d.ts +0 -4
- package/dist/store.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/extensions.test.ts +0 -16
- package/src/extensions.ts +0 -13
- package/src/index.ts +0 -1
- package/src/render.test.ts +0 -2
- package/src/render.ts +73 -76
- package/src/store.ts +0 -4
- package/dist/helpers.d.ts +0 -3
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js +0 -7
- package/src/helpers.ts +0 -9
package/.turbo/turbo-build.log
CHANGED
package/dist/extensions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAAA,kCAAkC;
|
|
1
|
+
{"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../src/extensions.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAwBlC,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAQ9B,MAAM,SAAS,CAAC;AAyMjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,UAGzD;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,sBAAsB,EAC7B,WAAW,EAAE,MAAM,GAClB,qBAAqB,GAAG,SAAS,CAGnC;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAG/F;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAO7E,CAAC;AAEN;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QA4B3D;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAmBpE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,iBAAiB,EAAE,MAAM,QAmBlD;AA4ID;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,wBAAwB,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAOlH;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAEjF;AAqBD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAsC1E,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,IAOzB,CAAC"}
|
package/dist/extensions.js
CHANGED
|
@@ -9,10 +9,7 @@
|
|
|
9
9
|
import { getExtensionConfigFromExtensionSlotStore, getExtensionConfigFromStore, getExtensionSlotConfigFromStore, getExtensionSlotsConfigStore, getExtensionsConfigStore } from "@openmrs/esm-config";
|
|
10
10
|
import { evaluateAsBoolean } from "@openmrs/esm-expression-evaluator";
|
|
11
11
|
import { featureFlagsStore } from "@openmrs/esm-feature-flags";
|
|
12
|
-
import { subscribeConnectivityChanged } from "@openmrs/esm-globals";
|
|
13
|
-
import { isOnline as isOnlineFn } from "@openmrs/esm-utils";
|
|
14
12
|
import { isEqual, merge } from "lodash-es";
|
|
15
|
-
import { checkStatusFor } from "./helpers.js";
|
|
16
13
|
import { getExtensionRenderingsStore, getExtensionInternalStore, getExtensionStore, scheduleRecomputation, updateInternalExtensionStore } from "./store.js";
|
|
17
14
|
const extensionInternalStore = getExtensionInternalStore();
|
|
18
15
|
const extensionStore = getExtensionStore();
|
|
@@ -86,7 +83,6 @@ function recomputeExtensionOutputStore() {
|
|
|
86
83
|
const previousSlots = extensionStore.getState().slots;
|
|
87
84
|
const slots = {};
|
|
88
85
|
let changed = false;
|
|
89
|
-
const isOnline = isOnlineFn();
|
|
90
86
|
const enabledFeatureFlags = Object.entries(featureFlagState.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);
|
|
91
87
|
for (let [slotName, slot] of Object.entries(internalState.slots)){
|
|
92
88
|
const previous = previousSlots[slotName];
|
|
@@ -95,7 +91,7 @@ function recomputeExtensionOutputStore() {
|
|
|
95
91
|
continue;
|
|
96
92
|
}
|
|
97
93
|
const { config } = getExtensionSlotConfigFromStore(extensionSlotConfigs, slot.name);
|
|
98
|
-
const candidateExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigState, enabledFeatureFlags,
|
|
94
|
+
const candidateExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigState, enabledFeatureFlags, sessionState.session);
|
|
99
95
|
if (previous && previous.moduleName === slot.moduleName && isEqual(previous.candidateExtensions, candidateExtensions)) {
|
|
100
96
|
slots[slotName] = previous;
|
|
101
97
|
} else {
|
|
@@ -149,7 +145,6 @@ function updateOutputStoreToCurrent() {
|
|
|
149
145
|
markSlotsDirty(null);
|
|
150
146
|
}
|
|
151
147
|
updateOutputStoreToCurrent();
|
|
152
|
-
subscribeConnectivityChanged(updateOutputStoreToCurrent);
|
|
153
148
|
function createNewExtensionSlotInfo(slotName, moduleName) {
|
|
154
149
|
return {
|
|
155
150
|
moduleName,
|
|
@@ -325,7 +320,7 @@ export function getExtensionRegistration(extensionId) {
|
|
|
325
320
|
}
|
|
326
321
|
}
|
|
327
322
|
}
|
|
328
|
-
function getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags,
|
|
323
|
+
function getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags, session) {
|
|
329
324
|
const attachedIds = internalState.slots[slotName].attachedIds;
|
|
330
325
|
const assignedIds = calculateAssignedIds(config, attachedIds);
|
|
331
326
|
const extensions = [];
|
|
@@ -351,9 +346,6 @@ function getAssignedExtensionsFromSlotData(slotName, internalState, config, exte
|
|
|
351
346
|
if (extension.featureFlag && !enabledFeatureFlags.includes(extension.featureFlag)) {
|
|
352
347
|
continue;
|
|
353
348
|
}
|
|
354
|
-
if (window.offlineEnabled && !checkStatusFor(isOnline, extension.online, extension.offline)) {
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
349
|
extensions.push({
|
|
358
350
|
id,
|
|
359
351
|
name,
|
|
@@ -361,8 +353,6 @@ function getAssignedExtensionsFromSlotData(slotName, internalState, config, exte
|
|
|
361
353
|
config: extensionConfig,
|
|
362
354
|
featureFlag: extension.featureFlag,
|
|
363
355
|
meta: extension.meta,
|
|
364
|
-
online: extensionConfig?.['Display conditions']?.online ?? extension.online ?? true,
|
|
365
|
-
offline: extensionConfig?.['Display conditions']?.offline ?? extension.offline ?? false,
|
|
366
356
|
displayConditionExpression: extensionConfig?.['Display conditions']?.expression || extension.displayExpression
|
|
367
357
|
});
|
|
368
358
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,WAAW,EAEhB,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,WAAW,EAEhB,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,CAAC;CACV;AAED,KAAK,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;AAyR3C;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,WAAW,EAChD,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,GAAG,CAAC,GAC3B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAQlC;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CAEjD;AAoCD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,WAAW,EACvB,iBAAiB,EAAE,MAAM,EACzB,uBAAuB,EAAE,MAAM,EAC/B,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,CAAC,WAAW,EAAE,YAAY,KAAK,YAAuB,EACtE,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACxC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqGxB"}
|
package/dist/render.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** @module @category Extension */ import { mountRootParcel } from "single-spa";
|
|
2
2
|
import { getExtensionNameFromId, getExtensionRegistration } from "./extensions.js";
|
|
3
|
-
import { checkStatus } from "./helpers.js";
|
|
4
3
|
import { registerExtensionRendering, unregisterExtensionRendering } from "./store.js";
|
|
5
4
|
let parcelCount = 0;
|
|
6
5
|
let parcelMounter = null;
|
|
@@ -275,77 +274,75 @@ let parcelMounter = null;
|
|
|
275
274
|
if (!extensionRegistration) {
|
|
276
275
|
throw Error(`Couldn't find extension '${extensionName}' to attach to '${extensionSlotName}'`);
|
|
277
276
|
}
|
|
278
|
-
const { meta, moduleName,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const forgetSafely = (cleanupErrorMessage)=>{
|
|
287
|
-
try {
|
|
288
|
-
forget();
|
|
289
|
-
} catch (cleanupError) {
|
|
290
|
-
console.error(cleanupErrorMessage, cleanupError);
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
// Registered before loading so that the config system can start resolving this extension's
|
|
294
|
-
// config while its bundle is still in flight. Registering drives the config derivation
|
|
295
|
-
// synchronously, so a failure there has to release the record before it propagates — nothing
|
|
296
|
-
// else has a handle on it yet.
|
|
297
|
-
try {
|
|
298
|
-
registerExtensionRendering({
|
|
299
|
-
renderingId,
|
|
300
|
-
extensionName,
|
|
301
|
-
extensionModuleName: moduleName,
|
|
302
|
-
extensionId,
|
|
303
|
-
slotName: extensionSlotName,
|
|
304
|
-
slotModuleName: extensionSlotModuleName
|
|
305
|
-
});
|
|
306
|
-
} catch (e) {
|
|
307
|
-
forgetSafely(`Recomputing configuration after registering '${extensionId}' failed also failed`);
|
|
308
|
-
throw e;
|
|
309
|
-
}
|
|
310
|
-
let lifecycle;
|
|
311
|
-
try {
|
|
312
|
-
lifecycle = await load();
|
|
313
|
-
} catch (e) {
|
|
314
|
-
forgetSafely(`Recomputing configuration after '${extensionId}' failed to load also failed`);
|
|
315
|
-
throw e;
|
|
316
|
-
}
|
|
277
|
+
const { meta, moduleName, load } = extensionRegistration;
|
|
278
|
+
const id = parcelCount++;
|
|
279
|
+
const renderingId = `${extensionSlotName}/${extensionId}-${id}`;
|
|
280
|
+
// Marks the node for the UI editor, which needs to pair a rendering with the element it went
|
|
281
|
+
// into and cannot tell two renderings of one extension apart by any other attribute.
|
|
282
|
+
domElement.dataset.extensionRenderingId = renderingId;
|
|
283
|
+
const forget = ()=>unregisterExtensionRendering(renderingId);
|
|
284
|
+
const forgetSafely = (cleanupErrorMessage)=>{
|
|
317
285
|
try {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}), {
|
|
322
|
-
...additionalProps,
|
|
323
|
-
_meta: meta,
|
|
324
|
-
_extensionContext: {
|
|
325
|
-
extensionId,
|
|
326
|
-
extensionSlotName,
|
|
327
|
-
extensionSlotModuleName,
|
|
328
|
-
extensionModuleName: moduleName,
|
|
329
|
-
extensionMeta: meta
|
|
330
|
-
},
|
|
331
|
-
domElement
|
|
332
|
-
});
|
|
333
|
-
} catch (e) {
|
|
334
|
-
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
335
|
-
throw e;
|
|
286
|
+
forget();
|
|
287
|
+
} catch (cleanupError) {
|
|
288
|
+
console.error(cleanupErrorMessage, cleanupError);
|
|
336
289
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
290
|
+
};
|
|
291
|
+
// Registered before loading so that the config system can start resolving this extension's
|
|
292
|
+
// config while its bundle is still in flight. Registering drives the config derivation
|
|
293
|
+
// synchronously, so a failure there has to release the record before it propagates — nothing
|
|
294
|
+
// else has a handle on it yet.
|
|
295
|
+
try {
|
|
296
|
+
registerExtensionRendering({
|
|
297
|
+
renderingId,
|
|
298
|
+
extensionName,
|
|
299
|
+
extensionModuleName: moduleName,
|
|
300
|
+
extensionId,
|
|
301
|
+
slotName: extensionSlotName,
|
|
302
|
+
slotModuleName: extensionSlotModuleName
|
|
343
303
|
});
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
304
|
+
} catch (e) {
|
|
305
|
+
forgetSafely(`Recomputing configuration after registering '${extensionId}' failed also failed`);
|
|
306
|
+
throw e;
|
|
307
|
+
}
|
|
308
|
+
let lifecycle;
|
|
309
|
+
try {
|
|
310
|
+
lifecycle = await load();
|
|
311
|
+
} catch (e) {
|
|
312
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to load also failed`);
|
|
313
|
+
throw e;
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
parcel = await renderParcel(renderFunction({
|
|
317
|
+
...lifecycle,
|
|
318
|
+
name: `${extensionSlotName}/${extensionName}-${id}`
|
|
319
|
+
}), {
|
|
320
|
+
...additionalProps,
|
|
321
|
+
_meta: meta,
|
|
322
|
+
_extensionContext: {
|
|
323
|
+
extensionId,
|
|
324
|
+
extensionSlotName,
|
|
325
|
+
extensionSlotModuleName,
|
|
326
|
+
extensionModuleName: moduleName,
|
|
327
|
+
extensionMeta: meta
|
|
328
|
+
},
|
|
329
|
+
domElement
|
|
347
330
|
});
|
|
331
|
+
} catch (e) {
|
|
332
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
333
|
+
throw e;
|
|
348
334
|
}
|
|
335
|
+
// A parcel that fails to bootstrap or mount never settles `unmountPromise`, so the mount
|
|
336
|
+
// rejection has to release the record too. single-spa hard-fails parcels, so its own error
|
|
337
|
+
// handlers never see either failure and the rejected promise is the only channel left.
|
|
338
|
+
parcel.mountPromise.then(undefined, (err)=>{
|
|
339
|
+
console.error(`Extension '${extensionId}' in slot '${extensionSlotName}' failed to mount`, err);
|
|
340
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
341
|
+
});
|
|
342
|
+
parcel.unmountPromise.then(()=>forgetSafely(`Recomputing configuration after unmounting '${extensionId}' failed`), (err)=>{
|
|
343
|
+
console.error(`Extension '${extensionId}' in slot '${extensionSlotName}' failed to unmount`, err);
|
|
344
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to unmount also failed`);
|
|
345
|
+
});
|
|
349
346
|
} else {
|
|
350
347
|
console.warn(`Tried to render ${extensionId} into ${extensionSlotName} but no DOM element was available.`);
|
|
351
348
|
}
|
package/dist/store.d.ts
CHANGED
|
@@ -10,8 +10,6 @@ export interface ExtensionRegistration {
|
|
|
10
10
|
readonly moduleName: string;
|
|
11
11
|
readonly meta: Readonly<ExtensionMeta>;
|
|
12
12
|
readonly order?: number;
|
|
13
|
-
readonly online?: boolean;
|
|
14
|
-
readonly offline?: boolean;
|
|
15
13
|
readonly privileges?: string | Array<string>;
|
|
16
14
|
readonly featureFlag?: string;
|
|
17
15
|
readonly displayExpression?: string;
|
|
@@ -103,8 +101,6 @@ export interface AssignedExtension {
|
|
|
103
101
|
readonly meta: Readonly<ExtensionMeta>;
|
|
104
102
|
/** The extension's config. Note that this will be `null` until the slot is mounted. */
|
|
105
103
|
readonly config: Readonly<ConfigObject> | null;
|
|
106
|
-
readonly online?: boolean | object;
|
|
107
|
-
readonly offline?: boolean | object;
|
|
108
104
|
readonly featureFlag?: string;
|
|
109
105
|
/** The condition under which this extension should be displayed. */
|
|
110
106
|
readonly displayConditionExpression?: string;
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,KAAK,EAA+B,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGrF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-extensions",
|
|
3
|
-
"version": "10.0.1-pre.
|
|
3
|
+
"version": "10.0.1-pre.5561",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Coordinates extensions and extension points in the OpenMRS Frontend",
|
|
6
6
|
"type": "module",
|
|
@@ -57,21 +57,21 @@
|
|
|
57
57
|
"lodash-es": "^4.17.21"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@openmrs/esm-api": "^10.0.1-pre.
|
|
61
|
-
"@openmrs/esm-config": "^10.0.1-pre.
|
|
62
|
-
"@openmrs/esm-expression-evaluator": "^10.0.1-pre.
|
|
63
|
-
"@openmrs/esm-feature-flags": "^10.0.1-pre.
|
|
64
|
-
"@openmrs/esm-state": "^10.0.1-pre.
|
|
65
|
-
"@openmrs/esm-utils": "^10.0.1-pre.
|
|
60
|
+
"@openmrs/esm-api": "^10.0.1-pre.5561",
|
|
61
|
+
"@openmrs/esm-config": "^10.0.1-pre.5561",
|
|
62
|
+
"@openmrs/esm-expression-evaluator": "^10.0.1-pre.5561",
|
|
63
|
+
"@openmrs/esm-feature-flags": "^10.0.1-pre.5561",
|
|
64
|
+
"@openmrs/esm-state": "^10.0.1-pre.5561",
|
|
65
|
+
"@openmrs/esm-utils": "^10.0.1-pre.5561",
|
|
66
66
|
"single-spa": "6.x"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@openmrs/esm-api": "10.0.1-pre.
|
|
70
|
-
"@openmrs/esm-config": "10.0.1-pre.
|
|
71
|
-
"@openmrs/esm-expression-evaluator": "10.0.1-pre.
|
|
72
|
-
"@openmrs/esm-feature-flags": "10.0.1-pre.
|
|
73
|
-
"@openmrs/esm-state": "10.0.1-pre.
|
|
74
|
-
"@openmrs/esm-utils": "10.0.1-pre.
|
|
69
|
+
"@openmrs/esm-api": "10.0.1-pre.5561",
|
|
70
|
+
"@openmrs/esm-config": "10.0.1-pre.5561",
|
|
71
|
+
"@openmrs/esm-expression-evaluator": "10.0.1-pre.5561",
|
|
72
|
+
"@openmrs/esm-feature-flags": "10.0.1-pre.5561",
|
|
73
|
+
"@openmrs/esm-state": "10.0.1-pre.5561",
|
|
74
|
+
"@openmrs/esm-utils": "10.0.1-pre.5561",
|
|
75
75
|
"@swc/cli": "0.8.1",
|
|
76
76
|
"@swc/core": "1.15.21",
|
|
77
77
|
"@vitest/coverage-v8": "^4.1.2",
|
package/src/extensions.test.ts
CHANGED
|
@@ -40,22 +40,6 @@ vi.mock('@openmrs/esm-api', () => ({
|
|
|
40
40
|
userHasAccess: vi.fn(() => true),
|
|
41
41
|
}));
|
|
42
42
|
|
|
43
|
-
vi.mock('@openmrs/esm-utils', async (importOriginal) => {
|
|
44
|
-
const actual = await importOriginal<typeof import('@openmrs/esm-utils')>();
|
|
45
|
-
return {
|
|
46
|
-
...actual,
|
|
47
|
-
isOnline: vi.fn(() => true),
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
vi.mock('@openmrs/esm-globals', async (importOriginal) => {
|
|
52
|
-
const actual = await importOriginal<typeof import('@openmrs/esm-globals')>();
|
|
53
|
-
return {
|
|
54
|
-
...actual,
|
|
55
|
-
subscribeConnectivityChanged: vi.fn(),
|
|
56
|
-
};
|
|
57
|
-
});
|
|
58
|
-
|
|
59
43
|
// Helper to create unique names for test isolation
|
|
60
44
|
let nameCounter = 0;
|
|
61
45
|
function getUniqueName(prefix: string = 'test'): string {
|
package/src/extensions.ts
CHANGED
|
@@ -21,10 +21,7 @@ import {
|
|
|
21
21
|
} from '@openmrs/esm-config';
|
|
22
22
|
import { evaluateAsBoolean, type VariablesMap } from '@openmrs/esm-expression-evaluator';
|
|
23
23
|
import { type FeatureFlagsStore, featureFlagsStore } from '@openmrs/esm-feature-flags';
|
|
24
|
-
import { subscribeConnectivityChanged } from '@openmrs/esm-globals';
|
|
25
|
-
import { isOnline as isOnlineFn } from '@openmrs/esm-utils';
|
|
26
24
|
import { isEqual, merge } from 'lodash-es';
|
|
27
|
-
import { checkStatusFor } from './helpers';
|
|
28
25
|
import {
|
|
29
26
|
type AssignedExtension,
|
|
30
27
|
type ExtensionInternalStore,
|
|
@@ -142,7 +139,6 @@ function updateExtensionOutputStore(
|
|
|
142
139
|
const slots: Record<string, ExtensionSlotState> = {};
|
|
143
140
|
let changed = false;
|
|
144
141
|
|
|
145
|
-
const isOnline = isOnlineFn();
|
|
146
142
|
const enabledFeatureFlags = Object.entries(featureFlagState.flags)
|
|
147
143
|
.filter(([, { enabled }]) => enabled)
|
|
148
144
|
.map(([name]) => name);
|
|
@@ -162,7 +158,6 @@ function updateExtensionOutputStore(
|
|
|
162
158
|
config,
|
|
163
159
|
extensionsConfigState,
|
|
164
160
|
enabledFeatureFlags,
|
|
165
|
-
isOnline,
|
|
166
161
|
sessionState.session,
|
|
167
162
|
);
|
|
168
163
|
|
|
@@ -231,7 +226,6 @@ function updateOutputStoreToCurrent() {
|
|
|
231
226
|
}
|
|
232
227
|
|
|
233
228
|
updateOutputStoreToCurrent();
|
|
234
|
-
subscribeConnectivityChanged(updateOutputStoreToCurrent);
|
|
235
229
|
|
|
236
230
|
function createNewExtensionSlotInfo(slotName: string, moduleName?: string): ExtensionSlotInfo {
|
|
237
231
|
return {
|
|
@@ -434,7 +428,6 @@ function getAssignedExtensionsFromSlotData(
|
|
|
434
428
|
config: ExtensionSlotConfig,
|
|
435
429
|
extensionConfigStoreState: ExtensionsConfigStore,
|
|
436
430
|
enabledFeatureFlags: Array<string>,
|
|
437
|
-
isOnline: boolean,
|
|
438
431
|
session: Session | null,
|
|
439
432
|
): Array<AssignedExtension> {
|
|
440
433
|
const attachedIds = internalState.slots[slotName].attachedIds;
|
|
@@ -473,10 +466,6 @@ function getAssignedExtensionsFromSlotData(
|
|
|
473
466
|
continue;
|
|
474
467
|
}
|
|
475
468
|
|
|
476
|
-
if (window.offlineEnabled && !checkStatusFor(isOnline, extension.online, extension.offline)) {
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
469
|
extensions.push({
|
|
481
470
|
id,
|
|
482
471
|
name,
|
|
@@ -484,8 +473,6 @@ function getAssignedExtensionsFromSlotData(
|
|
|
484
473
|
config: extensionConfig,
|
|
485
474
|
featureFlag: extension.featureFlag,
|
|
486
475
|
meta: extension.meta,
|
|
487
|
-
online: extensionConfig?.['Display conditions']?.online ?? extension.online ?? true,
|
|
488
|
-
offline: extensionConfig?.['Display conditions']?.offline ?? extension.offline ?? false,
|
|
489
476
|
displayConditionExpression: extensionConfig?.['Display conditions']?.expression || extension.displayExpression,
|
|
490
477
|
});
|
|
491
478
|
}
|
package/src/index.ts
CHANGED
package/src/render.test.ts
CHANGED
package/src/render.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
type ParcelProps,
|
|
10
10
|
} from 'single-spa';
|
|
11
11
|
import { getExtensionNameFromId, getExtensionRegistration } from './extensions';
|
|
12
|
-
import { checkStatus } from './helpers';
|
|
13
12
|
import { registerExtensionRendering, unregisterExtensionRendering } from './store';
|
|
14
13
|
|
|
15
14
|
export interface CancelLoading {
|
|
@@ -389,94 +388,92 @@ export async function renderExtension(
|
|
|
389
388
|
throw Error(`Couldn't find extension '${extensionName}' to attach to '${extensionSlotName}'`);
|
|
390
389
|
}
|
|
391
390
|
|
|
392
|
-
const { meta, moduleName,
|
|
391
|
+
const { meta, moduleName, load } = extensionRegistration;
|
|
393
392
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const renderingId = `${extensionSlotName}/${extensionId}-${id}`;
|
|
393
|
+
const id = parcelCount++;
|
|
394
|
+
const renderingId = `${extensionSlotName}/${extensionId}-${id}`;
|
|
397
395
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
396
|
+
// Marks the node for the UI editor, which needs to pair a rendering with the element it went
|
|
397
|
+
// into and cannot tell two renderings of one extension apart by any other attribute.
|
|
398
|
+
domElement.dataset.extensionRenderingId = renderingId;
|
|
401
399
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
try {
|
|
405
|
-
forget();
|
|
406
|
-
} catch (cleanupError) {
|
|
407
|
-
console.error(cleanupErrorMessage, cleanupError);
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
// Registered before loading so that the config system can start resolving this extension's
|
|
412
|
-
// config while its bundle is still in flight. Registering drives the config derivation
|
|
413
|
-
// synchronously, so a failure there has to release the record before it propagates — nothing
|
|
414
|
-
// else has a handle on it yet.
|
|
400
|
+
const forget = () => unregisterExtensionRendering(renderingId);
|
|
401
|
+
const forgetSafely = (cleanupErrorMessage: string) => {
|
|
415
402
|
try {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
extensionModuleName: moduleName,
|
|
420
|
-
extensionId,
|
|
421
|
-
slotName: extensionSlotName,
|
|
422
|
-
slotModuleName: extensionSlotModuleName,
|
|
423
|
-
});
|
|
424
|
-
} catch (e) {
|
|
425
|
-
forgetSafely(`Recomputing configuration after registering '${extensionId}' failed also failed`);
|
|
426
|
-
|
|
427
|
-
throw e;
|
|
403
|
+
forget();
|
|
404
|
+
} catch (cleanupError) {
|
|
405
|
+
console.error(cleanupErrorMessage, cleanupError);
|
|
428
406
|
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// Registered before loading so that the config system can start resolving this extension's
|
|
410
|
+
// config while its bundle is still in flight. Registering drives the config derivation
|
|
411
|
+
// synchronously, so a failure there has to release the record before it propagates — nothing
|
|
412
|
+
// else has a handle on it yet.
|
|
413
|
+
try {
|
|
414
|
+
registerExtensionRendering({
|
|
415
|
+
renderingId,
|
|
416
|
+
extensionName,
|
|
417
|
+
extensionModuleName: moduleName,
|
|
418
|
+
extensionId,
|
|
419
|
+
slotName: extensionSlotName,
|
|
420
|
+
slotModuleName: extensionSlotModuleName,
|
|
421
|
+
});
|
|
422
|
+
} catch (e) {
|
|
423
|
+
forgetSafely(`Recomputing configuration after registering '${extensionId}' failed also failed`);
|
|
429
424
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
try {
|
|
433
|
-
lifecycle = await load();
|
|
434
|
-
} catch (e) {
|
|
435
|
-
forgetSafely(`Recomputing configuration after '${extensionId}' failed to load also failed`);
|
|
425
|
+
throw e;
|
|
426
|
+
}
|
|
436
427
|
|
|
437
|
-
|
|
438
|
-
}
|
|
428
|
+
let lifecycle: LifeCycles;
|
|
439
429
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
name: `${extensionSlotName}/${extensionName}-${id}`,
|
|
445
|
-
}),
|
|
446
|
-
{
|
|
447
|
-
...additionalProps,
|
|
448
|
-
_meta: meta,
|
|
449
|
-
_extensionContext: {
|
|
450
|
-
extensionId,
|
|
451
|
-
extensionSlotName,
|
|
452
|
-
extensionSlotModuleName,
|
|
453
|
-
extensionModuleName: moduleName,
|
|
454
|
-
extensionMeta: meta,
|
|
455
|
-
},
|
|
456
|
-
domElement,
|
|
457
|
-
},
|
|
458
|
-
);
|
|
459
|
-
} catch (e) {
|
|
460
|
-
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
430
|
+
try {
|
|
431
|
+
lifecycle = await load();
|
|
432
|
+
} catch (e) {
|
|
433
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to load also failed`);
|
|
461
434
|
|
|
462
|
-
|
|
463
|
-
|
|
435
|
+
throw e;
|
|
436
|
+
}
|
|
464
437
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
438
|
+
try {
|
|
439
|
+
parcel = await renderParcel(
|
|
440
|
+
renderFunction({
|
|
441
|
+
...lifecycle,
|
|
442
|
+
name: `${extensionSlotName}/${extensionName}-${id}`,
|
|
443
|
+
}),
|
|
444
|
+
{
|
|
445
|
+
...additionalProps,
|
|
446
|
+
_meta: meta,
|
|
447
|
+
_extensionContext: {
|
|
448
|
+
extensionId,
|
|
449
|
+
extensionSlotName,
|
|
450
|
+
extensionSlotModuleName,
|
|
451
|
+
extensionModuleName: moduleName,
|
|
452
|
+
extensionMeta: meta,
|
|
453
|
+
},
|
|
454
|
+
domElement,
|
|
477
455
|
},
|
|
478
456
|
);
|
|
457
|
+
} catch (e) {
|
|
458
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
459
|
+
|
|
460
|
+
throw e;
|
|
479
461
|
}
|
|
462
|
+
|
|
463
|
+
// A parcel that fails to bootstrap or mount never settles `unmountPromise`, so the mount
|
|
464
|
+
// rejection has to release the record too. single-spa hard-fails parcels, so its own error
|
|
465
|
+
// handlers never see either failure and the rejected promise is the only channel left.
|
|
466
|
+
parcel.mountPromise.then(undefined, (err) => {
|
|
467
|
+
console.error(`Extension '${extensionId}' in slot '${extensionSlotName}' failed to mount`, err);
|
|
468
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to mount also failed`);
|
|
469
|
+
});
|
|
470
|
+
parcel.unmountPromise.then(
|
|
471
|
+
() => forgetSafely(`Recomputing configuration after unmounting '${extensionId}' failed`),
|
|
472
|
+
(err) => {
|
|
473
|
+
console.error(`Extension '${extensionId}' in slot '${extensionSlotName}' failed to unmount`, err);
|
|
474
|
+
forgetSafely(`Recomputing configuration after '${extensionId}' failed to unmount also failed`);
|
|
475
|
+
},
|
|
476
|
+
);
|
|
480
477
|
} else {
|
|
481
478
|
console.warn(`Tried to render ${extensionId} into ${extensionSlotName} but no DOM element was available.`);
|
|
482
479
|
}
|
package/src/store.ts
CHANGED
|
@@ -14,8 +14,6 @@ export interface ExtensionRegistration {
|
|
|
14
14
|
readonly moduleName: string;
|
|
15
15
|
readonly meta: Readonly<ExtensionMeta>;
|
|
16
16
|
readonly order?: number;
|
|
17
|
-
readonly online?: boolean;
|
|
18
|
-
readonly offline?: boolean;
|
|
19
17
|
readonly privileges?: string | Array<string>;
|
|
20
18
|
readonly featureFlag?: string;
|
|
21
19
|
readonly displayExpression?: string;
|
|
@@ -116,8 +114,6 @@ export interface AssignedExtension {
|
|
|
116
114
|
readonly meta: Readonly<ExtensionMeta>;
|
|
117
115
|
/** The extension's config. Note that this will be `null` until the slot is mounted. */
|
|
118
116
|
readonly config: Readonly<ConfigObject> | null;
|
|
119
|
-
readonly online?: boolean | object;
|
|
120
|
-
readonly offline?: boolean | object;
|
|
121
117
|
readonly featureFlag?: string;
|
|
122
118
|
/** The condition under which this extension should be displayed. */
|
|
123
119
|
readonly displayConditionExpression?: string;
|
package/dist/helpers.d.ts
DELETED
package/dist/helpers.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,MAAM,GAAE,OAAO,GAAG,MAAa,EAAE,OAAO,GAAE,OAAO,GAAG,MAAc,WAE7F;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,GAAE,OAAO,GAAG,MAAa,EAAE,OAAO,GAAE,OAAO,GAAG,MAAc,WAEjH"}
|
package/dist/helpers.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { isOnline } from "@openmrs/esm-utils";
|
|
2
|
-
export function checkStatus(online = true, offline = false) {
|
|
3
|
-
return checkStatusFor(isOnline(), online, offline);
|
|
4
|
-
}
|
|
5
|
-
export function checkStatusFor(status, online = true, offline = false) {
|
|
6
|
-
return Boolean(status ? online : offline);
|
|
7
|
-
}
|
package/src/helpers.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { isOnline } from '@openmrs/esm-utils';
|
|
2
|
-
|
|
3
|
-
export function checkStatus(online: boolean | object = true, offline: boolean | object = false) {
|
|
4
|
-
return checkStatusFor(isOnline(), online, offline);
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function checkStatusFor(status: boolean, online: boolean | object = true, offline: boolean | object = false) {
|
|
8
|
-
return Boolean(status ? online : offline);
|
|
9
|
-
}
|