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

infodocviewdoc

v3.0.4

Published

`infodocviewdoc` es una librería Angular para previsualizar documentos en microfrontends (shell + Native Federation u orquestador similar).

Downloads

670

Readme

MFE Document Viewer Integration Guide

infodocviewdoc es una librería Angular para previsualizar documentos en microfrontends (shell + Native Federation u orquestador similar).

1) Instalacion del paquete

npm i [email protected]

Para probar cambios locales sin publicar: npm install <ruta>/sgdea-component-library/dist/ui-components

2) Dependencias requeridas en el host (package.json)

El MFE debe tener exactamente (o al menos) la misma major/minor de PDF viewer que el paquete:

{
  "dependencies": {
    "infodocviewdoc": "^3.0.4",
    "@handsontable/angular": "^16.2.0",
    "handsontable": "^16.2.0",
    "jspdf": "^4.1.0",
    "ngx-extended-pdf-viewer": "^25.6.4",
    "xlsx": "^0.18.5"
  }
}

Critico entre microfronts

Si otro MFE usa otra version de ngx-extended-pdf-viewer (p. ej. 22.x / worker 5.1.xxx) y el usuario navega sin F5, el shell deja scripts globales conflictivos y el canvas puede quedar en blanco (toolbar si, documento no).

Regla: todos los MFE que abran PDFs deben alinear ngx-extended-pdf-viewer@^25.6.4 (PDF.js build 5.4.1105).

Ejemplo completo (MFE nuevo)

{
  "dependencies": {
    "@angular/animations": "19.2.4",
    "@angular/common": "19.2.4",
    "@angular/core": "19.2.4",
    "@angular/forms": "19.2.4",
    "@angular/platform-browser": "19.2.4",
    "@angular/platform-browser-dynamic": "19.2.4",
    "@angular/router": "19.2.4",
    "rxjs": "~7.8.0",
    "tslib": "2.3.0",
    "zone.js": "~0.15.0",
    "infodocviewdoc": "^3.0.4",
    "@handsontable/angular": "^16.2.0",
    "handsontable": "^16.2.0",
    "jspdf": "^4.1.0",
    "ngx-extended-pdf-viewer": "^25.6.4",
    "xlsx": "^0.18.5"
  }
}
npm install

3) Assets PDF en angular.json (recomendado)

Copia los assets al build (o usa CDN / pdfAssetsBaseUrl):

{
  "glob": "**/*",
  "input": "node_modules/ngx-extended-pdf-viewer/assets",
  "output": "/assets/"
}
  • Si no hay /assets/ local, el paquete usa fallback CDN: https://cdn.jsdelivr.net/npm/[email protected]/assets
  • Sin assets ni CDN → 404 en viewer-*.mjs y PDF en blanco aunque el download del archivo sea 200.

Assets en otra ruta

<sgdea-document-viewer
  [pdfAssetsBaseUrl]="'https://mi-dominio.com/assets'"
  ...
></sgdea-document-viewer>

4) Import y uso basico

import { PdfViewerComponent } from 'infodocviewdoc';

@Component({
  standalone: true,
  imports: [PdfViewerComponent],
})
export class PdfPreviewModalComponent {}
<sgdea-document-viewer
  [fileBlob]="blob"
  [fileBlobName]="fileName"
  [url]="apiUrl"
  [token]="token"
  [pdfAssetsBaseUrl]="pdfAssetsBaseUrl">
</sgdea-document-viewer>

5) Inputs

| Input | Uso | |-------|-----| | fileBlob | File \| Blob ya descargado por el host (requerido para render). | | fileBlobName | Nombre con extension (recomendado). | | url / token | Solo para conversion Office → PDF. | | pdfAssetsBaseUrl | Base de assets PDF.js (CDN o host). |

Formatos: .pdf, .txt, imagenes, .xlsx/.xls, .docx/.doc, .pptx/.ppt (Office via conversion).


6) Integracion anti-fallo entre MFEs (obligatoria si navegas sin F5)

Sintoma tipico

  1. Abriste un PDF en otro MFE.
  2. Entras a este MFE sin recargar.
  3. Modal del visor: toolbar OK, canvas blanco.
  4. Con F5 a veces “arregla”. Eso es estado global de PDF.js, no falta de fileBlob.

El paquete mitiga esto así (interno, no necesitas setearlo en tu template):

  • [forceFullReloadOfJavaScriptCode]="true" (re-ejecuta scripts de PDF.js al montar).
  • Remount diferido (~200 ms) + pdfMountKey.
  • Reaplica assetsFolder + workerSrc (5.4.1105) en cada apertura.
  • PDF como Uint8Array (mas estable que reusar un Blob cruzando MFEs).
  • No borra localStorage['pdfjs.history'] ni fuerza disableHistory = true.

6.1) Utilidad de preload en el MFE (copia esto)

Crea src/app/shared/utils/pdf-viewer-preload.util.ts:

const NGX_EXTENDED_PDF_VIEWER_ASSETS_VERSION = '25.6.4';
const PDF_JS_BUILD = '5.4.1105';

/** CDN alineado a la peerDependency del paquete. */
export const PDF_ASSETS_BASE_URL =
  `https://cdn.jsdelivr.net/npm/ngx-extended-pdf-viewer@${NGX_EXTENDED_PDF_VIEWER_ASSETS_VERSION}/assets`;

let preloadPromise: Promise<void> | null = null;

/**
 * Precarga assets/worker. NO borrar pdfjs.history ni poner disableHistory=true:
 * eso no carga el PDF y puede empeorar el estado entre MFEs.
 */
function applyPdfJsAssets(mod: typeof import('ngx-extended-pdf-viewer')): void {
  const base = PDF_ASSETS_BASE_URL.replace(/\/$/, '');
  mod.pdfDefaultOptions.assetsFolder = base;
  mod.pdfDefaultOptions.disableHistory = false;
  mod.pdfDefaultOptions.historyUpdateUrl = false;
  (mod.pdfDefaultOptions as { workerSrc: string | (() => string) }).workerSrc = () =>
    `${base}/pdf.worker-${PDF_JS_BUILD}.mjs`;
}

export function preloadPdfViewerAssets(): Promise<void> {
  if (!preloadPromise) {
    preloadPromise = (async () => {
      const mod = await import('ngx-extended-pdf-viewer');
      applyPdfJsAssets(mod);

      await Promise.all(
        [
          fetch(`${PDF_ASSETS_BASE_URL}/viewer-${PDF_JS_BUILD}.min.mjs`, {
            mode: 'cors',
            cache: 'force-cache',
          }),
          fetch(`${PDF_ASSETS_BASE_URL}/pdf.worker-${PDF_JS_BUILD}.mjs`, {
            mode: 'cors',
            cache: 'force-cache',
          }),
        ].map((request) => request.catch(() => undefined)),
      );
    })().catch((error) => {
      preloadPromise = null;
      throw error;
    });
  }
  return preloadPromise;
}

6.2) Precargar al entrar al MFE

import { Component, OnInit } from '@angular/core';
import { preloadPdfViewerAssets } from '@shared/utils/pdf-viewer-preload.util';

@Component({ /* ... */ })
export class AppComponent implements OnInit {
  ngOnInit(): void {
    void preloadPdfViewerAssets();
  }
}

6.3) Descargar el archivo ANTES de abrir el modal

No abras el dialog solo con storagePath esperando que el visor “se arregle solo”.

  1. Loading.
  2. En paralelo: preloadPdfViewerAssets() + download (ArrayBuffer/Blob).
  3. Abrir modal con [fileBlob] + [fileBlobName] (+ [pdfAssetsBaseUrl]).
import { firstValueFrom } from 'rxjs';
import { preloadPdfViewerAssets, PDF_ASSETS_BASE_URL } from '@shared/utils/pdf-viewer-preload.util';

openDocumentViewer(bucket: string, objectName: string, fileName: string): void {
  void Promise.all([
    preloadPdfViewerAssets().catch(() => undefined),
    firstValueFrom(this.fileService.getFileToView(bucket, objectName)),
  ])
    .then(([, arrayBuffer]) => {
      const blob = new Blob([arrayBuffer], { type: 'application/pdf' });

      this.dialog.open(DocumentViewComponent, {
        width: '95vw',
        height: '90vh',
        data: {
          fileName,
          blob,
          pdfAssetsBaseUrl: PDF_ASSETS_BASE_URL,
        },
      });
    })
    .catch(() => {
      /* error de descarga */
    });
}

6.4) Montar el visor cuando el dialog ya tiene tamaño

En MatDialog:

  1. Espera afterOpened().
  2. Usa *ngIf / @if para montar sgdea-document-viewer solo cuando el contenedor tenga tamaño (clientWidth/Height >= 48) o tras un delay corto (~150 ms).
  3. Opcional: @for con key nueva para forzar remount al reabrir.
@if (infodocViewerVisible) {
  @for (shellKey of [viewerShellKey]; track shellKey) {
    <sgdea-document-viewer
      [fileBlob]="previewBlob"
      [fileBlobName]="documentName"
      [url]="apiUrl"
      [token]="token"
      [pdfAssetsBaseUrl]="pdfAssetsBaseUrl">
    </sgdea-document-viewer>
  }
}

Altura del wrap (evitar canvas con 0 px):

.infodoc-wrap sgdea-document-viewer {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 70vh;
}

6.5) Checklist MFE federado

  1. [email protected] + ngx-extended-pdf-viewer@^25.6.4 (misma familia en todos los MFE).
  2. Util preloadPdfViewerAssets sin removeItem('pdfjs.history') ni disableHistory = true.
  3. Precarga en AppComponent (o al entrar al feature).
  4. Blob listo antes del modal; pasar fileBlob + fileBlobName + pdfAssetsBaseUrl.
  5. Contenedor con altura real; montaje diferido / remount.
  6. Probar sin F5: otro MFE (PDF) → este MFE → Anexo/visor.
  7. Network: viewer-5.4.1105*.mjs y pdf.worker-5.4.1105.mjs en 200.

6.6) Que NO hacer en el host

| Anti-patron | Por que falla | |-------------|---------------| | localStorage.removeItem('pdfjs.history') al entrar | No alimenta el PDF; confunde el debug y pelea con el paquete. | | pdfDefaultOptions.disableHistory = true en preload | No soluciona el blank entre MFEs. | | Abrir modal solo con ruta y sin fileBlob | Carrera con cold-start de PDF.js. | | Mezclar versiones distintas de ngx-extended-pdf-viewer entre MFE | Worker/viewer incorrectos → toolbar OK, canvas blanco. | | Depender de F5 / “recargar pagina” | No es aceptable en shell federado. |


7) Diagnostico rapido

| Observacion | Interpretacion | |-------------|----------------| | Download 200 + blobs desde pdf-viewer + toolbar + canvas blanco | Estado PDF.js entre MFEs / scripts no re-ejecutados. Revisar seccion 6 + versiones. | | 404 viewer-*.mjs / worker | Assets mal configurados o CDN bloqueado. | | create-audit 400 | Ruido; no bloquea el render del PDF. | | Falta pdfjs.history | Irrelevante para cargar bytes; el PDF va por fileBlob. |


8) Cambios del paquete (comportamiento actual 3.0.4 local / a publicar)

Contrato publico sin breaking changes:

  • Inputs: fileBlob, fileBlobName, url, token, pdfAssetsBaseUrl

| Area | Comportamiento | |------|----------------| | Reload MFE | forceFullReloadOfJavaScriptCode + delay de montaje. | | Assets | Reaplica assetsFolder + workerSrc (CDN/pdfAssetsBaseUrl) en cada apertura. | | Src PDF | Prefiere Uint8Array desde el blob. | | Historial | No limpia pdfjs.history; deja disableHistory = false. | | Remount | pdfMountKey fuerza nueva instancia de ngx-extended-pdf-viewer. |

Si tu README o util de host aun recomienda borrar pdfjs.history / disableHistory = true, actualiza el host al patron de la seccion 6.


9) Instalacion local (desarrollo sin publicar)

# En la libreria
npm run build:lib

# En el MFE
npm install "C:/Users/aguio/Repos/Front/Package/component-library/sgdea-component-library/dist/ui-components"

Reinicia ng serve del MFE despues de reinstalar/rebuild.

10) Public API

public-api.ts exporta:

  • PdfViewerComponent (selector: sgdea-document-viewer)

11) Publicar (mantenedores)

cd C:/Users/aguio/Repos/Front/Package/component-library/sgdea-component-library
npm run publish:lib
cd dist/ui-components
npm login
npm publish --access public
npm view infodocviewdoc version
npm i [email protected]

Resumen de adopcion en otro microfront

  1. Instalar deps alineadas (infodocviewdoc + [email protected]).
  2. Copiar preload de la seccion 6.1 (sin borrar history).
  3. Descargar blob → abrir modal → <sgdea-document-viewer>.
  4. Validar flujo shell → otro MFE → este MFE → PDF sin F5.