Fyr.js reactive frontend integration plugin for Flaxon framework
Project description
Flaxon Fyr.js
Fyr.js reactive frontend integration plugin for Flaxon framework.
What is Fyr.js?
Fyr.js is a CDN-only, HTML-first reactive JavaScript framework. It lets you build interactive web applications without installing Node.js, npm, or any build tools. Just add a script tag and use HTML directives.
Website: https://fyrjsorg.vercel.app/
Features
- ๐ CDN-only โ No installation required, just script tags
- ๐ฆ Reactive state โ Automatic DOM updates when state changes
- ๐ฏ Server actions โ Call backend endpoints with Fyr.action
- ๐ State hydration โ Pass server data to Fyr frontend
- ๐ก๏ธ CSRF protection โ Built-in CSRF for actions
- ๐ Plugin integration โ Seamless Flaxon plugin loading
- ๐ Template rendering โ Render Fyr HTML with Jinja2
- ๐จ Flexible assets โ CDN or local asset serving
Installation
pip install flaxon-fyr
Quick Start
1. Load the Plugin
python
from flaxon import Flaxon
from flaxon_fyr import FyrPlugin, fyr_app
app = Flaxon("my-app")
app.plugins.load_plugin(FyrPlugin(
cdn_version="0.1.2",
))
2. Create a Route with Fyr App
python
@app.get("/")
async def home(request):
return fyr_app(
"counter",
state={"count": 0},
template="templates/counter.html"
)
3. Define Fyr Controller (JavaScript)
javascript
// app.js
Fyr.createApp("counter", {
state: { count: 0 },
methods: {
increment() {
this.state.count += 1;
},
decrement() {
this.state.count -= 1;
}
}
});
Fyr.start("counter");
4. HTML Template
html
<!-- templates/counter.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Counter</title>
<script defer src="{{ fyr_cdn_url }}"></script>
<script defer src="/app.js"></script>
</head>
<body>
<main fyr-app="counter">
<h1>Counter: <span fyr-text="count"></span></h1>
<button fyr-click="increment()">+</button>
<button fyr-click="decrement()">-</button>
</main>
</body>
</html>
Server Actions
Define backend actions that Fyr can call:
python
from flaxon_fyr import fyr_action
@fyr_action("todos.create")
async def create_todo(data, request):
todo = await create_todo_in_db(data["text"])
return {"success": True, "data": todo}
@fyr_action("todos.list")
async def list_todos(request):
todos = await get_all_todos()
return {"data": todos}
Call from frontend:
javascript
const result = await Fyr.action.call("todos.create", { text: "Learn Fyr" });
if (result.success) {
console.log(result.data);
}
Configuration
Environment Variables
bash
# Fyr CDN version
FYR_CDN_VERSION=0.1.2
# Action prefix
FYR_ACTION_PREFIX=/_fyr/actions
# CSRF enabled
FYR_CSRF_ENABLED=true
# Use local assets
FYR_USE_LOCAL_ASSETS=false
# Debug mode
FYR_DEBUG=false
With Flaxon Config
python
app = Flaxon("my-app", config={
"FYR_CDN_VERSION": "0.1.2",
"FYR_ACTION_PREFIX": "/api/actions",
"FYR_CSRF_ENABLED": True,
})
plugin = FyrPlugin.from_config(app.config)
app.plugins.load_plugin(plugin)
Advanced Usage
State Hydration
Pass server data to Fyr frontend:
python
from flaxon_fyr import hydrate
@app.get("/dashboard")
async def dashboard(request):
user = await get_current_user(request)
tasks = await get_user_tasks(user.id)
state = hydrate({
"user": {"id": user.id, "name": user.name},
"tasks": [{"id": t.id, "text": t.text, "done": t.done} for t in tasks],
"flash": request.session.pop("flash", {}),
})
return fyr_app("dashboard", state)
Custom Templates
python
@app.get("/custom")
async def custom(request):
return fyr_app(
"custom-app",
state={"message": "Hello from server!"},
template="templates/custom.html",
context={
"page_title": "Custom Page",
"user": request.session.get("user"),
}
)
Multiple Fyr Apps
python
@app.get("/multi")
async def multi_apps(request):
return fyr_app(
"multi",
state={
"counter": {"count": 0},
"todo": {"items": [], "draft": ""},
}
)
html
<main fyr-app="multi">
<section>
<h2>Counter</h2>
<span fyr-text="counter.count"></span>
<button fyr-click="counter.count++">+</button>
</section>
<section>
<h2>Todo</h2>
<input fyr-model="todo.draft">
<button fyr-click="todo.items.push({id: Date.now(), text: todo.draft})">
Add
</button>
<template fyr-for="item in todo.items" fyr-key="item.id">
<p fyr-text="item.text"></p>
</template>
</section>
</main>
CSRF Protection
python
# Enabled by default
app.plugins.load_plugin(FyrPlugin(
csrf_enabled=True,
csrf_cookie_name="csrf_token",
csrf_header_name="X-CSRFToken",
))
# Disable for development
app.plugins.load_plugin(FyrPlugin(
csrf_enabled=False,
))
Local Asset Serving
python
# Serve Fyr assets from local static directory
app.plugins.load_plugin(FyrPlugin(
use_local_assets=True,
assets_path="static/fyr",
))
# The plugin will serve:
# /fyr/assets/fyr.js
# /fyr/assets/fyr.min.js
# /fyr/assets/fyr-python.js
# etc.
Fyr CDN Assets
Asset URL
Core https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr.min.js
ESM https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr.esm.js
Router https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-router.min.js
Python https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-python.min.js
WASM https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-wasm.min.js
Socket https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-socket.min.js
UI https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-ui.min.js
UI CSS https://cdn.jsdelivr.net/npm/@aldane-dev-create/fyr@0.1.2/dist/fyr-ui.css
Testing
bash
# Run all tests
pytest
# Run with coverage
pytest --cov=flaxon_fyr
# Run specific test
pytest tests/test_actions.py -v
Project Structure
text
flaxon-fyr/
โโโ pyproject.toml
โโโ README.md
โโโ LICENSE
โโโ src/
โ โโโ flaxon_fyr/
โ โโโ __init__.py # Public API exports
โ โโโ plugin.py # FyrPlugin class
โ โโโ renderer.py # Fyr template rendering
โ โโโ actions.py # Server action handler
โ โโโ assets.py # Asset serving (CDN/local)
โ โโโ hydration.py # Server-to-client state hydration
โ โโโ middleware.py # Fyr middleware (CSRF, etc.)
โ โโโ types.py # Type definitions
โโโ tests/
โโโ test_plugin.py
โโโ test_renderer.py
โโโ test_actions.py
โโโ test_integration.py
Security Best Practices
โ
Use CSRF protection in production
โ
Validate all action inputs on server
โ
Authenticate actions with session
โ
Use HTTPS in production
โ
Keep Fyr version pinned
โ
Use Subresource Integrity for CDN assets
โ
Sanitize data passed to fyr-html
โ
Never put secrets in frontend code
Fyr Directives Reference
Directive Purpose Example
fyr-app Mark application root fyr-app="todo"
fyr-controller Attach state and methods fyr-controller="cart"
fyr-text Render escaped text fyr-text="user.name"
fyr-html Render trusted HTML fyr-html="trustedContent"
fyr-model Two-way form binding fyr-model="form.email"
fyr-click Handle click fyr-click="save()"
fyr-on:event Handle any event fyr-on:input="search()"
fyr-show Toggle visibility fyr-show="loggedIn"
fyr-if Create/remove content fyr-if="items.length"
fyr-for Repeat template fyr-for="item in items"
fyr-submit Handle form submit fyr-submit="login()"
fyr-bind:* Bind attribute/property fyr-bind:disabled="busy"
fyr-class Bind CSS classes fyr-class="{ active: selected }"
fyr-style Bind styles fyr-style="{ width: progress + '%' }"
fyr-ref Store DOM reference fyr-ref="emailInput"
fyr-init Run startup method fyr-init="load()"
fyr-cloak Hide before initialization fyr-cloak
fyr-transition Apply transition hooks fyr-transition="fade"
Roadmap
Version Features
0.1.0 Basic Fyr integration, CDN serving
0.2.0 Server actions with CSRF
0.3.0 State hydration and session integration
0.4.0 Component rendering
0.5.0 Asset serving (local)
0.6.0 Fyr router integration
Related Plugins
flaxon-jinax - Jinja2 template integration
flaxon-sentry - Sentry error tracking
flaxon-oauth-google - Google OAuth
flaxon-inertia - Inertia.js integration
Contributing
Fork the repository
Create a feature branch
Add tests for new features
Ensure all tests pass
Submit a pull request
License
MIT License - See LICENSE file for details.
Support
๐ Documentation
๐ Issue Tracker
๐ฌ Discussions
๐ Fyr.js Website
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flaxon_fyr-0.1.0.tar.gz.
File metadata
- Download URL: flaxon_fyr-0.1.0.tar.gz
- Upload date:
- Size: 24.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31f331eab1ce29e5de88c010f7318a56eb2049776a896cf7785483584df1ed44
|
|
| MD5 |
9ed9bba81a981e97346d84b3007412a1
|
|
| BLAKE2b-256 |
4b29c3560bf92dd20281b70b35859c2e29a13d9ad2ed052eb874ae40c6c61664
|
File details
Details for the file flaxon_fyr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: flaxon_fyr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c75876d0b5f39b940ce3887ebc7d6940d75f075c24131ca7d9b2773b4613c0c
|
|
| MD5 |
80a74f927e6c8c86388e439743104c69
|
|
| BLAKE2b-256 |
2737aac07535cdeaad70508c867b22278ca4a5c23580c54c6a93e21b2a8e895a
|