Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flaxon_fyr-0.1.0.tar.gz (24.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flaxon_fyr-0.1.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

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

Hashes for flaxon_fyr-0.1.0.tar.gz
Algorithm Hash digest
SHA256 31f331eab1ce29e5de88c010f7318a56eb2049776a896cf7785483584df1ed44
MD5 9ed9bba81a981e97346d84b3007412a1
BLAKE2b-256 4b29c3560bf92dd20281b70b35859c2e29a13d9ad2ed052eb874ae40c6c61664

See more details on using hashes here.

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

Hashes for flaxon_fyr-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8c75876d0b5f39b940ce3887ebc7d6940d75f075c24131ca7d9b2773b4613c0c
MD5 80a74f927e6c8c86388e439743104c69
BLAKE2b-256 2737aac07535cdeaad70508c867b22278ca4a5c23580c54c6a93e21b2a8e895a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page