Type Document: ttl and ts marked wrongly as readonly

The properties ttl and ts are marked as read-only which is, in my opinion wrong because the ttl can be updated, and ts changes with every update or replace:

export declare class Document extends DocumentReference {
    readonly ts: TimeStub;
    readonly ttl?: TimeStub;
    constructor(obj: {
        coll: Module | string;
        id: string;
        ts: TimeStub;
        [key: string]: any;
    });
    toObject(): {
        coll: Module;
        id: string;
        ts: TimeStub;
        ttl?: TimeStub;
    };
}

Hi @Mike! I know from previous posts that you’ve been working on some ORM-like domain types to work with your data. Would you be able to elaborate on what you are doing now and why you want to mutate the ttl directly on the Document class instance?

We have intentionally made the typed Document responses from Fauna read-only. When you read a Document from the database, you have only a snapshot in time of that Document, and the immutability is intended to reflect that.

When you use one of the Document types as an argument in a query using the fql function we don’t send any of the data, but only send it as a reference. This is because there is no way of knowing if that Document has changed since you read it last.

The provided types are not meant for the user to mutate them in place and commit the changes. Rather, we are trying to provide round-trip-ability and semantics that make sense for working with a remote data store.

Consider a case where you mutate the data for the Document class and then provide it as a query argument:

const response = await client.query(fql`User.all().first()!`)
const user = response.data // { name: "Paul", ... }

// at some point, change the data
user.name = "Paul Paterson"

// then later use in a query
await client.query(fql`
  let user = ${user}
  // What should `user.name` be here?!
  // ...
`)

What should the value of user.name be in the second query? The answer is neither “Paul” nor “Paul Paterson”, per se, but whatever value is currently in the database.

1 Like

Hi @ptpaterson,
our ORM is a typed replication of the FQL language in Typescript. So you can write directly e.g. User.byId("1") instead as string fql'UserById("")'. Behind the scene we have a normalized cache acting as something like a local fauna database for all fetched documents including refetch and streaming mechanisms.

So if you call User.byId("1").update({}), the local cache will be optimisticaly updated and then send to Fauna and as soon the response arrives from Fauna, the cache will be updated again.
Leading to the point, that in our case the local documents are a replication of the documents in the Fauna database instead of a one-time snapshot.

1 Like