Skip to content

Document usage of JS Date object discouraged in Datastore #332

@peterpeterparker

Description

@peterpeterparker

Motivation

Data saved in the datastore is stored as a Blob, which we stringify and parse on write and read. To handle types not natively supported by the APIs, such as BigInt or Principal, we use reviver and replacer functions.

Today, we discussed extending support for mapping dates.

const tmp = {date: new Date()};
const tmp1 = JSON.stringify(tmp);
console.log(JSON.parse(tmp1));
// { date: "2025-02-26T12:37:47.624Z" } <---- a string

Our original intention was to improve the functions to map those types, but unfortunately, when I started the implementation, I realized this wasn't a perfect solution because it would come with a performance cost. Indeed, in a JSON replacer, it isn't possible to detect if an unknown value is a date by checking first if it's an instanceof Date. This is because JavaScript already transforms dates before calling the replacer.

export const jsonReplacer = (_key: string, value: unknown): unknown => {
  if (typeof value === "bigint") {
    return { [JSON_KEY_BIGINT]: `${value}` };
  }

  if (nonNullish(value) && value instanceof Principal) {
    return { [JSON_KEY_PRINCIPAL]: value.toText() };
  }

  if (nonNullish(value) && value instanceof Uint8Array) {
    return { [JSON_KEY_UINT8ARRAY]: Array.from(value) };
  }

  const isValidDate = (value: unknown): value is Date =>  value instanceof Date && !isNaN(value.getTime());

  // ❌ Does not work
  // value is not a Date object but already a string. As for example `2023-11-14T22:13:20.000Z`.
  if (nonNullish(value) && isValidDate(value)) {
    return { [JSON_KEY_DATE]: value.getTime() };
  }

  return value;
};

Potentially, we could use a regex or even try to construct a Date object, but given that the replacer is recursive, doing so would have quite a performance impact.

That's why I stopped working on this and why I think it's best to add a note in the documentation to advise developers not to use the Date object in their data types.

Source

OC: https://oc.app/community/vxgpi-nqaaa-aaaar-ar4lq-cai/channel/321040078/391

Follow-up of #1283

What to do

In the documentation of the Datastore, either in an existing chapter, a new chapter, or even a new page—open to suggestion—add a note that it's advised not to use the Date object for the data of documents.

Provide a short explanation based on the reasons above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions