@kosmas10/app-loader
v0.0.3
Published
Universal app loader for AI Chat Extensions. Stage 2 of the two-stage bootstrap architecture that loads apps from CDN.
Maintainers
Readme
@kosmas10/app-loader
Universal app loader for AI Chat Extensions. This is Stage 2 of the two-stage bootstrap architecture.
Architecture
The two-stage loader architecture ensures that bootstrap files distributed to clients never need to be updated:
┌─────────────────────────────────────────────────────────────────┐
│ Stage 1: Bootstrap HTML (distributed to clients, PERMANENT) │
│ - Ultra-minimal (~20 lines) │
│ - Sets window.__APP__ = 'app-name' │
│ - Loads Stage 2 from CDN with cache-busting │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 2: App Loader (this package, updatable via npm) │
│ - Derives package and file path from app name │
│ - Convention: @kosmas10/{app}/dist/{app}.html │
│ - Fetches app HTML from CDN │
│ - Replaces document with fetched app │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Stage 3: App (any npm package following the convention) │
│ - The actual application code │
│ - Loaded and executed by Stage 2 │
└─────────────────────────────────────────────────────────────────┘Benefits
- Permanent bootstrap files: Stage 1 is so simple it never needs updates
- Minimal config: Just set
window.__APP__to the app name - Centralized control: If an app moves, update the loader - not all bootstrap files
- Easy to add apps: Just create a bootstrap file with the app name
Configuration
The bootstrap only needs to set one variable:
window.__APP__ = 'my-app';The loader derives from the app name:
- Package:
@kosmas10/{app} - File:
dist/{app}.html - Title: Converts kebab-case to Title Case
Stage 1 Bootstrap Template
Distribute this to clients (only the app name changes):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script>
/**
* App Loader Bootstrap v1
* Copyright (c) 2025 Nova Science Ventures LLC
* DO NOT MODIFY - This file should never need updates.
*/
(async function() {
window.__APP__ = 'my-app';
var CDN = 'https://cdn.jsdelivr.net/npm/@kosmas10/app-loader';
var err = function() {
document.body.innerHTML =
'<div style="max-width:500px;margin:40px auto;padding:24px;font-family:system-ui,sans-serif;border:2px solid #dc3545;border-radius:12px">' +
'<h1 style="color:#dc3545;margin:0 0 12px">⚠️ Unable to Load</h1>' +
'<p style="margin:0 0 16px;color:#666">The application loader could not be reached.</p>' +
'<ul style="margin:0;padding-left:20px;color:#444;line-height:1.8">' +
'<li>Check your internet connection</li>' +
'<li>Refresh the page</li>' +
'<li>Try a different browser or network</li>' +
'</ul>' +
'<p style="margin:16px 0 0;padding-top:12px;border-top:1px solid #eee;font-size:0.9em;color:#888">' +
'If this persists: <a href="https://github.com/kosmas10/ai-chat-extensions/issues" style="color:#0066cc">Report issue</a>' +
'</p></div>';
};
try {
var r = await fetch(CDN + '@latest/package.json?t=' + Date.now());
if (!r.ok) throw new Error();
var pkg = await r.json();
var s = document.createElement('script');
s.src = CDN + '@' + pkg.version + '/dist/app-loader.js';
s.onerror = err;
document.body.appendChild(s);
} catch(e) { err(); }
})();
</script>
</body>
</html>CDN Caching Strategy
jsDelivr aggressively caches @latest URLs (up to 24 hours). We use a two-step approach:
- Fetch
package.jsonwith cache-busting:?t=Date.now()bypasses cache - Load script with version-specific URL:
@x.y.zin the URL is cached efficiently
This ensures updates are available immediately while still benefiting from CDN caching.
Adding New Apps
To add a new app:
- Build and publish your app to npm as
@kosmas10/{app-name} - Ensure the bundled HTML is at
dist/{app-name}.html - Create a bootstrap file:
window.__APP__ = 'app-name';
No changes to this app-loader package are needed.
Future Flexibility
If an app ever needs to be hosted at a different location, this loader can be updated to handle special cases. The bootstrap files distributed to clients never need to change - they just pass the app name.
Development
# Build
npm run build
# Publish
npm publishLicense
MIT License - Copyright (c) 2025 Nova Science Ventures LLC
