Releases: edelvalle/reactor
Releases · edelvalle/reactor
Better test support
Breaking changes in how to test components, for better
Using async with reactor() as comm
, you get an object that you can use to register components, send commands... doc
is a PyQuery object containing the HTML rendering of the object, so you can perform checkings of the rendering of the object.
from pytest import mark
from channels.db import database_sync_to_async as db
from reactor.tests import reactor
@mark.django_db(transaction=True)
async def test_live_components():
x_list = comm.add_component(
'x-todo-list',
{'id': 'someid', 'showing': 'all'}
)
x_todo_counter = comm.add_component(
'x-todo-counter',
{'id': 'someid-counter'}
)
doc = await comm.send_join(x_list)
todo_list = doc('#someid')
assert json.loads(todo_list.attr['state']) == comm[x_list].state
# Add new item
doc = await comm.send(x_list, 'add', new_item='First task')
# There was an item crated and rendered
assert await db(Item.objects.count)() == 1
assert len(doc('x-todo-item')) == 1
todo_item_id = doc('x-todo-item')[0].get('id')
todo_item_label = doc('x-todo-item label')[0]
assert todo_item_label.text == 'First task'
Add support for push state
Added:
Component.send_redirect
has a new parameterpush_state=True
, when set it will do a push state in the front-end.- In the front-end you can use
push_state(url)
to trigger this in the front-end.
Version 1
Changed
- Rename
reactor.component.send_to_group
toreactor.broadcast
- Open the reactor channel after all HTML5 elements are created.
- Improve reconnect timing logic.
- When an event is sent to the back-end and the event originates from a form or inside of it, just the form data is serialized and sent to the back-end.
Added
- Django settings
REACTOR_AUTO_BROADCAST = True
will trigger broadcast updates when models instances are manipulated. - Add a component for authenticated user only and staff component:
AuthComponent
andStaffComponent
- Add
debounce
function to send events to the backend. - Add directive
reactor-once
when an element is market with it, it will not be updated. - Add
ReactorChannel.reconnect
, closes the connection and reopens it. - Add
public
parameter to class inheritance, so you can decide if the element is exposed or not.
Redirects and DB transactions
Changes
Breaking changes:
- Now the dispatching of incoming events from the front-end are not
atomic
transactions. You will have to put@atomic
when you want something to be atomic. The reason for this is that some events don't have to deal at all with the database because they just change the local state of the component.
Added:
reactor.broadcast(*names)
: this broadcasts the messages that you can subscribe to usingComponent.subscribe()
.Component.send_redirect(url)
: now you can send a URL redirect to the front-end, when the component is being rendered for first time the redirect is rendered as a<meta http-equiv="refresh" content="0; url={{ url }}">
, if the component is alive then the front-end controller executes the redirect.AuthComponent
, this component has auser
attributed taken from theComponent._context
and onmount
if the user is authenticated returns the True, if the user is not returnsNone
and sends a redirect tosettings.LOGIN_URL
.- Serialization of arrays in the front-end, in case you have:
<input name="query" value="q">
<input name="persons[].name" value="a">
<input name="persons[].name" value="b">
This will be serialized as: {query: "q", persons: [{name: "a"}, {name: "b"}]}
Room for improvement:
- Proper documentation.
- More testing.
0.2.1b0
- Adds to component component
send_redirect(url)
. Example:
def receive_save(self, name, **kwargs):
self.instance.name = name
self.instance.save()
self.send_redirect(self.instance.get_absolute_url())
- Components are now based on
div
and this can be redefined by the user overwriting theextends
attribute. Example:
class MySpecialInput(Component):
extends = 'input'