Skip to content

Support chaining #12

Description

@tunnckoCore

It would be cool and is already some habit for some devs.

const mitt = require('mitt')
const emitter = mitt()
emitter.on('foo', console.log).on('bar', console.log).emit('foo', 123)

Activity

  1. developit commented on Jan 16, 2017

    @developit
    Owner

    Interesting! Would be curious to see the filesize hit.

  2. tunnckoCore commented on Jan 16, 2017

    @tunnckoCore
    CollaboratorAuthor

    I think the easiest fix is to make to exports. The default to be the "instance" (like invoking mitt()) and the another to export the current function

    export default mitt()
    export const mitt
    
    function mitt(all) {
    
    // code ...

    Something like that? So if users want to add initial events through mitt({}) they will use

    import { mitt } from 'mit'

    otherwise they will have directly all the methods

    import emitter from 'mitt'
    
    emitter.on().on()
  3. tunnckoCore commented on Jan 16, 2017

    @tunnckoCore
    CollaboratorAuthor

    Oookey, okey, let me think a bit, i'll try. Coding at github issue isn't feels good haha

  4. developit commented on Jan 16, 2017

    @developit
    Owner

    Hmm - that'd be a singleton, which is generally not going to be a good thing (npm dupe issues, etc). I've used that pattern before with a similar EventEmitter, and that was actually one of the reasons I wrote this one - you can do this:

    import mitt from 'mitt';
    const { on, off, emit } = mitt();
    export { on, off, emit };
    

    That's probably the better option if you're looking to then import the singleton methods later on. You get to use an instantiable library (mitt) but then work with your own created singleton in your codebase.

    Just my 2 cents :)

  5. tunnckoCore commented on Jan 16, 2017

    @tunnckoCore
    CollaboratorAuthor

    Actually, I did it :) But is 212bytes (tests passing) ;/ All of my above snippets was wrong. Idea is different.

    We need to not just return an object with the methods but assign that object to const ret, return that const and use that const in each method.

    export default function mitt(all) {
    	// Arrays of event handlers, keyed by type
    	all = all || {};
    
    	// Get or create a named handler list
    	function list(type) {
    		let t = type.toLowerCase();
    		return all[t] || (all[t] = []);
    	}
    
    	const ret = {
    
    		/** Register an event handler for the given type.
    		 *	@param {String} type		Type of event to listen for, or `"*"` for all events
    		 *	@param {Function} handler	Function to call in response to the given event
    		 *	@memberof mitt
    		 */
    		on(type, handler) {
    			list(type).push(handler);
    			return ret;
    		},
    
    		/** Remove an event handler for the given type.
    		 *	@param {String} type		Type of event to unregister `handler` from, or `"*"`
    		 *	@param {Function} handler	Handler function to remove
    		 *	@memberof mitt
    		 */
    		off(type, handler) {
    			let e = list(type),
    				i = e.indexOf(handler);
    			if (~i) e.splice(i, 1);
    			return ret;
    		},
    
    		/** Invoke all handlers for the given type.
    		 *	If present, `"*"` handlers are invoked prior to type-matched handlers.
    		 *	@param {String} type	The event type to invoke
    		 *	@param {Any} [event]	An event object, passed to each handler
    		 *	@memberof mitt
    		 */
    		emit(type, event) {
    			list('*').concat(list(type)).forEach( f => { f(event); });
    			return ret;
    		}
    	};
    
    	return ret;
    }
  6. tunnckoCore commented on Jan 16, 2017

    @tunnckoCore
    CollaboratorAuthor

    It will fit if we use #8. Damn.. that's freaking crazy haha

  7. developit commented on Jan 17, 2017

    @developit
    Owner

    Gotta get that size down somehow 😉 208 is pretty good though, basically just paying for one return ret thanks to gzip.

  8. dotproto commented on Jan 17, 2017

    @dotproto
    Contributor

    Seems like this issue and #1 are incompatible.

  9. developit commented on Jan 17, 2017

    @developit
    Owner

    Oooh - good point. I totally did not think of that.

  10. tunnckoCore commented on Jan 17, 2017

    @tunnckoCore
    CollaboratorAuthor

    Yea, absolutely. But I believe this lib is meant to be with kind of compat with most common and to be small. Or at least it is promoted as that. I not mean that #1 will be with bigger size, but it is other thing and can be done in separate more smaller lib. 2c

  11. sospedra commented on Jan 18, 2017

    @sospedra

    Instead of returning unsuscribe method (#1) we can add the getUnsuscribe on the fluent API. So you can get it whenever you need to.

  12. dotproto commented on Jan 18, 2017

    @dotproto
    Contributor

    @sospedra I'm not sure how viable a new method would be as the 200 B gzipped limit is quite a challenge to work around. @tunnckoCore has been doing some heroic with in #19.

  13. developit commented on Jan 18, 2017

    @developit
    Owner

    adding getUnsubscribe() would require that a fluent API return new instances of the interface for every call. I don't think that is possible given the size limitations here, and the performance would be quite poor.

  14. shshaw commented on Jan 23, 2017

    @shshaw

    Using Closure Compiler, you end up with 197 bytes after including the return in each function by it converting all let or const to var. If using let & const aren't a requirement, that's an easy way to get that gzip size down.

    function mitt(b){function c(a){a=a.toLowerCase();return b[a]||(b[a]=[])}b=b||{};var d={on:function(a,e){c(a).push(e);return d},off:function(a,e){var b=c(a),f=b.indexOf(e);~f&&b.splice(f,1);return d},emit:function(a,b){c("*").concat(c(a)).forEach(function(a){a(b)});return d}};return d};
    
  15. developit commented on Jan 23, 2017

    @developit
    Owner

    The source gets transpiled by Buble so those let declarations actually are var - good to know we could save a few bytes going with closure though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions