graphrefly 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. graphrefly/__init__.py +160 -0
  2. graphrefly/compat/__init__.py +18 -0
  3. graphrefly/compat/async_utils.py +228 -0
  4. graphrefly/compat/asyncio_runner.py +89 -0
  5. graphrefly/compat/trio_runner.py +81 -0
  6. graphrefly/core/__init__.py +142 -0
  7. graphrefly/core/clock.py +20 -0
  8. graphrefly/core/dynamic_node.py +749 -0
  9. graphrefly/core/guard.py +277 -0
  10. graphrefly/core/meta.py +149 -0
  11. graphrefly/core/node.py +963 -0
  12. graphrefly/core/protocol.py +460 -0
  13. graphrefly/core/runner.py +107 -0
  14. graphrefly/core/subgraph_locks.py +296 -0
  15. graphrefly/core/sugar.py +138 -0
  16. graphrefly/core/versioning.py +193 -0
  17. graphrefly/extra/__init__.py +313 -0
  18. graphrefly/extra/adapters.py +2149 -0
  19. graphrefly/extra/backoff.py +287 -0
  20. graphrefly/extra/backpressure.py +113 -0
  21. graphrefly/extra/checkpoint.py +307 -0
  22. graphrefly/extra/composite.py +303 -0
  23. graphrefly/extra/cron.py +133 -0
  24. graphrefly/extra/data_structures.py +707 -0
  25. graphrefly/extra/resilience.py +727 -0
  26. graphrefly/extra/sources.py +766 -0
  27. graphrefly/extra/tier1.py +1067 -0
  28. graphrefly/extra/tier2.py +1802 -0
  29. graphrefly/graph/__init__.py +31 -0
  30. graphrefly/graph/graph.py +2249 -0
  31. graphrefly/integrations/__init__.py +1 -0
  32. graphrefly/integrations/fastapi.py +767 -0
  33. graphrefly/patterns/__init__.py +5 -0
  34. graphrefly/patterns/ai.py +2132 -0
  35. graphrefly/patterns/cqrs.py +515 -0
  36. graphrefly/patterns/memory.py +639 -0
  37. graphrefly/patterns/messaging.py +553 -0
  38. graphrefly/patterns/orchestration.py +536 -0
  39. graphrefly/patterns/reactive_layout/__init__.py +81 -0
  40. graphrefly/patterns/reactive_layout/measurement_adapters.py +276 -0
  41. graphrefly/patterns/reactive_layout/reactive_block_layout.py +434 -0
  42. graphrefly/patterns/reactive_layout/reactive_layout.py +943 -0
  43. graphrefly/py.typed +1 -0
  44. graphrefly-0.1.0.dist-info/METADATA +253 -0
  45. graphrefly-0.1.0.dist-info/RECORD +47 -0
  46. graphrefly-0.1.0.dist-info/WHEEL +4 -0
  47. graphrefly-0.1.0.dist-info/licenses/LICENSE +21 -0
graphrefly/__init__.py ADDED
@@ -0,0 +1,160 @@
1
+ """graphrefly — Reactive graph protocol for human and LLM co-operation."""
2
+
3
+ from graphrefly import compat, integrations, patterns
4
+ from graphrefly.core import (
5
+ V0,
6
+ V1,
7
+ Actor,
8
+ DeferWhen,
9
+ DynamicNodeImpl,
10
+ EmitStrategy,
11
+ GuardAction,
12
+ GuardDenied,
13
+ GuardFn,
14
+ HashFn,
15
+ Message,
16
+ Messages,
17
+ MessageType,
18
+ Node,
19
+ NodeActions,
20
+ NodeFn,
21
+ NodeImpl,
22
+ NodeStatus,
23
+ NodeVersionInfo,
24
+ PipeOperator,
25
+ Runner,
26
+ SubscribeHints,
27
+ VersioningLevel,
28
+ access_hint_for_guard,
29
+ acquire_subgraph_write_lock,
30
+ acquire_subgraph_write_lock_with_defer,
31
+ advance_version,
32
+ batch,
33
+ compose_guards,
34
+ create_versioning,
35
+ default_hash,
36
+ defer_down,
37
+ defer_set,
38
+ derived,
39
+ describe_node,
40
+ dispatch_messages,
41
+ dynamic_node,
42
+ effect,
43
+ emit_with_batch,
44
+ ensure_registered,
45
+ get_default_runner,
46
+ is_batching,
47
+ is_phase2_message,
48
+ is_v1,
49
+ meta_snapshot,
50
+ monotonic_ns,
51
+ node,
52
+ normalize_actor,
53
+ partition_for_batch,
54
+ pipe,
55
+ policy,
56
+ policy_from_rules,
57
+ producer,
58
+ record_mutation,
59
+ resolve_runner,
60
+ set_default_runner,
61
+ state,
62
+ system_actor,
63
+ union_nodes,
64
+ wall_clock_ns,
65
+ )
66
+ from graphrefly.graph import (
67
+ GRAPH_META_SEGMENT,
68
+ GRAPH_SNAPSHOT_VERSION,
69
+ META_PATH_SEG,
70
+ PATH_SEP,
71
+ Graph,
72
+ GraphAutoCheckpointHandle,
73
+ GraphDiffResult,
74
+ GraphObserveSource,
75
+ ObserveResult,
76
+ SpyHandle,
77
+ TraceEntry,
78
+ reachable,
79
+ )
80
+
81
+ __version__ = "0.1.0"
82
+
83
+ __all__ = [
84
+ "GRAPH_META_SEGMENT",
85
+ "GRAPH_SNAPSHOT_VERSION",
86
+ "GraphAutoCheckpointHandle",
87
+ "Graph",
88
+ "GraphDiffResult",
89
+ "GraphObserveSource",
90
+ "HashFn",
91
+ "META_PATH_SEG",
92
+ "NodeVersionInfo",
93
+ "ObserveResult",
94
+ "PATH_SEP",
95
+ "SpyHandle",
96
+ "TraceEntry",
97
+ "V0",
98
+ "V1",
99
+ "VersioningLevel",
100
+ "reachable",
101
+ "compat",
102
+ "integrations",
103
+ "patterns",
104
+ "Runner",
105
+ "get_default_runner",
106
+ "resolve_runner",
107
+ "set_default_runner",
108
+ "Actor",
109
+ "DeferWhen",
110
+ "DynamicNodeImpl",
111
+ "EmitStrategy",
112
+ "GuardAction",
113
+ "GuardDenied",
114
+ "GuardFn",
115
+ "Message",
116
+ "MessageType",
117
+ "Messages",
118
+ "Node",
119
+ "PipeOperator",
120
+ "NodeActions",
121
+ "NodeFn",
122
+ "NodeImpl",
123
+ "NodeStatus",
124
+ "SubscribeHints",
125
+ "__version__",
126
+ "advance_version",
127
+ "create_versioning",
128
+ "default_hash",
129
+ "is_v1",
130
+ "monotonic_ns",
131
+ "wall_clock_ns",
132
+ "access_hint_for_guard",
133
+ "acquire_subgraph_write_lock",
134
+ "acquire_subgraph_write_lock_with_defer",
135
+ "batch",
136
+ "compose_guards",
137
+ "defer_down",
138
+ "defer_set",
139
+ "describe_node",
140
+ "dispatch_messages",
141
+ "emit_with_batch",
142
+ "ensure_registered",
143
+ "is_batching",
144
+ "is_phase2_message",
145
+ "meta_snapshot",
146
+ "node",
147
+ "normalize_actor",
148
+ "partition_for_batch",
149
+ "policy",
150
+ "policy_from_rules",
151
+ "record_mutation",
152
+ "system_actor",
153
+ "union_nodes",
154
+ "dynamic_node",
155
+ "derived",
156
+ "effect",
157
+ "pipe",
158
+ "producer",
159
+ "state",
160
+ ]
@@ -0,0 +1,18 @@
1
+ """Framework compatibility layer — asyncio/trio runners and async utilities (roadmap §5.1)."""
2
+
3
+ from graphrefly.compat.async_utils import (
4
+ first_value_from_async,
5
+ settled,
6
+ to_async_iter,
7
+ )
8
+ from graphrefly.compat.asyncio_runner import AsyncioRunner
9
+
10
+ __all__ = [
11
+ "AsyncioRunner",
12
+ "first_value_from_async",
13
+ "settled",
14
+ "to_async_iter",
15
+ ]
16
+
17
+ # TrioRunner is available via direct import (optional trio dependency):
18
+ # from graphrefly.compat.trio_runner import TrioRunner
@@ -0,0 +1,228 @@
1
+ """Async utility functions for consuming GraphReFly nodes from async code (roadmap §5.1).
2
+
3
+ All utilities are **reactive** — they subscribe to nodes via
4
+ :meth:`~graphrefly.core.node.NodeImpl.subscribe` and bridge to the async world
5
+ via :class:`asyncio.Event` / :class:`asyncio.Queue`. No polling.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import contextlib
12
+ from typing import TYPE_CHECKING, Any
13
+
14
+ from graphrefly.core.protocol import MessageType
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import AsyncIterator
18
+
19
+ from graphrefly.core.node import Node
20
+ from graphrefly.core.protocol import Messages
21
+
22
+
23
+ async def to_async_iter(source: Node[Any]) -> AsyncIterator[Any]:
24
+ """Yield values from *source* as an async iterator.
25
+
26
+ Subscribes reactively — each ``DATA`` message payload is yielded, and
27
+ each ``RESOLVED`` message yields the current value via ``source.get()``.
28
+ ``COMPLETE`` / ``ERROR`` / ``TEARDOWN`` end the iteration.
29
+ Unsubscribes on ``break`` / ``aclose()``.
30
+
31
+ Must be called from a running asyncio event loop.
32
+
33
+ Note:
34
+ ``state()`` nodes do not emit ``DATA`` on subscribe — they only emit
35
+ when :meth:`~graphrefly.core.node.NodeImpl.set` is called. For such
36
+ nodes, the iterator will block until the first update arrives.
37
+ Derived nodes emit ``DATA`` on subscribe when they recompute.
38
+
39
+ Example::
40
+
41
+ from graphrefly.extra import of
42
+ from graphrefly.compat import to_async_iter
43
+
44
+ async for value in to_async_iter(of(1, 2, 3)):
45
+ print(value)
46
+
47
+ Yields:
48
+ Each ``DATA`` payload or current value on ``RESOLVED`` from the source.
49
+ """
50
+ loop = asyncio.get_running_loop()
51
+ queue: asyncio.Queue[tuple[str, Any]] = asyncio.Queue()
52
+
53
+ def _enqueue(tag: str, payload: Any) -> None:
54
+ with contextlib.suppress(RuntimeError):
55
+ loop.call_soon_threadsafe(queue.put_nowait, (tag, payload))
56
+
57
+ def sink(messages: Messages) -> None:
58
+ for msg in messages:
59
+ t = msg[0]
60
+ if t is MessageType.DATA:
61
+ _enqueue("DATA", msg[1] if len(msg) > 1 else None)
62
+ elif t is MessageType.RESOLVED:
63
+ _enqueue("DATA", source.get())
64
+ elif t is MessageType.ERROR:
65
+ err = msg[1] if len(msg) > 1 else RuntimeError("node error")
66
+ _enqueue("ERROR", err)
67
+ elif t is MessageType.COMPLETE or t is MessageType.TEARDOWN:
68
+ _enqueue("DONE", None)
69
+
70
+ unsub = source.subscribe(sink)
71
+ try:
72
+ while True:
73
+ tag, payload = await queue.get()
74
+ if tag == "DATA":
75
+ yield payload
76
+ elif tag == "ERROR":
77
+ raise payload
78
+ else: # DONE
79
+ return
80
+ finally:
81
+ unsub()
82
+
83
+
84
+ async def first_value_from_async(source: Node[Any]) -> Any:
85
+ """Await the first ``DATA`` value from *source*.
86
+
87
+ If the node already has a settled cached value, returns it immediately
88
+ without subscribing. Otherwise subscribes reactively and waits.
89
+
90
+ Raises:
91
+ RuntimeError: If the source completes without emitting ``DATA``.
92
+ Exception: If the source emits ``ERROR``.
93
+
94
+ Example::
95
+
96
+ from graphrefly import state
97
+ from graphrefly.compat import first_value_from_async
98
+
99
+ s = state(42)
100
+ value = await first_value_from_async(s)
101
+ assert value == 42
102
+ """
103
+ # Fast path: already settled with a cached value.
104
+ # ``source.get()`` returns ``None`` when no value is cached, so
105
+ # ``is not None`` doubles as the "has value" sentinel while still
106
+ # returning falsy values like ``0``, ``False``, ``""``.
107
+ status = source.status
108
+ if status in ("settled", "resolved"):
109
+ v = source.get()
110
+ if v is not None:
111
+ return v
112
+
113
+ loop = asyncio.get_running_loop()
114
+ future: asyncio.Future[Any] = loop.create_future()
115
+
116
+ def _set_result(value: Any) -> None:
117
+ with contextlib.suppress(RuntimeError):
118
+ loop.call_soon_threadsafe(_resolve, future, value)
119
+
120
+ def _set_error(err: BaseException) -> None:
121
+ with contextlib.suppress(RuntimeError):
122
+ loop.call_soon_threadsafe(_reject, future, err)
123
+
124
+ def sink(messages: Messages) -> None:
125
+ for msg in messages:
126
+ t = msg[0]
127
+ if t is MessageType.DATA:
128
+ _set_result(msg[1] if len(msg) > 1 else None)
129
+ return
130
+ if t is MessageType.ERROR:
131
+ err = msg[1] if len(msg) > 1 else RuntimeError("node error")
132
+ _set_error(err)
133
+ return
134
+ if t is MessageType.COMPLETE or t is MessageType.TEARDOWN:
135
+ _set_error(RuntimeError("source completed without DATA"))
136
+ return
137
+
138
+ unsub = source.subscribe(sink)
139
+ try:
140
+ return await future
141
+ finally:
142
+ unsub()
143
+
144
+
145
+ async def settled(source: Node[Any]) -> Any:
146
+ """Await until *source* has a settled (non-dirty) value.
147
+
148
+ If the node already holds a cached value and is in a settled/resolved
149
+ status, returns it without waiting. Otherwise subscribes and waits for
150
+ the first ``DATA`` or ``RESOLVED`` message.
151
+
152
+ Raises:
153
+ RuntimeError: If the source completes or tears down without settling.
154
+ Exception: If the source emits ``ERROR``.
155
+
156
+ Example::
157
+
158
+ from graphrefly import derived, state
159
+ from graphrefly.compat import settled
160
+
161
+ a = state(10)
162
+ b = derived([a], lambda deps, _: deps[0] * 2)
163
+ value = await settled(b)
164
+ assert value == 20
165
+ """
166
+ # Fast path: already settled (see ``first_value_from_async`` for the
167
+ # ``is not None`` rationale).
168
+ status = source.status
169
+ if status in ("settled", "resolved"):
170
+ v = source.get()
171
+ if v is not None:
172
+ return v
173
+
174
+ loop = asyncio.get_running_loop()
175
+ future: asyncio.Future[Any] = loop.create_future()
176
+
177
+ def _set_result(value: Any) -> None:
178
+ with contextlib.suppress(RuntimeError):
179
+ loop.call_soon_threadsafe(_resolve, future, value)
180
+
181
+ def _set_error(err: BaseException) -> None:
182
+ with contextlib.suppress(RuntimeError):
183
+ loop.call_soon_threadsafe(_reject, future, err)
184
+
185
+ def sink(messages: Messages) -> None:
186
+ for msg in messages:
187
+ t = msg[0]
188
+ if t is MessageType.DATA:
189
+ _set_result(msg[1] if len(msg) > 1 else None)
190
+ return
191
+ if t is MessageType.RESOLVED:
192
+ _set_result(source.get())
193
+ return
194
+ if t is MessageType.ERROR:
195
+ err = msg[1] if len(msg) > 1 else RuntimeError("node error")
196
+ _set_error(err)
197
+ return
198
+ if t is MessageType.COMPLETE or t is MessageType.TEARDOWN:
199
+ _set_error(RuntimeError("source completed without settling"))
200
+ return
201
+
202
+ unsub = source.subscribe(sink)
203
+ try:
204
+ return await future
205
+ finally:
206
+ unsub()
207
+
208
+
209
+ # ---------------------------------------------------------------------------
210
+ # Helpers
211
+ # ---------------------------------------------------------------------------
212
+
213
+
214
+ def _resolve(future: asyncio.Future[Any], value: Any) -> None:
215
+ if not future.done():
216
+ future.set_result(value)
217
+
218
+
219
+ def _reject(future: asyncio.Future[Any], err: BaseException) -> None:
220
+ if not future.done():
221
+ future.set_exception(err)
222
+
223
+
224
+ __all__ = [
225
+ "first_value_from_async",
226
+ "settled",
227
+ "to_async_iter",
228
+ ]
@@ -0,0 +1,89 @@
1
+ """AsyncioRunner — schedule coroutines on an asyncio event loop (roadmap §5.1)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ if TYPE_CHECKING:
9
+ from collections.abc import Callable, Coroutine
10
+
11
+
12
+ class AsyncioRunner:
13
+ """Runner backed by a running :mod:`asyncio` event loop.
14
+
15
+ Schedule coroutines via ``loop.create_task`` with thread-safe dispatch.
16
+ Use inside an ``async def`` context (e.g. FastAPI lifespan, async test).
17
+
18
+ Example::
19
+
20
+ import asyncio
21
+ from graphrefly.compat import AsyncioRunner
22
+ from graphrefly.core.runner import set_default_runner
23
+
24
+ async def main():
25
+ runner = AsyncioRunner.from_running()
26
+ set_default_runner(runner)
27
+ # ... build graph, use from_awaitable, etc.
28
+
29
+ asyncio.run(main())
30
+ """
31
+
32
+ __slots__ = ("_loop",)
33
+
34
+ def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
35
+ self._loop = loop
36
+
37
+ @classmethod
38
+ def from_running(cls) -> AsyncioRunner:
39
+ """Create from the currently running asyncio event loop.
40
+
41
+ Raises:
42
+ RuntimeError: If no event loop is running.
43
+ """
44
+ return cls(asyncio.get_running_loop())
45
+
46
+ def schedule(
47
+ self,
48
+ coro: Coroutine[Any, Any, Any],
49
+ on_result: Callable[[Any], None],
50
+ on_error: Callable[[BaseException], None],
51
+ ) -> Callable[[], None]:
52
+ task: asyncio.Task[Any] | None = None
53
+ cancelled = False
54
+
55
+ def _create_task() -> None:
56
+ nonlocal task
57
+ if cancelled:
58
+ coro.close()
59
+ return
60
+
61
+ async def _wrapper() -> None:
62
+ try:
63
+ result = await coro
64
+ except asyncio.CancelledError:
65
+ raise
66
+ except KeyboardInterrupt:
67
+ raise
68
+ except SystemExit:
69
+ raise
70
+ except BaseException as err:
71
+ on_error(err)
72
+ else:
73
+ on_result(result)
74
+
75
+ task = self._loop.create_task(_wrapper())
76
+
77
+ # Thread-safe: schedule task creation on the event loop.
78
+ self._loop.call_soon_threadsafe(_create_task)
79
+
80
+ def cancel() -> None:
81
+ nonlocal cancelled
82
+ cancelled = True
83
+ if task is not None:
84
+ task.cancel()
85
+
86
+ return cancel
87
+
88
+
89
+ __all__ = ["AsyncioRunner"]
@@ -0,0 +1,81 @@
1
+ """TrioRunner — schedule coroutines on a trio nursery (roadmap §5.1).
2
+
3
+ Requires the ``trio`` package (optional dependency).
4
+
5
+ Usage::
6
+
7
+ import trio
8
+ from graphrefly.compat.trio_runner import TrioRunner
9
+ from graphrefly.core.runner import set_default_runner
10
+
11
+ async def main():
12
+ async with trio.open_nursery() as nursery:
13
+ runner = TrioRunner(nursery)
14
+ set_default_runner(runner)
15
+ # ... build graph, use from_awaitable, etc.
16
+
17
+ trio.run(main)
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from typing import TYPE_CHECKING, Any
23
+
24
+ if TYPE_CHECKING:
25
+ from collections.abc import Callable, Coroutine
26
+
27
+ import trio # type: ignore[import-not-found]
28
+
29
+
30
+ class TrioRunner:
31
+ """Runner backed by a :mod:`trio` nursery.
32
+
33
+ Each scheduled coroutine runs as a trio task in the nursery.
34
+ Cancel scopes provide best-effort cancellation.
35
+ """
36
+
37
+ __slots__ = ("_nursery",)
38
+
39
+ def __init__(self, nursery: trio.Nursery) -> None:
40
+ self._nursery = nursery
41
+
42
+ def schedule(
43
+ self,
44
+ coro: Coroutine[Any, Any, Any],
45
+ on_result: Callable[[Any], None],
46
+ on_error: Callable[[BaseException], None],
47
+ ) -> Callable[[], None]:
48
+ import trio as _trio
49
+
50
+ cancel_scope = _trio.CancelScope()
51
+ cancelled = False
52
+
53
+ async def _wrapper() -> None:
54
+ with cancel_scope:
55
+ if cancelled:
56
+ coro.close()
57
+ return
58
+ try:
59
+ result = await coro
60
+ except _trio.Cancelled:
61
+ raise
62
+ except KeyboardInterrupt:
63
+ raise
64
+ except SystemExit:
65
+ raise
66
+ except BaseException as err:
67
+ on_error(err)
68
+ else:
69
+ on_result(result)
70
+
71
+ self._nursery.start_soon(_wrapper)
72
+
73
+ def cancel() -> None:
74
+ nonlocal cancelled
75
+ cancelled = True
76
+ cancel_scope.cancel()
77
+
78
+ return cancel
79
+
80
+
81
+ __all__ = ["TrioRunner"]
@@ -0,0 +1,142 @@
1
+ """Core node primitives and protocol types for graphrefly."""
2
+
3
+ from graphrefly.core.clock import monotonic_ns, wall_clock_ns
4
+ from graphrefly.core.dynamic_node import DynamicNodeImpl, dynamic_node
5
+ from graphrefly.core.guard import (
6
+ Actor,
7
+ GuardAction,
8
+ GuardDenied,
9
+ GuardFn,
10
+ access_hint_for_guard,
11
+ compose_guards,
12
+ normalize_actor,
13
+ policy,
14
+ policy_from_rules,
15
+ record_mutation,
16
+ system_actor,
17
+ )
18
+ from graphrefly.core.meta import describe_node, meta_snapshot
19
+ from graphrefly.core.node import (
20
+ Node,
21
+ NodeActions,
22
+ NodeFn,
23
+ NodeImpl,
24
+ NodeStatus,
25
+ SubscribeHints,
26
+ node,
27
+ )
28
+ from graphrefly.core.protocol import (
29
+ DeferWhen,
30
+ EmitStrategy,
31
+ Message,
32
+ Messages,
33
+ MessageType,
34
+ batch,
35
+ dispatch_messages,
36
+ emit_with_batch,
37
+ is_batching,
38
+ is_phase2_message,
39
+ is_terminal_message,
40
+ message_tier,
41
+ partition_for_batch,
42
+ propagates_to_meta,
43
+ )
44
+ from graphrefly.core.runner import (
45
+ Runner,
46
+ get_default_runner,
47
+ resolve_runner,
48
+ set_default_runner,
49
+ )
50
+ from graphrefly.core.subgraph_locks import (
51
+ acquire_subgraph_write_lock,
52
+ acquire_subgraph_write_lock_with_defer,
53
+ defer_down,
54
+ defer_set,
55
+ ensure_registered,
56
+ union_nodes,
57
+ )
58
+ from graphrefly.core.sugar import (
59
+ PipeOperator,
60
+ derived,
61
+ effect,
62
+ pipe,
63
+ producer,
64
+ state,
65
+ )
66
+ from graphrefly.core.versioning import (
67
+ V0,
68
+ V1,
69
+ HashFn,
70
+ NodeVersionInfo,
71
+ VersioningLevel,
72
+ advance_version,
73
+ create_versioning,
74
+ default_hash,
75
+ is_v1,
76
+ )
77
+
78
+ __all__ = [
79
+ "Actor",
80
+ "DynamicNodeImpl",
81
+ "DeferWhen",
82
+ "EmitStrategy",
83
+ "GuardAction",
84
+ "GuardDenied",
85
+ "GuardFn",
86
+ "Message",
87
+ "MessageType",
88
+ "Messages",
89
+ "Node",
90
+ "PipeOperator",
91
+ "NodeActions",
92
+ "NodeFn",
93
+ "NodeImpl",
94
+ "NodeStatus",
95
+ "SubscribeHints",
96
+ "monotonic_ns",
97
+ "wall_clock_ns",
98
+ "access_hint_for_guard",
99
+ "acquire_subgraph_write_lock",
100
+ "acquire_subgraph_write_lock_with_defer",
101
+ "batch",
102
+ "compose_guards",
103
+ "defer_down",
104
+ "defer_set",
105
+ "describe_node",
106
+ "dispatch_messages",
107
+ "emit_with_batch",
108
+ "ensure_registered",
109
+ "is_batching",
110
+ "is_phase2_message",
111
+ "is_terminal_message",
112
+ "message_tier",
113
+ "propagates_to_meta",
114
+ "meta_snapshot",
115
+ "node",
116
+ "normalize_actor",
117
+ "partition_for_batch",
118
+ "policy",
119
+ "policy_from_rules",
120
+ "record_mutation",
121
+ "system_actor",
122
+ "union_nodes",
123
+ "dynamic_node",
124
+ "Runner",
125
+ "get_default_runner",
126
+ "resolve_runner",
127
+ "set_default_runner",
128
+ "derived",
129
+ "effect",
130
+ "pipe",
131
+ "producer",
132
+ "state",
133
+ "V0",
134
+ "V1",
135
+ "NodeVersionInfo",
136
+ "VersioningLevel",
137
+ "HashFn",
138
+ "advance_version",
139
+ "create_versioning",
140
+ "default_hash",
141
+ "is_v1",
142
+ ]