y-uniffi is a great yjs Swift implementation though,
I have created a completely Swift reimplementation of yjs, as y-uniffi dose not yet have a nested Map, UndoManager, etc. implementation.
Important
Now this library is based on yjs and implemented in Swift for a personal use and is not intended to be fully compatible with yjs.
class Person: YObject {
// Syncronized property
@Property var name: String = ""
// nested proeprty
@WProperty var children: YArray<Person> = []
required init() {
super.init()
self.register(_name, "name")
self.register(_children, "children")
}
convenience init(name: String) {
self.init()
self.name = name
}
}
let person = Person(name: "Alice")
// can use as Combine Publisher
person.$name
.sink{ print("name is \($0)") }.store(in: &bag)
person.$children
.sink{ print("children is \($0)") }.store(in: &bag)
// update to property to sync
person.name = "Bob"
// update nested type to sync
person.children.append(Person(name: "Bobson"))
YRefrence
Store a reference to an object.
class Layer: YObject {
@Property var parent: YReference<Layer>? = nil
@WProperty var children: YArray<Person> = []
func addChild(_ child: Layer) {
self.children.append(child)
// make Reference
child.parent = YReference(self)
}
...
}
let root = Layer("root")
root.addChild(Layer("child0"))
// copy dosen't change a reference.
let copiedRoot = root.copy()
// fail
assert(copiedRoot.children[0].parent.value === copiedRoot)
// smart copy changes a reference.
let smartCopiedRoot = root.smartCopy()
// success
assert(smartCopiedRoot.children[0].parent.value === smartCopiedRoot)
YElement
YElement is a protocol that is inherited by values that can be YArray, YMap values, and YObject properties.
public protocol YElement {
/// Make opaque data concrete.
static func fromOpaque(_ opaque: Any?) -> Self
/// Make concrete data opaque.
func toOpaque() -> Any?
}
You can use YCodable to turn a Codable value into a YElement, or YRawRepresentable to turn an enum into a YElement.
struct Point: YCodable {
var x: CGFloat
var y: CGFloat
}
let array = YArray<Point>()
array.append(Point(x: 1, y: 3))
enum LayerKind: String, YRawRepresentable {
case rect
case text
case path
}
let map = YMap<LayerKind>()
map["rect"] = .rect
map["text"] = .text
Or you can create a YElement by defining your own encoding and decoding.
enum Delta<T: YElement>: YElement {
case by(T)
case to(T)
public func toOpaque() -> Any? {
switch self {
case .by(let value): return ["by": value.toOpaque()]
case .to(let value): return ["to": value.toOpaque()]
}
}
public static func fromOpaque(_ opaque: Any?) -> Self {
let (key, value) = (opaque as! [String: Any?]).first
if (key == "by") { return .by(T.fromOpaque(value)) }
if (key == "to") { return .to(T.fromOpaque(value)) }
fatalError("Unexpected case.")
}
}
yswift
Swift version of yjs.
y-uniffi is a great yjs Swift implementation though, I have created a completely Swift reimplementation of yjs, as y-uniffi dose not yet have a nested Map, UndoManager, etc. implementation.
Important
Now this library is based on yjs and implemented in Swift for a personal use and is not intended to be fully compatible with yjs.
Install
Features
Objects
YArray
Swift implementation of YArray
example
YMap
Swift implementation of YMap
example
YObject
Binding to classes based on YMap
example
YRefrence
Store a reference to an object.
YElement
YElement
is a protocol that is inherited by values that can beYArray
,YMap
values, andYObject
properties.You can use
YCodable
to turn aCodable
value into aYElement
, orYRawRepresentable
to turn an enum into aYElement
.Or you can create a
YElement
by defining your own encoding and decoding.