[HN Gopher] Show HN: JavaScript PubSub in 163 Bytes
       ___________________________________________________________________
        
       Show HN: JavaScript PubSub in 163 Bytes
        
       Author : hmmokidk
       Score  : 89 points
       Date   : 2025-03-31 01:37 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | lerp-io wrote:
       | should this copy paste macro even be a package lol
        
         | nesarkvechnep wrote:
         | Of course not but it's JavaScript, why don't we pile more on
         | top of the garbage mountain.
        
           | kreetx wrote:
           | Not expert enough in pub/sub to tell whether these are
           | sufficient, but perhaps these two functions could be folded
           | into built-ins?
        
         | hu3 wrote:
         | In the author's defense they do write the entire source code in
         | README.md, including source for alternatives.
        
       | est wrote:
       | TIL CustomEvent
       | 
       | https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent...
        
         | bodantogat wrote:
         | Incredibly 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 wrote:
           | Bingo! 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.
        
       | pjc50 wrote:
       | This is local pubsub within an application, right? i.e.
       | corresponding to C#'s 'event' keyword.
        
         | diggan wrote:
         | It seems like it yeah. I did something that looks similar at a
         | surface-level (https://github.com/victorb/LightYearJS/blob/mast
         | er/test/acce...) around 11 years ago, but apparently called it
         | an "Event Dispatcher", something that might fit the submission
         | project better.
        
       | nsonha wrote:
       | is 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.
        
         | singpolyma3 wrote:
         | I think that's the (tounge in cheek) point being made
        
       | h1fra wrote:
       | sure if you remove the whole native package it's small
        
       | blatantly wrote:
       | 23 byte version:                   // Lib code>>
       | s={};call=(n)=>{s[n]()}         // <<
       | s.hello=()=>console.log('hello');         call('hello');
       | delete s.hello;
        
         | pavlov wrote:
         | This is missing the subscription feature?
         | 
         | Multiple independent listeners should be able to attach a
         | callback that fires when "hello" is called.
        
       | test1072 wrote:
       | Perhaps "eventlistener" word can be extracted, and dynamically
       | called as string to reduce bytes
        
         | hmmokidk wrote:
         | You joke, but I think about things like this...a lot.
        
       | sltkr wrote:
       | The 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 wrote:
         | I 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 wrote:
         | The 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.
        
       | arnorhs wrote:
       | I'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()
        
         | Joeri wrote:
         | If 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.
        
           | AgentME wrote:
           | The 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.
        
       | giancarlostoro wrote:
       | So why would I use this as opposed to BroadcastChannel?
        
         | ChocolateGod wrote:
         | Overkill if you don't want to cross between browser frames I
         | think, and I assume you can't pass references.
        
       | tipiirai wrote:
       | Thanks! Definitely going to use `new EventTarget()` in Nue. So
       | obvious.
       | 
       | https://nuejs.org/
        
       | zeroq wrote:
       | In similar spirit, a minimal implemention of KV store, in 22
       | bytes:                 export default new Map
        
       | thewisenerd wrote:
       | good 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/768db2a0046ca716e28ff14b...
        
       ___________________________________________________________________
       (page generated 2025-04-01 23:01 UTC)