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

Error: constructor undefined when using with (3rd party library) object #53

Open
EliasBeyer opened this issue Jul 25, 2023 · 1 comment
Labels
bug Something isn't working question Further information is requested

Comments

@EliasBeyer
Copy link

EliasBeyer commented Jul 25, 2023

I tried to use localStorage to store an object from another library and get this error:

TypeError: e2.constructor is undefined
    a index.mjs:1
    a index.mjs:1
    a index.mjs:1
    A index.mjs:1
    setValue index.mjs:1
    x index.mjs:1
    subscribe index.mjs:1
    x index.mjs:1
    X index.mjs:1
    H index.mjs:1
    <anonymous> store.js:19
app.js:16:41

Steps to reproduce:

  • npm create svelte@latest my_test (doesn't matter the configuration, tested with skeleton app, without types and with typescript, no linter etc)
  • install this library and another external one: npm install @macfja/svelte-persistent-store and npm install obs-websocket-js
  • create src/routes/store.js:
import { localWritable } from "@macfja/svelte-persistent-store"
import { writable } from "svelte/store"
import OBSWebSocket from 'obs-websocket-js';

export class BaseMyObj {}
class MyObj extends BaseMyObj {}

// export const obs = writable( new OBSWebSocket() ) // works
export const myobj = localWritable( "myobj" , new MyObj() ) // works
export const obs = localWritable( "obs" , new OBSWebSocket() ) // error
  • use store.js in +page.svelte: import { myobj } from "./store"

I am fairly new to webdev/js/svelte so it might be an error on my side.

What I have tried so far:

  • changed the sveltekit configuration (JS/TS) with the same error
  • tried to dig into the error itself, but there is no e2 or e2.constructor anywhere in the minified JS in the browser
  • tried to recreate the error with a custom class (that extends a base class) in JS/TS, these work just fine
  • also used the base functions (persist and all the available alias for localstorage) with the same error

I guess this error may be specific for the combination of those two libraries, however I lack the insight of both libraries to get into it deeper, especially with other 3rd party packages

@EliasBeyer EliasBeyer changed the title Error: constructor undefined when using with object Error: constructor undefined when using with (3rd party library) object Jul 25, 2023
@MacFJA MacFJA added bug Something isn't working question Further information is requested labels Jul 28, 2023
@MacFJA
Copy link
Owner

MacFJA commented Jul 28, 2023

Why do you need to persist a (Web)socket ?
A socket is a connection that will be opened and closed, and should not (IMO) be persisted in application data

What is the data you need to store/persist ?
From my vague understanding, what should be persisted is how to open a connection


OBSWebSocket is complex object that need some custom code to be persisted. (In particular, OBSWebSocket use EventEmitter which alter the standard object structure, needed to automagically save a class)

This lib can't handle this as-is. But the lib that @macfja/svelte-persistent-store rely on can!

// Somewhere in a init script
import { setSerialization } from "@macfja/svelte-persistent-store"
import { serialize, deserialize, addGlobalAllowedClass, addClassHandler } from "@macfja/serializer"
import { OBSWebSocket } from "obs-websocket-js";

addClassHandler(OBSWebSocket.constructor.name, (instance) => ({
    url: instance.socket.url,
    protocol: instance.protocol
    // any data that you need to save
}), (saved) => {
    const instance = new OBSWebSocket();
    instance.protocol = saved.protocol;
    instance.connect(saved.url);
    return instance;
})
setSerialization(serialize, deserialize, addGlobalAllowedClass)

// Now `@macfja/svelte-persistent-store` know how to save and load a `OBSWebSocket` in any futur call of `persist`

Warning
It's impossible to know any parameters used in OBSWebSocket.connect except for the url

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
Projects
None yet
Development

No branches or pull requests

2 participants