Git Product home page Git Product logo

yswift's Introduction

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

dependencies: [
    .package(url: "https://github.com/ObuchiYuki/yswift.git", branch: "1.0.0"),
]

Features

  • Supported collaborative types:
  • Text
    • text insertion
    • embedded elements insertion
    • insertion of formatting attributes
    • observe events and deltas
  • Map
    • insertion, update and removal of primitive JSON-like elements
    • recursive insertion, update and removal of other collaborative elements of any type
    • observe events and deltas
    • deep observe events bubbling up from nested collections
  • Array
    • insertion and removal of primitive JSON-like elements
    • recursive insertion of other collaborative elements of any type
    • observe events and deltas
    • deep observe events bubbling up from nested collections
    • move index positions
  • XML Types (Intentionally not supported)
  • Sub documents
  • Transaction origin
  • Undo/redo manager
  • Encoding formats:
    • lib0 v1 encoding
    • lib0 v2 encoding
  • Transaction events:
    • on event update
    • on after transaction
  • Tests
    • yjs tests
      • doc.tests
      • encoding.tests
      • snapshot.tests
      • undo-redo.tests
      • udpates.tests
      • y-array.tests
      • y-map.tests
      • y-test.tests
    • yswift tests
      • y-array.swift.tests
      • y-map.swift.tests
      • y-object.swift.tests
      • integration.swift.tests

Objects

YArray

Swift implementation of YArray

final public class YArray<Element: YElement> 
example
// init with array literal
let intArray: YArray<Int> = [1, 2] 
print(intArray) // [1, 2]
// index access
print(intArray[1]) // 2

// append Element
intArray.append(3) 
print(intArray) // [1, 2, 3]

// append Sequence
intArray.append(contentsOf: [4, 5]) 
print(intArray) // [1, 2, 3, 4, 5]

// range access
print(intArray[2...]) // [3, 4, 5]

// use as Sequence
for i in intArray { 
    print(i) // 1, 2 ...
}

// YArray with YMap type
let mapArray: YArray<YMap<Int>> = [
    ["Apple": 160]
]

mapArray.append(["Banana": 240])

YMap

Swift implementation of YMap

final public class YMap<Value: YElement> 
example
// init with dictionary literal
let intMap: YMap<Int> = [
    "Apple": 160
] 

// subscript access
intMap["Banana"] = 240
print(intMap["Apple"]) // 160

// nested map
let arrayMap: YMap<YArray<Int>> [
    "Alice": [12, 24],
    "Bob": [24, 64, 75]
]

YObject

Binding to classes based on YMap

open class YObject: YOpaqueObject
example
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's People

Contributors

obuchiyuki avatar

Stargazers

 avatar David avatar Igor Tarasenko avatar  avatar Jessé Correia Lins avatar fantasticit avatar Jonathan Yee avatar Martin Gratzer avatar Jeff Lewis avatar Sami Samhuri avatar Max Baumbach avatar Marc Bauer avatar Steve Harris avatar Stef Kors avatar Neil Allain avatar Jonathan Wight avatar Eden avatar Bharath Nadampalli S avatar Nikita avatar Tim Kersey avatar Kerem Cesme avatar Vatsal Manot avatar Max Garber avatar Kai Oelfke avatar Joseph Heck avatar  Kevin Jahns avatar AranoYuki avatar  avatar Aidar Nugmanoff avatar Ryohei Ikegami avatar

Watchers

 avatar  avatar

yswift's Issues

Errors in the build file

Whenever i try to add this yswift package to my project and try to build the file there seems to be a lot of errors in the yswift module itself.Is it just for me or for everyone using this package.If so kindly help me navigate through this error as this repositoy helps me to create an YArray with YMap type easily without any pre defining them unlike other yswift repositories.There is almost close to 58 errors found on the yswift package itself when i try to build the project.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.