TypeScript Client

By default, the ronin package on npm does not require any configuration to function, which is partially due to the fact that the most important piece of configuration (the App Token) is loaded from the RONIN_TOKEN environment variable automatically:

import { get } from 'ronin';

// No further config needed
const posts = await get.posts();

In the case that process.env.RONIN_TOKEN is not available in the global variable scope, you will need to pass the App Token explicitly, like so:

import roninFactory from 'ronin';

const ronin = roninFactory({
  token: 'YOUR_APP_TOKEN'
});

const posts = await ronin.get.posts();

Certain frontend frameworks (like Next.js) will automatically provide process.env, regardless of whether the code is executed on the edge (”Edge Functions”) or in a runtime like Node.js (”Serverless Functions”), despite process.env being a Node.js primitive. This means you never need to pass the App Token manually when using Next.js.

Batching (Transactions)

When running multiple write queries (create, set, or drop) at the same time, it is advised to batch them together as a transaction, which ensures that the respective database operations will be performed atomically.

Specifically, if one of the queries fails to be applied for a certain reason, all of the other write queries will be reverted as well, so the data stored in RONIN is guaranteed to never get into a faulty state.

import { batch, create } from 'ronin';

const [account, session] = await batch(() => [
  set.account({
    with: { id: '1234' },
    to: { emailVerified: true }
  }),
  create.session.with({
    account: { id: '1234' }
  })
]);

In the example above, an “Account” record is first updated, after which a new “Session” record is created for it. The queries are executed in the order in which they are defined, and reverted (if an error occurs) in reverse order, meaning starting from the last.

While database transactions are the designated use case for the exported batch method of the TypeScript client, you may also use it to ensure only a single query request is sent to RONIN, which might benefit the performance of your application:

import { batch, get } from 'ronin';

const [account, session] = await batch(() => [
  get.account.with.id('1234'),
  get.session.with.account.id('1234')
]);

In the example above, the queries are still executed serially inside RONIN, but only a single outgoing network request is performed, meaning that RONIN is only invoked a single time.

Caching

If you’re using Next.js or other frameworks that are caching outgoing fetch requests (which the RONIN JavaScript client uses internally), you can customize the behavior of fetch by passing custom options as config like so:

import roninFactory from 'ronin';

const ronin = roninFactory({
  fetch: { cache: 'force-cache' }
});

const ronin = roninFactory({
  fetch: { next: { revalidate: 3600 } }
});

Note that, for the create, set, and drop query types, the RONIN client specifies cache: 'no-store' by default, which skips the cache in Next.js, for example.

Config Factory

To apply the same configuration for multiple different query invocations (which are called “scratchpads”), you can do so using a so-called “function factory”:

import roninFactory from 'ronin';

const ronin = roninFactory({
  token: 'YOUR_APP_TOKEN'
});

const posts = await ronin.get.posts();
const reviews = await ronin.get.reviews();

If your environment requires you to pass the App Token configuration option explicitly, we strongly recommend initializing the ronin package only once and then passing around the initialized instance to keep your code as clean as possible.