mirror of
https://github.com/SteamFramelyHomebrew/framely.git
synced 2026-10-19 00:01:39 +02:00
49 lines
2.0 KiB
Python
49 lines
2.0 KiB
Python
"""Framely backend protocol and lifecycle callbacks (Python 3, no dependencies)."""
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
def emit(event, data):
|
|
print(json.dumps({"event": event, "data": data}), flush=True)
|
|
|
|
def serve(dispatch, lifecycle=None, visibility=None):
|
|
"""dispatch(method, params); lifecycle maps onInstall/onStart/... to callbacks.
|
|
|
|
Independent hooks receive FRAMELY_LIFECYCLE_CONTEXT and exit once completed.
|
|
Normal backend hooks are manager-only reserved protocol messages.
|
|
visibility(snapshot) receives framely.ui.visibility when opted in via manifest.
|
|
"""
|
|
lifecycle = lifecycle or {}
|
|
phase = os.environ.get("FRAMELY_LIFECYCLE")
|
|
if phase:
|
|
try:
|
|
callback = lifecycle.get(phase)
|
|
if callback is None:
|
|
raise ValueError("Lifecycle callback not registered: " + phase)
|
|
callback(json.loads(os.environ["FRAMELY_LIFECYCLE_CONTEXT"]))
|
|
except Exception as error:
|
|
print(str(error), file=sys.stderr)
|
|
raise SystemExit(1)
|
|
return
|
|
for line in sys.stdin:
|
|
request = {}
|
|
try:
|
|
if len(line.encode()) > 65536:
|
|
raise ValueError("Backend request too large")
|
|
request = json.loads(line)
|
|
method = request["method"]
|
|
params = request.get("params") or {}
|
|
if method.startswith("framely.lifecycle."):
|
|
phase = {"framely.lifecycle.start": "onStart", "framely.lifecycle.stop": "onStop"}.get(method)
|
|
if phase not in lifecycle:
|
|
raise ValueError("Lifecycle callback not registered")
|
|
result = lifecycle[phase](params)
|
|
elif method == "framely.ui.visibility" and visibility is not None:
|
|
result = visibility(params)
|
|
else:
|
|
result = dispatch(method, params)
|
|
response = {"id": request["id"], "result": result}
|
|
except Exception as error:
|
|
response = {"id": request.get("id"), "error": str(error)}
|
|
print(json.dumps(response), flush=True)
|