📣The November 15th release is out!Read the release notes

    An astronaut untangling a nest of wires

    Complex queries made easy and typesafe

    TLDR

    We add a new, fully-typed `subquery` builder method, expand the potential of `include`, and add documentation for offline-mode and server-side rendering.

    Fully-typed subquery builder method

    It's now possible to write fully-typed subqueries with the new subquery builder method. This method allows you to add an ad-hoc query on related data to an entity.

    const query = client
      .query('users')
      .subquery(
        'mostRecentBlog', // key to store the result in the parent query
        client // query
          .query('blogs')
          .select(['text'])
          .where('author', '=', '$1.id') // dynamic value from the parent query
          .orderBy('created_at', 'DESC')
          .limit(1)
          .build(),
        'one' // cardinality
      )
      .build();
    

    You'll get type hinting and autocomplete while constructing the subquery, and full types for the result. Docs.

    Relation aliasing and extending with include

    The include method can now be used to extend and alias relations. For example, given a schema with the allFilms relation from directors to films:

    const schema = {
      films: S.Schema({
        id: S.Id(),
        title: S.Id(),
        rating: S.Number(),
        directorId: S.String(),
      }),
      directors: S.Schema({
        id: S.Id(),
        name: S.String(),
        allFilms: S.RelationMany('films', {
          where: [['directorId', '=', '$1.id']],
        }),
      }),
    };
    

    You can write an adhoc query that narrows down a director's films to just their top 3, building off the existing allFilms relation.

    const query = client
      .query('directors')
      .include('bestFilms', (rel) =>
        rel('allFilms').order('rating', 'DESC').limit(3).build()
      )
      .build();
    

    Faster startup times

    We eliminated a bottleneck in the client startup process, which should result in faster initial queries when your app first loads. This will be most noticeable for users with a lot of data in an IndexedDB cache.

    New documentation

    We've added two new sections to the documentation:

    • Offline-mode. Triplit works offline by default, with no additional configuration required. This section explains how Triplit handles user action while offline and how it syncs data when the client comes back online.
    • Server-side rendering. Triplit can run in a server-side rendering environment, such as Next.js or SvelteKit. This section explains how to set up Triplit in a server-side rendering environment. Going forward, we hope to provide more specific integrations with popular server-side rendering frameworks.

    As the pace of contributions to Triplit has picked up, we've also put together a contributing guide to help new contributors get started.