vlcn-io / vlcn-orm Goto Github PK
View Code? Open in Web Editor NEWDevelop with your data model anywhere. Query and load data reactively. Replicate between peers without a central server.
Home Page: https://vlcn.io
License: Other
Develop with your data model anywhere. Query and load data reactively. Replicate between peers without a central server.
Home Page: https://vlcn.io
License: Other
The client facing API always presents the right generics. Internal to the framework they aren't always correct, however.
The problem has to do with queries being able to return different projects.
E.g.,
id, node, edge, hop with nodes projections.
And maybe edges being partially optimized (rolled into prior expressions) as well.
Todo lists barely require any interesting functionality.
Re-write strut to use Aphrodite and/or some other non-trivial apps.
see aphrodite-browser-starter
index.ts where we had to add the any
cast.
gen
in Base
and whereX
in query methods
Problem on generics where passing T | null
when T
is expected.
see linked diff
test that the codegen re-generates some expected output
See linked project description
wa-sqlite serializes reads that are on the same connection.
We should update the sqlite connectors to:
To allow for parallel reads.
Should we allow defining edges without defining id fields??
Foo as Node {
blahId: ID<Blah>
} & OutboundEdges {
blah: Edge<Foo.blahId>
}
to:
Foo as Node {
} & Edges {
blah: OneToOne<Blah>
}
but this removes control from the developer and feels a bit opaque.
Schema -> Models -> TSGraphQL -> ...
related to #24 which needs to be done first (before/after support).
See linked project description.
in SQLExpression.ts
Given the focus on local-first software the initial list would be:
And to not completely preclude adding a server as a peer for server side syncing
What else? The list should be fairly limited until we've proven the concept.
Should be trivial given current use of chunk iterables.
Some sort of modifier to allow returning the node that was traversed when doing nested traversals.
Similar to:
This kind of reminded me of https://riffle.systems/essays/prelude/ . Maybe you find the ideas presented there interesting and relevant.
Feel free to close this issue for lack of actionable items.
@databases connections do not support 64 bit ints. They silently get truncated.
better-sqlite returns everything as bigints. Not great.
sqlite-3 has a fork that returns ints as strings if they'd overflow.
Bundle all the various runtime-ts
packages into one so its easier for clients to use. Would require updating codegen to import from this single package.
Right now we're using our own 64bit int id generation scheme (loosely based on https://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_uuid-short). Problem is peer ids are not so easily assigned as server ids. Given the issue with assigning ids to peers (and clock skew between peers), I've done no formal verification that this won't collide.
Security would be another concern. What are the attack vectors in the p2p space when the id space is partially deterministic? Data that is shared between trusted peers wouldn't have an issue. "Public" apps where any peer can connect could have malicious peers that try resetting their clocks to clobber data. Authz rules and hmac'd replications should prevent this, however?
We could use nanoid but that has the concerns raised here https://www.percona.com/blog/2019/11/22/uuids-are-popular-but-bad-for-performance-lets-discuss/
maybe that doesn't matter given local first apps likely won't have datasets large enough for this to become an issue.
Given all the unknowns with sid
and the probably small perf hit with nanoid
-- we should go with nanoid
for now.
If schema definitions are removed, remove the generated code too.
Fields can be:
Lets add:
Explore adding:
Explore:
Should we just extend the GraphQL schema spec and use that for Aphrodite schemas?
Thought about this off and on for a long time.
A prompt that got me thinking in this direction one more time was GraphJin:
If a user strictly performs optimistic writes (without awaiting for the write to complete) they can issue a read that doesn't return what they expect.
The current design requires hitting the database to fulfill any query. So issuing a write that you don't await can result in a later query not returning the data in that write.
We can:
wa-sqlite-connector
as all those operations are serializedWhen we make changes for #46 we'll have to consider how it impacts this task.
Reactive queries do not update optimistically. This might not be a big deal but could lead to strange behavior where a component lags behind another. When tackling #49 we can address parts of this problem. E.g., by making single hop reactive queries resolve themselves in-memory.
So users can understand if all clauses are optimized or not.
Log a warning when a non-optimized query is run against a dataset of >1k rows.
like #57 but a language server component for auto-complete.
watch and auto-regenerate on schema change
I know it's early on, but I'm just tinkering with this. One thing I'd like to express in a query is a predicate which is related to another field on a model.
Example use case: a grocery list app which lets you change the quantity of items. Suppose you've already purchased 6 eggs, but you increase the desired quantity to 12. In order to express a query for "purchased items," I want to query all items where item.purchasedQuantity >= item.desiredQuantity
.
The scope here would only be predicates relevant to other fields on the same model, not traversing edges or anything like that.
https://github.com/tantaman/aphrodite/tree/main/packages/vscode provides syntax highlighting support for Aphrodite schemas. We should complete and publish this extension
interesting discussion at 45 min and beyond: https://museapp.com/podcast/56-sync/
https://adamwulf.me/2022/04/atomic-attributes-in-local-first-sync/
https://www.datomic.com/
Potential route to have a single table in sqlite that contains all the atoms of the application.
Currently we just re-run a query whenever one of its queried tables is updated.
This is good enough for now (based on current perf numbers and being in beta) but in the future if we need row-level reactivity some ideas are:
For single hop queries, we can run expressions in-memory against the modified/created/deleted node.
For multi-hop we of course lose the ids of the nodes we joined on. We have a few options:
While pure sqlite is great it is quite a bit of bloat to bring into the browser.
Is it worth supporting indexeddb directly?
Some reasons to do it:
Not to:
SourceExpression
type to supportIf not all peers are trusted, how can we ensure their changes are rejected?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.