graphrefly 0.18.0__tar.gz → 0.19.0__tar.gz
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.
- {graphrefly-0.18.0 → graphrefly-0.19.0}/CHANGELOG.md +34 -0
- graphrefly-0.19.0/CLAUDE.md +48 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/PKG-INFO +1 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/pyproject.toml +2 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/__init__.py +0 -6
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/compat/async_utils.py +7 -9
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/compat/asyncio_runner.py +34 -7
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/compat/trio_runner.py +29 -5
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/__init__.py +0 -3
- graphrefly-0.19.0/src/graphrefly/core/dynamic_node.py +382 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/meta.py +5 -1
- graphrefly-0.19.0/src/graphrefly/core/node.py +540 -0
- graphrefly-0.19.0/src/graphrefly/core/node_base.py +739 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/protocol.py +51 -26
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/runner.py +15 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/__init__.py +8 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/adapters.py +16 -8
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/cascading_cache.py +17 -7
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/data_structures.py +1 -3
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/resilience.py +13 -6
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/sources.py +186 -10
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/tier1.py +14 -32
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/tier2.py +22 -5
- graphrefly-0.19.0/src/graphrefly/graph/__init__.py +67 -0
- graphrefly-0.19.0/src/graphrefly/graph/codec.py +293 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/graph/graph.py +172 -144
- graphrefly-0.19.0/src/graphrefly/graph/profile.py +120 -0
- graphrefly-0.19.0/src/graphrefly/graph/sizeof.py +115 -0
- graphrefly-0.19.0/src/graphrefly/patterns/_internal.py +64 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/ai.py +866 -76
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/cqrs.py +4 -5
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/domain_templates.py +7 -9
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/harness/__init__.py +10 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/harness/bridge.py +44 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/harness/loop.py +153 -69
- graphrefly-0.19.0/src/graphrefly/patterns/harness/profile.py +84 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/harness/strategy.py +3 -4
- graphrefly-0.19.0/src/graphrefly/patterns/harness/trace.py +239 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/harness/types.py +7 -12
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/messaging.py +3 -8
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/orchestration.py +19 -11
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/reduction.py +108 -4
- graphrefly-0.19.0/tests/__init__.py +1 -0
- graphrefly-0.19.0/tests/conftest.py +123 -0
- graphrefly-0.19.0/tests/helpers/__init__.py +1 -0
- graphrefly-0.19.0/tests/helpers/mock_llm.py +122 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_adapters_ingest.py +17 -69
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_adapters_storage.py +8 -16
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_core.py +20 -9
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_domain_templates.py +3 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_dynamic_node.py +3 -3
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_edge_cases.py +19 -34
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_data_structures.py +2 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_resilience.py +23 -39
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_sources.py +5 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_sources_http.py +16 -17
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_tier1.py +57 -88
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_tier2.py +83 -90
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_fastapi.py +2 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_graph.py +36 -21
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_operator_protocol_matrix.py +4 -3
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_ai.py +726 -4
- graphrefly-0.19.0/tests/test_patterns_harness.py +698 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_orchestration.py +14 -10
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_reduction.py +9 -9
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_protocol.py +1 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_reduction.py +10 -10
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_sugar.py +3 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_versioning.py +2 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/astro.config.mjs +8 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/scripts/gen_api_docs.py +1 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/Header.astro +5 -2
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/Sidebar.astro +4 -2
- graphrefly-0.19.0/website/src/content/docs/api/ReactiveCounterBundle.md +14 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/first_value_from.md +6 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_any.md +1 -1
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/index.md +33 -36
- graphrefly-0.19.0/website/src/content/docs/api/is_local_only.md +16 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/is_terminal_message.md +2 -2
- graphrefly-0.19.0/website/src/content/docs/api/keepalive.md +21 -0
- graphrefly-0.19.0/website/src/content/docs/api/message_tier.md +20 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/partition_for_batch.md +1 -1
- graphrefly-0.19.0/website/src/content/docs/api/reactive_counter.md +19 -0
- graphrefly-0.19.0/website/src/content/docs/recipes/index.md +8 -0
- graphrefly-0.18.0/.claude/skills/dev-dispatch/SKILL.md +0 -119
- graphrefly-0.18.0/.claude/skills/parity/SKILL.md +0 -139
- graphrefly-0.18.0/.claude/skills/qa/SKILL.md +0 -104
- graphrefly-0.18.0/.gemini/skills/dev-dispatch/SKILL.md +0 -171
- graphrefly-0.18.0/.gemini/skills/parity/SKILL.md +0 -188
- graphrefly-0.18.0/CLAUDE.md +0 -77
- graphrefly-0.18.0/TRASH/EmitStrategy.md +0 -10
- graphrefly-0.18.0/TRASH/emit_with_batch.md +0 -43
- graphrefly-0.18.0/TRASH-FILES.md +0 -2
- graphrefly-0.18.0/archive/docs/DESIGN-ARCHIVE-INDEX.md +0 -79
- graphrefly-0.18.0/archive/docs/SESSION-access-control-actor-guard.md +0 -210
- graphrefly-0.18.0/archive/docs/SESSION-cross-repo-implementation-audit.md +0 -205
- graphrefly-0.18.0/archive/docs/SESSION-demo-test-strategy.md +0 -71
- graphrefly-0.18.0/archive/docs/SESSION-graphrefly-spec-design.md +0 -111
- graphrefly-0.18.0/archive/docs/SESSION-serialization-memory-footprint.md +0 -69
- graphrefly-0.18.0/archive/docs/SESSION-tier2-parity-nonlocal-forward-inner.md +0 -54
- graphrefly-0.18.0/archive/docs/SESSION-universal-reduction-layer.md +0 -65
- graphrefly-0.18.0/archive/docs/design-archive-index.jsonl +0 -14
- graphrefly-0.18.0/archive/optimizations/built-in-optimizations.jsonl +0 -8
- graphrefly-0.18.0/archive/optimizations/cross-language-notes.jsonl +0 -35
- graphrefly-0.18.0/archive/optimizations/parity-fixes.jsonl +0 -6
- graphrefly-0.18.0/archive/optimizations/qa-design-decisions.jsonl +0 -11
- graphrefly-0.18.0/archive/optimizations/resolved-decisions.jsonl +0 -95
- graphrefly-0.18.0/archive/optimizations/summary-table.jsonl +0 -49
- graphrefly-0.18.0/archive/roadmap/phase-0-foundation.jsonl +0 -7
- graphrefly-0.18.0/archive/roadmap/phase-1-graph-container.jsonl +0 -7
- graphrefly-0.18.0/archive/roadmap/phase-2-extra.jsonl +0 -3
- graphrefly-0.18.0/archive/roadmap/phase-3-resilience-data.jsonl +0 -4
- graphrefly-0.18.0/archive/roadmap/phase-4-domain-layers.jsonl +0 -5
- graphrefly-0.18.0/archive/roadmap/phase-5-framework-distribution.jsonl +0 -6
- graphrefly-0.18.0/archive/roadmap/phase-6-versioning.jsonl +0 -3
- graphrefly-0.18.0/archive/roadmap/phase-7-polish.jsonl +0 -2
- graphrefly-0.18.0/archive/roadmap/phase-8-reduction-layer.jsonl +0 -3
- graphrefly-0.18.0/archive/roadmap/phase-9-harness-sprint.jsonl +0 -1
- graphrefly-0.18.0/docs/docs-guidance.md +0 -247
- graphrefly-0.18.0/docs/optimizations.md +0 -80
- graphrefly-0.18.0/docs/roadmap.md +0 -161
- graphrefly-0.18.0/docs/test-guidance.md +0 -138
- graphrefly-0.18.0/src/graphrefly/core/dynamic_node.py +0 -774
- graphrefly-0.18.0/src/graphrefly/core/node.py +0 -1046
- graphrefly-0.18.0/src/graphrefly/graph/__init__.py +0 -33
- graphrefly-0.18.0/tests/conftest.py +0 -46
- graphrefly-0.18.0/tests/test_patterns_harness.py +0 -383
- graphrefly-0.18.0/website/src/content/docs/api/message_tier.md +0 -19
- {graphrefly-0.18.0 → graphrefly-0.19.0}/.github/workflows/pages.yml +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/.github/workflows/release.yml +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/.gitignore +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/.mise.toml +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/CONTRIBUTING.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/GEMINI.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/LICENSE +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/README.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/benchmarks/py-baseline.json +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/docs/ADAPTER-CONTRACT.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/docs/benchmark.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/examples/README.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/examples/basic_counter.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/llms.txt +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/compat/__init__.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/bridge.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/cancellation.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/clock.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/guard.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/subgraph_locks.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/sugar.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/timer.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/core/versioning.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/backoff.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/backpressure.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/checkpoint.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/composite.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/extra/cron.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/integrations/__init__.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/integrations/django.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/integrations/fastapi.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/__init__.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/graphspec.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/memory.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/reactive_layout/__init__.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/reactive_layout/measurement_adapters.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/reactive_layout/reactive_block_layout.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/patterns/reactive_layout/reactive_layout.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/src/graphrefly/py.typed +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/bench_core.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_adapter_contract.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_backpressure.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_bridge.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_cascading_cache.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_concurrency.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_django.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_extra_composite.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_graphspec.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_guard.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_measurement_adapters.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_cqrs.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_memory.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_patterns_messaging.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_perf_smoke.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_reactive_block_layout.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_reactive_layout.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_regressions.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_runner.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/tests/test_smoke.py +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/.gitignore +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/README.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/content.config.ts +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/package.json +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/pnpm-lock.yaml +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/public/llms.txt +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/py-api-sidebar.mjs +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/scripts/sync-docs.mjs +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/GraphreflyHero.astro +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/MobileMenuFooter.astro +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/PyodidePlayground.tsx +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/components/SiteTitle.astro +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/BackoffPreset.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/BackoffStrategy.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/CheckpointAdapter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/CircuitBreaker.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/CircuitOpenError.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/CompactEntry.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/DeferWhen.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/DictCheckpointAdapter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/DistillBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/DownStrategy.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/Extraction.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/FileCheckpointAdapter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/HttpBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/JitterMode.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/MemoryCheckpointAdapter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/Message.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/MessageType.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/Messages.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/NodeActions.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/NodeFn.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/NodeImpl.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/NodeStatus.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/PipeOperator.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/PubSubHub.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/ReactiveIndexBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/ReactiveListBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/ReactiveLogBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/ReactiveMapBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/SqliteCheckpointAdapter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/SubscribeHints.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/TimeoutError.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/TokenBucket.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/VerifiableBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/Versioned.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/WithBreakerBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/WithStatusBundle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/audit.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/batch.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/buffer.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/buffer_count.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/buffer_time.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/cache.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/cached.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/checkpoint_node_value.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/circuit_breaker.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/combine.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/concat.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/concat_map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/constant.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/debounce.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/decorrelated_jitter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/delay.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/derived.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/dispatch_messages.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/distill.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/distinct_until_changed.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/down_with_batch.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/effect.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/element_at.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/empty.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/exhaust_map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/exponential.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/fallback.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/fibonacci.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/filter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/find.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/first.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/flat_map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/for_each.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_async_iter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_awaitable.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_cron.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_event_emitter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_fs_watch.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_git_hook.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_http.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_iter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_mcp.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_timer.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_webhook.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/from_websocket.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/gate.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/interval.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/is_batching.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/is_phase2_message.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/last.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/linear.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/log_slice.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/merge.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/never.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/node.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/of.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/operator.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/pairwise.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/pausable.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/pipe.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/producer.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/propagates_to_meta.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/pubsub.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/race.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/rate_limiter.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/reactive_index.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/reactive_list.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/reactive_log.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/reactive_map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/reduce.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/repeat.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/replay.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/rescue.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/resolve_backoff_preset.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/restore_graph_checkpoint.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/retry.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/sample.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/save_graph_checkpoint.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/scan.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/share.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/skip.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/start_with.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/state.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/subscribe.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/switch_map.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/take.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/take_until.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/take_while.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/tap.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/throttle.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/throw_error.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/timeout.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/timeout_node.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/to_array.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/to_list.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/to_sse.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/to_websocket.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/token_bucket.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/token_tracker.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/valve.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/verifiable.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/window.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/window_count.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/window_time.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/with_breaker.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/with_latest_from.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/with_max_attempts.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/with_status.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/api/zip.md +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/index.mdx +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content/docs/lab/python.mdx +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/content.config.ts +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/env.d.ts +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/src/styles/custom.css +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/theme-prototypes.html +0 -0
- {graphrefly-0.18.0 → graphrefly-0.19.0}/website/tsconfig.json +0 -0
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v0.19.0 (2026-04-10)
|
|
6
|
+
|
|
7
|
+
### Chores
|
|
8
|
+
|
|
9
|
+
- 9.0 initial test (needs revisit)
|
|
10
|
+
([`f47a8b4`](https://github.com/graphrefly/graphrefly-py/commit/f47a8b4d32e999d4f867465f678d576184fc111d))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- Add start
|
|
15
|
+
([`4a008dc`](https://github.com/graphrefly/graphrefly-py/commit/4a008dcda7704e14be12a7111b1d0b9188c736b3))
|
|
16
|
+
|
|
17
|
+
- Address optimization items
|
|
18
|
+
([`371f9e2`](https://github.com/graphrefly/graphrefly-py/commit/371f9e25e590ded4150fd6aed7e0de3933b8f0f3))
|
|
19
|
+
|
|
20
|
+
- Consolidate inspection tools
|
|
21
|
+
([`94aa9af`](https://github.com/graphrefly/graphrefly-py/commit/94aa9af3e3d793103496bfcc71a0a4bbb38f5ea3))
|
|
22
|
+
|
|
23
|
+
- Fix
|
|
24
|
+
([`222e66f`](https://github.com/graphrefly/graphrefly-py/commit/222e66f4d8954aa772534c9fc796eea3ba30a304))
|
|
25
|
+
|
|
26
|
+
- Fix async pytest
|
|
27
|
+
([`f25ae08`](https://github.com/graphrefly/graphrefly-py/commit/f25ae0885fd824320b498fd2d923f6e4f6ebb0f5))
|
|
28
|
+
|
|
29
|
+
- Fix inspection tool
|
|
30
|
+
([`09c90f2`](https://github.com/graphrefly/graphrefly-py/commit/09c90f273613fbae1fd7987397d85d4b6fabec8d))
|
|
31
|
+
|
|
32
|
+
- Fix retries and reingestions
|
|
33
|
+
([`55d1a3d`](https://github.com/graphrefly/graphrefly-py/commit/55d1a3d0beff848a6ecefb054e42d194050d5c37))
|
|
34
|
+
|
|
35
|
+
- Reusable harness patterns
|
|
36
|
+
([`84bafbb`](https://github.com/graphrefly/graphrefly-py/commit/84bafbb8476c1d00ae373bbc757d4bf813ce16c8))
|
|
37
|
+
|
|
38
|
+
|
|
5
39
|
## v0.18.0 (2026-04-08)
|
|
6
40
|
|
|
7
41
|
### Features
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# graphrefly-py
|
|
2
|
+
|
|
3
|
+
Python implementation of the GraphReFly reactive graph protocol.
|
|
4
|
+
|
|
5
|
+
**All operational docs (roadmap, optimizations, test guidance, docs guidance, skills, archive) live in `~/src/graphrefly-ts`.** See that repo's `CLAUDE.md` for the full agent context.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
uv workspace managed by mise. `mise trust && mise install` to set up uv. `uv sync` to install dependencies.
|
|
10
|
+
|
|
11
|
+
- Test: `uv run pytest`
|
|
12
|
+
- Lint: `uv run ruff check src/ tests/`
|
|
13
|
+
- Lint fix: `uv run ruff check --fix src/ tests/`
|
|
14
|
+
- Format: `uv run ruff format src/ tests/`
|
|
15
|
+
- Type check: `uv run mypy src/`
|
|
16
|
+
|
|
17
|
+
## Package naming
|
|
18
|
+
|
|
19
|
+
- Distribution name: `graphrefly-py`
|
|
20
|
+
- Import path: `graphrefly`
|
|
21
|
+
|
|
22
|
+
## Layout
|
|
23
|
+
|
|
24
|
+
- `src/graphrefly/core/` — message protocol, `node` primitive, batch, sugar constructors (Phase 0)
|
|
25
|
+
- `src/graphrefly/graph/` — `Graph` container, describe/observe, snapshot (Phase 1+)
|
|
26
|
+
- `src/graphrefly/extra/` — operators, sources, data structures, resilience (Phase 2–3)
|
|
27
|
+
- `src/graphrefly/patterns/` — domain-layer APIs: orchestration, messaging, memory, AI, CQRS, reactive layout (Phase 4+)
|
|
28
|
+
- `src/graphrefly/compat/` — async runners: asyncio, trio (Phase 5+)
|
|
29
|
+
- `src/graphrefly/integrations/` — framework integrations: FastAPI (Phase 5+)
|
|
30
|
+
|
|
31
|
+
## Key references
|
|
32
|
+
|
|
33
|
+
| Doc | Location |
|
|
34
|
+
|-----|----------|
|
|
35
|
+
| Behavior spec | `~/src/graphrefly/GRAPHREFLY-SPEC.md` |
|
|
36
|
+
| Composition guide | `~/src/graphrefly/COMPOSITION-GUIDE.md` |
|
|
37
|
+
| Roadmap, optimizations, test/docs guidance, skills, archive | `~/src/graphrefly-ts/` (single source of truth) |
|
|
38
|
+
| Predecessor (patterns, concurrency) | `~/src/callbag-recharge-py` (reference only, not spec) |
|
|
39
|
+
|
|
40
|
+
## Design invariants (spec §5.8–5.12)
|
|
41
|
+
|
|
42
|
+
1. **No polling.** Use reactive timer sources (`from_timer`, `from_cron`).
|
|
43
|
+
2. **No imperative triggers.** Use reactive `NodeInput` signals.
|
|
44
|
+
3. **No raw async primitives.** Async boundaries belong in sources and runners, not node fns.
|
|
45
|
+
4. **Central timer and `message_tier`.** Use `core/clock.py`; never hardcode type checks.
|
|
46
|
+
5. **Phase 4+ APIs must be developer-friendly.** No protocol internals in primary surface.
|
|
47
|
+
6. **Thread safety.** Per-subgraph `RLock`, per-node `_cache_lock`. Design for GIL and free-threaded Python.
|
|
48
|
+
7. **No `async def` in public APIs.** Return `Node[T]`, `Graph`, `None`, or plain synchronous values.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphrefly
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19.0
|
|
4
4
|
Summary: Reactive harness layer for agent workflows. Describe automations in plain language, trace every decision, enforce policies, persist checkpoints. Zero dependencies.
|
|
5
5
|
Project-URL: Homepage, https://py.graphrefly.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/graphrefly/graphrefly-py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "graphrefly"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.19.0"
|
|
4
4
|
description = "Reactive harness layer for agent workflows. Describe automations in plain language, trace every decision, enforce policies, persist checkpoints. Zero dependencies."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -90,6 +90,7 @@ quote-style = "double"
|
|
|
90
90
|
|
|
91
91
|
[tool.pytest.ini_options]
|
|
92
92
|
testpaths = ["tests"]
|
|
93
|
+
pythonpath = ["tests"]
|
|
93
94
|
asyncio_mode = "auto"
|
|
94
95
|
addopts = "-m 'not benchmark'"
|
|
95
96
|
markers = [
|
|
@@ -37,7 +37,6 @@ from graphrefly.core import (
|
|
|
37
37
|
defer_down,
|
|
38
38
|
defer_set,
|
|
39
39
|
derived,
|
|
40
|
-
describe_node,
|
|
41
40
|
dispatch_messages,
|
|
42
41
|
down_with_batch,
|
|
43
42
|
dynamic_node,
|
|
@@ -47,7 +46,6 @@ from graphrefly.core import (
|
|
|
47
46
|
is_batching,
|
|
48
47
|
is_phase2_message,
|
|
49
48
|
is_v1,
|
|
50
|
-
meta_snapshot,
|
|
51
49
|
monotonic_ns,
|
|
52
50
|
node,
|
|
53
51
|
normalize_actor,
|
|
@@ -74,7 +72,6 @@ from graphrefly.graph import (
|
|
|
74
72
|
GraphDiffResult,
|
|
75
73
|
GraphObserveSource,
|
|
76
74
|
ObserveResult,
|
|
77
|
-
SpyHandle,
|
|
78
75
|
TraceEntry,
|
|
79
76
|
reachable,
|
|
80
77
|
)
|
|
@@ -93,7 +90,6 @@ __all__ = [
|
|
|
93
90
|
"NodeVersionInfo",
|
|
94
91
|
"ObserveResult",
|
|
95
92
|
"PATH_SEP",
|
|
96
|
-
"SpyHandle",
|
|
97
93
|
"TraceEntry",
|
|
98
94
|
"V0",
|
|
99
95
|
"V1",
|
|
@@ -138,13 +134,11 @@ __all__ = [
|
|
|
138
134
|
"compose_guards",
|
|
139
135
|
"defer_down",
|
|
140
136
|
"defer_set",
|
|
141
|
-
"describe_node",
|
|
142
137
|
"dispatch_messages",
|
|
143
138
|
"down_with_batch",
|
|
144
139
|
"ensure_registered",
|
|
145
140
|
"is_batching",
|
|
146
141
|
"is_phase2_message",
|
|
147
|
-
"meta_snapshot",
|
|
148
142
|
"node",
|
|
149
143
|
"normalize_actor",
|
|
150
144
|
"partition_for_batch",
|
|
@@ -11,6 +11,7 @@ import asyncio
|
|
|
11
11
|
import contextlib
|
|
12
12
|
from typing import TYPE_CHECKING, Any
|
|
13
13
|
|
|
14
|
+
from graphrefly.core.node import NO_VALUE
|
|
14
15
|
from graphrefly.core.protocol import MessageType
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
@@ -101,13 +102,11 @@ async def first_value_from_async(source: Node[Any]) -> Any:
|
|
|
101
102
|
assert value == 42
|
|
102
103
|
"""
|
|
103
104
|
# Fast path: already settled with a cached value.
|
|
104
|
-
#
|
|
105
|
-
# ``is not None`` doubles as the "has value" sentinel while still
|
|
106
|
-
# returning falsy values like ``0``, ``False``, ``""``.
|
|
105
|
+
# Uses NO_VALUE sentinel so ``None`` as a real domain value is not skipped.
|
|
107
106
|
status = source.status
|
|
108
107
|
if status in ("settled", "resolved"):
|
|
109
|
-
v = source
|
|
110
|
-
if v is not
|
|
108
|
+
v = getattr(source, "_cached", NO_VALUE)
|
|
109
|
+
if v is not NO_VALUE:
|
|
111
110
|
return v
|
|
112
111
|
|
|
113
112
|
loop = asyncio.get_running_loop()
|
|
@@ -163,12 +162,11 @@ async def settled(source: Node[Any]) -> Any:
|
|
|
163
162
|
value = await settled(b)
|
|
164
163
|
assert value == 20
|
|
165
164
|
"""
|
|
166
|
-
# Fast path: already settled
|
|
167
|
-
# ``is not None`` rationale).
|
|
165
|
+
# Fast path: already settled — uses NO_VALUE sentinel so ``None`` is not skipped.
|
|
168
166
|
status = source.status
|
|
169
167
|
if status in ("settled", "resolved"):
|
|
170
|
-
v = source
|
|
171
|
-
if v is not
|
|
168
|
+
v = getattr(source, "_cached", NO_VALUE)
|
|
169
|
+
if v is not NO_VALUE:
|
|
172
170
|
return v
|
|
173
171
|
|
|
174
172
|
loop = asyncio.get_running_loop()
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import threading
|
|
6
7
|
from typing import TYPE_CHECKING, Any
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
@@ -29,10 +30,12 @@ class AsyncioRunner:
|
|
|
29
30
|
asyncio.run(main())
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
__slots__ = ("_loop",)
|
|
33
|
+
__slots__ = ("_loop", "_scheduled", "_completed")
|
|
33
34
|
|
|
34
35
|
def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
|
|
35
36
|
self._loop = loop
|
|
37
|
+
self._scheduled = 0
|
|
38
|
+
self._completed = 0
|
|
36
39
|
|
|
37
40
|
@classmethod
|
|
38
41
|
def from_running(cls) -> AsyncioRunner:
|
|
@@ -50,11 +53,12 @@ class AsyncioRunner:
|
|
|
50
53
|
on_error: Callable[[BaseException], None],
|
|
51
54
|
) -> Callable[[], None]:
|
|
52
55
|
task: asyncio.Task[Any] | None = None
|
|
53
|
-
cancelled =
|
|
56
|
+
cancelled = threading.Event()
|
|
54
57
|
|
|
55
58
|
def _create_task() -> None:
|
|
56
59
|
nonlocal task
|
|
57
|
-
if cancelled:
|
|
60
|
+
if cancelled.is_set():
|
|
61
|
+
self._completed += 1
|
|
58
62
|
coro.close()
|
|
59
63
|
return
|
|
60
64
|
|
|
@@ -71,19 +75,42 @@ class AsyncioRunner:
|
|
|
71
75
|
on_error(err)
|
|
72
76
|
else:
|
|
73
77
|
on_result(result)
|
|
78
|
+
finally:
|
|
79
|
+
self._completed += 1
|
|
74
80
|
|
|
75
81
|
task = self._loop.create_task(_wrapper())
|
|
76
82
|
|
|
77
|
-
#
|
|
78
|
-
self.
|
|
83
|
+
# Increment eagerly on the calling thread so __repr__ is always consistent.
|
|
84
|
+
self._scheduled += 1
|
|
85
|
+
try:
|
|
86
|
+
self._loop.call_soon_threadsafe(_create_task)
|
|
87
|
+
except RuntimeError:
|
|
88
|
+
# Loop closed — cannot schedule; close the coroutine and balance the counter.
|
|
89
|
+
self._completed += 1
|
|
90
|
+
coro.close()
|
|
79
91
|
|
|
80
92
|
def cancel() -> None:
|
|
81
|
-
|
|
82
|
-
cancelled = True
|
|
93
|
+
cancelled.set()
|
|
83
94
|
if task is not None:
|
|
84
95
|
task.cancel()
|
|
85
96
|
|
|
86
97
|
return cancel
|
|
87
98
|
|
|
99
|
+
def would_block_deadlock(self) -> bool:
|
|
100
|
+
"""True if blocking the current thread would starve this runner's loop."""
|
|
101
|
+
try:
|
|
102
|
+
loop = asyncio.get_running_loop()
|
|
103
|
+
except RuntimeError:
|
|
104
|
+
return False
|
|
105
|
+
return loop is self._loop
|
|
106
|
+
|
|
107
|
+
def __repr__(self) -> str:
|
|
108
|
+
pending = self._scheduled - self._completed
|
|
109
|
+
running = self._loop.is_running()
|
|
110
|
+
return (
|
|
111
|
+
f"AsyncioRunner(scheduled={self._scheduled}, completed={self._completed}, "
|
|
112
|
+
f"pending={pending}, loop_running={running})"
|
|
113
|
+
)
|
|
114
|
+
|
|
88
115
|
|
|
89
116
|
__all__ = ["AsyncioRunner"]
|
|
@@ -8,6 +8,7 @@ Usage::
|
|
|
8
8
|
from graphrefly.compat.trio_runner import TrioRunner
|
|
9
9
|
from graphrefly.core.runner import set_default_runner
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
async def main():
|
|
12
13
|
async with trio.open_nursery() as nursery:
|
|
13
14
|
runner = TrioRunner(nursery)
|
|
@@ -19,6 +20,7 @@ Usage::
|
|
|
19
20
|
|
|
20
21
|
from __future__ import annotations
|
|
21
22
|
|
|
23
|
+
import threading
|
|
22
24
|
from typing import TYPE_CHECKING, Any
|
|
23
25
|
|
|
24
26
|
if TYPE_CHECKING:
|
|
@@ -34,10 +36,12 @@ class TrioRunner:
|
|
|
34
36
|
Cancel scopes provide best-effort cancellation.
|
|
35
37
|
"""
|
|
36
38
|
|
|
37
|
-
__slots__ = ("_nursery",)
|
|
39
|
+
__slots__ = ("_nursery", "_scheduled", "_completed")
|
|
38
40
|
|
|
39
41
|
def __init__(self, nursery: trio.Nursery) -> None:
|
|
40
42
|
self._nursery = nursery
|
|
43
|
+
self._scheduled = 0
|
|
44
|
+
self._completed = 0
|
|
41
45
|
|
|
42
46
|
def schedule(
|
|
43
47
|
self,
|
|
@@ -48,11 +52,12 @@ class TrioRunner:
|
|
|
48
52
|
import trio as _trio
|
|
49
53
|
|
|
50
54
|
cancel_scope = _trio.CancelScope()
|
|
51
|
-
cancelled =
|
|
55
|
+
cancelled = threading.Event()
|
|
52
56
|
|
|
53
57
|
async def _wrapper() -> None:
|
|
54
58
|
with cancel_scope:
|
|
55
|
-
if cancelled:
|
|
59
|
+
if cancelled.is_set():
|
|
60
|
+
self._completed += 1
|
|
56
61
|
coro.close()
|
|
57
62
|
return
|
|
58
63
|
try:
|
|
@@ -67,15 +72,34 @@ class TrioRunner:
|
|
|
67
72
|
on_error(err)
|
|
68
73
|
else:
|
|
69
74
|
on_result(result)
|
|
75
|
+
finally:
|
|
76
|
+
self._completed += 1
|
|
70
77
|
|
|
78
|
+
self._scheduled += 1
|
|
71
79
|
self._nursery.start_soon(_wrapper)
|
|
72
80
|
|
|
73
81
|
def cancel() -> None:
|
|
74
|
-
|
|
75
|
-
cancelled = True
|
|
82
|
+
cancelled.set()
|
|
76
83
|
cancel_scope.cancel()
|
|
77
84
|
|
|
78
85
|
return cancel
|
|
79
86
|
|
|
87
|
+
def would_block_deadlock(self) -> bool:
|
|
88
|
+
"""True if blocking the current thread would starve the trio nursery."""
|
|
89
|
+
try:
|
|
90
|
+
import trio as _trio
|
|
91
|
+
|
|
92
|
+
_trio.lowlevel.current_trio_token()
|
|
93
|
+
return True
|
|
94
|
+
except RuntimeError:
|
|
95
|
+
return False
|
|
96
|
+
|
|
97
|
+
def __repr__(self) -> str:
|
|
98
|
+
pending = self._scheduled - self._completed
|
|
99
|
+
return (
|
|
100
|
+
f"TrioRunner(scheduled={self._scheduled}, completed={self._completed}, "
|
|
101
|
+
f"pending={pending})"
|
|
102
|
+
)
|
|
103
|
+
|
|
80
104
|
|
|
81
105
|
__all__ = ["TrioRunner"]
|
|
@@ -17,7 +17,6 @@ from graphrefly.core.guard import (
|
|
|
17
17
|
record_mutation,
|
|
18
18
|
system_actor,
|
|
19
19
|
)
|
|
20
|
-
from graphrefly.core.meta import describe_node, meta_snapshot
|
|
21
20
|
from graphrefly.core.node import (
|
|
22
21
|
NO_VALUE,
|
|
23
22
|
Node,
|
|
@@ -112,7 +111,6 @@ __all__ = [
|
|
|
112
111
|
"compose_guards",
|
|
113
112
|
"defer_down",
|
|
114
113
|
"defer_set",
|
|
115
|
-
"describe_node",
|
|
116
114
|
"dispatch_messages",
|
|
117
115
|
"down_with_batch",
|
|
118
116
|
"ensure_registered",
|
|
@@ -121,7 +119,6 @@ __all__ = [
|
|
|
121
119
|
"is_terminal_message",
|
|
122
120
|
"message_tier",
|
|
123
121
|
"propagates_to_meta",
|
|
124
|
-
"meta_snapshot",
|
|
125
122
|
"node",
|
|
126
123
|
"normalize_actor",
|
|
127
124
|
"partition_for_batch",
|