Collapse signal platform primitives into pure SX dicts
Replace _Signal class (Python) and SxSignal constructor (JS) with plain dicts keyed by "__signal". Nine platform accessor functions become ~20 lines of pure SX in signals.sx. type-of returns "dict" for signals; signal? is now a structural predicate (dict? + has-key?). Net: -168 lines platform, +120 lines SX. Zero platform primitives for reactivity — signals compile to any host via the bootstrappers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -184,8 +184,6 @@ def type_of(x):
|
||||
return "component"
|
||||
if isinstance(x, Island):
|
||||
return "island"
|
||||
if isinstance(x, _Signal):
|
||||
return "signal"
|
||||
if isinstance(x, _Spread):
|
||||
return "spread"
|
||||
if isinstance(x, Macro):
|
||||
@@ -427,58 +425,6 @@ def is_identical(a, b):
|
||||
return a is b
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Signal platform -- reactive state primitives
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
class _Signal:
|
||||
"""Reactive signal container."""
|
||||
__slots__ = ("value", "subscribers", "deps")
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
self.subscribers = []
|
||||
self.deps = []
|
||||
|
||||
|
||||
def make_signal(value):
|
||||
return _Signal(value)
|
||||
|
||||
|
||||
def is_signal(x):
|
||||
return isinstance(x, _Signal)
|
||||
|
||||
|
||||
def signal_value(s):
|
||||
return s.value if isinstance(s, _Signal) else s
|
||||
|
||||
|
||||
def signal_set_value(s, v):
|
||||
if isinstance(s, _Signal):
|
||||
s.value = v
|
||||
|
||||
|
||||
def signal_subscribers(s):
|
||||
return list(s.subscribers) if isinstance(s, _Signal) else []
|
||||
|
||||
|
||||
def signal_add_sub(s, fn):
|
||||
if isinstance(s, _Signal) and fn not in s.subscribers:
|
||||
s.subscribers.append(fn)
|
||||
|
||||
|
||||
def signal_remove_sub(s, fn):
|
||||
if isinstance(s, _Signal) and fn in s.subscribers:
|
||||
s.subscribers.remove(fn)
|
||||
|
||||
|
||||
def signal_deps(s):
|
||||
return list(s.deps) if isinstance(s, _Signal) else []
|
||||
|
||||
|
||||
def signal_set_deps(s, deps):
|
||||
if isinstance(s, _Signal):
|
||||
s.deps = list(deps) if isinstance(deps, list) else []
|
||||
|
||||
|
||||
def invoke(f, *args):
|
||||
"""Call f with args — handles both native callables and SX lambdas.
|
||||
@@ -1037,6 +983,7 @@ replace = PRIMITIVES["replace"]
|
||||
parse_int = PRIMITIVES["parse-int"]
|
||||
upper = PRIMITIVES["upper"]
|
||||
has_key_p = PRIMITIVES["has-key?"]
|
||||
dict_p = PRIMITIVES["dict?"]
|
||||
dissoc = PRIMITIVES["dissoc"]
|
||||
index_of = PRIMITIVES["index-of"]
|
||||
|
||||
@@ -3456,6 +3403,44 @@ def prepare_url_expr(url_path, env):
|
||||
|
||||
# === Transpiled from signals (reactive signal runtime) ===
|
||||
|
||||
# make-signal
|
||||
def make_signal(value):
|
||||
return {'__signal': True, 'value': value, 'subscribers': [], 'deps': []}
|
||||
|
||||
# signal?
|
||||
def is_signal(x):
|
||||
return (dict_p(x) if not sx_truthy(dict_p(x)) else has_key_p(x, '__signal'))
|
||||
|
||||
# signal-value
|
||||
def signal_value(s):
|
||||
return get(s, 'value')
|
||||
|
||||
# signal-set-value!
|
||||
def signal_set_value(s, v):
|
||||
return _sx_dict_set(s, 'value', v)
|
||||
|
||||
# signal-subscribers
|
||||
def signal_subscribers(s):
|
||||
return get(s, 'subscribers')
|
||||
|
||||
# signal-add-sub!
|
||||
def signal_add_sub(s, f):
|
||||
if sx_truthy((not sx_truthy(contains_p(get(s, 'subscribers'), f)))):
|
||||
return _sx_append(get(s, 'subscribers'), f)
|
||||
return NIL
|
||||
|
||||
# signal-remove-sub!
|
||||
def signal_remove_sub(s, f):
|
||||
return _sx_dict_set(s, 'subscribers', filter(lambda sub: (not sx_truthy(is_identical(sub, f))), get(s, 'subscribers')))
|
||||
|
||||
# signal-deps
|
||||
def signal_deps(s):
|
||||
return get(s, 'deps')
|
||||
|
||||
# signal-set-deps!
|
||||
def signal_set_deps(s, deps):
|
||||
return _sx_dict_set(s, 'deps', deps)
|
||||
|
||||
# signal
|
||||
def signal(initial_value):
|
||||
return make_signal(initial_value)
|
||||
|
||||
Reference in New Issue
Block a user