amark / gun

An open source cybersecurity protocol for syncing decentralized graph data.
https://gun.eco/docs
Other
18.06k stars 1.16k forks source link

"gun.user() is not a function" due to SEA not loading properly #1383

Open CreaDisc opened 1 week ago

CreaDisc commented 1 week ago

Hi folks,

currently I am trying to use gun for a Lit-based project. Whenever I try to call gun.user() it gives me the error: TypeError: gun.user is not a function

Here is the relevant parts of the project:

this is my bundle entry point:

import Gun, {IGunInstance, IGunUserInstance} from 'gun';
import SEA from 'gun/sea';

// ...
document.addEventListener('DOMContentLoaded', () => {
  loadGun().then(() => {
    //...
  });
}

gun auth module:

import {IGunInstance} from 'gun';
import 'gun/sea';

export async function loadGun() {
    // ...
    const gun = Gun();
    await checkAndCreateUser(gun, 'username', 'password');

    console.log('Gun loaded');
}

async function checkAndCreateUser(
  gun: IGunInstance,
  username: string,
  password: string
) {
  return new Promise<void>((resolve, reject) => {
    const user = gun.user();                                     // !!! THIS IS WHERE IT FAILS

    console.log('user assigned');
    user.auth(username, password, (ack: any) => {
      //...
    });
  });
}

This is how I included the scripts in my HTML:

<script src="../node_modules/gun/gun.js"></script>
<script src="../node_modules/gun/sea.js"></script>

<script src="../out/bundle.js"></script>

What I tried so far:

I have seen this issue come up before but none of the solutions worked for me, so here I am.

CreaDisc commented 1 week ago

Ok, so somehow it works now, but still trying to figure out why. If I import SEA into my bundle at the entry point, everything seems fine. But as soon as I try to import SEA from a Lit component, it breaks.

So this is my Lit component:

@customElement('task-component')
export class TaskComponent extends LitElement {

  private todoRepo: TodoRepo | null;

  constructor() {
    super();
    this.todoRepo = getTodoRepo();
  }

  // ...
}

And this is my Todo Repo module:

import * as Gun from 'gun';
// import 'gun/sea';                                 // !!! INCLUDING THIS LINE BREAKS SEA GLOBALLY
import 'gun/axe';

export function getTodoRepo(): TodoRepo | null {
  if (!window.gun) {
    console.log('gun is undefined');
    return null;
  } else {
    console.log("gun is defined in TODO Repo");
    return TodoRepo.getInstance();
  }
}

// ...

Does somebody have a clue why this is happening?