dfinity / agent-js

A collection of libraries and tools for building software around the Internet Computer, in JavaScript.

Home Page:https://agent-js.icp.xyz

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Serialising responses and state management

infu opened this issue · comments

commented

Is your feature request related to a problem? Please describe.
Currently Agent responses include Bigint, Principal (class) and typed arrays (Uint8array)
I believe thats made to increase performance.
But these can't be stored in state.
One of the rules in state management libraries: "Do Not Put Non-Serializable Values in State"
So a developer would have to convert every response before storing it in state and then convert it back when making requests with values coming from state.

I am using this to transform my responses and store them.

export const SerializableIC = (x) => {
  if (x === undefined || x === null) return x;
  if (typeof x === "bigint") return x.toString();
  if (ArrayBuffer.isView(x) || x instanceof ArrayBuffer)
    return [...x].map((y) => SerializableIC(y));

  if (Array.isArray(x)) {
    return x.map((y) => SerializableIC(y));
  }

  if (typeof x === "object") {
    if ("toText" in x) return x.toText();

    return Object.fromEntries(
      Object.keys(x).map((k) => {
        return [k, SerializableIC(x[k])];
      })
    );
  }
  return x;
};

Describe the solution you'd like
While it's beneficial to have optimal performance when dealing with large files, I would like to opt out of it and be able to store responses and later use them in other requests without having to transform them two times.

This probably means a new createAgent option, which makes all BigInt become text. all Principals become text and uint8arrays become arrays. And then later accepts these in requests.

+1, actually ran into this yesterday as well. I'm a bit swamped with responsibilities right now but will let you know if I find a solution, since I also need this feature for an internal project.