You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+49-48Lines changed: 49 additions & 48 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,13 @@
1
1
# Deep Copy and Patch for Go
2
2
3
-
`deep` is a high-performance, reflection-based library for manipulating complex Go data structures. It provides three primary capabilities: recursive deep copying, structural diffing to produce patches, and a fluent API for manual patch construction.
3
+
`deep` is a high-performance, reflection-based library for manipulating complex Go data structures. It provides recursive deep copying, structural diffing to produce patches, a fluent API for manual patch construction, and first-class support for distributed state synchronization (CRDTs).
4
4
5
5
## Features
6
6
7
7
***Deep Copy**: Full recursive cloning of structs, maps, slices, and pointers.
8
8
***Deep Diff**: Calculate the semantic difference between two objects.
9
9
***Rich Patching**: Apply patches with atomicity, move/copy operations, and logging.
10
+
***Conflict Resolution**: Pluggable resolvers for convergent synchronization (CRDTs).
10
11
***Conditional Logic**: A built-in DSL for cross-field validation and soft-skipping (`If`/`Unless`).
11
12
***Standard Compliant**: Full support for JSON Pointer (RFC 6901) and JSON Patch (RFC 6902).
12
13
***Production Ready**: Handles circular references and unexported fields transparently.
@@ -35,14 +36,54 @@ if patch != nil {
35
36
36
37
---
37
38
39
+
## Distributed State (CRDT)
40
+
41
+
`deep` includes a first-class CRDT engine for synchronizing complex Go structures across multiple nodes without a central coordinator.
42
+
43
+
### Why Deep CRDTs?
44
+
Most CRDT libraries only handle primitives. `deep` uses its structural awareness to provide **granular, field-level convergence** for your existing Go types.
By tagging slice elements with `deep:"key"`, `deep` enables **Yjs-style semantic patching**. This ensures that concurrent insertions into a list interleave correctly rather than overwriting each other or failing due to index shifts.
64
+
65
+
```go
66
+
typeDocumentstruct {
67
+
Text []Char`deep:"key"`// Enable semantic list merging
68
+
}
69
+
```
70
+
71
+
---
72
+
38
73
## Core Concepts
39
74
40
-
### The Patch Model
41
-
A `Patch[T]` is a tree of operations. Unlike simple key-value maps, `deep` patches understand the structure of your data. A single patch can contain replacements, slice insertions/deletions, map manipulations, and even data movement between paths.
75
+
### Pluggable Resolution
76
+
You can provide custom logic to mediate how patches are applied using the `ConflictResolver` interface. This is how the CRDT package implements Last-Write-Wins (LWW) via Hybrid Logical Clocks (HLC).
77
+
78
+
```go
79
+
// Use a custom resolver to implement business-specific merge rules
80
+
err:= patch.ApplyResolved(&target, myResolver)
81
+
```
42
82
43
83
### Consistency Modes
44
84
***Strict (Default)**: `ApplyChecked` ensures the target value matches the `old` value recorded during the `Diff`. If the target has changed since the diff was taken, the patch fails.
45
-
***Flexible**: Disable strict checking using `patch.WithStrict(false)` to apply changes regardless of the current value, relying instead on custom Conditions.
85
+
***Flexible**: Disable strict checking using `patch.WithStrict(false)` to apply changes regardless of the current value.
86
+
***Resolved**: Use `ApplyResolved` to handle concurrent edits via a custom resolution strategy.
Tell `Copy` to zero-out types it cannot handle (like functions or channels) instead of returning an error:
132
-
```go
133
-
dst, _:= deep.Copy(src, deep.SkipUnsupported())
134
-
```
135
-
136
-
---
137
-
138
143
## Technical Details
139
144
145
+
### Hybrid Logical Clocks (HLC)
146
+
The CRDT package uses HLCs to provide causal ordering of events without requiring perfect clock synchronization between nodes.
147
+
140
148
### Unexported Fields
141
-
`deep` uses `unsafe` pointers to read and write unexported struct fields. This is required for true deep copying of third-party or internal types where fields are not public.
149
+
`deep` uses `unsafe` pointers to read and write unexported struct fields. This is required for true deep copying of third-party or internal types.
142
150
143
151
### Cycle Detection
144
152
The library tracks pointers during recursive operations. Circular references are handled correctly without entering infinite loops.
145
153
146
-
### Custom Copiers
147
-
Types can control their own cloning logic by implementing `Copier[T]`:
0 commit comments