sync

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package sync provides bidirectional synchronization between the model DSL and draw.io diagram files, including conflict detection and resolution.

Package sync handles bidirectional synchronization between the model and draw.io files.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComputeHash

func ComputeHash(path string) (string, error)

ComputeHash reads the file at path and returns a "sha256:<hex>" fingerprint.

func RemoveOrphanedViewPages

func RemoveOrphanedViewPages(doc *drawio.Document, m *model.BausteinsichtModel)

RemoveOrphanedViewPages removes pages from the draw.io document that were created for views that no longer exist in the model. Pages are identified as view-managed if their id starts with the "view-" prefix. Pages whose id does not start with "view-" are preserved (e.g., default template pages).

func ReversePatchOps

func ReversePatchOps(cs *ChangeSet) ([]model.PatchOp, bool)

ReversePatchOps converts the reverse (draw.io → model) changes in cs into PatchOps that can be applied to the JSONC file directly. Returns the ops and true if all changes are patchable (only element field modifications). Returns nil, false if any structural change (add/delete) or relationship change is present — the caller should fall back to full Save.

func SaveState

func SaveState(path string, state *SyncState) error

SaveState atomically writes state to path using a temp file + rename.

Types

type ChangeSet

type ChangeSet struct {
	ModelElementChanges       []ElementChange
	ModelRelationshipChanges  []RelationshipChange
	DrawioElementChanges      []ElementChange
	DrawioRelationshipChanges []RelationshipChange
	Conflicts                 []Conflict
}

ChangeSet contains all detected changes from both sides.

func DetectChanges

func DetectChanges(m *model.BausteinsichtModel, doc *drawio.Document, lastState *SyncState, newPageIDs map[string]bool) *ChangeSet

DetectChanges performs a three-way diff between the model, draw.io document, and the last known sync state. newPageIDs is the set of page IDs that were just created (not yet populated by forward sync). Elements expected only on new pages are excluded from draw.io-side deletion detection (#184, #188, #189).

type ChangeType

type ChangeType int

ChangeType classifies a change.

const (
	Added    ChangeType = iota
	Modified            // nolint:deadcode
	Deleted
)

type Conflict

type Conflict struct {
	ElementID     string
	Field         string // "title", "description", "technology"
	ModelValue    string
	DrawioValue   string
	LastSyncValue string
}

Conflict represents a field that was changed on both sides since the last sync.

type ConflictResolver

type ConflictResolver interface {
	Resolve(conflicts []Conflict) []ResolvedConflict
}

ConflictResolver resolves conflicts between model and draw.io changes. Designed as an interface for future extension (interactive, merge strategies).

type ElementChange

type ElementChange struct {
	ID       string
	Type     ChangeType
	Field    string // "title", "description", "technology", "" for add/delete
	OldValue string
	NewValue string
}

ElementChange represents a change to a single element.

type ElementState

type ElementState struct {
	Title       string `json:"title"`
	Description string `json:"description,omitempty"`
	Technology  string `json:"technology,omitempty"`
	Kind        string `json:"kind"`
}

ElementState captures an element's synced values.

type ForwardOptions

type ForwardOptions struct {
	ModelPath string // path to the model file, shown in metadata box
	SyncTime  string // timestamp string, shown in metadata box
	Relayout  bool   // when true, clear and re-layout all view pages
}

ForwardOptions holds optional parameters for forward sync.

type ForwardResult

type ForwardResult struct {
	ElementsCreated   int
	ElementsUpdated   int
	ElementsDeleted   int
	ConnectorsCreated int
	ConnectorsUpdated int
	ConnectorsDeleted int
	MetadataUpdated   int // metadata and legend boxes created/updated
	Warnings          []string
}

ForwardResult summarises the changes applied to a draw.io document.

func ApplyForward

func ApplyForward(
	cs *ChangeSet,
	doc *drawio.Document,
	templates *drawio.TemplateSet,
	m *model.BausteinsichtModel,
	opts ...ForwardOptions,
) *ForwardResult

ApplyForward applies ModelElementChanges and ModelRelationshipChanges from cs to doc, using templates for styles and m for element data. When the model defines views, elements and relationships are placed on their corresponding view pages. Without views, falls back to the first page. opts is optional — pass nil to skip metadata/legend generation.

type ModelWinsResolver

type ModelWinsResolver struct{}

ModelWinsResolver always picks the model value (v1 default strategy).

func NewModelWinsResolver

func NewModelWinsResolver() *ModelWinsResolver

NewModelWinsResolver creates a new ModelWinsResolver.

func (*ModelWinsResolver) Resolve

func (r *ModelWinsResolver) Resolve(conflicts []Conflict) []ResolvedConflict

Resolve resolves all conflicts by choosing the model value.

type RelationshipChange

type RelationshipChange struct {
	From     string
	To       string
	Index    int // relationship array index for disambiguation
	Type     ChangeType
	Field    string // "label", "" for add/delete
	OldValue string
	NewValue string
}

RelationshipChange represents a change to a relationship.

type RelationshipState

type RelationshipState struct {
	From  string `json:"from"`
	To    string `json:"to"`
	Index int    `json:"index"`
	Label string `json:"label,omitempty"`
	Kind  string `json:"kind,omitempty"`
}

RelationshipState captures a relationship's synced values.

type ResolvedConflict

type ResolvedConflict struct {
	Conflict
	Winner  string // "model" or "drawio"
	Warning string // human-readable warning message
}

ResolvedConflict is a conflict with its resolution decision.

type ReverseResult

type ReverseResult struct {
	ElementsCreated      int
	ElementsUpdated      int
	ElementsDeleted      int
	RelationshipsCreated int
	RelationshipsUpdated int
	RelationshipsDeleted int
	Warnings             []string
}

ReverseResult summarizes the changes applied back to the model.

func ApplyReverse

func ApplyReverse(changes *ChangeSet, m *model.BausteinsichtModel) *ReverseResult

ApplyReverse applies draw.io-side changes back to the model.

type SyncResult

type SyncResult struct {
	Forward   *ForwardResult
	Reverse   *ReverseResult
	Changes   *ChangeSet // The (post-conflict-resolution) changes used for sync.
	Conflicts []ResolvedConflict
	Warnings  []string
}

SyncResult contains the comprehensive result of a sync cycle.

func Run

func Run(
	m *model.BausteinsichtModel,
	doc *drawio.Document,
	lastState *SyncState,
	templates *drawio.TemplateSet,
	newPageIDs map[string]bool,
	opts ...ForwardOptions,
) *SyncResult

Run executes one full bidirectional sync cycle. It is a pure function — no file I/O. All data is passed as parameters.

Sequence (Chapter 6 - Runtime View):

  1. DetectChanges → ChangeSet
  2. Resolve conflicts (model wins)
  3. Remove conflicting fields from DrawioElementChanges
  4. ApplyForward → ForwardResult
  5. ApplyReverse → ReverseResult
  6. Collect all warnings

type SyncState

type SyncState struct {
	Checksum         string                  `json:"checksum,omitempty"`
	Timestamp        string                  `json:"timestamp"`
	ModelHash        string                  `json:"model_hash"`
	DrawioHash       string                  `json:"drawio_hash"`
	Elements         map[string]ElementState `json:"elements"`
	Relationships    []RelationshipState     `json:"relationships"`
	RenderedElements map[string]bool         `json:"rendered_elements,omitempty"`
}

SyncState stores the state after each successful sync.

func BuildState

func BuildState(m *model.BausteinsichtModel, doc *drawio.Document, modelPath, drawioPath string) (*SyncState, error)

BuildState creates a SyncState snapshot from the current model and draw.io document.

func LoadState

func LoadState(path string) (*SyncState, error)

LoadState reads a SyncState from the given path. If the file does not exist, an empty SyncState is returned (first-sync scenario).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL