Skip to content

Commit db8648c

Browse files
authored
Merge pull request #42 from wippyai/feature/v4-facade-1.0.6
v4 facade 1.0.15
2 parents 64a98a5 + b330def commit db8648c

File tree

4 files changed

+91
-75
lines changed

4 files changed

+91
-75
lines changed

src/facade/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ These fields are NOT configurable via requirements — they are computed at runt
3535

3636
| Requirement | Default | Description |
3737
|---|---|---|
38-
| `fe_facade_url` | `https://web-host.wippy.ai/webcomponents-1.0.12` | CDN base URL for the Web Host frontend bundle |
38+
| `fe_facade_url` | `https://web-host.wippy.ai/webcomponents-1.0.15` | CDN base URL for the Web Host frontend bundle |
3939
| `fe_entry_path` | `/iframe.html` | Iframe HTML entry point path (appended to `fe_facade_url`) |
4040

4141
### App Identity
@@ -126,9 +126,9 @@ Only override what differs from defaults.
126126

127127
```json
128128
{
129-
"facade_url": "https://web-host.wippy.ai/webcomponents-1.0.12",
129+
"facade_url": "https://web-host.wippy.ai/webcomponents-1.0.15",
130130
"iframe_origin": "https://web-host.wippy.ai",
131-
"iframe_url": "https://web-host.wippy.ai/webcomponents-1.0.12/iframe.html?waitForCustomConfig",
131+
"iframe_url": "https://web-host.wippy.ai/webcomponents-1.0.15/iframe.html?waitForCustomConfig",
132132
"api_url": "http://localhost:8085",
133133
"ws_url": "ws://localhost:8085",
134134
"feature": {

src/facade/_index.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ entries:
3333
targets:
3434
- entry: wippy.facade:fe_facade_url
3535
path: .default
36-
default: https://web-host.wippy.ai/webcomponents-1.0.12
36+
default: https://web-host.wippy.ai/webcomponents-1.0.15
3737

3838
- name: fe_entry_path
3939
kind: ns.requirement

src/facade/config_handler_test.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ local function define_tests()
9393
end)
9494

9595
test.it("extracts iframe origin from facade URL", function()
96-
local facade_url = "https://web-host.wippy.ai/webcomponents-1.0.12"
96+
local facade_url = "https://web-host.wippy.ai/webcomponents-1.0.15"
9797
local origin = facade_url:match("^(https?://[^/]+)")
9898

9999
test.eq(origin, "https://web-host.wippy.ai")

src/facade/public/index.html

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -41,87 +41,103 @@
4141
<div class="facade-loader__text">Loading...</div>
4242
</div>
4343
</div>
44-
<script type="module">
45-
const STORAGE_KEY = '@wippy_token_info';
46-
const appEl = document.getElementById('app');
44+
<script>
45+
(async function () {
46+
var STORAGE_KEY = '@wippy_token_info';
47+
var appEl = document.getElementById('app');
4748

48-
function showError(title, detail) {
49-
appEl.innerHTML =
50-
'<div class="facade-error">' +
51-
'<div class="facade-error__title">' + title + '</div>' +
52-
(detail ? '<div class="facade-error__detail">' + detail + '</div>' : '') +
53-
'<button class="facade-error__retry" onclick="location.reload()">Retry</button>' +
54-
'</div>';
55-
}
56-
57-
try {
58-
const res = await fetch('/api/public/facade/config');
59-
if (!res.ok) {
60-
showError('Failed to load configuration', 'Server returned ' + res.status + '. Check that the backend is running.');
61-
throw new Error('config fetch failed: ' + res.status);
49+
function showError(title, detail) {
50+
appEl.innerHTML =
51+
'<div class="facade-error">' +
52+
'<div class="facade-error__title">' + title + '</div>' +
53+
(detail ? '<div class="facade-error__detail">' + detail + '</div>' : '') +
54+
'<button class="facade-error__retry" onclick="location.reload()">Retry</button>' +
55+
'</div>';
6256
}
63-
const cfg = await res.json();
6457

65-
const stored = localStorage.getItem(STORAGE_KEY);
66-
if (!stored) { window.location.href = cfg.login_path || '/login.html'; throw new Error('no token'); }
58+
try {
59+
var res = await fetch('/api/public/facade/config');
60+
if (!res.ok) {
61+
showError('Failed to load configuration', 'Server returned ' + res.status + '. Check that the backend is running.');
62+
throw new Error('config fetch failed: ' + res.status);
63+
}
64+
var cfg = await res.json();
6765

68-
let token;
69-
try { token = JSON.parse(stored).token; }
70-
catch { window.location.href = cfg.login_path || '/login.html'; throw new Error('bad token'); }
66+
var stored = localStorage.getItem(STORAGE_KEY);
67+
if (!stored) { window.location.href = cfg.login_path || '/login.html'; throw new Error('no token'); }
7168

72-
const apiUrl = cfg.api_url || window.location.origin;
73-
const wsProto = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
74-
const wsUrl = cfg.ws_url || (wsProto + '//' + window.location.host);
69+
var token;
70+
try { token = JSON.parse(stored).token; }
71+
catch (e) { window.location.href = cfg.login_path || '/login.html'; throw new Error('bad token'); }
7572

76-
let mod;
77-
try {
78-
mod = await import(cfg.facade_url + '/module.js');
79-
} catch (importErr) {
80-
showError('Failed to load frontend bundle', 'Could not load ' + cfg.facade_url + '/module.js — ' + importErr.message);
81-
throw importErr;
82-
}
73+
var apiUrl = cfg.api_url || window.location.origin;
74+
var wsProto = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
75+
var wsUrl = cfg.ws_url || (wsProto + '//' + window.location.host);
8376

84-
if (typeof window.initWippyApp !== 'function') {
85-
showError('Frontend bundle error', 'initWippyApp not found after loading module. The bundle may be incompatible.');
86-
throw new Error('initWippyApp not found');
87-
}
77+
// Inject import map BEFORE any module loading
78+
try {
79+
var mapRes = await fetch(cfg.facade_url + '/import-map.json');
80+
if (mapRes.ok) {
81+
var mapData = await mapRes.json();
82+
var mapScript = document.createElement('script');
83+
mapScript.type = 'importmap';
84+
mapScript.textContent = JSON.stringify(mapData);
85+
document.head.appendChild(mapScript);
86+
}
87+
} catch (e) {
88+
console.warn('Failed to load import map:', e);
89+
}
90+
91+
// Now safe to load modules — import map is already in the DOM
92+
try {
93+
await import(cfg.facade_url + '/module.js');
94+
} catch (importErr) {
95+
showError('Failed to load frontend bundle', 'Could not load ' + cfg.facade_url + '/module.js — ' + importErr.message);
96+
throw importErr;
97+
}
8898

89-
const events = window.initWippyApp({
90-
auth: { token, expiresAt: new Date(Date.now() + 86400000).toISOString() },
91-
feature: {
92-
session: { type: cfg.feature.session_type },
93-
history: cfg.feature.history_mode,
94-
env: { APP_API_URL: apiUrl, APP_WEBSOCKET_URL: wsUrl },
95-
routePrefix: apiUrl,
96-
showAdmin: cfg.feature.show_admin,
97-
allowSelectModel: cfg.feature.allow_select_model,
98-
startNavOpen: cfg.feature.start_nav_open,
99-
hideNavBar: cfg.feature.hide_nav_bar,
100-
disableRightPanel: cfg.feature.disable_right_panel,
101-
},
102-
customization: {
103-
customCSS: cfg.customization.custom_css || '',
104-
cssVariables: cfg.customization.css_variables || {},
105-
i18n: cfg.customization.i18n || {},
106-
icons: cfg.customization.icons || {},
107-
},
108-
}, '#app');
99+
if (typeof window.initWippyApp !== 'function') {
100+
showError('Frontend bundle error', 'initWippyApp not found after loading module. The bundle may be incompatible.');
101+
throw new Error('initWippyApp not found');
102+
}
109103

110-
const loginPath = cfg.login_path || '/login.html';
104+
var events = window.initWippyApp({
105+
auth: { token: token, expiresAt: new Date(Date.now() + 86400000).toISOString() },
106+
feature: {
107+
session: { type: cfg.feature.session_type },
108+
history: cfg.feature.history_mode,
109+
env: { APP_API_URL: apiUrl, APP_WEBSOCKET_URL: wsUrl },
110+
routePrefix: apiUrl,
111+
showAdmin: cfg.feature.show_admin,
112+
allowSelectModel: cfg.feature.allow_select_model,
113+
startNavOpen: cfg.feature.start_nav_open,
114+
hideNavBar: cfg.feature.hide_nav_bar,
115+
disableRightPanel: cfg.feature.disable_right_panel,
116+
},
117+
customization: {
118+
customCSS: cfg.customization.custom_css || '',
119+
cssVariables: cfg.customization.css_variables || {},
120+
i18n: cfg.customization.i18n || {},
121+
icons: cfg.customization.icons || {},
122+
},
123+
}, '#app');
111124

112-
events.on('authExpired', () => {
113-
localStorage.removeItem(STORAGE_KEY);
114-
window.location.href = loginPath;
115-
});
125+
var loginPath = cfg.login_path || '/login.html';
116126

117-
events.on('error', (err) => {
118-
console.error('Wippy critical error:', err);
119-
localStorage.removeItem(STORAGE_KEY);
120-
window.location.href = loginPath;
121-
});
122-
} catch (err) {
123-
console.error('Facade initialization failed:', err);
124-
}
127+
events.on('authExpired', function () {
128+
localStorage.removeItem(STORAGE_KEY);
129+
window.location.href = loginPath;
130+
});
131+
132+
events.on('error', function (err) {
133+
console.error('Wippy critical error:', err);
134+
localStorage.removeItem(STORAGE_KEY);
135+
window.location.href = loginPath;
136+
});
137+
} catch (err) {
138+
console.error('Facade initialization failed:', err);
139+
}
140+
})();
125141
</script>
126142
</body>
127143
</html>

0 commit comments

Comments
 (0)