A project is only ever at /p/<id>/<slug>; / is the index of the projects
you own or edit. Every project has an owner, who can name editors;
anyone with the link can view. Every edit saves itself, one request in
flight at a time, as a patch of the leaves that changed, and a websocket
(channels + daphne) carries presence and each committed write to
everyone else in the project. The first write to a leaf wins, and the
loser is told.
Undo is per person: a step undoes only if the leaves it touched still
hold what it left, so it never takes a collaborator's work with it.
Named snapshots replace saving, and restore as an ordinary write.
An empty symbol now survives the leaf round trip with `:nodes {}`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
853 B
Python
25 lines
853 B
Python
"""ASGI entry point.
|
|
|
|
HTTP is Django as usual. The websocket carries presence and the document deltas
|
|
the server broadcasts after a write — never writes, which stay on HTTP. See
|
|
docs/architecture.md, Collaboration.
|
|
"""
|
|
import os
|
|
|
|
from django.core.asgi import get_asgi_application
|
|
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
|
|
django_asgi_app = get_asgi_application()
|
|
|
|
from channels.auth import AuthMiddlewareStack # noqa: E402
|
|
from channels.routing import ProtocolTypeRouter, URLRouter # noqa: E402
|
|
from channels.security.websocket import AllowedHostsOriginValidator # noqa: E402
|
|
|
|
from clips.routing import websocket_urlpatterns # noqa: E402
|
|
|
|
application = ProtocolTypeRouter({
|
|
"http": django_asgi_app,
|
|
"websocket": AllowedHostsOriginValidator(
|
|
AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
|
|
),
|
|
})
|