Skip to content

Type System

Jesse Gibson edited this page Dec 25, 2019 · 6 revisions

Note: types are very much a work in progress. All this is subject to change.

Types are fundamental to the redesign. They're at the core of everything I'm striving for.

Mytosis defines a few base types. Everything else is built on those. They are:

  • string
  • number
  • boolean
  • pointer (a string + the type of thing it points to)
  • literal (a literal primitive value)
  • union (represents one of a set of types)
  • Composite (an object whose fields are known in advance)

There's also a notion of a derivation, a type derived from a primitive. For example, date might be a derivation of a UTC-based ISO string.

These types can be mixed and matched in order to create some interesting type signatures. For example:

// An enum of strings
union([literal('online'), literal('offline')])

// A user-ish object
const User = Composite({ firstName: string, lastName: string })

// A nullable user
union([pointer(User), literal(null)])

Composite types are an internal mechanism - they won't be exposed to the end developer. Composites are used to define higher-level types such as Registers and Records. When you define a new Register, it wraps the type information with extra metadata internal to the CRDT:

const createRegister = valueType => Composite({
  type: string,
  clock: number,
  value: valueType,
})

In addition, if you pass a reference to another Register or Record, it'll replace that reference with a pointer. But that has nothing to do with the type system. I'm getting off topic.

Migrations

This is where stuff gets interesting! There's a high likelihood that you'll change your schema at some point in the future. Migrations help you do that.

Migrations are applied in a set. If any migration fails, it rolls back to the original value. Each set of migrations bumps a migration version number by 1 (you might've seen type@version in some other wiki pages).

There's one major limitation: you can't define your own migration operations in code. You have to pick from the list of supported operations.

Here's the list of supported migrations:

  • Add field (requires a default value)
  • Remove field (deletes the data too)
  • Change type of field (coerces any existing data into the new type)
  • Rename field (moves data along with it)

Since you have no immediate consistency guarantees, there aren't any cross-type migrations. You can't move something from one "table" to another, you can only rename it. There might be safe ways around this. I haven't thought of them yet.

Clone this wiki locally