Coder Social home page Coder Social logo

Comments (4)

pkieltyka avatar pkieltyka commented on June 12, 2024 1

hey @simontreny any updates on this one? would be cool to see 2.x and also if you've considered react v18 concurrent mode + useSyncExternalStore ?

from micro-observables.

lubieowoce avatar lubieowoce commented on June 12, 2024

Hey, looks like we can work around this "in userspace", using the previous value we get in subscribe!

import { observable, Observable } from 'micro-observables';

export type Equality<T> = (a: T, b: T) => boolean;

/**
* Takes an observable and produces a new one, which updates
* only if equals returns false.
* Example usage:
*  const obs2 = sameIf(isEqual)(obs1)
**/
export function sameIf<T>(equals: Equality<T>) {
return (original: Observable<T>): Observable<T> => {
  const derived = observable(original.get());
  original.subscribe((newVal: T, oldVal: T) => {
    if (!equals(newVal, oldVal)) {
      derived.set(newVal);
    }
  });
  return derived;
};
}

// or, if you prefer it as a constructor
export function observableMemo<T>(value: T, equals: Equality<T>): Observable<T> {
return sameIf(equals)(observable(value));
}

(sorry about the indents, github seems to mess them up no matter what i do)

codesandbox with some react code to check it out:
https://codesandbox.io/s/little-morning-jcq03u?file=/src/App.tsx

You'd still need to wrap everything with sameIf(myEquals)(...), but that's better than nothing i guess... or perhaps do something like this if you wanna save yourself some typing:

const selectIf = (equals) => (obs, selector) => sameIf(equals)(obs.select(selector))

Some alternative names: memoIf, keepIf, updateUnless. The original one was memoIf, but i feel like "memo" is a bit too general

from micro-observables.

pothos-dev avatar pothos-dev commented on June 12, 2024

This is something I am doing right now, but I am afraid that this solution is prone to memory leaks.

I assume that a regularly derived observable via .select() can be garbage collected when the last reference to it is deleted.

Using the solution outlined by lubieowoce, by explicitly creating a subscription on the source observable and referencing the target observable, we bind the lifetime of the target observable to the source observable, and cannot simply "let it go".

I noticed that there is an undocumented Plugin architecture in the library that supports stuff like onAttach etc.. so I think we might be able to make it memory safe using this, but since it's undocumented, kinda hard to say.

from micro-observables.

simontreny avatar simontreny commented on June 12, 2024

This is something I am doing right now, but I am afraid that this solution is prone to memory leaks.

I assume that a regularly derived observable via .select() can be garbage collected when the last reference to it is deleted.

Yes, you're right, deriving observables using subscribe() will cause memory leaks as the source observables won't be garbage collected unless the unsubscribe function returned by subscribe() is explicitly called.

I agree that equality function is definitely something that should be built-in directly in micro-observables. We actually already added support for it in the next major version of the library (that is not released yet). I've quickly tried to backport it into the 1.x version but unfortunately, this is not straightforward. The next version should hopefully be released in the next few weeks.

I noticed that there is an undocumented Plugin architecture in the library that supports stuff like onAttach etc.. so I think we might be able to make it memory safe using this, but since it's undocumented, kinda hard to say.

This API was an experiment to add support for persistence and dev tools to micro-observables but we will drop it in 2.x in favor of another mechanism. Anyway I don't think it can be used to achieve what you want here.

from micro-observables.

Related Issues (14)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.