diff --git a/docs/druid-ui/_category_.json b/docs/druid-ui/_category_.json new file mode 100644 index 0000000..0676cb5 --- /dev/null +++ b/docs/druid-ui/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "DruidUI Framework", + "position": 6, + "collapsed": false +} diff --git a/docs/druid-ui/introduction.md b/docs/druid-ui/introduction.md new file mode 100644 index 0000000..c94d09d --- /dev/null +++ b/docs/druid-ui/introduction.md @@ -0,0 +1,182 @@ +--- +sidebar_position: 1 +title: DruidUI +description: WebAssembly framework for sandboxed UIs +--- + +# DruidUI + +DruidUI is a React-like framework that compiles to **WebAssembly** for building sandboxed user interfaces. Use it when you need to run untrusted UI code safely. + +## Why WebAssembly? + +Traditional approaches can't provide true sandboxing: +- **JavaScript** - Can access all browser APIs +- **iframes** - Limited state sharing, poor UX + +**WebAssembly** provides complete isolation - code can only access explicitly granted functions. + +## Quick Start + +```bash +npx create-druid-ui my-app +cd my-app +npm install +npm run dev +``` + +### Hello World + +```tsx +import { createComponent, Context } from '@druid-ui/component'; + +let count = 0; + +export const component = createComponent((ctx: Context) => { + return ( +
+

Hello Druid!

+ +
+ ); +}); +``` + +### Build & Deploy + +```bash +# Build to WASM +npm run build # → dist/component.wasm + +# Add to scroll +ui: + - name: dashboard + path: ui/dashboard.wasm + route: /admin +``` + +## Core Concepts + +### Functional Components + +Similar to [React](https://react.dev) and [Mithril.js](https://mithril.js.org/): + +- JSX/TSX syntax +- Every event triggers full rerender (no complex diffing) +- Module-level state (no hooks) + +```tsx +let items = ['todo 1', 'todo 2']; + +export const component = createComponent(() => { + return ( + + ); +}); +``` + +### Context + +Access route data via context: + +```tsx +export const component = createComponent((ctx: Context) => { + return ( +
+

Path: {ctx.path}

+

User ID: {ctx.params.userId}

+
+ ); +}); +``` + +### Shadow DOM + +Each component renders in isolated Shadow DOM - styles can't leak in/out. + +## Development Workflow + +### Raw Mode (Fast) + +Develop without WASM overhead: + +```html + +``` + +- Instant hot reload +- Normal browser debugging +- Not sandboxed (dev only!) + +### Sandbox Mode (Production) + +Full WASM sandboxing: + +```bash +npm run build +npm run preview +``` + +- True isolation +- Production-ready +- Slower iteration + +## Extension System + +By default, WASM can only call `d()`, `log()`, and `rerender()`. Add custom APIs via extensions: + +**1. Define interface (WIT):** + +```wit +package my:api; + +interface fetch { + get-data: func(url: string) -> string; +} +``` + +**2. Implement in host:** + +```js +druidElement.extensionObject = { + 'my:api/fetch': { + getData: async (url) => { + const res = await fetch(url); + return res.text(); + } + } +}; +``` + +**3. Use in component:** + +```tsx +import { getData } from 'my:api/fetch'; + +const data = await getData('/api/status'); +``` + +See [package documentation](./packages/component.md) for full API reference. + +## Multi-Language Support + +**Current:** JavaScript/TypeScript ✅ + +**Planned:** Rust, C++ (waiting for WebAssembly Component Model maturity) + +## Limitations + +- No async/await yet (use callback workaround) +- Full rerenders on every event (less efficient than React) +- JavaScript only for now +- No SSR + +## Learn More + +- [NPM Packages](./packages/component.md) - API reference +- [Examples](https://github.com/highcard-dev/druid-ui/tree/main/examples) +- [Source Code](https://github.com/highcard-dev/druid-ui) diff --git a/docs/druid-ui/packages/_category_.json b/docs/druid-ui/packages/_category_.json new file mode 100644 index 0000000..a988d9b --- /dev/null +++ b/docs/druid-ui/packages/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "NPM Packages", + "position": 10, + "collapsed": false +} diff --git a/docs/druid-ui/packages/build.md b/docs/druid-ui/packages/build.md new file mode 100644 index 0000000..9fc2d2b --- /dev/null +++ b/docs/druid-ui/packages/build.md @@ -0,0 +1,92 @@ +--- +sidebar_position: 3 +title: "@druid-ui/build" +description: Build tools for compiling to WASM +--- + +# @druid-ui/build + +Build tools and CLI for compiling DruidUI components to WebAssembly. + +## Installation + +```bash +npm install --save-dev @druid-ui/build +``` + +## CLI Commands + +### `druid-ui-build` + +Compile TypeScript/JSX to WASM: + +```bash +druid-ui-build [options] + +Options: + --out Output WASM file (default: dist/component.wasm) + --wit WIT directory (default: wit) + --world World name (default: druid-ui) +``` + +**Example:** + +```bash +druid-ui-build src/index.tsx --out build/app.wasm +``` + +### `druid-ui-gen-types` + +Generate TypeScript types from WIT files: + +```bash +druid-ui-gen-types [options] + +Options: + --wit-dir WIT directory (default: wit) + --out-dir Output directory (default: types) +``` + +**Example:** + +```bash +druid-ui-gen-types druid-ui --out-dir generated +``` + +## Programmatic API + +```typescript +import { buildComponent, generateTypes } from '@druid-ui/build'; + +// Build component +await buildComponent({ + entry: 'src/index.tsx', + output: 'dist/component.wasm', + witDir: 'wit', + world: 'druid-ui' +}); + +// Generate types +await generateTypes({ + world: 'druid-ui', + witDir: 'wit', + outDir: 'types' +}); +``` + +## Package Scripts + +```json +{ + "scripts": { + "build": "druid-ui-build src/index.tsx", + "gen-types": "druid-ui-gen-types druid-ui", + "dev": "vite" + } +} +``` + +## See Also + +- [@druid-ui/component](./component.md) +- [@druid-ui/vite](./vite.md) diff --git a/docs/druid-ui/packages/component.md b/docs/druid-ui/packages/component.md new file mode 100644 index 0000000..d8ace5a --- /dev/null +++ b/docs/druid-ui/packages/component.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 2 +title: "@druid-ui/component" +description: Component runtime library +--- + +# @druid-ui/component + +Core runtime for building DruidUI components. + +## Installation + +```bash +npm install @druid-ui/component +``` + +## Exports + +| Export | Usage | +|--------|-------| +| `@druid-ui/component` | Main (WASM sandbox) | +| `@druid-ui/component/raw` | Raw mode (dev) | +| `@druid-ui/component/jsx` | JSX types | +| `@druid-ui/component/types` | WIT types | + +## API + +### `createComponent()` + +```typescript +function createComponent( + renderFn: (ctx: Context) => JSX.Element +): Component; +``` + +Creates a component from render function. + +```tsx +import { createComponent } from '@druid-ui/component'; + +let count = 0; + +export const component = createComponent((ctx) => { + return ( + + ); +}); +``` + +### Context + +```typescript +interface Context { + path: string; // Current route + params: Record; // URL params +} +``` + +### Events + +All standard DOM events supported: + +```tsx + + { /* handler */ }} /> +
{ /* handler */ }}>...
+``` + +Every event execution triggers full rerender. + +### State + +Use module-level variables (no hooks): + +```tsx +let todos: string[] = []; +let input = ''; + +export const component = createComponent(() => { + return ( +
+ { input = e.target.value; }} + /> + + +
    + {todos.map(todo =>
  • {todo}
  • )} +
+
+ ); +}); +``` + +### TypeScript + +Enable JSX in `tsconfig.json`: + +```json +{ + "compilerOptions": { + "jsx": "react", + "jsxFactory": "d", + "jsxFragmentFactory": "Fragment", + "types": ["@druid-ui/component/jsx"] + } +} +``` + +## See Also + +- [@druid-ui/build](./build.md) - Build tools +- [@druid-ui/vite](./vite.md) - Dev server +- [@druid-ui/host](./host.md) - Browser runtime diff --git a/docs/druid-ui/packages/create-druid-ui.md b/docs/druid-ui/packages/create-druid-ui.md new file mode 100644 index 0000000..9091628 --- /dev/null +++ b/docs/druid-ui/packages/create-druid-ui.md @@ -0,0 +1,70 @@ +--- +sidebar_position: 4 +title: "create-druid-ui" +description: Project scaffolding tool +--- + +# create-druid-ui + +Scaffolding tool for creating new DruidUI projects. + +## Usage + +```bash +npx create-druid-ui [options] + +Options: + --template Template (default: starter) + --npm Use npm + --yarn Use yarn + --pnpm Use pnpm +``` + +**Example:** + +```bash +npx create-druid-ui my-dashboard +cd my-dashboard +npm install +npm run dev +``` + +## Generated Structure + +``` +my-app/ +├── src/ +│ └── index.tsx # Entry point +├── public/ +│ └── index.html +├── package.json +├── tsconfig.json +├── vite.config.ts +└── README.md +``` + +## Templates + +- `starter` (default) - Basic setup +- `simple` - Minimal example +- `extended` - With extensions + +## Scripts + +Generated `package.json` includes: + +```json +{ + "scripts": { + "dev": "vite", + "build": "druid-ui-build src/index.tsx", + "preview": "vite preview", + "gen-types": "druid-ui-gen-types druid-ui" + } +} +``` + +## See Also + +- [@druid-ui/component](./component.md) +- [@druid-ui/vite](./vite.md) diff --git a/docs/druid-ui/packages/host.md b/docs/druid-ui/packages/host.md new file mode 100644 index 0000000..a58c7b1 --- /dev/null +++ b/docs/druid-ui/packages/host.md @@ -0,0 +1,115 @@ +--- +sidebar_position: 6 +title: "@druid-ui/host" +description: Browser runtime for WASM +--- + +# @druid-ui/host + +Browser-side runtime that loads and executes DruidUI WebAssembly components. + +## Installation + +```bash +npm install @druid-ui/host +``` + +**Note:** Usually installed automatically. You don't typically import this directly. + +## Custom Element + +### `` + +```html + +``` + +**Attributes:** +- `src` - URL to WASM or TypeScript file +- `no-sandbox` - Disable WASM (dev only) +- `path` - Route path +- `params` - URL params (JSON string) + +### JavaScript API + +```typescript +interface DruidUIElement extends HTMLElement { + sandbox: boolean; // Toggle sandbox + extensionObject: Record; // Extension APIs + rerender(): void; // Manual rerender + load(url: string): Promise; // Load component +} +``` + +**Example:** + +```typescript +const el = document.querySelector('druid-ui') as DruidUIElement; + +// Disable sandbox +el.sandbox = false; + +// Provide extensions +el.extensionObject = { + 'my:api/fetch': { + getData: async (url: string) => { + return await fetch(url).then(r => r.text()); + } + } +}; + +// Force rerender +el.rerender(); +``` + +## Extensions + +Provide custom APIs: + +```typescript +el.extensionObject = { + 'my:api/storage': { + save: (key: string, val: string) => { + localStorage.setItem(key, val); + }, + load: (key: string) => { + return localStorage.getItem(key) || ''; + } + } +}; +``` + +## Shadow DOM + +Components render in isolated Shadow DOM: + +```html + + #shadow-root + +
/* Component */
+
+``` + +## Security + +In WASM mode, components **cannot**: +- Access DOM directly +- Call browser APIs (unless provided) +- Execute eval() or new Function() + +They can only: +- Return JSX via `d()` +- Call provided extension functions +- Call `log()` and `rerender()` + +## See Also + +- [@druid-ui/component](./component.md) +- [@druid-ui/vite](./vite.md) +- [WebAssembly Component Model](https://component-model.bytecodealliance.org/) diff --git a/docs/druid-ui/packages/vite.md b/docs/druid-ui/packages/vite.md new file mode 100644 index 0000000..d85c9bc --- /dev/null +++ b/docs/druid-ui/packages/vite.md @@ -0,0 +1,93 @@ +--- +sidebar_position: 5 +title: "@druid-ui/vite" +description: Vite plugin for hot reload +--- + +# @druid-ui/vite + +Vite plugin for DruidUI development with hot module replacement. + +## Installation + +```bash +npm install --save-dev @druid-ui/vite +``` + +## Usage + +```typescript +// vite.config.ts +import { defineConfig } from 'vite'; +import druidUI from '@druid-ui/vite'; + +export default defineConfig({ + plugins: [druidUI()] +}); +``` + +## Options + +```typescript +interface DruidUIPluginOptions { + sandbox?: boolean; // Enable WASM sandbox (default: false in dev) + witDir?: string; // Custom WIT directory + entry?: string; // Custom entry point + debug?: boolean; // Verbose logging +} +``` + +**Example:** + +```typescript +export default defineConfig({ + plugins: [ + druidUI({ + sandbox: false, // Disable WASM in dev + debug: true + }) + ] +}); +``` + +## Development Modes + +### Raw Mode (Fast) + +```typescript +druidUI({ sandbox: false }) +``` + +- Instant hot reload +- Normal debugging +- Not sandboxed (dev only) + +### Sandbox Mode + +```typescript +druidUI({ sandbox: true }) +``` + +- Production-like +- True sandboxing +- Slower reload + +## HTML Template + +Auto-served: + +```html + + + + + + + +``` + +## See Also + +- [@druid-ui/component](./component.md) +- [@druid-ui/build](./build.md) +- [Vite Documentation](https://vite.dev)