Code Monkey home page Code Monkey logo

aspen-cloud / triplit Goto Github PK

View Code? Open in Web Editor NEW
1.8K 7.0 53.0 25.72 MB

A full-stack, syncing database that runs on both server and client. Pluggable storage (indexeddb, sqlite, durable objects), syncs over websockets, and works with your favorite framework (React, Solid, Vue, Svelte).

Home Page: https://triplit.dev

License: GNU Affero General Public License v3.0

JavaScript 1.97% TypeScript 87.89% MDX 8.95% HTML 0.17% CSS 0.61% Dockerfile 0.01% Shell 0.02% Svelte 0.22% Vue 0.15%
crdt database firestore fullstack multiplayer supabase bun cloudflare-workers deno durable-objects

triplit's Introduction

Triplit banner

Overview

Triplit is an open-source database that syncs data between server and browser in real-time.

Triplit provides a real-time syncing datastore that you can drop into your app as a Typescript package. Triplit handles storing your data on the server and intelligently syncs your queries to your clients. We call this type of system a “full stack database”—you can watch our presentation to the Local First community on this new paradigm here.

Triplit brings together:

🔄 Real-time sync with incremental updates and conflict resolution at the property level

🏠 Local caching powered by a full-fledged client-side database

💽 Durable server-side storage with an admin dashboard

🔌 Pluggable storage providers like SQLite, IndexedDB, LevelDB, Memory, etc

😃 Optimistic updates to make every interaction feel fast

🔗 Relational querying for complex data models

🛫 Offline-mode with automatic reconnection and consistency guarantees

🔙 Rollback and retry management on failed updates

🗂️ Schemas for data safety and Typescript autocompletion

🔐 Authorization that's enforced on the server for both read and writes

🤝 Collaboration/Multiplayer powered by CRDTs

🏎️ Low latency with minimal network traffic using delta patches

📝 Simple API for querying and mutating data in both vanilla Javascript and React

✅ Fully open-source!

Monorepo Overview

In triplit/packages you can find the various projects that power Triplit:

  • TriplitDB - Designed to run in any JS environment (browser, node, deno, React Native, etc) and provide expressive, fast, and live updating queries while maintaining consistency with many writers over a network.
  • Client - Browser library to interact with local and remote TriplitDBs.
  • CLI - CLI tool with commands to scaffold a project, run the full-stack development environment, migrate a server, and more.
  • React - React bindings for @triplit/client.
  • Svelte - Svelte bindings for @triplit/client.
  • Console - App for viewing and mutating data in Triplit projects and managing their schemas.
  • Server - Node server for syncing data between Triplit clients.
  • Server-core - Protocol agnostic library for building servers running Triplit.
  • Docs - Triplit docs, built with Nextra.
  • Types - Shared types for various Triplit projects.
  • UI - Shared UI components for Triplit frontend projects, built with shadcn.

Quick Start

Start a new project.

npm create triplit-app@latest my-app

Or add the dependencies to an existing project.

npm install --save-dev @triplit/cli
npm run triplit init

Define a schema in my-app/triplit/schema.ts.

import { Schema as S, ClientSchema } from '@triplit/client';

export const schema = {
  todos: {
    schema: S.Schema({
      id: S.Id(),
      text: S.String(),
      completed: S.Boolean({ default: false }),
    }),
  },
} satisfies ClientSchema;

Start the Triplit development sync server.

npm run triplit dev

This will output some important environmental variables that your app will need to sync with the server. Add them to your .env file (Vite example below).

VITE_TRIPLIT_SERVER_URL=http://localhost:6543
VITE_TRIPLIT_TOKEN=copied-in-from-triplit-dev

Define a query in your App (React example below).

import { TriplitClient } from '@triplit/client';
import { useQuery } from '@triplit/react';
import { schema } from '../triplit/schema';

const client = new TriplitClient({
  schema,
  serverUrl: import.meta.env.VITE_TRIPLIT_SERVER_URL,
  token: import.meta.env.VITE_TRIPLIT_TOKEN,
});

function App() {
  const { results: todos } = useQuery(client.query('todos'));

  return (
    <div>
      {Array.from(todos.values()).map((todo) => (
        <div key={todo.id}>
          <input
            type="checkbox"
            checked={todo.completed}
            onChange={() =>
              client.update('todos', todo.id, (todo) => ({
                todo.completed = !todo.completed,
              })
            }
          />
          {todo.text}
        </div>
      ))}
    </div>
  );
}

Start your app, open another browser tab, and watch the data sync in real-time.

Read the full getting started guide here. For an even more detailed and explanatory tutorial, check out this step-by-step guide to building a real-time todo app with Triplit, Vite, and React.

Contact us

If you're interested in getting early access to Triplit Cloud (currently in developer preview), sign up here to join the waitlist.

The best way to get in touch is to join our Discord! We're here to answer questions, help developers get started with Triplit and preview new features.

You can follow us on Twitter/X to see our latest announcements.

triplit's People

Contributors

armincerf avatar github-actions[bot] avatar honeymaro avatar i-am-henri avatar itoxiq avatar matlin avatar mentalgear avatar pbohlman avatar samuellawrentz avatar simonbukin avatar wernst avatar wonderpanda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

triplit's Issues

Deletes do not sync to disconnected clients

Reproduction:

  • Run a client with persistent storage, get it in sync with the server
  • Take the client offline
  • Perform a delete (remotely from a different connected client)
  • Take the client back online, the deletion does not sync to the client

Add tools to aid with seeding the db with data

Just jotting down some ideas here, am happy to edit this issue to refine/exclude anything you think shouldn't be in scope for this project.

  • Import data from file via the console (csv/json etc)
  • Import via cli
  • Add seed files in whatever format to a folder on the machine hosting the server, on startup the server applies those transactions if they are new (ala the many tools available for RDMS systems)

Codegen cannot handle kebab-case collection names

Reproduction:

  • Create a collection on remote with a kebab-case name
  • Run triplit migrate pull
  • Codegen fails

This appears to be a general issue that keys need to be wrapped in strings before prettifying them in the codegen process

Request: addative query builder api

Currently the query builder will overwrite values if the same method is used twice. For example client.query('todos').where(['completed', '=', true]).where('author', '=', 'alice') will just include the second where clause. An api like this could be preferred to many filter tuples in a single where statement, and also lets you define a base query with a filter in a variable then append to the where clause later.

There are some complicated edits you could make to a query's filters if the filter is deep and complex (ie deep ands / ors), so we'd need to figure out if/how the api would handle that.

Using triplit with react native, running into some problems

I'm running into a few problems trying to use triplit with react native. One is that after installing triplit, i see this anytime i install:

code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^18.3.1" from the root project
npm ERR!   peer react@"^16.8.0 || ^17.0.0 || ^18.0.0" from @ahooksjs/[email protected]
npm ERR!   node_modules/@ahooksjs/use-url-state
npm ERR!     @ahooksjs/use-url-state@"^3.5.1" from @triplit/[email protected]
npm ERR!     node_modules/@triplit/console
npm ERR!       @triplit/console@"^0.3.44" from @triplit/[email protected]
npm ERR!       node_modules/@triplit/cli
npm ERR!         dev @triplit/cli@"^0.3.47" from the root project
npm ERR!   33 more (@emotion/react, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"18.2.0" from [email protected]
npm ERR! node_modules/react-native
npm ERR!   react-native@"0.72.6" from the root project
npm ERR!   peer react-native@"^0.0.0-0 || 0.60 - 0.72 || 1000.0.0" from @react-native-async-storage/[email protected]
npm ERR!   node_modules/@react-native-async-storage/async-storage
npm ERR!   11 more (@react-native-community/checkbox, ...)
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"18.2.0" from [email protected]
npm ERR!   node_modules/react-native
npm ERR!     react-native@"0.72.6" from the root project
npm ERR!     peer react-native@"^0.0.0-0 || 0.60 - 0.72 || 1000.0.0" from @react-native-async-storage/[email protected]
npm ERR!     node_modules/@react-native-async-storage/async-storage
npm ERR!     11 more (@react-native-community/checkbox, ...)
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/tanishqkancharla/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/tanishqkancharla/.npm/_logs/2024-04-28T23_11_58_027Z-debug-0.log

something about peer dependencies.

Request: dont make me manually migrate my database on each restart during local development

When you run triplit dev your database server starts. Although the storage option is available to specify more persistent storage (like sqlite) it is not the default, instead the database will start with en empty in-memory storage instance.

Because the db starts empty, your migrations aren't tracked on the remote database and that can cause some small issues or features to not run (like authz).

From a pure ux perspective its tough to remember to run these migrations and I have to switch to a different terminal window to run them.

Suggestions:

  • Run your local migrations when starting the triplit dev server
  • When dev runs, if there are unapplied migrations, suggest that i run them
  • larger refactor surrounding how schemas/migrations are applied in local development

Synchronize between 2 clients and 1 server doesn't work

Hi! Thanks for the awesome libraries/database! I'm having a strange issue with Triplit's synchronization, however: when I set up 2 clients and 1 server, it won't work at all. I'll try to provide a more minimal way to reproduce, but it basically is:

  • I set up my client application at localhost:5173, and also expose it to local network (make it reachable through 192.168.x.y:5173)
  • I set up the development server at localhost:8080, and also expose it to local network (make it reachable through 192.168.x.y:8080)
  • On my desktop, I visit my client application at localhost:5173, and set the server's URL to localhost:8080
  • On my mobile phone, I visit my client application at 192.168.x.y:5173, and set the server's URL to 192.168.x.y:8080

The synchronization won't work at all between the desktop application and the mobile phone application: I let both connect to the server, but they won't have the same data.

What do you think? Thanks again!

IndexedDbStorage missing idb dependency

When using the IndexedDbStorage provider it appears a dependency to 'idb' is missing

import { IndexedDbStorage } from "@triplit/db/storage/indexed-db";
import { TriplitClient } from "@triplit/client";
const client = new TriplitClient({
  db: {
    storage: {
      client: new IndexedDbStorage("tripchat-client"),
      outbox: new IndexedDbStorage("tripchat-outbox"),
    }
  }
});

At runtime:
ERROR: Could not resolve "idb/with-async-ittr"

Include or export utilities for query building

Certain APIs dont have easily accessible query builders. They dont really use a lot of state, so we could export them to make them accessible. Or add a query api to RemoteClient and other utilities without query building capabilities.

Remote client fails to infer types based on query and schema

Example:

const client = new RemoteClient({ schema });
const result = await client.fetch({
    collectionName: 'todos',
});

// Result is Map<string, any>

I think we need to properly type the query parameter of fetch (so we can pull out the schema and proper return type) or ensure that happens under the hood of fetch somewhere.

Make connection errors more accessible

Although I can hook into the connection state, I don't have much information as to WHY a client cannot connect.

For example, I may have a malformed connection token, but have no way to pull this specific error information out of the client or react packages.

Without providing this, the app can really only inform the user the app is disconnected, but not what it could do about it (or if it expects that it may be able to reconnect).

chat template: `Missing required params: [token]. Skipping sync connection.`

Hi folks! I'm trying to setup the chat example locally on my machine. I followed all the steps in the README, including making a github app and filling in the details in .env. On running the app, I get this warning in my console:

image

And in the triplit terminal, I see this:
image

Because of which (I think) I'm not seeing any syncing across browsers. Do you folks have any pointers for how I can get this working? Thank you!

Removals from queries arent properly synced when a client connects

It seems based on how we initialize queries when connecting, we may miss updates based on filters.

Reproduction:

  • Set up a subscription to a query with a filter on client A and client B
  • Add some data
  • Take client B offline, mutate data on client A so it is evicted from the query result
  • Bring client B back online, see query result does not contain updates

Native Mobile Support

Feel free to close this issue if this is documented somewhere and I missed it. I like the idea here but I found nothing about android support. Is the idea that if you want mobile app support that you should use react native? That's not an option for me but it would be very nice to have some sort of integration with Compose / modern android primitives.

Case-insensitive sort

Hi. I'm trying to use query.order, but it seems like it is case-sensitive (A... comes before a...). Is there anyway to make the query case-insensitive (a... and A... are treated the same, but they come before b...)? Thanks!

SolidJS

Hi! Awesome stuff. I've been pulling my hairs solving local-first. How are you guys seamlessly making this look easy. Any limitations encountered so far? What conflicts can Triplit not handle?

In any case... It would be great to have a Solid adapter for this.
How much work would it take to port an adapter for SolidJS? (If it's not super difficult, I'd love to give it a shot)

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.