tpmjs/apps/web/public/isoflow-embed.html
Thomas Davis 6eb0ce7e23 fix(tech): compact Isoflow grid layout for readable labels at 92% zoom
Reduced tile grid from 14x13 to 7x7 with 2-tile spacing. This increases
the default fitToView zoom from 38% to ~92%, making all node labels
clearly readable. Removed GitHub and bridge nodes to reduce clutter,
fixed @tpmjs/npm-client naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:43:51 +10:00

139 lines
5.9 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TPMJS Architecture</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body, #root { width: 100%; height: 100%; overflow: hidden; }
.loading {
display: flex; align-items: center; justify-content: center;
height: 100%; font-family: system-ui, sans-serif; color: #666;
}
.error { color: #666; text-align: center; }
.error a { color: #3b82f6; }
</style>
</head>
<body>
<div id="root"><div class="loading">Loading diagram...</div></div>
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18.2.0",
"react-dom": "https://esm.sh/react-dom@18.2.0",
"react/jsx-runtime": "https://esm.sh/react@18.2.0/jsx-runtime",
"isoflow": "https://esm.sh/isoflow@1.1.1?external=react,react-dom",
"@isoflow/isopacks/dist/isoflow": "https://esm.sh/@isoflow/isopacks@0.0.10/dist/isoflow.js"
}
}
</script>
<script type="module">
import React from 'react';
import ReactDOM from 'react-dom';
import isoflowPack from '@isoflow/isopacks/dist/isoflow';
const collection = isoflowPack.default || isoflowPack;
const icons = (collection.icons || []).map(icon => ({
id: icon.id, name: icon.name, url: icon.url,
collection: collection.name || 'Isoflow', isIsometric: icon.isIsometric
}));
const initialData = {
title: 'TPMJS Ecosystem',
icons,
colors: [
{ id: 'orange', value: '#f97316' },
{ id: 'blue', value: '#3b82f6' },
{ id: 'green', value: '#22c55e' },
{ id: 'purple', value: '#a855f7' },
{ id: 'pink', value: '#ec4899' }
],
items: [
// External Services
{ id: 'npm', name: 'npm Registry', icon: 'cloud' },
{ id: 'vercel', name: 'Vercel', icon: 'server' },
{ id: 'postgres', name: 'PostgreSQL', icon: 'storage' },
{ id: 'ai', name: 'AI Providers', icon: 'diamond' },
// Applications
{ id: 'web', name: 'tpmjs.com', icon: 'desktop' },
{ id: 'playground', name: 'Playground', icon: 'laptop' },
{ id: 'executor', name: 'Executor', icon: 'vm' },
// Published Packages
{ id: 'cli', name: '@tpmjs/cli', icon: 'function-module' },
{ id: 'types', name: '@tpmjs/types', icon: 'cube' },
{ id: 'ui', name: '@tpmjs/ui', icon: 'block' },
{ id: 'mcp', name: '@tpmjs/mcp-client', icon: 'loadbalancer' },
// Internal Packages
{ id: 'db', name: '@tpmjs/db', icon: 'storage' },
{ id: 'npm-client', name: '@tpmjs/npm-client', icon: 'package-module' },
// Official Tools
{ id: 'tools', name: '191+ AI Tools', icon: 'tower' }
],
views: [{
id: 'overview',
name: 'Ecosystem Overview',
items: [
// Row 0: External Services (2-tile spacing, compact)
{ id: 'npm', tile: { x: 0, y: 0 } },
{ id: 'vercel', tile: { x: 2, y: 0 } },
{ id: 'postgres', tile: { x: 4, y: 0 } },
{ id: 'ai', tile: { x: 6, y: 0 } },
// Row 2: Applications
{ id: 'web', tile: { x: 1, y: 2 } },
{ id: 'playground', tile: { x: 3, y: 2 } },
{ id: 'executor', tile: { x: 5, y: 2 } },
// Row 4: Published Packages
{ id: 'cli', tile: { x: 0, y: 4 } },
{ id: 'types', tile: { x: 2, y: 4 } },
{ id: 'ui', tile: { x: 4, y: 4 } },
{ id: 'mcp', tile: { x: 6, y: 4 } },
// Row 6: Internal + Tools
{ id: 'db', tile: { x: 1, y: 6 } },
{ id: 'npm-client', tile: { x: 3, y: 6 } },
{ id: 'tools', tile: { x: 5, y: 6 } }
],
connectors: [
// External → Apps
{ id: 'c1', color: 'orange', style: 'SOLID', anchors: [{ id: 'a1', ref: { item: 'vercel' } }, { id: 'a2', ref: { item: 'web' } }] },
{ id: 'c2', color: 'orange', style: 'DASHED', anchors: [{ id: 'a3', ref: { item: 'vercel' } }, { id: 'a4', ref: { item: 'playground' } }] },
{ id: 'c3', color: 'orange', style: 'SOLID', anchors: [{ id: 'a5', ref: { item: 'ai' } }, { id: 'a6', ref: { item: 'web' } }] },
{ id: 'c4', color: 'orange', style: 'DASHED', anchors: [{ id: 'a7', ref: { item: 'ai' } }, { id: 'a8', ref: { item: 'executor' } }] },
{ id: 'c5', color: 'purple', style: 'SOLID', anchors: [{ id: 'a9', ref: { item: 'postgres' } }, { id: 'a10', ref: { item: 'db' } }] },
// Apps → Packages
{ id: 'c6', color: 'blue', style: 'SOLID', anchors: [{ id: 'a11', ref: { item: 'web' } }, { id: 'a12', ref: { item: 'types' } }] },
{ id: 'c7', color: 'blue', style: 'SOLID', anchors: [{ id: 'a13', ref: { item: 'web' } }, { id: 'a14', ref: { item: 'ui' } }] },
{ id: 'c8', color: 'blue', style: 'DASHED', anchors: [{ id: 'a15', ref: { item: 'web' } }, { id: 'a16', ref: { item: 'mcp' } }] },
// Internal → Apps
{ id: 'c9', color: 'purple', style: 'SOLID', anchors: [{ id: 'a17', ref: { item: 'db' } }, { id: 'a18', ref: { item: 'web' } }] },
{ id: 'c10', color: 'purple', style: 'DASHED', anchors: [{ id: 'a19', ref: { item: 'npm-client' } }, { id: 'a20', ref: { item: 'web' } }] },
{ id: 'c11', color: 'orange', style: 'DASHED', anchors: [{ id: 'a21', ref: { item: 'npm' } }, { id: 'a22', ref: { item: 'npm-client' } }] },
// Tools pipeline
{ id: 'c12', color: 'pink', style: 'SOLID', anchors: [{ id: 'a23', ref: { item: 'tools' } }, { id: 'a24', ref: { item: 'npm' } }] },
{ id: 'c13', color: 'pink', style: 'DASHED', anchors: [{ id: 'a25', ref: { item: 'tools' } }, { id: 'a26', ref: { item: 'cli' } }] }
]
}],
fitToView: true,
view: 'overview'
};
try {
const { default: Isoflow } = await import('isoflow');
ReactDOM.render(
React.createElement(Isoflow, {
initialData,
editorMode: 'EXPLORABLE_READONLY',
width: '100%',
height: '100%',
renderer: { showGrid: true }
}),
document.getElementById('root')
);
} catch (err) {
console.error('Isoflow load error:', err);
document.getElementById('root').innerHTML =
'<div class="loading error"><p>Failed to load diagram. <a href="/architecture">View alternative</a></p></div>';
}
</script>
</body>
</html>