npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@smoovy/composer

v1.0.10

Published

Component Manager, Service Manager all in one

Downloads

12

Readme

@smoovy/composer

Version Size

Very simple component/service system. Optimized for TypesScript usage.

Installation

yarn add @smoovy/composer

or

npm install --save @smoovy/composer

Component

A component is a very simple class, you just tell the composer what selector to use and it'll manage all updates and detects if the element is still in the DOM etc.

import { component } from  '@smoovy/composer';

/** Elements with the attribute `data-test` will be selected */
@component('test')
class TestComponent {
  constructor(
    private element: HTMLelement
  ) {}

  /** On creation after the injectors are done */
  onCreate() {}

  /** After the element is no longer in the DOM */
  onDestroy() {}

  /** Helper method to make unlistening easier **/
  onListen() {
    return () => {
      console.log('unlisten from listeners');
    };
  }
}

// you can change specify a different selector like this
@component({
  selector: '.select-this-class'
})

Lifecycle methods are: onCreate, onListen and onDestroy. All are optional ´

Component config

You can inject config from the element dataset into your component like this:

<div
  data-test-message="Hello Universe!"
  data-test-count="8"
></div>

<!-- It's also possible to define an object. So the following is the same: -->
<div
  data-test='{ "message": "Hello Universe!", "count": 8 }'
></div>

If you define both the "non-json" value has priority

import { component, config } from  '@smoovy/composer';

@component('test')
class TestComponent {
  @config('message')
  private message: string;

  @config('count', {
    type: Number,
    parse: (val: number) => val * val
  })
  private count = 0;

  onCreate() {
    console.log(this.message); // "Hello Universe!"
    console.log(this.count); // 64
  }
}

Component query

To simplify the step of querying elements from your root element, you can use the query or queryAll injector like this:

import { component, query, queryAll } from  '@smoovy/composer';

@component('test')
class TestComponent {
  @query('.headline')
  private headline: HTMLElement;

  @queryAll('p', { parse: list => Array.from(list) })
  private paragraphs: HTMLElement[] = [];

  onCreate() {
    console.log(this.headline); // contains DOM element
    console.log(this.paragraphs); // contains array of DOM p elements
  }
}

Service

A service is a class that exists as a singleton inside your project. This "singleton functionality" is achieved by using injectors. So you can inject services inside components and other services. A service is basically a Promise with extra functionality.

import { Service } from '@smoovy/composer';

class TestService extends Service<any, TestService> {
  get name() {
    return 'test';
  }

  get child() {
    return TestService;
  }

  async init() {
    this.resolve(this.config.msg);
  }
}

Creating sub services

A service can have children, so you can split the service into smaller ones and give them a separate context. For example you have a ScrollerService. Now you have a sidescroller which uses a different scroller, you could create a sub service with a name and different configuration. This allows you to create reusable components easier. Here's an example

const testService = new TestService({ msg: "I'm the parent" });

testService.addChild('sub1', { msg: "I'm the child" });

// now inside your components you can for the children
let message = '';

if (testService.hasChild('sub1')) {
  const sub1 = testService.getChild('sub1');
  message = await sub1;
} else {
  message = await testService;
}

// message will be "I'm the child"
console.log(message);

Using a service

Services can be injected into components or other services like this:

import { service, component } from  '@smoovy/composer';

class TestService2 {
  @service(TestService)
  private testService: TestService;

  async init() {
    // make sure to check if it's been activated otherwise it would wait forever
    if (this.testService.activated) {
      await this.testService;
    }
  }
}

@component('[data-test]')
class TestComponent {
  @service(TestService, true /** await automatically **/)
  private message: string;

  onCreate() {
    // We'll get value immediately since we told
    // to await the service on injection
    console.log(this.message);
  }
}

Composer

The composer glues components and services together. It manages injections, configurations and "garbage collection". Composers are defined with a class like this:

import { composer } from '@smoovy/composer';

@composer({
  services: [],
  components: []
})
class App {
  @composer()
  private composer!: Composer;

  onCreate() {
    console.log(this.composer);
  }
}

// Create the app to kick off initialization
new App();

Using composer in components

You can inject the composer into child components and services like this:

import { component, composer } from  '@smoovy/composer';

@component('[data-test]')
class TestComponent {
  @composer()
  private composer: Composer;

  onCreate() {
    this.composer.update();
  }
}

This also works for services

License

See the LICENSE file for license rights and limitations (MIT).