@elliemae/ssf-host 2.2.0 → 2.3.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/cjs/guest.js +0 -4
- package/dist/cjs/host.js +46 -40
- package/dist/cjs/v1-guest-v2-host.html +67 -0
- package/dist/cjs/v2-host-v1-guest.html +77 -0
- package/dist/esm/guest.js +0 -4
- package/dist/esm/host.js +46 -40
- package/dist/esm/v1-guest-v2-host.html +67 -0
- package/dist/esm/v2-host-v1-guest.html +77 -0
- package/dist/public/index.html +1 -1
- package/dist/public/js/{emuiSsfHost.b9fc3b6ba3c602646972.js → emuiSsfHost.574002466a68fa2d7031.js} +2 -2
- package/dist/public/js/emuiSsfHost.574002466a68fa2d7031.js.br +0 -0
- package/dist/public/js/emuiSsfHost.574002466a68fa2d7031.js.gz +0 -0
- package/dist/public/js/emuiSsfHost.574002466a68fa2d7031.js.map +1 -0
- package/dist/public/loan-object-v1.js +3 -0
- package/dist/public/loan-object-v1.js.br +0 -0
- package/dist/public/loan-object-v1.js.gz +0 -0
- package/dist/public/loan-object-v1.js.map +1 -0
- package/dist/public/loan-object.js +1 -1
- package/dist/public/loan-object.js.br +0 -0
- package/dist/public/loan-object.js.gz +0 -0
- package/dist/public/loan-object.js.map +1 -1
- package/dist/public/utils.js +1 -1
- package/dist/public/utils.js.br +0 -0
- package/dist/public/utils.js.gz +0 -0
- package/dist/public/utils.js.map +1 -1
- package/dist/public/v1-guest-v2-host.html +1 -0
- package/dist/public/v1-guest.html +65 -0
- package/dist/public/v1-host.html +69 -0
- package/dist/public/v2-host-v1-guest.html +1 -0
- package/dist/types/guest.d.ts +0 -4
- package/dist/types/host.d.ts +0 -13
- package/dist/types/ihost.d.ts +0 -12
- package/dist/types/types.d.ts +0 -5
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.br +0 -0
- package/dist/umd/index.js.gz +0 -0
- package/dist/umd/index.js.map +1 -1
- package/dist/umd/loan-object-v1.js +3 -0
- package/dist/umd/loan-object-v1.js.br +0 -0
- package/dist/umd/loan-object-v1.js.gz +0 -0
- package/dist/umd/loan-object-v1.js.map +1 -0
- package/dist/umd/loan-object.js +1 -1
- package/dist/umd/loan-object.js.br +0 -0
- package/dist/umd/loan-object.js.gz +0 -0
- package/dist/umd/loan-object.js.map +1 -1
- package/dist/umd/utils.js +1 -1
- package/dist/umd/utils.js.br +0 -0
- package/dist/umd/utils.js.gz +0 -0
- package/dist/umd/utils.js.map +1 -1
- package/dist/umd/v1-guest-v2-host.html +1 -0
- package/dist/umd/v1-guest.html +65 -0
- package/dist/umd/v1-host.html +69 -0
- package/dist/umd/v2-host-v1-guest.html +1 -0
- package/package.json +5 -5
- package/dist/public/js/emuiSsfHost.b9fc3b6ba3c602646972.js.br +0 -0
- package/dist/public/js/emuiSsfHost.b9fc3b6ba3c602646972.js.gz +0 -0
- package/dist/public/js/emuiSsfHost.b9fc3b6ba3c602646972.js.map +0 -1
package/dist/public/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack://ice.host/utils.js"],"sourcesContent":["let appConfig = null;\nlet host = null;\n\nconst createLogger = () => {\n const { logger, http, webvitals, logUnhandledErrors, Console } =\n window.emuiDiagnostics || {};\n if (logger) {\n window.logger = logger({\n transport: http(\n 'https://int.api.puidiagnostics.rd.elliemae.io/v2/logging',\n ),\n // transport: Console(),\n index: 'ssfhost',\n team: 'ui platform',\n appName: 'SSF Host Demo',\n });\n\n webvitals(window.logger);\n logUnhandledErrors(window.logger);\n window.logger.info('SSF Host launched');\n } else console.warn('ui logger missing'); // eslint-disable-line no-console\n};\n\nexport const getHost = () => {\n if (host) return host;\n createLogger();\n const hostOptions = {\n logger: window.logger,\n readyStateCallback: (guest) => {},\n };\n host = new ice.host.SSFHost('IMTProduct', hostOptions);\n // debug loglevel\n // host.setLogLevel(10);\n return host;\n};\n\nexport const getGuestBaseUrl = async () => {\n if (!appConfig) {\n const response = await fetch('./app.config.json');\n appConfig = await response.json();\n }\n const activeEnvConfig = {\n ...appConfig?.options,\n ...appConfig[appConfig.activeEnv]?.options,\n };\n return activeEnvConfig?.guestUrl;\n};\n"],"mappings":"AAAA,IAAIA,EAAY,KACZC,EAAO,KAEX,MAAMC,EAAe,IAAM,CACzB,KAAM,CAAE,OAAAC,EAAQ,KAAAC,EAAM,UAAAC,EAAW,mBAAAC,EAAoB,QAAAC,CAAQ,EAC3D,OAAO,iBAAmB,CAAC,EACzBJ,GACF,OAAO,OAASA,EAAO,CACrB,UAAWC,EACT,0DACF,EAEA,MAAO,UACP,KAAM,cACN,QAAS,eACX,CAAC,EAEDC,EAAU,OAAO,MAAM,EACvBC,EAAmB,OAAO,MAAM,EAChC,OAAO,OAAO,KAAK,mBAAmB,GACjC,QAAQ,KAAK,mBAAmB,CACzC,EAEO,aAAM,QAAU,IAAM,CAC3B,GAAIL,EAAM,OAAOA,EACjBC,EAAa,EACb,MAAMM,EAAc,CAClB,OAAQ,OAAO,OACf,mBAAqBC,GAAU,CAAC,CAClC,EACA,OAAAR,
|
|
1
|
+
{"version":3,"sources":["webpack://ice.host/utils.js"],"sourcesContent":["let appConfig = null;\nlet host = null;\n\nconst createLogger = () => {\n const { logger, http, webvitals, logUnhandledErrors, Console } =\n window.emuiDiagnostics || {};\n if (logger) {\n window.logger = logger({\n transport: http(\n 'https://int.api.puidiagnostics.rd.elliemae.io/v2/logging',\n ),\n // transport: Console(),\n index: 'ssfhost',\n team: 'ui platform',\n appName: 'SSF Host Demo',\n });\n\n webvitals(window.logger);\n logUnhandledErrors(window.logger);\n window.logger.info('SSF Host launched');\n } else console.warn('ui logger missing'); // eslint-disable-line no-console\n};\n\nexport const getHost = () => {\n if (host) return host;\n createLogger();\n const hostOptions = {\n logger: window.logger,\n readyStateCallback: (guest) => {},\n };\n host = (ice?.host?.SSFHost) ? new ice.host.SSFHost('IMTProduct', hostOptions) : null;\n // debug loglevel\n // host.setLogLevel(10);\n return host;\n};\n\nexport const getGuestBaseUrl = async () => {\n if (!appConfig) {\n const response = await fetch('./app.config.json');\n appConfig = await response.json();\n }\n const activeEnvConfig = {\n ...appConfig?.options,\n ...appConfig[appConfig.activeEnv]?.options,\n };\n return activeEnvConfig?.guestUrl;\n};\n"],"mappings":"AAAA,IAAIA,EAAY,KACZC,EAAO,KAEX,MAAMC,EAAe,IAAM,CACzB,KAAM,CAAE,OAAAC,EAAQ,KAAAC,EAAM,UAAAC,EAAW,mBAAAC,EAAoB,QAAAC,CAAQ,EAC3D,OAAO,iBAAmB,CAAC,EACzBJ,GACF,OAAO,OAASA,EAAO,CACrB,UAAWC,EACT,0DACF,EAEA,MAAO,UACP,KAAM,cACN,QAAS,eACX,CAAC,EAEDC,EAAU,OAAO,MAAM,EACvBC,EAAmB,OAAO,MAAM,EAChC,OAAO,OAAO,KAAK,mBAAmB,GACjC,QAAQ,KAAK,mBAAmB,CACzC,EAEO,aAAM,QAAU,IAAM,CAC3B,GAAIL,EAAM,OAAOA,EACjBC,EAAa,EACb,MAAMM,EAAc,CAClB,OAAQ,OAAO,OACf,mBAAqBC,GAAU,CAAC,CAClC,EACA,OAAAR,EAAQ,KAAK,MAAM,QAAW,IAAI,IAAI,KAAK,QAAQ,aAAcO,CAAW,EAAI,KAGzEP,CACT,EAEa,gBAAkB,UACxBD,IAEHA,EAAY,MADK,MAAM,MAAM,mBAAmB,GACrB,KAAK,GAEV,CACtB,GAAGA,GAAW,QACd,GAAGA,EAAUA,EAAU,SAAS,GAAG,OACrC,GACwB","names":["appConfig","host","createLogger","logger","http","webvitals","logUnhandledErrors","Console","hostOptions","guest"],"sourceRoot":"","file":"utils.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Guest V1 -> V2 Host</title><style>body,html,main{height:100%;margin:2px;padding:0}iframe{width:100%;height:100%;border:none}#guest-container{height:100%}</style><script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script><script src="https://cdn.elliemae.io/elliemae/core/ssf/1.0/elli.ssf.guest.js"></script><script defer="defer" src="js/emuiSsfHost.574002466a68fa2d7031.js"></script></head><body><h2>Guest V1 nesting Host V2</h2><div id="result"><p id="loan-details"></p><p id="loan-pre-save-event-details"></p></div><div id="guest-container"></div><script type="module">import{getGuestBaseUrl,getHost}from"./utils.js";const hostV2=getHost(),loadV2Guest=async()=>{const t=await getGuestBaseUrl(),{id:e}=hostV2.loadGuest({id:"guestV2",url:new URL("./v2-guest.html",t).href,title:"Guest V2",targetElement:document.getElementById("guest-container")})};window.addEventListener("load",(async()=>{await elli.script.connect();const t=await elli.script.getObject("Loan"),e=await t.getLoanDetails();document.getElementById("loan-details").innerText=`Loan Data: ${JSON.stringify(e)}`,elli.script.subscribe("loan","onPreSave",((t,e)=>(document.getElementById("loan-pre-save-event-details").innerText=`Presave event data: ${JSON.stringify(e)}`,!1))),hostV2.addScriptingObject(hostV2.cloneScriptingObject(t,{})),await loadV2Guest()}))</script></body></html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Guest V1 with or without V1 Host</title>
|
|
7
|
+
<style>
|
|
8
|
+
html,
|
|
9
|
+
body,
|
|
10
|
+
main {
|
|
11
|
+
height: 100%;
|
|
12
|
+
margin: 4px;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
iframe {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
border: none;
|
|
19
|
+
}
|
|
20
|
+
#guest-container {
|
|
21
|
+
height: 100%;
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
24
|
+
<script src="https://cdn.elliemae.io/elliemae/core/ssf/1.0/elli.ssf.guest.js"></script>
|
|
25
|
+
<script src="https://cdn.elliemae.io/elliemae/core/ssf/1.0/elli.ssf.host.js"></script>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<h2 id="pageHeader">V1 Guest</h2>
|
|
29
|
+
<div id="result">
|
|
30
|
+
<p id="loan-details"></p>
|
|
31
|
+
<p id="loan-pre-save-event-details"></p>
|
|
32
|
+
</div>
|
|
33
|
+
<div id="guest-container"></div>
|
|
34
|
+
<script type="module">
|
|
35
|
+
window.addEventListener('load', async () => {
|
|
36
|
+
await elli.script.connect();
|
|
37
|
+
const loan = await elli.script.getObject('Loan');
|
|
38
|
+
const details = await loan.getLoanDetails();
|
|
39
|
+
document.getElementById(
|
|
40
|
+
'loan-details',
|
|
41
|
+
).innerText = `Loan Data: ${JSON.stringify(details)}`;
|
|
42
|
+
elli.script.subscribe('loan', 'onPreSave', (loan, eventData) => {
|
|
43
|
+
document.getElementById(
|
|
44
|
+
'loan-pre-save-event-details',
|
|
45
|
+
).innerText = `Presave event data: ${JSON.stringify(eventData)}`;
|
|
46
|
+
return false;
|
|
47
|
+
});
|
|
48
|
+
// load the v1 host
|
|
49
|
+
const params = new URLSearchParams(document.location.search);
|
|
50
|
+
if (params.get('nestHostV1') === 'true') {
|
|
51
|
+
const pageHeaderEle = document.getElementById('pageHeader');
|
|
52
|
+
pageHeaderEle.innerText = 'V1 Guest with nested V1 Host';
|
|
53
|
+
const hostV1 = new elli.ssf.Host('HostV1');
|
|
54
|
+
hostV1.publish(elli.ssf.ScriptingObject.fromProxy(loan));
|
|
55
|
+
hostV1.renderGuest(
|
|
56
|
+
{ nestHostV1: false },
|
|
57
|
+
new URL('./v1-guest.html', window.location.href).href,
|
|
58
|
+
document.getElementById('guest-container'),
|
|
59
|
+
{ allowSameOrigin: true },
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
</script>
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Host V1 -> V1 Guest -> V2 Host -> V2 Guest</title>
|
|
7
|
+
<script src="https://cdn.elliemae.io/elliemae/core/ssf/1.0/elli.ssf.host.js"></script>
|
|
8
|
+
<style>
|
|
9
|
+
html,
|
|
10
|
+
body,
|
|
11
|
+
main {
|
|
12
|
+
height: 100%;
|
|
13
|
+
margin: 4px;
|
|
14
|
+
padding: 0;
|
|
15
|
+
}
|
|
16
|
+
iframe {
|
|
17
|
+
width: 100%;
|
|
18
|
+
height: 100%;
|
|
19
|
+
border: none;
|
|
20
|
+
}
|
|
21
|
+
#guest-container {
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<main>
|
|
28
|
+
<h1>Host V1</h1>
|
|
29
|
+
<button id="save-btn" type="button" onclick="saveLoan()">
|
|
30
|
+
Save Loan
|
|
31
|
+
</button>
|
|
32
|
+
<div id="results">
|
|
33
|
+
<p id="pre-save-feedback-result"></p>
|
|
34
|
+
</div>
|
|
35
|
+
<div id="guest-container" style="height: 100%"></div>
|
|
36
|
+
</main>
|
|
37
|
+
<script type="module">
|
|
38
|
+
import { Loan } from './loan-object-v1.js';
|
|
39
|
+
import { getGuestBaseUrl, getHost } from './utils.js';
|
|
40
|
+
|
|
41
|
+
const hostV1 = new elli.ssf.Host('v1');
|
|
42
|
+
const loanObj = new Loan();
|
|
43
|
+
hostV1.publish(loanObj);
|
|
44
|
+
hostV1.renderGuest(
|
|
45
|
+
{},
|
|
46
|
+
new URL('./v1-guest-v2-host.html', window.location.href).href,
|
|
47
|
+
document.getElementById('guest-container'),
|
|
48
|
+
{ allowSameOrigin: true },
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
window.saveLoan = async () => {
|
|
52
|
+
const loanDetails = loanObj.getLoanDetails();
|
|
53
|
+
const results = await elli.ssf.raiseEvent(
|
|
54
|
+
'Loan',
|
|
55
|
+
'onPreSave',
|
|
56
|
+
loanDetails,
|
|
57
|
+
{ timeout: 1000 },
|
|
58
|
+
);
|
|
59
|
+
if (results.some((result) => result === false)) {
|
|
60
|
+
document.getElementById('pre-save-feedback-result').innerText =
|
|
61
|
+
'Pre save failed';
|
|
62
|
+
} else {
|
|
63
|
+
document.getElementById('pre-save-feedback-result').innerText =
|
|
64
|
+
'Pre save succeeded';
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
</script>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Host V2 -> V1 Guest</title><style>body,html,main{height:100%;margin:4px;padding:0}iframe{width:100%;height:100%;border:none}#guest-container{height:100%}</style><script src="https://qa.assets.rd.elliemae.io/pui-diagnostics@3"></script><script defer="defer" src="js/emuiSsfHost.574002466a68fa2d7031.js"></script></head><body><main><h1>Host V2 nesting V1 Guest</h1><button id="save-btn" type="button" onclick="saveLoan()">Save Loan</button><div id="results"><p id="pre-save-feedback-result"></p></div><div id="guest-container"></div></main><script type="module">import{Loan}from"./loan-object.js";import{getGuestBaseUrl,getHost}from"./utils.js";const hostV2=getHost(),loanObj=new Loan;hostV2.addScriptingObject(loanObj);const params=new URLSearchParams(document.location.search),{id:id}=hostV2.loadGuest({id:"guestV1",url:new URL("true"!==params.get("nestV1GuestV2Host")?"./v1-guest.html":"./v1-guest-v2-host.html",window.location.href).href,searchParams:{nestHostV1:!0},title:"Guest V1",targetElement:document.getElementById("guest-container")});window.saveLoan=async()=>{const e=loanObj.getLoanDetails();(await hostV2.dispatchEvent({event:loanObj.onPreSave,eventParams:e,eventOptions:{timeout:1e3}})).some((e=>!1===e))?document.getElementById("pre-save-feedback-result").innerText="Pre save failed":document.getElementById("pre-save-feedback-result").innerText="Pre save succeeded"}</script></body></html>
|
package/dist/types/guest.d.ts
CHANGED
|
@@ -101,7 +101,6 @@ export declare class Guest {
|
|
|
101
101
|
capabilities: Record<string, unknown>;
|
|
102
102
|
/**
|
|
103
103
|
* Create object representing guest application
|
|
104
|
-
*
|
|
105
104
|
* @param {GuestOption} option - options for creating a guest application
|
|
106
105
|
*/
|
|
107
106
|
constructor(option: GuestOption);
|
|
@@ -111,7 +110,6 @@ export declare class Guest {
|
|
|
111
110
|
dispose: () => void;
|
|
112
111
|
/**
|
|
113
112
|
* Get information about the guest application
|
|
114
|
-
*
|
|
115
113
|
* @returns guest properties
|
|
116
114
|
*/
|
|
117
115
|
getInfo: () => {
|
|
@@ -125,14 +123,12 @@ export declare class Guest {
|
|
|
125
123
|
init: () => void;
|
|
126
124
|
/**
|
|
127
125
|
* invokes event callback on the guest application
|
|
128
|
-
*
|
|
129
126
|
* @param {EventObject} event - event object
|
|
130
127
|
* @param {number} timeout - timeout in milliseconds
|
|
131
128
|
*/
|
|
132
129
|
dispatchEvent: (event: EventObject, timeout: number) => Promise<unknown>;
|
|
133
130
|
/**
|
|
134
131
|
* Send a message without any form of response. fire and forget
|
|
135
|
-
*
|
|
136
132
|
* @param {MessageParam} param - message to be sent
|
|
137
133
|
*/
|
|
138
134
|
send: (param: MessageParam) => void;
|
package/dist/types/host.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { ISSFHost, HostOption, LoadGuestParam, LoadGuestsParam } from './ihost.j
|
|
|
6
6
|
import { Guest } from './guest.js';
|
|
7
7
|
/**
|
|
8
8
|
* Host class for embedding guest application and enabling bi-directional communication using scripting objects methods and events
|
|
9
|
-
*
|
|
10
9
|
* @typeParam AppObjects - scripting objects that are published by the host application
|
|
11
10
|
* @typeParam AppEvents - events that are published by the host application
|
|
12
11
|
*/
|
|
@@ -18,21 +17,18 @@ export declare class SSFHost<AppObjects extends ScriptingObjects = ScriptingObje
|
|
|
18
17
|
hostId: string;
|
|
19
18
|
/**
|
|
20
19
|
* Create a new host
|
|
21
|
-
*
|
|
22
20
|
* @param hostId unique identifier for the host
|
|
23
21
|
* @param {HostOption} option - options for the host
|
|
24
22
|
*/
|
|
25
23
|
constructor(hostId: string, option: HostOption);
|
|
26
24
|
/**
|
|
27
25
|
* registers scripting object to the host
|
|
28
|
-
*
|
|
29
26
|
* @param {ValueOf<AppObjects>} so scripting object to be registered
|
|
30
27
|
* @param {AddScriptingObjectParams} params params to add scripting object
|
|
31
28
|
*/
|
|
32
29
|
addScriptingObject: <SO extends ValueOf<AppObjects>>(so: SO, params?: AddScriptingObjectParams) => void;
|
|
33
30
|
/**
|
|
34
31
|
* Clone parent host's scripting object for exposing to grand children
|
|
35
|
-
*
|
|
36
32
|
* @param proxy - reference to the scripting object obtained through getObject method
|
|
37
33
|
* @param guest - reference to the ssf guest
|
|
38
34
|
* @returns cloned version of the scripting object
|
|
@@ -44,20 +40,17 @@ export declare class SSFHost<AppObjects extends ScriptingObjects = ScriptingObje
|
|
|
44
40
|
close: () => void;
|
|
45
41
|
/**
|
|
46
42
|
* dispatch event to guest application(s)
|
|
47
|
-
*
|
|
48
43
|
* @param {EventDetail} details details of the event to be dispatched
|
|
49
44
|
* @returns promise that resolves to an array with result from each guest application
|
|
50
45
|
*/
|
|
51
46
|
dispatchEvent: <EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]["eventParams"], Options extends EventOptions>(details: EventDetail<EventId, Params, Options>) => Promise<any[]>;
|
|
52
47
|
/**
|
|
53
48
|
* get reference to all guest applications
|
|
54
|
-
*
|
|
55
49
|
* @returns list of guest application references
|
|
56
50
|
*/
|
|
57
51
|
getGuests: () => Guest[];
|
|
58
52
|
/**
|
|
59
53
|
* get the scripting object by id
|
|
60
|
-
*
|
|
61
54
|
* @param objectId - id of the scripting object
|
|
62
55
|
* @param params
|
|
63
56
|
* @returns scripting object
|
|
@@ -65,39 +58,33 @@ export declare class SSFHost<AppObjects extends ScriptingObjects = ScriptingObje
|
|
|
65
58
|
getScriptingObject: <Id extends Extract<keyof AppObjects, string>>(objectId: Id) => AppObjects[Id] | null;
|
|
66
59
|
/**
|
|
67
60
|
* loads guest application inside sandboxed iframe
|
|
68
|
-
*
|
|
69
61
|
* @param {LoadGuestParam} param - parameters for loading the guest application
|
|
70
62
|
* @returns reference to the guest object
|
|
71
63
|
*/
|
|
72
64
|
loadGuest: <SearchParams extends Record<string, string | number | boolean>>(param: LoadGuestParam<SearchParams>) => Guest;
|
|
73
65
|
/**
|
|
74
66
|
* loads guest application inside sandboxed iframe with different params
|
|
75
|
-
*
|
|
76
67
|
* @param {LoadGuestsParam} param - parameters for loading the guest application
|
|
77
68
|
*/
|
|
78
69
|
loadGuests: <SearchParams extends Record<string, string | number | boolean>>(param: LoadGuestsParam<SearchParams>) => void;
|
|
79
70
|
/**
|
|
80
71
|
* removes all scripting objects from host
|
|
81
|
-
*
|
|
82
72
|
* @param guestId unique id of the guest application
|
|
83
73
|
*/
|
|
84
74
|
removeAllScriptingObjects: (guestId?: string) => void;
|
|
85
75
|
/**
|
|
86
76
|
* removes scripting object from the host
|
|
87
|
-
*
|
|
88
77
|
* @param objectId unique id of the scripting object
|
|
89
78
|
* @param guestId unique id of the guest application
|
|
90
79
|
*/
|
|
91
80
|
removeScriptingObject: (objectId: Extract<keyof AppObjects, string>, guestId?: string) => void;
|
|
92
81
|
/**
|
|
93
82
|
* set the log level for the host application
|
|
94
|
-
*
|
|
95
83
|
* @param level - log level
|
|
96
84
|
*/
|
|
97
85
|
setLogLevel: (level: LogLevels) => void;
|
|
98
86
|
/**
|
|
99
87
|
* unloads guest application from host
|
|
100
|
-
*
|
|
101
88
|
* @param guestIdOrWindowOrEle unique id of the guest application or window object or dom element of the guest application
|
|
102
89
|
* @throws Error if guestId or Window reference is invalid
|
|
103
90
|
*/
|
package/dist/types/ihost.d.ts
CHANGED
|
@@ -18,7 +18,6 @@ export type HostOption = {
|
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
20
|
* parameters for rendering a guest
|
|
21
|
-
*
|
|
22
21
|
* @typeParam Params - type of the SearchParams object
|
|
23
22
|
*/
|
|
24
23
|
export type LoadGuestParam<SearchParams> = {
|
|
@@ -52,7 +51,6 @@ export type LoadGuestsParam<SearchParams> = Omit<LoadGuestParam<SearchParams>, '
|
|
|
52
51
|
};
|
|
53
52
|
/**
|
|
54
53
|
* interface for the SSF Host
|
|
55
|
-
*
|
|
56
54
|
* @typeParam AppObjects - type of the scripting objects
|
|
57
55
|
* @typeParam AppEvents - type of the events
|
|
58
56
|
*/
|
|
@@ -63,14 +61,12 @@ export interface ISSFHost<AppObjects extends ScriptingObjects = ScriptingObjectT
|
|
|
63
61
|
hostId: string;
|
|
64
62
|
/**
|
|
65
63
|
* adds scripting object to host
|
|
66
|
-
*
|
|
67
64
|
* @param so scripting object
|
|
68
65
|
* @throws Error if the scripting object is invalid
|
|
69
66
|
*/
|
|
70
67
|
addScriptingObject: <SO extends ValueOf<AppObjects>>(so: SO, params?: AddScriptingObjectParams) => void;
|
|
71
68
|
/**
|
|
72
69
|
* Clone parent host's scripting object for exposing to grand children
|
|
73
|
-
*
|
|
74
70
|
* @param proxy - reference to the scripting object obtained through getObject method
|
|
75
71
|
* @param guest - reference to the ssf guest
|
|
76
72
|
* @returns cloned version of the scripting object
|
|
@@ -83,20 +79,17 @@ export interface ISSFHost<AppObjects extends ScriptingObjects = ScriptingObjectT
|
|
|
83
79
|
close: () => void;
|
|
84
80
|
/**
|
|
85
81
|
* dispatch event to guest application(s)
|
|
86
|
-
*
|
|
87
82
|
* @param {EventDetail} details details of the event to be dispatched
|
|
88
83
|
* @returns promise that resolves to an array with result from each guest application
|
|
89
84
|
*/
|
|
90
85
|
dispatchEvent: <EventId extends Extract<keyof AppEvents, string>, Params extends Parameters<AppEvents[EventId]>[0]['eventParams'], Options extends EventOptions>(details: EventDetail<EventId, Params, Options>) => Promise<any[]>;
|
|
91
86
|
/**
|
|
92
87
|
* get reference to all guest applications
|
|
93
|
-
*
|
|
94
88
|
* @returns list of guest application references
|
|
95
89
|
*/
|
|
96
90
|
getGuests: () => Array<Guest>;
|
|
97
91
|
/**
|
|
98
92
|
* get the scripting object by id
|
|
99
|
-
*
|
|
100
93
|
* @param objectId - id of the scripting object
|
|
101
94
|
* @param {GetObjectParams} params - parameters for getting the scripting object
|
|
102
95
|
* @returns scripting object
|
|
@@ -104,14 +97,12 @@ export interface ISSFHost<AppObjects extends ScriptingObjects = ScriptingObjectT
|
|
|
104
97
|
getScriptingObject: <Id extends Extract<keyof AppObjects, string>>(objectId: Id, params?: GetObjectParams) => AppObjects[Id] | null;
|
|
105
98
|
/**
|
|
106
99
|
* loads guest application inside sandboxed iframe
|
|
107
|
-
*
|
|
108
100
|
* @param {LoadGuestParam} param - parameters for rendering the guest application
|
|
109
101
|
* @returns reference to the guest object
|
|
110
102
|
*/
|
|
111
103
|
loadGuest: <SearchParams extends Record<string, string | number | boolean>>(param: LoadGuestParam<SearchParams>) => Guest;
|
|
112
104
|
/**
|
|
113
105
|
* loads guest application inside sandboxed iframe with different params
|
|
114
|
-
*
|
|
115
106
|
* @param {LoadGuestsParam} param - parameters for rendering the guest application
|
|
116
107
|
*/
|
|
117
108
|
loadGuests: <SearchParams extends Record<string, string | number | boolean>>(param: LoadGuestsParam<SearchParams>) => void;
|
|
@@ -122,20 +113,17 @@ export interface ISSFHost<AppObjects extends ScriptingObjects = ScriptingObjectT
|
|
|
122
113
|
removeAllScriptingObjects: () => void;
|
|
123
114
|
/**
|
|
124
115
|
* removes scripting object from host
|
|
125
|
-
*
|
|
126
116
|
* @param objectId id of the scripting object
|
|
127
117
|
* @param guestId unique id of the guest application
|
|
128
118
|
*/
|
|
129
119
|
removeScriptingObject: <Id extends Extract<keyof AppObjects, string>>(objectId: Id, guestId?: string) => void;
|
|
130
120
|
/**
|
|
131
121
|
* set the log level for the host application
|
|
132
|
-
*
|
|
133
122
|
* @param level - log level
|
|
134
123
|
*/
|
|
135
124
|
setLogLevel: (level: LogLevels) => void;
|
|
136
125
|
/**
|
|
137
126
|
* unloads guest application from host
|
|
138
|
-
*
|
|
139
127
|
* @param guestIdOrWindowOrEle unique id of the guest application or window object or dom element of the guest application
|
|
140
128
|
* @throws Error if guestId or Window reference is invalid
|
|
141
129
|
*/
|
package/dist/types/types.d.ts
CHANGED
|
@@ -69,25 +69,21 @@ export type WindowFeatures = {
|
|
|
69
69
|
export type GuestOptions = {
|
|
70
70
|
/**
|
|
71
71
|
* mode of opening the guest application, popup or embed
|
|
72
|
-
*
|
|
73
72
|
* @default OpenMode.Embed
|
|
74
73
|
*/
|
|
75
74
|
openMode?: OpenMode;
|
|
76
75
|
/**
|
|
77
76
|
* flag to disable sandboxing for iframe
|
|
78
|
-
*
|
|
79
77
|
* @default false
|
|
80
78
|
*/
|
|
81
79
|
disableSandbox?: boolean;
|
|
82
80
|
/**
|
|
83
81
|
* sandbox values for iframe
|
|
84
|
-
*
|
|
85
82
|
* @default [IFrameSandboxValues.AllowScripts, IFrameSandboxValues.AllowPopups, IFrameSandboxValues.AllowModals, IFrameSandboxValues.AllowForms, IFrameSandboxValues.AllowDownloads, IFrameSandboxValues.AllowSameOrigin ]
|
|
86
83
|
*/
|
|
87
84
|
sandboxValues?: Array<IFrameSandboxValues>;
|
|
88
85
|
/**
|
|
89
86
|
* resize the iframe to fit the content inside
|
|
90
|
-
*
|
|
91
87
|
* @default true
|
|
92
88
|
*/
|
|
93
89
|
fitToContent?: boolean;
|
|
@@ -97,7 +93,6 @@ export type GuestOptions = {
|
|
|
97
93
|
style?: string;
|
|
98
94
|
/**
|
|
99
95
|
* features for the popup window
|
|
100
|
-
*
|
|
101
96
|
* @default { width: 800, height: 600, top: 100, left: 100 }
|
|
102
97
|
*/
|
|
103
98
|
popupWindowFeatures?: WindowFeatures;
|
package/dist/umd/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(v,b){typeof exports=="object"&&typeof module=="object"?module.exports=b():typeof define=="function"&&define.amd?define([],b):typeof exports=="object"?exports.ice=b():(v.ice=v.ice||{},v.ice.host=b())})(globalThis,()=>(()=>{"use strict";var w={};w.d=(n,e)=>{for(var t in e)w.o(e,t)&&!w.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},w.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e),w.r=n=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})};var v={};w.r(v),w.d(v,{Event:()=>b,Guest:()=>P,IFrameSandboxValues:()=>m,OpenMode:()=>f,SSFHost:()=>J,ScriptingObject:()=>I});class b{scriptingObject;name;objectId;requiresFeedback;id;constructor(e){const{name:t,requiresFeedback:i=!1,so:s}=e;if(!t)throw new Error("Event name is required");if(!s)throw new Error("Scripting object is required");this.scriptingObject=s,this.objectId=s.id,this.name=t,this.id=`${this.objectId}.${this.name}`.toLowerCase(),this.requiresFeedback=i}}const _=n=>n instanceof b,Y=(n,e)=>`${n.toLowerCase()}.${e.toLowerCase()}`,x="function",C=(n,e)=>typeof n===x&&!!e&&!e.startsWith("_");class I{#e;#t="Object";constructor(e,t){this.#e=e,this.#t=t||this.#t}get id(){return this.#e}get objectType(){return this.#t}_toJSON=()=>{const e=[],t=[];return Object.keys(this).forEach(i=>{const s=this[i];_(s)?t.push(i):C(s,i)&&e.push(i)}),{objectId:this.#e,objectType:this.#t,functions:e,events:t}};_dispose=()=>{};dispose=()=>{}}var p=(n=>(n.GuestReady="guest:ready",n.GuestClose="guest:close",n.GuestReadyComplete="guest:readyComplete",n.GuestResize="guest:resize",n.GuestFocus="guest:focus",n.HandShake="handshake",n.HandShakeAck="handshake:ack",n.ObjectInvoke="object:invoke",n.ObjectGet="object:get",n.ObjectEvent="object:event",n.HostConfig="host:config",n))(p||{}),f=(n=>(n.Popup="popup",n.Embed="embed",n))(f||{}),m=(n=>(n.AllowDownloadsWithoutUserActivation="allow-downloads-without-user-activation",n.AllowDownloads="allow-downloads",n.AllowForms="allow-forms",n.AllowModals="allow-modals",n.AllowOrientationLock="allow-orientation-lock",n.AllowPointerLock="allow-pointer-lock",n.AllowPopups="allow-popups",n.AllowPopupsToEscapeSandbox="allow-popups-to-escape-sandbox",n.AllowPresentation="allow-presentation",n.AllowSameOrigin="allow-same-origin",n.AllowScripts="allow-scripts",n.AllowStorageAccessByUserActivation="allow-storage-access-by-user-activation",n.AllowTopNavigation="allow-top-navigation",n.AllowTopNavigationByUserActivation="allow-top-navigation-by-user-activation",n))(m||{});const U=n=>{if(n==="about:blank")return"*";const{origin:e}=new URL(n);return e==="null"||!e?n:e},$=(n,e=[])=>{const t=e||[];return n&&n.forEach?n.forEach(i=>{$(i,t)}):typeof n<"u"&&t.push(n),t},K=n=>typeof n?._toJSON=="function";function k(n){return typeof n=="function"}const L=n=>n?.constructor?.name==="Proxy",Q=n=>n?.id??n;class P{id;title;url;searchParams;domElement;window;openMode;origin;initialized=!1;ready=!1;capabilities;#e;constructor(e){const{guestId:t,domElement:i=null,title:s,url:o,window:r,searchParams:c={},openMode:a=f.Embed,remoting:l}=e;this.id=t,this.title=s,this.url=o,this.origin=U(o),this.searchParams=c,this.domElement=i,this.window=r,this.openMode=a,this.capabilities={},this.#e=l}dispose=()=>{this.#e.removeSender({origin:this.origin,window:this.window}),this.openMode===f.Popup?this.window.close():this.domElement?.remove?.()};getInfo=()=>({guestId:this.id,guestTitle:this.title,guestUrl:this.url});init=()=>{if(this.#e.addSender({origin:this.origin,window:this.window}),this.openMode===f.Popup){const e=setInterval(()=>{this.#e.send({targetWin:this.window,targetOrigin:this.origin,messageType:p.HandShake,messageBody:{}})},1e3);this.#e.listen({messageType:p.HandShakeAck,callback:()=>{clearInterval(e)}})}};dispatchEvent=(e,t)=>this.#e.invoke({targetWin:this.window,targetOrigin:this.origin,messageType:p.ObjectEvent,messageBody:e,responseTimeoutMs:t});send=e=>{this.#e.send({targetWin:this.window,targetOrigin:this.origin,...e})}}const G={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let j;const z=new Uint8Array(16);function N(){if(!j&&(j=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!j))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return j(z)}const u=[];for(let n=0;n<256;++n)u.push((n+256).toString(16).slice(1));function A(n,e=0){return u[n[e+0]]+u[n[e+1]]+u[n[e+2]]+u[n[e+3]]+"-"+u[n[e+4]]+u[n[e+5]]+"-"+u[n[e+6]]+u[n[e+7]]+"-"+u[n[e+8]]+u[n[e+9]]+"-"+u[n[e+10]]+u[n[e+11]]+u[n[e+12]]+u[n[e+13]]+u[n[e+14]]+u[n[e+15]]}function V(n,e=0){const t=A(n,e);if(!validate(t))throw TypeError("Stringified UUID is invalid");return t}const ee=null;function D(n,e,t){if(G.randomUUID&&!e&&!n)return G.randomUUID();n=n||{};const i=n.random||(n.rng||N)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){t=t||0;for(let s=0;s<16;++s)e[t+s]=i[s];return e}return A(i)}const R=D,q="elli:remoting",T="elli:remoting:response",M="elli:remoting:exception",E=({messageType:n,messageBody:e,onewayMsg:t=!1})=>({requestId:t?null:R(),source:q,type:n,body:e}),te=n=>{const{targetWin:e,targetOrigin:t,messageType:i,messageBody:s}=n,o=E({messageType:i,messageBody:s});e.postMessage(o,t)};class B{#e;#t;#i=new Map;#s=new Map;#n=null;#o=new Map;constructor(e,t){if(!e)throw new Error("logger is required");if(!t)throw new Error("correlationId is required");this.#e=t,this.#t=e}#a=()=>{const e=Date.now(),t=[];this.#s.forEach((i,s)=>{const{requestId:o,cancelTime:r}=i;this.#t.debug(`Checking response timeout for requestId: ${o}) @ ${r??""}`),i.cancelTime&&i.cancelTime<e&&(this.#t.debug(`Detected response timeout for requestId: ${o}...`),t.push(s),i.resolve(),this.#t.debug(`Aborted waiting for response to requestid: ${o})`))}),t.forEach(i=>{this.#t.debug(`removing invocations with requestId ${i} from cache since response time has expired`),this.#s.delete(i)}),this.#s.size===0&&(this.#t.debug("stopping response monitor"),this.#r())};#d=()=>{this.#n===null&&(this.#t.debug("Staring response timeout evaluator"),this.#n=window.setInterval(this.#a,200))};#r=()=>{this.#n!==null&&(window.clearInterval(this.#n),this.#n=null,this.#t.debug("Stopped response timeout evaluator"))};#l=e=>{const t=this.#s.get(e);return this.#t.debug(`serving requestId: ${e}`),this.#s.delete(e),t};#h=e=>{const{requestId:t}=e;this.#t.debug(`Response received for invocation requestId: ${t}`);const i=this.#l(t);return i?(i.resolve(e.body),!0):(this.#t.warn(`Received response to stale/invalid request with requestId: ${t}`),!1)};#u=e=>{this.#t.debug(`Exception received for invocation (requestId = ${e.requestId})`);const t=this.#l(e.requestId);return t?(t.reject(new Error(e.body)),!0):(this.#t.warn(`Received exception for stale/invalid request (requestId = ${e.requestId})`),!1)};#g=({sourceWin:e,sourceOrigin:t,message:i})=>{this.#t.debug(`Received message of type "${i.type}"`);const s=this.#i.get(i.type);return s?(s.forEach(o=>{this.#t.debug(`Invoking message handler ${o.name}`),o({sourceWin:e,sourceOrigin:t,requestId:i.requestId,type:i.type,body:i.body})}),!0):!1};#c=e=>{if(this.#t.debug(`Remoting: Received message ${JSON.stringify(e.data)}`),this.#o.size===0||!e.source)return!1;const t=this.#o.get(e.source);return!t||e?.data?.source!==q?!1:(e.data.type===T?this.#h(e.data):e.data.type===M?this.#u(e.data):this.#g({sourceWin:e.source,sourceOrigin:t,message:e.data}),!0)};addSender=e=>{const{origin:t,window:i}=e;if(!t)throw new Error("origin is required");if(!i)throw new Error("window is required");this.#o.set(i,t)};initialize=e=>{e.removeEventListener("message",this.#c),e.addEventListener("message",this.#c),this.#t.debug(`initialized remoting id: ${this.#e}`)};close=()=>{window.removeEventListener("message",this.#c),this.#t.debug(`closed remoting id: ${this.#e}`)};invoke=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o,responseTimeoutMs:r}=e;return new Promise((c,a)=>{const l=E({messageType:s,messageBody:o});this.#s.set(l.requestId,{requestId:l.requestId,resolve:c,reject:a,cancelTime:r?Date.now()+Number.parseInt(r,10):null}),t.postMessage(l,i);const{requestId:g}=l;this.#t.debug(`Posted invocation message of type ${s} requestId: ${g||""}`),r&&(this.#t.debug(`starting response monitor for requestId: ${g||""} for ${r} ms`),this.#d())})};listen=e=>{const{messageType:t,callback:i}=e,s=this.#i.get(t)||[];s.push(i),this.#i.set(t,s)};send=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o}=e,r=E({messageType:s,messageBody:o,onewayMsg:!0});t.postMessage(r,i),this.#t.debug(`Posted one-way message of type "${s}"`)};removeSender=e=>{const{window:t}=e;t&&this.#o.delete(t)};respond=e=>{const{targetWin:t,targetOrigin:i,requestId:s,response:o}=e,r=E({messageType:T,messageBody:o});r.requestId=s,t.postMessage(r,i),this.#t.debug(`Response sent to caller for invocation requestId: ${s}`)};raiseException=e=>{const{targetWin:t,targetOrigin:i,requestId:s,ex:o}=e,r=E({messageType:M,messageBody:o});r.requestId=s,t.postMessage(r,i),this.#t.debug(`Exception sent to caller for invocation. requestId: ${s}`)}}var F=(n=>(n.USER="USER",n.PARTNER="PARTNER",n))(F||{});class W{#e=new Map;#t=new Map;#i=e=>{const{so:t,guestId:i}=e,s=t.id.toLowerCase(),o=this.#t.get(i);if(!o)this.#t.set(i,new Map([[s,e]]));else{if(o.has(s))throw new Error(`Scripting Object ${t.id} already exists for guest ${i}`);o.set(s,e)}};#s=({so:e})=>{e._dispose&&typeof e._dispose=="function"&&e._dispose()};#n=({objectId:e,guestId:t})=>{const i=this.#t.get(t);return i?i.get(e)??null:null};#o=({objectId:e,guestId:t}={})=>{if(t){if(!e){const s=this.#t.get(t);s&&s.forEach(this.#s),this.#t.delete(t);return}const i=this.#t.get(t);if(i){const s=i.get(e);s&&this.#s(s),i.delete(e)}}else e&&this.#t.forEach(i=>{const s=i.get(e);s&&this.#s(s),i.delete(e)})};#a=({so:e,guest:t})=>new Proxy(e,{get(i,s,o){const r=i[s];return r instanceof Function&&s!=="constructor"?function(...c){const a=this;return Object.defineProperty(r,"callContext",{value:t,enumerable:!1,writable:!0}),r.apply(a===o?i:a,c)}:r}});addScriptingObject=(e,t)=>{const{guestId:i}=t||{};if(!e?.id||!e?._toJSON)throw new Error("Object is not derived from ScriptingObject");const s=e.id.toLowerCase();if(s==="module"&&!i)throw new Error("Guest id is required to add Module scripting object");if(i){this.#i({so:e,...t,guestId:i});return}if(this.#e.has(s))throw new Error(`Scripting Object ${e.id} already exists`);this.#e.set(s,{so:e,...t})};getObject=(e,t)=>{const i=e.toLowerCase();let s=null;t?.id&&(s=this.#n({objectId:i,guestId:t.id})),s=s??this.#e.get(i);const{so:o}=s||{};if(!o)return null;if(!t)return o;const r=this.#a({so:o,guest:t});return Object.defineProperty(r,"target",{value:o,enumerable:!1,configurable:!1,writable:!0}),r};removeScriptingObject=(e,t)=>{const i=e.toLowerCase();if(t)this.#o({objectId:i,guestId:t});else{this.#o({objectId:i});const s=this.#e.get(i);s&&this.#s(s),this.#e.delete(i)}};removeAllScriptingObjects=e=>{e?this.#o({guestId:e}):(this.#e.forEach(this.#s),this.#e.clear())}}const H=[m.AllowScripts,m.AllowPopups,m.AllowModals,m.AllowForms,m.AllowDownloads,m.AllowSameOrigin].join(" ");class J{hostId;#e;#t;#i;#s=new Map;#n;#o=null;#a=null;constructor(e,t){if(this.hostId=e,!t?.logger)throw new Error("Logger is required");if(this.#i=t.logger,this.#t=R(),this.#e=new B(this.#i,this.#t),t?.readyStateCallback&&typeof t?.readyStateCallback!="function")throw new Error("readyStateCallback must be a function");this.#o=t?.readyStateCallback||null,this.#n=new W,this.#e.initialize(window),this.#O(),this.#I(),this.#i.debug(`host is initialized. hostId: ${this.hostId}, correlationId: ${this.#t}`)}#d=()=>{for(const e of this.#s.values())e.openMode===f.Popup&&this.unloadGuest(e.id)};#r=e=>{for(const t of this.#s.values())if(t.window===e)return t;return null};#l=e=>{for(const t of this.#s.values())if(t.url===e)return t;return null};#h=e=>typeof e?._toJSON=="function";#u=e=>this.#h(e)?{type:"object",object:e._toJSON()}:{type:"value",value:e};#g=e=>typeof e=="string"?e:e instanceof Error?e.message:"An unexpected error occurred in the host application";#c=e=>{e.ready&&this.#e.send({targetWin:e.window,targetOrigin:e.origin,messageType:p.HostConfig,messageBody:{logLevel:this.#i.getLogLevel(),...e.getInfo()}})};#w=({guest:e,obj:t,functionName:i,functionParams:s})=>{const o=t[i];return k(o)?(this.#i.debug(`Invoking host implementation of ${t.id}.${String(i)}()`),new Promise(r=>{Object.prototype.hasOwnProperty.call(o,"callContext")||Object.defineProperty(o,"callContext",{value:{guest:e},enumerable:!0}),r(o(...s))})):(this.#i.warn(`Attempt to call invalid function on object type ${t.objectType}: ${String(i)}`),Promise.reject(new Error(`Method '${i}' not found in Scripting Object '${t.id}'`)))};#p=({sourceWin:e,sourceOrigin:t,requestId:i})=>{const s=this.#r(e);if(!s){this.#i.warn(`Received ready event for unknown guest. requestId: ${i}`);return}if(!s.initialized){this.#i.warn("Guest must be initialized before it is marked as ready"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Guest must be initialized before it is marked as ready"});return}s.ready||(s.ready=!0,this.#c(s),this.#o?.(s),this.#i.audit({message:"Guest is ready",...s.getInfo()}))};#b=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const o=this.#r(e);if(!o){this.#i.warn(`Received ready event for unknown guest. requestid = ${i}`);return}o.initialized||(o.initialized=!0,o.capabilities=s||{},this.#i.audit({message:"Guest is initialized",...o.getInfo()})),(!s||!s.onReady)&&this.#p({sourceWin:e,sourceOrigin:t,requestId:i,type:"",body:null})};#m=({sourceWin:e})=>{e?.window&&this.unloadGuest(e)};#v=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s;this.#i.debug(`Processing getObject request for object ${o}. requestId = ${i}`);const r=this.#r(e);if(!r)return this.#i.warn("Rejected object request from unknown guest window"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Specified window is not a known guest"}),!1;const c=this.getScriptingObject(o);return c?(this.#e.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#u(c)}),this.#i.audit({message:"Scripting Object returned",requestId:i,scriptingObject:o,...r.getInfo()}),!0):(this.#i.warn(`unknown or unauthorized object ${o} from guest ${r.id}`),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1)};#y=({sourceWin:e,requestId:t,body:i})=>{const s=this.#r(e);if(!s){this.#i.warn(`Received resize event from unknown guest. requestid = ${t}`);return}s.domElement&&(s.domElement.style.height=`${i.height}px`),this.#i.debug(`Guest ${s.id} resized to ${i.width}x${i.height}`)};#E=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s,r=this.#r(e);if(!r)return this.#i.warn("Rejected method invocation request from unknown guest window"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Specified window is not a known guest"}),!1;this.#i.debug(`Function ${o}.${String(s.functionName)}() called from guest "${r.id}" (requestId = ${i})`);const c=this.getScriptingObject(o);return c?(this.#w({guest:r,obj:c,functionName:s.functionName,functionParams:s.functionParams}).then(a=>{this.#e.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#u(a)}),this.#i.audit({message:"Value returned for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...r.getInfo()})}).catch(a=>{this.#e.raiseException({targetWin:e,targetOrigin:r.origin,requestId:i,ex:this.#g(a)}),this.#i.audit({message:"Exception thrown for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...r.getInfo()})}),!0):(this.#i.warn(`Invocation of unknown or unauthorized object ${o} from guest ${r.id}`),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1)};#j=()=>{this.#e.listen({messageType:p.GuestResize,callback:this.#y})};#O=()=>{this.#e.listen({messageType:p.GuestReady,callback:this.#b}),this.#e.listen({messageType:p.GuestReadyComplete,callback:this.#p}),this.#e.listen({messageType:p.GuestClose,callback:this.#m}),this.#e.listen({messageType:p.ObjectGet,callback:this.#v}),this.#e.listen({messageType:p.ObjectInvoke,callback:this.#E}),window.addEventListener("visibilitychange",this.#d)};#S=e=>e?.constructor?.name==="ProxyEvent";#f=e=>{const t=new P({...e,remoting:this.#e});return t.init(),this.#s.set(e.guestId,t),t};#I=()=>{this.#a=setInterval(()=>{const e=[];this.#s.forEach(t=>{t.openMode===f.Popup&&t.window.closed&&e.push(t)}),e.forEach(t=>{this.unloadGuest(t.id)})},1e3)};#$=e=>{const{url:t,title:i,popupWindowFeatures:s={},searchParams:o,guestId:r}=e,{width:c=800,height:a=600,top:l=100,left:g=100}=s;let h=this.#l(t);if(h)h.window.closed||h.send({messageType:p.GuestFocus,messageBody:{}});else{const O=[{key:"width",value:c},{key:"height",value:a},{key:"top",value:l},{key:"left",value:g}].reduce((y,S,X)=>(X>0&&S.value&&(y+=","),S.value?`${y}${S.key}=${S.value}`:y),""),d=window.open(t,i,`popup, ${O}`);if(!d)throw new Error("Failed to open guest application in popup window");d.opener=null,h=this.#f({guestId:r,window:d,title:i,url:t,searchParams:o,openMode:f.Popup})}return h};#k=e=>{const{url:t,title:i,targetElement:s,searchParams:o,guestId:r,options:c={}}=e,a=s.ownerDocument??document,{fitToContent:l=!1,disableSandbox:g=!1,sandboxValues:h=[],style:O=""}=c;if(!i)throw new Error("title is required");l&&this.#j();const d=a.createElement("iframe");d.setAttribute("id",r),d.addEventListener("load",()=>{this.#i.debug(`frame loaded for guest with id '${r}'`)}),d.setAttribute("style",`min-width: 100%; height: 100%; border: 0px; ${O}`),g||d.setAttribute("sandbox",`${H} ${h.join(" ")}`),d.setAttribute("title",i),d.setAttribute("src",t),s.appendChild(d);const y=a.getElementById(r);return this.#f({guestId:r,domElement:y,window:y.contentWindow,title:i,url:t,searchParams:o,openMode:f.Embed})};#P=(e,t)=>{let i="";return Object.keys(t).forEach(s=>{i+=`${(i.length?"&":"")+encodeURIComponent(s)}=${encodeURIComponent(t[s])}`}),e+(i?(e.indexOf("?")>=0?"&":"?")+i:"")};addScriptingObject=(e,t)=>{this.#n.addScriptingObject(e,t)};cloneScriptingObject=(e,t)=>{if(!e)throw new Error("proxy is required");if(!t)throw new Error("guest is required");const i=new I(e.id,e.objectType);let s=[];return Object.keys(e).forEach(o=>{const r=e[o];if(this.#S(r)){const c=new b({name:r.name,requiresFeedback:!1,so:i});Object.defineProperty(i,o,{value:c,enumerable:!0});const a=({eventParams:g,eventOptions:h})=>this.dispatchEvent({event:c,eventParams:g,eventOptions:h}),l=t.subscribe({eventId:r.id,callback:a});s.push(()=>{t.unsubscribe({eventId:r.id,token:l})})}else if(k(r)&&(Object.defineProperty(i,o,{value:async(...c)=>{const a=await r(...c);return L(a)?this.cloneScriptingObject(a,t):a},enumerable:!0}),o==="dispose")){const c=i.dispose;Object.defineProperty(i,o,{value:()=>(i._dispose(),c.apply(i)),enumerable:!0})}}),i._dispose=()=>{s.forEach(o=>{o?.()}),s=[]},i};close=()=>{clearInterval(this.#a),this.#e.close(),window.removeEventListener("visibilitychange",this.#d),this.#i.debug(`host is closed. hostId: ${this.hostId}, correlationId: ${this.#t}`)};dispatchEvent=async e=>{const{event:{id:t,name:i,scriptingObject:s},eventParams:o,eventOptions:r={}}=e,{eventHandler:c=null,timeout:a=null,window:l=null}=r,g={object:s._toJSON(),eventName:i,eventParams:o,eventHandler:c,eventOptions:{allowsFeedback:!1}};a&&!Number.isNaN(a)&&(g.eventOptions={allowsFeedback:!0,timeout:Number(a)});const h=[];return this.#s.forEach(d=>{(!l||l===d.window)&&(a&&d?.capabilities?.eventFeedback?(h.push(d.dispatchEvent(g,a)),this.#i.audit({message:"Event dispatched and awaiting feedback",scriptingEventId:t,...d.getInfo()})):(d.send({messageType:p.ObjectEvent,messageBody:g}),this.#i.audit({message:"Event dispatched",scriptingEventId:t,...d.getInfo()})))}),await Promise.all(h).then(d=>(this.#i.audit({message:"Event feedback received",scriptingEventId:t}),$(d))).catch(d=>{throw this.#i.error({message:"Error processing event",eventId:t,exception:d}),d})};getGuests=()=>{const e=[];return this.#s.forEach(t=>{e.push(t)}),e};getScriptingObject=e=>this.#n.getObject(e);loadGuest=e=>{const{id:t,url:i,targetElement:s,title:o,searchParams:r={},options:c={}}=e;if(!t)throw new Error("id for guest application is required");const{openMode:a=f.Embed,popupWindowFeatures:l={}}=c,g=this.#P(i,r);let h=null;if(a===f.Popup)h=this.#$({guestId:t,url:g,title:o,searchParams:r,popupWindowFeatures:l});else if(a===f.Embed)h=this.#k({guestId:t,url:g,title:o,targetElement:s,searchParams:r,options:c});else throw new Error(`Invalid openMode: ${a}`);return this.#i.audit({message:"Guest loaded",...h.getInfo()}),h};loadGuests=e=>{const{id:t,url:i,targetElement:s,title:o,searchParamsList:r=[],options:c={}}=e;r.forEach((a,l)=>{this.loadGuest({id:`${t}-${l}`,url:i,title:o,targetElement:s,searchParams:a,options:c})},this)};removeAllScriptingObjects=e=>{this.#n.removeAllScriptingObjects(e)};removeScriptingObject=(e,t)=>{this.#n.removeScriptingObject(e,t)};setLogLevel=e=>{this.#i.setLogLevel(e),this.#s.forEach(this.#c),this.#i.debug("Dispatched config events to all guests")};unloadGuest=e=>{let t=typeof e=="string"?this.#s.get(e):null;if(!t&&(t=Array.from(this.#s.values()).find(i=>i.window===e||i.domElement===e),!t))throw new Error("Invalid guestId or guestWindow reference");t.dispose(),this.#s.delete(t.id),this.#i.audit({message:"Guest is removed from host",...t.getInfo()})}}return v})());
|
|
1
|
+
(function(v,b){typeof exports=="object"&&typeof module=="object"?module.exports=b():typeof define=="function"&&define.amd?define([],b):typeof exports=="object"?exports.ice=b():(v.ice=v.ice||{},v.ice.host=b())})(globalThis,()=>(()=>{"use strict";var w={};w.d=(n,e)=>{for(var t in e)w.o(e,t)&&!w.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:e[t]})},w.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e),w.r=n=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})};var v={};w.r(v),w.d(v,{Event:()=>b,Guest:()=>P,IFrameSandboxValues:()=>m,OpenMode:()=>f,SSFHost:()=>J,ScriptingObject:()=>I});class b{scriptingObject;name;objectId;requiresFeedback;id;constructor(e){const{name:t,requiresFeedback:i=!1,so:s}=e;if(!t)throw new Error("Event name is required");if(!s)throw new Error("Scripting object is required");this.scriptingObject=s,this.objectId=s.id,this.name=t,this.id=`${this.objectId}.${this.name}`.toLowerCase(),this.requiresFeedback=i}}const _=n=>n instanceof b,Y=(n,e)=>`${n.toLowerCase()}.${e.toLowerCase()}`,x="function",C=(n,e)=>typeof n===x&&!!e&&!e.startsWith("_");class I{#e;#t="Object";constructor(e,t){this.#e=e,this.#t=t||this.#t}get id(){return this.#e}get objectType(){return this.#t}_toJSON=()=>{const e=[],t=[];return Object.keys(this).forEach(i=>{const s=this[i];_(s)?t.push(i):C(s,i)&&e.push(i)}),{objectId:this.#e,objectType:this.#t,functions:e,events:t}};_dispose=()=>{};dispose=()=>{}}var p=(n=>(n.GuestReady="guest:ready",n.GuestClose="guest:close",n.GuestReadyComplete="guest:readyComplete",n.GuestResize="guest:resize",n.GuestFocus="guest:focus",n.HandShake="handshake",n.HandShakeAck="handshake:ack",n.ObjectInvoke="object:invoke",n.ObjectGet="object:get",n.ObjectEvent="object:event",n.HostConfig="host:config",n))(p||{}),f=(n=>(n.Popup="popup",n.Embed="embed",n))(f||{}),m=(n=>(n.AllowDownloadsWithoutUserActivation="allow-downloads-without-user-activation",n.AllowDownloads="allow-downloads",n.AllowForms="allow-forms",n.AllowModals="allow-modals",n.AllowOrientationLock="allow-orientation-lock",n.AllowPointerLock="allow-pointer-lock",n.AllowPopups="allow-popups",n.AllowPopupsToEscapeSandbox="allow-popups-to-escape-sandbox",n.AllowPresentation="allow-presentation",n.AllowSameOrigin="allow-same-origin",n.AllowScripts="allow-scripts",n.AllowStorageAccessByUserActivation="allow-storage-access-by-user-activation",n.AllowTopNavigation="allow-top-navigation",n.AllowTopNavigationByUserActivation="allow-top-navigation-by-user-activation",n))(m||{});const U=n=>{if(n==="about:blank")return"*";const{origin:e}=new URL(n);return e==="null"||!e?n:e},$=(n,e=[])=>{const t=e||[];return n&&n.forEach?n.forEach(i=>{$(i,t)}):typeof n<"u"&&t.push(n),t},K=n=>typeof n?._toJSON=="function";function k(n){return typeof n=="function"}const L=n=>n?.constructor?.name==="Proxy",Q=n=>n?.id??n;class P{id;title;url;searchParams;domElement;window;openMode;origin;initialized=!1;ready=!1;capabilities;#e;constructor(e){const{guestId:t,domElement:i=null,title:s,url:o,window:r,searchParams:c={},openMode:a=f.Embed,remoting:l}=e;this.id=t,this.title=s,this.url=o,this.origin=U(o),this.searchParams=c,this.domElement=i,this.window=r,this.openMode=a,this.capabilities={},this.#e=l}dispose=()=>{this.#e.removeSender({origin:this.origin,window:this.window}),this.openMode===f.Popup?this.window.close():this.domElement?.remove?.()};getInfo=()=>({guestId:this.id,guestTitle:this.title,guestUrl:this.url});init=()=>{if(this.#e.addSender({origin:this.origin,window:this.window}),this.openMode===f.Popup){const e=setInterval(()=>{this.#e.send({targetWin:this.window,targetOrigin:this.origin,messageType:p.HandShake,messageBody:{}})},1e3);this.#e.listen({messageType:p.HandShakeAck,callback:()=>{clearInterval(e)}})}};dispatchEvent=(e,t)=>this.#e.invoke({targetWin:this.window,targetOrigin:this.origin,messageType:p.ObjectEvent,messageBody:e,responseTimeoutMs:t});send=e=>{this.#e.send({targetWin:this.window,targetOrigin:this.origin,...e})}}const G={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let j;const z=new Uint8Array(16);function D(){if(!j&&(j=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!j))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return j(z)}const h=[];for(let n=0;n<256;++n)h.push((n+256).toString(16).slice(1));function A(n,e=0){return h[n[e+0]]+h[n[e+1]]+h[n[e+2]]+h[n[e+3]]+"-"+h[n[e+4]]+h[n[e+5]]+"-"+h[n[e+6]]+h[n[e+7]]+"-"+h[n[e+8]]+h[n[e+9]]+"-"+h[n[e+10]]+h[n[e+11]]+h[n[e+12]]+h[n[e+13]]+h[n[e+14]]+h[n[e+15]]}function V(n,e=0){const t=A(n,e);if(!validate(t))throw TypeError("Stringified UUID is invalid");return t}const ee=null;function N(n,e,t){if(G.randomUUID&&!e&&!n)return G.randomUUID();n=n||{};const i=n.random||(n.rng||D)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,e){t=t||0;for(let s=0;s<16;++s)e[t+s]=i[s];return e}return A(i)}const R=N,q="elli:remoting",T="elli:remoting:response",M="elli:remoting:exception",E=({messageType:n,messageBody:e,onewayMsg:t=!1})=>({requestId:t?null:R(),source:q,type:n,body:e}),te=n=>{const{targetWin:e,targetOrigin:t,messageType:i,messageBody:s}=n,o=E({messageType:i,messageBody:s});e.postMessage(o,t)};class B{#e;#t;#i=new Map;#s=new Map;#n=null;#o=new Map;constructor(e,t){if(!e)throw new Error("logger is required");if(!t)throw new Error("correlationId is required");this.#e=t,this.#t=e}#a=()=>{const e=Date.now(),t=[];this.#s.forEach((i,s)=>{const{requestId:o,cancelTime:r}=i;this.#t.debug(`Checking response timeout for requestId: ${o}) @ ${r??""}`),i.cancelTime&&i.cancelTime<e&&(this.#t.debug(`Detected response timeout for requestId: ${o}...`),t.push(s),i.resolve(),this.#t.debug(`Aborted waiting for response to requestid: ${o})`))}),t.forEach(i=>{this.#t.debug(`removing invocations with requestId ${i} from cache since response time has expired`),this.#s.delete(i)}),this.#s.size===0&&(this.#t.debug("stopping response monitor"),this.#r())};#d=()=>{this.#n===null&&(this.#t.debug("Staring response timeout evaluator"),this.#n=window.setInterval(this.#a,200))};#r=()=>{this.#n!==null&&(window.clearInterval(this.#n),this.#n=null,this.#t.debug("Stopped response timeout evaluator"))};#l=e=>{const t=this.#s.get(e);return this.#t.debug(`serving requestId: ${e}`),this.#s.delete(e),t};#h=e=>{const{requestId:t}=e;this.#t.debug(`Response received for invocation requestId: ${t}`);const i=this.#l(t);return i?(i.resolve(e.body),!0):(this.#t.warn(`Received response to stale/invalid request with requestId: ${t}`),!1)};#u=e=>{this.#t.debug(`Exception received for invocation (requestId = ${e.requestId})`);const t=this.#l(e.requestId);return t?(t.reject(new Error(e.body)),!0):(this.#t.warn(`Received exception for stale/invalid request (requestId = ${e.requestId})`),!1)};#g=({sourceWin:e,sourceOrigin:t,message:i})=>{this.#t.debug(`Received message of type "${i.type}"`);const s=this.#i.get(i.type);return s?(s.forEach(o=>{this.#t.debug(`Invoking message handler ${o.name}`),o({sourceWin:e,sourceOrigin:t,requestId:i.requestId,type:i.type,body:i.body})}),!0):!1};#c=e=>{if(this.#t.debug(`Remoting: Received message ${JSON.stringify(e.data)}`),this.#o.size===0||!e.source)return!1;const t=this.#o.get(e.source);return!t||e?.data?.source!==q?!1:(e.data.type===T?this.#h(e.data):e.data.type===M?this.#u(e.data):this.#g({sourceWin:e.source,sourceOrigin:t,message:e.data}),!0)};addSender=e=>{const{origin:t,window:i}=e;if(!t)throw new Error("origin is required");if(!i)throw new Error("window is required");this.#o.set(i,t)};initialize=e=>{e.removeEventListener("message",this.#c),e.addEventListener("message",this.#c),this.#t.debug(`initialized remoting id: ${this.#e}`)};close=()=>{window.removeEventListener("message",this.#c),this.#t.debug(`closed remoting id: ${this.#e}`)};invoke=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o,responseTimeoutMs:r}=e;return new Promise((c,a)=>{const l=E({messageType:s,messageBody:o});this.#s.set(l.requestId,{requestId:l.requestId,resolve:c,reject:a,cancelTime:r?Date.now()+Number.parseInt(r,10):null}),t.postMessage(l,i);const{requestId:g}=l;this.#t.debug(`Posted invocation message of type ${s} requestId: ${g||""}`),r&&(this.#t.debug(`starting response monitor for requestId: ${g||""} for ${r} ms`),this.#d())})};listen=e=>{const{messageType:t,callback:i}=e,s=this.#i.get(t)||[];s.push(i),this.#i.set(t,s)};send=e=>{const{targetWin:t,targetOrigin:i,messageType:s,messageBody:o}=e,r=E({messageType:s,messageBody:o,onewayMsg:!0});t.postMessage(r,i),this.#t.debug(`Posted one-way message of type "${s}"`)};removeSender=e=>{const{window:t}=e;t&&this.#o.delete(t)};respond=e=>{const{targetWin:t,targetOrigin:i,requestId:s,response:o}=e,r=E({messageType:T,messageBody:o});r.requestId=s,t.postMessage(r,i),this.#t.debug(`Response sent to caller for invocation requestId: ${s}`)};raiseException=e=>{const{targetWin:t,targetOrigin:i,requestId:s,ex:o}=e,r=E({messageType:M,messageBody:o});r.requestId=s,t.postMessage(r,i),this.#t.debug(`Exception sent to caller for invocation. requestId: ${s}`)}}var F=(n=>(n.USER="USER",n.PARTNER="PARTNER",n))(F||{});class W{#e=new Map;#t=new Map;#i=e=>{const{so:t,guestId:i}=e,s=t.id.toLowerCase(),o=this.#t.get(i);if(!o)this.#t.set(i,new Map([[s,e]]));else{if(o.has(s))throw new Error(`Scripting Object ${t.id} already exists for guest ${i}`);o.set(s,e)}};#s=({so:e})=>{e._dispose&&typeof e._dispose=="function"&&e._dispose()};#n=({objectId:e,guestId:t})=>{const i=this.#t.get(t);return i?i.get(e)??null:null};#o=({objectId:e,guestId:t}={})=>{if(t){if(!e){const s=this.#t.get(t);s&&s.forEach(this.#s),this.#t.delete(t);return}const i=this.#t.get(t);if(i){const s=i.get(e);s&&this.#s(s),i.delete(e)}}else e&&this.#t.forEach(i=>{const s=i.get(e);s&&this.#s(s),i.delete(e)})};#a=({so:e,guest:t})=>new Proxy(e,{get(i,s,o){const r=i[s];return r instanceof Function&&s!=="constructor"?function(...c){const a=this;return Object.defineProperty(r,"callContext",{value:t,enumerable:!1,writable:!0}),r.apply(a===o?i:a,c)}:r}});addScriptingObject=(e,t)=>{const{guestId:i}=t||{};if(!e?.id||!e?._toJSON)throw new Error("Object is not derived from ScriptingObject");const s=e.id.toLowerCase();if(s==="module"&&!i)throw new Error("Guest id is required to add Module scripting object");if(i){this.#i({so:e,...t,guestId:i});return}if(this.#e.has(s))throw new Error(`Scripting Object ${e.id} already exists`);this.#e.set(s,{so:e,...t})};getObject=(e,t)=>{const i=e.toLowerCase();let s=null;t?.id&&(s=this.#n({objectId:i,guestId:t.id})),s=s??this.#e.get(i);const{so:o}=s||{};if(!o)return null;if(!t)return o;const r=this.#a({so:o,guest:t});return Object.defineProperty(r,"target",{value:o,enumerable:!1,configurable:!1,writable:!0}),r};removeScriptingObject=(e,t)=>{const i=e.toLowerCase();if(t)this.#o({objectId:i,guestId:t});else{this.#o({objectId:i});const s=this.#e.get(i);s&&this.#s(s),this.#e.delete(i)}};removeAllScriptingObjects=e=>{e?this.#o({guestId:e}):(this.#e.forEach(this.#s),this.#e.clear())}}const H=[m.AllowScripts,m.AllowPopups,m.AllowModals,m.AllowForms,m.AllowDownloads,m.AllowSameOrigin].join(" ");class J{hostId;#e;#t;#i;#s=new Map;#n;#o=null;#a=null;constructor(e,t){if(this.hostId=e,!t?.logger)throw new Error("Logger is required");if(this.#i=t.logger,this.#t=R(),this.#e=new B(this.#i,this.#t),t?.readyStateCallback&&typeof t?.readyStateCallback!="function")throw new Error("readyStateCallback must be a function");this.#o=t?.readyStateCallback||null,this.#n=new W,this.#e.initialize(window),this.#O(),this.#I(),this.#i.debug(`host is initialized. hostId: ${this.hostId}, correlationId: ${this.#t}`)}#d=()=>{for(const e of this.#s.values())e.openMode===f.Popup&&this.unloadGuest(e.id)};#r=e=>{for(const t of this.#s.values())if(t.window===e)return t;return null};#l=e=>{for(const t of this.#s.values())if(t.url===e)return t;return null};#h=e=>typeof e?._toJSON=="function";#u=e=>this.#h(e)?{type:"object",object:e._toJSON()}:{type:"value",value:e};#g=e=>typeof e=="string"?e:e instanceof Error?e.message:"An unexpected error occurred in the host application";#c=e=>{e.ready&&this.#e.send({targetWin:e.window,targetOrigin:e.origin,messageType:p.HostConfig,messageBody:{logLevel:this.#i.getLogLevel(),...e.getInfo()}})};#w=({guest:e,obj:t,functionName:i,functionParams:s})=>{const o=t[i];return k(o)?(this.#i.debug(`Invoking host implementation of ${t.id}.${String(i)}()`),new Promise(r=>{Object.prototype.hasOwnProperty.call(o,"callContext")||Object.defineProperty(o,"callContext",{value:{guest:e},enumerable:!0}),r(o(...s))})):(this.#i.warn(`Attempt to call invalid function on object type ${t.objectType}: ${String(i)}`),Promise.reject(new Error(`Method '${i}' not found in Scripting Object '${t.id}'`)))};#p=({sourceWin:e,sourceOrigin:t,requestId:i})=>{const s=this.#r(e);if(!s){this.#i.warn(`Received ready event for unknown guest. requestId: ${i}`);return}if(!s.initialized){this.#i.warn("Guest must be initialized before it is marked as ready"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Guest must be initialized before it is marked as ready"});return}s.ready||(s.ready=!0,this.#c(s),this.#o?.(s),this.#i.audit({message:"Guest is ready",...s.getInfo()}))};#b=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const o=this.#r(e);if(!o){this.#i.warn(`Received ready event for unknown guest. requestid = ${i}`);return}o.initialized||(o.initialized=!0,o.capabilities=s||{},this.#i.audit({message:"Guest is initialized",...o.getInfo()})),(!s||!s.onReady)&&this.#p({sourceWin:e,sourceOrigin:t,requestId:i,type:"",body:null})};#m=({sourceWin:e})=>{e?.window&&this.unloadGuest(e)};#v=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s;this.#i.debug(`Processing getObject request for object ${o}. requestId = ${i}`);const r=this.#r(e);if(!r)return this.#i.warn("Rejected object request from unknown guest window"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Specified window is not a known guest"}),!1;const c=this.getScriptingObject(o);return c?(this.#e.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#u(c)}),this.#i.audit({message:"Scripting Object returned",requestId:i,scriptingObject:o,...r.getInfo()}),!0):(this.#i.warn(`unknown or unauthorized object ${o} from guest ${r.id}`),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1)};#y=({sourceWin:e,requestId:t,body:i})=>{const s=this.#r(e);if(!s){this.#i.warn(`Received resize event from unknown guest. requestid = ${t}`);return}s.domElement&&(s.domElement.style.height=`${i.height}px`),this.#i.debug(`Guest ${s.id} resized to ${i.width}x${i.height}`)};#E=({sourceWin:e,sourceOrigin:t,requestId:i,body:s})=>{const{objectId:o}=s,r=this.#r(e);if(!r)return this.#i.warn("Rejected method invocation request from unknown guest window"),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:"Specified window is not a known guest"}),!1;this.#i.debug(`Function ${o}.${String(s.functionName)}() called from guest "${r.id}" (requestId = ${i})`);const c=this.getScriptingObject(o);return c?(this.#w({guest:r,obj:c,functionName:s.functionName,functionParams:s.functionParams}).then(a=>{this.#e.respond({targetWin:e,targetOrigin:t,requestId:i,response:this.#u(a)}),this.#i.audit({message:"Value returned for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...r.getInfo()})}).catch(a=>{this.#e.raiseException({targetWin:e,targetOrigin:r.origin,requestId:i,ex:this.#g(a)}),this.#i.audit({message:"Exception thrown for Scripting Object method call",requestId:i,scriptingObject:o,scriptingMethod:s.functionName,...r.getInfo()})}),!0):(this.#i.warn(`Invocation of unknown or unauthorized object ${o} from guest ${r.id}`),this.#e.raiseException({targetWin:e,targetOrigin:t,requestId:i,ex:`The requested object (${o}) is not available`}),!1)};#j=()=>{this.#e.listen({messageType:p.GuestResize,callback:this.#y})};#O=()=>{this.#e.listen({messageType:p.GuestReady,callback:this.#b}),this.#e.listen({messageType:p.GuestReadyComplete,callback:this.#p}),this.#e.listen({messageType:p.GuestClose,callback:this.#m}),this.#e.listen({messageType:p.ObjectGet,callback:this.#v}),this.#e.listen({messageType:p.ObjectInvoke,callback:this.#E}),window.addEventListener("visibilitychange",this.#d)};#S=e=>e?.constructor?.name==="ProxyEvent"||typeof e?.subscribe=="function";#f=e=>{const t=new P({...e,remoting:this.#e});return t.init(),this.#s.set(e.guestId,t),t};#I=()=>{this.#a=setInterval(()=>{const e=[];this.#s.forEach(t=>{t.openMode===f.Popup&&t.window.closed&&e.push(t)}),e.forEach(t=>{this.unloadGuest(t.id)})},1e3)};#$=e=>{const{url:t,title:i,popupWindowFeatures:s={},searchParams:o,guestId:r}=e,{width:c=800,height:a=600,top:l=100,left:g=100}=s;let u=this.#l(t);if(u)u.window.closed||u.send({messageType:p.GuestFocus,messageBody:{}});else{const O=[{key:"width",value:c},{key:"height",value:a},{key:"top",value:l},{key:"left",value:g}].reduce((y,S,X)=>(X>0&&S.value&&(y+=","),S.value?`${y}${S.key}=${S.value}`:y),""),d=window.open(t,i,`popup, ${O}`);if(!d)throw new Error("Failed to open guest application in popup window");d.opener=null,u=this.#f({guestId:r,window:d,title:i,url:t,searchParams:o,openMode:f.Popup})}return u};#k=e=>{const{url:t,title:i,targetElement:s,searchParams:o,guestId:r,options:c={}}=e,a=s.ownerDocument??document,{fitToContent:l=!1,disableSandbox:g=!1,sandboxValues:u=[],style:O=""}=c;if(!i)throw new Error("title is required");l&&this.#j();const d=a.createElement("iframe");d.setAttribute("id",r),d.addEventListener("load",()=>{this.#i.debug(`frame loaded for guest with id '${r}'`)}),d.setAttribute("style",`min-width: 100%; height: 100%; border: 0px; ${O}`),g||d.setAttribute("sandbox",`${H} ${u.join(" ")}`),d.setAttribute("title",i),d.setAttribute("src",t),s.appendChild(d);const y=a.getElementById(r);return this.#f({guestId:r,domElement:y,window:y.contentWindow,title:i,url:t,searchParams:o,openMode:f.Embed})};#P=(e,t)=>{let i="";return Object.keys(t).forEach(s=>{i+=`${(i.length?"&":"")+encodeURIComponent(s)}=${encodeURIComponent(t[s])}`}),e+(i?(e.indexOf("?")>=0?"&":"?")+i:"")};addScriptingObject=(e,t)=>{this.#n.addScriptingObject(e,t)};cloneScriptingObject=(e,t)=>{if(!e)throw new Error("proxy is required");if(!t)throw new Error("guest is required");const i=new I(e.id,e.objectType);let s=[];return Object.keys(e).forEach(o=>{const r=e[o];if(this.#S(r)){let c;if(r?.subscribe!=="function"?c=new b({name:r.name||o,requiresFeedback:!1,so:i}):c=new automation.Event,Object.defineProperty(i,o,{value:c,enumerable:!0}),t.subscribe){const a=({eventParams:g,eventOptions:u})=>this.dispatchEvent({event:c,eventParams:g,eventOptions:u}),l=t.subscribe({eventId:r.id,callback:a});s.push(()=>{t.unsubscribe({eventId:r.id,token:l})})}else{const a=r.subscribe?.((l,g,u)=>this.dispatchEvent({event:c,eventParams:g,eventOptions:u}));s.push(()=>{r.unsubscribe?.(a)})}}else if(k(r)&&(Object.defineProperty(i,o,{value:async(...c)=>{const a=await r(...c);return L(a)?this.cloneScriptingObject(a,t):a},enumerable:!0}),o==="dispose")){const c=i.dispose;Object.defineProperty(i,o,{value:()=>(i._dispose(),c.apply(i)),enumerable:!0})}}),i._dispose=()=>{s.forEach(o=>{o?.()}),s=[]},i};close=()=>{clearInterval(this.#a),this.#e.close(),window.removeEventListener("visibilitychange",this.#d),this.#i.debug(`host is closed. hostId: ${this.hostId}, correlationId: ${this.#t}`)};dispatchEvent=async e=>{const{event:{id:t,name:i,scriptingObject:s},eventParams:o,eventOptions:r={}}=e,{eventHandler:c=null,timeout:a=null,window:l=null}=r,g={object:s._toJSON(),eventName:i,eventParams:o,eventHandler:c,eventOptions:{allowsFeedback:!1}};a&&!Number.isNaN(a)&&(g.eventOptions={allowsFeedback:!0,timeout:Number(a)});const u=[];return this.#s.forEach(d=>{(!l||l===d.window)&&(a&&d?.capabilities?.eventFeedback?(u.push(d.dispatchEvent(g,a)),this.#i.audit({message:"Event dispatched and awaiting feedback",scriptingEventId:t,...d.getInfo()})):(d.send({messageType:p.ObjectEvent,messageBody:g}),this.#i.audit({message:"Event dispatched",scriptingEventId:t,...d.getInfo()})))}),await Promise.all(u).then(d=>(this.#i.audit({message:"Event feedback received",scriptingEventId:t}),$(d))).catch(d=>{throw this.#i.error({message:"Error processing event",eventId:t,exception:d}),d})};getGuests=()=>{const e=[];return this.#s.forEach(t=>{e.push(t)}),e};getScriptingObject=e=>this.#n.getObject(e);loadGuest=e=>{const{id:t,url:i,targetElement:s,title:o,searchParams:r={},options:c={}}=e;if(!t)throw new Error("id for guest application is required");const{openMode:a=f.Embed,popupWindowFeatures:l={}}=c,g=this.#P(i,r);let u=null;if(a===f.Popup)u=this.#$({guestId:t,url:g,title:o,searchParams:r,popupWindowFeatures:l});else if(a===f.Embed)u=this.#k({guestId:t,url:g,title:o,targetElement:s,searchParams:r,options:c});else throw new Error(`Invalid openMode: ${a}`);return this.#i.audit({message:"Guest loaded",...u.getInfo()}),u};loadGuests=e=>{const{id:t,url:i,targetElement:s,title:o,searchParamsList:r=[],options:c={}}=e;r.forEach((a,l)=>{this.loadGuest({id:`${t}-${l}`,url:i,title:o,targetElement:s,searchParams:a,options:c})},this)};removeAllScriptingObjects=e=>{this.#n.removeAllScriptingObjects(e)};removeScriptingObject=(e,t)=>{this.#n.removeScriptingObject(e,t)};setLogLevel=e=>{this.#i.setLogLevel(e),this.#s.forEach(this.#c),this.#i.debug("Dispatched config events to all guests")};unloadGuest=e=>{let t=typeof e=="string"?this.#s.get(e):null;if(!t&&(t=Array.from(this.#s.values()).find(i=>i.window===e||i.domElement===e),!t))throw new Error("Invalid guestId or guestWindow reference");t.dispose(),this.#s.delete(t.id),this.#i.audit({message:"Guest is removed from host",...t.getInfo()})}}return v})());
|
|
2
2
|
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/umd/index.js.br
CHANGED
|
Binary file
|
package/dist/umd/index.js.gz
CHANGED
|
Binary file
|