thebird 1.2.60 → 1.2.61
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/docs/index.html +30 -7
- package/docs/terminal.js +1 -2
- package/package.json +1 -1
package/docs/index.html
CHANGED
|
@@ -33,22 +33,45 @@ bird-chat { display: flex; flex-direction: column; height: 100%; }
|
|
|
33
33
|
</div>
|
|
34
34
|
<div id="pane-preview" class="flex flex-col flex-1 overflow-hidden hidden">
|
|
35
35
|
<div class="flex gap-2 px-3 py-1 bg-base-200 border-b border-base-300 shrink-0">
|
|
36
|
-
<button class="btn btn-xs btn-ghost" onclick="
|
|
37
|
-
<span class="text-xs text-base-content/50 self-center">preview/</span>
|
|
36
|
+
<button class="btn btn-xs btn-ghost" onclick="refreshPreview()">↺ Reload</button>
|
|
38
37
|
</div>
|
|
39
|
-
<iframe id="preview-frame" class="w-full flex-1 border-0"
|
|
38
|
+
<iframe id="preview-frame" class="w-full flex-1 border-0" sandbox="allow-scripts allow-same-origin allow-forms"></iframe>
|
|
40
39
|
</div>
|
|
41
40
|
</div>
|
|
42
41
|
<script>
|
|
42
|
+
function callExpressRoute(path, method) {
|
|
43
|
+
const handlers = window.__debug?.shell?.httpHandlers || {};
|
|
44
|
+
const app = Object.values(handlers)[0];
|
|
45
|
+
if (!app?.routes) return null;
|
|
46
|
+
const routes = app.routes[method || 'GET'] || [];
|
|
47
|
+
const match = routes.find(r => r.path === '*' || r.path === path || path.startsWith(r.path));
|
|
48
|
+
if (!match) return null;
|
|
49
|
+
return new Promise(resolve => {
|
|
50
|
+
const res = {
|
|
51
|
+
_body: '', _status: 200, _ct: 'text/html',
|
|
52
|
+
send(b) { this._body = b; resolve({ status: this._status, body: this._body, ct: this._ct }); },
|
|
53
|
+
json(o) { this._ct = 'application/json'; this.send(JSON.stringify(o)); },
|
|
54
|
+
status(n) { this._status = n; return this; },
|
|
55
|
+
};
|
|
56
|
+
try { match.fn({ method: method || 'GET', path, query: {}, headers: {} }, res); }
|
|
57
|
+
catch(e) { resolve({ status: 500, body: e.message, ct: 'text/plain' }); }
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async function refreshPreview() {
|
|
61
|
+
const iframe = document.getElementById('preview-frame');
|
|
62
|
+
if (!iframe) return;
|
|
63
|
+
const result = await callExpressRoute('/');
|
|
64
|
+
if (result) { iframe.srcdoc = result.body; return; }
|
|
65
|
+
const snap = window.__debug?.idbSnapshot || {};
|
|
66
|
+
if (snap['index.html']) { iframe.srcdoc = snap['index.html']; return; }
|
|
67
|
+
iframe.srcdoc = '<p style="font-family:sans-serif;padding:2rem;color:#888">No express app running and no index.html in filesystem.<br>Run <code>node app.js</code> in the terminal.</p>';
|
|
68
|
+
}
|
|
43
69
|
function switchTab(t) {
|
|
44
70
|
['chat', 'term', 'preview'].forEach(id => {
|
|
45
71
|
document.getElementById('pane-' + id).classList.toggle('hidden', id !== t);
|
|
46
72
|
document.getElementById('tab-' + id).classList.toggle('tab-active', id === t);
|
|
47
73
|
});
|
|
48
|
-
if (t === 'preview')
|
|
49
|
-
const f = document.getElementById('preview-frame');
|
|
50
|
-
if (f.src === 'about:blank' || f.src === '') f.src = 'preview/';
|
|
51
|
-
}
|
|
74
|
+
if (t === 'preview') refreshPreview();
|
|
52
75
|
}
|
|
53
76
|
</script>
|
|
54
77
|
<script type="module" src="app.js"></script>
|
package/docs/terminal.js
CHANGED
|
@@ -43,8 +43,7 @@ let reloadTimer = null;
|
|
|
43
43
|
function scheduleReload() {
|
|
44
44
|
clearTimeout(reloadTimer);
|
|
45
45
|
reloadTimer = setTimeout(() => {
|
|
46
|
-
|
|
47
|
-
if (frame) frame.src = frame.src;
|
|
46
|
+
if (typeof window.refreshPreview === 'function') window.refreshPreview();
|
|
48
47
|
}, 5000);
|
|
49
48
|
}
|
|
50
49
|
|
package/package.json
CHANGED