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

lacuna-spa

v8.8.0

Published

LacunaSpa is a framework that includes common parts of Lacuna's recent products, and, thus, was born as a code reuse strategy.

Readme

LacunaSpa

LacunaSpa is a framework that includes common parts of Lacuna's recent products, and, thus, was born as a code reuse strategy.

  • This package is intended to work with Angular 21.X.X

This Angular package includes common services, pipes, guards, components and API.

Besides using the resources mentioned above, you can also use its LacunaSpaRouteTree function inside your routing module's forRoot(), so that it returns the pre-configured Lacuna common route tree. Inside this function, you can configure the specific routes of your application.

While configuring a specific route level, you can also use the function ManagementRoutes, which returns an array of routes for management of subscriptions, users, applications, and so on.

Migrating an existing app from LacunaSpaModule.forRoot() to provideLacunaSpa()? See Migrating from LacunaSpaModule to provideLacunaSpa.

Example (standalone bootstrap — recommended)

import { bootstrapApplication } from '@angular/platform-browser';
import { provideLacunaSpa } from 'lacuna-spa';

bootstrapApplication(AppComponent, {
  providers: [
    provideLacunaSpa({
      listOfRoles: ['Admin', 'Manager', 'Worker'],
      requiredIdClaims: ['cpf'],
      //...
    }),
    // ...your app providers (router, http, etc.), after provideLacunaSpa() so that they override its tokens...
  ],
});

Example (NgModule bootstrap — for apps still on NgModules)

LacunaSpaModule.forRoot() takes the same params object as provideLacunaSpa(). It will be deprecated in Lacuna SPA 9, so prefer provideLacunaSpa() in new code.

import { LacunaSpaModule, LacunaSpaRouteTree, ManagementRoutes } from 'lacuna-spa';

//...

@NgModule({
  declarations: [
    //...
  ],
  imports: [
    //...,
    LacunaSpaModule.forRoot({
      listOfRoles: ['Admin', 'Manager', 'Worker'],
      requiredIdClaims: ['cpf'],
      //...
    }),
    RouterModule.forRoot(LacunaSpaRouteTree(
      {
        homeComponent: WelcomeComponent,
        layoutComponent: LayoutComponent,
      },
      {
        privateRoutes: [
          //...,
        ],
        subscriptionRoutes: [
          //...,
          ...ManagementRoutes({ subscriptionDetailComponent: SubscriptionDetailComponent }),
        ],
      }
    ))
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

//...

Migrating from LacunaSpaModule to provideLacunaSpa

Migrating is optional: LacunaSpaModule.forRoot() keeps working throughout 8.x, and is to be deprecated in Lacuna SPA 9. Upgrade first without touching your code, so that the migration is a diff of its own.

  1. Convert your app to standalone with Angular's schematic, one mode at a time:
    ng generate @angular/core:standalone --mode=convert-to-standalone
    ng generate @angular/core:standalone --mode=prune-ng-modules
    ng generate @angular/core:standalone --mode=standalone-bootstrap
    LacunaSpaModule re-exports FormsModule, ReactiveFormsModule, the Angular Material modules, TranslocoModule, PdfViewerModule and LacunaMatModule to every template that imports it, while a standalone component imports what its own template uses. The schematic adds most of these imports; add any it misses.
  2. Replace LacunaSpaModule.forRoot(params) with provideLacunaSpa(params) in bootstrapApplication's providers, as in the standalone example above. It takes the same params, whose type is now named LacunaSpaProviderParams; the old name, LacunaSpaModuleParams, is to be deprecated in Lacuna SPA 9.

Watch out for:

  • Your own providers go after provideLacunaSpa(). An AppModule's providers always beat the ones LacunaSpaModule.forRoot() brings in. In bootstrapApplication they share one injector, where the last provider of a token wins, so an override such as your own MatPaginatorIntl, DateAdapter, ErrorHandler or SPA_INVISIBLE_CAPTCHA_ENABLED placed before provideLacunaSpa() is silently replaced.
  • Your registerLocaleData(...) calls must survive the move. If they stay behind in a deleted app.module.ts, the first date, number or currency pipe throws NG0701, since Angular bundles only en-US.
  • Don't provide again what is already there. provideLacunaSpa() sets up ngx-mask, Transloco and its ICU transpiler, and bootstrapApplication the browser providers, so skip provideNgxMask(), provideTransloco() and importProvidersFrom(BrowserModule).

Then build, run, and open a screen with dates, numbers and translations, where these show up first.