wilco 0.1.2__tar.gz

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.
Files changed (137) hide show
  1. wilco-0.1.2/.claude/settings.local.json +58 -0
  2. wilco-0.1.2/.gitignore +5 -0
  3. wilco-0.1.2/CHANGELOG.md +41 -0
  4. wilco-0.1.2/CLAUDE.md +146 -0
  5. wilco-0.1.2/Makefile +55 -0
  6. wilco-0.1.2/PKG-INFO +185 -0
  7. wilco-0.1.2/Procfile +2 -0
  8. wilco-0.1.2/README.md +151 -0
  9. wilco-0.1.2/docs/django.rst +412 -0
  10. wilco-0.1.2/docs/fastapi.rst +241 -0
  11. wilco-0.1.2/docs/internals/standalone.rst +352 -0
  12. wilco-0.1.2/docs/javascripts.rst +250 -0
  13. wilco-0.1.2/docs/specs/components.rst +659 -0
  14. wilco-0.1.2/examples/django-project/.gitignore +9 -0
  15. wilco-0.1.2/examples/django-project/.python-version +1 -0
  16. wilco-0.1.2/examples/django-project/Makefile +43 -0
  17. wilco-0.1.2/examples/django-project/README.md +55 -0
  18. wilco-0.1.2/examples/django-project/db.sqlite3 +0 -0
  19. wilco-0.1.2/examples/django-project/ecommerce/__init__.py +0 -0
  20. wilco-0.1.2/examples/django-project/ecommerce/asgi.py +16 -0
  21. wilco-0.1.2/examples/django-project/ecommerce/settings.py +148 -0
  22. wilco-0.1.2/examples/django-project/ecommerce/urls.py +20 -0
  23. wilco-0.1.2/examples/django-project/ecommerce/wsgi.py +16 -0
  24. wilco-0.1.2/examples/django-project/fixtures/sample_products.json +68 -0
  25. wilco-0.1.2/examples/django-project/manage.py +22 -0
  26. wilco-0.1.2/examples/django-project/media/products/cartridge.jpg +0 -0
  27. wilco-0.1.2/examples/django-project/media/products/coin.jpg +0 -0
  28. wilco-0.1.2/examples/django-project/media/products/giftcard.jpg +0 -0
  29. wilco-0.1.2/examples/django-project/media/products/knife.jpg +0 -0
  30. wilco-0.1.2/examples/django-project/media/products/mop.jpg +0 -0
  31. wilco-0.1.2/examples/django-project/media/products/teeshirt.jpg +0 -0
  32. wilco-0.1.2/examples/django-project/pyproject.toml +15 -0
  33. wilco-0.1.2/examples/django-project/static/android-chrome-192x192.png +0 -0
  34. wilco-0.1.2/examples/django-project/static/android-chrome-512x512.png +0 -0
  35. wilco-0.1.2/examples/django-project/static/apple-touch-icon.png +0 -0
  36. wilco-0.1.2/examples/django-project/static/css/admin.css +9 -0
  37. wilco-0.1.2/examples/django-project/static/favicon-16x16.png +0 -0
  38. wilco-0.1.2/examples/django-project/static/favicon-32x32.png +0 -0
  39. wilco-0.1.2/examples/django-project/static/favicon.ico +0 -0
  40. wilco-0.1.2/examples/django-project/static/site.webmanifest +1 -0
  41. wilco-0.1.2/examples/django-project/store/__init__.py +0 -0
  42. wilco-0.1.2/examples/django-project/store/admin.py +88 -0
  43. wilco-0.1.2/examples/django-project/store/apps.py +5 -0
  44. wilco-0.1.2/examples/django-project/store/components/__init__.py +1 -0
  45. wilco-0.1.2/examples/django-project/store/components/product/Product.styles.ts +115 -0
  46. wilco-0.1.2/examples/django-project/store/components/product/Product.tsx +72 -0
  47. wilco-0.1.2/examples/django-project/store/components/product/__init__.py +1 -0
  48. wilco-0.1.2/examples/django-project/store/components/product/index.tsx +1 -0
  49. wilco-0.1.2/examples/django-project/store/components/product/schema.json +35 -0
  50. wilco-0.1.2/examples/django-project/store/components/product_list/ProductList.styles.ts +38 -0
  51. wilco-0.1.2/examples/django-project/store/components/product_list/ProductList.tsx +37 -0
  52. wilco-0.1.2/examples/django-project/store/components/product_list/__init__.py +0 -0
  53. wilco-0.1.2/examples/django-project/store/components/product_list/index.tsx +1 -0
  54. wilco-0.1.2/examples/django-project/store/components/product_list/schema.json +43 -0
  55. wilco-0.1.2/examples/django-project/store/components/product_preview/ProductPreview.styles.ts +57 -0
  56. wilco-0.1.2/examples/django-project/store/components/product_preview/ProductPreview.tsx +44 -0
  57. wilco-0.1.2/examples/django-project/store/components/product_preview/__init__.py +0 -0
  58. wilco-0.1.2/examples/django-project/store/components/product_preview/index.tsx +1 -0
  59. wilco-0.1.2/examples/django-project/store/components/product_preview/schema.json +26 -0
  60. wilco-0.1.2/examples/django-project/store/migrations/0001_initial.py +32 -0
  61. wilco-0.1.2/examples/django-project/store/migrations/0002_alter_product_image_url.py +22 -0
  62. wilco-0.1.2/examples/django-project/store/migrations/0003_remove_product_image_url_product_image.py +22 -0
  63. wilco-0.1.2/examples/django-project/store/migrations/__init__.py +0 -0
  64. wilco-0.1.2/examples/django-project/store/models.py +12 -0
  65. wilco-0.1.2/examples/django-project/store/tests.py +3 -0
  66. wilco-0.1.2/examples/django-project/store/urls.py +10 -0
  67. wilco-0.1.2/examples/django-project/store/views.py +49 -0
  68. wilco-0.1.2/examples/django-project/templates/base.html +154 -0
  69. wilco-0.1.2/examples/django-project/templates/store/product_detail.html +9 -0
  70. wilco-0.1.2/examples/django-project/templates/store/product_list.html +7 -0
  71. wilco-0.1.2/examples/django-project/uv.lock +731 -0
  72. wilco-0.1.2/pyproject.toml +74 -0
  73. wilco-0.1.2/src/wilco/__init__.py +15 -0
  74. wilco-0.1.2/src/wilco/__main__.py +57 -0
  75. wilco-0.1.2/src/wilco/bridges/__init__.py +5 -0
  76. wilco-0.1.2/src/wilco/bridges/django/__init__.py +53 -0
  77. wilco-0.1.2/src/wilco/bridges/django/admin.py +163 -0
  78. wilco-0.1.2/src/wilco/bridges/django/apps.py +11 -0
  79. wilco-0.1.2/src/wilco/bridges/django/static/wilco/live-loader.js +311 -0
  80. wilco-0.1.2/src/wilco/bridges/django/static/wilco/loader.js +71 -0
  81. wilco-0.1.2/src/wilco/bridges/django/templatetags/__init__.py +1 -0
  82. wilco-0.1.2/src/wilco/bridges/django/templatetags/wilco_tags.py +65 -0
  83. wilco-0.1.2/src/wilco/bridges/django/urls.py +22 -0
  84. wilco-0.1.2/src/wilco/bridges/django/views.py +183 -0
  85. wilco-0.1.2/src/wilco/bridges/django/widgets.py +134 -0
  86. wilco-0.1.2/src/wilco/bridges/fastapi.py +73 -0
  87. wilco-0.1.2/src/wilco/bundler.py +326 -0
  88. wilco-0.1.2/src/wilco/examples/__init__.py +1 -0
  89. wilco-0.1.2/src/wilco/examples/carousel/Carousel.tsx +101 -0
  90. wilco-0.1.2/src/wilco/examples/carousel/NavButton.tsx +31 -0
  91. wilco-0.1.2/src/wilco/examples/carousel/__init__.py +1 -0
  92. wilco-0.1.2/src/wilco/examples/carousel/index.tsx +1 -0
  93. wilco-0.1.2/src/wilco/examples/carousel/schema.json +37 -0
  94. wilco-0.1.2/src/wilco/examples/counter/Counter.tsx +23 -0
  95. wilco-0.1.2/src/wilco/examples/counter/__init__.py +1 -0
  96. wilco-0.1.2/src/wilco/examples/counter/index.tsx +1 -0
  97. wilco-0.1.2/src/wilco/examples/counter/schema.json +21 -0
  98. wilco-0.1.2/src/wilco/examples/crasher/Crasher.tsx +22 -0
  99. wilco-0.1.2/src/wilco/examples/crasher/__init__.py +1 -0
  100. wilco-0.1.2/src/wilco/examples/crasher/index.tsx +1 -0
  101. wilco-0.1.2/src/wilco/examples/crasher/schema.json +20 -0
  102. wilco-0.1.2/src/wilco/examples/image/Image.tsx +37 -0
  103. wilco-0.1.2/src/wilco/examples/image/__init__.py +1 -0
  104. wilco-0.1.2/src/wilco/examples/image/index.tsx +1 -0
  105. wilco-0.1.2/src/wilco/examples/image/schema.json +47 -0
  106. wilco-0.1.2/src/wilco/registry.py +148 -0
  107. wilco-0.1.2/src/wilcojs/react/.gitignore +24 -0
  108. wilco-0.1.2/src/wilcojs/react/biome.json +21 -0
  109. wilco-0.1.2/src/wilcojs/react/index.html +12 -0
  110. wilco-0.1.2/src/wilcojs/react/package.json +40 -0
  111. wilco-0.1.2/src/wilcojs/react/pnpm-lock.yaml +2195 -0
  112. wilco-0.1.2/src/wilcojs/react/src/App.tsx +315 -0
  113. wilco-0.1.2/src/wilcojs/react/src/api/bundles.test.tsx +180 -0
  114. wilco-0.1.2/src/wilcojs/react/src/api/bundles.ts +80 -0
  115. wilco-0.1.2/src/wilcojs/react/src/components/PropsEditor.test.tsx +302 -0
  116. wilco-0.1.2/src/wilcojs/react/src/components/PropsEditor.tsx +179 -0
  117. wilco-0.1.2/src/wilcojs/react/src/components/StackTrace.test.tsx +166 -0
  118. wilco-0.1.2/src/wilcojs/react/src/components/StackTrace.tsx +276 -0
  119. wilco-0.1.2/src/wilcojs/react/src/loader/ServerComponent.tsx +38 -0
  120. wilco-0.1.2/src/wilcojs/react/src/loader/sourceMapRegistry.ts +150 -0
  121. wilco-0.1.2/src/wilcojs/react/src/loader/standalone.ts +348 -0
  122. wilco-0.1.2/src/wilcojs/react/src/loader/useComponent.test.ts +157 -0
  123. wilco-0.1.2/src/wilcojs/react/src/loader/useComponent.ts +115 -0
  124. wilco-0.1.2/src/wilcojs/react/src/loader/wilco.ts +6 -0
  125. wilco-0.1.2/src/wilcojs/react/src/main.tsx +15 -0
  126. wilco-0.1.2/src/wilcojs/react/src/style.css +897 -0
  127. wilco-0.1.2/src/wilcojs/react/src/test/setup.ts +23 -0
  128. wilco-0.1.2/src/wilcojs/react/tsconfig.json +28 -0
  129. wilco-0.1.2/src/wilcojs/react/vite.config.ts +29 -0
  130. wilco-0.1.2/tests/conftest.py +154 -0
  131. wilco-0.1.2/tests/test_bridges_django.py +628 -0
  132. wilco-0.1.2/tests/test_bridges_fastapi.py +329 -0
  133. wilco-0.1.2/tests/test_bundler.py +406 -0
  134. wilco-0.1.2/tests/test_init.py +29 -0
  135. wilco-0.1.2/tests/test_registry.py +468 -0
  136. wilco-0.1.2/uv.lock +1539 -0
  137. wilco-0.1.2/wilco.jpg +0 -0
@@ -0,0 +1,58 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(pnpm install:*)",
5
+ "Bash(pnpm add:*)",
6
+ "Bash(uv sync:*)",
7
+ "Bash(uv run python:*)",
8
+ "Bash(ls:*)",
9
+ "Bash(pnpm typecheck:*)",
10
+ "Bash(curl:*)",
11
+ "Bash(pnpm dev)",
12
+ "Bash(pkill:*)",
13
+ "WebSearch",
14
+ "Bash(make start:*)",
15
+ "mcp__chrome-devtools__list_pages",
16
+ "mcp__chrome-devtools__navigate_page",
17
+ "mcp__chrome-devtools__take_snapshot",
18
+ "mcp__chrome-devtools__click",
19
+ "mcp__chrome-devtools__list_console_messages",
20
+ "mcp__chrome-devtools__get_console_message",
21
+ "mcp__chrome-devtools__list_network_requests",
22
+ "mcp__chrome-devtools__get_network_request",
23
+ "mcp__chrome-devtools__evaluate_script",
24
+ "mcp__chrome-devtools__take_screenshot",
25
+ "WebFetch(domain:pypi.org)",
26
+ "WebFetch(domain:github.com)",
27
+ "WebFetch(domain:www.npmjs.com)",
28
+ "WebFetch(domain:esbuild.github.io)",
29
+ "WebFetch(domain:raw.githubusercontent.com)",
30
+ "Bash(uv run pytest:*)",
31
+ "Bash(tree:*)",
32
+ "Bash(find:*)",
33
+ "Bash(mkdir:*)",
34
+ "Bash(python3:*)",
35
+ "mcp__chrome-devtools__wait_for",
36
+ "mcp__chrome-devtools__resize_page",
37
+ "Bash(make test:*)",
38
+ "Bash(make wheel:*)",
39
+ "Bash(uv init:*)",
40
+ "Bash(uv run:*)",
41
+ "WebFetch(domain:unfoldadmin.com)",
42
+ "mcp__chrome-devtools__new_page",
43
+ "mcp__chrome-devtools__fill_form",
44
+ "Bash(pnpm test:run:*)",
45
+ "Bash(pnpm build:loader:*)",
46
+ "mcp__chrome-devtools__fill",
47
+ "Bash(make format:*)",
48
+ "Bash(make format-frontend:*)",
49
+ "Bash(make test-frontend:*)",
50
+ "mcp__chrome-devtools__upload_file",
51
+ "Bash(cat:*)",
52
+ "Bash(uv build:*)",
53
+ "Bash(unzip:*)",
54
+ "Bash(uv lock:*)",
55
+ "Bash(uv pip install:*)"
56
+ ]
57
+ }
58
+ }
wilco-0.1.2/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ **/.DS_Store
2
+ **/__pycache__/*.pyc
3
+ /.idea/
4
+ node_modules/
5
+ /dist/
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - **Django Admin Live Preview**: New `LivePreviewAdminMixin` enables real-time component preview in Django admin forms. The preview updates automatically when form fields lose focus, showing validation errors or the updated component.
13
+ - **Standalone Loader**: Self-contained JavaScript loader (`loader.js`) for rendering wilco components in server-rendered pages without a full React app. Includes React, transforms ESM bundles at runtime, and manages component lifecycle.
14
+ - **Live Loader Extension**: Additional `live-loader.js` script that adds live preview functionality to the standalone loader, with debounced validation and error display.
15
+ - **Django Template Tags**: `{% wilco_component %}` and `{% wilco_loader_script %}` template tags for embedding components in Django templates.
16
+ - **Component Widget**: `WilcoComponentWidget` class for rendering components in Django admin readonly fields.
17
+ - **Multi-source Registry**: `ComponentRegistry.add_source()` now supports multiple component directories with optional prefixes.
18
+ - **Django App Autodiscovery**: Automatically discovers components from `components/` directories in Django apps, prefixed with the app label (e.g., `store:product`).
19
+ - **Bundle Caching**: Django bridge caches bundles in memory with file mtime invalidation.
20
+ - **Product Component Modes**: Example product component now supports `list` and `detail` display modes.
21
+ - **Product List Component**: New `product_list` component for displaying grids of products.
22
+ - **Product Preview Component**: New `product_preview` component showing both list and detail modes for admin preview.
23
+ - **Goober CSS-in-JS**: Integrated goober (~1KB) for styled-components-like styling with design tokens.
24
+ - **useComponent Hook**: Standalone loader now supports `useComponent()` for dynamic component loading with React Suspense.
25
+ - **Client-side Image Preview**: Live preview supports blob URLs for previewing uploaded images before form submission.
26
+
27
+ ### Changed
28
+
29
+ - **Barrel Pattern**: Example components now use barrel pattern with separate implementation and style files.
30
+ - **Component Composition**: ProductList and ProductPreview now use `useComponent("store:product")` instead of inline implementations.
31
+
32
+ - **Bundle Hash**: Metadata endpoint now includes content hash for cache busting.
33
+ - **Cache Headers**: Bundle responses use `immutable` cache directive for better CDN support.
34
+ - **Product Model**: Example Django project now uses `ImageField` instead of URL field for product images.
35
+
36
+ ### Documentation
37
+
38
+ - Added FastAPI integration guide (`docs/fastapi.rst`)
39
+ - Added Django integration guide (`docs/django.rst`)
40
+ - Added standalone loader internals documentation (`docs/internals/standalone.rst`)
41
+ - Added JavaScript architecture overview (`docs/javascripts.rst`)
wilco-0.1.2/CLAUDE.md ADDED
@@ -0,0 +1,146 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **wilco** is a proof-of-concept framework that enables Python backends to serve isolated React/TypeScript components to a Vite-based frontend. Components are defined in the Python codebase alongside their TypeScript implementations, then dynamically bundled with esbuild and loaded by the frontend at runtime.
8
+
9
+ ## Architecture
10
+
11
+ ```
12
+ wilco/
13
+ ├── pyproject.toml # Python package config
14
+ ├── uv.lock
15
+ ├── src/
16
+ │ ├── wilco/ # Python package
17
+ │ │ ├── __init__.py
18
+ │ │ ├── __main__.py # Development server entry point
19
+ │ │ ├── registry.py # Component discovery
20
+ │ │ ├── bundler.py # esbuild integration
21
+ │ │ ├── bridges/
22
+ │ │ │ ├── __init__.py
23
+ │ │ │ └── fastapi.py # Mountable FastAPI router
24
+ │ │ └── examples/ # Example components
25
+ │ └── wilcojs/ # JavaScript/TypeScript packages
26
+ │ └── react/ # React frontend app
27
+ │ ├── package.json
28
+ │ ├── index.html
29
+ │ ├── src/
30
+ │ │ ├── App.tsx
31
+ │ │ ├── api/
32
+ │ │ │ └── bundles.ts
33
+ │ │ └── loader/
34
+ │ │ ├── ServerComponent.tsx
35
+ │ │ ├── useComponent.ts
36
+ │ │ └── wilco.ts
37
+ │ ├── tsconfig.json
38
+ │ └── vite.config.ts
39
+ ├── tests/ # Python tests
40
+ └── docs/
41
+ ```
42
+
43
+ ### Key Concepts
44
+
45
+ - **Co-located components**: Each component has a Python package with `__init__.py`, `index.tsx` (React implementation), and optional `schema.json` (metadata/props)
46
+ - **Dynamic bundling**: Backend uses esbuild (from frontend's node_modules) to bundle TypeScript components on-demand
47
+ - **Runtime loading**: Frontend transforms ESM imports to use `window.__MODULES__`, then executes bundled code via `new Function()`
48
+ - **Bridge pattern**: The `wilco.bridges.fastapi` module provides a mountable router factory for easy integration
49
+
50
+ ### API Endpoints
51
+
52
+ - `GET /api/bundles` - List available bundles (names only)
53
+ - `GET /api/bundles/{name}.js` - Get bundled JavaScript for a component
54
+ - `GET /api/bundles/{name}/metadata` - Get component metadata (title, description, props)
55
+
56
+ ## Commands
57
+
58
+ ### Backend (Python/uv)
59
+
60
+ ```bash
61
+ # Install dependencies
62
+ uv sync
63
+
64
+ # Run development server (port 8000)
65
+ uv run python -m wilco
66
+
67
+ # Run tests
68
+ uv run pytest
69
+ uv run pytest tests/test_file.py -k "test_name"
70
+ ```
71
+
72
+ ### Frontend (Vite/pnpm)
73
+
74
+ ```bash
75
+ cd src/wilcojs/react
76
+
77
+ # Install dependencies
78
+ pnpm install
79
+
80
+ # Run development server (port 5173, proxies /api to backend)
81
+ pnpm dev
82
+
83
+ # Type checking
84
+ pnpm typecheck
85
+
86
+ # Build for production
87
+ pnpm build
88
+ ```
89
+
90
+ ### Running the POC
91
+
92
+ **Option 1: Using Procfile (recommended)**
93
+ ```bash
94
+ # Install a process manager (honcho, foreman, or overmind)
95
+ pip install honcho # or: brew install overmind
96
+
97
+ # Start both services
98
+ honcho start # or: overmind start
99
+ ```
100
+
101
+ **Option 2: Manual**
102
+ ```bash
103
+ # Terminal 1
104
+ uv run python -m wilco
105
+
106
+ # Terminal 2
107
+ cd src/wilcojs/react && pnpm dev
108
+ ```
109
+
110
+ Open http://localhost:5173
111
+
112
+ ### Hot Reloading
113
+
114
+ - **Backend**: uvicorn runs with `reload=True`, auto-reloads on Python file changes
115
+ - **Frontend**: Vite provides HMR (Hot Module Replacement) for instant updates
116
+
117
+ ## Adding New Components
118
+
119
+ 1. Create a component package: `src/wilco/examples/<name>/` (or your own components directory)
120
+ 2. Add `__init__.py` (can be empty)
121
+ 3. Add `index.tsx` with a default export React component
122
+ 4. Optionally add `schema.json` with title, description, and props schema
123
+ 5. Component will be auto-discovered and available at `/api/bundles/<name>.js`
124
+
125
+ ## Using the Bridge Pattern
126
+
127
+ The `wilco.bridges.fastapi` module provides a `create_router()` factory for integrating with any FastAPI app:
128
+
129
+ ```python
130
+ from fastapi import FastAPI
131
+ from wilco import ComponentRegistry
132
+ from wilco.bridges.fastapi import create_router
133
+
134
+ app = FastAPI()
135
+ registry = ComponentRegistry(Path("./my_components"))
136
+ app.include_router(create_router(registry), prefix="/api")
137
+ ```
138
+
139
+ ## Frontend State Management
140
+
141
+ Uses `@tanstack/react-query` for server state:
142
+ - `useBundles()` - Fetch list of available bundles
143
+ - `useBundleMetadata(name)` - Fetch metadata for a specific bundle
144
+ - `useBundleCode(name)` - Fetch bundled JavaScript code
145
+
146
+ Hooks are defined in `src/wilcojs/react/src/api/bundles.ts`.
wilco-0.1.2/Makefile ADDED
@@ -0,0 +1,55 @@
1
+ .PHONY: start test test-backend test-frontend install clean wheel format format-python format-frontend build-loader publish publish-test
2
+
3
+ # Start development servers (default target)
4
+ start:
5
+ overmind start
6
+
7
+ # Build the standalone loader (compiles TypeScript to JavaScript)
8
+ build-loader:
9
+ cd src/wilcojs/react && pnpm build:loader
10
+
11
+ # Build Python wheel (includes pre-built JavaScript assets)
12
+ wheel: build-loader
13
+ uv build
14
+
15
+ # Publish to PyPI
16
+ publish: wheel
17
+ uv run twine upload dist/*
18
+
19
+ # Publish to TestPyPI (for testing before production release)
20
+ publish-test: wheel
21
+ uv run twine upload --repository testpypi dist/*
22
+
23
+ # Run all tests
24
+ test: test-backend test-frontend
25
+
26
+ # Run backend tests (Python/pytest)
27
+ test-backend:
28
+ uv run pytest
29
+
30
+ # Run frontend tests (TypeScript typecheck + Vitest)
31
+ test-frontend:
32
+ cd src/wilcojs/react && pnpm typecheck && pnpm test:run
33
+
34
+ # Install all dependencies
35
+ install:
36
+ uv sync
37
+ cd src/wilcojs/react && pnpm install
38
+
39
+ # Clean build artifacts
40
+ clean:
41
+ rm -rf .pytest_cache
42
+ rm -rf dist
43
+ rm -rf src/wilcojs/react/dist
44
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
45
+
46
+ # Format all code
47
+ format: format-python format-frontend
48
+
49
+ # Format Python files with ruff (4 spaces, 120 chars)
50
+ format-python:
51
+ uv run ruff format src tests
52
+
53
+ # Format frontend files with biome
54
+ format-frontend:
55
+ cd src/wilcojs/react && pnpm exec biome format --write .
wilco-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: wilco
3
+ Version: 0.1.2
4
+ Summary: Serve React components from Python backends
5
+ Project-URL: Homepage, https://github.com/user/wilco
6
+ Project-URL: Documentation, https://github.com/user/wilco#readme
7
+ Project-URL: Repository, https://github.com/user/wilco
8
+ Project-URL: Issues, https://github.com/user/wilco/issues
9
+ License-Expression: MIT
10
+ Keywords: components,django,esbuild,fastapi,react,typescript
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Framework :: Django
13
+ Classifier: Framework :: FastAPI
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Internet :: WWW/HTTP
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: fastapi>=0.115.0
24
+ Requires-Dist: uvicorn[standard]>=0.32.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: django>=4.2.0; extra == 'dev'
27
+ Requires-Dist: httpx>=0.27.0; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
29
+ Requires-Dist: pytest-benchmark>=4.0.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
32
+ Requires-Dist: twine>=6.0.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # wilco
36
+
37
+ **Server-defined React components for Python backends.**
38
+
39
+ Wilco lets you define React components alongside your Python code and serve them dynamically to any frontend. Components are bundled on-demand with esbuild and loaded at runtime—no build step required for your component library.
40
+
41
+ ## Why wilco?
42
+
43
+ - **Co-locate components with backend logic**: Keep your UI components next to the Python code that powers them
44
+ - **No frontend build pipeline**: Components are bundled on-the-fly when requested
45
+ - **Full source map support**: Debug your TypeScript directly in browser devtools
46
+ - **Component composition**: Components can dynamically load other components
47
+ - **Framework agnostic**: Mount the API router in any FastAPI (or compatible) app
48
+
49
+ ## Quick Start
50
+
51
+ ### Installation
52
+
53
+ ```bash
54
+ pip install wilco
55
+ ```
56
+
57
+ ### Create a component
58
+
59
+ ```
60
+ my_components/
61
+ └── greeting/
62
+ ├── __init__.py
63
+ ├── index.tsx
64
+ └── schema.json
65
+ ```
66
+
67
+ ```tsx
68
+ // index.tsx
69
+ interface GreetingProps {
70
+ name: string;
71
+ formal?: boolean;
72
+ }
73
+
74
+ export default function Greeting({ name, formal = false }: GreetingProps) {
75
+ const message = formal ? `Good day, ${name}.` : `Hey ${name}!`;
76
+ return <p>{message}</p>;
77
+ }
78
+ ```
79
+
80
+ ```json
81
+ {
82
+ "title": "Greeting",
83
+ "description": "A friendly greeting component",
84
+ "type": "object",
85
+ "properties": {
86
+ "name": { "type": "string" },
87
+ "formal": { "type": "boolean", "default": false }
88
+ },
89
+ "required": ["name"]
90
+ }
91
+ ```
92
+
93
+ ### Mount the API
94
+
95
+ ```python
96
+ from pathlib import Path
97
+ from fastapi import FastAPI
98
+ from wilco import ComponentRegistry
99
+ from wilco.bridges.fastapi import create_router
100
+
101
+ app = FastAPI()
102
+ registry = ComponentRegistry(Path("./my_components"))
103
+ app.include_router(create_router(registry), prefix="/api")
104
+ ```
105
+
106
+ ### Load components in React
107
+
108
+ ```tsx
109
+ import { useComponent } from '@wilcojs/react';
110
+
111
+ function App() {
112
+ const Greeting = useComponent('greeting');
113
+ return <Greeting name="World" />;
114
+ }
115
+ ```
116
+
117
+ ## API Endpoints
118
+
119
+ | Endpoint | Description |
120
+ |----------|-------------|
121
+ | `GET /api/bundles` | List available components |
122
+ | `GET /api/bundles/{name}.js` | Get bundled JavaScript |
123
+ | `GET /api/bundles/{name}/metadata` | Get component metadata |
124
+
125
+ ## Component Structure
126
+
127
+ Each component is a Python package with:
128
+
129
+ | File | Required | Description |
130
+ |------|----------|-------------|
131
+ | `__init__.py` | Yes | Package marker |
132
+ | `index.tsx` | Yes | React component (default export) |
133
+ | `schema.json` | No | Props schema and metadata |
134
+
135
+ Components can include additional `.tsx` files—they're all bundled together.
136
+
137
+ ## Component Composition
138
+
139
+ Components can load other components dynamically:
140
+
141
+ ```tsx
142
+ import { useComponent } from '@wilcojs/react';
143
+
144
+ export default function Dashboard() {
145
+ const Chart = useComponent('chart');
146
+ const Table = useComponent('table');
147
+
148
+ return (
149
+ <div>
150
+ <Chart data={...} />
151
+ <Table rows={...} />
152
+ </div>
153
+ );
154
+ }
155
+ ```
156
+
157
+ ## Development Server
158
+
159
+ Run the built-in development server to preview components:
160
+
161
+ ```bash
162
+ uv run python -m wilco
163
+ ```
164
+
165
+ Then start the frontend:
166
+
167
+ ```bash
168
+ cd src/wilcojs/react && pnpm dev
169
+ ```
170
+
171
+ Open http://localhost:5173 to browse and test your components.
172
+
173
+ ## Requirements
174
+
175
+ - Python 3.10+
176
+ - Node.js (for esbuild bundling)
177
+ - React 18+ on the frontend
178
+
179
+ ## About the Name
180
+
181
+ Named after **Roger Wilco**, the janitor-turned-hero from Sierra's *Space Quest* series. Roger stumbles into saving the galaxy while just trying to do his job. Like its namesake, this framework gets the job done despite the chaos—bridging Python backends with React frontends through dynamic bundling magic.
182
+
183
+ ## License
184
+
185
+ MIT
wilco-0.1.2/Procfile ADDED
@@ -0,0 +1,2 @@
1
+ backend: uv run python -m wilco
2
+ frontend: cd src/wilcojs/react && pnpm dev
wilco-0.1.2/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # wilco
2
+
3
+ **Server-defined React components for Python backends.**
4
+
5
+ Wilco lets you define React components alongside your Python code and serve them dynamically to any frontend. Components are bundled on-demand with esbuild and loaded at runtime—no build step required for your component library.
6
+
7
+ ## Why wilco?
8
+
9
+ - **Co-locate components with backend logic**: Keep your UI components next to the Python code that powers them
10
+ - **No frontend build pipeline**: Components are bundled on-the-fly when requested
11
+ - **Full source map support**: Debug your TypeScript directly in browser devtools
12
+ - **Component composition**: Components can dynamically load other components
13
+ - **Framework agnostic**: Mount the API router in any FastAPI (or compatible) app
14
+
15
+ ## Quick Start
16
+
17
+ ### Installation
18
+
19
+ ```bash
20
+ pip install wilco
21
+ ```
22
+
23
+ ### Create a component
24
+
25
+ ```
26
+ my_components/
27
+ └── greeting/
28
+ ├── __init__.py
29
+ ├── index.tsx
30
+ └── schema.json
31
+ ```
32
+
33
+ ```tsx
34
+ // index.tsx
35
+ interface GreetingProps {
36
+ name: string;
37
+ formal?: boolean;
38
+ }
39
+
40
+ export default function Greeting({ name, formal = false }: GreetingProps) {
41
+ const message = formal ? `Good day, ${name}.` : `Hey ${name}!`;
42
+ return <p>{message}</p>;
43
+ }
44
+ ```
45
+
46
+ ```json
47
+ {
48
+ "title": "Greeting",
49
+ "description": "A friendly greeting component",
50
+ "type": "object",
51
+ "properties": {
52
+ "name": { "type": "string" },
53
+ "formal": { "type": "boolean", "default": false }
54
+ },
55
+ "required": ["name"]
56
+ }
57
+ ```
58
+
59
+ ### Mount the API
60
+
61
+ ```python
62
+ from pathlib import Path
63
+ from fastapi import FastAPI
64
+ from wilco import ComponentRegistry
65
+ from wilco.bridges.fastapi import create_router
66
+
67
+ app = FastAPI()
68
+ registry = ComponentRegistry(Path("./my_components"))
69
+ app.include_router(create_router(registry), prefix="/api")
70
+ ```
71
+
72
+ ### Load components in React
73
+
74
+ ```tsx
75
+ import { useComponent } from '@wilcojs/react';
76
+
77
+ function App() {
78
+ const Greeting = useComponent('greeting');
79
+ return <Greeting name="World" />;
80
+ }
81
+ ```
82
+
83
+ ## API Endpoints
84
+
85
+ | Endpoint | Description |
86
+ |----------|-------------|
87
+ | `GET /api/bundles` | List available components |
88
+ | `GET /api/bundles/{name}.js` | Get bundled JavaScript |
89
+ | `GET /api/bundles/{name}/metadata` | Get component metadata |
90
+
91
+ ## Component Structure
92
+
93
+ Each component is a Python package with:
94
+
95
+ | File | Required | Description |
96
+ |------|----------|-------------|
97
+ | `__init__.py` | Yes | Package marker |
98
+ | `index.tsx` | Yes | React component (default export) |
99
+ | `schema.json` | No | Props schema and metadata |
100
+
101
+ Components can include additional `.tsx` files—they're all bundled together.
102
+
103
+ ## Component Composition
104
+
105
+ Components can load other components dynamically:
106
+
107
+ ```tsx
108
+ import { useComponent } from '@wilcojs/react';
109
+
110
+ export default function Dashboard() {
111
+ const Chart = useComponent('chart');
112
+ const Table = useComponent('table');
113
+
114
+ return (
115
+ <div>
116
+ <Chart data={...} />
117
+ <Table rows={...} />
118
+ </div>
119
+ );
120
+ }
121
+ ```
122
+
123
+ ## Development Server
124
+
125
+ Run the built-in development server to preview components:
126
+
127
+ ```bash
128
+ uv run python -m wilco
129
+ ```
130
+
131
+ Then start the frontend:
132
+
133
+ ```bash
134
+ cd src/wilcojs/react && pnpm dev
135
+ ```
136
+
137
+ Open http://localhost:5173 to browse and test your components.
138
+
139
+ ## Requirements
140
+
141
+ - Python 3.10+
142
+ - Node.js (for esbuild bundling)
143
+ - React 18+ on the frontend
144
+
145
+ ## About the Name
146
+
147
+ Named after **Roger Wilco**, the janitor-turned-hero from Sierra's *Space Quest* series. Roger stumbles into saving the galaxy while just trying to do his job. Like its namesake, this framework gets the job done despite the chaos—bridging Python backends with React frontends through dynamic bundling magic.
148
+
149
+ ## License
150
+
151
+ MIT