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

handler for 'getState': Error: An object could not be cloned #75

Open
LeoLTM opened this issue Dec 9, 2024 · 2 comments
Open

handler for 'getState': Error: An object could not be cloned #75

LeoLTM opened this issue Dec 9, 2024 · 2 comments
Labels
question Further information is requested

Comments

@LeoLTM
Copy link

LeoLTM commented Dec 9, 2024

I tried to move from a regular zustand setup with multiple "slices" to zutron, but I as soon as I pass the store to the renderer with

const { unsubscribe } = mainZustandBridge(store, [mW]);

I get the error

Error occurred in handler for 'getState': Error: An object could not be cloned.
    at WebContents.<anonymous> (node:electron/js2c/browser_init:2:87064)

and my states in the frontend are undefined.

This is how I create my store:

export type AppState = DialogSlice & ControlSlice & EcuStatusSlice & AxesSlice & DevicesSlice & {
    [key: string]: any;
};
const store = createStore<AppState>()((...a) => ({
    ...createDialogSlice(...a),
    ...createControlSlice(...a),
    ...createEcuStatusSlice(...a),
    ...createAxesSlice(...a),
    ...createDevicesSlice(...a),    
}));

I added the & { [key: string]: any; } because my AppState type was not compatible with AnyState that is required by mainZustandBridge().

This is how a slice looks like:

import { StateCreator } from 'zustand';

export interface DeviceInterface {
    label: string
    id: number
    type: string
    axisCount: number
    axisIdOnDevice: number[]
    ueObjPath?: string
}

export interface DevicesSlice {
    devices: DeviceInterface[]
    setDevices: (devices: DeviceInterface[]) => void;
}

export const createDevicesSlice: StateCreator<
    DevicesSlice,
    [],
    [],
    DevicesSlice
> = (set) => ({
    devices: [],
    setDevices: (devices: DeviceInterface[]) => { set({ devices: devices })},
})

This is how I call the store in the React components:

// States
const { availablePorts, outputEngine, axes, devices } = useStore();
/ Setters
const { setAvailablePorts } = useStore();

Following your guide, I added zutron to the window type

declare global {
    interface Window {
        themeMode: ThemeModeContext;
        electronWindow: ElectronWindow;
        zutron: Handlers<AppState>;
    }
} 

and the context bridge to the preload.ts:

import exposeContexts from "./helpers/ipc/context-exposer";
import { contextBridge } from 'electron';
import { preloadZustandBridge } from 'zutron/preload';
import { AppState } from "./main";

exposeContexts();

// instantiate bridge
export const { handlers } = preloadZustandBridge<AppState>();
// expose handlers to renderer process
contextBridge.exposeInMainWorld('zutron', handlers);

After trying to find a solution, I found some references that the error might happen because there are states that can't be serialized and thus not synced over IPC, but there are no such states...

Any idea what I'm doing wrong?

@goosewobbler
Copy link
Owner

@LeoLTM It's difficult to see what's going on here without a minimal reproduction. The code you posted here looks fine, and as you say, the error is what you'd expect from trying to send something too complex over IPC. I just released 0.8 with improved docs, maybe this helps.

Some things to check:

  • The store passed to Zutron needs to be created using the zustand/vanilla function
  • Try commenting out slices one by one to see what might be causing the issues.
  • Try digging into the Zutron source (it's not that big) and log out the messages before they across the bridge to get an idea of where it might be breaking

@goosewobbler goosewobbler added the question Further information is requested label Dec 11, 2024
@goosewobbler
Copy link
Owner

I added the & { [key: string]: any; } because my AppState type was not compatible with AnyState that is required by mainZustandBridge().

This is interesting, I would say either the Zutron types need fixing or this is a lead for your issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants