📣The September 6th release is out!Read the release notes

    An astronaut contemplating underneath a space tree

    Ask deeper questions with `exists`

    TLDR

    We add a new `exists` helper for building relational filters, Vue bindings and new storage options for the Triplit server.

    exists helper for queries with relational filters

    You can now use an exists method to help build subqueries that reference your schema.

    import { Schema as S, exists } from '@triplit/client';
    const schema = {
      todos: {
        schema: S.Schema({
          id: S.Id(),
          text: S.String(),
          assignee_ids: S.Set(S.String()),
          assignees: S.RelationMany('users', {
            where: ['id', 'in', '$assignee_ids'],
          }),
        }),
      },
      users: {
        schema: S.Schema({
          id: S.Id(),
          name: S.String(),
          team: S.String(),
          title: S.String(),
        }),
      },
    };
    
    // Todos where at least one assignee is on the engineering team
    // and has the title of manager
    const query = client.query('todos').where(
      exists('assignees', {
        where: [
          ['team', '=', 'engineering'],
          ['title', '=', 'manager'],
        ],
      })
    );
    

    You may be tempted to write the query above as:

    const query = client
      .where('assignees.team', '=', 'engineering')
      .where('assignees.title', '=', 'manager');
    

    However, this will instead query for todos where at least one assignee is on the engineering team and where at least one assignee has the title of manager.

    Vue support

    Thanks to the contribution of Mo, Triplit now has Vue.js bindings. You can now use useQuery and useConnectionStatus in your Vue components by adding @triplit/vue. We plan on adding a Vue template for create-triplit-app in the coming weeks.

    <script setup lang="ts">
      import Todo from './components/Todo.vue';
      import { schema } from '../triplit/schema';
      import { useQuery, useConnectionStatus } from '@triplit/vue';
      import { computed } from 'vue';
    
      import { client } from './triplit';
      const { fetching, results, error } = useQuery(client, client.query('todos'));
      const { connectionStatus } = useConnectionStatus(client);
      const todos = computed(() =>
        results.value ? [...results.value.values()] : []
      );
    </script>
    
    <template>
      <div>
        <div class="title">
          <h1>Todos</h1>
          <span v-if="connectionStatus === 'OPEN'">🟢</span>
          <span v-else-if="connectionStatus === 'CLOSED'">🔴</span>
          <span v-else>🟡</span>
        </div>
        <span v-if="fetching">Loading...</span>
        <span v-else-if="error">Error: {{ error.message }}</span>
        <ul v-else>
          <Todo
            v-for="todo in todos"
            :key="todo.id"
            :id="todo.id"
            :text="todo.text"
            :completed="todo.completed"
          />
        </ul>
      </div>
    </template>
    

    LMBD, LevelDB and file storage options for local developments and custom servers

    We've added more storage providers for Triplit servers. You can now use LMBD, LevelDB and file storage for your local development server or custom server.

    For instance:

    npx triplit dev -s lmdb
    

    Will start a local development server with LMBD storage. Read the CLI docs to see all of the available storage options for triplit dev.

    You can also use these storage providers if you're building a custom, self-hosted Triplit server. Read the server docs to see how to configure storage providers for your server.

    Safer schema updates in the console

    You've always been able to make changes to your schema with the Triplit console, including adding, removing and updating collections and attributes. Triplit has a validation process for schema changes, that is documented here. Now, those same restrictions are enforced in the console. If you try to make a change that would break existing data, you'll see a warning and the change will not be applied.

    When you're done making changes in the console, you can expect your server schema to be "ahead" of your client schema. To update your client schema, we recommend running

    npx triplit schema print > triplit/schema.ts
    

    Which will update your local schema file with the latest schema from your server.

    New docs for self-hosting with Triplit Cloud

    Connecting a self-hosted machine to Triplit Cloud enables you to use the Triplit Console to view and manage your data, and to use the Triplit Dashboard to update your server's configuration without needing to redeploy it. Read the newly streamlined self-hosted deployments guide to get up and running in no time.

    Simple catch-all filters for easier rules

    Triplit where filters now support simple boolean arguments. For example, you can now write

    const schema = {
      announcements: {
        schema: S.Schema({
          id: S.Id(),
          title: S.String(),
          body: S.String(),
        }),
        rules: {
          read: { anyoneCanRead: { filter: [true] } },
          // No one can write to announcements, but service role tokens ignore rules
          write: { onlyServiceRolesCanWrite: { filter: [false] } },
        },
      },
    };
    

    Check back soon for a blog post on our redesigned rules and permissions system.