|
25 | 25 | from werkzeug.serving import BaseWSGIServer, make_server
|
26 | 26 |
|
27 | 27 | import idom
|
28 |
| -from idom.backend.types import Location |
29 |
| -from idom.core.hooks import Context, create_context, use_context |
| 28 | +from idom.backend.hooks import ConnectionContext |
| 29 | +from idom.backend.hooks import use_connection as _use_connection |
| 30 | +from idom.backend.types import Connection, Location |
30 | 31 | from idom.core.layout import LayoutEvent, LayoutUpdate
|
31 | 32 | from idom.core.serve import serve_json_patch
|
32 | 33 | from idom.core.types import ComponentType, RootComponentConstructor
|
|
37 | 38 |
|
38 | 39 | logger = logging.getLogger(__name__)
|
39 | 40 |
|
40 |
| -ConnectionContext: Context[Connection | None] = create_context(None) |
41 |
| - |
42 | 41 |
|
43 | 42 | def configure(
|
44 | 43 | app: Flask, component: RootComponentConstructor, options: Options | None = None
|
@@ -107,45 +106,25 @@ def run_server() -> None:
|
107 | 106 | raise RuntimeError("Failed to shutdown server.")
|
108 | 107 |
|
109 | 108 |
|
110 |
| -def use_location() -> Location: |
111 |
| - """Get the current route as a string""" |
112 |
| - conn = use_connection() |
113 |
| - search = conn.request.query_string.decode() |
114 |
| - return Location(pathname="/" + conn.path, search="?" + search if search else "") |
115 |
| - |
116 |
| - |
117 |
| -def use_scope() -> dict[str, Any]: |
118 |
| - """Get the current WSGI environment""" |
119 |
| - return use_request().environ |
| 109 | +def use_websocket() -> WebSocket: |
| 110 | + """A handle to the current websocket""" |
| 111 | + return use_connection().carrier.websocket |
120 | 112 |
|
121 | 113 |
|
122 | 114 | def use_request() -> Request:
|
123 | 115 | """Get the current ``Request``"""
|
124 |
| - return use_connection().request |
| 116 | + return use_connection().carrier.request |
125 | 117 |
|
126 | 118 |
|
127 |
| -def use_connection() -> Connection: |
| 119 | +def use_connection() -> Connection[_FlaskCarrier]: |
128 | 120 | """Get the current :class:`Connection`"""
|
129 |
| - connection = use_context(ConnectionContext) |
130 |
| - if connection is None: |
131 |
| - raise RuntimeError( # pragma: no cover |
132 |
| - "No connection. Are you running with a Flask server?" |
| 121 | + conn = _use_connection() |
| 122 | + if not isinstance(conn.carrier, _FlaskCarrier): |
| 123 | + raise TypeError( # pragma: no cover |
| 124 | + f"Connection has unexpected carrier {conn.carrier}. " |
| 125 | + "Are you running with a Flask server?" |
133 | 126 | )
|
134 |
| - return connection |
135 |
| - |
136 |
| - |
137 |
| -@dataclass |
138 |
| -class Connection: |
139 |
| - """A simple wrapper for holding connection information""" |
140 |
| - |
141 |
| - request: Request |
142 |
| - """The current request object""" |
143 |
| - |
144 |
| - websocket: WebSocket |
145 |
| - """A handle to the current websocket""" |
146 |
| - |
147 |
| - path: str |
148 |
| - """The current path being served""" |
| 127 | + return conn |
149 | 128 |
|
150 | 129 |
|
151 | 130 | @dataclass
|
@@ -230,11 +209,20 @@ async def recv_coro() -> Any:
|
230 | 209 | return await async_recv_queue.get()
|
231 | 210 |
|
232 | 211 | async def main() -> None:
|
| 212 | + search = request.query_string.decode() |
233 | 213 | await serve_json_patch(
|
234 | 214 | idom.Layout(
|
235 | 215 | ConnectionContext(
|
236 |
| - component, value=Connection(request, websocket, path) |
237 |
| - ) |
| 216 | + component, |
| 217 | + value=Connection( |
| 218 | + scope=request.environ, |
| 219 | + location=Location( |
| 220 | + pathname=f"/{path}", |
| 221 | + search=f"?{search}" if search else "", |
| 222 | + ), |
| 223 | + carrier=_FlaskCarrier(request, websocket), |
| 224 | + ), |
| 225 | + ), |
238 | 226 | ),
|
239 | 227 | send_coro,
|
240 | 228 | recv_coro,
|
@@ -283,3 +271,14 @@ class _DispatcherThreadInfo(NamedTuple):
|
283 | 271 | dispatch_future: "asyncio.Future[Any]"
|
284 | 272 | thread_send_queue: "ThreadQueue[LayoutUpdate]"
|
285 | 273 | async_recv_queue: "AsyncQueue[LayoutEvent]"
|
| 274 | + |
| 275 | + |
| 276 | +@dataclass |
| 277 | +class _FlaskCarrier: |
| 278 | + """A simple wrapper for holding a Flask request and WebSocket""" |
| 279 | + |
| 280 | + request: Request |
| 281 | + """The current request object""" |
| 282 | + |
| 283 | + websocket: WebSocket |
| 284 | + """A handle to the current websocket""" |
0 commit comments