Changeset 0.37.3 (#215)

Co-authored-by: gobha <jasafpro@gmail.com>
Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
2026-03-21 00:34:36 +00:00
committed by xcaliber
parent 4f1abc6321
commit fc43618501
9 changed files with 1722 additions and 0 deletions

View File

@@ -63,6 +63,152 @@
const { Dropdown } = await import('./js/sw/primitives/dropdown.js');
const { AppShell } = await import('./js/sw/shell/app-shell.js');
// ── SDK Boot ────────────────────────────
const { boot } = await import('./js/sw/sdk/index.js');
await boot().catch(e => console.warn('SDK boot (no backend):', e));
const sw = window.sw;
// ── SDK Demo Page ───────────────────────
function SDKPage() {
const [authState, setAuthState] = useState(null);
const [apiResult, setApiResult] = useState(null);
const [permInput, setPermInput] = useState('model.use');
const [canResult, setCanResult] = useState(null);
const [eventLog, setEventLog] = useState([]);
const [emitLabel, setEmitLabel] = useState('test.event');
const logRef = useRef([]);
// Subscribe to all events for live log
useEffect(() => {
const unsub = sw.on('*', (payload, meta) => {
const entry = { ts: new Date().toLocaleTimeString(), label: meta.event, local: meta.local };
logRef.current = [entry, ...logRef.current].slice(0, 20);
setEventLog([...logRef.current]);
});
return unsub;
}, []);
function refreshAuth() {
setAuthState({
isAuthenticated: sw.auth.isAuthenticated,
user: sw.auth.user,
permissions: [...sw.auth.permissions],
teams: sw.auth.teams,
policies: sw.auth.policies,
});
}
useEffect(() => { refreshAuth(); }, []);
async function testApi() {
try {
const res = await sw.api.channels.list();
setApiResult({ ok: true, data: res });
} catch (e) {
setApiResult({ ok: false, error: e.message });
}
}
function testCan() {
setCanResult(sw.can(permInput));
}
const monoStyle = 'font-family: var(--font-mono, monospace); font-size: 0.8rem; background: var(--bg-1); padding: 0.75rem; border-radius: 6px; overflow: auto; max-height: 200px; white-space: pre-wrap; word-break: break-all; color: var(--text-2);';
return html`
<div class="gallery">
<h1>SDK Demo</h1>
<p class="subtitle">Layer 1 — SDK modules (v0.37.3)</p>
<!-- Auth State -->
<div class="section">
<h2>sw.auth</h2>
<div class="row" style="margin-bottom:0.5rem">
<${Button} variant="secondary" size="sm" onClick=${refreshAuth}>Refresh<//>
</div>
<div style=${monoStyle}>${JSON.stringify(authState, null, 2)}</div>
</div>
<!-- API Test -->
<div class="section">
<h2>sw.api</h2>
<div class="row" style="margin-bottom:0.5rem">
<${Button} variant="secondary" size="sm" onClick=${testApi}>sw.api.channels.list()<//>
</div>
${apiResult && html`
<div style=${monoStyle}>
${apiResult.ok
? JSON.stringify(apiResult.data, null, 2)
: 'Error: ' + apiResult.error}
</div>
`}
</div>
<!-- RBAC Test -->
<div class="section">
<h2>sw.can()</h2>
<div class="row">
<input class="sw-input" style="width:180px" value=${permInput}
onInput=${e => setPermInput(e.target.value)} />
<${Button} variant="secondary" size="sm" onClick=${testCan}>Check<//>
${canResult !== null && html`
<span style="font-weight:600; color: ${canResult ? 'var(--success)' : 'var(--danger)'}">
${canResult ? 'ALLOWED' : 'DENIED'}
</span>
`}
</div>
<div class="row" style="margin-top:0.5rem">
<span style="color:var(--text-3); font-size:0.8rem">
sw.isAdmin: ${String(sw.isAdmin)}
</span>
</div>
</div>
<!-- Theme -->
<div class="section">
<h2>sw.theme</h2>
<div class="row">
<span style="color:var(--text-2); font-size:0.85rem">
mode: ${sw.theme.mode} · resolved: ${sw.theme.current}
</span>
</div>
<div class="row">
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('light')}>Light<//>
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('dark')}>Dark<//>
<${Button} variant="secondary" size="sm" onClick=${() => sw.theme.set('system')}>System<//>
</div>
</div>
<!-- Events -->
<div class="section">
<h2>sw.on / sw.emit</h2>
<div class="row" style="margin-bottom:0.5rem">
<input class="sw-input" style="width:180px" value=${emitLabel}
onInput=${e => setEmitLabel(e.target.value)} />
<${Button} variant="secondary" size="sm"
onClick=${() => sw.emit(emitLabel, { demo: true }, { localOnly: true })}>Emit<//>
</div>
<div style=${monoStyle + ' max-height:160px;'}>
${eventLog.length === 0 ? '(listening for events...)' :
eventLog.map(e => `${e.ts} ${e.local ? 'L' : 'R'} ${e.label}`).join('\n')}
</div>
</div>
<!-- Pipe -->
<div class="section">
<h2>sw.pipe</h2>
<div style=${monoStyle}>${JSON.stringify(sw.pipe.list(), null, 2)}</div>
</div>
<!-- Namespaces -->
<div class="section">
<h2>sw.api namespaces</h2>
<div style=${monoStyle}>${Object.keys(sw.api).filter(k => typeof sw.api[k] === 'object').join(', ')}</div>
</div>
</div>
`;
}
function PrimitivesPage() {
const [dialogOpen, setDialogOpen] = useState(false);
const [drawerOpen, setDrawerOpen] = useState(false);
@@ -336,6 +482,7 @@
<nav class="dev-nav">
<button class=${page === 'primitives' ? 'active' : ''} onClick=${() => setPage('primitives')}>Primitives</button>
<button class=${page === 'shell' ? 'active' : ''} onClick=${() => setPage('shell')}>Shell</button>
<button class=${page === 'sdk' ? 'active' : ''} onClick=${() => setPage('sdk')}>SDK</button>
<div style="flex:1" />
<${ShellControls} ...${{
bannerOn, setBannerOn, bannerVariant, setBannerVariant, bannerText, setBannerText,
@@ -345,6 +492,7 @@
</nav>
<div class="dev-page">
${page === 'primitives' && html`<${PrimitivesPage} />`}
${page === 'sdk' && html`<${SDKPage} />`}
</div>
</div>
<//>