-
Notifications
You must be signed in to change notification settings - Fork 0
test(sync): add no-coordination regression suite #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- GitGraphAdapter now retries transient Git failures using @git-stunts/alfred with exponential backoff and decorrelated jitter - Extract CachedValue utility from HealthCheckService for reusable TTL caching - BitmapIndexReader logs warning when ID-to-SHA cache exceeds 1M entries - Refactor TraversalService path reconstruction into unified helpers - Add Memory Considerations section to README - Update Docker build context to include alfred sibling package
BREAKING CHANGE: This release introduces managed mode as the recommended way to use EmptyGraph. Nodes created without managed mode or explicit ref management may be garbage collected by Git. ## Durability (Core Fix) - Add EmptyGraph.open() static factory with mode='managed' - Add GraphRefManager service for ref/anchor management - Add automatic anchor commits for disconnected subgraphs - Add fast-forward optimization (skip anchors for linear history) - Add isAncestor() to GitGraphAdapter for ancestry checking ## Batching API - Add beginBatch() for efficient bulk writes - Add GraphBatch with octopus anchoring on commit() - Add compactAnchors() utility for cleanup ## Validation - Add EmptyMessageError for empty message rejection - Reject empty messages at write time (fixes "ghost nodes") ## Index Improvements - Add canonical JSON checksums (SHARD_VERSION=2) - Add backward compatibility for v1 shards - Add SUPPORTED_SHARD_VERSIONS array ## Cancellation - Add AbortSignal to all TraversalService methods - Add AbortSignal to StreamingBitmapIndexBuilder finalization - Fix signal propagation in IndexRebuildService ## Documentation - Add SEMANTICS.md (durability contract) - Add docs/ANCHORING.md (anchor mechanics) - Add docs/ARCHITECTURE.md (hexagonal design) - Add docs/WARP-ROADMAP.md (v4/v5 evolution path) - Update README with durability guide - Update CHANGELOG for v3.0.0 ## Tests - Add 26 managed mode durability tests - Add 12 manual mode tests - Add 6 empty message validation tests - Add 9 shard versioning tests
- Add WARP-TECH-SPEC-ROADMAP.md normative specification for v4/v5 - Anchors now use trailer format (eg-kind: anchor) instead of JSON - OID trailers (eg-patch-oid, eg-frontier-oid, eg-index-oid) MUST match tree - Define canonical_state_bytes ordering for deterministic state hashing - Add writer ID constraints (ASCII, 1-64 chars, ref-safe charset) - Clarify v3 backward compat as explicit legacy mode with adapter - Update ANCHORING.md to document both v4+ trailer and legacy JSON formats
Phase 1 complete - all foundational infrastructure for WARP v4: 1.1 RefLayout (src/domain/utils/RefLayout.js) - Ref path builders: buildWriterRef, buildCheckpointRef, buildCoverageRef - Validators: validateGraphName, validateWriterId (per WARP spec) - Parser: parseWriterIdFromRef 1.2 WarpMessageCodec (src/domain/services/WarpMessageCodec.js) - Trailer-based message encoding for patch/checkpoint/anchor commits - Uses @git-stunts/trailer-codec - detectMessageKind helper for commit type detection 1.3 commitNodeWithTree (GitGraphAdapter) - Creates commits with custom trees (not empty tree) - Required for WARP patch commits with attachment trees 1.4 CborCodec (src/infrastructure/codecs/CborCodec.js) - Canonical CBOR encoding via cbor-x - Deterministic key sorting for state hashing 1.5 listRefs (GitGraphAdapter) - Lists refs by prefix for writer discovery - Uses git for-each-ref Tests: 176 new tests (all passing)
Phase 2 complete - core WARP v4 reducer implementation: 2.1 WarpTypes (src/domain/types/WarpTypes.js) - JSDoc types for OpV1, PatchV1, ValueRef, EdgeKey, NodeId - Factory functions for all operation types 2.2 EventId (src/domain/utils/EventId.js) - Total ordering: lamport → writerId → patchSha → opIndex - createEventId with validation, compareEventIds comparator 2.3 LWW Register (src/domain/crdt/LWW.js) - Last-Writer-Wins register with EventId-based max - Commutative, associative, idempotent join 2.4 Reducer (src/domain/services/Reducer.js) - Core reduce() algorithm: expand → sort → apply - applyOp for all 5 operation types with LWW semantics - Deterministic state from any patch ordering 2.5 Frontier (src/domain/services/Frontier.js) - Checkpoint frontier tracking (writerId → lastPatchSha) - Canonical CBOR serialization 2.6 StateSerializer (src/domain/services/StateSerializer.js) - Visibility predicates: nodeVisible, edgeVisible, propVisible - Canonical state serialization with sorted keys - computeStateHash (SHA-256 of canonical bytes) Also fixes pre-existing test failures: - Add isAncestor mock to persistence test fixtures - Fix idempotent sync expectation in ManagedModeDurability - Update BitmapIndexReader test for multi-version support Tests: 209 new tests (930 total, all passing)
BREAKING CHANGE: New major version with multi-writer support. Multi-Writer API: - EmptyGraph.openMultiWriter() factory method - MultiWriterGraph class with full WARP protocol support - PatchBuilder fluent API for atomic graph mutations - materialize() and materializeAt() for state reconstruction - createCheckpoint() for fast recovery snapshots - syncCoverage() for single-ref cloning - discoverWriters() for writer enumeration CRDT Foundation: - LWW (Last-Writer-Wins) register for conflict resolution - EventId total ordering (lamport, writerId, patchSha, opIndex) - Deterministic Reducer with LWW semantics - Frontier tracking for writer progress - StateSerializer with canonical hashing Infrastructure: - WarpMessageCodec for Git trailer encoding - CborCodec for deterministic CBOR serialization - RefLayout helpers for WARP ref structure - LegacyAnchorDetector for v3 backward compatibility - GitGraphAdapter extensions (commitNodeWithTree, listRefs) Performance: - 10K patches in ~100ms (50x faster than requirement) - Memory: ~35MB for 10K patches - Incremental materialization from checkpoints Testing: - 1079 unit tests passing - Determinism tests (reduce order independence) - Tombstone stability tests - Performance benchmarks (1K-25K patches) - v3 compatibility tests - Integration tests with real Git operations Documentation: - README Multi-Writer section - docs/MULTI-WRITER-GUIDE.md user guide - Comprehensive JSDoc coverage
WARP V5 upgrades from LWW-based deterministic fold to true lattice confluence using OR-Set CRDTs. Concurrent add + remove now results in add-wins semantics (remove only affects observed dots). Phase 1 - Benchmarks: - ReducerV5.benchmark.js: V5 reducer scaling (1K-25K patches) - Compaction.benchmark.js: orsetCompact() performance testing Phase 2 - Checkpoint V5 Format: - CheckpointSerializerV5.js: Full ORSet state serialization - computeAppliedVV() scans actual dots in state - V5 tree: state.cbor (authoritative), visible.cbor (cache), appliedVV.cbor, frontier.cbor - Backfill rejection via graph reachability (not lamport) Phase 3 - Network Sync: - SyncProtocol.js: Frontier-based per-writer chain sync - loadPatchRange() with divergence detection - computeSyncDelta() for bidirectional sync Phase 4 - GC Policy: - GCMetrics.js: Collect tombstone ratios and entry counts - GCPolicy.js: Configurable thresholds, shouldRunGC(), executeGC() CRDT Primitives (already existed, now used by V5): - Dot.js: Unique operation ID (writerId, counter) - VersionVector.js: Causality tracking, pointwise-max merge - ORSet.js: Global OR-Set with add-wins, orsetCompact() BREAKING CHANGE: Schema 2 patches use dots/observedDots instead of simple add/tombstone. Migration from v4 via MigrationService.
- Add eg-checkpoint: v5 trailer to WarpMessageCodec for schema:2 checkpoints - Wire GC auto-triggering into MultiWriterGraph (maybeRunGC, runGC, getGCMetrics) - Expose sync API on MultiWriterGraph (createSyncRequest, processSyncRequest, applySyncResponse, syncNeeded, getFrontier) - Add gcPolicy option to MultiWriterGraph.open() The backfill rejection implementation was verified correct: - _loadPatchesSince() validates all patches via _validatePatchAgainstCheckpoint() - materializeAt() loads patches forward from checkpoint (not backfill)
- Remove stale WARP planning/handoff docs (implementation complete) - Remove TASKLIST.md (v2.5 tasklist, now outdated) - Add docs/FUTURE.md with remaining wishlist items
Defines the path from three graph engines to one: - EmptyGraph: deprecated engine, becomes wrapper - schema:1: legacy read/extend only - schema:2: the default, the future Phase A (now): default to schema:2, add deprecation warnings Phase B (after v5): EmptyGraph becomes wrapper over MultiWriterGraph Phase C (v6): remove legacy code Key policy: no auto-migration, single-writer = one writerId, all new features land in MultiWriterGraph only.
Task 5 (Test Organization): - Created docs/V7_TEST_MAPPING.md mapping spec requirements to existing tests - Tests cover all WARP contracts (write/materialize/convergence/determinism) - Legacy tests confirmed deleted via v7-guards.test.js Task 6 (WarpBitmapIndex on Materialized State): - Added WarpStateIndexBuilder.js - builds index from WarpStateV5.edgeAlive - Index now built from WARP logical edges, not Git commit DAG - Added buildWarpStateIndex() convenience function Task 7 (Query API on Materialized State): - Added hasNode(nodeId) - check node existence - Added getNodeProps(nodeId) - get properties as Map - Added neighbors(nodeId, dir?, label?) - get connected nodes - Added getNodes() - list all visible nodes - Added getEdges() - list all visible edges - All methods query materialized state, never commit DAG Task 10 (Determinism Torture Suite): - Verified complete: JoinReducer.integration.test.js has Killer Tests 1-6 - Property-based tests with fast-check in properties/ directory - computeStateHashV5() provides stable state digest Tests: 1413 passing
…tate API Rewrite entire examples suite from event-sourcing traversal patterns to WarpGraph's CRDT-based materialized state queries. This completes the migration to the V7 architecture where all queries operate on OR-Set projected state rather than raw commit DAG traversal. Key changes: - explore.js: WarpGraph.open() + materialize() replaces loadIndexFromRef() - inspect-index.js: checkpoint tree inspection replaces bitmap shard analysis - lagrangian-path.js: uses new pathfinding.js with Dijkstra/A* over adjacency - streaming-benchmark.js: measures materialization vs raw git operations - traversal-benchmark.js: benchmarks getNodes/getEdges vs commit traversal - multi-writer.js: demonstrates CRDT merge with discoverWriters() - setup.js: simplified graph initialization with createPatch() API New utilities: - examples/pathfinding.js: MinPriorityQueue, Dijkstra, A*, depth computation - src/domain/utils/roaring.js: lazy-loaded roaring bitmap module wrapper - examples/html/: pre-rendered HTML documentation for all examples - examples/GUIDE.md: consolidated examples documentation - docs/images/git-stunts.svg: project logo Infrastructure: - Dockerfile: remove alfred volume mount dependency - package.json: update dependencies for standalone operation - BitmapIndex*: delegate to roaring.js utility for cleaner imports BREAKING CHANGE: Examples now require WarpGraph.open() initialization pattern and operate on materialized state, not commit traversal.
Link empty-graph as a reference WARP implementation within the AIΩN Foundations Series, noting its role as the Git-native JavaScript implementation with CRDT-based coordination-free multi-writer support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
package.json (1)
33-69:⚠️ Potential issue | 🟠 MajorMove
patch-packageto dependencies—it's required for postinstall.When installed as a dependency,
npmdoesn't installdevDependencies, so thepostinstallscript will fail withpatch-package: command not found. Since patches must be applied during installation (e.g.,@mapbox+node-pre-gyp+2.0.3.patch), movepatch-packagetodependenciesto ensure it's available for consumers.🔧 Suggested fix
"dependencies": { "@git-stunts/alfred": "^0.4.0", "@git-stunts/plumbing": "^2.8.0", "@git-stunts/trailer-codec": "^2.1.1", "cbor-x": "^1.6.0", + "patch-package": "^8.0.0", "roaring": "^2.7.0", "zod": "^3.24.1" }, "devDependencies": { "@eslint/js": "^9.17.0", "@git-stunts/docker-guard": "^0.1.0", "eslint": "^9.17.0", "fast-check": "^4.5.3", - "patch-package": "^8.0.0", "prettier": "^3.4.2", "vitest": "^2.1.8" },
🤖 Fix all issues with AI agents
In `@ARCHITECTURE.md`:
- Around line 52-90: The markdown diagram in ARCHITECTURE.md uses opening code
fences like ```text but incorrectly closes them with ```text (e.g., the
WarpGraph diagram block containing "WarpGraph (WarpGraph.js)" and the
surrounding Ports/Adapters sections); update each mismatched fence to close with
a plain triple backtick (```) so the block opens with ```text and closes with
```, and fix the same pattern at the other reported locations (lines noted in
the review) to ensure standard Markdown fencing for all code blocks.
In `@bin/warp-graph.js`:
- Around line 914-916: The check that throws usageError when writerId is falsy
is unreachable because options.writer has a default of 'cli'; either remove the
conditional that checks writerId (and the usageError call) so the default 'cli'
is used, or change the default for options.writer to null/undefined where
options are defined so the existing guard (the writerId check in the code that
throws usageError) can meaningfully enforce an explicit --writer; update the
option definition (the symbol options.writer) or the guard around
writerId/usageError accordingly to choose one of these two behaviors.
In `@CHANGELOG.md`:
- Around line 41-47: The two list items under the "### Documentation" section
("Hook docs updated in README/CONTRIBUTING" and "Example imports clarified for
external consumers") have an extra leading space breaking list indentation and
triggering MD005; edit CHANGELOG.md to remove the extra space so all bullet
lines under "### Documentation" align with the other list entries (same indent
as "- **`docs/V7_TEST_MAPPING.md`** ..."), verify the bullets use consistent "-"
prefix and spacing, and re-run markdown linting to confirm MD005 is resolved.
In `@index.d.ts`:
- Around line 894-896: The type declaration for createPatch is wrong because the
implementation in src/domain/WarpGraph.js is async; update the signature of
createPatch in the declaration file to return a Promise (e.g., change
createPatch(): unknown to createPatch(): Promise<unknown> or a more specific
Promise<T> if you can infer the real return type), keeping the function name
createPatch to match the implementation.
- Around line 885-891: The .d.ts for WarpGraph.open is inconsistent with
runtime: change the open() options so writerId is required (remove the ? from
writerId) and add gcPolicy as an optional property (e.g. gcPolicy?: GcPolicy) to
match the implementation that calls validateWriterId(writerId) and accepts a
gcPolicy default; ensure the added GcPolicy type name matches the actual
exported type used elsewhere in the codebase (or import it) and keep other
option names (graphName, persistence, logger, adjacencyCacheSize) unchanged.
In `@package.json`:
- Around line 71-81: The package.json "files" array omits the CLI executable
bin/git-warp so it won't be included in published packages; update the "files"
array entry list (the array containing "bin/warp-graph.js", "src", "index.js",
etc.) to include "bin/git-warp" so the CLI file is bundled when publishing, and
verify package.json's "bin" mapping (if present) still points to the correct
path.
In `@README.md`:
- Around line 1189-1202: Update the Quick Start import to use the correct
package scope: change the module specifier from 'empty-graph' to
'@git-stunts/empty-graph' where EmptyGraph and GitGraphAdapter are imported so
the import line reads import { EmptyGraph, GitGraphAdapter } from
'@git-stunts/empty-graph'; (leave the rest of the example, including Plumbing
from '@git-stunts/plumbing', unchanged).
🧹 Nitpick comments (4)
eslint.config.js (1)
106-118: Optional: prevent Node globals in browser assets.
Because the base config declares Node globals, browser asset scripts can still useprocess/Buffer/globalwithout lint errors. Consider disabling them here to catch accidental Node-only usage.♻️ Suggested tweak
{ files: ["examples/html/assets/**/*.js"], languageOptions: { globals: { window: "readonly", document: "readonly", localStorage: "readonly", CustomEvent: "readonly", - Viz: "readonly" + Viz: "readonly", + process: "off", + Buffer: "off", + global: "off" } } },examples/html/assets/ui.js (1)
270-283: Minor edge case in path matching.When
window.location.pathnameis/or ends with/,split('/').pop()returns an empty string. This won't cause errors (just no match), but if root-level highlighting is needed, consider handling this explicitly.const current = window.location.pathname.split('/').pop() || 'index.html';examples/html/streaming-benchmark.html (2)
7-8: Consider adding Subresource Integrity (SRI) hashes for CDN resources.External scripts and stylesheets from CDNs are loaded without integrity attributes. If these CDNs are compromised, malicious code could be injected. For production use, consider adding
integrityandcrossoriginattributes.Example:
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js" integrity="sha384-..." crossorigin="anonymous"></script>Also applies to: 16-18
22-27: Large SVG logo duplicated in masthead and footer.The same SVG (~15KB) appears twice. Consider extracting it to a separate file or using a
<use>reference to reduce HTML size and improve maintainability.Also applies to: 128-134
- Fix CSS stray brace breaking subsequent rules - Fix Dockerfile heredoc (DL1000) and git commit robustness - Surface spawn errors in git-warp CLI wrapper - Remove unreachable writerId check in warp-graph history - Add missing WarpGraph members to index.d.ts, fix open() options and createPatch return type - Move patch-package to dependencies, add bin/git-warp to files array - Fix markdown code fences, link paths, indentation, and duplicate header - Update CLI naming from empty-graph to warp-graph in docs - Fix example module paths to use repo-relative fallback via import.meta.url - Add path length check and NODES_PER_PATCH validation in examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@ARCHITECTURE.md`:
- Around line 5-6: Update the overview sentence for WarpGraph to accurately
describe the storage model: either replace "commits as nodes with commit
messages as payloads" with wording that explains WARP's patch-based model (e.g.,
commits represent patch objects/deltas and payloads are patch content with
parent relationships linking patch history) or explicitly mark the current
sentence as the legacy "EmptyGraph" model by naming it (EmptyGraph) and adding a
short note pointing readers to the WARP patch-based model description; ensure
the terms "WarpGraph", "WARP", and "EmptyGraph" appear so readers can find the
detailed sections elsewhere in the doc.
- Around line 361-382: Replace all occurrences of the product name "EmptyGraph"
in the "Core Durability Contract" and "Modes" sections with the correct product
name "WarpGraph" (or explicitly mark any mention as legacy behavior if you
intend to reference historical behavior); update headings and the sentences that
say "EmptyGraph provides mechanisms..." and "In managed/manual mode,
EmptyGraph..." to "WarpGraph provides..." or similar; ensure consistency in the
"Managed Mode (Default)" and "Manual Mode" bullets and any examples so every
durability-related sentence and label refers to WarpGraph (or clearly annotates
legacy references) to avoid ambiguity.
In `@docs/GUIDE.md`:
- Around line 145-147: The import statement for the library is using the wrong
package name; update the import that brings in WarpGraph and GitGraphAdapter to
reference the published scoped package name (replace the unscoped "empty-graph"
import with "@git-stunts/empty-graph") so examples importing WarpGraph and
GitGraphAdapter (and any related examples) use the correct package identifier.
- Around line 128-139: Add the missing public TypeScript declarations for the
checkpoint APIs: update index.d.ts to include method signatures for
createCheckpoint() and materializeAt(checkpointSha: string) (or appropriate
types) on the WarpGraph interface/class so the public type defs match the
implemented methods in src/domain/WarpGraph.js and the documented usage in
GUIDE.md/README.md; ensure the return types align with existing code/tests
(e.g., Promise<string> for createCheckpoint and Promise<StateType> or equivalent
for materializeAt) and export them so consumers see the APIs.
🧹 Nitpick comments (4)
examples/html/assets/style.css (1)
223-226: Make the theme popover keyboard-reachable (:focus-within).Right now it only appears on hover, so keyboard users won’t see it. Adding
:focus-withinkeeps it accessible without changing behavior for mouse users.♿ Suggested tweak
-.theme-toggle-wrap:hover .theme-popover { +.theme-toggle-wrap:hover .theme-popover, +.theme-toggle-wrap:focus-within .theme-popover { opacity: 1; transform: translateY(0); }examples/inspect-index.js (1)
44-48: Consider closing the WarpGraph instance after use.The
graphinstance opened on line 45 is not explicitly closed after checkpoint creation. For a short-lived CLI script this is acceptable since the process exits, but ifWarpGraphhas aclose()method, calling it would be cleaner for resource hygiene.examples/streaming-benchmark.js (1)
107-129: Avoid creating an unused patch after the final commit.When
NODE_COUNTis an exact multiple ofNODES_PER_PATCH, a new patch is created but never used. This is minor, but easy to avoid.Optional refactor
if (nodesInPatch >= NODES_PER_PATCH) { await patch.commit(); - patch = await graph.createPatch(); nodesInPatch = 0; + if (i < NODE_COUNT - 1) { + patch = await graph.createPatch(); + } }docs/ideas/IDEA-001-QUERY-LANGUAGE-AND-TRAVERSAL-ARCHITECTURE.md (1)
171-182: Add language specifier to code blocks for syntax highlighting.The code block on line 173 (and similarly on lines 207 and 279) lacks a language specifier. Adding
javascriptenables syntax highlighting and improves readability.🔧 Proposed fix for line 173
-``` +```javascript const query = graph.query()🔧 Proposed fix for line 207
-``` +```javascript for await (const order of graph.query().where({ type: 'order' })) {🔧 Proposed fix for line 279
-``` +```javascript // Example of the "Gut Choice" in action
- Add createCheckpoint() and materializeAt() to index.d.ts - Fix import package name in GUIDE.md to @git-stunts/empty-graph - Replace EmptyGraph with WarpGraph in ARCHITECTURE.md durability section - Update ARCHITECTURE.md overview to describe WARP patch-based model - Add :focus-within to theme popover for keyboard accessibility - Avoid creating unused patch after final commit in streaming-benchmark - Add javascript language specifiers to IDEA-001 code blocks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@examples/html/assets/style.css`:
- Around line 223-227: The visible popover isn't interactive because the base
.theme-popover sets pointer-events: none but the visible state in the
.theme-toggle-wrap:hover .theme-popover and .theme-toggle-wrap:focus-within
.theme-popover rules never restores it; update those selector rules to set
pointer-events: auto (in addition to opacity and transform) so interactive
elements inside .theme-popover (e.g., swatches) become clickable and focusable.
- Around line 272-284: Add a visible keyboard focus style for the interactive
element by extending the .menu-button rule with a .menu-button:focus-visible
selector (or separate block) that sets a clear, accessible outline or box-shadow
and ensures outline-offset and border color contrast (e.g., stronger border or
highlight color and slight outline-offset) while preserving existing
border-radius; update the styles so keyboard focus is not solely reliant on
mouse hover and test that .menu-button:focus-visible appears when tabbing to the
button and does not interfere with existing .menu-button hover/active visuals.
- Around line 140-157: The .theme-toggle lacks a keyboard focus indicator; add a
.theme-toggle:focus-visible rule to provide a clear, high-contrast visible focus
state (e.g., outline or ring using CSS variables like --focus-ring or a fallback
color, or a prominent box-shadow), ensure the transition/positioning works with
the existing .theme-toggle and .theme-toggle:hover rules, and keep the focus
styling accessible without relying on hover (use :focus-visible on the
.theme-toggle element).
🧹 Nitpick comments (3)
examples/streaming-benchmark.js (1)
17-17: Environment variable name inconsistent with WarpGraph refactor.The environment variable
EMPTYGRAPH_MODULEreferences the old EmptyGraph naming, but the file now uses WarpGraph throughout. Consider renaming toWARPGRAPH_MODULEfor consistency.♻️ Suggested rename
-const modulePath = process.env.EMPTYGRAPH_MODULE || path.resolve(__dirname, '..', 'index.js'); +const modulePath = process.env.WARPGRAPH_MODULE || path.resolve(__dirname, '..', 'index.js');examples/html/assets/style.css (1)
99-119: Consider combining duplicate.masthead-logoselectors.The
.masthead-logoclass is defined twice - consolidating into a single rule block improves maintainability.♻️ Proposed consolidation
.masthead-logo { display: flex; align-items: center; flex: 1; min-width: 0; + width: clamp(320px, 70vw, 920px); } .masthead-logo svg, .footer-logo svg { width: 100%; height: auto; display: block; } .masthead-logo svg { filter: drop-shadow(0 16px 24px rgba(0, 0, 0, 0.25)); } -.masthead-logo { - width: clamp(320px, 70vw, 920px); -}index.d.ts (1)
178-184: NarrowQueryBuilder.select()field types to match runtime validation.Runtime throws on unknown fields, but the type currently allows any string. This loses TS safety. Consider restricting to
'id' | 'props'.♻️ Suggested typing refinement
- select(fields?: string[]): QueryBuilder; + select(fields?: Array<'id' | 'props'>): QueryBuilder;
- Rename EMPTYGRAPH_MODULE env var to WARPGRAPH_MODULE in all examples - Consolidate duplicate .masthead-logo selectors in style.css - Add pointer-events: auto to visible theme popover state - Add :focus-visible styles to .theme-toggle and .menu-button - Narrow QueryBuilder.select() field types to 'id' | 'props'
Summary
Testing
npm run test:local -- test/unit/domain/WarpGraph.noCoordination.test.jsSummary by CodeRabbit
New Features
Documentation
Chores