LegendApp / legend-state

Legend-State is a super fast and powerful state library that enables fine-grained reactivity and easy automatic persistence
https://legendapp.com/open-source/state/
MIT License
3.03k stars 87 forks source link

Supabase sync & persist issues #344

Open bishsbytes opened 3 months ago

bishsbytes commented 3 months ago

I've notcied I'm seeing inconsistent sync / persist behaviour using the supabase plugin with ObservablePersistMMKV.

In testing on web and viewing what's in local storage, after calling 'set' I notice that the object that eventually gets persisted is missing a lot of the returned supabase fields. Here's an example:

    [
      "c0127a12-6c29-48a0-a82c-18f8a74c638e",
      {
        "id": "c0127a12-6c29-48a0-a82c-18f8a74c638e",
        "name": "ANOTHER",
        "created_at": "2024-08-01T16:26:32.81661+00:00",
        "created_by": "1a442538-5373-4402-bbd9-e6eee5b580a5",
        "metadata": null,
        "summary": null,
        "list_id": null,
        "action_type": "DO",
        "checked_off": false,
        "order": null,
        "updated_at": "2024-08-01T16:26:32.81661+00:00"
      }
    ],
    [
      "952a1b10-f91e-45c6-bf81-df622cd0a8bb",
      { "created_at": "2024-08-01T16:30:32.574531+00:00" }
    ],
    [
      "c9cddd56-65c2-48bf-9bf6-830ebcf8780a",
      { "id": "c9cddd56-65c2-48bf-9bf6-830ebcf8780a" }
    ]
  ]

Here's my store setup:

export const generateId = () => uuidv4();

configureSyncedSupabase({
  generateId,
});

configureObservableSync({
  persist: {
    plugin: ObservablePersistMMKV,
    retrySync: true,
  },
  retry: {
    infinite: true,
  },
});

export const isSignedIn$ = observable(false);

export const actionType$ = observable<{ type: Enums<'ActionType'> | null }>({
  type: null,
});

export const entry$ = observable(
  syncedSupabase({
    supabase,
    collection: 'Entry',
    as: 'Map',
    filter: (select) => {
      const actionType = actionType$.get().type;
      if (actionType) {
        return select.eq('action_type', actionType);
      } else {
        return select.is('action_type', null);
      }
    },
    persist: {
      name: 'entries',
      retrySync: true,
    },
    waitFor: isSignedIn$,
  })
);

And here's how I'm calling 'set':

  const handleAddEntry = ({ name }) => {
    const id = generateId();
    entry$[id].set({ id, name, action_type, list_id });
  };

I can't see why they aren't being persisted correctly. If I clear out localstorage and reload, all the objects are persisted correctly. It's only when they are added via 'set' - the new object will never persist in its entirety. I can see the full object being returned from supabase in the network request, but not sure what's causing them to be removed when persisted?

jmeistrich commented 3 months ago

Is it saving only the values you that specifically set? Or is it saving some but not all of the data that returns back from Supabase? If so which fields is it missing?

Is it possible you can share a repo with me that I can use to test? If not I'll see if I can reproduce it in my supabase test project.