The CRDT auto-persist was broadcasting state-refresh after each save, causing
other clients to fetch from DB and overwrite their local variables/characters
with stale values. Since CRDT already syncs nodes/edges via yjs-update
broadcasts, the state-refresh from auto-persist was redundant and destructive.
Manual save still broadcasts state-refresh as intended.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add connection timeout (15s) to handle stale initial subscribes, inactivity
pause (5min) to save resources when idle, and automatic resume on user activity
or tab focus. The heartbeat now detects unhealthy channel states and consecutive
failures to trigger reconnects. Unexpected CLOSED status also triggers reconnect
instead of staying disconnected silently.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of relying on Yjs broadcast serialization (which has delivery
issues), use a lightweight state-refresh broadcast event. When any
client persists (manual save or CRDT auto-persist), it broadcasts
state-refresh. Other clients fetch the latest flowchart_data from the
database and update their local state and CRDT.
Added isSuppressed flag to CRDTManager to prevent broadcast/persist
loops during initialization and refresh operations.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a user saves, the full Yjs document state is broadcast so all
connected clients converge, even if they missed incremental updates.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The yjs-update broadcast listener was added after the Supabase channel
was already subscribed, which meant it never received messages. Moved
the listener registration to the builder chain before .subscribe()
(matching how cursor/node-lock listeners work), and removed the broken
isRemoteUpdateRef guard that caused ReferenceErrors preventing local
changes from reaching the CRDT.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The merge at bcbad57 lost utility functions, type definitions, and
handlers from the developing branch. This restores: imports (useRef,
useEffect, ConditionalEdge, ContextMenu), constants (AUTOSAVE_DEBOUNCE_MS),
types (ContextMenuState, ConditionEditorState), utility functions
(fromReactFlowNodes, fromReactFlowEdges, saveDraft, loadDraft, clearDraft,
flowchartDataEquals, isValidFlowchartData, convertToRenpyFormat), context
menu handlers, proper FlowchartEditorProps (userId, userDisplayName,
isOwner), ReactFlow container height (h-screen), and fixes stale closure
dependency arrays for characters/variables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the variableName text input in edge conditions with a
Combobox-based variable selector. Adds ConditionEditor modal
that opens on edge click, with type-aware operators (comparison
for numeric, == and != for string/boolean) and type-adaptive
value inputs (number, text, or boolean toggle).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add toolbar component with buttons for adding nodes (Dialogue, Choice,
Variable) and managing projects (Save, Export, Import). Buttons are
styled with TailwindCSS and wired to placeholder handlers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement the flowchart editor page with React Flow integration:
- Install reactflow package for canvas rendering
- Create editor page that fetches project data from Supabase
- Add loading state with spinner while fetching
- Handle unauthorized access and not found with appropriate responses
- Render React Flow canvas with grid background
- Add header with project name and back link to dashboard
- Initialize React Flow with nodes and edges from flowchart_data
- Add type converters for FlowchartNode/Edge to React Flow types
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>