-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swift platform #97
Comments
Is this effort open to contributions? I would be very happy to help with the shaping and implementation of the Swift components. |
Hi @kkostov 👋, very open, thanks for the offer! Our top priority on the Swift platform is to create a great dev experience. So we're looking at having a very "Swifty" API that's object-oriented and reactive (via Compose), which wraps around the core m-ld API (three methods and lots of JSON 🤖). Here's our thinking so far: https://github.com/m-ld/m-ld-swift-poc We'd be really interested in your thoughts about that... and if you've got other ideas we'd love to talk about those too! |
Awesome, sounds great! I will have a look at the POC and share some insights. |
Hey @kkostov, great to have you stop by! Thanks for your offer to contribute; would be fantastic to get the input of someone with a lot of relevant experience to help make this as good as it can possibly be. Looking forward to hearing your feedback on the PoC, and to working with you! |
My apologies for the late reply. It's been one of those weeks 😅. I had a chance to review the PoC, and you did a great job translating a complex concept into an understandable client library! 🙌 I was delighted to see Swift Concurrency features like actors in use for the I would like to understand your concrete goals for the PoC, e.g., evolving the PoC to become a stand-alone library. Are there technological/conceptual aspects that remain experimental or theoretical and need to be de-risked within the scope of the PoC? The JavaScript library can be an inspiration here (although perhaps Meld for iOS can offer an even higher level API to "flatten" the initial learning curve). For example, consider making an SPM package that implements an Meld() // in memory storage with basic sync support
Meld(domain: .json) // local json storage with basic sync support
Meld(domain: MyCustomDomain()))
Meld(sync: MeldMultiPeerSync()) I like the idea of being able to select subjects based on a query or some predicate (do you see this as a custom DSL in the future?). Consider, for example, the implementation details of I also noticed that Subjects are instances of an object (reference types). It will be great if the choice between value and reference types remains with the developer. What is a good first step that I could undertake? |
Hey Konstantin! Thanks for your review and for your thoughts & ideas, wonderful 🙏 Our goals for the PoC are:
So the next steps include upwards (API) improvements, and downward (core) implementation. Lots more details below. My intuition is that you might be more interested with the API side. In any case, I think the first concrete step is to expand the example, so that it tests out writing data to the domain (and so, shakes out the usability of ideas like Although, if you think it's better to start with system tests rather than an example app, that's cool too. Any other ideas you have are most welcome. Maybe we can keep looking at the bigger picture in this thread, at the same time. APIThe constraints on the API are basically just that it must be implementable with m-ld... though of course we always want to improve m-ld, and we certainly will based on this work! The PoC is definitely a higher-level API, for flattening the learning curve, in the way you suggest. In that role it's opinionated, for example about references. Note that we've been working on a higher-level object-oriented API in Javascript too. I'm writing baseline documentation for it right now, and I'll link that here very soon. Yes, the PoC should evolve into a library, increasing the separation between it and the example app. I think one SPM package for the main lib is probably the way to go for now, but maybe other API patterns ultimately deserve their own lib. For example, one possible future packaging might be: graph RL
C(Functional API) --> A(m-ld Core)
B --> A
subgraph "(Current POC)"
D[Conferences Example App] --> B(Object-Oriented API)
end
With regard to separating storage and transport options, that's how the JS engine works, with its entry point, which uses injected dependencies for each. Having swappable sync options (concurrency models) too – that's very interesting. The idea with m-ld is that it will be able to support multiple concurrency models (concurrently!). That's the direction of some of our research right now. Having this choice on initialisation is certainly something we could do, even if we change how the choice is made in future. I love Other key open research questions in the API design are:
coreSo, how are we going to implement the API, whatever shape it takes? The core m-ld protocol is still in motion, so our idea here is to learn as much as we can with a simulated engine before diving into a full implementation. However, the simulation itself should be as useful as possible right from the start! We can learn a lot with a local un-synced JSON-file backend, but we should move as fast as possible to something with some sync, to shake out how the API behaves with concurrent changes. So one idea is to implement a back-end sync service, deployable locally with Docker and also on the cloud. This service would use m-ld-js internally and expose the clone JSON API via HTTP. Since this introduces the possibility of concurrent clients, we'd implement some naive optimistic locking just to ensure data integrity. So some transaction commits may incur a lock violation; which you wouldn't see if you used a local m-ld engine. Another option is to try and package up the m-ld-js engine, so it can be run as a process locally, in parallel with the app that's using the Swift API. Not being an iOS expert I don't know whether this is more trouble than its worth, or even possible! E.g. Interprocess communication on iOS with Mach messages sounds a bit arcane & brittle 😳. Plus, local persistence and network connections from the process might be tricky/impossible. |
Sounds good!
Your intuition is correct. I can try implementing the
Cool! There are not a lot of JSON-LD libraries currently available for Swift. To create a json-rql DSL, we can take advantage of some Swift 5.4+ features like result builders! We can start this as a separate SPM (which is not specific to Meld, but rather json-rql in general).
The answer is a solid Yes. App performance is paramount when building apps for iOS. As a developer, I need a way to quickly access a subset of data with minimal impact on the system. One example is the expectation that a native app should be loaded and interactive by the time the launch animation is complete (that is, the animation that "expands" the app from the icon when you tap it on the Home screen). That's under 400ms to load the start screen, get data and render it. How to represent it is an interesting question. My first thought is that it should be transparent, e.g., the library does what it needs to do by default. Some options to customize this can be provided, e.g., to force a query to be loaded on demand.
Good question. If a relation is defined using a property attribute, perhaps this can be added as an argument, e.g.: class Notebook {
// ...
var notes: Note[]
}
class Note {
// ...
@MeldField("notebookId", onDelete: .cascade)
var notebook: Notebook
var notebookId: String
}
Agreed, I think having a clear action to designate saving/updating changes makes a lot of sense. I'd also consider a .rollback() or similar which resets the subject back to last known state (e.g. in case of accidental writes on the objects).
That's a good idea. For simplicity, it could use the already existing js library (for a Node-based solution), or we could start creating a Swift Package, which can be used both on the client and the server e.g using Vapor. |
Great thoughts & actions, thanks Konstantin!
Awesome, thanks. You could create a ticket in the repo for further discussion if you like. In any case, I've given you direct write access to the repo.
Agreed. Would you like to create a repo for that? – you'll have a much better idea that me about how best to set that up. (I've generally created json-rql stuff on my personal account.) I've created three tickets in the POC repo for these bits:
Yes! The Swift Package is the actual Swift engine (this ticket!). We can certainly embark on that. It would help for us to first document the clone protocol. We've held off on that so far because it's still in flux. Packaging up the Node library as a process/image in the interim has also just come up in another discussion, in relation to using it in a PHP environment (before having a PHP engine). I'll reference both motivations from here into #41. |
m-ld for Swift is coming soon (we're already working on it). This is for peer-to-peer live data sharing among iOS, iPadOS and MacOS devices (and with other platforms that can run m-ld, such as JavaScript).
Please +1 this issue to vote for it.
The text was updated successfully, but these errors were encountered: