<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: NickSettler</title>
    <description>The latest articles on DEV Community by NickSettler (@nicksettler).</description>
    <link>https://dev.to/nicksettler</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F412195%2F66112065-a6a6-417b-abe3-4dc1c778f494.jpeg</url>
      <title>DEV Community: NickSettler</title>
      <link>https://dev.to/nicksettler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicksettler"/>
    <language>en</language>
    <item>
      <title>Extending Global Event System with Typescript Generics</title>
      <dc:creator>NickSettler</dc:creator>
      <pubDate>Thu, 04 Aug 2022 11:06:00 +0000</pubDate>
      <link>https://dev.to/nicksettler/extending-global-event-system-with-typescript-generics-14f0</link>
      <guid>https://dev.to/nicksettler/extending-global-event-system-with-typescript-generics-14f0</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/nicksettler/build-a-global-event-system-with-typescript-4f2h"&gt;In the first part&lt;/a&gt; we have gone through creation of the initial Event System. It allowed to track events happening anywhere in the code and trigger handlers for these events.&lt;/p&gt;

&lt;p&gt;Anyway, the events currently must be predefined in the source code of the Event System. Also there is no event buffering, which means some code that has to process older events would not be able to retrieve them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Undoing Singleton Pattern
&lt;/h2&gt;

&lt;p&gt;Due to impossibility to pass and store types to Event System made using Singleton pattern, it is necessary to remove this pattern. So this post expects working with code without private constructor, &lt;code&gt;getInstance&lt;/code&gt; method and &lt;code&gt;instance&lt;/code&gt; field of the Event System class.&lt;/p&gt;

&lt;p&gt;After implementing this part, the Event System should always be initialized and stored in the code as a separate module.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Event Types
&lt;/h2&gt;

&lt;p&gt;The current implementation allows to set predefined list of events that can be tracked via the Events System. Using such implementation as a library will not allow third party developers to extend this list according to their own needs. Also such lack makes code hard to refactor.&lt;/p&gt;

&lt;p&gt;To fix this issue we can use the power of Typescript with generics, which will make third party customisation easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types and Interfaces Refactoring
&lt;/h3&gt;

&lt;p&gt;Firstly, it is necessary to update type definitions including Event System class types.&lt;/p&gt;

&lt;p&gt;Event System is expected to work with object-like types, in which key is a name of the event and value is a function that will be triggered when the event happens. So we can refactor our types to accept this kind of variables using TypeScript generics.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Using this refactoring makes it possible to pass a type containing key-value pairs of events’ names and their handlers. Such refactoring will be useful while adding generics to the Event System class methods.&lt;/p&gt;

&lt;h3&gt;
  
  
  Class Methods Refactoring
&lt;/h3&gt;

&lt;p&gt;To make Event System class methods work with events type passed via constructor, it is necessary to pass a type containing event’s names that will be handled.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After this update it will be possible to present the event name via generic while calling the function. Anyway, passing event name via generic is not necessary, because it is also passed as a function parameter, so it will be bound to generic key and this will ensure type safety while passing handler function or its parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Events Buffering
&lt;/h2&gt;

&lt;p&gt;Events buffering can be useful when some of the Subscribers attach to an event too late when the event has already been triggered. This missed event trigger may be important for the Subscriber, but in the current implementation it is unable to get it afterwards.&lt;/p&gt;

&lt;p&gt;Events buffering implementation will store the few last events. If the subscriber will attach later, he will receive the last few events and will have the possibility to handle them.&lt;/p&gt;

&lt;p&gt;To implement this feature is necessary to install third party lib &lt;a href="https://www.npmjs.com/package/mnemonist"&gt;Mnemonist&lt;/a&gt;, which has functionality of fixed length buffers. The last item is deleted when there is a new item in such kind of buffer. This is useful to prevent storing all events, which can potentially fill a lot of memory even if they will not be needed anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buffer Typing
&lt;/h3&gt;

&lt;p&gt;The Event System should have availability to configure buffer behavior. For this purpose it is reasonable to introduce a few more types. The current buffer implementation assumes setting buffer direction from the following (First-In-First-Out or Last-In-First-Out) and buffer size.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Event System Class Buffer Introduce
&lt;/h3&gt;

&lt;p&gt;To setup buffer configuration it is required to pass buffer setup options via Event System constructor parameters. These parameters should be also made optional, so the Event System can be easier used as a library by third party developers.&lt;/p&gt;

&lt;p&gt;The Mneonist data structure called &lt;code&gt;CircularBuffer&lt;/code&gt; will be used to store a particular number of the last events. It will make sure that the number of events stored in the array is always constant.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Buffer Processing Logic
&lt;/h3&gt;

&lt;p&gt;To store past events and trigger their handlers from new subscribers, it is necessary to update Event System methods.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;subscribe&lt;/code&gt; method should check if there are any events in the buffer, in which a new subscriber is interested.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;notify&lt;/code&gt; method should store all the events it receives in the buffer, to make their processing available for the subscribe method.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Currently implemented logic makes it possible to initialize the Event System in a separate module and use it anywhere in the code. TypeScript with generics provides availability to set custom event types and ensures event handlers and arguments are passed with required data types. Events buffering affords events to be buffered and available for late subscribers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Github Repository: &lt;a href="https://github.com/NickSettler/events-system"&gt;https://github.com/NickSettler/events-system&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>eventdriven</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Build a Global Event System With TypeScript</title>
      <dc:creator>NickSettler</dc:creator>
      <pubDate>Mon, 01 Aug 2022 00:36:00 +0000</pubDate>
      <link>https://dev.to/nicksettler/build-a-global-event-system-with-typescript-4f2h</link>
      <guid>https://dev.to/nicksettler/build-a-global-event-system-with-typescript-4f2h</guid>
      <description>&lt;p&gt;Writing complex projects may require handling different events between components. Some of these components may be too far away from each other in the way of programming. Building a global event system to handle this can solve the problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  Event System Pattern
&lt;/h1&gt;

&lt;p&gt;Event System should contain the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;subscribe(event, handler)&lt;/code&gt;. This method is used to subscribe entities to receive events and run handlers of these events. It is gonna be used by an entity interested in some events.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unsubscribe(event, handler)&lt;/code&gt;. This method is used to unsubcribe entities from receiving events. It is gonna be used by an entity interested in some events.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;notify(event, ...args)&lt;/code&gt;. This method is used to notify all entities, which are subscribed to the event, of the event that was triggered. It is gonna be used by an entity sending events to others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2Z0Sk1No--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9ytc0rsu13wbrbcw9r3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2Z0Sk1No--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9ytc0rsu13wbrbcw9r3.jpg" alt="Event System Pattern" width="788" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Singleton
&lt;/h2&gt;

&lt;p&gt;Singleton is a programming pattern that ensures that there is only one instance of a class in memory. This is useful for classes that manage resources that should only be used for one instance at a time.&lt;/p&gt;

&lt;p&gt;The Singleton pattern is implemented by creating a private constructor for the class, which prevents other pieces of code from instantiating it. The only way to get an instance of the class is through a static method that returns the one existing instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event System Singleton
&lt;/h2&gt;

&lt;p&gt;Event System will use the Singleton pattern to avoid memory leaks and to make sure there’s only one Event System instance all over the code to ensure logic consistency. This will make the Event System class behave the same globally in the code and will allow getting access to Event System logic through getInstance static method.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Events
&lt;/h1&gt;

&lt;p&gt;Event System will be able to trigger events and notify subscribers about them. This process should be as typed as possible. For the first time, events can be stored in the interface with their names, handler arguments, and handler return types. Later we will extend this using &lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;TypeScript generics&lt;/a&gt; so it will be possible to use your own types which will make the Event System more customizable.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Event Subscribers
&lt;/h2&gt;

&lt;p&gt;Subscribers will be notified about happening events. Each subscriber will have an event it will get notified about and a handler that will be used to process the event.&lt;/p&gt;

&lt;p&gt;Functions are non-primitives in the JavaScript world (moreover, they are &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions"&gt;objects&lt;/a&gt;) and are stored in the program as pointers. In this way, functions can be unique even if they have the same code inside. This allows discerning unique subscribers to use the event they are subscribed to and the event handler used for the event.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Subscribers Methods
&lt;/h2&gt;

&lt;p&gt;Since &lt;code&gt;subscribers&lt;/code&gt; field of the EventSystem class is an array, it is enough to add or remove an entry of the array. The logic of firing an event handler will be implemented in the &lt;code&gt;notify&lt;/code&gt; method.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Notification Methods
&lt;/h2&gt;

&lt;p&gt;Event System method &lt;code&gt;notify&lt;/code&gt; will be used by components which intend to trigger some action. This method will fire all subscribers’ event handlers.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Usage
&lt;/h1&gt;

&lt;p&gt;So after all this logic implementation Event System is ready to work. Currently, there is no possibility to extend events, so they should be predefined. Such extension and some other features will be implemented &lt;a href="https://dev.to/nicksettler/extending-global-event-system-with-typescript-generics-14f0"&gt;in the second part&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Github Repository: &lt;a href="https://github.com/NickSettler/events-system"&gt;https://github.com/NickSettler/events-system&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>typescript</category>
      <category>eventdriven</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
