Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange reference values when using new svelte-persistent-store. #24

Open
michaelcuneo opened this issue Aug 25, 2022 · 8 comments
Open
Labels
bug Something isn't working question Further information is requested version 2.x

Comments

@michaelcuneo
Copy link

I just transitioned an old project to a new version of Svelte, with .TS and all the other upgrades I can think of., and I'm getting unusual references in my localStorage and sessionStorage instead of actual data.

This is my store.ts

import { persist, createLocalStorage, createSessionStorage } from '@macfja/svelte-persistent-store';
import type { PersistentStore } from '@macfja/svelte-persistent-store';
import { writable } from 'svelte/store';

type user = {
  username: string;
};

type error = {
  status: boolean;
  message: string;
};

class CapripolStore {
  constructor(
    public transitionUser: PersistentStore<object> = persist(writable([]), createSessionStorage(), 'transitionUser'),
    public user: PersistentStore<user> = persist(writable(<user>({})), createSessionStorage(), 'user'),
    public mfa: PersistentStore<boolean> = persist(writable(false), createSessionStorage(), 'mfa'),
    public signupConfirm: PersistentStore<boolean> = persist(writable(false), createSessionStorage(), 'signupConfirm'),
    public passwordReset: PersistentStore<boolean> = persist(writable(false), createSessionStorage(), 'passwordReset'),
    public error: PersistentStore<error> = persist(writable(<error>({})), createSessionStorage(), 'error'),
  ) {}
}

export const capripolStore = new CapripolStore();

When I look at the values of everything, transitionUser, user, and error, are all ["#$@__reference__0"]

For some reason, signupConfirm, passwordReset, and mfa are all fine. Not sure what's going on here.

@MacFJA
Copy link
Owner

MacFJA commented Aug 27, 2022

The #$@__reference__0 is an internal key used by the serialization module.
It's used for circular reference detection.

This value shouldn't be "visible" when using the store. It only appear in the saved data.

So normally if you log the content of the store you shouldn't see it, but if you look at the content of your browser SessionStorage you should see it.


BTW, you can use persistBrowserSession instead of persist + createSessionStorage

@MacFJA MacFJA added question Further information is requested version 2.x labels Aug 28, 2022
@michaelcuneo
Copy link
Author

I have noticed though that my entire app breaks in this case because I rely on a lot of data checking to see if a field or object etc is empty or filled to manipulate the UI/UX... and because of these 'values' they're actually responding with fake information... i.e. a simple

export const isEmpty = obj => {
  return obj && Object.keys(obj).length === 0;
};

... will return false on an object with the '#$@__reference__0' inside.

@brianorwhatever
Copy link

I am also seeing these references and my store is still a string when I am accessing it. I think there is something timing wise happening -- maybe when there is a large amount of data to deserialize?

@MacFJA
Copy link
Owner

MacFJA commented Dec 9, 2022

Do you have a reproduction repository (or a stackblitz or similar) so I can check it ?

@MacFJA MacFJA added the bug Something isn't working label Dec 9, 2022
@brianorwhatever
Copy link

sorry, I have moved my code to dexie.js and am using that now but I suspect it was happening when I was loading a large json. Something I'm doing with dexie now is awaiting an init fn in my store that resolves after the stores have been populated so I won't encounter a similar condition

@JBloss1517
Copy link

@brianorwhatever I had the same issue. The #$@__reference__0 keys would cause issues with checking if the store was empty and iterating over the items in the store. I know you have already moved on to a different library now, but I was able to revert to the older style without the #$@__reference__0 keys by specifying what serialization library to use as documented here:

https://github.com/MacFJA/svelte-persistent-store/blob/main/.docs/How-To/06-Change-Serialization.md

@MacFJA thanks for the easy copy/paste samples you provided in the link above.

@kithe-raker
Copy link

@brianorwhatever I had the same issue. The #$@__reference__0 keys would cause issues with checking if the store was empty and iterating over the items in the store. I know you have already moved on to a different library now, but I was able to revert to the older style without the #$@__reference__0 keys by specifying what serialization library to use as documented here:

https://github.com/MacFJA/svelte-persistent-store/blob/main/.docs/How-To/06-Change-Serialization.md

@MacFJA thanks for the easy copy/paste samples you provided in the link above.

Same here. Able to resolve the issue by using JSON for serialization. But I don't know if there will be any drawback of using JSON instead of the default one.

@MacFJA
Copy link
Owner

MacFJA commented Sep 30, 2023

Each serializer have they own benefits and drawbacks

Serializer Benefits Drawbacks
JSON Well known format ; compatible with any parser No protection for circular reference ; No protection for duplicate value ; No serialization of no-standard data1
esserializer Handle circular reference2 ; Can serialize most Built-In JS Classes3 ; Can serialize custom class
devalue Handle circular reference ; Can serialize some built-in JS Classes ; Handle duplicate value ; Can serialize custom class ; Can product function like executable (can be run in eval) Can product function like executable (can be run in eval)
@macfja/serializer Handle circular reference ; Handle duplicate value ; Can serialize Built-In JS Classes ; Can serialize custom class

For every Serializer that are not JSON, the output can be harder to read, it need to be deserialized with the same logic, output is often larger (as more data is need to save complete information) for some simple structure
But they can serialize more complex data like classes and circular reference (which can happen in custom classes)

Footnotes

  1. JSON only support: object, array, string, number, boolean, null (see https://www.json.org/json-en.html)

  2. In the Pro version (https://github.com/shaochuancs/esserializer#esserializer-pro)

  3. Map and Symbol are in the Pro version only (https://github.com/shaochuancs/esserializer#esserializer-pro)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested version 2.x
Projects
None yet
Development

No branches or pull requests

5 participants