3.0.0 • Published 9 months ago

@html_first/simple_signal v3.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

about @html_first/simple_signal

all of our classes designed to works in asynchronous context using Queues, so you can use it for api calls reactively without too much of mental overheads; we use attributeName to target elements on the DOM so it can be used as declaratively as possible despite minified; non-gzipped version of this library is less then 5kB;

classes api

  • Lifecycle:

    • usefull for:
      • adding event listeners;
      • track lifecycle of created element;
    • params:
      • attrLifecycleCallback: { [attributeName:string]: (element:HTMLElement|Element, observer:MutationObserver)=>(Promise<()=>Promise<void>>) }
        • fires when element is created/exist in the initial document;
        • returns callback which then fires when element no longer o documentScope
        • param element is the curent element which is created/exist in the initial document;
      • documentScope?: HTMLElement|Element|ShadowRoot|Document
    • example:
      • const clickEvent=()=>{ console.log("i've been clicked") }
      • new Lifecycle('elem-event', async (element) => { element.addEventListener('click', clickEvent); return async () => { element.removeEventListener('click', clickEvent); }; });
      • <buttton elem-event="unique string optional">click me</button>
        • you can minimise the number of MutationObserver instances on a documentScope, by keeping attributeName selector to minimum, then handle inside the lifecycleCallback using element.getAttribute(attributeName) to conditionally handle element's lifecycle, this is usefull if you are trying to create a library, or just having a pattern to render specific attributeName inside your html;
    • returns:
      • unObserve:()=>void: will un-observe the MutationObserver for the documentScope, except documentScope == undefined || documentScope == document
    • note:
      • observer options are set to {childList: true, subtree: true}, for performance purposes, therefore on creating new Element OR adding it as inner/outerHTML must contains the attributeName to be observed;
  • Let:

    • params:
      • value: VType
      • attributeName?: string
        • allow to reflect the value to dom, by targeting the value of ...(attributeName|propertyName);;
      • documentScope?: HTMLElement|Element|ShadowRoot|Document
        • scope of the dom reflector;
    • returns:
      • get value(): VType
      • set value(newValue:VType): void
      • call$:()=>void: manually trigger all registered effects;
      • remove$:(effect:$)=>void: remove registed effect to this Instance;
      • removeAll$:()=>void: remove all registered effects to this Instance, including that is auto recorded using signal to this instance;
    • example1:
      • const a = new Let('a');
    • example2:
      • const a = new Let('example', 'param-b');
      • <div param-b="innerText;data-a"></div> will reflect to DOM <div param-b="innerText;data-a" data-a="example">example</div>
    • note:
      • adding value to the html attribute like = attributeName="...;value;...", will bind the js variable value to the element value, only works on element that have valid oninput attribute
  • Derived:

    • params
      • asyncCallback: ()=>Promise<VType>
      • attributeName?: string
        • allow to reflect the value to dom, by targeting the value of ...(attributeName|propertyName);;
      • documentScope?: HTMLElement|Element|ShadowRoot|Document
        • scope of the dom reflector;
    • returns:
      • get value(): VType
      • remove$:(effect:$)=>void: remove registed effect to this Instance;
      • removeAll$:()=>void: remove all registered effects to this Instance;
    • example1:
      • "const b = new Derived(async()=>`derived from ${a.value}`);"
    • example2:
      • "const b = new Derived(async()=>`derived from ${a.value}`, 'param-a');"
      • <div param-a="innerText;data-a"></div> will reflect to DOM <div param-a="innerText;data-a" data-a="value of a">value of a</div>
  • Ping:

    • wrapper for async context using simple_signal internal Queue Handler;
    • params:
      • asyncCallbackWhenPinged: (isAtInitisalization:boolean)=>Promise<void>
    • returns:
      • ping:(isAtInitisalization:boolean)=>void
        • run asyncCallbackWhenPinged;
  • $:

    • params:
      • asyncCallback: (isAtInitialization:boolean)=>Promise<VType>
    • example:
      • new $( async (isAtInitialization) => { document.querySelector('p')?.setAttribute('text', b.value) });
    • returns:
      • E:asyncCallback: (isAtInitialization:boolean)=>Promise<VType>
        • used for lib internal functionality;
  • OnViewPort:

    • tips: coupled with Lifecycle it can be helpfull for complex client side routing/rendering;
    • params:
      • attributeName: string
        • allow to reflect the value to dom, by targeting the value of ...(attributeName|propertyName);;
      • OnViewCallback: (element:IntersectionObserverEntry['target'])=>Promise<void>
        • fires when element is entering viewport;
      • onExitingViewport?: (element:IntersectionObserverEntry['target'], unObserve:()=>void)=>Promise<void>
        • fires when element is exiting viewport;
        • when undefined: will automatically unObserve the elements;
      • documentScope?: HTMLElement|Element|ShadowRoot|Document
        • scope of the dom reflector;
    • example:
      • new OnViewPort('lazy-test', async (element, unobserve) => { console.log({element, message:'lazy is on viewport'}); return async () => { console.log({element, message:'lazy is leavinng viewport'}); unobserve() }; });
      • <p lazy-test>lazy test on view port</p>

function api

  • attrHelper
    • params:
      • attrHelpers:Record.<key:string<Vtype>,''>
    • returns:
      • Record.<key:string<Vtype>,string>
        • validated attribute name;

how to setup

we have several way of installing this library to your app, depending on how do you want to use it

IF you have no need of typehinting

we have very little api to remember so you can just slap our prebundled on head tag and use it as is

  • download the prebundled.mjs;
  • add the script on html head;
<head>
	...
	<script src="./path/to/prebundled.mjs" type="module" defer></script>
	...
</head>
  • we put it in a .mjs and type="module" so the variables doesn't bleed out without add additional closures, or function calls in the libs

IF you are comfortable with typehinting and you wanted to make it modular

  • install using npm i @html_first/simple_signal
// @ts-check

import { Let, $, Derived, Lifecycle, OnViewPort } from '@html_first/simple_signal';

no longer supported as we try to modularize the exports

copy the index.mjs on our github code and slap before your own js code

  • delete the export statement on all classes;
3.0.0

9 months ago

2.6.1

10 months ago

2.6.0

10 months ago

2.5.1

10 months ago

2.5.0

10 months ago

2.4.8

11 months ago

2.4.6

11 months ago

2.4.5

11 months ago

2.4.4

11 months ago

2.4.3

11 months ago

2.4.2

11 months ago

2.4.1

11 months ago

2.4.0

11 months ago

2.3.11

11 months ago

2.3.10

11 months ago

2.3.9

11 months ago

2.3.8

11 months ago

2.3.7

11 months ago

2.3.6

12 months ago

2.3.5

12 months ago

2.3.4

12 months ago

2.3.3

12 months ago

2.3.2

12 months ago

2.3.1

12 months ago

2.3.0

12 months ago

2.2.0

12 months ago

2.1.0

12 months ago

2.0.2

12 months ago

2.0.1

12 months ago

2.0.0

12 months ago

1.5.1

12 months ago

1.5.0

12 months ago

1.4.3

12 months ago

1.4.2

12 months ago

1.4.1

12 months ago

1.4.0

12 months ago

1.3.1

12 months ago

1.3.0

12 months ago

1.2.2

12 months ago

1.2.1

12 months ago

1.2.0

12 months ago

1.1.2

1 year ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.2

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago