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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@processpuzzle/util

v1.0.1

Published

![Build and Test](https://github.com/ZsZs/processpuzzle/actions/workflows/build-util.yml/badge.svg) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=processpuzzle_util&metric=alert_status)](https://sonarcloud.io/summary?id=

Readme

@processpuzzle/util

Build and Test Quality Gate Status Node version

General-purpose utilities used across ProcessPuzzle Angular applications: small data structures, a runtime configuration loader, a central error handler, a logging provider, a layout service and a few helpers.

Installation

npm install @processpuzzle/util

Public API overview

| Symbol | Kind | Purpose | | --- | --- | --- | | wildcardTextMatcher | function | Match a string against a wildcard pattern. | | getEnvironment | function | Map the current origin to an environment key. | | Stack<T> | class | LIFO stack data structure. | | SubstringPipe | Angular pipe | substring pipe for templates. | | LayoutService | Angular service | Reactive breakpoint/sidenav state. | | ConfigurationService | Angular service | Loads and merges JSON config files at startup. | | RUNTIME_CONFIGURATION | injection token | Provides the merged runtime configuration. | | CONFIGURATION_OPTIONS, CONFIGURATION_TYPE, CONFIGURATION_APP_INITIALIZER | injection tokens | Configuration hooks. | | BaseConfiguration, FirebaseConfig | types | Shared configuration shapes. | | provideLoggingService / LoggingConfiguration | provider | Configures ngx-logging-kit. | | provideCentralErrorHandler, CentralErrorHandler | provider / class | Global Angular ErrorHandler. | | centralHttpErrorInterceptor | HTTP interceptor | Forwards HTTP errors to the central handler. | | ERROR_MESSAGE_REPORTER / ErrorMessageReporter | injection token / interface | Optional UI reporter for the central handler. |

wildcardTextMatcher(str, rule)

Returns true when str matches rule. * in the rule matches any sequence of characters.

wildcardTextMatcher('Hello World', 'Hello*'); // true
wildcardTextMatcher('Hello World', '*World'); // true
wildcardTextMatcher('Hello World', 'Hello'); // true (rule is implicitly suffixed with .*)

getEnvironment(originUrl?)

Returns the environment key that corresponds to the application's origin. Falls back to location.origin when no argument is given.

| Origin | Returns | | --- | --- | | http://localhost:8080* | 'docker' | | http://localhost* | 'local' | | http://*.elasticbeanstalk.com | 'aws' | | anything else | throws Error |

Stack<T>

const stack = new Stack<number>();
stack.push(10);
stack.push(20);
stack.peek(); // 20
stack.pop();  // 20
stack.size(); // 1
stack.isEmpty(); // false
stack.toArray(); // [10]
stack.clear();

The constructor optionally accepts an initial array: new Stack([1, 2, 3]).

SubstringPipe

Standalone Angular pipe registered under the name substring. The arguments are forwarded to String.prototype.substring.

<div>{{ item.title | substring: 0 : 10 }}</div>

LayoutService

Tracks the current BreakpointObserver state as signals.

private readonly layout = inject(LayoutService);

readonly isCompact = computed(() => this.layout.isSmallDevice());
readonly sidenavMode = this.layout.sidenavMode; // SidenavStatus.EXPAND | CLOSE | SHRINK

Exposed signals: layoutClass, isSmallDevice, isMediumDevice, isLargeDevice, sidenavMode.

Runtime configuration

ConfigurationService<TEnv, TConfig> loads one or more JSON files at bootstrap, merges them in order (later files override earlier ones) and returns the result. The list of URLs is derived from the environment:

run-time-conf/config.common.json
run-time-conf/config.${PIPELINE_STAGE}.json
...CONFIGURATION_OVERRIDES (optional)

Typical bootstrap (see apps/processpuzzle-testbed/src/main.ts):

async function bootstrap() {
  const env = environment as EnvironmentVariables;
  const service = new ConfigurationService<EnvironmentVariables, RuntimeConfiguration>();
  const runtimeConfig = await service.init(env);

  await bootstrapApplication(AppComponent, createAppConfig(runtimeConfig));
}

The loaded value is then exposed to the rest of the app through the RUNTIME_CONFIGURATION token:

{ provide: RUNTIME_CONFIGURATION, useValue: runtimeConfig }

BaseConfiguration describes the minimum shape every application's configuration must satisfy (pipeline stage, backend provider, backend / object-store URLs and Firebase config). Extend it in your own RuntimeConfiguration type.

The other tokens — CONFIGURATION_OPTIONS, CONFIGURATION_TYPE, CONFIGURATION_APP_INITIALIZER — are reserved for downstream libraries that wire configuration into their own bootstrap hooks.

Logging

provideLoggingService wires ngx-logging-kit based on a LoggingConfiguration:

export interface LoggingConfiguration {
  level: 'none' | 'trace' | 'debug' | 'info' | 'log' | 'warn' | 'error' | 'fatal';
  serverLogLevel: 'none' | 'trace' | 'debug' | 'info' | 'log' | 'warn' | 'error' | 'fatal';
  serverLoggingUrl?: string;
}
providers: [
  provideLoggingService(runtimeConfig.LOGGING_CONFIGURATION),
]

When serverLogLevel is 'none', no server URL is registered even if one is provided.

Central error handling

provideCentralErrorHandler() registers CentralErrorHandler as Angular's global ErrorHandler. It:

  • unwraps rejection / ngOriginalError / originalError,
  • reloads the page on chunk-load errors,
  • logs HttpErrorResponse with status, statusText and URL,
  • logs everything else as fatal,
  • optionally forwards a display message to an ErrorMessageReporter.
providers: [
  provideHttpClient(withInterceptors([centralHttpErrorInterceptor])),
  provideCentralErrorHandler(),
  { provide: ERROR_MESSAGE_REPORTER, useExisting: MyToastReporterService }, // optional
]

Implement ErrorMessageReporter.showErrorMessage(message, error) to surface errors in the UI (snackbar, toast, dialog, etc.).

centralHttpErrorInterceptor simply pipes any HTTP error through the registered ErrorHandler and rethrows, so failures still propagate to caller subscribe/catchError blocks.