Editor State Blueprint

Centralized state management with sliced architecture, action dispatching, computed selections, and public API

   
Feature editor-state
Category Data
Version 1.0.0
Tags state-management, store, reducer, editor, centralized-state
YAML Source View on GitHub
JSON API editor-state.json

Actors

ID Name Type Description
dispatcher Action Dispatcher system Routes actions through the reducer to modify state
store State Store system Single source of truth for all editor state
consumer State Consumer system Any UI component or system that reads from the store

Fields

Name Type Required Label Description
data json Yes Page Data  
ui_state json Yes UI State  
selected_item json No Selected Item  
item_selector json No Item Selector  
left_sidebar_visible boolean Yes Left Sidebar Visible  
right_sidebar_visible boolean Yes Right Sidebar Visible  
preview_mode select Yes Preview Mode  
is_dragging boolean Yes Is Dragging  
field_focus text No Focused Field  
status select Yes Editor Status  
component_loading_state json No Component Loading  

States

State field: status

Values:

State Initial Terminal
LOADING Yes  
MOUNTED    
READY    

Transitions:

Name From To Actor Condition
  LOADING MOUNTED store  
  MOUNTED READY store All stylesheets loaded in iframe (if iframe enabled)

Rules

  • store_architecture:
    • single_store: true
    • sliced: true
    • immutable_updates: true
  • action_types:
    • supported: insert, move, remove, duplicate, replace, replace_root, reorder, set, set_data, set_ui, register_zone, unregister_zone
  • dispatch_interceptor:
    • history_recording: true
    • action_callback: true
    • selected_item_sync: true
  • slices:
    • history_slice: true
    • nodes_slice: true
    • fields_slice: true
    • permissions_slice: true
  • computed_state:
    • selected_item_from_selector: true
    • component_config_from_type: true
  • component_loading:
    • deferred_loading_timeout: true
    • reference_counting: true
    • cleanup_on_cancel: true
  • public_api:
    • read_state: true
    • dispatch_actions: true
    • access_history: true
    • get_permissions: true
    • resolve_data_by_id: true
    • resolve_data_by_selector: true
    • get_item_by_id: true
    • get_item_by_selector: true
    • get_selector_for_id: true
    • get_parent_by_id: true

Outcomes

Dispatch_action (Priority: 1)

Given:

  • a valid action with a recognized type is dispatched

Then:

  • call_service target: reducer — Route action to appropriate handler (insert, move, remove, etc.)
  • set_field target: application_state — Update state with reducer output
  • set_field target: selected_item — Recompute selectedItem from updated itemSelector
  • call_service target: history — Record state snapshot to history (if action is history-enabled)
  • call_service target: on_action_callback — Call onAction callback with action, new state, and previous state
  • emit_event event: state.action.dispatched

Result: State updated, history recorded, callbacks notified

Select_component (Priority: 2)

Given:

  • user clicks on a component in the canvas or outline

Then:

  • set_field target: item_selector — Set itemSelector to { zone, index } of clicked component
  • set_field target: selected_item — Compute selectedItem from the new selector
  • call_service target: fields_slice — Resolve and display fields for the selected component
  • emit_event event: state.selection.changed

Result: Component highlighted on canvas, properties panel shows its fields

Deselect_component (Priority: 3)

Given:

  • user clicks on empty canvas area or presses Escape

Then:

  • set_field target: item_selector — Set itemSelector to null
  • set_field target: selected_item — Set selectedItem to null
  • emit_event event: state.selection.cleared

Result: No component selected, properties panel empty or shows page settings

Toggle_preview_mode (Priority: 4)

Given:

  • user toggles between edit and interactive preview

Then:

  • set_field target: preview_mode — Switch between ‘edit’ (editable canvas) and ‘interactive’ (clickable preview)
  • emit_event event: state.preview_mode.changed

Result: Canvas switches between editable and interactive modes

Set_component_loading (Priority: 5)

Given:

  • an async operation starts for a component (data resolution, external fetch)

Then:

  • set_field target: component_loading_state — Increment loading counter for the component ID (with optional defer timeout)

Result: Component shows loading indicator while async operation is in progress

Clear_component_loading (Priority: 6)

Given:

  • an async operation completes for a component

Then:

  • set_field target: component_loading_state — Decrement loading counter for the component ID

Result: Loading indicator removed when counter reaches 0

Batch_resolve_on_load (Priority: 7)

Given:

  • editor loads initial data

Then:

  • call_service target: resolver — Walk all top-level components and resolve their data with trigger ‘load’
  • set_field target: application_state — Replace each component’s data with resolved version if changed
  • emit_event event: state.data.batch_resolved

Result: All components have their dynamic data resolved

Errors

Code Status Message Retry
UNKNOWN_ACTION_TYPE 400 Unrecognized action type No
INVALID_SELECTOR 400 Item selector does not point to a valid component No

Events

Event Description Payload
state.action.dispatched An action was processed by the reducer action_type
state.selection.changed A different component was selected component_id, zone, index
state.selection.cleared Component selection was cleared  
state.preview_mode.changed Editor switched between edit and interactive preview mode
state.data.batch_resolved Batch data resolution completed on page load resolved_count, changed_count
Feature Relationship Reason
content-tree required Page data (root, content, zones) is core state
undo-redo required History slice manages undo/redo within the store
component-registry required Component configs inform how state is structured and resolved
field-transforms required Field resolution pipeline reads and writes state
drag-drop-editor recommended Drag state (isDragging, preview) is UI state

AGI Readiness

Goals

Reliable Editor State

Centralized state management with sliced architecture, action dispatching, computed selections, and public API

Success Metrics:

Metric Target Measurement
data_accuracy 100% Records matching source of truth
duplicate_rate 0% Duplicate records detected post-creation

Constraints:

  • performance (non-negotiable): Data consistency must be maintained across concurrent operations

Autonomy

Level: supervised

Escalation Triggers:

  • error_rate > 5

Tradeoffs

Prefer Over Reason
data_integrity performance data consistency must be maintained across all operations

Coordination

Protocol: orchestrated

Consumes:

Capability From Fallback
content_tree content-tree degrade
undo_redo undo-redo degrade
component_registry component-registry degrade
field_transforms field-transforms degrade

Safety

Action Permission Cooldown Max Auto
dispatch_action autonomous - -
select_component autonomous - -
deselect_component autonomous - -
toggle_preview_mode autonomous - -
set_component_loading autonomous - -
clear_component_loading autonomous - -
batch_resolve_on_load autonomous - -
Extensions (framework-specific hints) ```yaml source: repo: https://github.com/puckeditor/puck project: Page editor tech_stack: TypeScript + React files_traced: 15 entry_points: - store/index.ts - store/slices/ - store/default-app-state.ts - lib/use-puck.ts - reducer/index.ts ```