feat: add NovelPage component with bookshelf, open book, and reading views
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
"""
|
||||
事件纲要生成进度广播 — 供 NDJSON 订阅端与后台流水线共享。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import Any, AsyncIterator, Dict, List
|
||||
|
||||
_subscribers: Dict[str, List[asyncio.Queue]] = {}
|
||||
|
||||
|
||||
def emit(book_id: str, event: Dict[str, Any]) -> None:
|
||||
for q in list(_subscribers.get(book_id, [])):
|
||||
try:
|
||||
q.put_nowait(event)
|
||||
except asyncio.QueueFull:
|
||||
pass
|
||||
|
||||
|
||||
async def subscribe(book_id: str) -> AsyncIterator[Dict[str, Any]]:
|
||||
q: asyncio.Queue = asyncio.Queue(maxsize=128)
|
||||
_subscribers.setdefault(book_id, []).append(q)
|
||||
try:
|
||||
while True:
|
||||
item = await q.get()
|
||||
yield item
|
||||
if item.get("type") in ("done", "error"):
|
||||
break
|
||||
finally:
|
||||
subs = _subscribers.get(book_id, [])
|
||||
if q in subs:
|
||||
subs.remove(q)
|
||||
if not subs:
|
||||
_subscribers.pop(book_id, None)
|
||||
Reference in New Issue
Block a user