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

hashchange / even source? #73

Closed
dy opened this issue Jan 21, 2022 · 10 comments
Closed

hashchange / even source? #73

dy opened this issue Jan 21, 2022 · 10 comments

Comments

@dy
Copy link
Contributor

dy commented Jan 21, 2022

Found myself implementing wrapper for hashchange event as:

import ref from 'value-ref'
const hash = ref(window.location.hash || '#/')
window.addEventListener('hashchange', e => hash(window.location.hash))
hash.subscribe(...)

Does it make sense to provide hash source? Or mb location? Probably it's vast topic.

import hash from 'subscribable-sources'
hash.subscribe(...)

?

@chrisguttandin
Copy link
Owner

Hi Dmitry,

there is already a generic function for listening to events.

Here is the part in the README that talks about it: https://github.com/chrisguttandin/subscribable-things#ontarget-eventtarget-type-string-options-boolean--addeventlisteneroptions-subscribablethingevent.

Here is the integration test which probably documents it better:

it('should work with hyperf', async () => {
const test = h`<div id="test">${map(on(htmlElement, 'click'), ({ target }) => target.nodeName)}</div>`;
document.body.appendChild(test);
finalizationRegistry.register(test);
while (true) {
try {
expect(document.getElementById('test').textContent).to.equal('A');
break;
} catch {
await new Promise((resolve) => {
setTimeout(resolve, 100);
});
}
}
document.body.removeChild(test);
});

Does that help with your use case?

@dy
Copy link
Contributor Author

dy commented Jan 21, 2022

Right

import { on, map } from 'subscribable-things'
map(on(window, 'hashchange'), e => window.location.hash)

A couple of off-topics, if you don't mind.

  1. Zen-observable defines .map method for observables, so that it's not necessary to require map. Wdyt?
  2. Now titles in docs are a bit heavy:

on(target: EventTarget, type: string, options?: boolean | AddEventListenerOptions): SubscribableThing

The keywords get lost in type definitions, makes it a bit hard to find.

Would it make sense to making it more lightweight as:

on(target, type, options?)

on(target: EventTarget, type: string, options?: boolean | AddEventListenerOptions): SubscribableThing<Event>

@chrisguttandin
Copy link
Owner

Thanks a lot for your suggestion. I just updated the README. 41983a3 It looks much better now.

I'm not sure about adding a .map() function. If we do so then someone might ask for a .filter() function next and at some point we end up with a lot of operators which will bloat the bundle for everyone.

Currently the map() operator isn't even public. It's just a test helper for now. https://github.com/chrisguttandin/subscribable-things/blob/41983a368f1936fbd349595d632126f442ea0d77/test/helpers/map.js

I wonder if there is already a collection of operators that could be reused somehow.

@dy
Copy link
Contributor Author

dy commented Feb 1, 2022

Looks nice! Yeah, I also doubt about map. Observable proposal discussion converges to minimal possible implementation, which makes the most sense.

As for the operators library - good idea. In value-ref I came to Ref.from(anyReactiveSource) method, mimicking Array.from for observables.

But there indeed seems to be missing a small lib for observables with minimal set of operators and reactive sources (value/object/list). Like tiny rxjs, or reactive lodash. Sort of less proprietary vue reactivity.

@chrisguttandin
Copy link
Owner

Maybe we could create a package called pipeable-operators (the name is still available) which draws some inspiration from RxJS.

It could provide some operators and a pipe() function which takes a SubscribableThing (or any other standards compliant Observable) as a first parameter and a list of operators to apply. The return value would be another SubscribableThing.

const newObservable = pipe(
    oldObservable,
    map((value) => value + 2),
    filter((value) => value % 2 === 0)
);

Like in RxJS an operator would be a function which takes an Observable and returns another one.

But it almost feels unrealistic to me that something like this doesn't exist yet. 🤷‍♂️

@dy
Copy link
Contributor Author

dy commented Feb 2, 2022

I like the idea, but I think that is rxjs/operators we're talking about, unless there's a point for a separate portable lib with minimal set of indispensable ones. map, filter, take, ... That reminds mutant for actual Observables.

Yeah, it can also possibly subscribe to asyncIterables as well? Or that's a separate concern though.

@dy
Copy link
Contributor Author

dy commented Feb 2, 2022

To the point there is:

@chrisguttandin
Copy link
Owner

Thanks for all the links. It looks like it's a solved problem. ;-) Should we then close this issue? Or am I missing something?

@dy
Copy link
Contributor Author

dy commented Feb 5, 2022

I guess, yes.

@chrisguttandin
Copy link
Owner

Alright, I'm going to close it. Please feel free to open a new issue if you have another idea how this library could be extended or improved.

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

2 participants