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

Qwik js support #174

Open
CherphAlt opened this issue Mar 21, 2023 · 7 comments
Open

Qwik js support #174

CherphAlt opened this issue Mar 21, 2023 · 7 comments

Comments

@CherphAlt
Copy link

No description provided.

@ai
Copy link
Member

ai commented Mar 21, 2023

We need some developer with Qwik experience.

Please create a repo with a integration example and after a review we will move it under nanostores org.

@joshua1
Copy link

joshua1 commented Jun 13, 2023

Am new to qwik but i want this feature. to enable me share state manegement logic between qwik and svelte-native (existing app)

@thejackshelton
Copy link

Hey @joshua1 @ai @CherphAlt I'd be happy to make a qwik version for this. So a separate repo that is then moved into nanostores?

@ai
Copy link
Member

ai commented Dec 24, 2023

@thejackshelton yes, start the project (prepare to use @nanostores/ prefix in npm name). Post link here when you will be ready. We will review and give your Github access (to transfer repo) and npm access (to publish).

@thejackshelton
Copy link

@thejackshelton yes, start the project (prepare to use @nanostores/ prefix in npm name). Post link here when you will be ready. We will review and give your Github access (to transfer repo) and npm access (to publish).

Awesome, and thanks for the speedy response. I'll tackle this right after the holidays 😄 🎄

@jamaluddinrumi
Copy link

@thejackshelton yes, start the project (prepare to use @nanostores/ prefix in npm name). Post link here when you will be ready. We will review and give your Github access (to transfer repo) and npm access (to publish).

Awesome, and thanks for the speedy response. I'll tackle this right after the holidays 😄 🎄

wishing, any updates?

@thejackshelton
Copy link

thejackshelton commented Feb 16, 2024

@thejackshelton yes, start the project (prepare to use @nanostores/ prefix in npm name). Post link here when you will be ready. We will review and give your Github access (to transfer repo) and npm access (to publish).

Awesome, and thanks for the speedy response. I'll tackle this right after the holidays 😄 🎄

wishing, any updates?

Ah sorry for not updating sooner! Here was my approach:

import {
  component$,
  type Signal,
  useOnDocument,
  useSignal,
  useTask$,
  $,
  useOn,
} from "@builder.io/qwik";
import { type WritableAtom, atom } from "nanostores";
// @ts-ignore
import { isDev } from "@builder.io/qwik/build";

// global state

const count = atom(123);
const useCount = useNanostore(count, "count");

export const Island1 = component$(() => {
  const count = useCount();
  return <div>Count: {count.value}</div>;
});

export const Island2 = component$(() => {
  const count = useCount();
  return <button onClick$={() => count.value++}>+1</button>;
});

/* @nanostore/qwik */
export function useNanostore<T>(
  atom: WritableAtom<T>,
  name: string
): () => Signal<T> {
  const updateAtomEvent = "ns_set_" + name;
  const notifyQwikName = "ns_notify_" + name;
  let afterInitialSubscription = false;

  atom.subscribe(() => {
    if (afterInitialSubscription && typeof document !== "undefined") {
      document.dispatchEvent(new CustomEvent(notifyQwikName, { detail: atom }));
    }
  });

  afterInitialSubscription = true;

  if (typeof document !== "undefined") {
    document.addEventListener(updateAtomEvent, (event) => {
      const value = (event as CustomEvent<T>).detail;
      console.log(updateAtomEvent, value);
      atom.set(value);
    });
  }

  return function useNanoToQwik() {
    const signal = useSignal(atom.get());
    useTask$(({ track }) => {
      const value = track(() => signal.value);
      if (typeof document !== "undefined") {
        document.dispatchEvent(
          new CustomEvent(updateAtomEvent, { detail: value })
        );
      }
    });

    // we don't want this!
    if (isDev) {
      useOn(
        "qvisible",
        $(() => {
          // initializes in dev when referenced
          useNanostore;
        })
      );
    }

    useOnDocument(
      notifyQwikName,
      $((event) => {
        const atom = (event as CustomEvent<WritableAtom<T>>).detail;
        console.log(notifyQwikName, atom);
        signal.value = atom.get();
      })
    );
    return signal;
  };
}

in .astro

	<body>
		<h1>Astro</h1>
		<Island1 />
		<Island2 />
	</body>

The problem I had, was that I could not get nanostores working properly, without waking up the entire framework and the component eagerly.

I was able to get it to execute on interaction if they were in the same file with that useNanostore reference hack to initialize it on demand, but outside of the file I needed to use qvisible or a visible task.

My current recommendation in the Qwik Astro integration is to use custom events, so that things only execute on interaction.

That said, I still want to figure this out, pretty swamped at the moment 😅

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

No branches or pull requests

5 participants