saasquatch / bunshi

Molecule pattern for jotai, valtio, zustand, nanostores, xstate, react and vue
https://www.bunshi.org/
MIT License
201 stars 14 forks source link

Can't `use` a molecule from a scope #63

Open loganvolkers opened 1 month ago

loganvolkers commented 1 month ago

Given that you have LibraryMolecule that is relying on ConfigScope to set up how the molecule should be used:

import { Atom, atom } from "jotai";
import { molecule, createScope, Molecule, use } from "../../vanilla";

export type ExampleConfig = {
  example: Atom<string>;
};

export const ConfigScope = createScope<Molecule<ExampleConfig> | undefined>(
  undefined,
);

export const LibaryMolecule = molecule(() => {
  const configMol = use(ConfigScope);
  if (!configMol)
    throw new Error("This molecule requires ConfigScope to function!");

  const config = use(configMol) as ExampleConfig;
  const derivedAtom = atom((get) => get(config.example).toUpperCase());

  return {
    ...config,
    derivedAtom,
  };
});

And you have two different configs for scope:

export const ConfigAMolecule = molecule<ExampleConfig>(() => {
  return {
    example: atom("Config A"),
  };
});

const ScopeB = createScope("Longer tree");
export const ConfigBMolecule = molecule<ExampleConfig>(() => {
  // This creates a different path for the dependencies of `LibraryMolecule`
  // And can throw errors
  use(ScopeB);
  return {
    example: atom("Config B"),
  };
});

When you use LibraryMolecule with ConfigScope set to ConfigAMolecule Then it works just fine But you use LibraryMolecule with ConfigScope set to ConfigBMolecule And it will throw a Molecule is using conditional dependencies. This is not supported. exception

This is a new limitation in Bunshi 2.1 as part of the introduction of molecule lifecycles.

loganvolkers commented 1 month ago

Conditional dependencies started throwing error in Bunshi 2.1 with the introduction of lifecycle hooks because it became difficult to know how to unmount dependencies when a scope was released.

The un-intended side-effect of that was disabling this use-case.