Skip to content

RFC: useSerialized$/createSerialized$ + SerializeSymbol #204

Closed
@wmertens

Description

@wmertens

Champion

@wmertens

What's the motivation for this proposal?

Problems you are trying to solve:

  • third-party libraries with non-serializable objects

Proposed Solution / Feature

What do you propose?

  1. a Symbol prop, SerializerSymbol, you can attach to an object that will serialize the object
  2. a Signal that holds the object and will lazily recreate it when needed

Code examples

Providing its own data:

class MyCustomSerializable {
  constructor(public n: number) {}
  inc() {
    this.n++;
  }
}
const Cmp = component$(() => {
  const custom = useSerialized$({
    deserialize: (n) => new MyCustomSerializable(n),
    serialize: (obj) => obj.n,
    initial: 3
  );
  return <div onClick$={() => custom.value.inc()}>{custom.value.n}</div>;
});

Getting the data from a signal:

import {makeThing} from 'things'

const serializer = (thing) => thing.toJSON()

const Cmp = component$(() => {
  const myData = useSignal(3);
  const custom = useSerialized$(() => ({
    deserialize() { return makeThing(myData.value); }
    update(current) {
      current.update(myData.value);
      return current;
    }
  }));
  return <div onClick$={() => custom.value.doThing()}>{custom.value.stuff}</div>;
});

In detail

  • you must provide a deserialize function that gets the data and the current object. It gets called to create the value the first time, to update when signals change, and to recreate the value with serialized data
  • useSerialized$() {deserialize, initial, update, serialize} that will be executed on the server as well as the browser to create the object, and it returns a Signal
    • the Signal works exactly like ComputedSignal, except that it will always be marked to-calculate in the browser, and it passes the serialized value + the previous value to the compute function
  • bonus: you can add [SerializeSymbol]: (obj) => serialize(obj) to any object that needs custom serialization (but not deser)
    • note that this can also used on regular objects to do housekeeping before serialization
    • Promise results are awaited so you can even e.g. save a reference number to a db

PRs/ Links / References

QwikDev/qwik#7223

Metadata

Metadata

Assignees

Labels

[STAGE-3] docs changes not added yetRemove this label when the necessary documentation for the feature / change is added[STAGE-3] missing 2 reviews for RFC PRsRemove this label when at least 2 core team members reviewed and approved the RFC implementation

Type

No type

Projects

Status

Done

Status

Released as Stable (STAGE 5)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions