- Define your service API as a json data structure representing virtual SQL tables (the table manifest) and a json data structure representing a list of queries on those tables (the query manifest).
- Run the rowcachec compiler to generate code.
- Implement the handler interfaces that Rowcache generated for the server.
- Emits a TypeScript websocket service client.
- Emits a node TypeScript websocket server. (More server languages could be supported in the future.)
- Emits Protobuffv3 to describe each request and response, then uses protobufjs to generate JS serializers and deseserializers. Describe your data once and get it on both sides of the wire.
- Generates TypeScript type declarations for request and response protobuffs: Send SQL queries and consume SQL results type safely.
- Exposes a Reactive API and a Promise API.
- Emits server-side handler interfaces.
- Rowcache can share facts from a client-side cache to optimize away requests.
- Insert, Upsert, Update, and Delete API.
- Manual fact sharing: teach rowcache how two queries are related by defining a mapping function, and rowcache will share facts between them.
- Transactions and batches.
- Automatic fact sharing: rowcache could use SQL semantics to automatically infer cases where one query is derivable from another.
- Diff-based API.
- Optimstic updating of suscribers when sending writes.
- For those services that are actually backed by an ACID SQL database, a library to translate request protos into SQL prepared statements.
- A utility to read a database schema and generate the table manifest automatically.
- Write your table manifest and query manifest as literal SQL statements, instead of in a pseudo-sql JSON structure.
- Generate validation code that enforces constraints in your table manifest on both sides of the wire (even if your backend isn't TypeScript).
- Support other backend languages. (E.g., Go).
- Support other transport layers. (E.g., grpc-web).
- Latency efficient. The best queries are ones you never have to send. Joins allow you to ask for all the data you need in one shot, and the cache prevents duplicate queries from going over the wire.
- Bandwidth efficient. It's so easy to add another SQL query that you'll never have to ask for data you don't need just to re-use an existing endpoint, nor will you be tempted to inefficiently reuse an existing endpoint in order to get your client-side cache to share results.
- DRY: Only describe your data one time, and use it efficiently and type-safely on both sides of the wire.
- Separation of concerns. You won't be tempted to organize your data service layer as one giant blob of global state, a la Reflux, in order to dedupe / fact share. Each widget knows how to query for the data it wants and how those requests get serviced is an orthogonal concern that is resolved behind the rowcache service API.
- No impedance mismatch. If your data is relational, then querying it relationally is the most efficient way: pass along your database's true power directly to the client.
- Observable or Promise interface to your data.
Rowcache alpha exists now only as a small example that, nevertheless, shows a complete project layout and request-response roundtripping for inserts, query observation, and single-shot queries.
This is a 'developer's release'. The npm module is not hosted on npm yet. You have to compile the module locally and link it to run the example.
cd $REPO
npm install
cd src
tsc
npm link
cd ../example/typescript
npm link rowcache
npm install
npm run bootstrap
cd server
ts-node src/wsserver.ts &
cd ../client
ts-node src/sendqueries.ts
Also take a gander at the manifests, a headless client and the server.
Note that socketserver.ts and socketservice.ts are handwritten now, but are destined to be code-generated in the future.