6 ms·
Show HN: JavaScript PubSub in 163 Bytes
- lerp-io 2y agoshould this copy paste macro even be a package lol
- nesarkvechnep 2y agoOf course not but it's JavaScript, why don't we pile more on top of the garbage mountain.
- kreetx 2y agoNot expert enough in pub/sub to tell whether these are sufficient, but perhaps these two functions could be folded into built-ins?
- hu3 2y agoIn the author's defense they do write the entire source code in README.md, including source for alternatives.
- est 2y agoTIL CustomEvent https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent...
- bodantogat 2y agoIncredibly useful, especially with React, where the Context API, state lifting, and prop drilling often feel clunky. That said, it can lead to messy code if not carefully managed.
- jilles 2y agoBingo! Having tons of `CustomEvents` with arbitrary handlers gets unwieldy. One way we "solved" this is by only allowing custom events in a `events.ts` file and document them pretty extensively.
- RazorDev 2y ago[flagged]
- sltkr 2y agoSurely this comment was generated by an LLM?
- pjc50 2y agoThis is local pubsub within an application, right? i.e. corresponding to C#'s 'event' keyword.
- diggan 2y agoIt seems like it yeah. I did something that looks similar at a surface-level (https://github.com/victorb/LightYearJS/blob/master/test/acceptance/hello.js https://github.com/victorb/LightYearJS/blob/master/test/acce...) around 11 years ago, but apparently called it an "Event Dispatcher", something that might fit the submission project better.
- nsonha 2y agois this like left-pad but for EventTarget? If being small is the PRIMARY goal, then we are already able to do it without a wrapper.
- deleted 2y ago[deleted]
- singpolyma3 2y agoI think that's the (tounge in cheek) point being made
- h1fra 2y agosure if you remove the whole native package it's small
- blatantly 2y ago23 byte version: // Lib code>> s={};call=(n)=>{s[n]()} // << s.hello=()=>console.log('hello'); call('hello'); delete s.hello;
- pavlov 2y agoThis is missing the subscription feature? Multiple independent listeners should be able to attach a callback that fires when “hello” is called.
- test1072 2y agoPerhaps "eventlistener" word can be extracted, and dynamically called as string to reduce bytes
- deleted 2y ago[deleted]
- hmmokidk 2y agoYou joke, but I think about things like this...a lot.
- chrismorgan 2y agoThis has been a popular technique at times, but it tends to increase compressed sizes: gzip and similar are better at common string deduplication, having lower overhead. Such shenanigans are also bad for performance, especially in hot paths due to making it harder for the browser to optimise it.
- deleted 2y ago[deleted]
- sltkr 2y agoThe API feels wrong. The object that was passed to pub() is the object that should be received by the callback passed to sub(). The use of EventTarget/CustomEvent is an implementation detail; it should not be part of the API. As a result, every callback implementation is larger because it must explicitly unwrap the CustomEvent object. Essentially, the author made the library smaller by pushing necessary code to unwrap the CustomEvent object to the callsites. That's the opposite of what good libraries do! The mentioned nano-pubsub gets this right, and it even gets the types correct (which the posted code doesn't even try).
- hmmokidk 2y agoI disagree with the first point, and agree with the second. The usage, to me, feels appropriate for JS. I agree that event.detail should be returned instead of the whole event. Can definitely save some space at the callsites there!
- nine_k 2y agoThe point of this exercise, to my mind, is to show the utter simplicity of pub-sub. Such code belongs to the API documentation, like the code snippets on MDN. Proper code would have expressive parameter names, good doc comments, types (TS FTW) and the niceties like unpacking you mention. One of them would be named topics mapped to EventTargets, so that publishers and subscribers won't need to have visibility into this implementation detail.
- deleted 2y ago[deleted]
- arnorhs 2y agoI'm not a huge fan of using CustomEvent for this.. esp. in terms of interoperability (which for these <kb challenges probably doesnt matter) personally, i'll just roll with something like this which also is typed etc: export function createPubSub<T extends readonly any[]>() { const l = new Set<(...args: T) => void>() return { pub: (...args: T) => l.forEach((f) => f(...args)), sub: (f: (...args: T) => void) => l.add(f) && (() => l.delete(f)), } } // usage: const greetings = createPubSub<[string]>() const unsubscribe = greetings.sub((name) => { console.log('hi there', name) }) greetings.pub('Dudeman') unsubscribe()
- deleted 2y ago[deleted]
- Joeri 2y agoIf listeners of this implementation aren’t unsubscribed they can’t be garbage collected, and in a real world codebase that means memory leaks are inevitable. EventDispatcher has weak refs to its listeners, so it doesn’t have this problem.
- deleted 2y ago[deleted]
- AgentME 2y agoThe listeners can be garbage-collected if the `greetings` publisher object and any unsubscribe callbacks are garbage-collectable. This is consistent with normal Javascript EventTargets which don't use weak refs. If only weak refs were kept to listeners, then any listeners you don't plan to unsubscribe and don't keep that callback around will effectively auto-unsubscribe themselves. If this was done and you called `greetings.sub((name) => console.log("hi there", name));` to greet every published value, then published values will stop being greeted whenever a garbage collection happens.
- arnorhs 2y agoThis is correct. The subscribers are unlikely to be garbage collected with a weak ref as long as something else is pointing to the subscriber, so it would be a viable alternative to manual unsubscriptions - but personally I prefer to give explicit lifecycle controls to the subscriber, if possible.
- giancarlostoro 2y agoSo why would I use this as opposed to BroadcastChannel?
- ChocolateGod 2y agoOverkill if you don't want to cross between browser frames I think, and I assume you can't pass references.
- tipiirai 2y agoThanks! Definitely going to use `new EventTarget()` in Nue. So obvious. https://nuejs.org/ https://nuejs.org/
- zeroq 2y agoIn similar spirit, a minimal implemention of KV store, in 22 bytes: export default new Map
- curtisszmania 2y ago[dead]
- thewisenerd 2y agogood to know pub-sub shenanigans are ubiquitous lol here's my implementation from a while back with `setTimeout` like semantics; used it to avoid prop-drilling in an internal dashboard (sue me) https://gist.github.com/thewisenerd/768db2a0046ca716e28ff14be6c28538 https://gist.github.com/thewisenerd/768db2a0046ca716e28ff14b...
- tubs 2y agosub => ref = 0 sub => ref = 1 unsub(0) sub => ref = 1 (two subs with same ref!)